@varlet/axle 1.0.2 → 1.1.1

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/use.d.mts CHANGED
@@ -9,6 +9,7 @@ interface RunOptions<V, P, D> {
9
9
  config?: AxleRequestConfig<D>;
10
10
  resetValue?: boolean;
11
11
  cloneResetValue?: boolean | ((value: V) => V);
12
+ silent?: boolean;
12
13
  }
13
14
  type UseAxleExtra<V> = {
14
15
  loading: Ref<boolean>;
@@ -45,11 +46,13 @@ interface UseAxleOptions<V = any, R = any, P = Record<string, any>, D = Record<s
45
46
  resetValue?: boolean;
46
47
  cloneResetValue?: boolean | ((value: V) => V);
47
48
  abortOnUnmount?: boolean;
49
+ abortPrevious?: boolean;
48
50
  cacheKey?: string | (() => string);
49
51
  cacheTime?: number;
50
52
  config?: AxleRequestConfig<D> | (() => AxleRequestConfig<D>);
51
53
  watch?: WatchOptions;
52
- pollingInterval?: number;
54
+ pollingInterval?: number | (() => number | null | undefined);
55
+ pollingSilent?: boolean;
53
56
  pollingOnHidden?: boolean;
54
57
  pollingOnDeactivated?: boolean;
55
58
  refreshOnWindowFocus?: boolean;
@@ -68,6 +71,8 @@ interface CreateUseAxleOptions {
68
71
  axle: AxleInstance;
69
72
  immediate?: boolean;
70
73
  abortOnUnmount?: boolean;
74
+ abortPrevious?: boolean;
75
+ pollingSilent?: boolean;
71
76
  cacheTime?: number;
72
77
  onTransform?(response: any, refs: any): any;
73
78
  }
package/dist/use.mjs CHANGED
@@ -1,3 +1,4 @@
1
+ import { isCancel } from "axios";
1
2
  import { isFunction } from "rattail";
2
3
  import { getCurrentInstance, onActivated, onDeactivated, onMounted, onUnmounted, ref, watch } from "vue";
3
4
  //#region src/use.ts
@@ -11,9 +12,9 @@ function cleanupCacheBuffer() {
11
12
  });
12
13
  }
