@modern-js/runtime-utils 2.67.3 → 2.67.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/cjs/browser/deferreds.js +165 -0
- package/dist/cjs/browser/index.js +3 -1
- package/dist/cjs/browser/nestedRoutes.js +23 -2
- package/dist/cjs/universal/async_storage.js +13 -2
- package/dist/cjs/universal/cache.js +87 -30
- package/dist/esm/browser/deferreds.js +227 -0
- package/dist/esm/browser/index.js +1 -0
- package/dist/esm/browser/nestedRoutes.js +23 -2
- package/dist/esm/universal/async_storage.js +13 -2
- package/dist/esm/universal/cache.js +130 -48
- package/dist/esm-node/browser/deferreds.js +138 -0
- package/dist/esm-node/browser/index.js +1 -0
- package/dist/esm-node/browser/nestedRoutes.js +23 -2
- package/dist/esm-node/universal/async_storage.js +13 -2
- package/dist/esm-node/universal/cache.js +87 -30
- package/dist/types/browser/deferreds.d.ts +31 -0
- package/dist/types/browser/index.d.ts +1 -0
- package/dist/types/universal/async_storage.server.d.ts +2 -0
- package/dist/types/universal/cache.d.ts +18 -1
- package/package.json +3 -3
|
@@ -9,6 +9,10 @@ import { Suspense } from "react";
|
|
|
9
9
|
import { Outlet, Route, createRoutesFromElements } from "react-router-dom";
|
|
10
10
|
import { time } from "../time";
|
|
11
11
|
import { getAsyncLocalStorage } from "../universal/async_storage";
|
|
12
|
+
import { DeferredData, activeDeferreds as originalActiveDeferreds } from "./deferreds";
|
|
13
|
+
var privateDefer = function(data) {
|
|
14
|
+
return new DeferredData(data);
|
|
15
|
+
};
|
|
12
16
|
var transformNestedRoutes = function(routes) {
|
|
13
17
|
var routeElements = [];
|
|
14
18
|
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
|
|
@@ -102,12 +106,15 @@ var renderNestedRoute = function(nestedRoute) {
|
|
|
102
106
|
}), id);
|
|
103
107
|
return routeElement;
|
|
104
108
|
};
|
|
109
|
+
function isPlainObject(value) {
|
|
110
|
+
return value != null && (typeof value === "undefined" ? "undefined" : _type_of(value)) === "object" && Object.getPrototypeOf(value) === Object.prototype;
|
|
111
|
+
}
|
|
105
112
|
function createLoader(route) {
|
|
106
113
|
var loader = route.loader;
|
|
107
114
|
if (loader) {
|
|
108
115
|
return function() {
|
|
109
116
|
var _ref = _async_to_generator(function(args) {
|
|
110
|
-
var end, res, cost, _storage_useContext_monitors, storage;
|
|
117
|
+
var end, res, isRouterV7, activeDeferreds, _getAsyncLocalStorage_useContext, _getAsyncLocalStorage, deferredData, cost, _route_id, _storage_useContext_monitors, storage;
|
|
111
118
|
return _ts_generator(this, function(_state) {
|
|
112
119
|
switch (_state.label) {
|
|
113
120
|
case 0:
|
|
@@ -121,11 +128,25 @@ function createLoader(route) {
|
|
|
121
128
|
];
|
|
122
129
|
case 1:
|
|
123
130
|
res = _state.sent();
|
|
131
|
+
isRouterV7 = process.env._MODERN_ROUTER_VERSION === "v7";
|
|
132
|
+
if (isRouterV7) {
|
|
133
|
+
activeDeferreds = null;
|
|
134
|
+
if (typeof document === "undefined") {
|
|
135
|
+
;
|
|
136
|
+
activeDeferreds = (_getAsyncLocalStorage = getAsyncLocalStorage()) === null || _getAsyncLocalStorage === void 0 ? void 0 : (_getAsyncLocalStorage_useContext = _getAsyncLocalStorage.useContext()) === null || _getAsyncLocalStorage_useContext === void 0 ? void 0 : _getAsyncLocalStorage_useContext.activeDeferreds;
|
|
137
|
+
} else {
|
|
138
|
+
activeDeferreds = originalActiveDeferreds;
|
|
139
|
+
}
|
|
140
|
+
if (isPlainObject(res)) {
|
|
141
|
+
deferredData = privateDefer(res);
|
|
142
|
+
activeDeferreds.set(route.id, deferredData);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
124
145
|
cost = end();
|
|
125
146
|
if (typeof document === "undefined") {
|
|
126
147
|
;
|
|
127
148
|
storage = getAsyncLocalStorage();
|
|
128
|
-
storage === null || storage === void 0 ? void 0 : (_storage_useContext_monitors = storage.useContext().monitors) === null || _storage_useContext_monitors === void 0 ? void 0 : _storage_useContext_monitors.timing("".concat(LOADER_REPORTER_NAME, "-").concat(route.id), cost);
|
|
149
|
+
storage === null || storage === void 0 ? void 0 : (_storage_useContext_monitors = storage.useContext().monitors) === null || _storage_useContext_monitors === void 0 ? void 0 : _storage_useContext_monitors.timing("".concat(LOADER_REPORTER_NAME, "-").concat((_route_id = route.id) === null || _route_id === void 0 ? void 0 : _route_id.replace(/\//g, "_")), cost);
|
|
129
150
|
}
|
|
130
151
|
return [
|
|
131
152
|
2,
|
|
@@ -1,6 +1,17 @@
|
|
|
1
|
+
var isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
1
2
|
var getAsyncLocalStorage = function() {
|
|
2
|
-
|
|
3
|
-
|
|
3
|
+
if (isBrowser) {
|
|
4
|
+
console.error("You should not get async storage in browser");
|
|
5
|
+
return null;
|
|
6
|
+
} else {
|
|
7
|
+
try {
|
|
8
|
+
var serverStorage = require("./async_storage.server");
|
|
9
|
+
return serverStorage.getAsyncLocalStorage();
|
|
10
|
+
} catch (err) {
|
|
11
|
+
console.error("Failed to load server async storage", err);
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
4
15
|
};
|
|
5
16
|
export {
|
|
6
17
|
getAsyncLocalStorage
|
|
@@ -26,22 +26,23 @@ var lruCache;
|
|
|
26
26
|
var cacheConfig = {
|
|
27
27
|
maxSize: CacheSize.GB
|
|
28
28
|
};
|
|
29
|
-
var
|
|
30
|
-
function
|
|
31
|
-
var
|
|
32
|
-
if (!
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
var tagKeyMap = /* @__PURE__ */ new Map();
|
|
30
|
+
function addTagKeyRelation(tag, key) {
|
|
31
|
+
var keys = tagKeyMap.get(tag);
|
|
32
|
+
if (!keys) {
|
|
33
|
+
keys = /* @__PURE__ */ new Set();
|
|
34
|
+
tagKeyMap.set(tag, keys);
|
|
35
35
|
}
|
|
36
|
-
|
|
36
|
+
keys.add(key);
|
|
37
37
|
}
|
|
38
38
|
function configureCache(config) {
|
|
39
39
|
cacheConfig = _object_spread({}, cacheConfig, config);
|
|
40
40
|
}
|
|
41
41
|
function getLRUCache() {
|
|
42
42
|
if (!lruCache) {
|
|
43
|
+
var _cacheConfig_maxSize;
|
|
43
44
|
lruCache = new LRUCache({
|
|
44
|
-
maxSize: cacheConfig.maxSize,
|
|
45
|
+
maxSize: (_cacheConfig_maxSize = cacheConfig.maxSize) !== null && _cacheConfig_maxSize !== void 0 ? _cacheConfig_maxSize : CacheSize.GB,
|
|
45
46
|
sizeCalculation: function(value) {
|
|
46
47
|
if (!value.size) {
|
|
47
48
|
return 1;
|
|
@@ -121,16 +122,20 @@ function generateKey(args) {
|
|
|
121
122
|
});
|
|
122
123
|
}
|
|
123
124
|
function cache(fn, options) {
|
|
124
|
-
var _ref = options || {}, _ref_tag = _ref.tag, tag = _ref_tag === void 0 ? "default" : _ref_tag, _ref_maxAge = _ref.maxAge, maxAge = _ref_maxAge === void 0 ? CacheTime.MINUTE * 5 : _ref_maxAge, _ref_revalidate = _ref.revalidate, revalidate = _ref_revalidate === void 0 ? 0 : _ref_revalidate;
|
|
125
|
+
var _ref = options || {}, _ref_tag = _ref.tag, tag = _ref_tag === void 0 ? "default" : _ref_tag, _ref_maxAge = _ref.maxAge, maxAge = _ref_maxAge === void 0 ? CacheTime.MINUTE * 5 : _ref_maxAge, _ref_revalidate = _ref.revalidate, revalidate = _ref_revalidate === void 0 ? 0 : _ref_revalidate, customKey = _ref.customKey, onCache = _ref.onCache, getKey = _ref.getKey;
|
|
125
126
|
var store = getLRUCache();
|
|
126
127
|
var tags = Array.isArray(tag) ? tag : [
|
|
127
128
|
tag
|
|
128
129
|
];
|
|
129
|
-
|
|
130
|
-
return
|
|
131
|
-
|
|
130
|
+
var getCacheKey = function(args, generatedKey) {
|
|
131
|
+
return customKey ? customKey({
|
|
132
|
+
params: args,
|
|
133
|
+
fn,
|
|
134
|
+
generatedKey
|
|
135
|
+
}) : fn;
|
|
136
|
+
};
|
|
132
137
|
return /* @__PURE__ */ _async_to_generator(function() {
|
|
133
|
-
var _len, args, _key, _storage_useContext, storage, request, requestCache, fnCache, key, promise, data, error,
|
|
138
|
+
var _len, args, _key, _storage_useContext, storage, request, shouldDisableCaching, requestCache, fnCache, key, promise, data, error, genKey, now, cacheKey, finalKey, cacheStore, storeKey, shouldDisableCaching1, _storage_useContext1, storage1, request1, cached, age, data1;
|
|
134
139
|
var _arguments = arguments;
|
|
135
140
|
return _ts_generator(this, function(_state) {
|
|
136
141
|
switch (_state.label) {
|
|
@@ -141,15 +146,37 @@ function cache(fn, options) {
|
|
|
141
146
|
if (!(isServer && typeof options === "undefined"))
|
|
142
147
|
return [
|
|
143
148
|
3,
|
|
144
|
-
|
|
149
|
+
7
|
|
145
150
|
];
|
|
146
151
|
storage = getAsyncLocalStorage();
|
|
147
152
|
request = storage === null || storage === void 0 ? void 0 : (_storage_useContext = storage.useContext()) === null || _storage_useContext === void 0 ? void 0 : _storage_useContext.request;
|
|
148
153
|
if (!request)
|
|
149
154
|
return [
|
|
150
155
|
3,
|
|
151
|
-
|
|
156
|
+
6
|
|
157
|
+
];
|
|
158
|
+
shouldDisableCaching = false;
|
|
159
|
+
if (!cacheConfig.unstable_shouldDisable)
|
|
160
|
+
return [
|
|
161
|
+
3,
|
|
162
|
+
2
|
|
152
163
|
];
|
|
164
|
+
return [
|
|
165
|
+
4,
|
|
166
|
+
cacheConfig.unstable_shouldDisable({
|
|
167
|
+
request
|
|
168
|
+
})
|
|
169
|
+
];
|
|
170
|
+
case 1:
|
|
171
|
+
shouldDisableCaching = _state.sent();
|
|
172
|
+
_state.label = 2;
|
|
173
|
+
case 2:
|
|
174
|
+
if (shouldDisableCaching) {
|
|
175
|
+
return [
|
|
176
|
+
2,
|
|
177
|
+
fn.apply(void 0, _to_consumable_array(args))
|
|
178
|
+
];
|
|
179
|
+
}
|
|
153
180
|
requestCache = requestCacheMap.get(request);
|
|
154
181
|
if (!requestCache) {
|
|
155
182
|
requestCache = /* @__PURE__ */ new Map();
|
|
@@ -169,55 +196,100 @@ function cache(fn, options) {
|
|
|
169
196
|
}
|
|
170
197
|
promise = fn.apply(void 0, _to_consumable_array(args));
|
|
171
198
|
fnCache.set(key, promise);
|
|
172
|
-
_state.label =
|
|
173
|
-
case
|
|
199
|
+
_state.label = 3;
|
|
200
|
+
case 3:
|
|
174
201
|
_state.trys.push([
|
|
175
|
-
1,
|
|
176
202
|
3,
|
|
203
|
+
5,
|
|
177
204
|
,
|
|
178
|
-
|
|
205
|
+
6
|
|
179
206
|
]);
|
|
180
207
|
return [
|
|
181
208
|
4,
|
|
182
209
|
promise
|
|
183
210
|
];
|
|
184
|
-
case
|
|
211
|
+
case 4:
|
|
185
212
|
data = _state.sent();
|
|
186
213
|
return [
|
|
187
214
|
2,
|
|
188
215
|
data
|
|
189
216
|
];
|
|
190
|
-
case
|
|
217
|
+
case 5:
|
|
191
218
|
error = _state.sent();
|
|
192
219
|
fnCache.delete(key);
|
|
193
220
|
throw error;
|
|
194
|
-
case
|
|
221
|
+
case 6:
|
|
195
222
|
return [
|
|
196
223
|
3,
|
|
197
|
-
|
|
224
|
+
12
|
|
198
225
|
];
|
|
199
|
-
case
|
|
226
|
+
case 7:
|
|
200
227
|
if (!(typeof options !== "undefined"))
|
|
201
228
|
return [
|
|
202
229
|
3,
|
|
203
|
-
|
|
230
|
+
11
|
|
204
231
|
];
|
|
205
|
-
|
|
206
|
-
if (!tagCache) {
|
|
207
|
-
tagCache = /* @__PURE__ */ new Map();
|
|
208
|
-
}
|
|
209
|
-
key1 = generateKey(args);
|
|
210
|
-
cached = tagCache.get(key1);
|
|
232
|
+
genKey = getKey ? getKey.apply(void 0, _to_consumable_array(args)) : generateKey(args);
|
|
211
233
|
now = Date.now();
|
|
212
|
-
|
|
234
|
+
cacheKey = getCacheKey(args, genKey);
|
|
235
|
+
finalKey = typeof cacheKey === "function" ? genKey : cacheKey;
|
|
236
|
+
tags.forEach(function(t) {
|
|
237
|
+
return addTagKeyRelation(t, cacheKey);
|
|
238
|
+
});
|
|
239
|
+
cacheStore = store.get(cacheKey);
|
|
240
|
+
if (!cacheStore) {
|
|
241
|
+
cacheStore = /* @__PURE__ */ new Map();
|
|
242
|
+
}
|
|
243
|
+
storeKey = customKey && (typeof cacheKey === "undefined" ? "undefined" : _type_of(cacheKey)) === "symbol" ? "symbol-key" : genKey;
|
|
244
|
+
shouldDisableCaching1 = false;
|
|
245
|
+
if (!(isServer && cacheConfig.unstable_shouldDisable))
|
|
246
|
+
return [
|
|
247
|
+
3,
|
|
248
|
+
9
|
|
249
|
+
];
|
|
250
|
+
storage1 = getAsyncLocalStorage();
|
|
251
|
+
request1 = storage1 === null || storage1 === void 0 ? void 0 : (_storage_useContext1 = storage1.useContext()) === null || _storage_useContext1 === void 0 ? void 0 : _storage_useContext1.request;
|
|
252
|
+
if (!request1)
|
|
253
|
+
return [
|
|
254
|
+
3,
|
|
255
|
+
9
|
|
256
|
+
];
|
|
257
|
+
return [
|
|
258
|
+
4,
|
|
259
|
+
cacheConfig.unstable_shouldDisable({
|
|
260
|
+
request: request1
|
|
261
|
+
})
|
|
262
|
+
];
|
|
263
|
+
case 8:
|
|
264
|
+
shouldDisableCaching1 = _state.sent();
|
|
265
|
+
_state.label = 9;
|
|
266
|
+
case 9:
|
|
267
|
+
cached = cacheStore.get(storeKey);
|
|
268
|
+
if (cached && !shouldDisableCaching1) {
|
|
213
269
|
age = now - cached.timestamp;
|
|
214
270
|
if (age < maxAge) {
|
|
271
|
+
if (onCache) {
|
|
272
|
+
onCache({
|
|
273
|
+
status: "hit",
|
|
274
|
+
key: finalKey,
|
|
275
|
+
params: args,
|
|
276
|
+
result: cached.data
|
|
277
|
+
});
|
|
278
|
+
}
|
|
215
279
|
return [
|
|
216
280
|
2,
|
|
217
281
|
cached.data
|
|
218
282
|
];
|
|
219
283
|
}
|
|
220
284
|
if (revalidate > 0 && age < maxAge + revalidate) {
|
|
285
|
+
if (onCache) {
|
|
286
|
+
onCache({
|
|
287
|
+
status: "stale",
|
|
288
|
+
key: finalKey,
|
|
289
|
+
params: args,
|
|
290
|
+
result: cached.data
|
|
291
|
+
});
|
|
292
|
+
}
|
|
221
293
|
if (!cached.isRevalidating) {
|
|
222
294
|
cached.isRevalidating = true;
|
|
223
295
|
Promise.resolve().then(/* @__PURE__ */ _async_to_generator(function() {
|
|
@@ -237,12 +309,12 @@ function cache(fn, options) {
|
|
|
237
309
|
];
|
|
238
310
|
case 1:
|
|
239
311
|
newData = _state2.sent();
|
|
240
|
-
|
|
312
|
+
cacheStore.set(storeKey, {
|
|
241
313
|
data: newData,
|
|
242
314
|
timestamp: Date.now(),
|
|
243
315
|
isRevalidating: false
|
|
244
316
|
});
|
|
245
|
-
store.set(
|
|
317
|
+
store.set(cacheKey, cacheStore);
|
|
246
318
|
return [
|
|
247
319
|
3,
|
|
248
320
|
3
|
|
@@ -279,25 +351,35 @@ function cache(fn, options) {
|
|
|
279
351
|
4,
|
|
280
352
|
fn.apply(void 0, _to_consumable_array(args))
|
|
281
353
|
];
|
|
282
|
-
case
|
|
354
|
+
case 10:
|
|
283
355
|
data1 = _state.sent();
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
356
|
+
if (!shouldDisableCaching1) {
|
|
357
|
+
cacheStore.set(storeKey, {
|
|
358
|
+
data: data1,
|
|
359
|
+
timestamp: now,
|
|
360
|
+
isRevalidating: false
|
|
361
|
+
});
|
|
362
|
+
store.set(cacheKey, cacheStore);
|
|
363
|
+
}
|
|
364
|
+
if (onCache) {
|
|
365
|
+
onCache({
|
|
366
|
+
status: "miss",
|
|
367
|
+
key: finalKey,
|
|
368
|
+
params: args,
|
|
369
|
+
result: data1
|
|
370
|
+
});
|
|
371
|
+
}
|
|
290
372
|
return [
|
|
291
373
|
2,
|
|
292
374
|
data1
|
|
293
375
|
];
|
|
294
|
-
case
|
|
376
|
+
case 11:
|
|
295
377
|
console.warn("The cache function will not work because it runs on the browser and there are no options are provided.");
|
|
296
378
|
return [
|
|
297
379
|
2,
|
|
298
380
|
fn.apply(void 0, _to_consumable_array(args))
|
|
299
381
|
];
|
|
300
|
-
case
|
|
382
|
+
case 12:
|
|
301
383
|
return [
|
|
302
384
|
2
|
|
303
385
|
];
|
|
@@ -336,17 +418,17 @@ function withRequestCache(handler) {
|
|
|
336
418
|
}();
|
|
337
419
|
}
|
|
338
420
|
function revalidateTag(tag) {
|
|
339
|
-
var
|
|
340
|
-
if (
|
|
341
|
-
|
|
342
|
-
lruCache === null || lruCache === void 0 ? void 0 : lruCache.delete(
|
|
421
|
+
var keys = tagKeyMap.get(tag);
|
|
422
|
+
if (keys) {
|
|
423
|
+
keys.forEach(function(key) {
|
|
424
|
+
lruCache === null || lruCache === void 0 ? void 0 : lruCache.delete(key);
|
|
343
425
|
});
|
|
344
426
|
}
|
|
345
427
|
}
|
|
346
428
|
function clearStore() {
|
|
347
429
|
lruCache === null || lruCache === void 0 ? void 0 : lruCache.clear();
|
|
348
430
|
lruCache = void 0;
|
|
349
|
-
|
|
431
|
+
tagKeyMap.clear();
|
|
350
432
|
}
|
|
351
433
|
export {
|
|
352
434
|
CacheSize,
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
function invariant(value, message) {
|
|
2
|
+
if (value === false || value === null || typeof value === "undefined") {
|
|
3
|
+
throw new Error(message);
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
class AbortedDeferredError extends Error {
|
|
7
|
+
}
|
|
8
|
+
function isTrackedPromise(value) {
|
|
9
|
+
return value instanceof Promise && value._tracked === true;
|
|
10
|
+
}
|
|
11
|
+
function unwrapTrackedPromise(value) {
|
|
12
|
+
if (!isTrackedPromise(value)) {
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
if (value._error) {
|
|
16
|
+
throw value._error;
|
|
17
|
+
}
|
|
18
|
+
return value._data;
|
|
19
|
+
}
|
|
20
|
+
class DeferredData {
|
|
21
|
+
trackPromise(key, value) {
|
|
22
|
+
if (!(value instanceof Promise)) {
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
this.deferredKeys.push(key);
|
|
26
|
+
this.pendingKeysSet.add(key);
|
|
27
|
+
const promise = Promise.race([
|
|
28
|
+
value,
|
|
29
|
+
this.abortPromise
|
|
30
|
+
]).then((data) => this.onSettle(promise, key, void 0, data), (error) => this.onSettle(promise, key, error));
|
|
31
|
+
promise.catch(() => {
|
|
32
|
+
});
|
|
33
|
+
Object.defineProperty(promise, "_tracked", {
|
|
34
|
+
get: () => true
|
|
35
|
+
});
|
|
36
|
+
return promise;
|
|
37
|
+
}
|
|
38
|
+
onSettle(promise, key, error, data) {
|
|
39
|
+
if (this.controller.signal.aborted && error instanceof AbortedDeferredError) {
|
|
40
|
+
this.unlistenAbortSignal();
|
|
41
|
+
Object.defineProperty(promise, "_error", {
|
|
42
|
+
get: () => error
|
|
43
|
+
});
|
|
44
|
+
return Promise.reject(error);
|
|
45
|
+
}
|
|
46
|
+
this.pendingKeysSet.delete(key);
|
|
47
|
+
if (this.done) {
|
|
48
|
+
this.unlistenAbortSignal();
|
|
49
|
+
}
|
|
50
|
+
if (error === void 0 && data === void 0) {
|
|
51
|
+
const undefinedError = new Error(`Deferred data for key "${key}" resolved/rejected with \`undefined\`, you must resolve/reject with a value or \`null\`.`);
|
|
52
|
+
Object.defineProperty(promise, "_error", {
|
|
53
|
+
get: () => undefinedError
|
|
54
|
+
});
|
|
55
|
+
this.emit(false, key);
|
|
56
|
+
return Promise.reject(undefinedError);
|
|
57
|
+
}
|
|
58
|
+
if (data === void 0) {
|
|
59
|
+
Object.defineProperty(promise, "_error", {
|
|
60
|
+
get: () => error
|
|
61
|
+
});
|
|
62
|
+
this.emit(false, key);
|
|
63
|
+
return Promise.reject(error);
|
|
64
|
+
}
|
|
65
|
+
Object.defineProperty(promise, "_data", {
|
|
66
|
+
get: () => data
|
|
67
|
+
});
|
|
68
|
+
this.emit(false, key);
|
|
69
|
+
return data;
|
|
70
|
+
}
|
|
71
|
+
emit(aborted, settledKey) {
|
|
72
|
+
this.subscribers.forEach((subscriber) => subscriber(aborted, settledKey));
|
|
73
|
+
}
|
|
74
|
+
subscribe(fn) {
|
|
75
|
+
this.subscribers.add(fn);
|
|
76
|
+
return () => this.subscribers.delete(fn);
|
|
77
|
+
}
|
|
78
|
+
cancel() {
|
|
79
|
+
this.controller.abort();
|
|
80
|
+
this.pendingKeysSet.forEach((v, k) => this.pendingKeysSet.delete(k));
|
|
81
|
+
this.emit(true);
|
|
82
|
+
}
|
|
83
|
+
async resolveData(signal) {
|
|
84
|
+
let aborted = false;
|
|
85
|
+
if (!this.done) {
|
|
86
|
+
const onAbort = () => this.cancel();
|
|
87
|
+
signal.addEventListener("abort", onAbort);
|
|
88
|
+
aborted = await new Promise((resolve) => {
|
|
89
|
+
this.subscribe((aborted2) => {
|
|
90
|
+
signal.removeEventListener("abort", onAbort);
|
|
91
|
+
if (aborted2 || this.done) {
|
|
92
|
+
resolve(aborted2);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
return aborted;
|
|
98
|
+
}
|
|
99
|
+
get done() {
|
|
100
|
+
return this.pendingKeysSet.size === 0;
|
|
101
|
+
}
|
|
102
|
+
get unwrappedData() {
|
|
103
|
+
invariant(this.data !== null && this.done, "Can only unwrap data on initialized and settled deferreds");
|
|
104
|
+
return Object.entries(this.data).reduce((acc, [key, value]) => Object.assign(acc, {
|
|
105
|
+
[key]: unwrapTrackedPromise(value)
|
|
106
|
+
}), {});
|
|
107
|
+
}
|
|
108
|
+
get pendingKeys() {
|
|
109
|
+
return Array.from(this.pendingKeysSet);
|
|
110
|
+
}
|
|
111
|
+
constructor(data, responseInit) {
|
|
112
|
+
this.pendingKeysSet = /* @__PURE__ */ new Set();
|
|
113
|
+
this.subscribers = /* @__PURE__ */ new Set();
|
|
114
|
+
this.__modern_deferred = true;
|
|
115
|
+
this.deferredKeys = [];
|
|
116
|
+
invariant(data && typeof data === "object" && !Array.isArray(data), "defer() only accepts plain objects");
|
|
117
|
+
let reject;
|
|
118
|
+
this.abortPromise = new Promise((_, r) => reject = r);
|
|
119
|
+
this.controller = new AbortController();
|
|
120
|
+
const onAbort = () => reject(new AbortedDeferredError("Deferred data aborted"));
|
|
121
|
+
this.unlistenAbortSignal = () => this.controller.signal.removeEventListener("abort", onAbort);
|
|
122
|
+
this.controller.signal.addEventListener("abort", onAbort);
|
|
123
|
+
this.data = Object.entries(data).reduce((acc, [key, value]) => Object.assign(acc, {
|
|
124
|
+
[key]: this.trackPromise(key, value)
|
|
125
|
+
}), {});
|
|
126
|
+
if (this.done) {
|
|
127
|
+
this.unlistenAbortSignal();
|
|
128
|
+
}
|
|
129
|
+
this.init = responseInit;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const activeDeferreds = /* @__PURE__ */ new Map();
|
|
133
|
+
export {
|
|
134
|
+
AbortedDeferredError,
|
|
135
|
+
DeferredData,
|
|
136
|
+
activeDeferreds,
|
|
137
|
+
invariant
|
|
138
|
+
};
|
|
@@ -4,6 +4,10 @@ import { Suspense } from "react";
|
|
|
4
4
|
import { Outlet, Route, createRoutesFromElements } from "react-router-dom";
|
|
5
5
|
import { time } from "../time";
|
|
6
6
|
import { getAsyncLocalStorage } from "../universal/async_storage";
|
|
7
|
+
import { DeferredData, activeDeferreds as originalActiveDeferreds } from "./deferreds";
|
|
8
|
+
const privateDefer = (data) => {
|
|
9
|
+
return new DeferredData(data);
|
|
10
|
+
};
|
|
7
11
|
const transformNestedRoutes = (routes) => {
|
|
8
12
|
const routeElements = [];
|
|
9
13
|
for (const route of routes) {
|
|
@@ -86,6 +90,9 @@ const renderNestedRoute = (nestedRoute, options = {}) => {
|
|
|
86
90
|
}, id);
|
|
87
91
|
return routeElement;
|
|
88
92
|
};
|
|
93
|
+
function isPlainObject(value) {
|
|
94
|
+
return value != null && typeof value === "object" && Object.getPrototypeOf(value) === Object.prototype;
|
|
95
|
+
}
|
|
89
96
|
function createLoader(route) {
|
|
90
97
|
const { loader } = route;
|
|
91
98
|
if (loader) {
|
|
@@ -95,11 +102,25 @@ function createLoader(route) {
|
|
|
95
102
|
}
|
|
96
103
|
const end = time();
|
|
97
104
|
const res = await loader(args);
|
|
105
|
+
const isRouterV7 = process.env._MODERN_ROUTER_VERSION === "v7";
|
|
106
|
+
if (isRouterV7) {
|
|
107
|
+
let activeDeferreds = null;
|
|
108
|
+
if (typeof document === "undefined") {
|
|
109
|
+
var _getAsyncLocalStorage_useContext, _getAsyncLocalStorage;
|
|
110
|
+
activeDeferreds = (_getAsyncLocalStorage = getAsyncLocalStorage()) === null || _getAsyncLocalStorage === void 0 ? void 0 : (_getAsyncLocalStorage_useContext = _getAsyncLocalStorage.useContext()) === null || _getAsyncLocalStorage_useContext === void 0 ? void 0 : _getAsyncLocalStorage_useContext.activeDeferreds;
|
|
111
|
+
} else {
|
|
112
|
+
activeDeferreds = originalActiveDeferreds;
|
|
113
|
+
}
|
|
114
|
+
if (isPlainObject(res)) {
|
|
115
|
+
const deferredData = privateDefer(res);
|
|
116
|
+
activeDeferreds.set(route.id, deferredData);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
98
119
|
const cost = end();
|
|
99
120
|
if (typeof document === "undefined") {
|
|
100
|
-
var _storage_useContext_monitors;
|
|
121
|
+
var _route_id, _storage_useContext_monitors;
|
|
101
122
|
const storage = getAsyncLocalStorage();
|
|
102
|
-
storage === null || storage === void 0 ? void 0 : (_storage_useContext_monitors = storage.useContext().monitors) === null || _storage_useContext_monitors === void 0 ? void 0 : _storage_useContext_monitors.timing(`${LOADER_REPORTER_NAME}-${route.id}`, cost);
|
|
123
|
+
storage === null || storage === void 0 ? void 0 : (_storage_useContext_monitors = storage.useContext().monitors) === null || _storage_useContext_monitors === void 0 ? void 0 : _storage_useContext_monitors.timing(`${LOADER_REPORTER_NAME}-${(_route_id = route.id) === null || _route_id === void 0 ? void 0 : _route_id.replace(/\//g, "_")}`, cost);
|
|
103
124
|
}
|
|
104
125
|
return res;
|
|
105
126
|
};
|
|
@@ -1,6 +1,17 @@
|
|
|
1
|
+
const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
1
2
|
const getAsyncLocalStorage = () => {
|
|
2
|
-
|
|
3
|
-
|
|
3
|
+
if (isBrowser) {
|
|
4
|
+
console.error("You should not get async storage in browser");
|
|
5
|
+
return null;
|
|
6
|
+
} else {
|
|
7
|
+
try {
|
|
8
|
+
const serverStorage = require("./async_storage.server");
|
|
9
|
+
return serverStorage.getAsyncLocalStorage();
|
|
10
|
+
} catch (err) {
|
|
11
|
+
console.error("Failed to load server async storage", err);
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
4
15
|
};
|
|
5
16
|
export {
|
|
6
17
|
getAsyncLocalStorage
|