@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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ciwergrp/nuxid",
3
3
  "configKey": "nuxid",
4
- "version": "1.17.3",
4
+ "version": "1.17.7",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
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: "useCursorHttp", as: "useCursorHttp", from });
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
  }
@@ -44,3 +44,4 @@ export declare function useCursorHttp<T extends Record<string, any> = any, TResp
44
44
  refresh: () => Promise<void>;
45
45
  init: () => Promise<void>;
46
46
  }>;
47
+ export default useCursorHttp;
@@ -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 key in obj) {
9
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
10
- const value = obj[key];
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 key in obj) {
26
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
27
- const value = obj[key];
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[key] = value.value;
29
+ unwrapped[key2] = value.value;
30
30
  } else if (typeof value === "object") {
31
- unwrapped[key] = unwrapReactiveObject(value);
31
+ unwrapped[key2] = unwrapReactiveObject(value);
32
32
  } else {
33
- unwrapped[key] = value;
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
- data.value = response;
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 fetchData(initialUrl, currentParams.value);
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 fetchData(initialUrl, currentParams.value);
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
- void fetchData(initialUrl, currentParams.value);
261
+ if (import.meta.client && lazy) {
262
+ onBeforeMount(() => {
263
+ void fetchInitialData();
264
+ });
205
265
  } else {
206
- await fetchData(initialUrl, currentParams.value);
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;
@@ -1 +1,2 @@
1
+ export { default, useCursorHttp } from './cursor.js';
1
2
  export * from './cursor.js';
@@ -1 +1,2 @@
1
+ export { default, useCursorHttp } from "./cursor.js";
1
2
  export * from "./cursor.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ciwergrp/nuxid",
3
- "version": "1.17.3",
3
+ "version": "1.17.7",
4
4
  "description": "All-in-one essential modules for Nuxt",
5
5
  "repository": {
6
6
  "type": "git",