@modern-js/main-doc 0.0.0-nightly-20250302160335 → 0.0.0-nightly-20250303160335
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
["data-fetch", "data-write"]
|
|
1
|
+
["data-fetch", "data-write", "data-cache"]
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Data Caching
|
|
3
|
+
sidebar_position: 4
|
|
4
|
+
---
|
|
5
|
+
# Data Caching
|
|
6
|
+
|
|
7
|
+
The `cache` function allows you to cache the results of data fetching or computation.
|
|
8
|
+
|
|
9
|
+
## Basic Usage
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { cache } from '@modern-js/runtime/cache';
|
|
13
|
+
import { fetchUserData } from './api';
|
|
14
|
+
|
|
15
|
+
const getUser = cache(fetchUserData);
|
|
16
|
+
|
|
17
|
+
const loader = async () => {
|
|
18
|
+
const user = await getUser(user); // When the parameters of the function changes, the function will be re-executed
|
|
19
|
+
return {
|
|
20
|
+
user,
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
### Parameters
|
|
27
|
+
|
|
28
|
+
- `fn`: The data fetching or computation function to be cached
|
|
29
|
+
- `options` (optional): Cache configuration
|
|
30
|
+
- `tag`: Tag to identify the cache, which can be used to invalidate the cache
|
|
31
|
+
- `maxAge`: Cache validity period (milliseconds)
|
|
32
|
+
- `revalidate`: Time window for revalidating the cache (milliseconds), similar to HTTP Cache-Control's stale-while-revalidate functionality
|
|
33
|
+
|
|
34
|
+
The type of the `options` parameter is as follows:
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
interface CacheOptions {
|
|
38
|
+
tag?: string | string[];
|
|
39
|
+
maxAge?: number;
|
|
40
|
+
revalidate?: number;
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
### Return Value
|
|
46
|
+
|
|
47
|
+
The `cache` function returns a new function with caching capabilities. Multiple calls to this function will not re-execute the `fn` function.
|
|
48
|
+
|
|
49
|
+
## Usage Scope
|
|
50
|
+
|
|
51
|
+
Unlike React's [cache](https://react.dev/reference/react/cache) function which can only be used in server components,
|
|
52
|
+
EdenX's `cache` function can be used in any frontend or server-side code.
|
|
53
|
+
|
|
54
|
+
## Detailed Usage
|
|
55
|
+
|
|
56
|
+
### Without `options` Parameter
|
|
57
|
+
|
|
58
|
+
When no `options` parameter is provided, it's primarily useful in SSR projects, the cache lifecycle is limited to a single SSR rendering request. For example, when the same cachedFn is called in multiple data loaders, the cachedFn function won't be executed repeatedly. This allows data sharing between different data loaders while avoiding duplicate requests. EdenX will re-execute the `fn` function with each server request.
|
|
59
|
+
|
|
60
|
+
:::info
|
|
61
|
+
Without the `options` parameter, it can be considered a replacement for React's [`cache`](https://react.dev/reference/react/cache) function and can be used in any server-side code (such as in data loaders of SSR projects), not limited to server components.
|
|
62
|
+
:::
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
import { cache } from '@modern-js/runtime/cache';
|
|
66
|
+
import { fetchUserData } from './api';
|
|
67
|
+
|
|
68
|
+
const getUser = cache(fetchUserData);
|
|
69
|
+
|
|
70
|
+
const loader = async () => {
|
|
71
|
+
const user = await getUser();
|
|
72
|
+
return {
|
|
73
|
+
user,
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
### With `options` Parameter
|
|
80
|
+
|
|
81
|
+
#### `maxAge` Parameter
|
|
82
|
+
|
|
83
|
+
After each computation, the framework records the time when the cache is written.
|
|
84
|
+
When the function is called again, it checks if the cache has expired based on the `maxAge` parameter.
|
|
85
|
+
If expired, the `fn` function is re-executed; otherwise, the cached data is returned.
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
import { cache, CacheTime } from '@modern-js/runtime/cache';
|
|
89
|
+
|
|
90
|
+
const getDashboardStats = cache(
|
|
91
|
+
async () => {
|
|
92
|
+
return await fetchComplexStatistics();
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
maxAge: CacheTime.MINUTE * 2, // Calling this function within 2 minutes will return cached data
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
#### `revalidate` Parameter
|
|
102
|
+
|
|
103
|
+
The `revalidate` parameter sets a time window for revalidating the cache after it expires. It can be used together with the `maxAge` parameter, similar to HTTP Cache-Control's stale-while-revalidate mode.
|
|
104
|
+
|
|
105
|
+
In the following example, within the 2-minute period before the cache expires, calls to `getDashboardStats` will return cached data. If the cache has expired (between 2 and 3 minutes), requests will first return the old data, then refresh the data in the background and update the cache.
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
import { cache, CacheTime } from '@modern-js/runtime/cache';
|
|
109
|
+
|
|
110
|
+
const getDashboardStats = cache(
|
|
111
|
+
async () => {
|
|
112
|
+
return await fetchComplexStatistics();
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
maxAge: CacheTime.MINUTE * 2,
|
|
116
|
+
revalidate: CacheTime.MINUTE * 1,
|
|
117
|
+
}
|
|
118
|
+
);
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
#### `tag` Parameter
|
|
123
|
+
|
|
124
|
+
The `tag` parameter identifies the cache with a tag, which can be a string or an array of strings.
|
|
125
|
+
You can invalidate caches based on this tag, and multiple cache functions can use the same tag.
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
import { cache, revalidateTag } from '@modern-js/runtime/cache';
|
|
129
|
+
|
|
130
|
+
const getDashboardStats = cache(
|
|
131
|
+
async () => {
|
|
132
|
+
return await fetchDashboardStats();
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
tag: 'dashboard',
|
|
136
|
+
}
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
const getComplexStatistics = cache(
|
|
140
|
+
async () => {
|
|
141
|
+
return await fetchComplexStatistics();
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
tag: 'dashboard',
|
|
145
|
+
}
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
revalidateTag('dashboard-stats'); // Invalidates the cache for both getDashboardStats and getComplexStatistics functions
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
### Storage
|
|
153
|
+
|
|
154
|
+
Currently, both client and server caches are stored in memory.
|
|
155
|
+
The default storage limit for all cached functions is 1GB. When this limit is reached, the oldest cache is removed using an LRU algorithm.
|
|
156
|
+
|
|
157
|
+
:::info
|
|
158
|
+
Considering that the results of `cache` function caching are not large, they are currently stored in memory by default.
|
|
159
|
+
:::
|
|
160
|
+
|
|
161
|
+
You can specify the storage limit using the `configureCache` function:
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
import { configureCache, CacheSize } from '@modern-js/runtime/cache';
|
|
165
|
+
|
|
166
|
+
configureCache({
|
|
167
|
+
maxSize: CacheSize.MB * 10, // 10MB
|
|
168
|
+
});
|
|
169
|
+
```
|
|
@@ -1 +1 @@
|
|
|
1
|
-
["data-fetch", "data-write"]
|
|
1
|
+
["data-fetch", "data-write", "data-cache"]
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 数据缓存
|
|
3
|
+
sidebar_position: 4
|
|
4
|
+
---
|
|
5
|
+
# 数据缓存
|
|
6
|
+
|
|
7
|
+
`cache` 函数可以让你缓存数据获取或计算的结果。
|
|
8
|
+
|
|
9
|
+
## 基本用法
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { cache } from '@modern-js/runtime/cache';
|
|
13
|
+
import { fetchUserData } from './api';
|
|
14
|
+
|
|
15
|
+
const getUser = cache(fetchUserData);
|
|
16
|
+
|
|
17
|
+
const loader = async () => {
|
|
18
|
+
const user = await getUser(user); // 函数入参发生变化时,函数会重新执行
|
|
19
|
+
return {
|
|
20
|
+
user,
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### 参数
|
|
26
|
+
|
|
27
|
+
- `fn`: 需要缓存的数据获取或计算的函数
|
|
28
|
+
- `options`(可选): 缓存配置
|
|
29
|
+
- `tag`: 用于标识缓存的标签,可以基于这个标签使缓存失效
|
|
30
|
+
- `maxAge`: 缓存的有效期 (毫秒)
|
|
31
|
+
- `revalidate`: 重新验证缓存的时间窗口(毫秒),与 HTTP Cache-Control 的 stale-while-revalidate 功能一致
|
|
32
|
+
|
|
33
|
+
`options` 参数的类型如下:
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
interface CacheOptions {
|
|
37
|
+
tag?: string | string[];
|
|
38
|
+
maxAge?: number;
|
|
39
|
+
revalidate?: number;
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 返回值
|
|
44
|
+
|
|
45
|
+
`cache` 函数会返回一个新的函数,该函数有缓存的能力,多次调用该函数,不会重复执行 `fn` 函数。
|
|
46
|
+
|
|
47
|
+
## 使用范围
|
|
48
|
+
|
|
49
|
+
与 react 的 [cache](https://react.dev/reference/react/cache) 函数只能在 server component 组件中使用不同,
|
|
50
|
+
EdenX 提供的 `cache` 函数可以在任意的前端或服务端的代码中使用。
|
|
51
|
+
|
|
52
|
+
## 详细用法
|
|
53
|
+
|
|
54
|
+
### 无 `options` 参数
|
|
55
|
+
|
|
56
|
+
当无 `options` 参数传入时,主要可以用于 SSR 项目,缓存的生命周期是单次 ssr 渲染的请求,如可以在多个 data loader 中调用同一个 cachedFn 时,不会重复执行 cachedFn 函数。这样可以在不同的 data loader 中共享数据,同时避免重复的请求,EdenX 会在每次收到服务端请求时,重新执行 `fn` 函数。
|
|
57
|
+
|
|
58
|
+
:::info
|
|
59
|
+
无 `options` 参数时,可以看作是 react [`cache`](https://react.dev/reference/react/cache) 函数的替代品,可以在任意服务端代码中使用(比如可以在 SSR 项目的 data loader 中),不局限于 server component。
|
|
60
|
+
:::
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
import { cache } from '@modern-js/runtime/cache';
|
|
65
|
+
import { fetchUserData } from './api';
|
|
66
|
+
|
|
67
|
+
const getUser = cache(fetchUserData);
|
|
68
|
+
|
|
69
|
+
const loader = async () => {
|
|
70
|
+
const user = await getUser();
|
|
71
|
+
return {
|
|
72
|
+
user,
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 有 `options` 参数
|
|
78
|
+
|
|
79
|
+
#### `maxAge` 参数
|
|
80
|
+
|
|
81
|
+
每次计算完成后,框架会记录写入缓存的时间,当再次调用该函数时,会根据 `maxAge` 参数判断缓存是否过期,如果过期,则重新执行 `fn` 函数,否则返回缓存的数据。
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
import { cache, CacheTime } from '@modern-js/runtime/cache';
|
|
85
|
+
|
|
86
|
+
const getDashboardStats = cache(
|
|
87
|
+
async () => {
|
|
88
|
+
return await fetchComplexStatistics();
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
maxAge: CacheTime.MINUTE * 2, // 在 2 分钟内调用该函数会返回缓存的数据
|
|
92
|
+
}
|
|
93
|
+
);
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
#### `revalidate` 参数
|
|
97
|
+
|
|
98
|
+
`revalidate` 参数用于设置缓存过期后,重新验证缓存的时间窗口,可以和 `maxAge` 参数一起使用,类似与 HTTP Cache-Control 的 stale-while-revalidate 模式。
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
如以下示例,在缓存未过期的 2分钟内,如果调用 `getDashboardStats` 函数,会返回缓存的数据,如果缓存过期,2分到3分钟内,收到的请求会先返回旧数据,然后后台会重新请求数据,并更新缓存。
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
import { cache, CacheTime } from '@modern-js/runtime/cache';
|
|
105
|
+
|
|
106
|
+
const getDashboardStats = cache(
|
|
107
|
+
async () => {
|
|
108
|
+
return await fetchComplexStatistics();
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
maxAge: CacheTime.MINUTE * 2,
|
|
112
|
+
revalidate: CacheTime.MINUTE * 1,
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
#### `tag` 参数
|
|
118
|
+
|
|
119
|
+
`tag` 参数用于标识缓存的标签,可以传入一个字符串或字符串数组,可以基于这个标签使缓存失效,多个缓存函数可以使用一个标签。
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
import { cache, revalidateTag } from '@modern-js/runtime/cache';
|
|
123
|
+
|
|
124
|
+
const getDashboardStats = cache(
|
|
125
|
+
async () => {
|
|
126
|
+
return await fetchDashboardStats();
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
tag: 'dashboard',
|
|
130
|
+
}
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
const getComplexStatistics = cache(
|
|
134
|
+
async () => {
|
|
135
|
+
return await fetchComplexStatistics();
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
tag: 'dashboard',
|
|
139
|
+
}
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
revalidateTag('dashboard-stats'); // 会使 getDashboardStats 函数和 getComplexStatistics 函数的缓存都失效
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
### 存储
|
|
147
|
+
|
|
148
|
+
目前不管是客户端还是服务端,缓存都存储在内存中,默认情况下所有缓存函数共享的存储上限是 1GB,当达到存储上限后,使用 LRU 算法移除旧的缓存。
|
|
149
|
+
|
|
150
|
+
:::info
|
|
151
|
+
考虑到 `cache` 函数缓存的结果内容不会很大,所以目前默认都存储在内存中
|
|
152
|
+
:::
|
|
153
|
+
|
|
154
|
+
可以通过 `configureCache` 函数指定缓存的存储上限:
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
import { configureCache, CacheSize } from '@modern-js/runtime/cache';
|
|
158
|
+
|
|
159
|
+
configureCache({
|
|
160
|
+
maxSize: CacheSize.MB * 10, // 10MB
|
|
161
|
+
});
|
|
162
|
+
```
|
package/package.json
CHANGED
|
@@ -15,14 +15,14 @@
|
|
|
15
15
|
"modern",
|
|
16
16
|
"modern.js"
|
|
17
17
|
],
|
|
18
|
-
"version": "0.0.0-nightly-
|
|
18
|
+
"version": "0.0.0-nightly-20250303160335",
|
|
19
19
|
"publishConfig": {
|
|
20
20
|
"registry": "https://registry.npmjs.org/",
|
|
21
21
|
"access": "public",
|
|
22
22
|
"provenance": true
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@modern-js/sandpack-react": "0.0.0-nightly-
|
|
25
|
+
"@modern-js/sandpack-react": "0.0.0-nightly-20250303160335"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@rspress/shared": "1.42.0",
|