@ametie/vue-muza-use 0.8.0 → 0.9.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/index.cjs CHANGED
@@ -31,8 +31,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
33
  AuthEventType: () => AuthEventType,
34
+ clearAllCache: () => clearAllCache,
34
35
  createApi: () => createApi,
35
36
  createApiClient: () => createApiClient,
37
+ invalidateCache: () => invalidateCache,
36
38
  setAuthMonitor: () => setAuthMonitor,
37
39
  setupInterceptors: () => setupInterceptors,
38
40
  tokenManager: () => tokenManager,
@@ -212,8 +214,39 @@ function useAbortController() {
212
214
  };
213
215
  }
214
216
 
217
+ // src/features/cacheManager.ts
218
+ var DEFAULT_STALE_TIME = 3e5;
219
+ var cacheStore = /* @__PURE__ */ new Map();
220
+ function readCache(id) {
221
+ const entry = cacheStore.get(id);
222
+ if (!entry) return null;
223
+ const isValid = Date.now() - entry.cachedAt < entry.staleTime;
224
+ if (!isValid) {
225
+ cacheStore.delete(id);
226
+ return null;
227
+ }
228
+ return entry.data;
229
+ }
230
+ function writeCache(id, data, staleTime) {
231
+ cacheStore.set(id, { data, cachedAt: Date.now(), staleTime });
232
+ }
233
+ function invalidateCache(id) {
234
+ const ids = Array.isArray(id) ? id : [id];
235
+ ids.forEach((key) => cacheStore.delete(key));
236
+ }
237
+ function clearAllCache() {
238
+ cacheStore.clear();
239
+ }
240
+
215
241
  // src/useApi.ts
216
242
  var DEFAULT_RETRY_STATUS_CODES = [408, 429, 500, 502, 503, 504];
