@modern-js/runtime-utils 2.67.3 → 2.67.5

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.
@@ -19,14 +19,14 @@ let lruCache;
19
19
  let cacheConfig = {
20
20
  maxSize: CacheSize.GB
21
21
  };
22
- const tagFnMap = /* @__PURE__ */ new Map();
23
- function addTagFnRelation(tag, fn) {
24
- let fns = tagFnMap.get(tag);
25
- if (!fns) {
26
- fns = /* @__PURE__ */ new Set();
27
- tagFnMap.set(tag, fns);
22
+ const tagKeyMap = /* @__PURE__ */ new Map();
23
+ function addTagKeyRelation(tag, key) {
24
+ let keys = tagKeyMap.get(tag);
25
+ if (!keys) {
26
+ keys = /* @__PURE__ */ new Set();
27
+ tagKeyMap.set(tag, keys);
28
28
  }
29
- fns.add(fn);
29
+ keys.add(key);
30
30
  }
31
31
  function configureCache(config) {
32
32
  cacheConfig = {
@@ -36,8 +36,9 @@ function configureCache(config) {
36
36
  }
37
37
  function getLRUCache() {
38
38
  if (!lruCache) {
39
+ var _cacheConfig_maxSize;
39
40
  lruCache = new LRUCache({
40
- maxSize: cacheConfig.maxSize,
41
+ maxSize: (_cacheConfig_maxSize = cacheConfig.maxSize) !== null && _cacheConfig_maxSize !== void 0 ? _cacheConfig_maxSize : CacheSize.GB,
41
42
  sizeCalculation: (value) => {
42
43
  if (!value.size) {
43
44
  return 1;
@@ -95,18 +96,33 @@ function generateKey(args) {
95
96
  });
96
97
  }
97
98
  function cache(fn, options) {
98
- const { tag = "default", maxAge = CacheTime.MINUTE * 5, revalidate = 0 } = options || {};
99
+ const { tag = "default", maxAge = CacheTime.MINUTE * 5, revalidate = 0, customKey, onCache, getKey } = options || {};
99
100
  const store = getLRUCache();
100
101
  const tags = Array.isArray(tag) ? tag : [
101
102
  tag
102
103
  ];
103
- tags.forEach((t) => addTagFnRelation(t, fn));
104
+ const getCacheKey = (args, generatedKey) => {
105
+ return customKey ? customKey({
106
+ params: args,
107
+ fn,
108
+ generatedKey
109
+ }) : fn;
110
+ };
104
111
  return async (...args) => {
105
112
  if (isServer && typeof options === "undefined") {
106
113
  var _storage_useContext;
107
114
  const storage = getAsyncLocalStorage();
108
115
  const request = storage === null || storage === void 0 ? void 0 : (_storage_useContext = storage.useContext()) === null || _storage_useContext === void 0 ? void 0 : _storage_useContext.request;
109
116
  if (request) {
117
+ let shouldDisableCaching = false;
118
+ if (cacheConfig.unstable_shouldDisable) {
119
+ shouldDisableCaching = await cacheConfig.unstable_shouldDisable({
120
+ request
121
+ });
122
+ }
123
+ if (shouldDisableCaching) {
124
+ return fn(...args);
125
+ }
110
126
  let requestCache = requestCacheMap.get(request);
111
127
  if (!requestCache) {
112
128
  requestCache = /* @__PURE__ */ new Map();
@@ -132,30 +148,61 @@ function cache(fn, options) {
132
148
  }
133
149
  }
134
150
  } else if (typeof options !== "undefined") {
135
- let tagCache = store.get(fn);
136
- if (!tagCache) {
137
- tagCache = /* @__PURE__ */ new Map();
138
- }
139
- const key = generateKey(args);
140
- const cached = tagCache.get(key);
151
+ const genKey = getKey ? getKey(...args) : generateKey(args);
141
152
  const now = Date.now();
142
- if (cached) {
153
+ const cacheKey = getCacheKey(args, genKey);
154
+ const finalKey = typeof cacheKey === "function" ? genKey : cacheKey;
155
+ tags.forEach((t) => addTagKeyRelation(t, cacheKey));
156
+ let cacheStore = store.get(cacheKey);
157
+ if (!cacheStore) {
158
+ cacheStore = /* @__PURE__ */ new Map();
159
+ }
160
+ const storeKey = customKey && typeof cacheKey === "symbol" ? "symbol-key" : genKey;
161
+ let shouldDisableCaching = false;
162
+ if (isServer && cacheConfig.unstable_shouldDisable) {
163
+ var _storage_useContext1;
164
+ const storage = getAsyncLocalStorage();
165
+ const request = storage === null || storage === void 0 ? void 0 : (_storage_useContext1 = storage.useContext()) === null || _storage_useContext1 === void 0 ? void 0 : _storage_useContext1.request;
166
+ if (request) {
167
+ shouldDisableCaching = await cacheConfig.unstable_shouldDisable({
168
+ request
169
+ });
170
+ }
171
+ }
172
+ const cached = cacheStore.get(storeKey);
173
+ if (cached && !shouldDisableCaching) {
143
174
  const age = now - cached.timestamp;
144
175
  if (age < maxAge) {
176
+ if (onCache) {
177
+ onCache({
178
+ status: "hit",
179
+ key: finalKey,
180
+ params: args,
181
+ result: cached.data
182
+ });
183
+ }
145
184
  return cached.data;
146
185
  }
147
186
  if (revalidate > 0 && age < maxAge + revalidate) {
187
+ if (onCache) {
188
+ onCache({
189
+ status: "stale",
190
+ key: finalKey,
191
+ params: args,
192
+ result: cached.data
193
+ });
194
+ }
148
195
  if (!cached.isRevalidating) {
149
196
  cached.isRevalidating = true;
150
197
  Promise.resolve().then(async () => {
151
198
  try {
152
199
  const newData = await fn(...args);
153
- tagCache.set(key, {
200
+ cacheStore.set(storeKey, {
154
201
  data: newData,
155
202
  timestamp: Date.now(),
156
203
  isRevalidating: false
157
204
  });
158
- store.set(fn, tagCache);
205
+ store.set(cacheKey, cacheStore);
159
206
  } catch (error) {
160
207
  cached.isRevalidating = false;
161
208
  if (isServer) {
@@ -172,12 +219,22 @@ function cache(fn, options) {
172
219
  }
173
220
  }
174
221
  const data = await fn(...args);
175
- tagCache.set(key, {
176
- data,
177
- timestamp: now,
178
- isRevalidating: false
179
- });
180
- store.set(fn, tagCache);
222
+ if (!shouldDisableCaching) {
223
+ cacheStore.set(storeKey, {
224
+ data,
225
+ timestamp: now,
226
+ isRevalidating: false
227
+ });
228
+ store.set(cacheKey, cacheStore);
229
+ }
230
+ if (onCache) {
231
+ onCache({
232
+ status: "miss",
233
+ key: finalKey,
234
+ params: args,
235
+ result: data
236
+ });
237
+ }
181
238
  return data;
182
239
  } else {
183
240
  console.warn("The cache function will not work because it runs on the browser and there are no options are provided.");
@@ -197,17 +254,17 @@ function withRequestCache(handler) {
197
254
  };
198
255
  }
199
256
  function revalidateTag(tag) {
200
- const fns = tagFnMap.get(tag);
201
- if (fns) {
202
- fns.forEach((fn) => {
203
- lruCache === null || lruCache === void 0 ? void 0 : lruCache.delete(fn);
257
+ const keys = tagKeyMap.get(tag);
258
+ if (keys) {
259
+ keys.forEach((key) => {
260
+ lruCache === null || lruCache === void 0 ? void 0 : lruCache.delete(key);
204
261
  });
205
262
  }
206
263
  }
207
264
  function clearStore() {
208
265
  lruCache === null || lruCache === void 0 ? void 0 : lruCache.clear();
209
266
  lruCache = void 0;
210
- tagFnMap.clear();
267
+ tagKeyMap.clear();
211
268
  }
212
269
  export {
213
270
  CacheSize,
@@ -0,0 +1,31 @@
1
+ export declare function invariant(value: boolean, message?: string): asserts value;
2
+ export declare function invariant<T>(value: T | null | undefined, message?: string): asserts value is T;
3
+ export declare class AbortedDeferredError extends Error {
4
+ }
5
+ export interface TrackedPromise extends Promise<any> {
6
+ _tracked?: boolean;
7
+ _data?: any;
8
+ _error?: any;
9
+ }
10
+ export declare class DeferredData {
11
+ private pendingKeysSet;
12
+ private controller;
13
+ private abortPromise;
14
+ private unlistenAbortSignal;
15
+ private subscribers;
16
+ __modern_deferred: boolean;
17
+ data: Record<string, unknown>;
18
+ init?: ResponseInit;
19
+ deferredKeys: string[];
20
+ constructor(data: Record<string, unknown>, responseInit?: ResponseInit);
21
+ private trackPromise;
22
+ private onSettle;
23
+ private emit;
24
+ subscribe(fn: (aborted: boolean, settledKey?: string) => void): () => boolean;
25
+ cancel(): void;
26
+ resolveData(signal: AbortSignal): Promise<boolean>;
27
+ get done(): boolean;
28
+ get unwrappedData(): {};
29
+ get pendingKeys(): string[];
30
+ }
31
+ export declare const activeDeferreds: Map<string, DeferredData>;
@@ -1 +1,2 @@
1
1
  export * from './nestedRoutes';
2
+ export * from './deferreds';
@@ -9,6 +9,7 @@ declare const storage: {
9
9
  headers: Record<string, string>;
10
10
  status: number;
11
11
  };
12
+ activeDeferreds?: Map<string, unknown>;
12
13
  }, cb: () => O | Promise<O>) => Promise<O>;
13
14
  useContext: () => {
14
15
  monitors?: Monitors;
@@ -18,6 +19,7 @@ declare const storage: {
18
19
  headers: Record<string, string>;
19
20
  status: number;
20
21
  };
22
+ activeDeferreds?: Map<string, unknown>;
21
23
  };
22
24
  };
23
25
  type Storage = typeof storage;
@@ -11,13 +11,30 @@ export declare const CacheTime: {
11
11
  readonly WEEK: number;
12
12
  readonly MONTH: number;
13
13
  };
14
+ export type CacheStatus = 'hit' | 'stale' | 'miss';
15
+ export interface CacheStatsInfo {
16
+ status: CacheStatus;
17
+ key: string | symbol;
18
+ params: any[];
19
+ result: any;
20
+ }
14
21
  interface CacheOptions {
15
22
  tag?: string | string[];
16
23
  maxAge?: number;
17
24
  revalidate?: number;
25
+ getKey?: <Args extends any[]>(...args: Args) => string;
26
+ customKey?: <Args extends any[]>(options: {
27
+ params: Args;
28
+ fn: (...args: Args) => any;
29
+ generatedKey: string;
30
+ }) => string | symbol;
31
+ onCache?: (info: CacheStatsInfo) => void;
18
32
  }
19
33
  interface CacheConfig {
20
- maxSize: number;
34
+ maxSize?: number;
35
+ unstable_shouldDisable?: ({ request, }: {
36
+ request: Request;
37
+ }) => boolean | Promise<boolean>;
21
38
  }
22
39
  export declare function configureCache(config: CacheConfig): void;
23
40
  export declare function generateKey(args: unknown[]): string;
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "modern",
16
16
  "modern.js"
17
17
  ],
18
- "version": "2.67.3",
18
+ "version": "2.67.5",
19
19
  "_comment": "Provide ESM and CJS exports, ESM is used by runtime package, for treeshaking",
20
20
  "exports": {
21
21
  "./router": {
@@ -141,12 +141,12 @@
141
141
  },
142
142
  "dependencies": {
143
143
  "@remix-run/router": "1.20.0",
144
- "@swc/helpers": "0.5.13",
144
+ "@swc/helpers": "^0.5.17",
145
145
  "lru-cache": "^10.4.3",
146
146
  "react-router-dom": "6.27.0",
147
147
  "serialize-javascript": "^6.0.0",
148
- "@modern-js/types": "2.67.3",
149
- "@modern-js/utils": "2.67.3"
148
+ "@modern-js/types": "2.67.5",
149
+ "@modern-js/utils": "2.67.5"
150
150
  },
151
151
  "peerDependencies": {
152
152
  "react": ">=17.0.0",