@modern-js/runtime-utils 2.69.5 → 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,118 @@
|
|
|
1
|
+
function invariant(value, message) {
|
|
2
|
+
if (false === value || null == value) throw new Error(message);
|
|
3
|
+
}
|
|
4
|
+
class AbortedDeferredError extends Error {
|
|
5
|
+
}
|
|
6
|
+
function isTrackedPromise(value) {
|
|
7
|
+
return value instanceof Promise && true === value._tracked;
|
|
8
|
+
}
|
|
9
|
+
function unwrapTrackedPromise(value) {
|
|
10
|
+
if (!isTrackedPromise(value)) return value;
|
|
11
|
+
if (value._error) throw value._error;
|
|
12
|
+
return value._data;
|
|
13
|
+
}
|
|
14
|
+
class DeferredData {
|
|
15
|
+
trackPromise(key, value) {
|
|
16
|
+
if (!(value instanceof Promise)) return value;
|
|
17
|
+
this.deferredKeys.push(key);
|
|
18
|
+
this.pendingKeysSet.add(key);
|
|
19
|
+
const promise = Promise.race([
|
|
20
|
+
value,
|
|
21
|
+
this.abortPromise
|
|
22
|
+
]).then((data)=>this.onSettle(promise, key, void 0, data), (error)=>this.onSettle(promise, key, error));
|
|
23
|
+
promise.catch(()=>{});
|
|
24
|
+
Object.defineProperty(promise, '_tracked', {
|
|
25
|
+
get: ()=>true
|
|
26
|
+
});
|
|
27
|
+
return promise;
|
|
28
|
+
}
|
|
29
|
+
onSettle(promise, key, error, data) {
|
|
30
|
+
if (this.controller.signal.aborted && error instanceof AbortedDeferredError) {
|
|
31
|
+
this.unlistenAbortSignal();
|
|
32
|
+
Object.defineProperty(promise, '_error', {
|
|
33
|
+
get: ()=>error
|
|
34
|
+
});
|
|
35
|
+
return Promise.reject(error);
|
|
36
|
+
}
|
|
37
|
+
this.pendingKeysSet.delete(key);
|
|
38
|
+
if (this.done) this.unlistenAbortSignal();
|
|
39
|
+
if (void 0 === error && void 0 === data) {
|
|
40
|
+
const undefinedError = new Error(`Deferred data for key "${key}" resolved/rejected with \`undefined\`, you must resolve/reject with a value or \`null\`.`);
|
|
41
|
+
Object.defineProperty(promise, '_error', {
|
|
42
|
+
get: ()=>undefinedError
|
|
43
|
+
});
|
|
44
|
+
this.emit(false, key);
|
|
45
|
+
return Promise.reject(undefinedError);
|
|
46
|
+
}
|
|
47
|
+
if (void 0 === data) {
|
|
48
|
+
Object.defineProperty(promise, '_error', {
|
|
49
|
+
get: ()=>error
|
|
50
|
+
});
|
|
51
|
+
this.emit(false, key);
|
|
52
|
+
return Promise.reject(error);
|
|
53
|
+
}
|
|
54
|
+
Object.defineProperty(promise, '_data', {
|
|
55
|
+
get: ()=>data
|
|
56
|
+
});
|
|
57
|
+
this.emit(false, key);
|
|
58
|
+
return data;
|
|
59
|
+
}
|
|
60
|
+
emit(aborted, settledKey) {
|
|
61
|
+
this.subscribers.forEach((subscriber)=>subscriber(aborted, settledKey));
|
|
62
|
+
}
|
|
63
|
+
subscribe(fn) {
|
|
64
|
+
this.subscribers.add(fn);
|
|
65
|
+
return ()=>this.subscribers.delete(fn);
|
|
66
|
+
}
|
|
67
|
+
cancel() {
|
|
68
|
+
this.controller.abort();
|
|
69
|
+
this.pendingKeysSet.forEach((v, k)=>this.pendingKeysSet.delete(k));
|
|
70
|
+
this.emit(true);
|
|
71
|
+
}
|
|
72
|
+
async resolveData(signal) {
|
|
73
|
+
let aborted = false;
|
|
74
|
+
if (!this.done) {
|
|
75
|
+
const onAbort = ()=>this.cancel();
|
|
76
|
+
signal.addEventListener('abort', onAbort);
|
|
77
|
+
aborted = await new Promise((resolve)=>{
|
|
78
|
+
this.subscribe((aborted)=>{
|
|
79
|
+
signal.removeEventListener('abort', onAbort);
|
|
80
|
+
if (aborted || this.done) resolve(aborted);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return aborted;
|
|
85
|
+
}
|
|
86
|
+
get done() {
|
|
87
|
+
return 0 === this.pendingKeysSet.size;
|
|
88
|
+
}
|
|
89
|
+
get unwrappedData() {
|
|
90
|
+
invariant(null !== this.data && this.done, 'Can only unwrap data on initialized and settled deferreds');
|
|
91
|
+
return Object.entries(this.data).reduce((acc, [key, value])=>Object.assign(acc, {
|
|
92
|
+
[key]: unwrapTrackedPromise(value)
|
|
93
|
+
}), {});
|
|
94
|
+
}
|
|
95
|
+
get pendingKeys() {
|
|
96
|
+
return Array.from(this.pendingKeysSet);
|
|
97
|
+
}
|
|
98
|
+
constructor(data, responseInit){
|
|
99
|
+
this.pendingKeysSet = new Set();
|
|
100
|
+
this.subscribers = new Set();
|
|
101
|
+
this.__modern_deferred = true;
|
|
102
|
+
this.deferredKeys = [];
|
|
103
|
+
invariant(data && 'object' == typeof data && !Array.isArray(data), 'defer() only accepts plain objects');
|
|
104
|
+
let reject;
|
|
105
|
+
this.abortPromise = new Promise((_, r)=>reject = r);
|
|
106
|
+
this.controller = new AbortController();
|
|
107
|
+
const onAbort = ()=>reject(new AbortedDeferredError('Deferred data aborted'));
|
|
108
|
+
this.unlistenAbortSignal = ()=>this.controller.signal.removeEventListener('abort', onAbort);
|
|
109
|
+
this.controller.signal.addEventListener('abort', onAbort);
|
|
110
|
+
this.data = Object.entries(data).reduce((acc, [key, value])=>Object.assign(acc, {
|
|
111
|
+
[key]: this.trackPromise(key, value)
|
|
112
|
+
}), {});
|
|
113
|
+
if (this.done) this.unlistenAbortSignal();
|
|
114
|
+
this.init = responseInit;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const activeDeferreds = new Map();
|
|
118
|
+
export { AbortedDeferredError, DeferredData, activeDeferreds, invariant };
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { LOADER_REPORTER_NAME } from "@modern-js/utils/universal/constants";
|
|
3
|
+
import { Suspense } from "react";
|
|
4
|
+
import { Outlet, Route, createRoutesFromElements } from "react-router";
|
|
5
|
+
import { time } from "../time.mjs";
|
|
6
|
+
import { getAsyncLocalStorage } from "../universal/async_storage.mjs";
|
|
7
|
+
import { DeferredData, activeDeferreds as external_deferreds_mjs_activeDeferreds } from "./deferreds.mjs";
|
|
8
|
+
const privateDefer = (data)=>new DeferredData(data);
|
|
9
|
+
const transformNestedRoutes = (routes)=>{
|
|
10
|
+
const routeElements = [];
|
|
11
|
+
for (const route of routes){
|
|
12
|
+
const routeElement = renderNestedRoute(route);
|
|
13
|
+
routeElements.push(routeElement);
|
|
14
|
+
}
|
|
15
|
+
return createRoutesFromElements(routeElements);
|
|
16
|
+
};
|
|
17
|
+
const renderNestedRoute = (nestedRoute, options = {})=>{
|
|
18
|
+
const { children, index, id, component, isRoot, lazyImport, config, handle } = nestedRoute;
|
|
19
|
+
const Component = component;
|
|
20
|
+
const { parent, props = {} } = options;
|
|
21
|
+
const routeProps = {
|
|
22
|
+
caseSensitive: nestedRoute.caseSensitive,
|
|
23
|
+
path: nestedRoute.path,
|
|
24
|
+
id: nestedRoute.id,
|
|
25
|
+
loader: createLoader(nestedRoute),
|
|
26
|
+
action: nestedRoute.action,
|
|
27
|
+
hasErrorBoundary: nestedRoute.hasErrorBoundary,
|
|
28
|
+
shouldRevalidate: nestedRoute.shouldRevalidate,
|
|
29
|
+
handle: {
|
|
30
|
+
...handle,
|
|
31
|
+
...'object' == typeof config ? config?.handle : {}
|
|
32
|
+
},
|
|
33
|
+
index: nestedRoute.index,
|
|
34
|
+
element: nestedRoute.element,
|
|
35
|
+
errorElement: nestedRoute.errorElement
|
|
36
|
+
};
|
|
37
|
+
if (nestedRoute.error) {
|
|
38
|
+
const errorElement = /*#__PURE__*/ jsx(nestedRoute.error, {});
|
|
39
|
+
routeProps.errorElement = errorElement;
|
|
40
|
+
}
|
|
41
|
+
let element;
|
|
42
|
+
if (Component) if (parent?.loading && lazyImport) {
|
|
43
|
+
const Loading = parent.loading;
|
|
44
|
+
element = isLoadableComponent(Component) ? /*#__PURE__*/ jsx(Component, {
|
|
45
|
+
fallback: /*#__PURE__*/ jsx(Loading, {})
|
|
46
|
+
}) : /*#__PURE__*/ jsx(Suspense, {
|
|
47
|
+
fallback: /*#__PURE__*/ jsx(Loading, {}),
|
|
48
|
+
children: /*#__PURE__*/ jsx(Component, {})
|
|
49
|
+
});
|
|
50
|
+
} else element = isLoadableComponent(Component) && lazyImport ? /*#__PURE__*/ jsx(Component, {}) : isRoot ? /*#__PURE__*/ jsx(Component, {
|
|
51
|
+
...props
|
|
52
|
+
}) : lazyImport ? /*#__PURE__*/ jsx(Suspense, {
|
|
53
|
+
fallback: null,
|
|
54
|
+
children: /*#__PURE__*/ jsx(Component, {})
|
|
55
|
+
}) : /*#__PURE__*/ jsx(Component, {});
|
|
56
|
+
else {
|
|
57
|
+
nestedRoute.loading = parent?.loading;
|
|
58
|
+
routeProps.element = /*#__PURE__*/ jsx(Outlet, {});
|
|
59
|
+
}
|
|
60
|
+
if (element) routeProps.element = element;
|
|
61
|
+
const childElements = children?.map((childRoute)=>renderNestedRoute(childRoute, {
|
|
62
|
+
parent: nestedRoute
|
|
63
|
+
}));
|
|
64
|
+
const routeElement = index ? /*#__PURE__*/ jsx(Route, {
|
|
65
|
+
...routeProps,
|
|
66
|
+
index: true
|
|
67
|
+
}, id) : /*#__PURE__*/ jsx(Route, {
|
|
68
|
+
...routeProps,
|
|
69
|
+
index: false,
|
|
70
|
+
children: childElements
|
|
71
|
+
}, id);
|
|
72
|
+
return routeElement;
|
|
73
|
+
};
|
|
74
|
+
function isPlainObject(value) {
|
|
75
|
+
return null != value && 'object' == typeof value && Object.getPrototypeOf(value) === Object.prototype;
|
|
76
|
+
}
|
|
77
|
+
function createLoader(route) {
|
|
78
|
+
const { loader } = route;
|
|
79
|
+
if (loader) return async (args)=>{
|
|
80
|
+
if ('function' == typeof route.lazyImport) route.lazyImport();
|
|
81
|
+
const end = time();
|
|
82
|
+
const res = await loader(args);
|
|
83
|
+
let activeDeferreds = null;
|
|
84
|
+
activeDeferreds = "u" < typeof document ? (await getAsyncLocalStorage())?.useContext()?.activeDeferreds : external_deferreds_mjs_activeDeferreds;
|
|
85
|
+
if (isPlainObject(res)) {
|
|
86
|
+
const deferredData = privateDefer(res);
|
|
87
|
+
activeDeferreds.set(route.id, deferredData);
|
|
88
|
+
}
|
|
89
|
+
const cost = end();
|
|
90
|
+
if ("u" < typeof document) {
|
|
91
|
+
const storage = await getAsyncLocalStorage();
|
|
92
|
+
storage?.useContext().monitors?.timing(`${LOADER_REPORTER_NAME}-${route.id?.replace(/\//g, '_')}`, cost);
|
|
93
|
+
}
|
|
94
|
+
return res;
|
|
95
|
+
};
|
|
96
|
+
return ()=>{
|
|
97
|
+
if ('function' == typeof route.lazyImport) route.lazyImport();
|
|
98
|
+
return null;
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function isLoadableComponent(component) {
|
|
102
|
+
return component && 'Loadable' === component.displayName && component.preload && 'function' == typeof component.preload;
|
|
103
|
+
}
|
|
104
|
+
export { renderNestedRoute, transformNestedRoutes };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
function isObject(obj) {
|
|
2
|
+
return obj && 'object' == typeof obj && !Array.isArray(obj);
|
|
3
|
+
}
|
|
4
|
+
function isComplexInstance(obj) {
|
|
5
|
+
if (!isObject(obj)) return false;
|
|
6
|
+
const hasMethods = 'function' == typeof obj.init || 'function' == typeof obj.changeLanguage || 'function' == typeof obj.t;
|
|
7
|
+
const hasInternalProps = void 0 !== obj.isInitialized || void 0 !== obj.language || void 0 !== obj.store;
|
|
8
|
+
return hasMethods || hasInternalProps;
|
|
9
|
+
}
|
|
10
|
+
function merge(target, ...sources) {
|
|
11
|
+
if (!sources.length) return target;
|
|
12
|
+
const source = sources.shift();
|
|
13
|
+
if (isObject(target) && isObject(source)) for(const key in source)if (isComplexInstance(source[key])) Object.assign(target, {
|
|
14
|
+
[key]: source[key]
|
|
15
|
+
});
|
|
16
|
+
else if (isObject(source[key])) {
|
|
17
|
+
if (!target[key]) Object.assign(target, {
|
|
18
|
+
[key]: {}
|
|
19
|
+
});
|
|
20
|
+
merge(target[key], source[key]);
|
|
21
|
+
} else Object.assign(target, {
|
|
22
|
+
[key]: source[key]
|
|
23
|
+
});
|
|
24
|
+
return merge(target, ...sources);
|
|
25
|
+
}
|
|
26
|
+
export { merge };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import fs_extra from "@modern-js/utils/fs-extra";
|
|
2
|
+
import { createMemoryStorage } from "./storer/index.mjs";
|
|
3
|
+
class FileReader {
|
|
4
|
+
async readFile(path, encoding = 'utf-8') {
|
|
5
|
+
const { fs } = this;
|
|
6
|
+
const _readfile = this._readFileFactory(fs);
|
|
7
|
+
return _readfile(path, encoding);
|
|
8
|
+
}
|
|
9
|
+
async readFileFromSystem(path, encoding = 'utf-8') {
|
|
10
|
+
const _readfile = this._readFileFactory(fs_extra);
|
|
11
|
+
return _readfile(path, encoding);
|
|
12
|
+
}
|
|
13
|
+
_readFileFactory(fs) {
|
|
14
|
+
return async (path, encoding = 'utf-8')=>{
|
|
15
|
+
const cache = await this.storage.get(path);
|
|
16
|
+
if (null === cache) return null;
|
|
17
|
+
if (cache) return this.encodingContent(cache, encoding);
|
|
18
|
+
const isExistFile = await new Promise((resolve)=>{
|
|
19
|
+
fs.stat(path, (err, stats)=>{
|
|
20
|
+
if (err) return void resolve(false);
|
|
21
|
+
stats.isFile() ? resolve(true) : resolve(false);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
if (isExistFile) {
|
|
25
|
+
const content = await fs.promises.readFile(path);
|
|
26
|
+
this.storage.set(path, content);
|
|
27
|
+
return this.encodingContent(content, encoding);
|
|
28
|
+
}
|
|
29
|
+
this.storage.set(path, null);
|
|
30
|
+
return null;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
reset(fs) {
|
|
34
|
+
fs && (this.fs = fs);
|
|
35
|
+
return this.storage.clear?.();
|
|
36
|
+
}
|
|
37
|
+
encodingContent(value, encoding) {
|
|
38
|
+
if ('utf-8' === encoding) return value.toString();
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
constructor(storage){
|
|
42
|
+
this.fs = fs_extra;
|
|
43
|
+
this.storage = storage;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const fileReader = new FileReader(createMemoryStorage('__file__system'));
|
|
47
|
+
export { FileReader, fileReader };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
class LoaderContext {
|
|
2
|
+
getDefaultValue() {
|
|
3
|
+
if (!this.defaultValue) throw new Error("Can't get defaultValue before initialed");
|
|
4
|
+
return this.defaultValue;
|
|
5
|
+
}
|
|
6
|
+
constructor(defaultValue){
|
|
7
|
+
this.defaultValue = defaultValue;
|
|
8
|
+
this.symbol = Symbol('loaderContext');
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function createLoaderContext(defaultValue) {
|
|
12
|
+
return new LoaderContext(defaultValue);
|
|
13
|
+
}
|
|
14
|
+
export { LoaderContext, createLoaderContext };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
function createRequestContext(context) {
|
|
2
|
+
const _context = context || new Map();
|
|
3
|
+
function get(key) {
|
|
4
|
+
if ('string' == typeof key) return _context.get(key);
|
|
5
|
+
return _context.get(key.symbol) || key.getDefaultValue();
|
|
6
|
+
}
|
|
7
|
+
function set(key, value) {
|
|
8
|
+
if ('string' == typeof key) _context.set(key, value);
|
|
9
|
+
else _context.set(key.symbol, value);
|
|
10
|
+
}
|
|
11
|
+
return {
|
|
12
|
+
set,
|
|
13
|
+
get
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export { createRequestContext };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { LRUCache } from "lru-cache";
|
|
2
|
+
class MemoryContainer {
|
|
3
|
+
async get(key) {
|
|
4
|
+
return this.cache.get(key);
|
|
5
|
+
}
|
|
6
|
+
async set(key, value) {
|
|
7
|
+
this.cache.set(key, value);
|
|
8
|
+
return this;
|
|
9
|
+
}
|
|
10
|
+
async has(key) {
|
|
11
|
+
return this.cache.has(key);
|
|
12
|
+
}
|
|
13
|
+
async delete(key) {
|
|
14
|
+
const exist = await this.has(key);
|
|
15
|
+
if (exist) this.cache.delete(key);
|
|
16
|
+
return exist;
|
|
17
|
+
}
|
|
18
|
+
forEach(callbackFn) {
|
|
19
|
+
this.cache.forEach((value, key)=>{
|
|
20
|
+
callbackFn(value, key, this);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
constructor({ max, maxAge } = {}){
|
|
24
|
+
this.cache = new LRUCache({
|
|
25
|
+
maxSize: (max || 256) * MemoryContainer.MB,
|
|
26
|
+
ttl: maxAge || MemoryContainer.hour,
|
|
27
|
+
sizeCalculation: (value, key)=>JSON.stringify(value).length
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
MemoryContainer.BYTE = 1;
|
|
32
|
+
MemoryContainer.KB = 1024 * MemoryContainer.BYTE;
|
|
33
|
+
MemoryContainer.MB = 1024 * MemoryContainer.KB;
|
|
34
|
+
MemoryContainer.ms = 1;
|
|
35
|
+
MemoryContainer.second = 1000 * MemoryContainer.ms;
|
|
36
|
+
MemoryContainer.minute = 60 * MemoryContainer.second;
|
|
37
|
+
MemoryContainer.hour = 60 * MemoryContainer.minute;
|
|
38
|
+
export { MemoryContainer };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { MemoryContainer } from "./container.mjs";
|
|
2
|
+
import { Storage } from "./storage.mjs";
|
|
3
|
+
const memoryContainer = new MemoryContainer();
|
|
4
|
+
function createMemoryStorage(namespace) {
|
|
5
|
+
return new Storage(namespace, memoryContainer);
|
|
6
|
+
}
|
|
7
|
+
export { Storage, createMemoryStorage };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
class Storage {
|
|
2
|
+
async keys() {
|
|
3
|
+
const _keys = [];
|
|
4
|
+
this.forEach?.((_, k)=>{
|
|
5
|
+
_keys.push(k);
|
|
6
|
+
});
|
|
7
|
+
return _keys;
|
|
8
|
+
}
|
|
9
|
+
async values() {
|
|
10
|
+
const _values = [];
|
|
11
|
+
this.forEach?.((v)=>{
|
|
12
|
+
_values.push(v);
|
|
13
|
+
});
|
|
14
|
+
return _values;
|
|
15
|
+
}
|
|
16
|
+
get(key) {
|
|
17
|
+
const uniqueKey = this.computedUniqueKey(key);
|
|
18
|
+
return this.container.get(uniqueKey);
|
|
19
|
+
}
|
|
20
|
+
async set(key, value) {
|
|
21
|
+
const uniqueKey = this.computedUniqueKey(key);
|
|
22
|
+
await this.container.set(uniqueKey, value);
|
|
23
|
+
return this;
|
|
24
|
+
}
|
|
25
|
+
has(key) {
|
|
26
|
+
const uniqueKey = this.computedUniqueKey(key);
|
|
27
|
+
return this.container.has(uniqueKey);
|
|
28
|
+
}
|
|
29
|
+
delete(key) {
|
|
30
|
+
const uniqueKey = this.computedUniqueKey(key);
|
|
31
|
+
return this.container.delete(uniqueKey);
|
|
32
|
+
}
|
|
33
|
+
async clear() {
|
|
34
|
+
const keys = await this.keys?.();
|
|
35
|
+
await Promise.all(keys?.map(async (key)=>this.container.delete(key)) || []);
|
|
36
|
+
}
|
|
37
|
+
forEach(fallbackFn) {
|
|
38
|
+
this.container.forEach?.((v, k)=>{
|
|
39
|
+
if (this.checkIsOwnkey(k)) fallbackFn(v, k, this);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
computedUniqueKey(k) {
|
|
43
|
+
return `${this.namespace}:${k}`;
|
|
44
|
+
}
|
|
45
|
+
checkIsOwnkey(k) {
|
|
46
|
+
return k.startsWith(this.namespace);
|
|
47
|
+
}
|
|
48
|
+
constructor(namespace, container){
|
|
49
|
+
this.namespace = namespace;
|
|
50
|
+
this.container = container;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export { Storage };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Stream } from "stream";
|
|
2
|
+
const createReadableStreamFromReadable = (source)=>{
|
|
3
|
+
const pump = new StreamPump(source);
|
|
4
|
+
const stream = new ReadableStream(pump, pump);
|
|
5
|
+
return stream;
|
|
6
|
+
};
|
|
7
|
+
class StreamPump {
|
|
8
|
+
size(chunk) {
|
|
9
|
+
return chunk?.byteLength || 0;
|
|
10
|
+
}
|
|
11
|
+
start(controller) {
|
|
12
|
+
this.controller = controller;
|
|
13
|
+
this.stream.on('data', this.enqueue);
|
|
14
|
+
this.stream.once('error', this.error);
|
|
15
|
+
this.stream.once('end', this.close);
|
|
16
|
+
this.stream.once('close', this.close);
|
|
17
|
+
}
|
|
18
|
+
pull() {
|
|
19
|
+
this.resume();
|
|
20
|
+
}
|
|
21
|
+
cancel(reason) {
|
|
22
|
+
if (this.stream.destroy) this.stream.destroy(reason);
|
|
23
|
+
process.nextTick(()=>{
|
|
24
|
+
this.stream.off('data', this.enqueue);
|
|
25
|
+
this.stream.off('error', this.error);
|
|
26
|
+
this.stream.off('end', this.close);
|
|
27
|
+
this.stream.off('close', this.close);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
enqueue(chunk) {
|
|
31
|
+
if (this.controller) try {
|
|
32
|
+
const bytes = chunk instanceof Uint8Array ? chunk : Buffer.from(chunk);
|
|
33
|
+
const available = (this.controller.desiredSize || 0) - bytes.byteLength;
|
|
34
|
+
this.controller.enqueue(bytes);
|
|
35
|
+
if (available <= 0) this.pause();
|
|
36
|
+
} catch (error) {
|
|
37
|
+
this.controller.error(new Error('Could not create Buffer, chunk must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object'));
|
|
38
|
+
this.cancel();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
pause() {
|
|
42
|
+
if (this.stream.pause) this.stream.pause();
|
|
43
|
+
}
|
|
44
|
+
resume() {
|
|
45
|
+
if (this.stream.readable && this.stream.resume) this.stream.resume();
|
|
46
|
+
}
|
|
47
|
+
close() {
|
|
48
|
+
if (this.controller) {
|
|
49
|
+
this.controller.close();
|
|
50
|
+
delete this.controller;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
error(error) {
|
|
54
|
+
if (this.controller) {
|
|
55
|
+
this.controller.error(error);
|
|
56
|
+
delete this.controller;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
constructor(stream){
|
|
60
|
+
this.highWaterMark = stream.readableHighWaterMark || new Stream.Readable().readableHighWaterMark;
|
|
61
|
+
this.accumalatedSize = 0;
|
|
62
|
+
this.stream = stream;
|
|
63
|
+
this.enqueue = this.enqueue.bind(this);
|
|
64
|
+
this.error = this.error.bind(this);
|
|
65
|
+
this.close = this.close.bind(this);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export { createReadableStreamFromReadable };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const parsedJSONFromElement = (id)=>{
|
|
2
|
+
const elements = document.querySelectorAll(`#${id}`);
|
|
3
|
+
if (0 === elements.length) return;
|
|
4
|
+
const element = elements[elements.length - 1];
|
|
5
|
+
if (element) try {
|
|
6
|
+
const parsed = JSON.parse(element?.textContent || '');
|
|
7
|
+
return parsed;
|
|
8
|
+
} catch (e) {
|
|
9
|
+
console.error(`parse ${id} error`, e);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
export { parsedJSONFromElement };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export * from "react-router";
|
|
2
|
+
const DEFERRED_SYMBOL = Symbol('deferred');
|
|
3
|
+
const json = (data, init)=>{
|
|
4
|
+
const responseInit = init ? 'number' == typeof init ? {
|
|
5
|
+
status: init
|
|
6
|
+
} : init : void 0;
|
|
7
|
+
return new Response(JSON.stringify(data), responseInit);
|
|
8
|
+
};
|
|
9
|
+
const defer = (data, init)=>{
|
|
10
|
+
if (void 0 === init) return data;
|
|
11
|
+
{
|
|
12
|
+
const responseInit = init ? 'number' == typeof init ? {
|
|
13
|
+
status: init
|
|
14
|
+
} : init : void 0;
|
|
15
|
+
return new Response(JSON.stringify(data), responseInit);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
export { DEFERRED_SYMBOL, defer, json };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "react-router";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./nestedRoutes.mjs";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
function sortByUrlPath(entries) {
|
|
2
|
+
entries.sort(function(a, b) {
|
|
3
|
+
const length1 = a.urlPath.length;
|
|
4
|
+
const length2 = b.urlPath.length;
|
|
5
|
+
if (length1 < length2) return 1;
|
|
6
|
+
if (length1 > length2) return -1;
|
|
7
|
+
return 0;
|
|
8
|
+
});
|
|
9
|
+
return entries;
|
|
10
|
+
}
|
|
11
|
+
const matchEntry = (pathname, entries)=>{
|
|
12
|
+
sortByUrlPath(entries);
|
|
13
|
+
return entries.find((entry)=>pathname.startsWith(entry.urlPath));
|
|
14
|
+
};
|
|
15
|
+
export { matchEntry };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
function processHrtime(previousTimestamp) {
|
|
2
|
+
const now = new Date().getTime();
|
|
3
|
+
const clocktime = 1e-3 * now;
|
|
4
|
+
let seconds = Math.floor(clocktime);
|
|
5
|
+
let nanoseconds = Math.floor(clocktime % 1 * 1e9);
|
|
6
|
+
if (previousTimestamp) {
|
|
7
|
+
seconds -= previousTimestamp[0];
|
|
8
|
+
nanoseconds -= previousTimestamp[1];
|
|
9
|
+
if (nanoseconds < 0) {
|
|
10
|
+
seconds--;
|
|
11
|
+
nanoseconds += 1e9;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return [
|
|
15
|
+
seconds,
|
|
16
|
+
nanoseconds
|
|
17
|
+
];
|
|
18
|
+
}
|
|
19
|
+
const getLatency = (hrtime)=>{
|
|
20
|
+
const [s, ns] = processHrtime(hrtime);
|
|
21
|
+
return 1e3 * s + ns / 1e6;
|
|
22
|
+
};
|
|
23
|
+
const time = ()=>{
|
|
24
|
+
const hrtime = processHrtime();
|
|
25
|
+
return ()=>getLatency(hrtime);
|
|
26
|
+
};
|
|
27
|
+
export { time };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const isBrowser = "u" > typeof window && void 0 !== window.document;
|
|
2
|
+
const IS_WEB_FALLBACK = "u" > typeof IS_WEB ? IS_WEB : isBrowser;
|
|
3
|
+
const getAsyncLocalStorage = async ()=>{
|
|
4
|
+
if (isBrowser) {
|
|
5
|
+
console.error('You should not get async storage in browser');
|
|
6
|
+
return null;
|
|
7
|
+
}
|
|
8
|
+
if (!IS_WEB_FALLBACK) try {
|
|
9
|
+
const serverStorage = await import("./async_storage.server.mjs");
|
|
10
|
+
return serverStorage.getAsyncLocalStorage();
|
|
11
|
+
} catch (extensionError) {
|
|
12
|
+
try {
|
|
13
|
+
const serverStorage = await import("./async_storage.server");
|
|
14
|
+
return serverStorage.getAsyncLocalStorage();
|
|
15
|
+
} catch (fallbackError) {
|
|
16
|
+
console.error('Failed to load server async storage', {
|
|
17
|
+
extensionError: extensionError instanceof Error ? extensionError.message : extensionError,
|
|
18
|
+
fallbackError: fallbackError instanceof Error ? fallbackError.message : fallbackError
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
};
|
|
24
|
+
export { getAsyncLocalStorage };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
2
|
+
const createStorage = ()=>{
|
|
3
|
+
let storage;
|
|
4
|
+
if (void 0 !== AsyncLocalStorage) storage = new AsyncLocalStorage();
|
|
5
|
+
const run = (context, cb)=>{
|
|
6
|
+
if (!storage) throw new Error(`Unable to use async_hook, please confirm the node version >= 12.17
|
|
7
|
+
`);
|
|
8
|
+
return new Promise((resolve, reject)=>{
|
|
9
|
+
storage.run(context, ()=>{
|
|
10
|
+
try {
|
|
11
|
+
return resolve(cb());
|
|
12
|
+
} catch (error) {
|
|
13
|
+
return reject(error);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
const useContext = ()=>{
|
|
19
|
+
if (!storage) throw new Error(`Unable to use async_hook, please confirm the node version >= 12.17
|
|
20
|
+
`);
|
|
21
|
+
const context = storage?.getStore();
|
|
22
|
+
if (!context) throw new Error("Can't call useContext out of scope, make sure @modern-js/runtime-utils is a single version in node_modules");
|
|
23
|
+
return context;
|
|
24
|
+
};
|
|
25
|
+
return {
|
|
26
|
+
run,
|
|
27
|
+
useContext
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
const async_storage_server_storage = createStorage();
|
|
31
|
+
const getAsyncLocalStorage = async ()=>async_storage_server_storage;
|
|
32
|
+
export { getAsyncLocalStorage, async_storage_server_storage as storage };
|