243
+ function normalizeCacheOptions(cache) {
244
+ if (!cache) return null;
245
+ if (typeof cache === "string") {
246
+ return { id: cache, staleTime: DEFAULT_STALE_TIME };
247
+ }
248
+ return { id: cache.id, staleTime: cache.staleTime ?? DEFAULT_STALE_TIME };
249
+ }
217
250
  function cancellableSleep(ms, signal) {
218
251
  return new Promise((resolve) => {
219
252
  if (signal.aborted) {
@@ -272,6 +305,14 @@ function useApi(url, options = {}) {
272
305
  return { interval: 0, whenHidden: false };
273
306
  };
274
307
  const executeRequest = async (config) => {
308
+ const cacheOpts = normalizeCacheOptions(options.cache);
309
+ if (cacheOpts) {
310
+ const cached = readCache(cacheOpts.id);
311
+ if (cached !== null) {
312
+ state.mutate(cached);
313
+ return cached;
314
+ }
315
+ }
275
316
  if (pollTimer) clearTimeout(pollTimer);
276
317
  const requestUrl = (0, import_vue4.toValue)(url);
277
318
  if (abortController2.value) abortController2.value.abort("Cancelled by new request");
@@ -317,6 +358,12 @@ function useApi(url, options = {}) {
317
358
  });
318
359
  state.mutate(response.data, response);
319
360
  state.setStatusCode(response.status);
361
+ if (cacheOpts) {
362
+ writeCache(cacheOpts.id, response.data, cacheOpts.staleTime);
363
+ }
364
+ if (options.invalidateCache) {
365
+ invalidateCache(options.invalidateCache);
366
+ }
320
367
  onSuccess?.(response);
321
368
  return response.data;
322
369
  } catch (err) {
@@ -1015,8 +1062,10 @@ function createApiClient(options = {}) {
1015
1062
  // Annotate the CommonJS export names for ESM import in node:
1016
1063
  0 && (module.exports = {
1017
1064
  AuthEventType,
1065
+ clearAllCache,
1018
1066
  createApi,
1019
1067
  createApiClient,
1068
+ invalidateCache,
1020
1069
  setAuthMonitor,
1021
1070
  setupInterceptors,
1022
1071
  tokenManager,
package/dist/index.d.cts CHANGED
@@ -10,6 +10,14 @@ interface ApiError {
10
10
  details?: unknown;
11
11
  }
12
12
  type AuthMode = "default" | "public" | "optional";
13
+ interface CacheOptions {
14
+ id: string;
15
+ /**
16
+ * How long the cached entry is valid in milliseconds.
17
+ * Default: 300_000 (5 minutes)
18
+ */
19
+ staleTime?: number;
20
+ }
13
21
  interface ApiState<T = unknown> {
14
22
  data: T | null;
15
23
  loading: boolean;
@@ -47,6 +55,22 @@ interface UseApiOptions<T = unknown, D = unknown> extends ApiRequestConfig<D> {
47
55
  * - Pass an **object** `{ interval: number, whenHidden?: boolean }` for advanced control.
48
56
  * Properties inside the object can also be Refs.
49
57
  */
58
+ /**
59
+ * Cache the response data by a string id.
60
+ * - String shorthand: `cache: 'key'` uses DEFAULT_STALE_TIME (5 min)
61
+ * - Object form: `cache: { id: 'key', staleTime: 10_000 }` for custom TTL
62
+ *
63
+ * On cache hit: mutate() is called with cached data, loading stays false,
64
+ * onBefore/onSuccess/onFinish are NOT called, axios request is NOT made.
65
+ * Cache is written only on HTTP 2xx success.
66
+ */
67
+ cache?: string | CacheOptions;
68
+ /**
69
+ * Invalidate one or more cache entries on HTTP 2xx success.
70
+ * Fires only after a confirmed successful response — never in catch/finally.
71
+ * Useful for POST/PUT/DELETE that should bust related GET caches.
72
+ */
73
+ invalidateCache?: string | string[];
50
74
  poll?: MaybeRefOrGetter<number | {
51
75
  interval: MaybeRefOrGetter<number>;
52
76
  whenHidden?: MaybeRefOrGetter<boolean>;
@@ -595,4 +619,13 @@ interface AuthEventPayload {
595
619
  type AuthMonitorFn = (type: AuthEventType, payload: AuthEventPayload) => void;
596
620
  declare function setAuthMonitor(fn: AuthMonitorFn): void;
597
621
 
598
- export { type ApiError, type ApiPluginOptions, type ApiRequestConfig, type ApiState, type AuthEventPayload, AuthEventType, type AuthMode, type AuthMonitorFn, type AuthTokens$1 as AuthTokens, type BatchProgress, type BatchRequestConfig, type BatchResultItem, type SetDataInput, type UseApiBatchOptions, type UseApiBatchReturn, type UseApiOptions, type UseApiReturn, createApi, createApiClient, setAuthMonitor, setupInterceptors, tokenManager, useAbortController, useApi, useApiBatch, useApiConfig, useApiDelete, useApiGet, useApiPatch, useApiPost, useApiPut, useApiState };
622
+ /**
623
+ * Invalidate one or multiple cache entries by id.
624
+ */
625
+ declare function invalidateCache(id: string | string[]): void;
626
+ /**
627
+ * Clear all cache entries. Call on logout to prevent data leaks between users.
628
+ */
629
+ declare function clearAllCache(): void;
630
+
631
+ export { type ApiError, type ApiPluginOptions, type ApiRequestConfig, type ApiState, type AuthEventPayload, AuthEventType, type AuthMode, type AuthMonitorFn, type AuthTokens$1 as AuthTokens, type BatchProgress, type BatchRequestConfig, type BatchResultItem, type CacheOptions, type SetDataInput, type UseApiBatchOptions, type UseApiBatchReturn, type UseApiOptions, type UseApiReturn, clearAllCache, createApi, createApiClient, invalidateCache, setAuthMonitor, setupInterceptors, tokenManager, useAbortController, useApi, useApiBatch, useApiConfig, useApiDelete, useApiGet, useApiPatch, useApiPost, useApiPut, useApiState };
package/dist/index.d.ts CHANGED
@@ -10,6 +10,14 @@ interface ApiError {
10
10
  details?: unknown;
11
11
  }
12
12
  type AuthMode = "default" | "public" | "optional";
13
+ interface CacheOptions {
14
+ id: string;
15
+ /**
16
+ * How long the cached entry is valid in milliseconds.
17
+ * Default: 300_000 (5 minutes)
18
+ */
19
+ staleTime?: number;
20
+ }
13
21
  interface ApiState<T = unknown> {
14
22
  data: T | null;
15
23
  loading: boolean;
@@ -47,6 +55,22 @@ interface UseApiOptions<T = unknown, D = unknown> extends ApiRequestConfig<D> {
47
55
  * - Pass an **object** `{ interval: number, whenHidden?: boolean }` for advanced control.
48
56
  * Properties inside the object can also be Refs.
49
57
  */
58
+ /**
59
+ * Cache the response data by a string id.
60
+ * - String shorthand: `cache: 'key'` uses DEFAULT_STALE_TIME (5 min)
61
+ * - Object form: `cache: { id: 'key', staleTime: 10_000 }` for custom TTL
62
+ *
63
+ * On cache hit: mutate() is called with cached data, loading stays false,
64
+ * onBefore/onSuccess/onFinish are NOT called, axios request is NOT made.
65
+ * Cache is written only on HTTP 2xx success.
66
+ */
67
+ cache?: string | CacheOptions;
68
+ /**
69
+ * Invalidate one or more cache entries on HTTP 2xx success.
70
+ * Fires only after a confirmed successful response — never in catch/finally.
71
+ * Useful for POST/PUT/DELETE that should bust related GET caches.
72
+ */
73
+ invalidateCache?: string | string[];
50
74
  poll?: MaybeRefOrGetter<number | {
51
75
  interval: MaybeRefOrGetter<number>;
52
76
  whenHidden?: MaybeRefOrGetter<boolean>;
@@ -595,4 +619,13 @@ interface AuthEventPayload {
595
619
  type AuthMonitorFn = (type: AuthEventType, payload: AuthEventPayload) => void;
596
620
  declare function setAuthMonitor(fn: AuthMonitorFn): void;
597
621
 
598
- export { type ApiError, type ApiPluginOptions, type ApiRequestConfig, type ApiState, type AuthEventPayload, AuthEventType, type AuthMode, type AuthMonitorFn, type AuthTokens$1 as AuthTokens, type BatchProgress, type BatchRequestConfig, type BatchResultItem, type SetDataInput, type UseApiBatchOptions, type UseApiBatchReturn, type UseApiOptions, type UseApiReturn, createApi, createApiClient, setAuthMonitor, setupInterceptors, tokenManager, useAbortController, useApi, useApiBatch, useApiConfig, useApiDelete, useApiGet, useApiPatch, useApiPost, useApiPut, useApiState };
622
+ /**
623
+ * Invalidate one or multiple cache entries by id.
624
+ */
625
+ declare function invalidateCache(id: string | string[]): void;
626
+ /**
627
+ * Clear all cache entries. Call on logout to prevent data leaks between users.
628
+ */
629
+ declare function clearAllCache(): void;
630
+
631
+ export { type ApiError, type ApiPluginOptions, type ApiRequestConfig, type ApiState, type AuthEventPayload, AuthEventType, type AuthMode, type AuthMonitorFn, type AuthTokens$1 as AuthTokens, type BatchProgress, type BatchRequestConfig, type BatchResultItem, type CacheOptions, type SetDataInput, type UseApiBatchOptions, type UseApiBatchReturn, type UseApiOptions, type UseApiReturn, clearAllCache, createApi, createApiClient, invalidateCache, setAuthMonitor, setupInterceptors, tokenManager, useAbortController, useApi, useApiBatch, useApiConfig, useApiDelete, useApiGet, useApiPatch, useApiPost, useApiPut, useApiState };
package/dist/index.mjs CHANGED
@@ -161,8 +161,39 @@ function useAbortController() {
161
161
  };
162
162
  }
163
163
 
164
+ // src/features/cacheManager.ts
165
+ var DEFAULT_STALE_TIME = 3e5;
166
+ var cacheStore = /* @__PURE__ */ new Map();
167
+ function readCache(id) {
168
+ const entry = cacheStore.get(id);
169
+ if (!entry) return null;
170
+ const isValid = Date.now() - entry.cachedAt < entry.staleTime;
171
+ if (!isValid) {
172
+ cacheStore.delete(id);
173
+ return null;
174
+ }
175
+ return entry.data;
176
+ }
177
+ function writeCache(id, data, staleTime) {
178
+ cacheStore.set(id, { data, cachedAt: Date.now(), staleTime });
179
+ }
180
+ function invalidateCache(id) {
181
+ const ids = Array.isArray(id) ? id : [id];
182
+ ids.forEach((key) => cacheStore.delete(key));
183
+ }
184
+ function clearAllCache() {
185
+ cacheStore.clear();
186
+ }
187
+
164
188
  // src/useApi.ts
165
189
  var DEFAULT_RETRY_STATUS_CODES = [408, 429, 500, 502, 503, 504];
190
+ function normalizeCacheOptions(cache) {
191
+ if (!cache) return null;
192
+ if (typeof cache === "string") {
193
+ return { id: cache, staleTime: DEFAULT_STALE_TIME };
194
+ }
195
+ return { id: cache.id, staleTime: cache.staleTime ?? DEFAULT_STALE_TIME };
196
+ }
166
197
  function cancellableSleep(ms, signal) {
167
198
  return new Promise((resolve) => {
168
199
  if (signal.aborted) {
@@ -221,6 +252,14 @@ function useApi(url, options = {}) {
221
252
  return { interval: 0, whenHidden: false };
222
253
  };
223
254
  const executeRequest = async (config) => {
255
+ const cacheOpts = normalizeCacheOptions(options.cache);
256
+ if (cacheOpts) {
257
+ const cached = readCache(cacheOpts.id);
258
+ if (cached !== null) {
259
+ state.mutate(cached);
260
+ return cached;
261
+ }
262
+ }
224
263
  if (pollTimer) clearTimeout(pollTimer);
225
264
  const requestUrl = toValue(url);
226
265
  if (abortController2.value) abortController2.value.abort("Cancelled by new request");
@@ -266,6 +305,12 @@ function useApi(url, options = {}) {
266
305
  });
267
306
  state.mutate(response.data, response);
268
307
  state.setStatusCode(response.status);
308
+ if (cacheOpts) {
309
+ writeCache(cacheOpts.id, response.data, cacheOpts.staleTime);
310
+ }
311
+ if (options.invalidateCache) {
312
+ invalidateCache(options.invalidateCache);
313
+ }
269
314
  onSuccess?.(response);
270
315
  return response.data;
271
316
  } catch (err) {
@@ -963,8 +1008,10 @@ function createApiClient(options = {}) {
963
1008
  }
964
1009
  export {
965
1010
  AuthEventType,
1011
+ clearAllCache,
966
1012
  createApi,
967
1013
  createApiClient,
1014
+ invalidateCache,
968
1015
  setAuthMonitor,
969
1016
  setupInterceptors,
970
1017
  tokenManager,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ametie/vue-muza-use",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Powerful Vue 3 API composable (Muza Kit) with Axios, Auto-Refresh & TypeScript",
5
5
  "author": "MortyQ",
6
6
  "license": "MIT",