@esmx/core 3.0.0-rc.60 → 3.0.0-rc.62
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/app.d.ts +27 -27
- package/dist/core.d.ts +274 -272
- package/dist/core.mjs +233 -231
- package/dist/pack-config.d.ts +92 -92
- package/dist/render-context.d.ts +465 -465
- package/dist/render-context.mjs +338 -338
- package/dist/utils/cache.d.ts +15 -15
- package/dist/utils/middleware.d.ts +19 -19
- package/dist/utils/static-import-lexer.d.ts +12 -12
- package/dist/utils/static-import-lexer.mjs +1 -1
- package/package.json +3 -3
- package/src/app.ts +34 -34
- package/src/core.ts +318 -316
- package/src/pack-config.ts +92 -92
- package/src/render-context.ts +465 -465
- package/src/utils/cache.ts +15 -15
- package/src/utils/middleware.ts +19 -19
- package/src/utils/static-import-lexer.ts +18 -18
package/src/utils/cache.ts
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Type definition for cache handling function
|
|
3
3
|
*
|
|
4
|
-
* @template T -
|
|
5
|
-
* @param name -
|
|
6
|
-
* @param fetch -
|
|
7
|
-
* @returns
|
|
4
|
+
* @template T - Type of cached data
|
|
5
|
+
* @param name - Unique identifier for the cache item
|
|
6
|
+
* @param fetch - Asynchronous function to fetch data
|
|
7
|
+
* @returns Returns cached data or newly fetched data
|
|
8
8
|
*
|
|
9
9
|
* @example
|
|
10
10
|
* ```ts
|
|
11
11
|
* const cache = createCache(true);
|
|
12
12
|
*
|
|
13
|
-
* //
|
|
13
|
+
* // First call will execute the fetch function
|
|
14
14
|
* const data1 = await cache('key', async () => {
|
|
15
15
|
* return await fetchSomeData();
|
|
16
16
|
* });
|
|
17
17
|
*
|
|
18
|
-
* //
|
|
18
|
+
* // Second call will directly return the cached result
|
|
19
19
|
* const data2 = await cache('key', async () => {
|
|
20
20
|
* return await fetchSomeData();
|
|
21
21
|
* });
|
|
@@ -27,24 +27,24 @@ export type CacheHandle = <T>(
|
|
|
27
27
|
) => Promise<T>;
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
30
|
+
* Create a cache handling function
|
|
31
31
|
*
|
|
32
|
-
* @param enable -
|
|
33
|
-
* @returns
|
|
32
|
+
* @param enable - Whether to enable caching functionality
|
|
33
|
+
* @returns Returns a cache handling function
|
|
34
34
|
*
|
|
35
35
|
* @description
|
|
36
|
-
*
|
|
37
|
-
*
|
|
36
|
+
* When enable is true, it creates a processing function with memory cache, the same name will only execute fetch once.
|
|
37
|
+
* When enable is false, each call will execute the fetch function and will not cache the result.
|
|
38
38
|
*
|
|
39
39
|
* @example
|
|
40
40
|
* ```ts
|
|
41
|
-
* //
|
|
41
|
+
* // Create a cache-enabled processing function
|
|
42
42
|
* const cacheEnabled = createCache(true);
|
|
43
43
|
*
|
|
44
|
-
* //
|
|
44
|
+
* // Create a cache-disabled processing function
|
|
45
45
|
* const cacheDisabled = createCache(false);
|
|
46
46
|
*
|
|
47
|
-
* //
|
|
47
|
+
* // Use the cache processing function
|
|
48
48
|
* const result = await cacheEnabled('userProfile', async () => {
|
|
49
49
|
* return await fetchUserProfile(userId);
|
|
50
50
|
* });
|
package/src/utils/middleware.ts
CHANGED
|
@@ -4,18 +4,18 @@ import send from 'send';
|
|
|
4
4
|
import type { Esmx } from '../core';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* Middleware function type definition
|
|
8
8
|
*
|
|
9
9
|
* @description
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* -
|
|
13
|
-
* -
|
|
14
|
-
* -
|
|
10
|
+
* Middleware is a function used to handle HTTP requests. It receives the request object, response object, and the next middleware function as parameters.
|
|
11
|
+
* Middleware can perform the following operations:
|
|
12
|
+
* - Modify request and response objects
|
|
13
|
+
* - End the request-response cycle
|
|
14
|
+
* - Call the next middleware
|
|
15
15
|
*
|
|
16
16
|
* @example
|
|
17
17
|
* ```ts
|
|
18
|
-
* //
|
|
18
|
+
* // Create a simple logging middleware
|
|
19
19
|
* const loggerMiddleware: Middleware = (req, res, next) => {
|
|
20
20
|
* console.log(`${req.method} ${req.url}`);
|
|
21
21
|
* next();
|
|
@@ -30,24 +30,24 @@ export type Middleware = (
|
|
|
30
30
|
|
|
31
31
|
const reFinal = /\.final\.[a-zA-Z0-9]+$/;
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
34
|
-
* @param path
|
|
33
|
+
* Determine if a file path is an immutable file that complies with esmx specifications
|
|
34
|
+
* @param path File path
|
|
35
35
|
*/
|
|
36
36
|
export function isImmutableFile(filename: string) {
|
|
37
37
|
return reFinal.test(filename);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
|
-
*
|
|
41
|
+
* Create middleware for Esmx application
|
|
42
42
|
*
|
|
43
|
-
* @param esmx - Esmx
|
|
44
|
-
* @returns
|
|
43
|
+
* @param esmx - Esmx instance
|
|
44
|
+
* @returns Returns a middleware that handles static resources
|
|
45
45
|
*
|
|
46
46
|
* @description
|
|
47
|
-
*
|
|
48
|
-
* -
|
|
49
|
-
* -
|
|
50
|
-
* -
|
|
47
|
+
* This function creates a middleware to handle static resource requests for modules. It will:
|
|
48
|
+
* - Create corresponding static resource middleware based on module configuration
|
|
49
|
+
* - Handle cache control for resources
|
|
50
|
+
* - Support long-term caching for immutable files
|
|
51
51
|
*
|
|
52
52
|
* @example
|
|
53
53
|
* ```ts
|
|
@@ -56,7 +56,7 @@ export function isImmutableFile(filename: string) {
|
|
|
56
56
|
* const esmx = new Esmx();
|
|
57
57
|
* const middleware = createMiddleware(esmx);
|
|
58
58
|
*
|
|
59
|
-
* //
|
|
59
|
+
* // Use in HTTP server
|
|
60
60
|
* server.use(middleware);
|
|
61
61
|
* ```
|
|
62
62
|
*/
|
|
@@ -96,8 +96,8 @@ export function createMiddleware(esmx: Esmx): Middleware {
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
|
-
*
|
|
100
|
-
* @param middlewares
|
|
99
|
+
* Merge multiple middlewares into one middleware execution
|
|
100
|
+
* @param middlewares List of middlewares
|
|
101
101
|
* @returns
|
|
102
102
|
*/
|
|
103
103
|
export function mergeMiddlewares(middlewares: Middleware[]): Middleware {
|
|
@@ -7,23 +7,23 @@ import type { ParsedModuleConfig } from '../module-config';
|
|
|
7
7
|
import * as esmLexer from 'es-module-lexer';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
11
|
-
* @param code
|
|
12
|
-
* @returns `Promise<string[]>`
|
|
10
|
+
* Get the list of statically imported module names from JS code. Maybe cannot handle multiple concurrent calls, not tested.
|
|
11
|
+
* @param code JS code
|
|
12
|
+
* @returns `Promise<string[]>` List of statically imported module names
|
|
13
13
|
*/
|
|
14
14
|
export async function getImportsFromJsCode(code: string): Promise<string[]> {
|
|
15
15
|
await esmLexer.init;
|
|
16
16
|
const [imports] = esmLexer.parse(code);
|
|
17
|
-
//
|
|
17
|
+
// Static import && has module name
|
|
18
18
|
return imports
|
|
19
19
|
.filter((item) => item.t === 1 && item.n)
|
|
20
20
|
.map((item) => item.n as string);
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
25
|
-
* @param filepath
|
|
26
|
-
* @returns `Promise<string[]>`
|
|
24
|
+
* Get the list of statically imported module names from a JS file.
|
|
25
|
+
* @param filepath JS file path
|
|
26
|
+
* @returns `Promise<string[]>` List of statically imported module names
|
|
27
27
|
*/
|
|
28
28
|
export async function getImportsFromJsFile(
|
|
29
29
|
filepath: fs.PathLike | fs.promises.FileHandle
|
|
@@ -34,13 +34,13 @@ export async function getImportsFromJsFile(
|
|
|
34
34
|
|
|
35
35
|
export type ImportPreloadInfo = SpecifierMap;
|
|
36
36
|
/**
|
|
37
|
-
*
|
|
38
|
-
* @param specifier
|
|
39
|
-
* @param importMap
|
|
40
|
-
* @param moduleConfig
|
|
37
|
+
* Get import preload information.
|
|
38
|
+
* @param specifier Module name
|
|
39
|
+
* @param importMap Import map object
|
|
40
|
+
* @param moduleConfig Module configuration
|
|
41
41
|
* @returns
|
|
42
|
-
* - `Promise<{ [specifier: string]: ImportPreloadPathString }>`
|
|
43
|
-
* - `null` specifier
|
|
42
|
+
* - `Promise<{ [specifier: string]: ImportPreloadPathString }>` Mapping object of module names to file paths
|
|
43
|
+
* - `null` specifier does not exist
|
|
44
44
|
*/
|
|
45
45
|
export async function getImportPreloadInfo(
|
|
46
46
|
specifier: string,
|
|
@@ -53,18 +53,18 @@ export async function getImportPreloadInfo(
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
const ans: ImportPreloadInfo = {
|
|
56
|
-
//
|
|
56
|
+
// Entry file is also added to the preload list
|
|
57
57
|
[specifier]: importInfo[specifier]
|
|
58
58
|
};
|
|
59
59
|
|
|
60
|
-
//
|
|
60
|
+
// Lexical analysis is a time-consuming operation, so the fewer files processed, the faster, in other words, the shallower the depth, the faster, so breadth-first search is used here
|
|
61
61
|
const needHandles: string[] = [specifier];
|
|
62
62
|
while (needHandles.length) {
|
|
63
63
|
const specifier = needHandles.shift()!;
|
|
64
64
|
let filepath = importInfo[specifier];
|
|
65
65
|
const splitRes = filepath.split('/');
|
|
66
66
|
if (splitRes[0] === '') splitRes.shift();
|
|
67
|
-
//
|
|
67
|
+
// Here it is assumed that the first directory in the path is the soft package name
|
|
68
68
|
const name = splitRes.shift() + '';
|
|
69
69
|
const link = moduleConfig.links[name];
|
|
70
70
|
if (!link) {
|
|
@@ -73,13 +73,13 @@ export async function getImportPreloadInfo(
|
|
|
73
73
|
filepath = path.join(link.client, ...splitRes);
|
|
74
74
|
const imports = await getImportsFromJsFile(filepath);
|
|
75
75
|
for (const specifier of imports) {
|
|
76
|
-
//
|
|
76
|
+
// If the module name does not exist in importMap or has been processed
|
|
77
77
|
if (!(specifier in importInfo) || specifier in ans) continue;
|
|
78
78
|
ans[specifier] = importInfo[specifier];
|
|
79
79
|
needHandles.push(specifier);
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
//
|
|
83
|
+
// Reverse order, theoretically browser parsing may be faster after reversing
|
|
84
84
|
return Object.fromEntries(Object.entries(ans).reverse());
|
|
85
85
|
}
|