13
14
  function createUseAxle(options) {
14
- const { axle, onTransform: defaultOnTransform, immediate: defaultImmediate = true, abortOnUnmount: defaultAbortOnUnmount = true, cacheTime: defaultCacheTime = Infinity } = options;
15
+ const { axle, onTransform: defaultOnTransform, immediate: defaultImmediate = true, abortOnUnmount: defaultAbortOnUnmount = true, abortPrevious: defaultAbortPrevious = false, pollingSilent: defaultPollingSilent = false, cacheTime: defaultCacheTime = Infinity } = options;
15
16
  const useAxle = (options) => {
16
- const { url: initialUrlOrGetter, method, immediate = defaultImmediate, abortOnUnmount = defaultAbortOnUnmount, cacheTime = defaultCacheTime, cacheKey, pollingInterval, pollingOnHidden = true, pollingOnDeactivated = false, refreshOnWindowFocus = false, value: initialValue, resetValue: initialResetValue, cloneResetValue: initialCloneResetValue, params: initialParamsOrGetter, config: initialConfigOrGetter, watch: watchOptions, runnable = () => true, onBefore = () => {}, onAfter = () => {}, onTransform = defaultOnTransform ?? ((response) => response), onSuccess = () => {}, onError = () => {} } = options;
17
+ const { url: initialUrlOrGetter, method, immediate = defaultImmediate, abortOnUnmount = defaultAbortOnUnmount, abortPrevious = defaultAbortPrevious, cacheTime = defaultCacheTime, cacheKey, pollingInterval, pollingSilent = defaultPollingSilent, pollingOnHidden = true, pollingOnDeactivated = false, refreshOnWindowFocus = false, value: initialValue, resetValue: initialResetValue, cloneResetValue: initialCloneResetValue, params: initialParamsOrGetter, config: initialConfigOrGetter, watch: watchOptions, runnable = () => true, onBefore = () => {}, onAfter = () => {}, onTransform = defaultOnTransform ?? ((response) => response), onSuccess = () => {}, onError = () => {} } = options;
17
18
  const value = ref(initialValue);
18
19
  const loading = ref(false);
19
20
  const error = ref();
@@ -40,62 +41,92 @@ function createUseAxle(options) {
40
41
  cancelPolling
41
42
  };
42
43
  let controller = new AbortController();
44
+ let latestRunId = 0;
45
+ let pendingCaches = [];
43
46
  let pollingTimer = null;
47
+ let running = false;
44
48
  let deactivated = false;
45
49
  let hidden = false;
46
50
  let unmounted = false;
47
51
  const run = Object.assign(async (options = {}) => {
48
52
  if (!runnable() || abortOnUnmount && unmounted) return;
49
- pollingCanceled.value = false;
53
+ if (abortPrevious && getPendingCaches().length === 0) controller.abort();
50
54
  if (controller.signal.aborted) controller = new AbortController();
51
- if ((options.resetValue ?? initialResetValue ?? false) === true) resetValue(options);
52
- uploadProgress.value = 0;
53
- downloadProgress.value = 0;
54
- const url = options.url ?? normalizeValueGetter(initialUrlOrGetter);
55
- const params = options.params ?? normalizeValueGetter(initialParamsOrGetter);
56
- const config = options.config ?? normalizeValueGetter(initialConfigOrGetter);
57
- const normalizedCacheKey = cacheKey ? normalizeValueGetter(cacheKey) : void 0;
58
- onBefore(refs);
59
- loading.value = true;
55
+ const runId = ++latestRunId;
56
+ const runController = controller;
57
+ running = true;
58
+ pollingCanceled.value = false;
59
+ clearPolling();
60
60
  try {
61
+ if ((options.resetValue ?? initialResetValue ?? false) === true) resetValue(options);
62
+ uploadProgress.value = 0;
63
+ downloadProgress.value = 0;
64
+ const request = createRequest();
65
+ onBefore(refs);
66
+ if (!options.silent) loading.value = true;
61
67
  cleanupCacheBuffer();
62
- const response = await getResponse();
63
- if (shouldSetCacheResponse(normalizedCacheKey)) {
64
- const cache = cacheBuffer.get(normalizedCacheKey);
68
+ const response = await getResponse(request);
69
+ if (shouldSetCacheResponse(request.cacheKey)) {
70
+ const cache = cacheBuffer.get(request.cacheKey);
65
71
  cache.response = response;
66
72
  cache.expiredTime = Date.now() + cacheTime;
67
73
  }
68
- value.value = await onTransform(response, refs);
74
+ if (!isLatestRun()) return response;
75
+ const transformedValue = await onTransform(response, refs);
76
+ if (!isLatestRun()) return response;
77
+ value.value = transformedValue;
69
78
  error.value = void 0;
70
79
  onSuccess(response, refs);
71
80
  loading.value = false;
72
81
  onAfter(refs);
73
82
  return response;
74
83
  } catch (responseError) {
84
+ if (!isLatestRun()) throw responseError;
75
85
  error.value = responseError;
76
86
  onError(responseError, refs);
77
87
  loading.value = false;
78
88
  onAfter(refs);
79
89
  throw responseError;
80
90
  } finally {
81
- clearPolling();
82
- startPolling();
91
+ if (isLatestRun()) {
92
+ running = false;
93
+ clearPolling();
94
+ startPolling();
95
+ }
96
+ }
97
+ function isLatestRun() {
98
+ return !abortPrevious || runId === latestRunId;
83
99
  }
84
- function getResponse() {
100
+ function createRequest() {
101
+ return {
102
+ url: options.url ?? normalizeValueGetter(initialUrlOrGetter),
103
+ params: options.params ?? normalizeValueGetter(initialParamsOrGetter),
104
+ config: options.config ?? normalizeValueGetter(initialConfigOrGetter),
105
+ cacheKey: cacheKey ? normalizeValueGetter(cacheKey) : void 0
106
+ };
107
+ }
108
+ function getResponse(request) {
109
+ const { cacheKey: normalizedCacheKey } = request;
85
110
  if (shouldUseCache(normalizedCacheKey)) return JSON.parse(JSON.stringify(cacheBuffer.get(normalizedCacheKey).response));
86
111
  if (shouldAwaitCachePromise(normalizedCacheKey)) return cacheBuffer.get(normalizedCacheKey).promise;
87
- const promise = fetchResponse();
88
- if (shouldSetCachePromise(normalizedCacheKey)) cacheBuffer.set(normalizedCacheKey, { promise });
112
+ const promise = fetchResponse(request);
113
+ if (shouldSetCachePromise(normalizedCacheKey)) {
114
+ cacheBuffer.set(normalizedCacheKey, { promise });
115
+ pendingCaches = [...getPendingCaches(), {
116
+ key: normalizedCacheKey,
117
+ promise
118
+ }];
119
+ }
89
120
  return promise;
90
121
  }
91
- function fetchResponse() {
122
+ function fetchResponse({ url, params, config }) {
92
123
  return axle[method](url, params, {
93
- signal: controller.signal,
124
+ signal: runController.signal,
94
125
  onUploadProgress(event) {
95
- uploadProgress.value = event.progress ?? 0;
126
+ if (isLatestRun()) uploadProgress.value = event.progress ?? 0;
96
127
  },
97
128
  onDownloadProgress(event) {
98
- downloadProgress.value = event.progress ?? 0;
129
+ if (isLatestRun()) downloadProgress.value = event.progress ?? 0;
99
130
  },
100
131
  ...config
101
132
  });
@@ -163,12 +194,20 @@ function createUseAxle(options) {
163
194
  runWithInitialConfig();
164
195
  });
165
196
  }
197
+ if (isFunction(pollingInterval)) watch(pollingInterval, () => {
198
+ clearPolling();
199
+ startPolling();
200
+ });
166
201
  }
167
- function runWithInitialConfig() {
202
+ function runWithInitialConfig({ silent = false } = {}) {
168
203
  return run({
169
204
  url: normalizeValueGetter(initialUrlOrGetter),
170
205
  params: normalizeValueGetter(initialParamsOrGetter),
171
- config: normalizeValueGetter(initialConfigOrGetter)
206
+ config: normalizeValueGetter(initialConfigOrGetter),
207
+ silent
208
+ }).catch((runError) => {
209
+ if (isCancel(runError)) return;
210
+ throw runError;
172
211
  });
173
212
  }
174
213
  function resetValue(options = {}) {
@@ -176,6 +215,14 @@ function createUseAxle(options) {
176
215
  }
177
216
  function abort() {
178
217
  controller.abort();
218
+ getPendingCaches().forEach(({ key }) => cacheBuffer.delete(key));
219
+ pendingCaches = [];
220
+ }
221
+ function getPendingCaches() {
222
+ return pendingCaches.filter(({ key, promise }) => {
223
+ const buffer = cacheBuffer.get(key);
224
+ return buffer?.promise === promise && buffer.response == null;
225
+ });
179
226
  }
180
227
  function addWindowFocusListener() {
181
228
  if (typeof window !== "undefined") window.addEventListener("focus", handleWindowFocus);
@@ -198,10 +245,12 @@ function createUseAxle(options) {
198
245
  hidden ? clearPolling() : startPolling();
199
246
  }
200
247
  function startPolling() {
201
- if (pollingInterval == null || pollingCanceled.value || pollingTimer != null || deactivated && !pollingOnDeactivated || hidden && !pollingOnHidden) return;
248
+ const interval = normalizeValueGetter(pollingInterval);
249
+ if (interval == null || running || pollingCanceled.value || pollingTimer != null || deactivated && !pollingOnDeactivated || hidden && !pollingOnHidden) return;
202
250
  pollingTimer = setTimeout(() => {
203
- runWithInitialConfig();
204
- }, pollingInterval);
251
+ pollingTimer = null;
252
+ runWithInitialConfig({ silent: pollingSilent });
253
+ }, interval);
205
254
  }
206
255
  function clearPolling() {
207
256
  if (pollingTimer == null) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@varlet/axle",
3
- "version": "1.0.2",
3
+ "version": "1.1.1",
4
4
  "description": "Progressive request tool based on axios",
5
5
  "keywords": [
6
6
  "axios",
@@ -56,21 +56,34 @@
56
56
  "crypto-js": "^4.2.0",
57
57
  "lodash": "4.17.21",
58
58
  "qs": "^6.11.0",
59
- "rattail": "^1.8.1"
59
+ "rattail": "^2.0.3"
60
60
  },
61
61
  "devDependencies": {
62
62
  "@types/crypto-js": "^4.2.1",
63
63
  "@types/lodash": "4.14.202",
64
64
  "@types/qs": "^6.9.7",
65
- "typescript": "^5.1.5",
66
- "vite-plus": "^0.1.16",
67
- "vue": "3.3.4"
65
+ "oxc-minify": "^0.125.0",
66
+ "typescript": "5.3.3",
67
+ "vite-plus": "0.1.18",
68
+ "vitepress": "2.0.0-alpha.17",
69
+ "vue": "3.5.32"
68
70
  },
69
71
  "peerDependencies": {
70
72
  "vue": "^3.2.0"
71
73
  },
74
+ "engines": {
75
+ "pnpm": ">=10.0.0"
76
+ },
72
77
  "scripts": {
73
78
  "build": "vp pack",
74
- "dev": "vp pack --watch"
79
+ "clean": "rt clean",
80
+ "dev": "vp pack --watch",
81
+ "docs:build": "vitepress build docs",
82
+ "docs:dev": "vitepress dev docs",
83
+ "docs:preview": "vitepress preview docs",
84
+ "lint": "vp lint --fix",
85
+ "format": "vp fmt",
86
+ "release": "pnpm build && rt release",
87
+ "test": "vp test run"
75
88
  }
76
89
  }