@ciwergrp/nuxid 1.17.3 → 1.17.7
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/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -599,7 +599,7 @@ function registerFetcherFeature(options, { from }) {
|
|
|
599
599
|
if (!options.enabled) {
|
|
600
600
|
return;
|
|
601
601
|
}
|
|
602
|
-
addImports({ name: "
|
|
602
|
+
addImports({ name: "default", as: "useCursorHttp", from });
|
|
603
603
|
addImports({ name: "APIResponseCursor", as: "APIResponseCursor", from, type: true });
|
|
604
604
|
addImports({ name: "CursorFetchOptions", as: "CursorFetchOptions", from, type: true });
|
|
605
605
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { isRef, onUnmounted, readonly, ref, shallowRef, watch } from "vue";
|
|
1
|
+
import { isRef, onBeforeMount, onUnmounted, readonly, ref, shallowRef, watch } from "vue";
|
|
2
2
|
export async function useCursorHttp(url, options) {
|
|
3
3
|
function findReactiveSources(obj) {
|
|
4
4
|
const sources = [];
|
|
5
5
|
if (!obj || typeof obj !== "object") {
|
|
6
6
|
return sources;
|
|
7
7
|
}
|
|
8
|
-
for (const
|
|
9
|
-
if (Object.prototype.hasOwnProperty.call(obj,
|
|
10
|
-
const value = obj[
|
|
8
|
+
for (const key2 in obj) {
|
|
9
|
+
if (Object.prototype.hasOwnProperty.call(obj, key2)) {
|
|
10
|
+
const value = obj[key2];
|
|
11
11
|
if (isRef(value)) {
|
|
12
12
|
sources.push(value);
|
|
13
13
|
} else if (typeof value === "object") {
|
|
@@ -22,15 +22,15 @@ export async function useCursorHttp(url, options) {
|
|
|
22
22
|
return obj;
|
|
23
23
|
}
|
|
24
24
|
const unwrapped = Array.isArray(obj) ? [] : {};
|
|
25
|
-
for (const
|
|
26
|
-
if (Object.prototype.hasOwnProperty.call(obj,
|
|
27
|
-
const value = obj[
|
|
25
|
+
for (const key2 in obj) {
|
|
26
|
+
if (Object.prototype.hasOwnProperty.call(obj, key2)) {
|
|
27
|
+
const value = obj[key2];
|
|
28
28
|
if (isRef(value)) {
|
|
29
|
-
unwrapped[
|
|
29
|
+
unwrapped[key2] = value.value;
|
|
30
30
|
} else if (typeof value === "object") {
|
|
31
|
-
unwrapped[
|
|
31
|
+
unwrapped[key2] = unwrapReactiveObject(value);
|
|
32
32
|
} else {
|
|
33
|
-
unwrapped[
|
|
33
|
+
unwrapped[key2] = value;
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -56,9 +56,11 @@ export async function useCursorHttp(url, options) {
|
|
|
56
56
|
pollInterval,
|
|
57
57
|
fetcher,
|
|
58
58
|
fetchOptions,
|
|
59
|
+
query,
|
|
59
60
|
meta,
|
|
60
61
|
itemKey = "id",
|
|
61
|
-
cursorParam = "cursor"
|
|
62
|
+
cursorParam = "cursor",
|
|
63
|
+
key
|
|
62
64
|
} = options ?? {};
|
|
63
65
|
const initialUrl = url;
|
|
64
66
|
const data = ref();
|
|
@@ -70,6 +72,23 @@ export async function useCursorHttp(url, options) {
|
|
|
70
72
|
const currentParams = shallowRef(
|
|
71
73
|
unwrapReactiveObject(fetchOptions) ?? {}
|
|
72
74
|
);
|
|
75
|
+
const normalizeStateKey = (value, fallback) => {
|
|
76
|
+
if (typeof value !== "string") {
|
|
77
|
+
return fallback;
|
|
78
|
+
}
|
|
79
|
+
const trimmed = value.trim();
|
|
80
|
+
return trimmed.length > 0 ? trimmed : fallback;
|
|
81
|
+
};
|
|
82
|
+
const stateKey = normalizeStateKey(key, (() => {
|
|
83
|
+
try {
|
|
84
|
+
const queryValue = query ?? currentParams.value?.query ?? {};
|
|
85
|
+
return `${String(url)}:${JSON.stringify(queryValue)}`;
|
|
86
|
+
} catch {
|
|
87
|
+
return String(url);
|
|
88
|
+
}
|
|
89
|
+
})());
|
|
90
|
+
const { useState } = await import("#app");
|
|
91
|
+
const initialResponseState = useState(stateKey, () => null);
|
|
73
92
|
let pollTimer = null;
|
|
74
93
|
let fetchPromise = null;
|
|
75
94
|
const fetcherFn = fetcher ?? globalThis.$fetch;
|
|
@@ -97,6 +116,18 @@ export async function useCursorHttp(url, options) {
|
|
|
97
116
|
}
|
|
98
117
|
return String(value);
|
|
99
118
|
};
|
|
119
|
+
const cloneResponse = (response) => ({
|
|
120
|
+
...response,
|
|
121
|
+
data: [...response.data]
|
|
122
|
+
});
|
|
123
|
+
const applyResponse = (response, cacheInitial = false) => {
|
|
124
|
+
data.value = cloneResponse(response);
|
|
125
|
+
nextCursor.value = normalizeCursorValue(response.meta?.[cursorKey]);
|
|
126
|
+
hasNextPage.value = response.meta?.[hasMoreKey] ?? false;
|
|
127
|
+
if (cacheInitial) {
|
|
128
|
+
initialResponseState.value = cloneResponse(response);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
100
131
|
const fetchData = async (fetchUrl, params) => {
|
|
101
132
|
if (loading.value) {
|
|
102
133
|
return fetchPromise ?? Promise.resolve();
|
|
@@ -130,6 +161,35 @@ export async function useCursorHttp(url, options) {
|
|
|
130
161
|
}
|
|
131
162
|
}
|
|
132
163
|
};
|
|
164
|
+
const fetchInitialData = async (params, useCache = true) => {
|
|
165
|
+
if (loading.value) {
|
|
166
|
+
return fetchPromise ?? Promise.resolve();
|
|
167
|
+
}
|
|
168
|
+
if (useCache && initialResponseState.value) {
|
|
169
|
+
applyResponse(initialResponseState.value);
|
|
170
|
+
return Promise.resolve();
|
|
171
|
+
}
|
|
172
|
+
loading.value = true;
|
|
173
|
+
error.value = null;
|
|
174
|
+
const promise = (async () => {
|
|
175
|
+
try {
|
|
176
|
+
const response = await fetcherFn(initialUrl, params ?? currentParams.value);
|
|
177
|
+
applyResponse(response, true);
|
|
178
|
+
} catch (e) {
|
|
179
|
+
error.value = normalizeFetchError(e);
|
|
180
|
+
} finally {
|
|
181
|
+
loading.value = false;
|
|
182
|
+
}
|
|
183
|
+
})();
|
|
184
|
+
fetchPromise = promise;
|
|
185
|
+
try {
|
|
186
|
+
await promise;
|
|
187
|
+
} finally {
|
|
188
|
+
if (fetchPromise === promise) {
|
|
189
|
+
fetchPromise = null;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
};
|
|
133
193
|
const pollData = async () => {
|
|
134
194
|
try {
|
|
135
195
|
const response = await fetcherFn(initialUrl, currentParams.value);
|
|
@@ -144,9 +204,7 @@ export async function useCursorHttp(url, options) {
|
|
|
144
204
|
data.value.data.unshift(...newItems);
|
|
145
205
|
}
|
|
146
206
|
} else {
|
|
147
|
-
|
|
148
|
-
nextCursor.value = normalizeCursorValue(response.meta?.[cursorKey]);
|
|
149
|
-
hasNextPage.value = response.meta?.[hasMoreKey] ?? false;
|
|
207
|
+
applyResponse(response, true);
|
|
150
208
|
}
|
|
151
209
|
} catch (e) {
|
|
152
210
|
console.error("Polling error:", e);
|
|
@@ -172,13 +230,13 @@ export async function useCursorHttp(url, options) {
|
|
|
172
230
|
nextCursor.value = null;
|
|
173
231
|
hasNextPage.value = true;
|
|
174
232
|
isLoadMoreTriggered.value = false;
|
|
175
|
-
await
|
|
233
|
+
await fetchInitialData(currentParams.value, false);
|
|
176
234
|
};
|
|
177
235
|
const init = async () => {
|
|
178
236
|
if (data.value) {
|
|
179
237
|
return;
|
|
180
238
|
}
|
|
181
|
-
await
|
|
239
|
+
await fetchInitialData(currentParams.value);
|
|
182
240
|
};
|
|
183
241
|
const reactiveSources = findReactiveSources(fetchOptions);
|
|
184
242
|
if (reactiveSources.length > 0) {
|
|
@@ -200,10 +258,12 @@ export async function useCursorHttp(url, options) {
|
|
|
200
258
|
}
|
|
201
259
|
});
|
|
202
260
|
if (immediate) {
|
|
203
|
-
if (lazy) {
|
|
204
|
-
|
|
261
|
+
if (import.meta.client && lazy) {
|
|
262
|
+
onBeforeMount(() => {
|
|
263
|
+
void fetchInitialData();
|
|
264
|
+
});
|
|
205
265
|
} else {
|
|
206
|
-
await
|
|
266
|
+
await fetchInitialData();
|
|
207
267
|
}
|
|
208
268
|
}
|
|
209
269
|
return {
|
|
@@ -217,3 +277,4 @@ export async function useCursorHttp(url, options) {
|
|
|
217
277
|
init
|
|
218
278
|
};
|
|
219
279
|
}
|
|
280
|
+
export default useCursorHttp;
|