@modern-js/runtime-utils 2.69.4 → 3.0.0-alpha.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/cjs/browser/deferreds.js +141 -145
- package/dist/cjs/browser/index.js +62 -21
- package/dist/cjs/browser/nestedRoutes.js +121 -147
- package/dist/cjs/merge.js +51 -44
- package/dist/cjs/node/fileReader.js +88 -97
- package/dist/cjs/node/index.js +87 -33
- package/dist/cjs/node/loaderContext/createLoaderCtx.js +43 -36
- package/dist/cjs/node/loaderContext/createRequestCtx.js +43 -41
- package/dist/cjs/node/loaderContext/index.js +38 -29
- package/dist/cjs/node/serialize.js +46 -40
- package/dist/cjs/node/storer/container.js +62 -58
- package/dist/cjs/node/storer/index.js +39 -31
- package/dist/cjs/node/storer/storage.js +82 -92
- package/dist/cjs/node/stream.js +89 -91
- package/dist/cjs/parsed.js +40 -38
- package/dist/cjs/router.js +88 -19
- package/dist/cjs/rsc.js +58 -0
- package/dist/cjs/server/index.js +55 -19
- package/dist/cjs/server/nestedRoutes.js +43 -39
- package/dist/cjs/time.js +53 -47
- package/dist/cjs/universal/async_storage.js +53 -37
- package/dist/cjs/universal/async_storage.server.js +63 -74
- package/dist/cjs/universal/cache.js +330 -381
- package/dist/cjs/universal/request.js +73 -65
- package/dist/cjs/url.js +33 -28
- package/dist/esm/browser/deferreds.mjs +118 -0
- package/dist/esm/browser/nestedRoutes.mjs +104 -0
- package/dist/esm/merge.mjs +26 -0
- package/dist/esm/node/fileReader.mjs +47 -0
- package/dist/{esm-node/node/index.js → esm/node/index.mjs} +2 -5
- package/dist/esm/node/loaderContext/createLoaderCtx.mjs +14 -0
- package/dist/esm/node/loaderContext/createRequestCtx.mjs +16 -0
- package/dist/{esm-node/node/loaderContext/index.js → esm/node/loaderContext/index.mjs} +1 -4
- package/dist/esm/node/serialize.mjs +5 -0
- package/dist/esm/node/storer/container.mjs +38 -0
- package/dist/{esm-node/node/storer/index.js → esm/node/storer/index.mjs} +2 -6
- package/dist/esm/node/storer/storage.mjs +53 -0
- package/dist/esm/node/stream.mjs +68 -0
- package/dist/esm/parsed.mjs +12 -0
- package/dist/esm/router.mjs +18 -0
- package/dist/esm/rsc.mjs +1 -0
- package/dist/esm/server/nestedRoutes.mjs +15 -0
- package/dist/esm/time.mjs +27 -0
- package/dist/esm/universal/async_storage.mjs +7 -0
- package/dist/esm/universal/async_storage.server.mjs +32 -0
- package/dist/esm/universal/cache.mjs +326 -0
- package/dist/esm/universal/request.mjs +40 -0
- package/dist/esm/url.mjs +5 -0
- package/dist/esm-node/browser/deferreds.mjs +118 -0
- package/dist/esm-node/browser/index.mjs +2 -0
- package/dist/esm-node/browser/nestedRoutes.mjs +104 -0
- package/dist/esm-node/merge.mjs +26 -0
- package/dist/esm-node/node/fileReader.mjs +47 -0
- package/dist/esm-node/node/index.mjs +5 -0
- package/dist/esm-node/node/loaderContext/createLoaderCtx.mjs +14 -0
- package/dist/esm-node/node/loaderContext/createRequestCtx.mjs +16 -0
- package/dist/esm-node/node/loaderContext/index.mjs +4 -0
- package/dist/esm-node/node/serialize.mjs +5 -0
- package/dist/esm-node/node/storer/container.mjs +38 -0
- package/dist/esm-node/node/storer/index.mjs +7 -0
- package/dist/esm-node/node/storer/storage.mjs +53 -0
- package/dist/esm-node/node/stream.mjs +68 -0
- package/dist/esm-node/parsed.mjs +12 -0
- package/dist/esm-node/router.mjs +18 -0
- package/dist/esm-node/rsc.mjs +1 -0
- package/dist/esm-node/server/index.mjs +1 -0
- package/dist/esm-node/server/nestedRoutes.mjs +15 -0
- package/dist/esm-node/time.mjs +27 -0
- package/dist/esm-node/universal/async_storage.mjs +24 -0
- package/dist/esm-node/universal/async_storage.server.mjs +32 -0
- package/dist/esm-node/universal/cache.mjs +326 -0
- package/dist/esm-node/universal/request.mjs +40 -0
- package/dist/esm-node/url.mjs +5 -0
- package/dist/types/browser/nestedRoutes.d.ts +2 -1
- package/dist/types/node/stream.d.ts +1 -1
- package/dist/types/router.d.ts +6 -1
- package/dist/types/rsc.d.ts +1 -0
- package/dist/types/universal/async_storage.d.ts +1 -1
- package/dist/types/universal/async_storage.server.d.ts +1 -1
- package/package.json +36 -46
- package/rslib.config.mts +27 -0
- package/rstest.config.ts +26 -0
- package/dist/cjs/node/router.js +0 -22
- package/dist/cjs/remixRouter.js +0 -43
- package/dist/esm/browser/deferreds.js +0 -227
- package/dist/esm/browser/index.js +0 -2
- package/dist/esm/browser/nestedRoutes.js +0 -177
- package/dist/esm/merge.js +0 -33
- package/dist/esm/node/fileReader.js +0 -140
- package/dist/esm/node/index.js +0 -8
- package/dist/esm/node/loaderContext/createLoaderCtx.js +0 -24
- package/dist/esm/node/loaderContext/createRequestCtx.js +0 -24
- package/dist/esm/node/loaderContext/index.js +0 -7
- package/dist/esm/node/router.js +0 -1
- package/dist/esm/node/serialize.js +0 -9
- package/dist/esm/node/storer/container.js +0 -94
- package/dist/esm/node/storer/index.js +0 -11
- package/dist/esm/node/storer/storage.js +0 -135
- package/dist/esm/node/stream.js +0 -87
- package/dist/esm/parsed.js +0 -20
- package/dist/esm/remixRouter.js +0 -7
- package/dist/esm/router.js +0 -1
- package/dist/esm/server/index.js +0 -1
- package/dist/esm/server/nestedRoutes.js +0 -23
- package/dist/esm/time.js +0 -32
- package/dist/esm/universal/async_storage.js +0 -18
- package/dist/esm/universal/async_storage.server.js +0 -43
- package/dist/esm/universal/cache.js +0 -1032
- package/dist/esm/universal/request.js +0 -51
- package/dist/esm/url.js +0 -10
- package/dist/esm-node/browser/deferreds.js +0 -138
- package/dist/esm-node/browser/nestedRoutes.js +0 -142
- package/dist/esm-node/merge.js +0 -29
- package/dist/esm-node/node/fileReader.js +0 -68
- package/dist/esm-node/node/loaderContext/createLoaderCtx.js +0 -19
- package/dist/esm-node/node/loaderContext/createRequestCtx.js +0 -24
- package/dist/esm-node/node/router.js +0 -1
- package/dist/esm-node/node/serialize.js +0 -9
- package/dist/esm-node/node/storer/container.js +0 -44
- package/dist/esm-node/node/storer/storage.js +0 -73
- package/dist/esm-node/node/stream.js +0 -80
- package/dist/esm-node/parsed.js +0 -20
- package/dist/esm-node/remixRouter.js +0 -7
- package/dist/esm-node/router.js +0 -1
- package/dist/esm-node/server/nestedRoutes.js +0 -21
- package/dist/esm-node/time.js +0 -31
- package/dist/esm-node/universal/async_storage.js +0 -18
- package/dist/esm-node/universal/async_storage.server.js +0 -45
- package/dist/esm-node/universal/cache.js +0 -401
- package/dist/esm-node/universal/request.js +0 -50
- package/dist/esm-node/url.js +0 -10
- package/dist/types/node/router.d.ts +0 -1
- package/dist/types/remixRouter.d.ts +0 -2
- /package/dist/{esm-node/browser/index.js → esm/browser/index.mjs} +0 -0
- /package/dist/{esm-node/server/index.js → esm/server/index.mjs} +0 -0
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
import { LRUCache } from "lru-cache";
|
|
2
|
+
import { getAsyncLocalStorage } from "./async_storage.mjs";
|
|
3
|
+
const CacheSize = {
|
|
4
|
+
KB: 1024,
|
|
5
|
+
MB: 1048576,
|
|
6
|
+
GB: 1073741824
|
|
7
|
+
};
|
|
8
|
+
const CacheTime = {
|
|
9
|
+
SECOND: 1000,
|
|
10
|
+
MINUTE: 60000,
|
|
11
|
+
HOUR: 3600000,
|
|
12
|
+
DAY: 86400000,
|
|
13
|
+
WEEK: 604800000,
|
|
14
|
+
MONTH: 2592000000
|
|
15
|
+
};
|
|
16
|
+
function estimateObjectSize(data) {
|
|
17
|
+
const type = typeof data;
|
|
18
|
+
if ('number' === type) return 8;
|
|
19
|
+
if ('boolean' === type) return 4;
|
|
20
|
+
if ('string' === type) return Math.max(2 * data.length, 1);
|
|
21
|
+
if (null == data) return 1;
|
|
22
|
+
if (ArrayBuffer.isView(data)) return Math.max(data.byteLength, 1);
|
|
23
|
+
if (Array.isArray(data)) return Math.max(data.reduce((acc, item)=>acc + estimateObjectSize(item), 0), 1);
|
|
24
|
+
if (data instanceof Map || data instanceof Set) return 1024;
|
|
25
|
+
if (data instanceof Date) return 8;
|
|
26
|
+
if ('object' === type) return Math.max(Object.entries(data).reduce((acc, [key, value])=>acc + 2 * key.length + estimateObjectSize(value), 0), 1);
|
|
27
|
+
return 1;
|
|
28
|
+
}
|
|
29
|
+
class MemoryContainer {
|
|
30
|
+
async get(key) {
|
|
31
|
+
return this.lru.get(key);
|
|
32
|
+
}
|
|
33
|
+
async set(key, value, options) {
|
|
34
|
+
if (options?.ttl) this.lru.set(key, value, {
|
|
35
|
+
ttl: 1000 * options.ttl
|
|
36
|
+
});
|
|
37
|
+
else this.lru.set(key, value);
|
|
38
|
+
}
|
|
39
|
+
async has(key) {
|
|
40
|
+
return this.lru.has(key);
|
|
41
|
+
}
|
|
42
|
+
async delete(key) {
|
|
43
|
+
return this.lru.delete(key);
|
|
44
|
+
}
|
|
45
|
+
async clear() {
|
|
46
|
+
this.lru.clear();
|
|
47
|
+
}
|
|
48
|
+
constructor(options){
|
|
49
|
+
this.lru = new LRUCache({
|
|
50
|
+
maxSize: options?.maxSize ?? CacheSize.GB,
|
|
51
|
+
sizeCalculation: estimateObjectSize,
|
|
52
|
+
updateAgeOnGet: true,
|
|
53
|
+
updateAgeOnHas: true
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const isServer = "u" < typeof window;
|
|
58
|
+
const requestCacheMap = new WeakMap();
|
|
59
|
+
const TAG_PREFIX = 'tag:';
|
|
60
|
+
const CACHE_PREFIX = 'modernjs_cache:';
|
|
61
|
+
const ongoingRevalidations = new Map();
|
|
62
|
+
let cache_storage;
|
|
63
|
+
let cacheConfig = {
|
|
64
|
+
maxSize: CacheSize.GB
|
|
65
|
+
};
|
|
66
|
+
function getStorage() {
|
|
67
|
+
if (cache_storage) return cache_storage;
|
|
68
|
+
cache_storage = cacheConfig.container ? cacheConfig.container : new MemoryContainer({
|
|
69
|
+
maxSize: cacheConfig.maxSize
|
|
70
|
+
});
|
|
71
|
+
return cache_storage;
|
|
72
|
+
}
|
|
73
|
+
function configureCache(config) {
|
|
74
|
+
cacheConfig = {
|
|
75
|
+
...cacheConfig,
|
|
76
|
+
...config
|
|
77
|
+
};
|
|
78
|
+
cache_storage = void 0;
|
|
79
|
+
}
|
|
80
|
+
function generateKey(args) {
|
|
81
|
+
return JSON.stringify(args, (_, value)=>{
|
|
82
|
+
if (value && 'object' == typeof value && !Array.isArray(value)) return Object.keys(value).sort().reduce((result, key)=>{
|
|
83
|
+
result[key] = value[key];
|
|
84
|
+
return result;
|
|
85
|
+
}, {});
|
|
86
|
+
return value;
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
function generateStableFunctionId(fn) {
|
|
90
|
+
const fnString = fn.toString();
|
|
91
|
+
let hash = 0;
|
|
92
|
+
for(let i = 0; i < fnString.length; i++){
|
|
93
|
+
const char = fnString.charCodeAt(i);
|
|
94
|
+
hash = (hash << 5) - hash + char;
|
|
95
|
+
hash &= hash;
|
|
96
|
+
}
|
|
97
|
+
return `fn_${fn.name || 'anonymous'}_${Math.abs(hash).toString(36)}`;
|
|
98
|
+
}
|
|
99
|
+
function cache(fn, options) {
|
|
100
|
+
return async (...args)=>{
|
|
101
|
+
if (isServer && void 0 === options) {
|
|
102
|
+
const storage = await getAsyncLocalStorage();
|
|
103
|
+
const request = storage?.useContext()?.request;
|
|
104
|
+
if (request) {
|
|
105
|
+
let shouldDisableCaching = false;
|
|
106
|
+
if (cacheConfig.unstable_shouldDisable) shouldDisableCaching = await cacheConfig.unstable_shouldDisable({
|
|
107
|
+
request
|
|
108
|
+
});
|
|
109
|
+
if (shouldDisableCaching) return fn(...args);
|
|
110
|
+
let requestCache = requestCacheMap.get(request);
|
|
111
|
+
if (!requestCache) {
|
|
112
|
+
requestCache = new Map();
|
|
113
|
+
requestCacheMap.set(request, requestCache);
|
|
114
|
+
}
|
|
115
|
+
let fnCache = requestCache.get(fn);
|
|
116
|
+
if (!fnCache) {
|
|
117
|
+
fnCache = new Map();
|
|
118
|
+
requestCache.set(fn, fnCache);
|
|
119
|
+
}
|
|
120
|
+
const key = generateKey(args);
|
|
121
|
+
if (fnCache.has(key)) return fnCache.get(key);
|
|
122
|
+
const promise = fn(...args);
|
|
123
|
+
fnCache.set(key, promise);
|
|
124
|
+
try {
|
|
125
|
+
const data = await promise;
|
|
126
|
+
return data;
|
|
127
|
+
} catch (error) {
|
|
128
|
+
fnCache.delete(key);
|
|
129
|
+
throw error;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
} else if (void 0 !== options) try {
|
|
133
|
+
const { tag, maxAge = 5 * CacheTime.MINUTE, revalidate = 0, customKey, onCache, getKey, unstable_shouldCache } = options;
|
|
134
|
+
let missReason;
|
|
135
|
+
const currentStorage = getStorage();
|
|
136
|
+
const now = Date.now();
|
|
137
|
+
const tags = tag ? Array.isArray(tag) ? tag : [
|
|
138
|
+
tag
|
|
139
|
+
] : [];
|
|
140
|
+
const genKey = getKey ? getKey(...args) : generateKey(args);
|
|
141
|
+
let finalKey;
|
|
142
|
+
if (customKey) finalKey = customKey({
|
|
143
|
+
params: args,
|
|
144
|
+
fn,
|
|
145
|
+
generatedKey: genKey
|
|
146
|
+
});
|
|
147
|
+
else {
|
|
148
|
+
const functionId = generateStableFunctionId(fn);
|
|
149
|
+
finalKey = `${functionId}:${genKey}`;
|
|
150
|
+
}
|
|
151
|
+
const storageKey = `${CACHE_PREFIX}${finalKey}`;
|
|
152
|
+
let shouldDisableCaching = false;
|
|
153
|
+
if (isServer && cacheConfig.unstable_shouldDisable) {
|
|
154
|
+
const asyncStorage = await getAsyncLocalStorage();
|
|
155
|
+
const request = asyncStorage?.useContext()?.request;
|
|
156
|
+
if (request) shouldDisableCaching = await cacheConfig.unstable_shouldDisable({
|
|
157
|
+
request
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
if (shouldDisableCaching) missReason = 1;
|
|
161
|
+
else {
|
|
162
|
+
const cached = await currentStorage.get(storageKey);
|
|
163
|
+
if (cached) try {
|
|
164
|
+
const cacheItem = cached;
|
|
165
|
+
const age = now - cacheItem.timestamp;
|
|
166
|
+
if (age < maxAge) {
|
|
167
|
+
onCache?.({
|
|
168
|
+
status: 'hit',
|
|
169
|
+
key: finalKey,
|
|
170
|
+
params: args,
|
|
171
|
+
result: cacheItem.data
|
|
172
|
+
});
|
|
173
|
+
return cacheItem.data;
|
|
174
|
+
}
|
|
175
|
+
if (revalidate > 0 && age < maxAge + revalidate) {
|
|
176
|
+
onCache?.({
|
|
177
|
+
status: 'stale',
|
|
178
|
+
key: finalKey,
|
|
179
|
+
params: args,
|
|
180
|
+
result: cacheItem.data
|
|
181
|
+
});
|
|
182
|
+
if (!ongoingRevalidations.has(storageKey)) {
|
|
183
|
+
const revalidationPromise = (async ()=>{
|
|
184
|
+
try {
|
|
185
|
+
const newData = await fn(...args);
|
|
186
|
+
let shouldCache = true;
|
|
187
|
+
if (unstable_shouldCache) shouldCache = await unstable_shouldCache({
|
|
188
|
+
params: args,
|
|
189
|
+
result: newData
|
|
190
|
+
});
|
|
191
|
+
if (shouldCache) await setCacheItem(currentStorage, storageKey, newData, tags, maxAge, revalidate);
|
|
192
|
+
} catch (error) {
|
|
193
|
+
if (isServer) {
|
|
194
|
+
const asyncStorage = await getAsyncLocalStorage();
|
|
195
|
+
asyncStorage?.useContext()?.monitors?.error(error.message);
|
|
196
|
+
} else console.error('Background revalidation failed:', error);
|
|
197
|
+
} finally{
|
|
198
|
+
ongoingRevalidations.delete(storageKey);
|
|
199
|
+
}
|
|
200
|
+
})();
|
|
201
|
+
ongoingRevalidations.set(storageKey, revalidationPromise);
|
|
202
|
+
}
|
|
203
|
+
return cacheItem.data;
|
|
204
|
+
}
|
|
205
|
+
missReason = 3;
|
|
206
|
+
} catch (error) {
|
|
207
|
+
console.warn('Failed to parse cached data:', error);
|
|
208
|
+
missReason = 4;
|
|
209
|
+
}
|
|
210
|
+
else missReason = 2;
|
|
211
|
+
}
|
|
212
|
+
const data = await fn(...args);
|
|
213
|
+
if (!shouldDisableCaching) {
|
|
214
|
+
let shouldCache = true;
|
|
215
|
+
if (unstable_shouldCache) shouldCache = await unstable_shouldCache({
|
|
216
|
+
params: args,
|
|
217
|
+
result: data
|
|
218
|
+
});
|
|
219
|
+
if (shouldCache) await setCacheItem(currentStorage, storageKey, data, tags, maxAge, revalidate);
|
|
220
|
+
}
|
|
221
|
+
onCache?.({
|
|
222
|
+
status: 'miss',
|
|
223
|
+
key: finalKey,
|
|
224
|
+
params: args,
|
|
225
|
+
result: data,
|
|
226
|
+
reason: missReason
|
|
227
|
+
});
|
|
228
|
+
return data;
|
|
229
|
+
} catch (error) {
|
|
230
|
+
console.warn('Cache operation failed, falling back to direct execution:', error);
|
|
231
|
+
const data = await fn(...args);
|
|
232
|
+
const { onCache } = options;
|
|
233
|
+
try {
|
|
234
|
+
onCache?.({
|
|
235
|
+
status: 'miss',
|
|
236
|
+
key: 'cache_failed',
|
|
237
|
+
params: args,
|
|
238
|
+
result: data,
|
|
239
|
+
reason: 5
|
|
240
|
+
});
|
|
241
|
+
} catch (callbackError) {
|
|
242
|
+
console.warn('Failed to call onCache callback:', callbackError);
|
|
243
|
+
}
|
|
244
|
+
return data;
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
console.warn('The cache function will not work because it runs on the browser and there are no options are provided.');
|
|
248
|
+
return fn(...args);
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
async function setCacheItem(storage, storageKey, data, tags, maxAge, revalidate) {
|
|
253
|
+
const newItem = {
|
|
254
|
+
data,
|
|
255
|
+
timestamp: Date.now(),
|
|
256
|
+
tags: tags.length > 0 ? tags : void 0
|
|
257
|
+
};
|
|
258
|
+
const ttl = (maxAge + revalidate) / 1000;
|
|
259
|
+
await storage.set(storageKey, newItem, {
|
|
260
|
+
ttl: ttl > 0 ? ttl : void 0
|
|
261
|
+
});
|
|
262
|
+
await updateTagRelationships(storage, storageKey, tags);
|
|
263
|
+
}
|
|
264
|
+
async function updateTagRelationships(storage, storageKey, tags) {
|
|
265
|
+
for (const tag of tags){
|
|
266
|
+
const tagStoreKey = `${TAG_PREFIX}${tag}`;
|
|
267
|
+
const keyList = await storage.get(tagStoreKey);
|
|
268
|
+
const keyArray = keyList || [];
|
|
269
|
+
if (!keyArray.includes(storageKey)) keyArray.push(storageKey);
|
|
270
|
+
await storage.set(tagStoreKey, keyArray);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
async function removeKeyFromTags(storage, storageKey, tags) {
|
|
274
|
+
for (const tag of tags){
|
|
275
|
+
const tagStoreKey = `${TAG_PREFIX}${tag}`;
|
|
276
|
+
const keyList = await storage.get(tagStoreKey);
|
|
277
|
+
if (keyList) try {
|
|
278
|
+
const keyArray = Array.isArray(keyList) ? keyList : [];
|
|
279
|
+
const updatedKeyList = keyArray.filter((key)=>key !== storageKey);
|
|
280
|
+
if (updatedKeyList.length > 0) await storage.set(tagStoreKey, updatedKeyList);
|
|
281
|
+
else await storage.delete(tagStoreKey);
|
|
282
|
+
} catch (error) {
|
|
283
|
+
console.warn(`Failed to process tag key list for tag ${tag}:`, error);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
function withRequestCache(handler) {
|
|
288
|
+
if (!isServer) return handler;
|
|
289
|
+
return async (req, ...args)=>{
|
|
290
|
+
const storage = await getAsyncLocalStorage();
|
|
291
|
+
return storage.run({
|
|
292
|
+
request: req
|
|
293
|
+
}, ()=>handler(req, ...args));
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
async function revalidateTag(tag) {
|
|
297
|
+
const currentStorage = getStorage();
|
|
298
|
+
const tagStoreKey = `${TAG_PREFIX}${tag}`;
|
|
299
|
+
const keyList = await currentStorage.get(tagStoreKey);
|
|
300
|
+
if (keyList) try {
|
|
301
|
+
const keyArray = Array.isArray(keyList) ? keyList : [];
|
|
302
|
+
for (const cacheKey of keyArray){
|
|
303
|
+
const cached = await currentStorage.get(cacheKey);
|
|
304
|
+
if (cached) try {
|
|
305
|
+
const cacheItem = cached;
|
|
306
|
+
if (cacheItem.tags) {
|
|
307
|
+
const otherTags = cacheItem.tags.filter((t)=>t !== tag);
|
|
308
|
+
await removeKeyFromTags(currentStorage, cacheKey, otherTags);
|
|
309
|
+
}
|
|
310
|
+
} catch (error) {
|
|
311
|
+
console.warn('Failed to parse cached data while revalidating:', error);
|
|
312
|
+
}
|
|
313
|
+
await currentStorage.delete(cacheKey);
|
|
314
|
+
}
|
|
315
|
+
await currentStorage.delete(tagStoreKey);
|
|
316
|
+
} catch (error) {
|
|
317
|
+
console.warn('Failed to process tag key list:', error);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
async function clearStore() {
|
|
321
|
+
const currentStorage = getStorage();
|
|
322
|
+
await currentStorage.clear();
|
|
323
|
+
cache_storage = void 0;
|
|
324
|
+
ongoingRevalidations.clear();
|
|
325
|
+
}
|
|
326
|
+
export { CacheSize, CacheTime, cache, clearStore, configureCache, generateKey, revalidateTag, withRequestCache };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
function parseQuery(req) {
|
|
2
|
+
const query = {};
|
|
3
|
+
const { url } = req;
|
|
4
|
+
const q = url.split('?')[1];
|
|
5
|
+
if (q) {
|
|
6
|
+
const search = new URLSearchParams(q);
|
|
7
|
+
search.forEach((v, k)=>{
|
|
8
|
+
query[k] = v;
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
return query;
|
|
12
|
+
}
|
|
13
|
+
function parseHeaders(request) {
|
|
14
|
+
const headersData = {};
|
|
15
|
+
request.headers.forEach((value, key)=>{
|
|
16
|
+
headersData[key] = value;
|
|
17
|
+
});
|
|
18
|
+
return headersData;
|
|
19
|
+
}
|
|
20
|
+
function getPathname(request) {
|
|
21
|
+
const match = request.url.match(/^https?:\/\/[^/]+(\/[^?]*)/);
|
|
22
|
+
return match ? match[1] : '/';
|
|
23
|
+
}
|
|
24
|
+
function getHost(request) {
|
|
25
|
+
const { headers } = request;
|
|
26
|
+
let host = headers.get('X-Forwarded-Host');
|
|
27
|
+
if (!host) host = headers.get('Host');
|
|
28
|
+
host = host?.split(/\s*,\s*/, 1)[0] || 'undefined';
|
|
29
|
+
return host;
|
|
30
|
+
}
|
|
31
|
+
function parseCookie(req) {
|
|
32
|
+
const _cookie = req.headers.get('Cookie');
|
|
33
|
+
const cookie = {};
|
|
34
|
+
_cookie?.trim().split(';').forEach((item)=>{
|
|
35
|
+
const [k, v] = item.trim().split('=');
|
|
36
|
+
if (k) cookie[k] = v;
|
|
37
|
+
});
|
|
38
|
+
return cookie;
|
|
39
|
+
}
|
|
40
|
+
export { getHost, getPathname, parseCookie, parseHeaders, parseQuery };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { NestedRoute } from '@modern-js/types';
|
|
2
|
-
|
|
2
|
+
import { type JSX } from 'react';
|
|
3
|
+
export declare const transformNestedRoutes: (routes: NestedRoute[]) => import("react-router").RouteObject[];
|
|
3
4
|
type DeferredDataComponentType = (props?: {
|
|
4
5
|
nonce?: string;
|
|
5
6
|
}) => JSX.Element | null;
|
package/dist/types/router.d.ts
CHANGED
|
@@ -1 +1,6 @@
|
|
|
1
|
-
export * from 'react-router
|
|
1
|
+
export * from 'react-router';
|
|
2
|
+
export declare const DEFERRED_SYMBOL: unique symbol;
|
|
3
|
+
/** @deprecated Please use Response.json instead. */
|
|
4
|
+
export declare const json: (data: any, init?: number | ResponseInit) => Response;
|
|
5
|
+
/** @deprecated defer is deprecated, You don't need to use it. */
|
|
6
|
+
export declare const defer: (data: any, init?: number | ResponseInit) => any;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from 'react-router';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { Storage } from './async_storage.server';
|
|
2
|
-
export declare const getAsyncLocalStorage: () => Storage | null
|
|
2
|
+
export declare const getAsyncLocalStorage: () => Promise<Storage | null>;
|
package/package.json
CHANGED
|
@@ -15,78 +15,73 @@
|
|
|
15
15
|
"modern",
|
|
16
16
|
"modern.js"
|
|
17
17
|
],
|
|
18
|
-
"version": "
|
|
18
|
+
"version": "3.0.0-alpha.0",
|
|
19
19
|
"_comment": "Provide ESM and CJS exports, ESM is used by runtime package, for treeshaking",
|
|
20
20
|
"exports": {
|
|
21
21
|
"./router": {
|
|
22
22
|
"types": "./dist/types/router.d.ts",
|
|
23
23
|
"require": "./dist/cjs/router.js",
|
|
24
|
-
"default": "./dist/esm/router.
|
|
24
|
+
"default": "./dist/esm/router.mjs"
|
|
25
25
|
},
|
|
26
|
-
"./
|
|
27
|
-
"types": "./dist/types/
|
|
28
|
-
"require": "./dist/cjs/
|
|
29
|
-
"default": "./dist/esm/
|
|
26
|
+
"./router/rsc": {
|
|
27
|
+
"types": "./dist/types/rsc.d.ts",
|
|
28
|
+
"require": "./dist/cjs/rsc.js",
|
|
29
|
+
"default": "./dist/esm/rsc.js"
|
|
30
30
|
},
|
|
31
31
|
"./browser": {
|
|
32
32
|
"types": "./dist/types/browser/index.d.ts",
|
|
33
33
|
"require": "./dist/cjs/browser/index.js",
|
|
34
|
-
"default": "./dist/esm/browser/index.
|
|
34
|
+
"default": "./dist/esm/browser/index.mjs"
|
|
35
35
|
},
|
|
36
36
|
"./node": {
|
|
37
37
|
"types": "./dist/types/node/index.d.ts",
|
|
38
38
|
"require": "./dist/cjs/node/index.js",
|
|
39
|
-
"default": "./dist/esm/node/index.
|
|
39
|
+
"default": "./dist/esm-node/node/index.mjs"
|
|
40
40
|
},
|
|
41
41
|
"./server": {
|
|
42
42
|
"types": "./dist/types/server/index.d.ts",
|
|
43
43
|
"require": "./dist/cjs/server/index.js",
|
|
44
|
-
"default": "./dist/esm/server/index.
|
|
45
|
-
},
|
|
46
|
-
"./node/router": {
|
|
47
|
-
"types": "./dist/types/node/router.d.ts",
|
|
48
|
-
"require": "./dist/cjs/node/router.js",
|
|
49
|
-
"default": "./dist/esm/node/router.js"
|
|
44
|
+
"default": "./dist/esm/server/index.mjs"
|
|
50
45
|
},
|
|
51
46
|
"./universal/request": {
|
|
52
47
|
"types": "./dist/universal/request.d.ts",
|
|
53
48
|
"require": "./dist/cjs/universal/request.js",
|
|
54
|
-
"default": "./dist/esm/universal/request.
|
|
49
|
+
"default": "./dist/esm/universal/request.mjs"
|
|
55
50
|
},
|
|
56
51
|
"./time": {
|
|
57
52
|
"types": "./dist/types/time.d.ts",
|
|
58
53
|
"require": "./dist/cjs/time.js",
|
|
59
|
-
"default": "./dist/esm/time.
|
|
54
|
+
"default": "./dist/esm/time.mjs"
|
|
60
55
|
},
|
|
61
56
|
"./parsed": {
|
|
62
57
|
"types": "./dist/types/parsed.d.ts",
|
|
63
58
|
"require": "./dist/cjs/parsed.js",
|
|
64
|
-
"default": "./dist/esm/parsed.
|
|
59
|
+
"default": "./dist/esm/parsed.mjs"
|
|
65
60
|
},
|
|
66
61
|
"./storer": {
|
|
67
62
|
"types": "./dist/types/node/storer/index.d.ts",
|
|
68
63
|
"require": "./dist/cjs/node/storer/index.js",
|
|
69
|
-
"default": "./dist/esm/node/storer/index.
|
|
64
|
+
"default": "./dist/esm/node/storer/index.mjs"
|
|
70
65
|
},
|
|
71
66
|
"./fileReader": {
|
|
72
67
|
"types": "./dist/types/node/fileReader.d.ts",
|
|
73
68
|
"require": "./dist/cjs/node/fileReader.js",
|
|
74
|
-
"default": "./dist/esm/node/fileReader.
|
|
69
|
+
"default": "./dist/esm/node/fileReader.mjs"
|
|
75
70
|
},
|
|
76
71
|
"./url": {
|
|
77
72
|
"types": "./dist/types/url.d.ts",
|
|
78
73
|
"require": "./dist/cjs/url.js",
|
|
79
|
-
"default": "./dist/esm/url.
|
|
74
|
+
"default": "./dist/esm/url.mjs"
|
|
80
75
|
},
|
|
81
76
|
"./merge": {
|
|
82
77
|
"types": "./dist/types/merge.d.ts",
|
|
83
78
|
"require": "./dist/cjs/merge.js",
|
|
84
|
-
"default": "./dist/esm/merge.
|
|
79
|
+
"default": "./dist/esm/merge.mjs"
|
|
85
80
|
},
|
|
86
81
|
"./cache": {
|
|
87
82
|
"types": "./dist/types/universal/cache.d.ts",
|
|
88
83
|
"require": "./dist/cjs/universal/cache.js",
|
|
89
|
-
"default": "./dist/esm/universal/cache.
|
|
84
|
+
"default": "./dist/esm/universal/cache.mjs"
|
|
90
85
|
}
|
|
91
86
|
},
|
|
92
87
|
"publishConfig": {
|
|
@@ -98,8 +93,8 @@
|
|
|
98
93
|
"router": [
|
|
99
94
|
"./dist/types/router.d.ts"
|
|
100
95
|
],
|
|
101
|
-
"
|
|
102
|
-
"./dist/types/
|
|
96
|
+
"router/rsc": [
|
|
97
|
+
"./dist/types/rsc.d.ts"
|
|
103
98
|
],
|
|
104
99
|
"browser": [
|
|
105
100
|
"./dist/types/browser/index.d.ts"
|
|
@@ -110,9 +105,6 @@
|
|
|
110
105
|
"server": [
|
|
111
106
|
"./dist/types/server/index.d.ts"
|
|
112
107
|
],
|
|
113
|
-
"node/router": [
|
|
114
|
-
"./dist/types/node/router.d.ts"
|
|
115
|
-
],
|
|
116
108
|
"universal/request": [
|
|
117
109
|
"./dist/types/universal/request.d.ts"
|
|
118
110
|
],
|
|
@@ -140,17 +132,16 @@
|
|
|
140
132
|
}
|
|
141
133
|
},
|
|
142
134
|
"dependencies": {
|
|
143
|
-
"@remix-run/router": "1.20.0",
|
|
144
135
|
"@swc/helpers": "^0.5.17",
|
|
145
136
|
"lru-cache": "^10.4.3",
|
|
146
|
-
"react-router
|
|
147
|
-
"serialize-javascript": "^6.0.
|
|
148
|
-
"@modern-js/types": "
|
|
149
|
-
"@modern-js/utils": "
|
|
137
|
+
"react-router": "7.8.2",
|
|
138
|
+
"serialize-javascript": "^6.0.2",
|
|
139
|
+
"@modern-js/types": "3.0.0-alpha.0",
|
|
140
|
+
"@modern-js/utils": "3.0.0-alpha.0"
|
|
150
141
|
},
|
|
151
142
|
"peerDependencies": {
|
|
152
|
-
"react": ">=17.0.
|
|
153
|
-
"react-dom": ">=17.0.
|
|
143
|
+
"react": ">=17.0.2",
|
|
144
|
+
"react-dom": ">=17.0.2"
|
|
154
145
|
},
|
|
155
146
|
"peerDependenciesMeta": {
|
|
156
147
|
"react": {
|
|
@@ -162,23 +153,22 @@
|
|
|
162
153
|
},
|
|
163
154
|
"devDependencies": {
|
|
164
155
|
"@types/ioredis-mock": "^8.2.6",
|
|
165
|
-
"@types/
|
|
166
|
-
"@types/
|
|
167
|
-
"
|
|
168
|
-
"
|
|
169
|
-
"
|
|
170
|
-
"
|
|
171
|
-
"react-dom": "^18.3.1",
|
|
156
|
+
"@types/node": "^20",
|
|
157
|
+
"@types/serialize-javascript": "^5.0.4",
|
|
158
|
+
"ioredis-mock": "^8.13.1",
|
|
159
|
+
"react": "^19.2.3",
|
|
160
|
+
"react-dom": "^19.2.3",
|
|
161
|
+
"@rslib/core": "0.18.5",
|
|
172
162
|
"typescript": "^5",
|
|
173
163
|
"@scripts/build": "2.66.0",
|
|
174
|
-
"@scripts/
|
|
164
|
+
"@scripts/rstest-config": "2.66.0",
|
|
165
|
+
"@modern-js/rslib": "2.68.10"
|
|
175
166
|
},
|
|
176
167
|
"sideEffects": false,
|
|
177
168
|
"scripts": {
|
|
178
|
-
"
|
|
179
|
-
"
|
|
180
|
-
"
|
|
181
|
-
"test": "jest --passWithNoTests"
|
|
169
|
+
"dev": "rslib build --watch",
|
|
170
|
+
"build": "rslib build",
|
|
171
|
+
"test": "rstest --passWithNoTests"
|
|
182
172
|
},
|
|
183
173
|
"types": "./dist/types/index.d.ts"
|
|
184
174
|
}
|
package/rslib.config.mts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { rslibConfig } from '@modern-js/rslib';
|
|
2
|
+
import { defineConfig } from '@rslib/core';
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
...rslibConfig,
|
|
6
|
+
lib: rslibConfig.lib?.map(libConfig => {
|
|
7
|
+
const isWebTarget = libConfig.output?.target === 'web';
|
|
8
|
+
|
|
9
|
+
return {
|
|
10
|
+
...libConfig,
|
|
11
|
+
...(isWebTarget && {
|
|
12
|
+
source: {
|
|
13
|
+
define: {
|
|
14
|
+
IS_WEB: 'true',
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
}),
|
|
18
|
+
output: {
|
|
19
|
+
...libConfig.output,
|
|
20
|
+
externals: {
|
|
21
|
+
async_hooks: 'async_hooks',
|
|
22
|
+
'./async_storage.server': './async_storage.server',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
}),
|
|
27
|
+
});
|
package/rstest.config.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { withTestPreset } from '@scripts/rstest-config';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
projects: [
|
|
5
|
+
withTestPreset({
|
|
6
|
+
name: 'runtime-utils-node',
|
|
7
|
+
root: __dirname,
|
|
8
|
+
testEnvironment: 'node',
|
|
9
|
+
exclude: [
|
|
10
|
+
'tests/universal/cache-client.test.ts',
|
|
11
|
+
'tests/browser/**/*.{test,spec}.{js,cjs,mjs,ts,tsx}',
|
|
12
|
+
],
|
|
13
|
+
globals: true,
|
|
14
|
+
}),
|
|
15
|
+
withTestPreset({
|
|
16
|
+
name: 'runtime-utils-client',
|
|
17
|
+
root: __dirname,
|
|
18
|
+
testEnvironment: 'jsdom',
|
|
19
|
+
include: [
|
|
20
|
+
'tests/universal/cache-client.test.ts',
|
|
21
|
+
'tests/browser/**/*.{test,spec}.{js,cjs,mjs,ts,tsx}',
|
|
22
|
+
],
|
|
23
|
+
globals: true,
|
|
24
|
+
}),
|
|
25
|
+
],
|
|
26
|
+
};
|
package/dist/cjs/node/router.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __copyProps = (to, from, except, desc) => {
|
|
7
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
-
for (let key of __getOwnPropNames(from))
|
|
9
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
-
}
|
|
12
|
-
return to;
|
|
13
|
-
};
|
|
14
|
-
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
15
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
16
|
-
var router_exports = {};
|
|
17
|
-
module.exports = __toCommonJS(router_exports);
|
|
18
|
-
__reExport(router_exports, require("react-router-dom/server"), module.exports);
|
|
19
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
20
|
-
0 && (module.exports = {
|
|
21
|
-
...require("react-router-dom/server")
|
|
22
|
-
});
|