@katlux/providers 0.1.1-alpha.100 → 0.1.1-alpha.101
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 +1480 -747
- package/dist/index.d.cts +199 -122
- package/dist/index.d.mts +199 -122
- package/dist/index.d.ts +199 -122
- package/dist/index.mjs +1440 -709
- package/package.json +1 -20
- package/dist/nuxtAppCompat.cjs +0 -35
- package/dist/nuxtAppCompat.d.cts +0 -21
- package/dist/nuxtAppCompat.d.mts +0 -21
- package/dist/nuxtAppCompat.d.ts +0 -21
- package/dist/nuxtAppCompat.mjs +0 -27
- package/dist/nuxtAppCompat.server.cjs +0 -45
- package/dist/nuxtAppCompat.server.d.cts +0 -21
- package/dist/nuxtAppCompat.server.d.mts +0 -21
- package/dist/nuxtAppCompat.server.d.ts +0 -21
- package/dist/nuxtAppCompat.server.mjs +0 -37
- package/dist/shared/providers.C8C1HrDy.mjs +0 -228
- package/dist/shared/providers.CxZeMH3Y.cjs +0 -241
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const index = require('./shared/providers.CxZeMH3Y.cjs');
|
|
4
3
|
const ofetch = require('ofetch');
|
|
5
4
|
const h3 = require('h3');
|
|
6
5
|
|
|
6
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
7
7
|
var EDataFilterOperator = /* @__PURE__ */ ((EDataFilterOperator2) => {
|
|
8
8
|
EDataFilterOperator2["Equal"] = "==";
|
|
9
9
|
EDataFilterOperator2["NotEqual"] = "!=";
|
|
@@ -37,36 +37,213 @@ var EQueueStorage = /* @__PURE__ */ ((EQueueStorage2) => {
|
|
|
37
37
|
|
|
38
38
|
const useDebounce = (callback, delay) => {
|
|
39
39
|
let timeoutId = null;
|
|
40
|
-
|
|
40
|
+
const debounced = function(...args) {
|
|
41
41
|
if (timeoutId !== null) {
|
|
42
42
|
clearTimeout(timeoutId);
|
|
43
43
|
}
|
|
44
44
|
timeoutId = setTimeout(() => {
|
|
45
|
+
timeoutId = null;
|
|
45
46
|
callback.apply(this, args);
|
|
46
47
|
}, delay);
|
|
47
48
|
};
|
|
49
|
+
debounced.cancel = () => {
|
|
50
|
+
if (timeoutId !== null) {
|
|
51
|
+
clearTimeout(timeoutId);
|
|
52
|
+
timeoutId = null;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
return debounced;
|
|
48
56
|
};
|
|
49
57
|
const debounce = useDebounce;
|
|
50
58
|
|
|
59
|
+
class DefaultHydrationAdapter {
|
|
60
|
+
getSSRData(key, context) {
|
|
61
|
+
const contextData = context?.payload?.data?.[key] ?? context?.ssrContext?.payload?.data?.[key];
|
|
62
|
+
if (contextData !== void 0 && contextData !== null) {
|
|
63
|
+
return contextData;
|
|
64
|
+
}
|
|
65
|
+
if (typeof window !== "undefined") {
|
|
66
|
+
const win = window;
|
|
67
|
+
const clientData = win.__KATLUX_DATA__?.[key] ?? win.__SSR_DATA__?.[key] ?? win.__INITIAL_DATA__?.[key] ?? win.__NEXT_DATA__?.props?.pageProps?.[key];
|
|
68
|
+
if (clientData !== void 0 && clientData !== null) {
|
|
69
|
+
return clientData;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
async fetchWithSSR(key, fetcher, context) {
|
|
75
|
+
const cached = this.getSSRData(key, context);
|
|
76
|
+
if (cached !== null) {
|
|
77
|
+
return cached;
|
|
78
|
+
}
|
|
79
|
+
const result = await fetcher();
|
|
80
|
+
if (context?.payload?.data) {
|
|
81
|
+
context.payload.data[key] = result;
|
|
82
|
+
} else if (context?.ssrContext?.payload?.data) {
|
|
83
|
+
context.ssrContext.payload.data[key] = result;
|
|
84
|
+
}
|
|
85
|
+
return result;
|
|
86
|
+
}
|
|
87
|
+
clearSSRData(key, context) {
|
|
88
|
+
if (context?.payload?.data) {
|
|
89
|
+
delete context.payload.data[key];
|
|
90
|
+
}
|
|
91
|
+
if (context?.ssrContext?.payload?.data) {
|
|
92
|
+
delete context.ssrContext.payload.data[key];
|
|
93
|
+
}
|
|
94
|
+
if (typeof window !== "undefined") {
|
|
95
|
+
const win = window;
|
|
96
|
+
if (win.__KATLUX_DATA__?.payload?.data) delete win.__KATLUX_DATA__.payload.data[key];
|
|
97
|
+
if (win.__SSR_DATA__?.payload?.data) delete win.__SSR_DATA__.payload.data[key];
|
|
98
|
+
if (win.__INITIAL_DATA__?.payload?.data) delete win.__INITIAL_DATA__.payload.data[key];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
getSSRPayload(context) {
|
|
102
|
+
if (context?.payload?.data) return context.payload.data;
|
|
103
|
+
if (context?.ssrContext?.payload?.data) return context.ssrContext.payload.data;
|
|
104
|
+
if (typeof window !== "undefined") {
|
|
105
|
+
const win = window;
|
|
106
|
+
return win.__KATLUX_DATA__?.payload?.data || win.__KATLUX_DATA__ || win.__SSR_DATA__?.payload?.data || win.__SSR_DATA__ || win.__INITIAL_DATA__?.payload?.data || win.__INITIAL_DATA__ || null;
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
let currentAdapter = null;
|
|
113
|
+
function getHydrationAdapter() {
|
|
114
|
+
if (!currentAdapter) {
|
|
115
|
+
currentAdapter = new DefaultHydrationAdapter();
|
|
116
|
+
}
|
|
117
|
+
return currentAdapter;
|
|
118
|
+
}
|
|
119
|
+
function setHydrationAdapter(adapter) {
|
|
120
|
+
currentAdapter = adapter;
|
|
121
|
+
}
|
|
122
|
+
function getSSRData(key, context) {
|
|
123
|
+
return getHydrationAdapter().getSSRData(key, context);
|
|
124
|
+
}
|
|
125
|
+
async function fetchWithSSR(key, fetcher, context) {
|
|
126
|
+
return await getHydrationAdapter().fetchWithSSR(key, fetcher, context);
|
|
127
|
+
}
|
|
128
|
+
function clearSSRData(key, context) {
|
|
129
|
+
getHydrationAdapter().clearSSRData?.(key, context);
|
|
130
|
+
}
|
|
131
|
+
function getSSRPayload(context) {
|
|
132
|
+
return getHydrationAdapter().getSSRPayload?.(context) ?? null;
|
|
133
|
+
}
|
|
134
|
+
function getPlatformApp() {
|
|
135
|
+
if (typeof globalThis.__KATLUX_APP__ !== "undefined") {
|
|
136
|
+
return globalThis.__KATLUX_APP__;
|
|
137
|
+
}
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
function getAppRoute() {
|
|
141
|
+
if (typeof window !== "undefined") {
|
|
142
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
143
|
+
const query = {};
|
|
144
|
+
searchParams.forEach((val, key) => {
|
|
145
|
+
query[key] = val;
|
|
146
|
+
});
|
|
147
|
+
return { query, path: window.location.pathname };
|
|
148
|
+
}
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
function getAppRouter() {
|
|
152
|
+
if (typeof window !== "undefined") {
|
|
153
|
+
return {
|
|
154
|
+
replace: (options) => {
|
|
155
|
+
const url = new URL(window.location.href);
|
|
156
|
+
url.search = "";
|
|
157
|
+
if (options.query) {
|
|
158
|
+
for (const [k, v] of Object.entries(options.query)) {
|
|
159
|
+
if (v !== void 0 && v !== null) {
|
|
160
|
+
url.searchParams.set(k, String(v));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
window.history.replaceState({}, "", url.toString());
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
function onPlatformReady(cb) {
|
|
171
|
+
if (typeof window !== "undefined") {
|
|
172
|
+
if (document.readyState === "complete") {
|
|
173
|
+
setTimeout(cb, 0);
|
|
174
|
+
} else {
|
|
175
|
+
window.addEventListener("DOMContentLoaded", cb, { once: true });
|
|
176
|
+
}
|
|
177
|
+
} else {
|
|
178
|
+
setTimeout(cb, 0);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
51
182
|
class ADataProvider {
|
|
52
183
|
idKey = "id";
|
|
53
184
|
pageData = [];
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
185
|
+
_rowCount = 0;
|
|
186
|
+
get rowCount() {
|
|
187
|
+
return this._rowCount;
|
|
188
|
+
}
|
|
189
|
+
set rowCount(val) {
|
|
190
|
+
if (this._rowCount !== val) {
|
|
191
|
+
this._rowCount = val;
|
|
192
|
+
this.notify();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
_loading = false;
|
|
196
|
+
get loading() {
|
|
197
|
+
return this._loading;
|
|
198
|
+
}
|
|
199
|
+
set loading(val) {
|
|
200
|
+
if (this._loading !== val) {
|
|
201
|
+
this._loading = val;
|
|
202
|
+
this.notify();
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
_initialLoad = true;
|
|
206
|
+
get initialLoad() {
|
|
207
|
+
return this._initialLoad;
|
|
208
|
+
}
|
|
209
|
+
set initialLoad(val) {
|
|
210
|
+
if (this._initialLoad !== val) {
|
|
211
|
+
this._initialLoad = val;
|
|
212
|
+
this.notify();
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
_error = null;
|
|
216
|
+
get error() {
|
|
217
|
+
return this._error;
|
|
218
|
+
}
|
|
219
|
+
set error(val) {
|
|
220
|
+
if (this._error !== val) {
|
|
221
|
+
this._error = val;
|
|
222
|
+
this.notify();
|
|
223
|
+
}
|
|
224
|
+
}
|
|
58
225
|
SSR = false;
|
|
59
226
|
deduplicate = true;
|
|
60
227
|
context = null;
|
|
61
|
-
|
|
62
|
-
|
|
228
|
+
urlPageParam = "";
|
|
229
|
+
_selectedRows = [];
|
|
230
|
+
get selectedRows() {
|
|
231
|
+
return this._selectedRows;
|
|
232
|
+
}
|
|
233
|
+
set selectedRows(val) {
|
|
234
|
+
this._selectedRows = Array.isArray(val) ? val : [];
|
|
235
|
+
this.notify();
|
|
63
236
|
}
|
|
64
|
-
|
|
65
|
-
|
|
237
|
+
_selectAll = false;
|
|
238
|
+
get selectAll() {
|
|
239
|
+
return this._selectAll;
|
|
240
|
+
}
|
|
241
|
+
set selectAll(val) {
|
|
242
|
+
if (this._selectAll !== val) {
|
|
243
|
+
this._selectAll = val;
|
|
244
|
+
this.notify();
|
|
245
|
+
}
|
|
66
246
|
}
|
|
67
|
-
urlPageParam = "";
|
|
68
|
-
selectedRows = [];
|
|
69
|
-
selectAll = false;
|
|
70
247
|
_currentPage = 1;
|
|
71
248
|
_pageSize = 10;
|
|
72
249
|
_filter = null;
|
|
@@ -97,6 +274,7 @@ class ADataProvider {
|
|
|
97
274
|
}
|
|
98
275
|
_listeners = /* @__PURE__ */ new Set();
|
|
99
276
|
_debouncedFilterLoad;
|
|
277
|
+
_debouncedSortLoad;
|
|
100
278
|
constructor(options) {
|
|
101
279
|
Object.defineProperty(this, "__v_skip", { value: true, enumerable: false });
|
|
102
280
|
if (options?.idKey) {
|
|
@@ -112,17 +290,15 @@ class ADataProvider {
|
|
|
112
290
|
this.urlPageParam = options?.urlPageParam || "";
|
|
113
291
|
if (options?.context) {
|
|
114
292
|
this.context = options.context;
|
|
115
|
-
} else if (options?.nuxtApp) {
|
|
116
|
-
this.context = options.nuxtApp;
|
|
117
293
|
} else {
|
|
118
294
|
try {
|
|
119
|
-
this.context =
|
|
295
|
+
this.context = getPlatformApp();
|
|
120
296
|
} catch {
|
|
121
297
|
}
|
|
122
298
|
}
|
|
123
299
|
if (options?.urlPageParam && typeof window !== "undefined") {
|
|
124
300
|
try {
|
|
125
|
-
const route =
|
|
301
|
+
const route = getAppRoute();
|
|
126
302
|
if (route) {
|
|
127
303
|
const pageFromUrl = route.query[options.urlPageParam];
|
|
128
304
|
if (pageFromUrl) {
|
|
@@ -138,8 +314,11 @@ class ADataProvider {
|
|
|
138
314
|
this._debouncedFilterLoad = useDebounce(() => {
|
|
139
315
|
this._currentPage = 1;
|
|
140
316
|
this.loadPageData();
|
|
141
|
-
this.notify();
|
|
142
317
|
}, 300);
|
|
318
|
+
this._debouncedSortLoad = useDebounce(() => {
|
|
319
|
+
this._currentPage = 1;
|
|
320
|
+
this.loadPageData();
|
|
321
|
+
}, 200);
|
|
143
322
|
this.setFilter = this.setFilter.bind(this);
|
|
144
323
|
this.setSortList = this.setSortList.bind(this);
|
|
145
324
|
this.setCurrentPage = this.setCurrentPage.bind(this);
|
|
@@ -149,21 +328,71 @@ class ADataProvider {
|
|
|
149
328
|
this.loadPageData = this.loadPageData.bind(this);
|
|
150
329
|
this.refresh = this.refresh.bind(this);
|
|
151
330
|
this.subscribe = this.subscribe.bind(this);
|
|
152
|
-
this.
|
|
331
|
+
this.batchUpdates = this.batchUpdates.bind(this);
|
|
153
332
|
this.getState = this.getState.bind(this);
|
|
333
|
+
this.cancelPending = this.cancelPending.bind(this);
|
|
334
|
+
}
|
|
335
|
+
_batchDepth = 0;
|
|
336
|
+
_pendingNotify = false;
|
|
337
|
+
_isNotifying = false;
|
|
338
|
+
/**
|
|
339
|
+
* Batches multiple state updates so notify() fires exactly once upon completion.
|
|
340
|
+
*/
|
|
341
|
+
batchUpdates(fn) {
|
|
342
|
+
this._batchDepth++;
|
|
343
|
+
let isAsync = false;
|
|
344
|
+
try {
|
|
345
|
+
const res = fn();
|
|
346
|
+
if (res instanceof Promise || res && typeof res.then === "function") {
|
|
347
|
+
isAsync = true;
|
|
348
|
+
return Promise.resolve(res).finally(() => {
|
|
349
|
+
this._batchDepth = Math.max(0, this._batchDepth - 1);
|
|
350
|
+
if (this._batchDepth === 0 && this._pendingNotify) {
|
|
351
|
+
this._pendingNotify = false;
|
|
352
|
+
this.notify();
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
return res;
|
|
357
|
+
} finally {
|
|
358
|
+
if (!isAsync) {
|
|
359
|
+
this._batchDepth = Math.max(0, this._batchDepth - 1);
|
|
360
|
+
if (this._batchDepth === 0 && this._pendingNotify) {
|
|
361
|
+
this._pendingNotify = false;
|
|
362
|
+
this.notify();
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
154
366
|
}
|
|
155
367
|
subscribe(listener) {
|
|
156
368
|
this._listeners.add(listener);
|
|
157
369
|
return () => this._listeners.delete(listener);
|
|
158
370
|
}
|
|
159
371
|
notify() {
|
|
160
|
-
this.
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
372
|
+
if (this._batchDepth > 0) {
|
|
373
|
+
this._pendingNotify = true;
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
if (this._isNotifying) {
|
|
377
|
+
this._pendingNotify = true;
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
this._isNotifying = true;
|
|
381
|
+
try {
|
|
382
|
+
this._listeners.forEach((listener) => {
|
|
383
|
+
try {
|
|
384
|
+
listener(this);
|
|
385
|
+
} catch (e) {
|
|
386
|
+
console.error("[Katlux Providers] Listener error:", e);
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
} finally {
|
|
390
|
+
this._isNotifying = false;
|
|
391
|
+
if (this._pendingNotify && this._batchDepth === 0) {
|
|
392
|
+
this._pendingNotify = false;
|
|
393
|
+
this.notify();
|
|
165
394
|
}
|
|
166
|
-
}
|
|
395
|
+
}
|
|
167
396
|
}
|
|
168
397
|
getState() {
|
|
169
398
|
return {
|
|
@@ -184,20 +413,24 @@ class ADataProvider {
|
|
|
184
413
|
this._filter = filter;
|
|
185
414
|
this._debouncedFilterLoad();
|
|
186
415
|
}
|
|
187
|
-
setSortList(sortList) {
|
|
416
|
+
setSortList(sortList, immediate = false) {
|
|
188
417
|
this._sortList = sortList;
|
|
189
418
|
this._currentPage = 1;
|
|
190
|
-
|
|
191
|
-
|
|
419
|
+
if (immediate) {
|
|
420
|
+
this.loadPageData();
|
|
421
|
+
} else {
|
|
422
|
+
this._debouncedSortLoad();
|
|
423
|
+
}
|
|
192
424
|
}
|
|
193
425
|
setCurrentPage(currentPage) {
|
|
194
426
|
this._currentPage = currentPage;
|
|
427
|
+
this._selectAll = false;
|
|
195
428
|
this.loadPageData();
|
|
196
429
|
if (typeof window !== "undefined" && this.urlPageParam) {
|
|
197
430
|
try {
|
|
198
|
-
const router =
|
|
431
|
+
const router = getAppRouter();
|
|
199
432
|
if (router) {
|
|
200
|
-
const currentRoute = router.currentRoute?.value ||
|
|
433
|
+
const currentRoute = router.currentRoute?.value || getAppRoute();
|
|
201
434
|
const currentQuery = { ...currentRoute?.query || {} };
|
|
202
435
|
if (currentPage === 1) {
|
|
203
436
|
delete currentQuery[this.urlPageParam];
|
|
@@ -226,6 +459,10 @@ class ADataProvider {
|
|
|
226
459
|
async refresh(hardRefresh = false) {
|
|
227
460
|
await this.loadPageData({ disableCache: hardRefresh });
|
|
228
461
|
}
|
|
462
|
+
cancelPending() {
|
|
463
|
+
this._debouncedFilterLoad?.cancel?.();
|
|
464
|
+
this._debouncedSortLoad?.cancel?.();
|
|
465
|
+
}
|
|
229
466
|
}
|
|
230
467
|
|
|
231
468
|
const compareIn = (rowValue, filterValue) => {
|
|
@@ -472,34 +709,35 @@ class CFlatClientDataProvider extends ADataProvider {
|
|
|
472
709
|
await this.refreshData({ disableCache: hardRefresh });
|
|
473
710
|
}
|
|
474
711
|
async loadPageData() {
|
|
475
|
-
this.
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
this.
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
this.
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
712
|
+
this.batchUpdates(() => {
|
|
713
|
+
this.loading = true;
|
|
714
|
+
this.error = null;
|
|
715
|
+
try {
|
|
716
|
+
if (!this.filter) {
|
|
717
|
+
this.filteredData = this.allData;
|
|
718
|
+
} else {
|
|
719
|
+
const { results } = filterData(this.allData, this.filter);
|
|
720
|
+
this.filteredData = results;
|
|
721
|
+
}
|
|
722
|
+
this.rowCount = this.filteredData.length;
|
|
723
|
+
if (this.sortList.length > 0) {
|
|
724
|
+
this.filteredData = sortData(this.sortList, this.filteredData);
|
|
725
|
+
}
|
|
726
|
+
if (this.pageSize <= 0) {
|
|
727
|
+
this.pageData = this.filteredData;
|
|
728
|
+
} else {
|
|
729
|
+
const startIndex = (this.currentPage - 1) * this.pageSize;
|
|
730
|
+
const endIndex = startIndex + this.pageSize;
|
|
731
|
+
this.pageData = this.filteredData.slice(startIndex, endIndex);
|
|
732
|
+
}
|
|
733
|
+
} catch (err) {
|
|
734
|
+
this.error = err;
|
|
735
|
+
console.warn("[Katlux Providers] CFlatClientDataProvider loadPageData error", err);
|
|
736
|
+
} finally {
|
|
737
|
+
this.loading = false;
|
|
738
|
+
this.initialLoad = false;
|
|
494
739
|
}
|
|
495
|
-
}
|
|
496
|
-
this.error = err;
|
|
497
|
-
console.warn("[Katlux Providers] CFlatClientDataProvider loadPageData error", err);
|
|
498
|
-
} finally {
|
|
499
|
-
this.loading = false;
|
|
500
|
-
this.initialLoad = false;
|
|
501
|
-
this.notify();
|
|
502
|
-
}
|
|
740
|
+
});
|
|
503
741
|
}
|
|
504
742
|
}
|
|
505
743
|
|
|
@@ -569,6 +807,319 @@ class ACacheProvider {
|
|
|
569
807
|
}
|
|
570
808
|
}
|
|
571
809
|
|
|
810
|
+
class CApplicationCache extends ACacheProvider {
|
|
811
|
+
static instance = null;
|
|
812
|
+
static _storage = null;
|
|
813
|
+
static get storage() {
|
|
814
|
+
if (!this._storage) {
|
|
815
|
+
this._storage = /* @__PURE__ */ new Map();
|
|
816
|
+
}
|
|
817
|
+
return this._storage;
|
|
818
|
+
}
|
|
819
|
+
static getInstance() {
|
|
820
|
+
if (!this.instance) {
|
|
821
|
+
this.instance = new CApplicationCache();
|
|
822
|
+
}
|
|
823
|
+
return this.instance;
|
|
824
|
+
}
|
|
825
|
+
static MAX_ENTRIES = 1e4;
|
|
826
|
+
static getSnapshot() {
|
|
827
|
+
return this.storage;
|
|
828
|
+
}
|
|
829
|
+
/**
|
|
830
|
+
* Purges expired entries when storage size reaches MAX_ENTRIES watermark.
|
|
831
|
+
* Avoids persistent background setInterval timers on Node.js/SSR.
|
|
832
|
+
*/
|
|
833
|
+
static purgeExpiredEntries() {
|
|
834
|
+
const now = Date.now();
|
|
835
|
+
const storage = this.storage;
|
|
836
|
+
for (const [key, entry] of storage.entries()) {
|
|
837
|
+
if (now - entry.timestamp > entry.lifetime) {
|
|
838
|
+
storage.delete(key);
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* Clears all cached entries (used for test isolation).
|
|
844
|
+
*/
|
|
845
|
+
static clear() {
|
|
846
|
+
this._storage?.clear();
|
|
847
|
+
}
|
|
848
|
+
constructor() {
|
|
849
|
+
super();
|
|
850
|
+
}
|
|
851
|
+
isServer(context) {
|
|
852
|
+
const event = context?.event ?? context?.ssrContext?.event ?? (context?.node ? context : null);
|
|
853
|
+
return typeof window === "undefined" || !!event || !!context?.ssrContext || typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)) }) !== "undefined" && !!undefined;
|
|
854
|
+
}
|
|
855
|
+
async getKeyList(context) {
|
|
856
|
+
if (!this.isServer(context)) return [];
|
|
857
|
+
const prefix = "cache:";
|
|
858
|
+
const storage = CApplicationCache.storage;
|
|
859
|
+
return Array.from(storage.keys()).filter((key) => key.startsWith(prefix)).map((key) => key.substring(prefix.length));
|
|
860
|
+
}
|
|
861
|
+
async get(key, context) {
|
|
862
|
+
if (this.isServer(context)) {
|
|
863
|
+
const prefixedKey = "cache:" + key;
|
|
864
|
+
const storage = CApplicationCache.storage;
|
|
865
|
+
const entry = storage.get(prefixedKey);
|
|
866
|
+
if (!entry) return null;
|
|
867
|
+
if (Date.now() - entry.timestamp > entry.lifetime) {
|
|
868
|
+
storage.delete(prefixedKey);
|
|
869
|
+
return null;
|
|
870
|
+
}
|
|
871
|
+
return entry.data;
|
|
872
|
+
}
|
|
873
|
+
return null;
|
|
874
|
+
}
|
|
875
|
+
async set(key, data, lifetime, context) {
|
|
876
|
+
if (this.isServer(context)) {
|
|
877
|
+
const storage = CApplicationCache.storage;
|
|
878
|
+
if (storage.size >= CApplicationCache.MAX_ENTRIES) {
|
|
879
|
+
CApplicationCache.purgeExpiredEntries();
|
|
880
|
+
}
|
|
881
|
+
const prefixedKey = "cache:" + key;
|
|
882
|
+
storage.set(prefixedKey, {
|
|
883
|
+
data,
|
|
884
|
+
timestamp: Date.now(),
|
|
885
|
+
lifetime
|
|
886
|
+
});
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
async remove(key, context) {
|
|
890
|
+
if (this.isServer(context)) {
|
|
891
|
+
const prefixedKey = "cache:" + key;
|
|
892
|
+
CApplicationCache.storage.delete(prefixedKey);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
async removeByPrefix(prefix, context) {
|
|
896
|
+
if (this.isServer(context)) {
|
|
897
|
+
const fullPrefix = "cache:" + prefix;
|
|
898
|
+
const storage = CApplicationCache.storage;
|
|
899
|
+
const keysToDelete = [];
|
|
900
|
+
for (const key of storage.keys()) {
|
|
901
|
+
if (key.startsWith(fullPrefix)) {
|
|
902
|
+
keysToDelete.push(key);
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
for (const key of keysToDelete) {
|
|
906
|
+
storage.delete(key);
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
async getRemainingTime(key, context) {
|
|
911
|
+
if (this.isServer(context)) {
|
|
912
|
+
const prefixedKey = "cache:" + key;
|
|
913
|
+
const storage = CApplicationCache.storage;
|
|
914
|
+
const entry = storage.get(prefixedKey);
|
|
915
|
+
if (!entry) return null;
|
|
916
|
+
return Math.max(0, entry.timestamp + entry.lifetime - Date.now());
|
|
917
|
+
}
|
|
918
|
+
return null;
|
|
919
|
+
}
|
|
920
|
+
async cleanupExpired(context) {
|
|
921
|
+
if (this.isServer(context)) {
|
|
922
|
+
CApplicationCache.purgeExpiredEntries();
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
const CApplicationCache$1 = {
|
|
928
|
+
__proto__: null,
|
|
929
|
+
CApplicationCache: CApplicationCache
|
|
930
|
+
};
|
|
931
|
+
|
|
932
|
+
class CMemoryCache extends ACacheProvider {
|
|
933
|
+
static instance = null;
|
|
934
|
+
static _storage = null;
|
|
935
|
+
static get storage() {
|
|
936
|
+
if (!this._storage) this._storage = /* @__PURE__ */ new Map();
|
|
937
|
+
return this._storage;
|
|
938
|
+
}
|
|
939
|
+
static getInstance() {
|
|
940
|
+
if (!this.instance) {
|
|
941
|
+
this.instance = new CMemoryCache();
|
|
942
|
+
}
|
|
943
|
+
return this.instance;
|
|
944
|
+
}
|
|
945
|
+
constructor() {
|
|
946
|
+
super();
|
|
947
|
+
const isClient = typeof window !== "undefined" || typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)) }) !== "undefined" && !!undefined;
|
|
948
|
+
if (isClient && CMemoryCache.storage.size === 0) {
|
|
949
|
+
this._hydrateFromPayload();
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
async _hydrateFromPayload() {
|
|
953
|
+
try {
|
|
954
|
+
const payloadData = getSSRPayload();
|
|
955
|
+
if (!payloadData) return;
|
|
956
|
+
for (const key in payloadData) {
|
|
957
|
+
const value = payloadData[key];
|
|
958
|
+
if (value && typeof value === "object" && "data" in value && "timestamp" in value && "lifetime" in value) {
|
|
959
|
+
if (typeof value.lifetime === "number") {
|
|
960
|
+
CMemoryCache.storage.set(key, value);
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
} catch (e) {
|
|
965
|
+
console.warn("[Katlux Cache] CMemoryCache payload hydration failed", e);
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
async getKeyList(context) {
|
|
969
|
+
const prefix = "cache:";
|
|
970
|
+
if (this.isServer(context)) {
|
|
971
|
+
const payload = getSSRPayload(context);
|
|
972
|
+
if (!payload) return [];
|
|
973
|
+
return Object.keys(payload).filter((k) => k.startsWith(prefix)).map((k) => k.substring(prefix.length));
|
|
974
|
+
}
|
|
975
|
+
return Array.from(CMemoryCache.storage.keys()).filter((key) => key.startsWith(prefix)).map((key) => key.substring(prefix.length));
|
|
976
|
+
}
|
|
977
|
+
async get(key, context) {
|
|
978
|
+
const prefixedKey = "cache:" + key;
|
|
979
|
+
if (this.isServer(context)) {
|
|
980
|
+
try {
|
|
981
|
+
const payloadData = getSSRPayload(context);
|
|
982
|
+
if (payloadData && payloadData[prefixedKey]) {
|
|
983
|
+
const entry2 = payloadData[prefixedKey];
|
|
984
|
+
if (Date.now() - entry2.timestamp <= entry2.lifetime) {
|
|
985
|
+
return entry2.data;
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
} catch (e) {
|
|
989
|
+
console.warn("[Katlux Cache] CMemoryCache error reading SSR payload for key: " + key, e);
|
|
990
|
+
}
|
|
991
|
+
return null;
|
|
992
|
+
}
|
|
993
|
+
const entry = CMemoryCache.storage.get(prefixedKey);
|
|
994
|
+
if (entry) {
|
|
995
|
+
if (Date.now() - entry.timestamp <= entry.lifetime) {
|
|
996
|
+
return entry.data;
|
|
997
|
+
} else {
|
|
998
|
+
CMemoryCache.storage.delete(prefixedKey);
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
try {
|
|
1002
|
+
const payloadData = getSSRPayload(context);
|
|
1003
|
+
if (payloadData && payloadData[prefixedKey]) {
|
|
1004
|
+
const entry2 = payloadData[prefixedKey];
|
|
1005
|
+
if (Date.now() - entry2.timestamp <= entry2.lifetime) {
|
|
1006
|
+
CMemoryCache.storage.set(prefixedKey, entry2);
|
|
1007
|
+
return entry2.data;
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
} catch (e) {
|
|
1011
|
+
console.warn("[Katlux Cache] CMemoryCache error reading SSR payload for key: " + key, e);
|
|
1012
|
+
}
|
|
1013
|
+
return null;
|
|
1014
|
+
}
|
|
1015
|
+
isServer(context) {
|
|
1016
|
+
return typeof window === "undefined" || typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)) }) !== "undefined" && !!undefined || !!context?.event || !!context?.ssrContext || !!context?.node;
|
|
1017
|
+
}
|
|
1018
|
+
async set(key, data, lifetime, context) {
|
|
1019
|
+
const prefixedKey = "cache:" + key;
|
|
1020
|
+
const entry = {
|
|
1021
|
+
data,
|
|
1022
|
+
timestamp: Date.now(),
|
|
1023
|
+
lifetime
|
|
1024
|
+
};
|
|
1025
|
+
if (this.isServer(context)) {
|
|
1026
|
+
if (context) {
|
|
1027
|
+
try {
|
|
1028
|
+
const payload = context.payload?.data || context.ssrContext?.payload?.data;
|
|
1029
|
+
if (payload) {
|
|
1030
|
+
payload[prefixedKey] = entry;
|
|
1031
|
+
}
|
|
1032
|
+
} catch (e) {
|
|
1033
|
+
console.warn("[Katlux Cache] CMemoryCache error writing SSR payload for key: " + key, e);
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
return;
|
|
1037
|
+
}
|
|
1038
|
+
CMemoryCache.storage.set(prefixedKey, entry);
|
|
1039
|
+
}
|
|
1040
|
+
async remove(key, context) {
|
|
1041
|
+
const prefixedKey = "cache:" + key;
|
|
1042
|
+
if (this.isServer(context)) {
|
|
1043
|
+
if (context) {
|
|
1044
|
+
try {
|
|
1045
|
+
const payload = context.payload?.data || context.ssrContext?.payload?.data;
|
|
1046
|
+
if (payload && payload[prefixedKey]) {
|
|
1047
|
+
delete payload[prefixedKey];
|
|
1048
|
+
}
|
|
1049
|
+
} catch (e) {
|
|
1050
|
+
console.warn("[Katlux Cache] CMemoryCache error deleting key from SSR payload: " + key, e);
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
return;
|
|
1054
|
+
}
|
|
1055
|
+
CMemoryCache.storage.delete(prefixedKey);
|
|
1056
|
+
}
|
|
1057
|
+
async removeByPrefix(prefix, context) {
|
|
1058
|
+
const fullPrefix = "cache:" + prefix;
|
|
1059
|
+
if (this.isServer(context)) {
|
|
1060
|
+
if (context) {
|
|
1061
|
+
try {
|
|
1062
|
+
const payload = context.payload?.data || context.ssrContext?.payload?.data;
|
|
1063
|
+
if (payload) {
|
|
1064
|
+
for (const key in payload) {
|
|
1065
|
+
if (key.startsWith(fullPrefix)) {
|
|
1066
|
+
delete payload[key];
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
} catch (e) {
|
|
1071
|
+
console.warn("[Katlux Cache] CMemoryCache error removing by prefix from SSR payload: " + prefix, e);
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
return;
|
|
1075
|
+
}
|
|
1076
|
+
const keysToDelete = [];
|
|
1077
|
+
for (const key of CMemoryCache.storage.keys()) {
|
|
1078
|
+
if (key.startsWith(fullPrefix)) {
|
|
1079
|
+
keysToDelete.push(key);
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
for (const key of keysToDelete) {
|
|
1083
|
+
CMemoryCache.storage.delete(key);
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
async getRemainingTime(key, context) {
|
|
1087
|
+
const prefixedKey = "cache:" + key;
|
|
1088
|
+
if (this.isServer(context)) {
|
|
1089
|
+
const payload = getSSRPayload(context);
|
|
1090
|
+
if (payload && payload[prefixedKey]) {
|
|
1091
|
+
const entry2 = payload[prefixedKey];
|
|
1092
|
+
return Math.max(0, entry2.timestamp + entry2.lifetime - Date.now());
|
|
1093
|
+
}
|
|
1094
|
+
return null;
|
|
1095
|
+
}
|
|
1096
|
+
const entry = CMemoryCache.storage.get(prefixedKey);
|
|
1097
|
+
if (!entry) return null;
|
|
1098
|
+
return Math.max(0, entry.timestamp + entry.lifetime - Date.now());
|
|
1099
|
+
}
|
|
1100
|
+
async cleanupExpired() {
|
|
1101
|
+
if (typeof window === "undefined") return;
|
|
1102
|
+
const prefix = "cache:";
|
|
1103
|
+
const now = Date.now();
|
|
1104
|
+
const keysToDelete = [];
|
|
1105
|
+
for (const [key, entry] of CMemoryCache.storage.entries()) {
|
|
1106
|
+
if (key.startsWith(prefix)) {
|
|
1107
|
+
if (now - entry.timestamp > entry.lifetime) {
|
|
1108
|
+
keysToDelete.push(key);
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
for (const key of keysToDelete) {
|
|
1113
|
+
CMemoryCache.storage.delete(key);
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
const CMemoryCache$1 = {
|
|
1119
|
+
__proto__: null,
|
|
1120
|
+
CMemoryCache: CMemoryCache
|
|
1121
|
+
};
|
|
1122
|
+
|
|
572
1123
|
class KatluxIndexedDB {
|
|
573
1124
|
static db = null;
|
|
574
1125
|
static openPromise = null;
|
|
@@ -589,7 +1140,7 @@ class KatluxIndexedDB {
|
|
|
589
1140
|
if (typeof indexedDB === "undefined") {
|
|
590
1141
|
return reject(new Error("IndexedDB is not available in this environment"));
|
|
591
1142
|
}
|
|
592
|
-
const req = indexedDB.open(KatluxIndexedDB.DB_NAME
|
|
1143
|
+
const req = indexedDB.open(KatluxIndexedDB.DB_NAME);
|
|
593
1144
|
req.onupgradeneeded = (event) => {
|
|
594
1145
|
const db = event.target.result;
|
|
595
1146
|
if (!db.objectStoreNames.contains("cache")) db.createObjectStore("cache");
|
|
@@ -601,17 +1152,27 @@ class KatluxIndexedDB {
|
|
|
601
1152
|
}
|
|
602
1153
|
}
|
|
603
1154
|
};
|
|
604
|
-
req.onsuccess = () => {
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
1155
|
+
req.onsuccess = async () => {
|
|
1156
|
+
const db = req.result;
|
|
1157
|
+
KatluxIndexedDB.db = db;
|
|
1158
|
+
if (db.version) {
|
|
1159
|
+
KatluxIndexedDB.currentVersion = db.version;
|
|
608
1160
|
}
|
|
609
|
-
|
|
610
|
-
|
|
1161
|
+
db.onversionchange = () => {
|
|
1162
|
+
db.close();
|
|
611
1163
|
KatluxIndexedDB.db = null;
|
|
612
1164
|
KatluxIndexedDB.openPromise = null;
|
|
613
1165
|
console.warn("[KatluxIndexedDB] Database closed due to version change. Will reopen on next access.");
|
|
614
1166
|
};
|
|
1167
|
+
const missingStandards = ["cache", "queue", "dead_letter"].some((s) => !db.objectStoreNames.contains(s));
|
|
1168
|
+
if (missingStandards) {
|
|
1169
|
+
try {
|
|
1170
|
+
const upgraded = await KatluxIndexedDB.upgradeToVersion((db.version || 1) + 1);
|
|
1171
|
+
resolve(upgraded);
|
|
1172
|
+
return;
|
|
1173
|
+
} catch (e) {
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
615
1176
|
resolve(KatluxIndexedDB.db);
|
|
616
1177
|
};
|
|
617
1178
|
req.onerror = () => {
|
|
@@ -624,6 +1185,37 @@ class KatluxIndexedDB {
|
|
|
624
1185
|
});
|
|
625
1186
|
return this.openPromise;
|
|
626
1187
|
}
|
|
1188
|
+
static async upgradeToVersion(newVersion) {
|
|
1189
|
+
KatluxIndexedDB.currentVersion = newVersion;
|
|
1190
|
+
if (KatluxIndexedDB.db) {
|
|
1191
|
+
KatluxIndexedDB.db.close();
|
|
1192
|
+
KatluxIndexedDB.db = null;
|
|
1193
|
+
}
|
|
1194
|
+
KatluxIndexedDB.openPromise = null;
|
|
1195
|
+
return new Promise((resolve, reject) => {
|
|
1196
|
+
const req = indexedDB.open(KatluxIndexedDB.DB_NAME, newVersion);
|
|
1197
|
+
req.onupgradeneeded = (event) => {
|
|
1198
|
+
const upgradedDb = event.target.result;
|
|
1199
|
+
if (!upgradedDb.objectStoreNames.contains("cache")) upgradedDb.createObjectStore("cache");
|
|
1200
|
+
if (!upgradedDb.objectStoreNames.contains("queue")) upgradedDb.createObjectStore("queue");
|
|
1201
|
+
if (!upgradedDb.objectStoreNames.contains("dead_letter")) upgradedDb.createObjectStore("dead_letter");
|
|
1202
|
+
for (const s of KatluxIndexedDB.customStores) {
|
|
1203
|
+
if (!upgradedDb.objectStoreNames.contains(s)) {
|
|
1204
|
+
upgradedDb.createObjectStore(s);
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
};
|
|
1208
|
+
req.onsuccess = () => {
|
|
1209
|
+
KatluxIndexedDB.db = req.result;
|
|
1210
|
+
KatluxIndexedDB.currentVersion = req.result.version;
|
|
1211
|
+
resolve(req.result);
|
|
1212
|
+
};
|
|
1213
|
+
req.onerror = () => {
|
|
1214
|
+
KatluxIndexedDB.openPromise = null;
|
|
1215
|
+
reject(req.error);
|
|
1216
|
+
};
|
|
1217
|
+
});
|
|
1218
|
+
}
|
|
627
1219
|
/**
|
|
628
1220
|
* Dynamically ensures that an object store exists in the database.
|
|
629
1221
|
* If not present, performs a database version bump and creates the store.
|
|
@@ -633,35 +1225,7 @@ class KatluxIndexedDB {
|
|
|
633
1225
|
let db = await KatluxIndexedDB.open();
|
|
634
1226
|
if (!db.objectStoreNames.contains(storeName)) {
|
|
635
1227
|
const newVersion = (db.version || KatluxIndexedDB.currentVersion) + 1;
|
|
636
|
-
|
|
637
|
-
if (KatluxIndexedDB.db) {
|
|
638
|
-
KatluxIndexedDB.db.close();
|
|
639
|
-
KatluxIndexedDB.db = null;
|
|
640
|
-
}
|
|
641
|
-
KatluxIndexedDB.openPromise = null;
|
|
642
|
-
db = await new Promise((resolve, reject) => {
|
|
643
|
-
const req = indexedDB.open(KatluxIndexedDB.DB_NAME, newVersion);
|
|
644
|
-
req.onupgradeneeded = (event) => {
|
|
645
|
-
const upgradedDb = event.target.result;
|
|
646
|
-
if (!upgradedDb.objectStoreNames.contains("cache")) upgradedDb.createObjectStore("cache");
|
|
647
|
-
if (!upgradedDb.objectStoreNames.contains("queue")) upgradedDb.createObjectStore("queue");
|
|
648
|
-
if (!upgradedDb.objectStoreNames.contains("dead_letter")) upgradedDb.createObjectStore("dead_letter");
|
|
649
|
-
for (const s of KatluxIndexedDB.customStores) {
|
|
650
|
-
if (!upgradedDb.objectStoreNames.contains(s)) {
|
|
651
|
-
upgradedDb.createObjectStore(s);
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
};
|
|
655
|
-
req.onsuccess = () => {
|
|
656
|
-
KatluxIndexedDB.db = req.result;
|
|
657
|
-
KatluxIndexedDB.currentVersion = req.result.version;
|
|
658
|
-
resolve(req.result);
|
|
659
|
-
};
|
|
660
|
-
req.onerror = () => {
|
|
661
|
-
KatluxIndexedDB.openPromise = null;
|
|
662
|
-
reject(req.error);
|
|
663
|
-
};
|
|
664
|
-
});
|
|
1228
|
+
db = await KatluxIndexedDB.upgradeToVersion(newVersion);
|
|
665
1229
|
}
|
|
666
1230
|
return db;
|
|
667
1231
|
}
|
|
@@ -814,8 +1378,11 @@ class RequestProviderRegistry {
|
|
|
814
1378
|
/**
|
|
815
1379
|
* Register a provider with one or more tags.
|
|
816
1380
|
* If the provider is already registered, its tags are updated.
|
|
1381
|
+
* In SSR (Node.js), registration is skipped to prevent process-global memory leaks
|
|
1382
|
+
* and cross-user multi-tenant invalidation.
|
|
817
1383
|
*/
|
|
818
1384
|
static register(provider, tags) {
|
|
1385
|
+
if (typeof window === "undefined") return;
|
|
819
1386
|
const existing = this.entries.find((e) => e.provider === provider);
|
|
820
1387
|
if (existing) {
|
|
821
1388
|
existing.tags = tags;
|
|
@@ -835,7 +1402,7 @@ class RequestProviderRegistry {
|
|
|
835
1402
|
*/
|
|
836
1403
|
static async refreshByTag(tag, hardRefresh = true) {
|
|
837
1404
|
const matched = this.entries.filter((e) => e.tags.includes(tag));
|
|
838
|
-
await Promise.
|
|
1405
|
+
await Promise.allSettled(matched.map((e) => e.provider.refresh(hardRefresh)));
|
|
839
1406
|
}
|
|
840
1407
|
/**
|
|
841
1408
|
* Called internally by RequestProvider (after non-GET success) and by
|
|
@@ -853,7 +1420,12 @@ class RequestProviderRegistry {
|
|
|
853
1420
|
toRefresh.add(entry.provider);
|
|
854
1421
|
}
|
|
855
1422
|
}
|
|
856
|
-
await Promise.
|
|
1423
|
+
const results = await Promise.allSettled([...toRefresh].map((p) => p.refresh(true)));
|
|
1424
|
+
for (const res of results) {
|
|
1425
|
+
if (res.status === "rejected") {
|
|
1426
|
+
console.warn("[RequestProviderRegistry] Provider refresh failed during mutation notification:", res.reason);
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
857
1429
|
}
|
|
858
1430
|
/**
|
|
859
1431
|
* Returns a copy of all registry entries.
|
|
@@ -869,16 +1441,99 @@ class RequestProviderRegistry {
|
|
|
869
1441
|
static clear() {
|
|
870
1442
|
this.entries = [];
|
|
871
1443
|
}
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
-
function generateId() {
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
function generateId() {
|
|
1447
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
1448
|
+
return crypto.randomUUID();
|
|
1449
|
+
}
|
|
1450
|
+
if (typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function") {
|
|
1451
|
+
const bytes = new Uint8Array(8);
|
|
1452
|
+
crypto.getRandomValues(bytes);
|
|
1453
|
+
return Date.now().toString(36) + Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
1454
|
+
}
|
|
1455
|
+
return Date.now().toString(36) + Math.random().toString(36).slice(2);
|
|
1456
|
+
}
|
|
1457
|
+
const SENSITIVE_HEADER_KEYS = ["authorization", "cookie", "set-cookie", "x-csrf-token"];
|
|
1458
|
+
class RequestQueue {
|
|
1459
|
+
// ── State ──────────────────────────────────────────────────────────────────
|
|
1460
|
+
static queue = [];
|
|
1461
|
+
static deadLetterQueue = [];
|
|
1462
|
+
static isFlushing = false;
|
|
1463
|
+
// ── Capacity & Size Limits ────────────────────────────────────────────────
|
|
1464
|
+
static MAX_PAYLOAD_SIZE_BYTES = 5 * 1024 * 1024;
|
|
1465
|
+
// 5 MB default
|
|
1466
|
+
static MAX_QUEUE_SIZE = 500;
|
|
1467
|
+
static MAX_DEAD_LETTER_SIZE = 200;
|
|
1468
|
+
static setMaxPayloadSize(bytes) {
|
|
1469
|
+
this.MAX_PAYLOAD_SIZE_BYTES = bytes;
|
|
1470
|
+
}
|
|
1471
|
+
static setMaxQueueSize(limit) {
|
|
1472
|
+
this.MAX_QUEUE_SIZE = limit;
|
|
1473
|
+
}
|
|
1474
|
+
static setMaxDeadLetterSize(limit) {
|
|
1475
|
+
this.MAX_DEAD_LETTER_SIZE = limit;
|
|
1476
|
+
}
|
|
1477
|
+
/**
|
|
1478
|
+
* Strips sensitive headers (e.g., authorization, cookie, x-csrf-token) before persisting
|
|
1479
|
+
* request options to persistent storage (IndexedDB / LocalStorage).
|
|
1480
|
+
* Sensitive credentials must never be stored in plaintext in browser storage, and are
|
|
1481
|
+
* instead regenerated dynamically at execution time.
|
|
1482
|
+
*/
|
|
1483
|
+
static sanitizeOptions(options) {
|
|
1484
|
+
if (!options) return {};
|
|
1485
|
+
const sanitized = {
|
|
1486
|
+
method: options.method
|
|
1487
|
+
};
|
|
1488
|
+
if (options.headers) {
|
|
1489
|
+
const headersObj = {};
|
|
1490
|
+
const sensitiveSet = new Set(SENSITIVE_HEADER_KEYS.map((k) => k.toLowerCase()));
|
|
1491
|
+
if (typeof options.headers.forEach === "function") {
|
|
1492
|
+
options.headers.forEach((value, key) => {
|
|
1493
|
+
if (!sensitiveSet.has(String(key).toLowerCase())) {
|
|
1494
|
+
headersObj[String(key)] = String(value);
|
|
1495
|
+
}
|
|
1496
|
+
});
|
|
1497
|
+
} else if (Array.isArray(options.headers)) {
|
|
1498
|
+
for (const [key, value] of options.headers) {
|
|
1499
|
+
if (!sensitiveSet.has(String(key).toLowerCase())) {
|
|
1500
|
+
headersObj[String(key)] = String(value);
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
} else if (typeof options.headers === "object") {
|
|
1504
|
+
for (const [key, value] of Object.entries(options.headers)) {
|
|
1505
|
+
if (!sensitiveSet.has(key.toLowerCase())) {
|
|
1506
|
+
headersObj[key] = value;
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
sanitized.headers = headersObj;
|
|
1511
|
+
}
|
|
1512
|
+
if (options.query) {
|
|
1513
|
+
try {
|
|
1514
|
+
sanitized.query = JSON.parse(JSON.stringify(options.query));
|
|
1515
|
+
} catch (err) {
|
|
1516
|
+
throw new Error(`[RequestQueue] Failed to serialize request query parameters: ${err?.message || "circular structure"}`);
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
if (options.body !== void 0) {
|
|
1520
|
+
try {
|
|
1521
|
+
const serialized = JSON.stringify(options.body);
|
|
1522
|
+
if (serialized && serialized.length > this.MAX_PAYLOAD_SIZE_BYTES) {
|
|
1523
|
+
throw new Error(
|
|
1524
|
+
`[RequestQueue] Payload size (${(serialized.length / (1024 * 1024)).toFixed(2)} MB) exceeds maximum allowed size (${(this.MAX_PAYLOAD_SIZE_BYTES / (1024 * 1024)).toFixed(2)} MB)`
|
|
1525
|
+
);
|
|
1526
|
+
}
|
|
1527
|
+
sanitized.body = JSON.parse(serialized);
|
|
1528
|
+
} catch (err) {
|
|
1529
|
+
if (err.message?.includes("exceeds maximum allowed size")) {
|
|
1530
|
+
throw err;
|
|
1531
|
+
}
|
|
1532
|
+
throw new Error(`[RequestQueue] Failed to serialize request body: ${err?.message || "circular structure"}`);
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
return sanitized;
|
|
1536
|
+
}
|
|
882
1537
|
// ── Subscribers ────────────────────────────────────────────────────────────
|
|
883
1538
|
static _subscribers = /* @__PURE__ */ new Set();
|
|
884
1539
|
static subscribe(listener) {
|
|
@@ -899,6 +1554,7 @@ class RequestQueue {
|
|
|
899
1554
|
// ── Internal ──────────────────────────────────────────────────────────────
|
|
900
1555
|
static adapter = QueueStorageFactory.getAdapter("IndexedDB");
|
|
901
1556
|
static initialized = false;
|
|
1557
|
+
static initPromise = null;
|
|
902
1558
|
static _onDeadLetter = null;
|
|
903
1559
|
static _onFlushComplete = null;
|
|
904
1560
|
static _onNetworkError = null;
|
|
@@ -909,10 +1565,24 @@ class RequestQueue {
|
|
|
909
1565
|
*/
|
|
910
1566
|
static async init() {
|
|
911
1567
|
if (this.initialized) return;
|
|
912
|
-
this.
|
|
913
|
-
this.
|
|
914
|
-
|
|
915
|
-
|
|
1568
|
+
if (this.initPromise) return this.initPromise;
|
|
1569
|
+
this.initPromise = (async () => {
|
|
1570
|
+
try {
|
|
1571
|
+
const loadedQueue = await this.adapter.loadQueue();
|
|
1572
|
+
const loadedDeadLetter = await this.adapter.loadDeadLetter();
|
|
1573
|
+
const existingIds = new Set(this.queue.map((i) => i.id));
|
|
1574
|
+
const mergedQueue = [...loadedQueue.filter((i) => !existingIds.has(i.id)), ...this.queue];
|
|
1575
|
+
const existingDlIds = new Set(this.deadLetterQueue.map((i) => i.id));
|
|
1576
|
+
const mergedDl = [...loadedDeadLetter.filter((i) => !existingDlIds.has(i.id)), ...this.deadLetterQueue];
|
|
1577
|
+
this.queue = mergedQueue;
|
|
1578
|
+
this.deadLetterQueue = mergedDl;
|
|
1579
|
+
this.initialized = true;
|
|
1580
|
+
this.notify();
|
|
1581
|
+
} finally {
|
|
1582
|
+
this.initPromise = null;
|
|
1583
|
+
}
|
|
1584
|
+
})();
|
|
1585
|
+
return this.initPromise;
|
|
916
1586
|
}
|
|
917
1587
|
/**
|
|
918
1588
|
* Set the storage backend. Call before init().
|
|
@@ -921,6 +1591,7 @@ class RequestQueue {
|
|
|
921
1591
|
static setStorageBackend(backend) {
|
|
922
1592
|
this.adapter = QueueStorageFactory.getAdapter(backend);
|
|
923
1593
|
this.initialized = false;
|
|
1594
|
+
this.initPromise = null;
|
|
924
1595
|
}
|
|
925
1596
|
// ── Hooks ─────────────────────────────────────────────────────────────────
|
|
926
1597
|
static onDeadLetter(cb) {
|
|
@@ -940,8 +1611,13 @@ class RequestQueue {
|
|
|
940
1611
|
*/
|
|
941
1612
|
static async enqueue(operation) {
|
|
942
1613
|
await this.init();
|
|
1614
|
+
const sanitizedOptions = this.sanitizeOptions(operation.options);
|
|
1615
|
+
if (this.queue.length >= this.MAX_QUEUE_SIZE) {
|
|
1616
|
+
this.queue = this.queue.slice(1);
|
|
1617
|
+
}
|
|
943
1618
|
const item = {
|
|
944
1619
|
...operation,
|
|
1620
|
+
options: sanitizedOptions,
|
|
945
1621
|
id: generateId(),
|
|
946
1622
|
createdAt: Date.now(),
|
|
947
1623
|
flushAttempts: 0,
|
|
@@ -1094,12 +1770,33 @@ class RequestQueue {
|
|
|
1094
1770
|
this.notify();
|
|
1095
1771
|
}
|
|
1096
1772
|
// ── Internal helpers ──────────────────────────────────────────────────────
|
|
1773
|
+
static regenerateHeaders(existingHeaders) {
|
|
1774
|
+
const headers = {};
|
|
1775
|
+
if (existingHeaders) {
|
|
1776
|
+
if (typeof existingHeaders.forEach === "function") {
|
|
1777
|
+
existingHeaders.forEach((val, key) => {
|
|
1778
|
+
headers[String(key)] = String(val);
|
|
1779
|
+
});
|
|
1780
|
+
} else if (Array.isArray(existingHeaders)) {
|
|
1781
|
+
for (const [key, val] of existingHeaders) {
|
|
1782
|
+
headers[String(key)] = String(val);
|
|
1783
|
+
}
|
|
1784
|
+
} else if (typeof existingHeaders === "object") {
|
|
1785
|
+
Object.assign(headers, existingHeaders);
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
if (typeof document !== "undefined" && document.cookie && !headers["cookie"] && !headers["Cookie"]) {
|
|
1789
|
+
headers["cookie"] = document.cookie;
|
|
1790
|
+
}
|
|
1791
|
+
return headers;
|
|
1792
|
+
}
|
|
1097
1793
|
static async executeRequest(item) {
|
|
1098
1794
|
const { url, options } = item;
|
|
1795
|
+
const headers = this.regenerateHeaders(options.headers);
|
|
1099
1796
|
const fetchOptions = {
|
|
1100
1797
|
method: item.method,
|
|
1101
1798
|
body: options.body,
|
|
1102
|
-
headers
|
|
1799
|
+
headers,
|
|
1103
1800
|
query: options.query
|
|
1104
1801
|
};
|
|
1105
1802
|
const fetchFn = globalThis.$fetch || ofetch.$fetch;
|
|
@@ -1113,6 +1810,9 @@ class RequestQueue {
|
|
|
1113
1810
|
httpStatus
|
|
1114
1811
|
};
|
|
1115
1812
|
this.queue = this.queue.filter((i) => i.id !== item.id);
|
|
1813
|
+
if (this.deadLetterQueue.length >= this.MAX_DEAD_LETTER_SIZE) {
|
|
1814
|
+
this.deadLetterQueue = this.deadLetterQueue.slice(1);
|
|
1815
|
+
}
|
|
1116
1816
|
this.deadLetterQueue = [...this.deadLetterQueue, deadItem];
|
|
1117
1817
|
await this.persistQueue();
|
|
1118
1818
|
await this.persistDeadLetter();
|
|
@@ -1134,11 +1834,45 @@ class RequestQueue {
|
|
|
1134
1834
|
this._onDeadLetter = null;
|
|
1135
1835
|
this._onFlushComplete = null;
|
|
1136
1836
|
this._onNetworkError = null;
|
|
1837
|
+
this.MAX_PAYLOAD_SIZE_BYTES = 5 * 1024 * 1024;
|
|
1838
|
+
this.MAX_QUEUE_SIZE = 500;
|
|
1839
|
+
this.MAX_DEAD_LETTER_SIZE = 200;
|
|
1137
1840
|
this._subscribers.clear();
|
|
1138
1841
|
QueueStorageFactory._reset();
|
|
1139
1842
|
}
|
|
1140
1843
|
}
|
|
1141
1844
|
|
|
1845
|
+
function hashIdentity(str) {
|
|
1846
|
+
if (typeof globalThis.process !== "undefined" && globalThis.process.versions?.node) {
|
|
1847
|
+
try {
|
|
1848
|
+
const getBuiltin = globalThis.process.getBuiltinModule;
|
|
1849
|
+
if (typeof getBuiltin === "function") {
|
|
1850
|
+
const crypto = getBuiltin("node:crypto");
|
|
1851
|
+
if (crypto?.createHash) {
|
|
1852
|
+
return crypto.createHash("sha256").update(str).digest("hex").slice(0, 16);
|
|
1853
|
+
}
|
|
1854
|
+
}
|
|
1855
|
+
const req = typeof require !== "undefined" ? require : globalThis.__non_webpack_require__;
|
|
1856
|
+
if (req) {
|
|
1857
|
+
const crypto = req("node:crypto");
|
|
1858
|
+
if (crypto?.createHash) {
|
|
1859
|
+
return crypto.createHash("sha256").update(str).digest("hex").slice(0, 16);
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1862
|
+
} catch {
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1865
|
+
let h1 = 3735928559 ^ 5381;
|
|
1866
|
+
let h2 = 1103547991 ^ 5381;
|
|
1867
|
+
for (let i = 0; i < str.length; i++) {
|
|
1868
|
+
const ch = str.charCodeAt(i);
|
|
1869
|
+
h1 = Math.imul(h1 ^ ch, 2654435761);
|
|
1870
|
+
h2 = Math.imul(h2 ^ ch, 1597334677);
|
|
1871
|
+
}
|
|
1872
|
+
h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
|
|
1873
|
+
h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
1874
|
+
return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(16);
|
|
1875
|
+
}
|
|
1142
1876
|
class RequestProvider {
|
|
1143
1877
|
cacheProvider = null;
|
|
1144
1878
|
cacheStrategy;
|
|
@@ -1189,6 +1923,15 @@ class RequestProvider {
|
|
|
1189
1923
|
onDataReceived(callback) {
|
|
1190
1924
|
this.dataReceivedCallback = callback;
|
|
1191
1925
|
}
|
|
1926
|
+
invokeDataReceivedCallback(data, generation) {
|
|
1927
|
+
if (this.dataReceivedCallback) {
|
|
1928
|
+
try {
|
|
1929
|
+
this.dataReceivedCallback(data, generation);
|
|
1930
|
+
} catch (err) {
|
|
1931
|
+
console.error("[RequestProvider] dataReceivedCallback threw an error:", err);
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1192
1935
|
hasLastUrl() {
|
|
1193
1936
|
return !!this.lastUrl;
|
|
1194
1937
|
}
|
|
@@ -1206,18 +1949,79 @@ class RequestProvider {
|
|
|
1206
1949
|
}
|
|
1207
1950
|
return this.request(this.lastUrl, options);
|
|
1208
1951
|
}
|
|
1952
|
+
resolveContext(options) {
|
|
1953
|
+
if (options?.context) return options.context;
|
|
1954
|
+
try {
|
|
1955
|
+
const getReqEvent = globalThis.useRequestEvent;
|
|
1956
|
+
if (typeof getReqEvent === "function") {
|
|
1957
|
+
const evt = getReqEvent();
|
|
1958
|
+
if (evt) return { event: evt };
|
|
1959
|
+
}
|
|
1960
|
+
const app = globalThis.__KATLUX_APP__ || (globalThis.useNuxtApp ? globalThis.useNuxtApp() : null);
|
|
1961
|
+
if (app?.ssrContext?.event) {
|
|
1962
|
+
return { event: app.ssrContext.event };
|
|
1963
|
+
}
|
|
1964
|
+
} catch {
|
|
1965
|
+
}
|
|
1966
|
+
return null;
|
|
1967
|
+
}
|
|
1968
|
+
getInFlightMap(options) {
|
|
1969
|
+
const ctx = this.resolveContext(options);
|
|
1970
|
+
const isServer = typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)) }) !== "undefined" && undefined || !!ctx?.event || !!ctx?.ssrContext || !!ctx?.node;
|
|
1971
|
+
if (isServer) {
|
|
1972
|
+
const event = ctx?.event ?? ctx?.ssrContext?.event ?? (ctx?.node ? ctx : null);
|
|
1973
|
+
if (event) {
|
|
1974
|
+
if (!event.context) event.context = {};
|
|
1975
|
+
if (!event.context.__katluxRequestsInFlight) {
|
|
1976
|
+
event.context.__katluxRequestsInFlight = /* @__PURE__ */ new Map();
|
|
1977
|
+
}
|
|
1978
|
+
return event.context.__katluxRequestsInFlight;
|
|
1979
|
+
}
|
|
1980
|
+
}
|
|
1981
|
+
return RequestProvider.requestsInFlight;
|
|
1982
|
+
}
|
|
1209
1983
|
getUniqueKey(url, options) {
|
|
1210
1984
|
const namespace = options?.cacheKey || this.cacheKey;
|
|
1211
|
-
if (options?.key) return namespace ? `${namespace}:${options.key}` : options.key;
|
|
1212
1985
|
const { query, body, headers, method } = options || {};
|
|
1213
1986
|
const stableStringify = (val) => JSON.stringify(val === void 0 ? null : val);
|
|
1214
|
-
|
|
1987
|
+
let serverAuthIdentity = "";
|
|
1988
|
+
const ctx = this.resolveContext(options);
|
|
1989
|
+
const isServer = typeof window === "undefined" || typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)) }) !== "undefined" && undefined || !!ctx?.event || !!ctx?.ssrContext || !!ctx?.node;
|
|
1990
|
+
if (isServer) {
|
|
1991
|
+
const event = ctx?.event ?? ctx?.ssrContext?.event ?? (ctx?.node ? ctx : null);
|
|
1992
|
+
if (event?.headers?.get) {
|
|
1993
|
+
serverAuthIdentity = event.headers.get("cookie") || event.headers.get("authorization") || "";
|
|
1994
|
+
} else if (event?.node?.req?.headers) {
|
|
1995
|
+
const reqH = event.node.req.headers;
|
|
1996
|
+
serverAuthIdentity = reqH["cookie"] || reqH["authorization"] || "";
|
|
1997
|
+
}
|
|
1998
|
+
}
|
|
1999
|
+
if (options?.key) {
|
|
2000
|
+
const authSuffix = serverAuthIdentity ? `|${hashIdentity(serverAuthIdentity)}` : "";
|
|
2001
|
+
const fullKey = `${options.key}${authSuffix}`;
|
|
2002
|
+
return namespace ? `${namespace}:${fullKey}` : fullKey;
|
|
2003
|
+
}
|
|
2004
|
+
let headersForCache = headers || {};
|
|
2005
|
+
if (!isServer && headers) {
|
|
2006
|
+
headersForCache = {};
|
|
2007
|
+
for (const [k, v] of Object.entries(headers)) {
|
|
2008
|
+
const lower = k.toLowerCase();
|
|
2009
|
+
if (lower !== "authorization" && lower !== "cookie") {
|
|
2010
|
+
headersForCache[k] = v;
|
|
2011
|
+
}
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
const parts = [
|
|
1215
2015
|
url,
|
|
1216
2016
|
stableStringify(query || {}),
|
|
1217
2017
|
stableStringify(body || null),
|
|
1218
|
-
stableStringify(
|
|
1219
|
-
|
|
1220
|
-
|
|
2018
|
+
stableStringify(headersForCache)
|
|
2019
|
+
];
|
|
2020
|
+
if (serverAuthIdentity) {
|
|
2021
|
+
parts.push(hashIdentity(serverAuthIdentity));
|
|
2022
|
+
}
|
|
2023
|
+
parts.push(method || "GET");
|
|
2024
|
+
const baseKey = parts.join("|");
|
|
1221
2025
|
return namespace ? `${namespace}:${baseKey}` : baseKey;
|
|
1222
2026
|
}
|
|
1223
2027
|
registerRequest(url, options) {
|
|
@@ -1234,15 +2038,16 @@ class RequestProvider {
|
|
|
1234
2038
|
label
|
|
1235
2039
|
});
|
|
1236
2040
|
}
|
|
2041
|
+
const inFlightMap = this.getInFlightMap(options);
|
|
1237
2042
|
const uniqueKey = this.getUniqueKey(url, options);
|
|
1238
|
-
const shouldDeduplicate = options?.deduplicate ?? this.deduplicate;
|
|
1239
|
-
if (shouldDeduplicate &&
|
|
1240
|
-
const inflightPromise =
|
|
2043
|
+
const shouldDeduplicate = (options?.deduplicate ?? this.deduplicate) && method === "GET";
|
|
2044
|
+
if (shouldDeduplicate && inFlightMap.has(uniqueKey)) {
|
|
2045
|
+
const inflightPromise = inFlightMap.get(uniqueKey);
|
|
1241
2046
|
return inflightPromise.then((result) => {
|
|
1242
2047
|
this.lastUrl = url;
|
|
1243
2048
|
this.lastOptions = options;
|
|
1244
|
-
if (
|
|
1245
|
-
this.
|
|
2049
|
+
if (method === "GET") {
|
|
2050
|
+
this.invokeDataReceivedCallback(result, options?._generation);
|
|
1246
2051
|
}
|
|
1247
2052
|
return result;
|
|
1248
2053
|
});
|
|
@@ -1258,11 +2063,11 @@ class RequestProvider {
|
|
|
1258
2063
|
RequestProvider.executeAll();
|
|
1259
2064
|
}).finally(() => {
|
|
1260
2065
|
if (shouldDeduplicate) {
|
|
1261
|
-
|
|
2066
|
+
inFlightMap.delete(uniqueKey);
|
|
1262
2067
|
}
|
|
1263
2068
|
});
|
|
1264
2069
|
if (shouldDeduplicate) {
|
|
1265
|
-
|
|
2070
|
+
inFlightMap.set(uniqueKey, promise);
|
|
1266
2071
|
}
|
|
1267
2072
|
return promise;
|
|
1268
2073
|
}
|
|
@@ -1282,18 +2087,45 @@ class RequestProvider {
|
|
|
1282
2087
|
}
|
|
1283
2088
|
});
|
|
1284
2089
|
}
|
|
2090
|
+
isSameOriginUrl(url, context) {
|
|
2091
|
+
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
|
2092
|
+
return true;
|
|
2093
|
+
}
|
|
2094
|
+
try {
|
|
2095
|
+
const targetUrl = new URL(url);
|
|
2096
|
+
if (typeof window !== "undefined" && typeof window.location !== "undefined") {
|
|
2097
|
+
return targetUrl.origin === window.location.origin;
|
|
2098
|
+
}
|
|
2099
|
+
const event = context?.event ?? context?.ssrContext?.event ?? (context?.node ? context : null);
|
|
2100
|
+
const host = event?.node?.req?.headers?.host || event?.headers?.get?.("host");
|
|
2101
|
+
if (host) {
|
|
2102
|
+
return targetUrl.host === host;
|
|
2103
|
+
}
|
|
2104
|
+
} catch {
|
|
2105
|
+
return false;
|
|
2106
|
+
}
|
|
2107
|
+
return false;
|
|
2108
|
+
}
|
|
1285
2109
|
async request(url, options) {
|
|
1286
2110
|
const { cacheStrategy, lifetime, query, body, headers, method } = options || {};
|
|
1287
2111
|
const uniqueKey = this.getUniqueKey(url, options);
|
|
1288
|
-
const
|
|
2112
|
+
const context = this.resolveContext(options);
|
|
1289
2113
|
let serverHeaders = {};
|
|
1290
|
-
|
|
1291
|
-
|
|
2114
|
+
const isServer = typeof window === "undefined" || typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)) }) !== "undefined" && undefined || !!context?.event || !!context?.ssrContext || !!context?.node;
|
|
2115
|
+
if (context && isServer && this.isSameOriginUrl(url, context)) {
|
|
2116
|
+
const event = context?.event ?? context?.ssrContext?.event ?? (context?.node ? context : null);
|
|
1292
2117
|
if (event) {
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
2118
|
+
try {
|
|
2119
|
+
const { getRequestHeader } = await import('h3');
|
|
2120
|
+
const cookieHeader = getRequestHeader(event, "cookie");
|
|
2121
|
+
if (cookieHeader) {
|
|
2122
|
+
serverHeaders = { cookie: cookieHeader };
|
|
2123
|
+
}
|
|
2124
|
+
} catch {
|
|
2125
|
+
const cookieHeader = event.node?.req?.headers?.cookie || event.headers?.get?.("cookie");
|
|
2126
|
+
if (cookieHeader) {
|
|
2127
|
+
serverHeaders = { cookie: cookieHeader };
|
|
2128
|
+
}
|
|
1297
2129
|
}
|
|
1298
2130
|
}
|
|
1299
2131
|
}
|
|
@@ -1301,49 +2133,72 @@ class RequestProvider {
|
|
|
1301
2133
|
const cacheLifetime = lifetime || this.cacheLifetime;
|
|
1302
2134
|
const requestMethod = method || "GET";
|
|
1303
2135
|
const isGetRequest = requestMethod === "GET";
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
2136
|
+
const effectiveHeaders = { ...headers, ...serverHeaders };
|
|
2137
|
+
const hasCookieOrAuth = !!serverHeaders.cookie || !!headers?.cookie || !!headers?.Cookie || !!headers?.authorization || !!headers?.Authorization;
|
|
2138
|
+
const isAppCache = provider instanceof CApplicationCache || provider?.constructor?.name === "CApplicationCache" || cacheStrategy === ECacheStrategy.Application;
|
|
2139
|
+
const isServerMemoryCache = typeof window === "undefined" && (provider instanceof CMemoryCache || provider?.constructor?.name === "CMemoryCache" || cacheStrategy === ECacheStrategy.Memory);
|
|
2140
|
+
const canReadFromCache = provider && isGetRequest && !options?.disableCache && !((isAppCache || isServerMemoryCache) && hasCookieOrAuth);
|
|
2141
|
+
if (canReadFromCache) {
|
|
2142
|
+
const cached = await provider.get(uniqueKey, context);
|
|
2143
|
+
if (cached !== null && cached !== void 0) {
|
|
1307
2144
|
this.lastUrl = url;
|
|
1308
2145
|
this.lastOptions = options;
|
|
1309
|
-
|
|
1310
|
-
this.dataReceivedCallback(cached);
|
|
1311
|
-
}
|
|
2146
|
+
this.invokeDataReceivedCallback(cached, options?._generation);
|
|
1312
2147
|
return cached;
|
|
1313
2148
|
}
|
|
1314
2149
|
}
|
|
1315
2150
|
const fetchOptions = {
|
|
1316
2151
|
method: requestMethod,
|
|
1317
2152
|
body,
|
|
1318
|
-
headers:
|
|
2153
|
+
headers: effectiveHeaders,
|
|
1319
2154
|
query,
|
|
2155
|
+
...options?.signal ? { signal: options.signal } : {},
|
|
1320
2156
|
...options?.disableCache ? { cache: "no-store" } : {}
|
|
1321
2157
|
};
|
|
1322
2158
|
const fetchFn = globalThis.$fetch || ofetch.$fetch;
|
|
1323
2159
|
const responseData = await fetchFn(url, fetchOptions);
|
|
1324
2160
|
let finalData = responseData;
|
|
1325
|
-
if (
|
|
1326
|
-
const cached = await provider.get(uniqueKey,
|
|
1327
|
-
if (cached) {
|
|
2161
|
+
if ((finalData === void 0 || finalData === null) && canReadFromCache) {
|
|
2162
|
+
const cached = await provider.get(uniqueKey, context);
|
|
2163
|
+
if (cached !== null && cached !== void 0) {
|
|
1328
2164
|
finalData = cached;
|
|
1329
2165
|
}
|
|
1330
2166
|
}
|
|
1331
|
-
|
|
1332
|
-
|
|
2167
|
+
const canWriteToCache = provider && cacheLifetime && (finalData !== void 0 && finalData !== null) && isGetRequest && !((isAppCache || isServerMemoryCache) && hasCookieOrAuth);
|
|
2168
|
+
if (canWriteToCache) {
|
|
2169
|
+
await provider.set(uniqueKey, finalData, cacheLifetime, context);
|
|
1333
2170
|
}
|
|
1334
2171
|
this.lastUrl = url;
|
|
1335
2172
|
this.lastOptions = options;
|
|
1336
|
-
if (
|
|
1337
|
-
this.
|
|
2173
|
+
if (isGetRequest && (finalData !== void 0 && finalData !== null)) {
|
|
2174
|
+
this.invokeDataReceivedCallback(finalData, options?._generation);
|
|
1338
2175
|
}
|
|
1339
2176
|
const requestTags = options?.tags || this.tags;
|
|
1340
2177
|
if (requestTags.length > 0 && requestMethod !== "GET") {
|
|
1341
|
-
|
|
2178
|
+
try {
|
|
2179
|
+
await RequestProviderRegistry.notifyMutation(requestTags);
|
|
2180
|
+
} catch (err) {
|
|
2181
|
+
console.warn("[RequestProvider] notifyMutation failed:", err);
|
|
2182
|
+
}
|
|
1342
2183
|
}
|
|
1343
2184
|
return finalData;
|
|
1344
2185
|
}
|
|
1345
2186
|
}
|
|
1346
2187
|
|
|
2188
|
+
function normalizeDataResult(result) {
|
|
2189
|
+
if (result === null || result === void 0) return null;
|
|
2190
|
+
if (Array.isArray(result)) {
|
|
2191
|
+
return { rows: result, rowCount: result.length };
|
|
2192
|
+
}
|
|
2193
|
+
if (typeof result === "object") {
|
|
2194
|
+
const rows = Array.isArray(result.rows) ? result.rows : Array.isArray(result.data) ? result.data : Array.isArray(result.items) ? result.items : null;
|
|
2195
|
+
if (rows !== null) {
|
|
2196
|
+
return { rows, rowCount: result.rowCount ?? result.total ?? rows.length };
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
return null;
|
|
2200
|
+
}
|
|
2201
|
+
|
|
1347
2202
|
class CAPIFlatClientDataProvider extends CFlatClientDataProvider {
|
|
1348
2203
|
apiUrl = "";
|
|
1349
2204
|
contextKey = "";
|
|
@@ -1356,78 +2211,73 @@ class CAPIFlatClientDataProvider extends CFlatClientDataProvider {
|
|
|
1356
2211
|
if (options?.cacheStrategy) this.cacheStrategy = options.cacheStrategy;
|
|
1357
2212
|
if (options?.cacheLifetime) this.cacheLifetime = options.cacheLifetime;
|
|
1358
2213
|
if (options?.refreshOnMutation !== void 0) this.refreshOnMutation = options.refreshOnMutation;
|
|
2214
|
+
if (options?.contextKey) this.contextKey = options.contextKey;
|
|
1359
2215
|
this.requestProvider.onDataReceived((data) => {
|
|
1360
2216
|
if (data) {
|
|
1361
|
-
|
|
2217
|
+
const normalized = normalizeDataResult(data);
|
|
2218
|
+
this.setData(normalized ? normalized.rows : data.rows || data);
|
|
1362
2219
|
}
|
|
1363
2220
|
});
|
|
1364
2221
|
}
|
|
1365
2222
|
setContextKey(key) {
|
|
1366
2223
|
this.contextKey = key;
|
|
1367
|
-
this.requestProvider.cacheKey = key;
|
|
1368
|
-
if (this.cacheStrategy) this.requestProvider.setCacheProvider(this.cacheStrategy);
|
|
1369
|
-
if (this.cacheLifetime) this.requestProvider.setCacheLifetime(this.cacheLifetime);
|
|
1370
2224
|
}
|
|
1371
|
-
|
|
1372
|
-
|
|
2225
|
+
setCacheStrategy(strategy) {
|
|
2226
|
+
this.cacheStrategy = strategy;
|
|
2227
|
+
this.requestProvider.setCacheProvider(strategy);
|
|
2228
|
+
}
|
|
2229
|
+
setCacheLifetime(lifetime) {
|
|
2230
|
+
this.cacheLifetime = lifetime;
|
|
2231
|
+
this.requestProvider.setCacheLifetime(lifetime);
|
|
1373
2232
|
}
|
|
1374
2233
|
async refreshData(options) {
|
|
1375
|
-
if (!this.requestProvider.hasLastUrl()) {
|
|
1376
|
-
await this._initialFetch(options?.disableCache ?? false);
|
|
1377
|
-
return;
|
|
1378
|
-
}
|
|
1379
2234
|
this.loading = true;
|
|
1380
2235
|
this.error = null;
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
} catch (err) {
|
|
1384
|
-
this.error = err;
|
|
1385
|
-
throw err;
|
|
1386
|
-
} finally {
|
|
1387
|
-
this.loading = false;
|
|
1388
|
-
}
|
|
1389
|
-
}
|
|
1390
|
-
async _initialFetch(disableCache = false) {
|
|
1391
|
-
if (!this.SSR && undefined) return;
|
|
2236
|
+
this.notify();
|
|
2237
|
+
const disableCache = options?.disableCache ?? false;
|
|
1392
2238
|
const fetcher = async () => {
|
|
1393
2239
|
const promise = this.requestProvider.registerRequest(this.apiUrl, {
|
|
1394
2240
|
deduplicate: this.deduplicate,
|
|
1395
|
-
nuxtApp: this.context,
|
|
1396
2241
|
context: this.context,
|
|
1397
2242
|
disableCache
|
|
1398
2243
|
});
|
|
1399
|
-
if (this.SSR && undefined) return await promise;
|
|
2244
|
+
if (this.SSR && typeof window === "undefined") return await promise;
|
|
1400
2245
|
return promise;
|
|
1401
2246
|
};
|
|
1402
2247
|
const key = `${this.contextKey}`;
|
|
1403
2248
|
if (this.contextKey && this.initialLoad && !disableCache) {
|
|
1404
|
-
const result =
|
|
1405
|
-
|
|
1406
|
-
|
|
2249
|
+
const result = getSSRData(key, this.context);
|
|
2250
|
+
const normalized = normalizeDataResult(result);
|
|
2251
|
+
if (normalized) {
|
|
2252
|
+
this.setData(normalized.rows);
|
|
1407
2253
|
this.initialLoad = false;
|
|
1408
2254
|
this.loading = false;
|
|
1409
2255
|
this.notify();
|
|
1410
2256
|
return;
|
|
1411
2257
|
}
|
|
1412
2258
|
}
|
|
1413
|
-
if (undefined && this.contextKey) {
|
|
2259
|
+
if (typeof window === "undefined" && this.contextKey) {
|
|
1414
2260
|
if (disableCache) {
|
|
1415
|
-
|
|
2261
|
+
clearSSRData(key, this.context);
|
|
1416
2262
|
}
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
2263
|
+
try {
|
|
2264
|
+
const result = await fetchWithSSR(key, fetcher, this.context);
|
|
2265
|
+
const normalized = normalizeDataResult(result);
|
|
2266
|
+
if (normalized) {
|
|
2267
|
+
this.setData(normalized.rows);
|
|
2268
|
+
return;
|
|
2269
|
+
}
|
|
2270
|
+
} finally {
|
|
1420
2271
|
this.initialLoad = false;
|
|
1421
2272
|
this.loading = false;
|
|
1422
2273
|
this.notify();
|
|
1423
|
-
return;
|
|
1424
2274
|
}
|
|
1425
2275
|
}
|
|
1426
2276
|
if (!this.SSR) {
|
|
1427
2277
|
try {
|
|
1428
2278
|
await this.requestProvider.registerRequest(this.apiUrl, {
|
|
1429
2279
|
deduplicate: this.deduplicate,
|
|
1430
|
-
|
|
2280
|
+
context: this.context,
|
|
1431
2281
|
disableCache
|
|
1432
2282
|
});
|
|
1433
2283
|
this.error = null;
|
|
@@ -1452,28 +2302,33 @@ class CAPIFlatClientDataProvider extends CFlatClientDataProvider {
|
|
|
1452
2302
|
}
|
|
1453
2303
|
async setAPIUrl(url) {
|
|
1454
2304
|
this.apiUrl = url;
|
|
1455
|
-
this.
|
|
2305
|
+
if (!this.contextKey) {
|
|
2306
|
+
this.setContextKey(this.urlPageParam ? `${url}:${this.urlPageParam}` : url);
|
|
2307
|
+
}
|
|
1456
2308
|
if (this.SSR && this.initialLoad) {
|
|
1457
|
-
const ssrData =
|
|
1458
|
-
|
|
1459
|
-
|
|
2309
|
+
const ssrData = getSSRData(this.contextKey, this.context);
|
|
2310
|
+
const normalized = normalizeDataResult(ssrData);
|
|
2311
|
+
if (normalized) {
|
|
2312
|
+
this.setData(normalized.rows);
|
|
1460
2313
|
this.initialLoad = false;
|
|
1461
2314
|
this.loading = false;
|
|
1462
2315
|
this.notify();
|
|
1463
2316
|
return;
|
|
1464
2317
|
}
|
|
1465
2318
|
}
|
|
1466
|
-
this.
|
|
1467
|
-
this.error = null;
|
|
1468
|
-
if (this.allData.length === 0)
|
|
2319
|
+
if (this.allData.length === 0) {
|
|
1469
2320
|
await this.refreshData();
|
|
2321
|
+
} else {
|
|
2322
|
+
this.loading = false;
|
|
2323
|
+
this.notify();
|
|
2324
|
+
}
|
|
1470
2325
|
}
|
|
1471
2326
|
async create(item) {
|
|
1472
2327
|
if (!this.apiUrl) return;
|
|
1473
2328
|
const result = await this.requestProvider.registerRequest(this.apiUrl, {
|
|
1474
2329
|
method: "POST",
|
|
1475
2330
|
body: item,
|
|
1476
|
-
|
|
2331
|
+
context: this.context
|
|
1477
2332
|
});
|
|
1478
2333
|
if (this.refreshOnMutation) {
|
|
1479
2334
|
await this.refresh(true);
|
|
@@ -1488,7 +2343,7 @@ class CAPIFlatClientDataProvider extends CFlatClientDataProvider {
|
|
|
1488
2343
|
await this.requestProvider.cacheProvider.removeByPrefix(this.apiUrl);
|
|
1489
2344
|
}
|
|
1490
2345
|
if (this.contextKey) {
|
|
1491
|
-
|
|
2346
|
+
clearSSRData(this.contextKey, this.context);
|
|
1492
2347
|
}
|
|
1493
2348
|
}
|
|
1494
2349
|
}
|
|
@@ -1497,18 +2352,17 @@ class CAPIFlatClientDataProvider extends CFlatClientDataProvider {
|
|
|
1497
2352
|
const result = await this.requestProvider.registerRequest(this.apiUrl, {
|
|
1498
2353
|
method: "PUT",
|
|
1499
2354
|
body: item,
|
|
1500
|
-
nuxtApp: this.context,
|
|
1501
2355
|
context: this.context
|
|
1502
2356
|
});
|
|
1503
2357
|
if (this.refreshOnMutation) {
|
|
1504
2358
|
await this.refresh(true);
|
|
1505
2359
|
} else {
|
|
1506
|
-
const index
|
|
1507
|
-
if (index
|
|
2360
|
+
const index = this.allData.findIndex((row) => row[this.idKey] === item[this.idKey]);
|
|
2361
|
+
if (index !== -1) {
|
|
1508
2362
|
if (result && result.item) {
|
|
1509
|
-
this.allData[index
|
|
2363
|
+
this.allData[index] = result.item;
|
|
1510
2364
|
} else {
|
|
1511
|
-
this.allData[index
|
|
2365
|
+
this.allData[index] = { ...this.allData[index], ...item };
|
|
1512
2366
|
}
|
|
1513
2367
|
this.loadPageData();
|
|
1514
2368
|
}
|
|
@@ -1516,7 +2370,7 @@ class CAPIFlatClientDataProvider extends CFlatClientDataProvider {
|
|
|
1516
2370
|
await this.requestProvider.cacheProvider.removeByPrefix(this.apiUrl);
|
|
1517
2371
|
}
|
|
1518
2372
|
if (this.contextKey) {
|
|
1519
|
-
|
|
2373
|
+
clearSSRData(this.contextKey, this.context);
|
|
1520
2374
|
}
|
|
1521
2375
|
}
|
|
1522
2376
|
}
|
|
@@ -1527,7 +2381,6 @@ class CAPIFlatClientDataProvider extends CFlatClientDataProvider {
|
|
|
1527
2381
|
await this.requestProvider.registerRequest(this.apiUrl, {
|
|
1528
2382
|
method: "DELETE",
|
|
1529
2383
|
body: { id: ids },
|
|
1530
|
-
nuxtApp: this.context,
|
|
1531
2384
|
context: this.context
|
|
1532
2385
|
});
|
|
1533
2386
|
if (this.refreshOnMutation) {
|
|
@@ -1540,7 +2393,7 @@ class CAPIFlatClientDataProvider extends CFlatClientDataProvider {
|
|
|
1540
2393
|
await this.requestProvider.cacheProvider.removeByPrefix(this.apiUrl);
|
|
1541
2394
|
}
|
|
1542
2395
|
if (this.contextKey) {
|
|
1543
|
-
|
|
2396
|
+
clearSSRData(this.contextKey, this.context);
|
|
1544
2397
|
}
|
|
1545
2398
|
}
|
|
1546
2399
|
}
|
|
@@ -1594,21 +2447,23 @@ class CFlatServerDataProvider extends ADataProvider {
|
|
|
1594
2447
|
);
|
|
1595
2448
|
try {
|
|
1596
2449
|
if (!options?.disableCache && this.SSR && this.contextKey && this.initialLoad) {
|
|
1597
|
-
const result =
|
|
1598
|
-
|
|
2450
|
+
const result = getSSRData(key, this.context);
|
|
2451
|
+
const normalized = normalizeDataResult(result);
|
|
2452
|
+
if (normalized) {
|
|
1599
2453
|
if (requestId !== this.latestRequestId) return;
|
|
1600
|
-
this.pageData =
|
|
1601
|
-
this.rowCount =
|
|
2454
|
+
this.pageData = normalized.rows;
|
|
2455
|
+
this.rowCount = normalized.rowCount;
|
|
1602
2456
|
this.initialLoad = false;
|
|
1603
2457
|
return;
|
|
1604
2458
|
}
|
|
1605
2459
|
}
|
|
1606
|
-
if (this.SSR && this.contextKey && !options?.disableCache && (undefined || this.initialLoad)) {
|
|
1607
|
-
const result = await
|
|
1608
|
-
|
|
2460
|
+
if (this.SSR && this.contextKey && !options?.disableCache && (typeof window === "undefined" || this.initialLoad)) {
|
|
2461
|
+
const result = await fetchWithSSR(key, fetcher, this.context);
|
|
2462
|
+
const normalized = normalizeDataResult(result);
|
|
2463
|
+
if (normalized) {
|
|
1609
2464
|
if (requestId !== this.latestRequestId) return;
|
|
1610
|
-
this.pageData =
|
|
1611
|
-
this.rowCount =
|
|
2465
|
+
this.pageData = normalized.rows;
|
|
2466
|
+
this.rowCount = normalized.rowCount;
|
|
1612
2467
|
this.initialLoad = false;
|
|
1613
2468
|
return;
|
|
1614
2469
|
}
|
|
@@ -1616,8 +2471,14 @@ class CFlatServerDataProvider extends ADataProvider {
|
|
|
1616
2471
|
const returnedData = await fetcher();
|
|
1617
2472
|
if (requestId !== this.latestRequestId) return;
|
|
1618
2473
|
if (returnedData) {
|
|
1619
|
-
|
|
1620
|
-
|
|
2474
|
+
const normalized = normalizeDataResult(returnedData);
|
|
2475
|
+
if (normalized) {
|
|
2476
|
+
this.pageData = normalized.rows;
|
|
2477
|
+
this.rowCount = normalized.rowCount;
|
|
2478
|
+
} else {
|
|
2479
|
+
this.pageData = returnedData.rows || [];
|
|
2480
|
+
this.rowCount = returnedData.rowCount ?? 0;
|
|
2481
|
+
}
|
|
1621
2482
|
}
|
|
1622
2483
|
this.initialLoad = false;
|
|
1623
2484
|
} catch (err) {
|
|
@@ -1646,12 +2507,15 @@ class CAPIFlatServerDataProvider extends CFlatServerDataProvider {
|
|
|
1646
2507
|
cacheLifetime = 0;
|
|
1647
2508
|
refreshOnMutation = true;
|
|
1648
2509
|
// Default true for server
|
|
2510
|
+
/** Incremented on every new request; stale onDataReceived callbacks are discarded. */
|
|
2511
|
+
_requestGeneration = 0;
|
|
1649
2512
|
constructor(options) {
|
|
1650
2513
|
super(options);
|
|
1651
2514
|
if (options?.cacheStrategy) this.cacheStrategy = options.cacheStrategy;
|
|
1652
2515
|
if (options?.cacheLifetime) this.cacheLifetime = options.cacheLifetime;
|
|
1653
2516
|
if (options?.refreshOnMutation !== void 0) this.refreshOnMutation = options.refreshOnMutation;
|
|
1654
|
-
this.requestProvider.onDataReceived((data) => {
|
|
2517
|
+
this.requestProvider.onDataReceived((data, generation) => {
|
|
2518
|
+
if (generation !== void 0 && generation !== this._requestGeneration) return;
|
|
1655
2519
|
if (data) {
|
|
1656
2520
|
this.pageData = data.rows || data;
|
|
1657
2521
|
if (data.rowCount !== void 0) {
|
|
@@ -1664,23 +2528,21 @@ class CAPIFlatServerDataProvider extends CFlatServerDataProvider {
|
|
|
1664
2528
|
if (hardRefresh && this.requestProvider.cacheProvider) {
|
|
1665
2529
|
await this.requestProvider.cacheProvider.removeByPrefix(this.apiUrl);
|
|
1666
2530
|
}
|
|
1667
|
-
this.
|
|
1668
|
-
try {
|
|
1669
|
-
await this.loadPageData(hardRefresh ? { disableCache: true } : void 0);
|
|
1670
|
-
} finally {
|
|
1671
|
-
this.loading = false;
|
|
1672
|
-
}
|
|
2531
|
+
await this.loadPageData(hardRefresh ? { disableCache: true } : void 0);
|
|
1673
2532
|
}
|
|
1674
2533
|
async refreshData(options) {
|
|
1675
2534
|
await this.refresh(options?.disableCache ?? false);
|
|
1676
2535
|
}
|
|
1677
2536
|
async setAPIUrl(url) {
|
|
1678
2537
|
this.apiUrl = url;
|
|
1679
|
-
this.
|
|
2538
|
+
if (!this.contextKey) {
|
|
2539
|
+
this.setContextKey(this.urlPageParam ? `${url}:${this.urlPageParam}` : url);
|
|
2540
|
+
}
|
|
1680
2541
|
if (this.cacheStrategy) this.requestProvider.setCacheProvider(this.cacheStrategy);
|
|
1681
2542
|
if (this.cacheLifetime) this.requestProvider.setCacheLifetime(this.cacheLifetime);
|
|
1682
2543
|
await this.setPageDataHandler(
|
|
1683
2544
|
async (currentPage, pageSize, filter, sortList, options) => {
|
|
2545
|
+
const generation = ++this._requestGeneration;
|
|
1684
2546
|
const queryParams = {
|
|
1685
2547
|
pageNumber: currentPage,
|
|
1686
2548
|
pageSize
|
|
@@ -1691,13 +2553,16 @@ class CAPIFlatServerDataProvider extends CFlatServerDataProvider {
|
|
|
1691
2553
|
if (sortList && sortList.length > 0) {
|
|
1692
2554
|
queryParams.sortList = sortList;
|
|
1693
2555
|
}
|
|
1694
|
-
|
|
2556
|
+
const result = await this.requestProvider.registerRequest(this.apiUrl, {
|
|
1695
2557
|
query: queryParams,
|
|
1696
2558
|
deduplicate: this.deduplicate,
|
|
1697
|
-
nuxtApp: this.context,
|
|
1698
2559
|
context: this.context,
|
|
1699
|
-
disableCache: options?.disableCache
|
|
2560
|
+
disableCache: options?.disableCache,
|
|
2561
|
+
signal: options?.signal,
|
|
2562
|
+
_generation: generation
|
|
1700
2563
|
});
|
|
2564
|
+
if (generation !== this._requestGeneration) return { rows: [], rowCount: 0 };
|
|
2565
|
+
return result;
|
|
1701
2566
|
}
|
|
1702
2567
|
);
|
|
1703
2568
|
}
|
|
@@ -1708,7 +2573,6 @@ class CAPIFlatServerDataProvider extends CFlatServerDataProvider {
|
|
|
1708
2573
|
await this.requestProvider.registerRequest(this.apiUrl, {
|
|
1709
2574
|
method: "DELETE",
|
|
1710
2575
|
body: { id: ids },
|
|
1711
|
-
nuxtApp: this.context,
|
|
1712
2576
|
context: this.context
|
|
1713
2577
|
});
|
|
1714
2578
|
if (this.refreshOnMutation !== false) {
|
|
@@ -1723,7 +2587,6 @@ class CAPIFlatServerDataProvider extends CFlatServerDataProvider {
|
|
|
1723
2587
|
await this.requestProvider.registerRequest(this.apiUrl, {
|
|
1724
2588
|
method: "POST",
|
|
1725
2589
|
body: item,
|
|
1726
|
-
nuxtApp: this.context,
|
|
1727
2590
|
context: this.context
|
|
1728
2591
|
});
|
|
1729
2592
|
if (this.refreshOnMutation !== false) {
|
|
@@ -1738,7 +2601,6 @@ class CAPIFlatServerDataProvider extends CFlatServerDataProvider {
|
|
|
1738
2601
|
await this.requestProvider.registerRequest(this.apiUrl, {
|
|
1739
2602
|
method: "PUT",
|
|
1740
2603
|
body: item,
|
|
1741
|
-
nuxtApp: this.context,
|
|
1742
2604
|
context: this.context
|
|
1743
2605
|
});
|
|
1744
2606
|
if (this.refreshOnMutation !== false) {
|
|
@@ -1906,22 +2768,46 @@ class CTreeClientDataProvider extends CFlatClientDataProvider {
|
|
|
1906
2768
|
}
|
|
1907
2769
|
return sortedIds;
|
|
1908
2770
|
}
|
|
1909
|
-
isNodeVisible(node, nodeMap) {
|
|
1910
|
-
if (
|
|
2771
|
+
isNodeVisible(node, nodeMap, visibilityCache) {
|
|
2772
|
+
if (visibilityCache?.has(node.id)) {
|
|
2773
|
+
return visibilityCache.get(node.id);
|
|
2774
|
+
}
|
|
2775
|
+
if (node.parentId === null || !nodeMap.has(node.parentId)) {
|
|
2776
|
+
visibilityCache?.set(node.id, true);
|
|
2777
|
+
return true;
|
|
2778
|
+
}
|
|
2779
|
+
if (visibilityCache?.has(node.parentId)) {
|
|
2780
|
+
const parentVisible = visibilityCache.get(node.parentId);
|
|
2781
|
+
const isVisible2 = parentVisible && this.expandedNodes.has(node.parentId);
|
|
2782
|
+
visibilityCache.set(node.id, isVisible2);
|
|
2783
|
+
return isVisible2;
|
|
2784
|
+
}
|
|
1911
2785
|
const visited = /* @__PURE__ */ new Set([node.id]);
|
|
1912
2786
|
let currentId = node.parentId;
|
|
2787
|
+
let isVisible = true;
|
|
1913
2788
|
while (currentId !== null) {
|
|
1914
2789
|
if (visited.has(currentId)) {
|
|
1915
|
-
|
|
2790
|
+
break;
|
|
1916
2791
|
}
|
|
1917
2792
|
visited.add(currentId);
|
|
2793
|
+
if (visibilityCache?.has(currentId)) {
|
|
2794
|
+
const ancestorVisible = visibilityCache.get(currentId);
|
|
2795
|
+
if (!ancestorVisible) {
|
|
2796
|
+
isVisible = false;
|
|
2797
|
+
break;
|
|
2798
|
+
}
|
|
2799
|
+
}
|
|
1918
2800
|
const parent = nodeMap.get(currentId);
|
|
1919
|
-
if (!parent)
|
|
2801
|
+
if (!parent) break;
|
|
1920
2802
|
const parentExpanded = this.expandedNodes.has(currentId);
|
|
1921
|
-
if (!parentExpanded)
|
|
2803
|
+
if (!parentExpanded) {
|
|
2804
|
+
isVisible = false;
|
|
2805
|
+
break;
|
|
2806
|
+
}
|
|
1922
2807
|
currentId = parent.parentId !== null && nodeMap.has(parent.parentId) ? parent.parentId : null;
|
|
1923
2808
|
}
|
|
1924
|
-
|
|
2809
|
+
visibilityCache?.set(node.id, isVisible);
|
|
2810
|
+
return isVisible;
|
|
1925
2811
|
}
|
|
1926
2812
|
paginateNodes(visible) {
|
|
1927
2813
|
const pageSize = this.pageSize;
|
|
@@ -1977,25 +2863,29 @@ class CTreeClientDataProvider extends CFlatClientDataProvider {
|
|
|
1977
2863
|
current = current.parentId != null ? nodeMap.get(current.parentId) : void 0;
|
|
1978
2864
|
}
|
|
1979
2865
|
});
|
|
2866
|
+
const filterExpanded = new Set(this.expandedNodes);
|
|
1980
2867
|
visibleIds.forEach((id) => {
|
|
1981
2868
|
if (nodeMap.get(id)?.hasChildren) {
|
|
1982
|
-
|
|
2869
|
+
filterExpanded.add(id);
|
|
1983
2870
|
}
|
|
1984
2871
|
});
|
|
1985
2872
|
const filteredNodes = sortedIds.filter((id) => visibleIds.has(id)).map((id) => {
|
|
1986
2873
|
const node = nodeMap.get(id);
|
|
1987
2874
|
return {
|
|
1988
2875
|
...node,
|
|
1989
|
-
isExpanded:
|
|
2876
|
+
isExpanded: filterExpanded.has(id)
|
|
1990
2877
|
};
|
|
1991
2878
|
});
|
|
1992
2879
|
this.filteredData = filteredNodes;
|
|
1993
|
-
|
|
2880
|
+
const paginated = this.paginateNodes(filteredNodes);
|
|
2881
|
+
this.pageData = paginated.map((node) => ({
|
|
1994
2882
|
...node.data,
|
|
1995
2883
|
...node,
|
|
1996
2884
|
__treeNode: node
|
|
1997
2885
|
}));
|
|
1998
|
-
this.
|
|
2886
|
+
if (this.allData.length > 0) {
|
|
2887
|
+
this.initialLoad = false;
|
|
2888
|
+
}
|
|
1999
2889
|
return;
|
|
2000
2890
|
}
|
|
2001
2891
|
const visible = this.visibleRows;
|
|
@@ -2033,10 +2923,11 @@ class CTreeClientDataProvider extends CFlatClientDataProvider {
|
|
|
2033
2923
|
const nodeMap = this._nodeMap;
|
|
2034
2924
|
const sortedIds = this._sortedNodeIds;
|
|
2035
2925
|
const visibleNodes = [];
|
|
2926
|
+
const visibilityCache = /* @__PURE__ */ new Map();
|
|
2036
2927
|
for (const id of sortedIds) {
|
|
2037
2928
|
const staticNode = nodeMap.get(id);
|
|
2038
2929
|
if (!staticNode) continue;
|
|
2039
|
-
if (this.isNodeVisible(staticNode, nodeMap)) {
|
|
2930
|
+
if (this.isNodeVisible(staticNode, nodeMap, visibilityCache)) {
|
|
2040
2931
|
visibleNodes.push({
|
|
2041
2932
|
...staticNode,
|
|
2042
2933
|
isExpanded: this.expandedNodes.has(id)
|
|
@@ -2117,9 +3008,11 @@ class CAPITreeClientDataProvider extends CTreeClientDataProvider {
|
|
|
2117
3008
|
if (options?.cacheStrategy) this.cacheStrategy = options.cacheStrategy;
|
|
2118
3009
|
if (options?.cacheLifetime) this.cacheLifetime = options.cacheLifetime;
|
|
2119
3010
|
if (options?.refreshOnMutation !== void 0) this.refreshOnMutation = options.refreshOnMutation;
|
|
3011
|
+
if (options?.contextKey) this.contextKey = options.contextKey;
|
|
2120
3012
|
this.requestProvider.onDataReceived((data) => {
|
|
2121
3013
|
if (data) {
|
|
2122
|
-
|
|
3014
|
+
const normalized = normalizeDataResult(data);
|
|
3015
|
+
this.setData(normalized ? normalized.rows : data.rows || data);
|
|
2123
3016
|
}
|
|
2124
3017
|
});
|
|
2125
3018
|
}
|
|
@@ -2150,46 +3043,50 @@ class CAPITreeClientDataProvider extends CTreeClientDataProvider {
|
|
|
2150
3043
|
}
|
|
2151
3044
|
}
|
|
2152
3045
|
async _initialFetch(disableCache = false) {
|
|
2153
|
-
if (!this.SSR && undefined) return;
|
|
3046
|
+
if (!this.SSR && typeof window === "undefined") return;
|
|
2154
3047
|
const fetcher = async () => {
|
|
2155
3048
|
const promise = this.requestProvider.registerRequest(this.apiUrl, {
|
|
2156
3049
|
deduplicate: this.deduplicate,
|
|
2157
|
-
nuxtApp: this.context,
|
|
2158
3050
|
context: this.context,
|
|
2159
3051
|
disableCache
|
|
2160
3052
|
});
|
|
2161
|
-
if (this.SSR && undefined) return await promise;
|
|
3053
|
+
if (this.SSR && typeof window === "undefined") return await promise;
|
|
2162
3054
|
return promise;
|
|
2163
3055
|
};
|
|
2164
3056
|
const key = `${this.contextKey}`;
|
|
2165
3057
|
if (this.contextKey && this.initialLoad && !disableCache) {
|
|
2166
|
-
const result =
|
|
2167
|
-
|
|
2168
|
-
|
|
3058
|
+
const result = getSSRData(key, this.context);
|
|
3059
|
+
const normalized = normalizeDataResult(result);
|
|
3060
|
+
if (normalized) {
|
|
3061
|
+
this.setData(normalized.rows);
|
|
2169
3062
|
this.initialLoad = false;
|
|
2170
3063
|
this.loading = false;
|
|
2171
3064
|
this.notify();
|
|
2172
3065
|
return;
|
|
2173
3066
|
}
|
|
2174
3067
|
}
|
|
2175
|
-
if (undefined && this.contextKey) {
|
|
3068
|
+
if (typeof window === "undefined" && this.contextKey) {
|
|
2176
3069
|
if (disableCache) {
|
|
2177
|
-
|
|
3070
|
+
clearSSRData(key, this.context);
|
|
2178
3071
|
}
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
3072
|
+
try {
|
|
3073
|
+
const result = await fetchWithSSR(key, fetcher, this.context);
|
|
3074
|
+
const normalized = normalizeDataResult(result);
|
|
3075
|
+
if (normalized) {
|
|
3076
|
+
this.setData(normalized.rows);
|
|
3077
|
+
return;
|
|
3078
|
+
}
|
|
3079
|
+
} finally {
|
|
2182
3080
|
this.initialLoad = false;
|
|
2183
3081
|
this.loading = false;
|
|
2184
3082
|
this.notify();
|
|
2185
|
-
return;
|
|
2186
3083
|
}
|
|
2187
3084
|
}
|
|
2188
3085
|
if (!this.SSR) {
|
|
2189
3086
|
try {
|
|
2190
3087
|
await this.requestProvider.registerRequest(this.apiUrl, {
|
|
2191
3088
|
deduplicate: this.deduplicate,
|
|
2192
|
-
|
|
3089
|
+
context: this.context,
|
|
2193
3090
|
disableCache
|
|
2194
3091
|
});
|
|
2195
3092
|
this.error = null;
|
|
@@ -2213,19 +3110,34 @@ class CAPITreeClientDataProvider extends CTreeClientDataProvider {
|
|
|
2213
3110
|
}
|
|
2214
3111
|
}
|
|
2215
3112
|
async setAPIUrl(url) {
|
|
2216
|
-
this.loading = true;
|
|
2217
|
-
this.error = null;
|
|
2218
3113
|
this.apiUrl = url;
|
|
2219
|
-
this.
|
|
2220
|
-
|
|
3114
|
+
if (!this.contextKey) {
|
|
3115
|
+
this.setContextKey(this.urlPageParam ? `${url}:${this.urlPageParam}` : url);
|
|
3116
|
+
}
|
|
3117
|
+
if (this.SSR && this.initialLoad) {
|
|
3118
|
+
const ssrData = getSSRData(this.contextKey, this.context);
|
|
3119
|
+
const normalized = normalizeDataResult(ssrData);
|
|
3120
|
+
if (normalized) {
|
|
3121
|
+
this.setData(normalized.rows);
|
|
3122
|
+
this.initialLoad = false;
|
|
3123
|
+
this.loading = false;
|
|
3124
|
+
this.notify();
|
|
3125
|
+
return;
|
|
3126
|
+
}
|
|
3127
|
+
}
|
|
3128
|
+
if (this.allData.length === 0) {
|
|
2221
3129
|
await this.refreshData();
|
|
3130
|
+
} else {
|
|
3131
|
+
this.loading = false;
|
|
3132
|
+
this.notify();
|
|
3133
|
+
}
|
|
2222
3134
|
}
|
|
2223
3135
|
async create(item) {
|
|
2224
3136
|
if (!this.apiUrl) return;
|
|
2225
3137
|
const result = await this.requestProvider.registerRequest(this.apiUrl, {
|
|
2226
3138
|
method: "POST",
|
|
2227
3139
|
body: item,
|
|
2228
|
-
|
|
3140
|
+
context: this.context
|
|
2229
3141
|
});
|
|
2230
3142
|
if (this.refreshOnMutation) {
|
|
2231
3143
|
await this.refresh(true);
|
|
@@ -2241,7 +3153,7 @@ class CAPITreeClientDataProvider extends CTreeClientDataProvider {
|
|
|
2241
3153
|
await this.requestProvider.cacheProvider.removeByPrefix(this.apiUrl);
|
|
2242
3154
|
}
|
|
2243
3155
|
if (this.contextKey) {
|
|
2244
|
-
|
|
3156
|
+
clearSSRData(this.contextKey, this.context);
|
|
2245
3157
|
}
|
|
2246
3158
|
}
|
|
2247
3159
|
}
|
|
@@ -2250,18 +3162,17 @@ class CAPITreeClientDataProvider extends CTreeClientDataProvider {
|
|
|
2250
3162
|
const result = await this.requestProvider.registerRequest(this.apiUrl, {
|
|
2251
3163
|
method: "PUT",
|
|
2252
3164
|
body: item,
|
|
2253
|
-
nuxtApp: this.context,
|
|
2254
3165
|
context: this.context
|
|
2255
3166
|
});
|
|
2256
3167
|
if (this.refreshOnMutation) {
|
|
2257
3168
|
await this.refresh(true);
|
|
2258
3169
|
} else {
|
|
2259
|
-
const index
|
|
2260
|
-
if (index
|
|
3170
|
+
const index = this.allData.findIndex((row) => row[this.idKey] === item[this.idKey]);
|
|
3171
|
+
if (index !== -1) {
|
|
2261
3172
|
if (result && result.item) {
|
|
2262
|
-
this.allData[index
|
|
3173
|
+
this.allData[index] = result.item;
|
|
2263
3174
|
} else {
|
|
2264
|
-
this.allData[index
|
|
3175
|
+
this.allData[index] = { ...this.allData[index], ...item };
|
|
2265
3176
|
}
|
|
2266
3177
|
this.invalidateStaticCache();
|
|
2267
3178
|
this.loadPageData();
|
|
@@ -2270,7 +3181,7 @@ class CAPITreeClientDataProvider extends CTreeClientDataProvider {
|
|
|
2270
3181
|
await this.requestProvider.cacheProvider.removeByPrefix(this.apiUrl);
|
|
2271
3182
|
}
|
|
2272
3183
|
if (this.contextKey) {
|
|
2273
|
-
|
|
3184
|
+
clearSSRData(this.contextKey, this.context);
|
|
2274
3185
|
}
|
|
2275
3186
|
}
|
|
2276
3187
|
}
|
|
@@ -2281,7 +3192,6 @@ class CAPITreeClientDataProvider extends CTreeClientDataProvider {
|
|
|
2281
3192
|
await this.requestProvider.registerRequest(this.apiUrl, {
|
|
2282
3193
|
method: "DELETE",
|
|
2283
3194
|
body: { id: ids },
|
|
2284
|
-
nuxtApp: this.context,
|
|
2285
3195
|
context: this.context
|
|
2286
3196
|
});
|
|
2287
3197
|
if (this.refreshOnMutation) {
|
|
@@ -2295,7 +3205,7 @@ class CAPITreeClientDataProvider extends CTreeClientDataProvider {
|
|
|
2295
3205
|
await this.requestProvider.cacheProvider.removeByPrefix(this.apiUrl);
|
|
2296
3206
|
}
|
|
2297
3207
|
if (this.contextKey) {
|
|
2298
|
-
|
|
3208
|
+
clearSSRData(this.contextKey, this.context);
|
|
2299
3209
|
}
|
|
2300
3210
|
}
|
|
2301
3211
|
}
|
|
@@ -2374,21 +3284,23 @@ class CTreeServerDataProvider extends ADataProvider {
|
|
|
2374
3284
|
);
|
|
2375
3285
|
try {
|
|
2376
3286
|
if (!options?.disableCache && this.SSR && this.contextKey && this.initialLoad) {
|
|
2377
|
-
const result =
|
|
2378
|
-
|
|
3287
|
+
const result = getSSRData(key, this.context);
|
|
3288
|
+
const normalized = normalizeDataResult(result);
|
|
3289
|
+
if (normalized) {
|
|
2379
3290
|
if (requestId !== this.latestRequestId) return;
|
|
2380
|
-
this.pageData =
|
|
2381
|
-
this.rowCount =
|
|
3291
|
+
this.pageData = normalized.rows;
|
|
3292
|
+
this.rowCount = normalized.rowCount;
|
|
2382
3293
|
this.initialLoad = false;
|
|
2383
3294
|
return;
|
|
2384
3295
|
}
|
|
2385
3296
|
}
|
|
2386
|
-
if (this.SSR && this.contextKey && !options?.disableCache && (undefined || this.initialLoad)) {
|
|
2387
|
-
const result = await
|
|
2388
|
-
|
|
3297
|
+
if (this.SSR && this.contextKey && !options?.disableCache && (typeof window === "undefined" || this.initialLoad)) {
|
|
3298
|
+
const result = await fetchWithSSR(key, fetcher, this.context);
|
|
3299
|
+
const normalized = normalizeDataResult(result);
|
|
3300
|
+
if (normalized) {
|
|
2389
3301
|
if (requestId !== this.latestRequestId) return;
|
|
2390
|
-
this.pageData =
|
|
2391
|
-
this.rowCount =
|
|
3302
|
+
this.pageData = normalized.rows;
|
|
3303
|
+
this.rowCount = normalized.rowCount;
|
|
2392
3304
|
this.initialLoad = false;
|
|
2393
3305
|
return;
|
|
2394
3306
|
}
|
|
@@ -2396,8 +3308,14 @@ class CTreeServerDataProvider extends ADataProvider {
|
|
|
2396
3308
|
const returnedData = await fetcher();
|
|
2397
3309
|
if (requestId !== this.latestRequestId) return;
|
|
2398
3310
|
if (returnedData) {
|
|
2399
|
-
|
|
2400
|
-
|
|
3311
|
+
const normalized = normalizeDataResult(returnedData);
|
|
3312
|
+
if (normalized) {
|
|
3313
|
+
this.pageData = normalized.rows;
|
|
3314
|
+
this.rowCount = normalized.rowCount;
|
|
3315
|
+
} else {
|
|
3316
|
+
this.pageData = returnedData.rows || [];
|
|
3317
|
+
this.rowCount = returnedData.rowCount ?? 0;
|
|
3318
|
+
}
|
|
2401
3319
|
}
|
|
2402
3320
|
this.initialLoad = false;
|
|
2403
3321
|
} catch (err) {
|
|
@@ -2469,12 +3387,15 @@ class CAPITreeServerDataProvider extends CTreeServerDataProvider {
|
|
|
2469
3387
|
cacheLifetime = 0;
|
|
2470
3388
|
refreshOnMutation = true;
|
|
2471
3389
|
// Default true for server
|
|
3390
|
+
/** Incremented on every new request; stale onDataReceived callbacks are discarded. */
|
|
3391
|
+
_requestGeneration = 0;
|
|
2472
3392
|
constructor(options) {
|
|
2473
3393
|
super(options);
|
|
2474
3394
|
if (options?.cacheStrategy) this.cacheStrategy = options.cacheStrategy;
|
|
2475
3395
|
if (options?.cacheLifetime) this.cacheLifetime = options.cacheLifetime;
|
|
2476
3396
|
if (options?.refreshOnMutation !== void 0) this.refreshOnMutation = options.refreshOnMutation;
|
|
2477
|
-
this.requestProvider.onDataReceived((data) => {
|
|
3397
|
+
this.requestProvider.onDataReceived((data, generation) => {
|
|
3398
|
+
if (generation !== void 0 && generation !== this._requestGeneration) return;
|
|
2478
3399
|
if (data) {
|
|
2479
3400
|
this.pageData = data.rows || data;
|
|
2480
3401
|
if (data.rowCount !== void 0) {
|
|
@@ -2488,24 +3409,22 @@ class CAPITreeServerDataProvider extends CTreeServerDataProvider {
|
|
|
2488
3409
|
if (hardRefresh && this.requestProvider.cacheProvider) {
|
|
2489
3410
|
await this.requestProvider.cacheProvider.removeByPrefix(this.apiUrl);
|
|
2490
3411
|
}
|
|
2491
|
-
this.
|
|
2492
|
-
try {
|
|
2493
|
-
await this.loadPageData(hardRefresh ? { disableCache: true } : void 0);
|
|
2494
|
-
} finally {
|
|
2495
|
-
this.loading = false;
|
|
2496
|
-
}
|
|
3412
|
+
await this.loadPageData(hardRefresh ? { disableCache: true } : void 0);
|
|
2497
3413
|
}
|
|
2498
3414
|
async refreshData(options) {
|
|
2499
3415
|
await this.refresh(options?.disableCache ?? false);
|
|
2500
3416
|
}
|
|
2501
3417
|
async setAPIUrl(url) {
|
|
2502
3418
|
this.apiUrl = url;
|
|
2503
|
-
this.
|
|
3419
|
+
if (!this.contextKey) {
|
|
3420
|
+
this.setContextKey(this.urlPageParam ? `${url}:${this.urlPageParam}` : url);
|
|
3421
|
+
}
|
|
2504
3422
|
if (this.cacheStrategy) this.requestProvider.setCacheProvider(this.cacheStrategy);
|
|
2505
3423
|
if (this.cacheLifetime) this.requestProvider.setCacheLifetime(this.cacheLifetime);
|
|
2506
3424
|
await this.setPageDataHandler(
|
|
2507
3425
|
async (currentPage, pageSize, filter, sortList, treeParams, options) => {
|
|
2508
|
-
|
|
3426
|
+
const generation = ++this._requestGeneration;
|
|
3427
|
+
const result = await this.requestProvider.registerRequest(this.apiUrl, {
|
|
2509
3428
|
query: {
|
|
2510
3429
|
pageNumber: currentPage,
|
|
2511
3430
|
pageSize,
|
|
@@ -2519,10 +3438,13 @@ class CAPITreeServerDataProvider extends CTreeServerDataProvider {
|
|
|
2519
3438
|
expandedByDefault: treeParams.expandedByDefault
|
|
2520
3439
|
},
|
|
2521
3440
|
deduplicate: this.deduplicate,
|
|
2522
|
-
nuxtApp: this.context,
|
|
2523
3441
|
context: this.context,
|
|
2524
|
-
disableCache: options?.disableCache
|
|
3442
|
+
disableCache: options?.disableCache,
|
|
3443
|
+
signal: options?.signal,
|
|
3444
|
+
_generation: generation
|
|
2525
3445
|
});
|
|
3446
|
+
if (generation !== this._requestGeneration) return { rows: [], rowCount: 0 };
|
|
3447
|
+
return result;
|
|
2526
3448
|
}
|
|
2527
3449
|
);
|
|
2528
3450
|
}
|
|
@@ -2533,7 +3455,6 @@ class CAPITreeServerDataProvider extends CTreeServerDataProvider {
|
|
|
2533
3455
|
await this.requestProvider.registerRequest(this.apiUrl, {
|
|
2534
3456
|
method: "DELETE",
|
|
2535
3457
|
body: { id: ids },
|
|
2536
|
-
nuxtApp: this.context,
|
|
2537
3458
|
context: this.context
|
|
2538
3459
|
});
|
|
2539
3460
|
if (this.refreshOnMutation !== false) {
|
|
@@ -2548,7 +3469,6 @@ class CAPITreeServerDataProvider extends CTreeServerDataProvider {
|
|
|
2548
3469
|
await this.requestProvider.registerRequest(this.apiUrl, {
|
|
2549
3470
|
method: "POST",
|
|
2550
3471
|
body: item,
|
|
2551
|
-
nuxtApp: this.context,
|
|
2552
3472
|
context: this.context
|
|
2553
3473
|
});
|
|
2554
3474
|
if (this.refreshOnMutation !== false) {
|
|
@@ -2563,7 +3483,6 @@ class CAPITreeServerDataProvider extends CTreeServerDataProvider {
|
|
|
2563
3483
|
await this.requestProvider.registerRequest(this.apiUrl, {
|
|
2564
3484
|
method: "PUT",
|
|
2565
3485
|
body: item,
|
|
2566
|
-
nuxtApp: this.context,
|
|
2567
3486
|
context: this.context
|
|
2568
3487
|
});
|
|
2569
3488
|
if (this.refreshOnMutation !== false) {
|
|
@@ -2599,11 +3518,12 @@ class CCookieCache extends ACacheProvider {
|
|
|
2599
3518
|
}
|
|
2600
3519
|
return null;
|
|
2601
3520
|
}
|
|
2602
|
-
isClient(
|
|
2603
|
-
|
|
3521
|
+
isClient(context) {
|
|
3522
|
+
const isExplicitServer = typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)) }) !== "undefined" && undefined || !!context?.event || !!context?.ssrContext || !!context?.node;
|
|
3523
|
+
return typeof document !== "undefined" && !isExplicitServer || typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)) }) !== "undefined" && !!undefined && !isExplicitServer;
|
|
2604
3524
|
}
|
|
2605
|
-
async getKeyList(
|
|
2606
|
-
if (this.isClient(
|
|
3525
|
+
async getKeyList(context) {
|
|
3526
|
+
if (this.isClient(context)) {
|
|
2607
3527
|
const cookieStr = typeof document !== "undefined" ? document.cookie : "";
|
|
2608
3528
|
if (!cookieStr) return [];
|
|
2609
3529
|
const keys = [];
|
|
@@ -2620,8 +3540,8 @@ class CCookieCache extends ACacheProvider {
|
|
|
2620
3540
|
}
|
|
2621
3541
|
}
|
|
2622
3542
|
return keys;
|
|
2623
|
-
} else if (
|
|
2624
|
-
const event =
|
|
3543
|
+
} else if (context) {
|
|
3544
|
+
const event = context?.event ?? context?.ssrContext?.event ?? (context?.node ? context : null);
|
|
2625
3545
|
if (event) {
|
|
2626
3546
|
const cookies = h3.parseCookies(event);
|
|
2627
3547
|
const keys = [];
|
|
@@ -2634,10 +3554,10 @@ class CCookieCache extends ACacheProvider {
|
|
|
2634
3554
|
}
|
|
2635
3555
|
return [];
|
|
2636
3556
|
}
|
|
2637
|
-
async get(key,
|
|
3557
|
+
async get(key, context) {
|
|
2638
3558
|
const cookieKey = this.getCookieKey(key);
|
|
2639
3559
|
let rawValue = null;
|
|
2640
|
-
if (this.isClient(
|
|
3560
|
+
if (this.isClient(context)) {
|
|
2641
3561
|
const namePrefix = cookieKey + "=";
|
|
2642
3562
|
const cookies = (typeof document !== "undefined" ? document.cookie : "").split(";");
|
|
2643
3563
|
for (let i = 0; i < cookies.length; i++) {
|
|
@@ -2647,10 +3567,14 @@ class CCookieCache extends ACacheProvider {
|
|
|
2647
3567
|
break;
|
|
2648
3568
|
}
|
|
2649
3569
|
}
|
|
2650
|
-
} else if (
|
|
2651
|
-
const event =
|
|
3570
|
+
} else if (context) {
|
|
3571
|
+
const event = context?.event ?? context?.ssrContext?.event ?? (context?.node ? context : null);
|
|
2652
3572
|
if (event) {
|
|
2653
|
-
|
|
3573
|
+
try {
|
|
3574
|
+
rawValue = h3.getCookie(event, cookieKey) ?? null;
|
|
3575
|
+
} catch {
|
|
3576
|
+
rawValue = null;
|
|
3577
|
+
}
|
|
2654
3578
|
}
|
|
2655
3579
|
}
|
|
2656
3580
|
if (!rawValue) return null;
|
|
@@ -2666,7 +3590,7 @@ class CCookieCache extends ACacheProvider {
|
|
|
2666
3590
|
if (Date.now() - val.timestamp <= val.lifetime) {
|
|
2667
3591
|
return val.data;
|
|
2668
3592
|
} else {
|
|
2669
|
-
await this.remove(key,
|
|
3593
|
+
await this.remove(key, context);
|
|
2670
3594
|
}
|
|
2671
3595
|
}
|
|
2672
3596
|
return null;
|
|
@@ -2675,7 +3599,7 @@ class CCookieCache extends ACacheProvider {
|
|
|
2675
3599
|
return null;
|
|
2676
3600
|
}
|
|
2677
3601
|
}
|
|
2678
|
-
async set(key, data, lifetime,
|
|
3602
|
+
async set(key, data, lifetime, context) {
|
|
2679
3603
|
const cookieKey = this.getCookieKey(key);
|
|
2680
3604
|
const entry = {
|
|
2681
3605
|
data,
|
|
@@ -2683,53 +3607,56 @@ class CCookieCache extends ACacheProvider {
|
|
|
2683
3607
|
lifetime
|
|
2684
3608
|
};
|
|
2685
3609
|
const serialized = JSON.stringify(entry);
|
|
2686
|
-
|
|
2687
|
-
|
|
3610
|
+
const cookieValue = encodeURIComponent(serialized);
|
|
3611
|
+
if (cookieKey.length + cookieValue.length > 4e3) {
|
|
3612
|
+
console.warn(`[CCookieCache] Payload for key "${key}" exceeds cookie size limit (${cookieKey.length + cookieValue.length} bytes encoded). Skipping cookie write.`);
|
|
2688
3613
|
return;
|
|
2689
3614
|
}
|
|
2690
3615
|
const maxAge = Math.floor(lifetime / 1e3);
|
|
2691
|
-
|
|
2692
|
-
if (this.isClient(nuxtApp)) {
|
|
3616
|
+
if (this.isClient(context)) {
|
|
2693
3617
|
if (typeof document !== "undefined") {
|
|
2694
3618
|
document.cookie = `${cookieKey}=${cookieValue}; Max-Age=${maxAge}; Path=/; SameSite=Lax`;
|
|
2695
3619
|
}
|
|
2696
|
-
} else if (
|
|
2697
|
-
const event =
|
|
3620
|
+
} else if (context) {
|
|
3621
|
+
const event = context?.event ?? context?.ssrContext?.event ?? (context?.node ? context : null);
|
|
2698
3622
|
if (event) {
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
3623
|
+
try {
|
|
3624
|
+
h3.setCookie(event, cookieKey, serialized, {
|
|
3625
|
+
maxAge,
|
|
3626
|
+
path: "/",
|
|
3627
|
+
sameSite: "lax",
|
|
3628
|
+
httpOnly: true
|
|
3629
|
+
});
|
|
3630
|
+
} catch {
|
|
3631
|
+
}
|
|
2705
3632
|
}
|
|
2706
3633
|
}
|
|
2707
3634
|
}
|
|
2708
|
-
async remove(key,
|
|
3635
|
+
async remove(key, context) {
|
|
2709
3636
|
const cookieKey = this.getCookieKey(key);
|
|
2710
|
-
if (this.isClient(
|
|
3637
|
+
if (this.isClient(context)) {
|
|
2711
3638
|
if (typeof document !== "undefined") {
|
|
2712
3639
|
document.cookie = `${cookieKey}=; Max-Age=0; Path=/; SameSite=Lax`;
|
|
2713
3640
|
}
|
|
2714
|
-
} else if (
|
|
2715
|
-
const event =
|
|
3641
|
+
} else if (context) {
|
|
3642
|
+
const event = context?.event ?? context?.ssrContext?.event ?? (context?.node ? context : null);
|
|
2716
3643
|
if (event) {
|
|
2717
3644
|
h3.deleteCookie(event, cookieKey, { path: "/", sameSite: "lax", httpOnly: true });
|
|
2718
3645
|
}
|
|
2719
3646
|
}
|
|
2720
3647
|
}
|
|
2721
|
-
async removeByPrefix(prefix,
|
|
2722
|
-
const keys = await this.getKeyList(
|
|
3648
|
+
async removeByPrefix(prefix, context) {
|
|
3649
|
+
const keys = await this.getKeyList(context);
|
|
2723
3650
|
for (const k of keys) {
|
|
2724
3651
|
if (k.startsWith(prefix)) {
|
|
2725
|
-
await this.remove(k,
|
|
3652
|
+
await this.remove(k, context);
|
|
2726
3653
|
}
|
|
2727
3654
|
}
|
|
2728
3655
|
}
|
|
2729
|
-
async getRemainingTime(key,
|
|
3656
|
+
async getRemainingTime(key, context) {
|
|
2730
3657
|
const cookieKey = this.getCookieKey(key);
|
|
2731
3658
|
let rawValue = null;
|
|
2732
|
-
if (this.isClient(
|
|
3659
|
+
if (this.isClient(context)) {
|
|
2733
3660
|
const namePrefix = cookieKey + "=";
|
|
2734
3661
|
const cookies = (typeof document !== "undefined" ? document.cookie : "").split(";");
|
|
2735
3662
|
for (let i = 0; i < cookies.length; i++) {
|
|
@@ -2739,8 +3666,8 @@ class CCookieCache extends ACacheProvider {
|
|
|
2739
3666
|
break;
|
|
2740
3667
|
}
|
|
2741
3668
|
}
|
|
2742
|
-
} else if (
|
|
2743
|
-
const event =
|
|
3669
|
+
} else if (context) {
|
|
3670
|
+
const event = context?.event ?? context?.ssrContext?.event ?? (context?.node ? context : null);
|
|
2744
3671
|
if (event) {
|
|
2745
3672
|
rawValue = h3.getCookie(event, cookieKey) ?? null;
|
|
2746
3673
|
}
|
|
@@ -2764,7 +3691,7 @@ class CCookieCache extends ACacheProvider {
|
|
|
2764
3691
|
}
|
|
2765
3692
|
}
|
|
2766
3693
|
async cleanupExpired() {
|
|
2767
|
-
if (
|
|
3694
|
+
if (this.isClient() && typeof document !== "undefined") {
|
|
2768
3695
|
const now = Date.now();
|
|
2769
3696
|
const cookies = document.cookie.split(";");
|
|
2770
3697
|
for (let i = 0; i < cookies.length; i++) {
|
|
@@ -2815,17 +3742,38 @@ class CSessionCache extends ACacheProvider {
|
|
|
2815
3742
|
static getSnapshot() {
|
|
2816
3743
|
return this.storage;
|
|
2817
3744
|
}
|
|
2818
|
-
static
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
3745
|
+
static MAX_SERVER_SESSIONS = 5e3;
|
|
3746
|
+
/**
|
|
3747
|
+
* Purges expired entries across all server sessions synchronously when the storage
|
|
3748
|
+
* exceeds MAX_SERVER_SESSIONS. Avoids persistent background setInterval timers on Node.js/SSR.
|
|
3749
|
+
*/
|
|
3750
|
+
static purgeExpiredServerSessions() {
|
|
3751
|
+
const now = Date.now();
|
|
3752
|
+
const prefix = "cache:";
|
|
3753
|
+
const sessionsToDelete = [];
|
|
3754
|
+
for (const [sessionId, sessionData] of CSessionCache.storage.entries()) {
|
|
3755
|
+
const keysToDelete = [];
|
|
3756
|
+
for (const [key, entry] of sessionData.entries()) {
|
|
3757
|
+
if (key.startsWith(prefix) && now - entry.timestamp > entry.lifetime) {
|
|
3758
|
+
keysToDelete.push(key);
|
|
3759
|
+
}
|
|
3760
|
+
}
|
|
3761
|
+
for (const key of keysToDelete) {
|
|
3762
|
+
sessionData.delete(key);
|
|
3763
|
+
}
|
|
3764
|
+
if (sessionData.size === 0) {
|
|
3765
|
+
sessionsToDelete.push(sessionId);
|
|
3766
|
+
}
|
|
3767
|
+
}
|
|
3768
|
+
for (const sessionId of sessionsToDelete) {
|
|
3769
|
+
CSessionCache.storage.delete(sessionId);
|
|
3770
|
+
}
|
|
3771
|
+
while (CSessionCache.storage.size >= CSessionCache.MAX_SERVER_SESSIONS && CSessionCache.storage.size > 0) {
|
|
3772
|
+
const oldestSessionKey = CSessionCache.storage.keys().next().value;
|
|
3773
|
+
if (oldestSessionKey) {
|
|
3774
|
+
CSessionCache.storage.delete(oldestSessionKey);
|
|
3775
|
+
} else {
|
|
3776
|
+
break;
|
|
2829
3777
|
}
|
|
2830
3778
|
}
|
|
2831
3779
|
}
|
|
@@ -2835,12 +3783,22 @@ class CSessionCache extends ACacheProvider {
|
|
|
2835
3783
|
constructor() {
|
|
2836
3784
|
super();
|
|
2837
3785
|
this.sessionIdCache = CCookieCache.getInstance();
|
|
2838
|
-
CSessionCache.initCleanupTimer();
|
|
2839
3786
|
}
|
|
2840
3787
|
/**
|
|
2841
3788
|
* Generate a UUID v4 sessionId
|
|
2842
3789
|
*/
|
|
2843
3790
|
generateSessionId() {
|
|
3791
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
3792
|
+
return crypto.randomUUID();
|
|
3793
|
+
}
|
|
3794
|
+
if (typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function") {
|
|
3795
|
+
const bytes = new Uint8Array(16);
|
|
3796
|
+
crypto.getRandomValues(bytes);
|
|
3797
|
+
bytes[6] = bytes[6] & 15 | 64;
|
|
3798
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
3799
|
+
const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
3800
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
3801
|
+
}
|
|
2844
3802
|
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
2845
3803
|
const r = Math.random() * 16 | 0;
|
|
2846
3804
|
const v = c === "x" ? r : r & 3 | 8;
|
|
@@ -2850,44 +3808,99 @@ class CSessionCache extends ACacheProvider {
|
|
|
2850
3808
|
/**
|
|
2851
3809
|
* Get or create sessionId
|
|
2852
3810
|
*/
|
|
2853
|
-
async getSessionId(
|
|
2854
|
-
const
|
|
3811
|
+
async getSessionId(context) {
|
|
3812
|
+
const event = context?.event ?? context?.ssrContext?.event ?? (context?.node ? context : null);
|
|
3813
|
+
const isServer = typeof window === "undefined" || !!event || !!context?.ssrContext;
|
|
3814
|
+
if (isServer && !event) {
|
|
3815
|
+
return "__no_session__";
|
|
3816
|
+
}
|
|
3817
|
+
const contextSessionId = event?.context?.sessionId;
|
|
2855
3818
|
if (contextSessionId) {
|
|
2856
3819
|
return contextSessionId;
|
|
2857
3820
|
}
|
|
2858
|
-
if (this.sessionId) {
|
|
3821
|
+
if (!isServer && this.sessionId) {
|
|
2859
3822
|
return this.sessionId;
|
|
2860
3823
|
}
|
|
2861
|
-
|
|
2862
|
-
|
|
3824
|
+
let existingId = null;
|
|
3825
|
+
if (isServer && event) {
|
|
3826
|
+
const req = event.node?.req || event.req;
|
|
3827
|
+
const cookieHeader = req?.headers?.cookie || "";
|
|
3828
|
+
const match = cookieHeader.match(/(?:^|; )_session_id=([^;]*)/);
|
|
3829
|
+
if (match) existingId = decodeURIComponent(match[1]);
|
|
3830
|
+
} else if (!isServer && typeof document !== "undefined") {
|
|
3831
|
+
const match = document.cookie.match(/(?:^|; )_session_id=([^;]*)/);
|
|
3832
|
+
if (match) existingId = decodeURIComponent(match[1]);
|
|
3833
|
+
}
|
|
3834
|
+
if (!existingId && this.sessionIdCache) {
|
|
3835
|
+
existingId = await this.sessionIdCache.get(this.SESSION_ID_KEY, context);
|
|
2863
3836
|
}
|
|
2864
|
-
const existingId = await this.sessionIdCache.get(this.SESSION_ID_KEY, nuxtApp);
|
|
2865
3837
|
if (existingId) {
|
|
2866
|
-
|
|
3838
|
+
if (isServer) {
|
|
3839
|
+
if (event) {
|
|
3840
|
+
if (!event.context) event.context = {};
|
|
3841
|
+
event.context.sessionId = existingId;
|
|
3842
|
+
}
|
|
3843
|
+
} else {
|
|
3844
|
+
this.sessionId = existingId;
|
|
3845
|
+
}
|
|
2867
3846
|
return existingId;
|
|
2868
3847
|
}
|
|
2869
3848
|
const newId = this.generateSessionId();
|
|
2870
|
-
|
|
3849
|
+
if (isServer) {
|
|
3850
|
+
if (event) {
|
|
3851
|
+
if (!event.context) event.context = {};
|
|
3852
|
+
event.context.sessionId = newId;
|
|
3853
|
+
}
|
|
3854
|
+
} else {
|
|
3855
|
+
this.sessionId = newId;
|
|
3856
|
+
if (typeof document !== "undefined") {
|
|
3857
|
+
document.cookie = `_session_id=${encodeURIComponent(newId)}; path=/; max-age=31536000; SameSite=Lax`;
|
|
3858
|
+
}
|
|
3859
|
+
}
|
|
2871
3860
|
if (this.sessionIdCache) {
|
|
2872
|
-
await this.sessionIdCache.set(this.SESSION_ID_KEY, newId, 365 * 24 * 60 * 60 * 1e3,
|
|
3861
|
+
await this.sessionIdCache.set(this.SESSION_ID_KEY, newId, 365 * 24 * 60 * 60 * 1e3, context);
|
|
2873
3862
|
}
|
|
2874
3863
|
return newId;
|
|
2875
3864
|
}
|
|
2876
|
-
async getKeyList(
|
|
3865
|
+
async getKeyList(context) {
|
|
2877
3866
|
const prefix = "cache:";
|
|
2878
|
-
|
|
2879
|
-
|
|
3867
|
+
const event = context?.event ?? context?.ssrContext?.event ?? (context?.node ? context : null);
|
|
3868
|
+
const isServer = typeof window === "undefined" || !!event || !!context?.ssrContext;
|
|
3869
|
+
if (isServer) {
|
|
3870
|
+
const sessionId = await this.getSessionId(context);
|
|
3871
|
+
const sessionData = CSessionCache.storage.get(sessionId);
|
|
3872
|
+
if (!sessionData) {
|
|
3873
|
+
return [];
|
|
3874
|
+
}
|
|
3875
|
+
return Array.from(sessionData.keys()).filter((key) => key.startsWith(prefix)).map((key) => key.substring(prefix.length));
|
|
2880
3876
|
}
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
if (!sessionData) {
|
|
2884
|
-
return [];
|
|
3877
|
+
if (typeof window !== "undefined" && typeof sessionStorage !== "undefined") {
|
|
3878
|
+
return Object.keys(sessionStorage).filter((key) => key.startsWith(prefix)).map((key) => key.substring(prefix.length));
|
|
2885
3879
|
}
|
|
2886
|
-
return
|
|
3880
|
+
return [];
|
|
2887
3881
|
}
|
|
2888
|
-
async get(key,
|
|
3882
|
+
async get(key, context) {
|
|
2889
3883
|
const prefixedKey = "cache:" + key;
|
|
2890
|
-
|
|
3884
|
+
const event = context?.event ?? context?.ssrContext?.event ?? (context?.node ? context : null);
|
|
3885
|
+
const isServer = typeof window === "undefined" || !!event || !!context?.ssrContext;
|
|
3886
|
+
if (isServer) {
|
|
3887
|
+
const sessionId = await this.getSessionId(context);
|
|
3888
|
+
const sessionData = CSessionCache.storage.get(sessionId);
|
|
3889
|
+
if (!sessionData) {
|
|
3890
|
+
return null;
|
|
3891
|
+
}
|
|
3892
|
+
const entry = sessionData.get(prefixedKey);
|
|
3893
|
+
if (!entry) {
|
|
3894
|
+
return null;
|
|
3895
|
+
}
|
|
3896
|
+
if (Date.now() - entry.timestamp <= entry.lifetime) {
|
|
3897
|
+
return entry.data;
|
|
3898
|
+
} else {
|
|
3899
|
+
sessionData.delete(prefixedKey);
|
|
3900
|
+
return null;
|
|
3901
|
+
}
|
|
3902
|
+
}
|
|
3903
|
+
if (typeof window !== "undefined" && typeof sessionStorage !== "undefined") {
|
|
2891
3904
|
try {
|
|
2892
3905
|
const stored = sessionStorage.getItem(prefixedKey);
|
|
2893
3906
|
if (stored) {
|
|
@@ -2902,7 +3915,7 @@ class CSessionCache extends ACacheProvider {
|
|
|
2902
3915
|
console.warn("[Katlux Cache] CSessionCache parse error for key: " + key, e);
|
|
2903
3916
|
}
|
|
2904
3917
|
try {
|
|
2905
|
-
const payloadData =
|
|
3918
|
+
const payloadData = getSSRPayload(context);
|
|
2906
3919
|
if (payloadData && payloadData[prefixedKey]) {
|
|
2907
3920
|
const entry = payloadData[prefixedKey];
|
|
2908
3921
|
if (Date.now() - entry.timestamp <= entry.lifetime) {
|
|
@@ -2915,73 +3928,56 @@ class CSessionCache extends ACacheProvider {
|
|
|
2915
3928
|
}
|
|
2916
3929
|
return null;
|
|
2917
3930
|
}
|
|
2918
|
-
if (undefined) {
|
|
2919
|
-
const sessionId = await this.getSessionId(nuxtApp);
|
|
2920
|
-
const sessionData = CSessionCache.storage.get(sessionId);
|
|
2921
|
-
if (!sessionData) {
|
|
2922
|
-
return null;
|
|
2923
|
-
}
|
|
2924
|
-
const entry = sessionData.get(prefixedKey);
|
|
2925
|
-
if (!entry) {
|
|
2926
|
-
return null;
|
|
2927
|
-
}
|
|
2928
|
-
if (Date.now() - entry.timestamp <= entry.lifetime) {
|
|
2929
|
-
return entry.data;
|
|
2930
|
-
} else {
|
|
2931
|
-
sessionData.delete(prefixedKey);
|
|
2932
|
-
return null;
|
|
2933
|
-
}
|
|
2934
|
-
}
|
|
2935
3931
|
return null;
|
|
2936
3932
|
}
|
|
2937
|
-
async set(key, data, lifetime,
|
|
3933
|
+
async set(key, data, lifetime, context) {
|
|
2938
3934
|
const prefixedKey = "cache:" + key;
|
|
2939
3935
|
const entry = {
|
|
2940
3936
|
data,
|
|
2941
3937
|
timestamp: Date.now(),
|
|
2942
3938
|
lifetime
|
|
2943
3939
|
};
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
} catch (e) {
|
|
2948
|
-
console.warn("[Katlux Cache] CSessionCache sessionStorage setItem error (possible quota exceeded) for key: " + key, e);
|
|
2949
|
-
}
|
|
2950
|
-
}
|
|
2951
|
-
if (undefined || nuxtApp) {
|
|
3940
|
+
const event = context?.event ?? context?.ssrContext?.event ?? (context?.node ? context : null);
|
|
3941
|
+
const isServer = typeof window === "undefined" || !!event || !!context?.ssrContext;
|
|
3942
|
+
if (isServer) {
|
|
2952
3943
|
try {
|
|
2953
|
-
const sessionId = await this.getSessionId(
|
|
3944
|
+
const sessionId = await this.getSessionId(context);
|
|
3945
|
+
if (sessionId === "__no_session__") return;
|
|
3946
|
+
if (CSessionCache.storage.size >= CSessionCache.MAX_SERVER_SESSIONS) {
|
|
3947
|
+
CSessionCache.purgeExpiredServerSessions();
|
|
3948
|
+
}
|
|
2954
3949
|
let sessionData = CSessionCache.storage.get(sessionId);
|
|
2955
3950
|
if (!sessionData) {
|
|
2956
3951
|
sessionData = /* @__PURE__ */ new Map();
|
|
2957
|
-
CSessionCache.storage.set(sessionId, sessionData);
|
|
2958
|
-
}
|
|
2959
|
-
sessionData.set(prefixedKey, entry);
|
|
2960
|
-
if (nuxtApp) {
|
|
2961
|
-
const payload = nuxtApp.payload?.data || nuxtApp.ssrContext?.payload?.data;
|
|
2962
|
-
if (payload) {
|
|
2963
|
-
payload[prefixedKey] = entry;
|
|
2964
|
-
}
|
|
3952
|
+
CSessionCache.storage.set(sessionId, sessionData);
|
|
2965
3953
|
}
|
|
3954
|
+
sessionData.set(prefixedKey, entry);
|
|
2966
3955
|
} catch (e) {
|
|
2967
3956
|
console.warn("[Katlux Cache] CSessionCache server session storage error for key: " + key, e);
|
|
2968
3957
|
}
|
|
3958
|
+
return;
|
|
3959
|
+
}
|
|
3960
|
+
if (typeof window !== "undefined" && typeof sessionStorage !== "undefined") {
|
|
3961
|
+
try {
|
|
3962
|
+
sessionStorage.setItem(prefixedKey, JSON.stringify(entry));
|
|
3963
|
+
} catch (e) {
|
|
3964
|
+
console.warn("[Katlux Cache] CSessionCache sessionStorage setItem error (possible quota exceeded) for key: " + key, e);
|
|
3965
|
+
}
|
|
2969
3966
|
}
|
|
2970
3967
|
}
|
|
2971
|
-
async remove(key,
|
|
3968
|
+
async remove(key, context) {
|
|
2972
3969
|
const prefixedKey = "cache:" + key;
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
if (undefined) {
|
|
3970
|
+
const event = context?.event ?? context?.ssrContext?.event ?? (context?.node ? context : null);
|
|
3971
|
+
const isServer = typeof window === "undefined" || !!event || !!context?.ssrContext;
|
|
3972
|
+
if (isServer) {
|
|
2977
3973
|
try {
|
|
2978
|
-
const sessionId = await this.getSessionId(
|
|
3974
|
+
const sessionId = await this.getSessionId(context);
|
|
2979
3975
|
const sessionData = CSessionCache.storage.get(sessionId);
|
|
2980
3976
|
if (sessionData) {
|
|
2981
3977
|
sessionData.delete(prefixedKey);
|
|
2982
3978
|
}
|
|
2983
|
-
if (
|
|
2984
|
-
const payload =
|
|
3979
|
+
if (context) {
|
|
3980
|
+
const payload = context.payload?.data || context.ssrContext?.payload?.data;
|
|
2985
3981
|
if (payload && payload[prefixedKey]) {
|
|
2986
3982
|
delete payload[prefixedKey];
|
|
2987
3983
|
}
|
|
@@ -2989,11 +3985,15 @@ class CSessionCache extends ACacheProvider {
|
|
|
2989
3985
|
} catch (e) {
|
|
2990
3986
|
console.warn("[Katlux Cache] CSessionCache remove error on server for key: " + key, e);
|
|
2991
3987
|
}
|
|
3988
|
+
return;
|
|
3989
|
+
}
|
|
3990
|
+
if (typeof window !== "undefined" && typeof sessionStorage !== "undefined") {
|
|
3991
|
+
sessionStorage.removeItem(prefixedKey);
|
|
2992
3992
|
}
|
|
2993
3993
|
}
|
|
2994
|
-
async removeByPrefix(prefix,
|
|
3994
|
+
async removeByPrefix(prefix, context) {
|
|
2995
3995
|
const fullPrefix = "cache:" + prefix;
|
|
2996
|
-
if (undefined) {
|
|
3996
|
+
if (typeof window !== "undefined") {
|
|
2997
3997
|
const keysToDelete = [];
|
|
2998
3998
|
for (let i = 0; i < sessionStorage.length; i++) {
|
|
2999
3999
|
const key = sessionStorage.key(i);
|
|
@@ -3005,9 +4005,9 @@ class CSessionCache extends ACacheProvider {
|
|
|
3005
4005
|
sessionStorage.removeItem(key);
|
|
3006
4006
|
}
|
|
3007
4007
|
}
|
|
3008
|
-
if (undefined) {
|
|
4008
|
+
if (typeof window === "undefined") {
|
|
3009
4009
|
try {
|
|
3010
|
-
const sessionId = await this.getSessionId(
|
|
4010
|
+
const sessionId = await this.getSessionId(context);
|
|
3011
4011
|
const sessionData = CSessionCache.storage.get(sessionId);
|
|
3012
4012
|
if (sessionData) {
|
|
3013
4013
|
const keysToDelete = [];
|
|
@@ -3020,8 +4020,8 @@ class CSessionCache extends ACacheProvider {
|
|
|
3020
4020
|
sessionData.delete(key);
|
|
3021
4021
|
}
|
|
3022
4022
|
}
|
|
3023
|
-
if (
|
|
3024
|
-
const payload =
|
|
4023
|
+
if (context) {
|
|
4024
|
+
const payload = context.payload?.data || context.ssrContext?.payload?.data;
|
|
3025
4025
|
if (payload) {
|
|
3026
4026
|
for (const key in payload) {
|
|
3027
4027
|
if (key.startsWith(fullPrefix)) {
|
|
@@ -3035,9 +4035,9 @@ class CSessionCache extends ACacheProvider {
|
|
|
3035
4035
|
}
|
|
3036
4036
|
}
|
|
3037
4037
|
}
|
|
3038
|
-
async getRemainingTime(key,
|
|
4038
|
+
async getRemainingTime(key, context) {
|
|
3039
4039
|
const prefixedKey = "cache:" + key;
|
|
3040
|
-
if (undefined) {
|
|
4040
|
+
if (typeof window !== "undefined") {
|
|
3041
4041
|
const entryStr = sessionStorage.getItem(prefixedKey);
|
|
3042
4042
|
if (!entryStr) return null;
|
|
3043
4043
|
try {
|
|
@@ -3048,8 +4048,8 @@ class CSessionCache extends ACacheProvider {
|
|
|
3048
4048
|
return null;
|
|
3049
4049
|
}
|
|
3050
4050
|
}
|
|
3051
|
-
if (undefined) {
|
|
3052
|
-
const sessionId = await this.getSessionId(
|
|
4051
|
+
if (typeof window === "undefined") {
|
|
4052
|
+
const sessionId = await this.getSessionId(context);
|
|
3053
4053
|
const sessionData = CSessionCache.storage.get(sessionId);
|
|
3054
4054
|
if (!sessionData) return null;
|
|
3055
4055
|
const entry = sessionData.get(prefixedKey);
|
|
@@ -3061,7 +4061,7 @@ class CSessionCache extends ACacheProvider {
|
|
|
3061
4061
|
async cleanupExpired() {
|
|
3062
4062
|
const prefix = "cache:";
|
|
3063
4063
|
const now = Date.now();
|
|
3064
|
-
if (undefined) {
|
|
4064
|
+
if (typeof window !== "undefined") {
|
|
3065
4065
|
const keysToDelete = [];
|
|
3066
4066
|
for (let i = 0; i < sessionStorage.length; i++) {
|
|
3067
4067
|
const key = sessionStorage.key(i);
|
|
@@ -3084,7 +4084,7 @@ class CSessionCache extends ACacheProvider {
|
|
|
3084
4084
|
sessionStorage.removeItem(key);
|
|
3085
4085
|
}
|
|
3086
4086
|
}
|
|
3087
|
-
if (undefined || CSessionCache.storage.size > 0) {
|
|
4087
|
+
if (typeof window === "undefined" || CSessionCache.storage.size > 0) {
|
|
3088
4088
|
const sessionsToDelete = [];
|
|
3089
4089
|
for (const [sessionId, sessionData] of CSessionCache.storage.entries()) {
|
|
3090
4090
|
const keysToDelete = [];
|
|
@@ -3125,13 +4125,13 @@ class CLocalStorageCache extends ACacheProvider {
|
|
|
3125
4125
|
type = "LocalStorage";
|
|
3126
4126
|
constructor() {
|
|
3127
4127
|
super();
|
|
3128
|
-
if (undefined) {
|
|
4128
|
+
if (typeof window !== "undefined") {
|
|
3129
4129
|
this._hydrateFromPayload();
|
|
3130
4130
|
}
|
|
3131
4131
|
}
|
|
3132
4132
|
async _hydrateFromPayload() {
|
|
3133
4133
|
try {
|
|
3134
|
-
const payloadData =
|
|
4134
|
+
const payloadData = getSSRPayload();
|
|
3135
4135
|
if (!payloadData) return;
|
|
3136
4136
|
const prefix = "cache:";
|
|
3137
4137
|
for (const key in payloadData) {
|
|
@@ -3150,14 +4150,14 @@ class CLocalStorageCache extends ACacheProvider {
|
|
|
3150
4150
|
console.warn("[Katlux Cache] LocalStorage payload hydration failed", e);
|
|
3151
4151
|
}
|
|
3152
4152
|
}
|
|
3153
|
-
async getKeyList(
|
|
3154
|
-
if (!undefined) return [];
|
|
4153
|
+
async getKeyList(context) {
|
|
4154
|
+
if (!(typeof window !== "undefined")) return [];
|
|
3155
4155
|
const prefix = "cache:";
|
|
3156
4156
|
return Object.keys(localStorage).filter((key) => key.startsWith(prefix)).map((key) => key.substring(prefix.length));
|
|
3157
4157
|
}
|
|
3158
|
-
async get(key,
|
|
4158
|
+
async get(key, context) {
|
|
3159
4159
|
const prefixedKey = "cache:" + key;
|
|
3160
|
-
if (undefined) {
|
|
4160
|
+
if (typeof window !== "undefined") {
|
|
3161
4161
|
try {
|
|
3162
4162
|
const stored = localStorage.getItem(prefixedKey);
|
|
3163
4163
|
if (stored) {
|
|
@@ -3173,11 +4173,11 @@ class CLocalStorageCache extends ACacheProvider {
|
|
|
3173
4173
|
}
|
|
3174
4174
|
}
|
|
3175
4175
|
try {
|
|
3176
|
-
const payloadData =
|
|
4176
|
+
const payloadData = getSSRPayload(context);
|
|
3177
4177
|
if (payloadData && payloadData[prefixedKey]) {
|
|
3178
4178
|
const entry = payloadData[prefixedKey];
|
|
3179
4179
|
if (Date.now() - entry.timestamp <= entry.lifetime) {
|
|
3180
|
-
if (undefined) {
|
|
4180
|
+
if (typeof window !== "undefined") {
|
|
3181
4181
|
localStorage.setItem(prefixedKey, JSON.stringify(entry));
|
|
3182
4182
|
}
|
|
3183
4183
|
return entry.data;
|
|
@@ -3188,24 +4188,14 @@ class CLocalStorageCache extends ACacheProvider {
|
|
|
3188
4188
|
}
|
|
3189
4189
|
return null;
|
|
3190
4190
|
}
|
|
3191
|
-
async set(key, data, lifetime,
|
|
4191
|
+
async set(key, data, lifetime, context) {
|
|
3192
4192
|
const prefixedKey = "cache:" + key;
|
|
3193
4193
|
const entry = {
|
|
3194
4194
|
data,
|
|
3195
4195
|
timestamp: Date.now(),
|
|
3196
4196
|
lifetime
|
|
3197
4197
|
};
|
|
3198
|
-
if (
|
|
3199
|
-
try {
|
|
3200
|
-
const payload = nuxtApp.payload?.data || nuxtApp.ssrContext?.payload?.data;
|
|
3201
|
-
if (payload) {
|
|
3202
|
-
payload[prefixedKey] = entry;
|
|
3203
|
-
}
|
|
3204
|
-
} catch (e) {
|
|
3205
|
-
console.warn("[Katlux Cache] LocalStorage error writing to SSR payload for key: " + key, e);
|
|
3206
|
-
}
|
|
3207
|
-
}
|
|
3208
|
-
if (undefined) {
|
|
4198
|
+
if (typeof window !== "undefined") {
|
|
3209
4199
|
try {
|
|
3210
4200
|
localStorage.setItem(prefixedKey, JSON.stringify(entry));
|
|
3211
4201
|
} catch (e) {
|
|
@@ -3213,14 +4203,14 @@ class CLocalStorageCache extends ACacheProvider {
|
|
|
3213
4203
|
}
|
|
3214
4204
|
}
|
|
3215
4205
|
}
|
|
3216
|
-
async remove(key,
|
|
4206
|
+
async remove(key, context) {
|
|
3217
4207
|
const prefixedKey = "cache:" + key;
|
|
3218
|
-
if (undefined) {
|
|
4208
|
+
if (typeof window !== "undefined") {
|
|
3219
4209
|
localStorage.removeItem(prefixedKey);
|
|
3220
4210
|
}
|
|
3221
|
-
if (undefined &&
|
|
4211
|
+
if (typeof window === "undefined" && context) {
|
|
3222
4212
|
try {
|
|
3223
|
-
const payload =
|
|
4213
|
+
const payload = context.payload?.data || context.ssrContext?.payload?.data;
|
|
3224
4214
|
if (payload && payload[prefixedKey]) {
|
|
3225
4215
|
delete payload[prefixedKey];
|
|
3226
4216
|
}
|
|
@@ -3229,9 +4219,9 @@ class CLocalStorageCache extends ACacheProvider {
|
|
|
3229
4219
|
}
|
|
3230
4220
|
}
|
|
3231
4221
|
}
|
|
3232
|
-
async removeByPrefix(prefix,
|
|
4222
|
+
async removeByPrefix(prefix, context) {
|
|
3233
4223
|
const fullPrefix = "cache:" + prefix;
|
|
3234
|
-
if (undefined) {
|
|
4224
|
+
if (typeof window !== "undefined") {
|
|
3235
4225
|
const keysToDelete = [];
|
|
3236
4226
|
for (let i = 0; i < localStorage.length; i++) {
|
|
3237
4227
|
const key = localStorage.key(i);
|
|
@@ -3243,9 +4233,9 @@ class CLocalStorageCache extends ACacheProvider {
|
|
|
3243
4233
|
localStorage.removeItem(key);
|
|
3244
4234
|
}
|
|
3245
4235
|
}
|
|
3246
|
-
if (undefined &&
|
|
4236
|
+
if (typeof window === "undefined" && context) {
|
|
3247
4237
|
try {
|
|
3248
|
-
const payload =
|
|
4238
|
+
const payload = context.payload?.data || context.ssrContext?.payload?.data;
|
|
3249
4239
|
if (payload) {
|
|
3250
4240
|
for (const key in payload) {
|
|
3251
4241
|
if (key.startsWith(fullPrefix)) {
|
|
@@ -3258,8 +4248,8 @@ class CLocalStorageCache extends ACacheProvider {
|
|
|
3258
4248
|
}
|
|
3259
4249
|
}
|
|
3260
4250
|
}
|
|
3261
|
-
async getRemainingTime(key,
|
|
3262
|
-
if (undefined) {
|
|
4251
|
+
async getRemainingTime(key, context) {
|
|
4252
|
+
if (typeof window !== "undefined") {
|
|
3263
4253
|
const prefixedKey = "cache:" + key;
|
|
3264
4254
|
const entryStr = localStorage.getItem(prefixedKey);
|
|
3265
4255
|
if (!entryStr) return null;
|
|
@@ -3274,7 +4264,7 @@ class CLocalStorageCache extends ACacheProvider {
|
|
|
3274
4264
|
return null;
|
|
3275
4265
|
}
|
|
3276
4266
|
async cleanupExpired() {
|
|
3277
|
-
if (undefined) {
|
|
4267
|
+
if (typeof window !== "undefined") {
|
|
3278
4268
|
try {
|
|
3279
4269
|
const prefix = "cache:";
|
|
3280
4270
|
const now = Date.now();
|
|
@@ -3312,21 +4302,31 @@ const CLocalStorageCache$1 = {
|
|
|
3312
4302
|
|
|
3313
4303
|
class CIndexedDBCache extends ACacheProvider {
|
|
3314
4304
|
static instance = null;
|
|
3315
|
-
static
|
|
3316
|
-
|
|
3317
|
-
|
|
4305
|
+
static instances = /* @__PURE__ */ new Map();
|
|
4306
|
+
storeName;
|
|
4307
|
+
static getInstance(storeName = "cache") {
|
|
4308
|
+
if (storeName === "cache" && this.instance) {
|
|
4309
|
+
return this.instance;
|
|
3318
4310
|
}
|
|
3319
|
-
|
|
4311
|
+
if (!this.instances.has(storeName)) {
|
|
4312
|
+
const inst = new CIndexedDBCache(storeName);
|
|
4313
|
+
this.instances.set(storeName, inst);
|
|
4314
|
+
if (storeName === "cache") {
|
|
4315
|
+
this.instance = inst;
|
|
4316
|
+
}
|
|
4317
|
+
}
|
|
4318
|
+
return this.instances.get(storeName);
|
|
3320
4319
|
}
|
|
3321
|
-
constructor() {
|
|
4320
|
+
constructor(storeName = "cache") {
|
|
3322
4321
|
super();
|
|
3323
|
-
|
|
4322
|
+
this.storeName = storeName;
|
|
4323
|
+
if (typeof window !== "undefined") {
|
|
3324
4324
|
this._hydrateFromPayload();
|
|
3325
4325
|
}
|
|
3326
4326
|
}
|
|
3327
4327
|
async _hydrateFromPayload() {
|
|
3328
4328
|
try {
|
|
3329
|
-
const payloadData =
|
|
4329
|
+
const payloadData = getSSRPayload();
|
|
3330
4330
|
if (!payloadData) return;
|
|
3331
4331
|
const prefix = "cache:";
|
|
3332
4332
|
let count = 0;
|
|
@@ -3336,8 +4336,8 @@ class CIndexedDBCache extends ACacheProvider {
|
|
|
3336
4336
|
if (value && typeof value === "object" && "data" in value && "timestamp" in value && "lifetime" in value) {
|
|
3337
4337
|
KatluxIndexedDB.open().then(async (db) => {
|
|
3338
4338
|
try {
|
|
3339
|
-
const tx = db.transaction(
|
|
3340
|
-
const store = tx.objectStore(
|
|
4339
|
+
const tx = db.transaction(this.storeName, "readwrite");
|
|
4340
|
+
const store = tx.objectStore(this.storeName);
|
|
3341
4341
|
store.put(value, key);
|
|
3342
4342
|
tx.commit?.();
|
|
3343
4343
|
} catch (e) {
|
|
@@ -3354,10 +4354,10 @@ class CIndexedDBCache extends ACacheProvider {
|
|
|
3354
4354
|
}
|
|
3355
4355
|
}
|
|
3356
4356
|
async getStore(mode) {
|
|
3357
|
-
return KatluxIndexedDB.getStore(
|
|
4357
|
+
return KatluxIndexedDB.getStore(this.storeName, mode);
|
|
3358
4358
|
}
|
|
3359
|
-
async getKeyList(
|
|
3360
|
-
if (!undefined) return [];
|
|
4359
|
+
async getKeyList(context) {
|
|
4360
|
+
if (!(typeof window !== "undefined")) return [];
|
|
3361
4361
|
try {
|
|
3362
4362
|
const store = await this.getStore("readonly");
|
|
3363
4363
|
const keys = await new Promise((resolve, reject) => {
|
|
@@ -3372,9 +4372,9 @@ class CIndexedDBCache extends ACacheProvider {
|
|
|
3372
4372
|
return [];
|
|
3373
4373
|
}
|
|
3374
4374
|
}
|
|
3375
|
-
async get(key,
|
|
4375
|
+
async get(key, context) {
|
|
3376
4376
|
const prefixedKey = "cache:" + key;
|
|
3377
|
-
if (undefined) {
|
|
4377
|
+
if (typeof window !== "undefined") {
|
|
3378
4378
|
try {
|
|
3379
4379
|
const store = await this.getStore("readonly");
|
|
3380
4380
|
const data = await new Promise((resolve, reject) => {
|
|
@@ -3395,12 +4395,12 @@ class CIndexedDBCache extends ACacheProvider {
|
|
|
3395
4395
|
}
|
|
3396
4396
|
}
|
|
3397
4397
|
try {
|
|
3398
|
-
const payloadData =
|
|
4398
|
+
const payloadData = getSSRPayload(context);
|
|
3399
4399
|
if (payloadData && payloadData[prefixedKey]) {
|
|
3400
4400
|
const entry = payloadData[prefixedKey];
|
|
3401
4401
|
if (Date.now() - entry.timestamp <= entry.lifetime) {
|
|
3402
|
-
if (undefined) {
|
|
3403
|
-
this.set(key, entry.data, entry.lifetime,
|
|
4402
|
+
if (typeof window !== "undefined") {
|
|
4403
|
+
this.set(key, entry.data, entry.lifetime, context);
|
|
3404
4404
|
}
|
|
3405
4405
|
return entry.data;
|
|
3406
4406
|
}
|
|
@@ -3410,24 +4410,14 @@ class CIndexedDBCache extends ACacheProvider {
|
|
|
3410
4410
|
}
|
|
3411
4411
|
return null;
|
|
3412
4412
|
}
|
|
3413
|
-
async set(key, data, lifetime,
|
|
4413
|
+
async set(key, data, lifetime, context) {
|
|
3414
4414
|
const prefixedKey = "cache:" + key;
|
|
3415
4415
|
const entry = {
|
|
3416
4416
|
data,
|
|
3417
4417
|
timestamp: Date.now(),
|
|
3418
4418
|
lifetime
|
|
3419
4419
|
};
|
|
3420
|
-
if (
|
|
3421
|
-
try {
|
|
3422
|
-
const payload = nuxtApp.payload?.data || nuxtApp.ssrContext?.payload?.data;
|
|
3423
|
-
if (payload) {
|
|
3424
|
-
payload[prefixedKey] = entry;
|
|
3425
|
-
}
|
|
3426
|
-
} catch (e) {
|
|
3427
|
-
console.warn("[Katlux Cache] IndexedDB error writing SSR payload for key: " + key, e);
|
|
3428
|
-
}
|
|
3429
|
-
}
|
|
3430
|
-
if (undefined) {
|
|
4420
|
+
if (typeof window !== "undefined") {
|
|
3431
4421
|
try {
|
|
3432
4422
|
const store = await this.getStore("readwrite");
|
|
3433
4423
|
await new Promise((resolve, reject) => {
|
|
@@ -3440,9 +4430,9 @@ class CIndexedDBCache extends ACacheProvider {
|
|
|
3440
4430
|
}
|
|
3441
4431
|
}
|
|
3442
4432
|
}
|
|
3443
|
-
async remove(key,
|
|
4433
|
+
async remove(key, context) {
|
|
3444
4434
|
const prefixedKey = "cache:" + key;
|
|
3445
|
-
if (undefined) {
|
|
4435
|
+
if (typeof window !== "undefined") {
|
|
3446
4436
|
try {
|
|
3447
4437
|
const store = await this.getStore("readwrite");
|
|
3448
4438
|
await new Promise((resolve, reject) => {
|
|
@@ -3454,9 +4444,9 @@ class CIndexedDBCache extends ACacheProvider {
|
|
|
3454
4444
|
console.warn("[Katlux Cache] IndexedDB error deleting key: " + key, e);
|
|
3455
4445
|
}
|
|
3456
4446
|
}
|
|
3457
|
-
if (undefined &&
|
|
4447
|
+
if (typeof window === "undefined" && context) {
|
|
3458
4448
|
try {
|
|
3459
|
-
const payload =
|
|
4449
|
+
const payload = context.payload?.data || context.ssrContext?.payload?.data;
|
|
3460
4450
|
if (payload && payload[prefixedKey]) {
|
|
3461
4451
|
delete payload[prefixedKey];
|
|
3462
4452
|
}
|
|
@@ -3465,9 +4455,9 @@ class CIndexedDBCache extends ACacheProvider {
|
|
|
3465
4455
|
}
|
|
3466
4456
|
}
|
|
3467
4457
|
}
|
|
3468
|
-
async removeByPrefix(prefix,
|
|
4458
|
+
async removeByPrefix(prefix, context) {
|
|
3469
4459
|
const fullPrefix = "cache:" + prefix;
|
|
3470
|
-
if (undefined) {
|
|
4460
|
+
if (typeof window !== "undefined") {
|
|
3471
4461
|
try {
|
|
3472
4462
|
const store = await this.getStore("readwrite");
|
|
3473
4463
|
const allKeys = await new Promise((resolve, reject) => {
|
|
@@ -3487,9 +4477,9 @@ class CIndexedDBCache extends ACacheProvider {
|
|
|
3487
4477
|
console.warn("[Katlux Cache] IndexedDB error removing by prefix: " + prefix, e);
|
|
3488
4478
|
}
|
|
3489
4479
|
}
|
|
3490
|
-
if (undefined &&
|
|
4480
|
+
if (typeof window === "undefined" && context) {
|
|
3491
4481
|
try {
|
|
3492
|
-
const payload =
|
|
4482
|
+
const payload = context.payload?.data || context.ssrContext?.payload?.data;
|
|
3493
4483
|
if (payload) {
|
|
3494
4484
|
for (const key in payload) {
|
|
3495
4485
|
if (key.startsWith(fullPrefix)) {
|
|
@@ -3502,8 +4492,8 @@ class CIndexedDBCache extends ACacheProvider {
|
|
|
3502
4492
|
}
|
|
3503
4493
|
}
|
|
3504
4494
|
}
|
|
3505
|
-
async getRemainingTime(key,
|
|
3506
|
-
if (undefined) {
|
|
4495
|
+
async getRemainingTime(key, context) {
|
|
4496
|
+
if (typeof window !== "undefined") {
|
|
3507
4497
|
try {
|
|
3508
4498
|
const prefixedKey = "cache:" + key;
|
|
3509
4499
|
const store = await this.getStore("readonly");
|
|
@@ -3522,7 +4512,7 @@ class CIndexedDBCache extends ACacheProvider {
|
|
|
3522
4512
|
return null;
|
|
3523
4513
|
}
|
|
3524
4514
|
async cleanupExpired() {
|
|
3525
|
-
if (!undefined) return;
|
|
4515
|
+
if (!(typeof window !== "undefined")) return;
|
|
3526
4516
|
try {
|
|
3527
4517
|
const prefix = "cache:";
|
|
3528
4518
|
const now = Date.now();
|
|
@@ -3563,275 +4553,6 @@ const CIndexedDBCache$1 = {
|
|
|
3563
4553
|
CIndexedDBCache: CIndexedDBCache
|
|
3564
4554
|
};
|
|
3565
4555
|
|
|
3566
|
-
class CMemoryCache extends ACacheProvider {
|
|
3567
|
-
static instance = null;
|
|
3568
|
-
static _storage = null;
|
|
3569
|
-
static get storage() {
|
|
3570
|
-
if (!this._storage) this._storage = /* @__PURE__ */ new Map();
|
|
3571
|
-
return this._storage;
|
|
3572
|
-
}
|
|
3573
|
-
static getInstance() {
|
|
3574
|
-
if (!this.instance) {
|
|
3575
|
-
this.instance = new CMemoryCache();
|
|
3576
|
-
}
|
|
3577
|
-
return this.instance;
|
|
3578
|
-
}
|
|
3579
|
-
constructor() {
|
|
3580
|
-
super();
|
|
3581
|
-
if (undefined && CMemoryCache.storage.size === 0) {
|
|
3582
|
-
this._hydrateFromPayload();
|
|
3583
|
-
}
|
|
3584
|
-
}
|
|
3585
|
-
async _hydrateFromPayload() {
|
|
3586
|
-
try {
|
|
3587
|
-
const payloadData = index.getSSRPayload();
|
|
3588
|
-
if (!payloadData) return;
|
|
3589
|
-
for (const key in payloadData) {
|
|
3590
|
-
const value = payloadData[key];
|
|
3591
|
-
if (value && typeof value === "object" && "data" in value && "timestamp" in value && "lifetime" in value) {
|
|
3592
|
-
if (typeof value.lifetime === "number") {
|
|
3593
|
-
CMemoryCache.storage.set(key, value);
|
|
3594
|
-
}
|
|
3595
|
-
}
|
|
3596
|
-
}
|
|
3597
|
-
} catch (e) {
|
|
3598
|
-
console.warn("[Katlux Cache] CMemoryCache payload hydration failed", e);
|
|
3599
|
-
}
|
|
3600
|
-
}
|
|
3601
|
-
async getKeyList(nuxtApp) {
|
|
3602
|
-
const prefix = "cache:";
|
|
3603
|
-
return Array.from(CMemoryCache.storage.keys()).filter((key) => key.startsWith(prefix)).map((key) => key.substring(prefix.length));
|
|
3604
|
-
}
|
|
3605
|
-
async get(key, nuxtApp) {
|
|
3606
|
-
const prefixedKey = "cache:" + key;
|
|
3607
|
-
const entry = CMemoryCache.storage.get(prefixedKey);
|
|
3608
|
-
if (entry) {
|
|
3609
|
-
if (Date.now() - entry.timestamp <= entry.lifetime) {
|
|
3610
|
-
return entry.data;
|
|
3611
|
-
} else {
|
|
3612
|
-
CMemoryCache.storage.delete(prefixedKey);
|
|
3613
|
-
}
|
|
3614
|
-
}
|
|
3615
|
-
try {
|
|
3616
|
-
const payloadData = index.getSSRPayload(nuxtApp);
|
|
3617
|
-
if (payloadData && payloadData[prefixedKey]) {
|
|
3618
|
-
const entry2 = payloadData[prefixedKey];
|
|
3619
|
-
if (Date.now() - entry2.timestamp <= entry2.lifetime) {
|
|
3620
|
-
CMemoryCache.storage.set(prefixedKey, entry2);
|
|
3621
|
-
return entry2.data;
|
|
3622
|
-
}
|
|
3623
|
-
}
|
|
3624
|
-
} catch (e) {
|
|
3625
|
-
console.warn("[Katlux Cache] CMemoryCache error reading SSR payload for key: " + key, e);
|
|
3626
|
-
}
|
|
3627
|
-
return null;
|
|
3628
|
-
}
|
|
3629
|
-
async set(key, data, lifetime, nuxtApp) {
|
|
3630
|
-
const prefixedKey = "cache:" + key;
|
|
3631
|
-
const entry = {
|
|
3632
|
-
data,
|
|
3633
|
-
timestamp: Date.now(),
|
|
3634
|
-
lifetime
|
|
3635
|
-
};
|
|
3636
|
-
if (undefined && nuxtApp) {
|
|
3637
|
-
try {
|
|
3638
|
-
const payload = nuxtApp.payload?.data || nuxtApp.ssrContext?.payload?.data;
|
|
3639
|
-
if (payload) {
|
|
3640
|
-
payload[prefixedKey] = entry;
|
|
3641
|
-
}
|
|
3642
|
-
} catch (e) {
|
|
3643
|
-
console.warn("[Katlux Cache] CMemoryCache error writing SSR payload for key: " + key, e);
|
|
3644
|
-
}
|
|
3645
|
-
}
|
|
3646
|
-
CMemoryCache.storage.set(prefixedKey, entry);
|
|
3647
|
-
}
|
|
3648
|
-
async remove(key, nuxtApp) {
|
|
3649
|
-
const prefixedKey = "cache:" + key;
|
|
3650
|
-
CMemoryCache.storage.delete(prefixedKey);
|
|
3651
|
-
if (undefined && nuxtApp) {
|
|
3652
|
-
try {
|
|
3653
|
-
const payload = nuxtApp.payload?.data || nuxtApp.ssrContext?.payload?.data;
|
|
3654
|
-
if (payload && payload[prefixedKey]) {
|
|
3655
|
-
delete payload[prefixedKey];
|
|
3656
|
-
}
|
|
3657
|
-
} catch (e) {
|
|
3658
|
-
console.warn("[Katlux Cache] CMemoryCache error deleting key from SSR payload: " + key, e);
|
|
3659
|
-
}
|
|
3660
|
-
}
|
|
3661
|
-
}
|
|
3662
|
-
async removeByPrefix(prefix, nuxtApp) {
|
|
3663
|
-
const fullPrefix = "cache:" + prefix;
|
|
3664
|
-
const keysToDelete = [];
|
|
3665
|
-
for (const key of CMemoryCache.storage.keys()) {
|
|
3666
|
-
if (key.startsWith(fullPrefix)) {
|
|
3667
|
-
keysToDelete.push(key);
|
|
3668
|
-
}
|
|
3669
|
-
}
|
|
3670
|
-
for (const key of keysToDelete) {
|
|
3671
|
-
CMemoryCache.storage.delete(key);
|
|
3672
|
-
}
|
|
3673
|
-
if (undefined && nuxtApp) {
|
|
3674
|
-
try {
|
|
3675
|
-
const payload = nuxtApp.payload?.data || nuxtApp.ssrContext?.payload?.data;
|
|
3676
|
-
if (payload) {
|
|
3677
|
-
for (const key in payload) {
|
|
3678
|
-
if (key.startsWith(fullPrefix)) {
|
|
3679
|
-
delete payload[key];
|
|
3680
|
-
}
|
|
3681
|
-
}
|
|
3682
|
-
}
|
|
3683
|
-
} catch (e) {
|
|
3684
|
-
console.warn("[Katlux Cache] CMemoryCache error removing prefix from SSR payload: " + prefix, e);
|
|
3685
|
-
}
|
|
3686
|
-
}
|
|
3687
|
-
}
|
|
3688
|
-
async getRemainingTime(key, nuxtApp) {
|
|
3689
|
-
const prefixedKey = "cache:" + key;
|
|
3690
|
-
const entry = CMemoryCache.storage.get(prefixedKey);
|
|
3691
|
-
if (!entry) return null;
|
|
3692
|
-
return Math.max(0, entry.timestamp + entry.lifetime - Date.now());
|
|
3693
|
-
}
|
|
3694
|
-
async cleanupExpired() {
|
|
3695
|
-
const prefix = "cache:";
|
|
3696
|
-
const now = Date.now();
|
|
3697
|
-
const keysToDelete = [];
|
|
3698
|
-
for (const [key, entry] of CMemoryCache.storage.entries()) {
|
|
3699
|
-
if (key.startsWith(prefix)) {
|
|
3700
|
-
if (now - entry.timestamp > entry.lifetime) {
|
|
3701
|
-
keysToDelete.push(key);
|
|
3702
|
-
}
|
|
3703
|
-
}
|
|
3704
|
-
}
|
|
3705
|
-
for (const key of keysToDelete) {
|
|
3706
|
-
CMemoryCache.storage.delete(key);
|
|
3707
|
-
}
|
|
3708
|
-
}
|
|
3709
|
-
}
|
|
3710
|
-
|
|
3711
|
-
const CMemoryCache$1 = {
|
|
3712
|
-
__proto__: null,
|
|
3713
|
-
CMemoryCache: CMemoryCache
|
|
3714
|
-
};
|
|
3715
|
-
|
|
3716
|
-
class CApplicationCache extends ACacheProvider {
|
|
3717
|
-
static instance = null;
|
|
3718
|
-
static _storage = null;
|
|
3719
|
-
static get storage() {
|
|
3720
|
-
if (!this._storage) {
|
|
3721
|
-
this._storage = /* @__PURE__ */ new Map();
|
|
3722
|
-
}
|
|
3723
|
-
return this._storage;
|
|
3724
|
-
}
|
|
3725
|
-
static getInstance() {
|
|
3726
|
-
if (!this.instance) {
|
|
3727
|
-
this.instance = new CApplicationCache();
|
|
3728
|
-
}
|
|
3729
|
-
return this.instance;
|
|
3730
|
-
}
|
|
3731
|
-
static getSnapshot() {
|
|
3732
|
-
return this.storage;
|
|
3733
|
-
}
|
|
3734
|
-
constructor() {
|
|
3735
|
-
super();
|
|
3736
|
-
}
|
|
3737
|
-
async getKeyList(nuxtApp) {
|
|
3738
|
-
const prefix = "cache:";
|
|
3739
|
-
const storage = CApplicationCache.storage;
|
|
3740
|
-
return Array.from(storage.keys()).filter((key) => key.startsWith(prefix)).map((key) => key.substring(prefix.length));
|
|
3741
|
-
}
|
|
3742
|
-
async get(key, nuxtApp) {
|
|
3743
|
-
if (undefined) {
|
|
3744
|
-
const prefixedKey = "cache:" + key;
|
|
3745
|
-
const storage = CApplicationCache.storage;
|
|
3746
|
-
const entry = storage.get(prefixedKey);
|
|
3747
|
-
if (!entry) return null;
|
|
3748
|
-
if (Date.now() - entry.timestamp > entry.lifetime) {
|
|
3749
|
-
storage.delete(prefixedKey);
|
|
3750
|
-
return null;
|
|
3751
|
-
}
|
|
3752
|
-
return entry.data;
|
|
3753
|
-
}
|
|
3754
|
-
return null;
|
|
3755
|
-
}
|
|
3756
|
-
async set(key, data, lifetime, nuxtApp) {
|
|
3757
|
-
if (undefined) {
|
|
3758
|
-
const prefixedKey = "cache:" + key;
|
|
3759
|
-
const storage = CApplicationCache.storage;
|
|
3760
|
-
storage.set(prefixedKey, {
|
|
3761
|
-
data,
|
|
3762
|
-
timestamp: Date.now(),
|
|
3763
|
-
lifetime
|
|
3764
|
-
});
|
|
3765
|
-
}
|
|
3766
|
-
}
|
|
3767
|
-
async remove(key, nuxtApp) {
|
|
3768
|
-
if (undefined) {
|
|
3769
|
-
const prefixedKey = "cache:" + key;
|
|
3770
|
-
CApplicationCache.storage.delete(prefixedKey);
|
|
3771
|
-
}
|
|
3772
|
-
}
|
|
3773
|
-
async removeByPrefix(prefix, nuxtApp) {
|
|
3774
|
-
if (undefined) {
|
|
3775
|
-
const fullPrefix = "cache:" + prefix;
|
|
3776
|
-
const storage = CApplicationCache.storage;
|
|
3777
|
-
const keysToDelete = [];
|
|
3778
|
-
for (const key of storage.keys()) {
|
|
3779
|
-
if (key.startsWith(fullPrefix)) {
|
|
3780
|
-
keysToDelete.push(key);
|
|
3781
|
-
}
|
|
3782
|
-
}
|
|
3783
|
-
for (const key of keysToDelete) {
|
|
3784
|
-
storage.delete(key);
|
|
3785
|
-
}
|
|
3786
|
-
}
|
|
3787
|
-
}
|
|
3788
|
-
async getRemainingTime(key, nuxtApp) {
|
|
3789
|
-
if (undefined) {
|
|
3790
|
-
const prefixedKey = "cache:" + key;
|
|
3791
|
-
const storage = CApplicationCache.storage;
|
|
3792
|
-
const entry = storage.get(prefixedKey);
|
|
3793
|
-
if (!entry) return null;
|
|
3794
|
-
return Math.max(0, entry.timestamp + entry.lifetime - Date.now());
|
|
3795
|
-
}
|
|
3796
|
-
return null;
|
|
3797
|
-
}
|
|
3798
|
-
async cleanupExpired() {
|
|
3799
|
-
if (undefined) {
|
|
3800
|
-
const prefix = "cache:";
|
|
3801
|
-
const now = Date.now();
|
|
3802
|
-
const storage = CApplicationCache.storage;
|
|
3803
|
-
const keysToDelete = [];
|
|
3804
|
-
for (const [key, entry] of storage.entries()) {
|
|
3805
|
-
if (key.startsWith(prefix)) {
|
|
3806
|
-
if (now - entry.timestamp > entry.lifetime) {
|
|
3807
|
-
keysToDelete.push(key);
|
|
3808
|
-
}
|
|
3809
|
-
}
|
|
3810
|
-
}
|
|
3811
|
-
for (const key of keysToDelete) {
|
|
3812
|
-
storage.delete(key);
|
|
3813
|
-
}
|
|
3814
|
-
}
|
|
3815
|
-
}
|
|
3816
|
-
}
|
|
3817
|
-
|
|
3818
|
-
const CApplicationCache$1 = {
|
|
3819
|
-
__proto__: null,
|
|
3820
|
-
CApplicationCache: CApplicationCache
|
|
3821
|
-
};
|
|
3822
|
-
|
|
3823
|
-
exports.DefaultHydrationAdapter = index.DefaultHydrationAdapter;
|
|
3824
|
-
exports.NuxtHydrationAdapter = index.NuxtHydrationAdapter;
|
|
3825
|
-
exports.clearSSRData = index.clearSSRData;
|
|
3826
|
-
exports.fetchWithSSR = index.fetchWithSSR;
|
|
3827
|
-
exports.getAppRoute = index.getAppRoute;
|
|
3828
|
-
exports.getAppRouter = index.getAppRouter;
|
|
3829
|
-
exports.getHydrationAdapter = index.getHydrationAdapter;
|
|
3830
|
-
exports.getPlatformApp = index.getPlatformApp;
|
|
3831
|
-
exports.getSSRData = index.getSSRData;
|
|
3832
|
-
exports.getSSRPayload = index.getSSRPayload;
|
|
3833
|
-
exports.onPlatformReady = index.onPlatformReady;
|
|
3834
|
-
exports.setHydrationAdapter = index.setHydrationAdapter;
|
|
3835
4556
|
exports.AAPIDataProvider = AAPIDataProvider;
|
|
3836
4557
|
exports.ADataProvider = ADataProvider;
|
|
3837
4558
|
exports.CAPIFlatClientDataProvider = CAPIFlatClientDataProvider;
|
|
@@ -3849,6 +4570,7 @@ exports.CSessionCache = CSessionCache;
|
|
|
3849
4570
|
exports.CTreeClientDataProvider = CTreeClientDataProvider;
|
|
3850
4571
|
exports.CTreeServerDataProvider = CTreeServerDataProvider;
|
|
3851
4572
|
exports.CacheProviderFactory = CacheProviderFactory;
|
|
4573
|
+
exports.DefaultHydrationAdapter = DefaultHydrationAdapter;
|
|
3852
4574
|
exports.ECacheStrategy = ECacheStrategy;
|
|
3853
4575
|
exports.EDataFilterOperator = EDataFilterOperator;
|
|
3854
4576
|
exports.EQueueStorage = EQueueStorage;
|
|
@@ -3857,7 +4579,9 @@ exports.QueueStorageFactory = QueueStorageFactory;
|
|
|
3857
4579
|
exports.RequestProvider = RequestProvider;
|
|
3858
4580
|
exports.RequestProviderRegistry = RequestProviderRegistry;
|
|
3859
4581
|
exports.RequestQueue = RequestQueue;
|
|
4582
|
+
exports.SENSITIVE_HEADER_KEYS = SENSITIVE_HEADER_KEYS;
|
|
3860
4583
|
exports.applyOperator = applyOperator;
|
|
4584
|
+
exports.clearSSRData = clearSSRData;
|
|
3861
4585
|
exports.compareAnd = compareAnd;
|
|
3862
4586
|
exports.compareEqual = compareEqual;
|
|
3863
4587
|
exports.compareIn = compareIn;
|
|
@@ -3865,8 +4589,17 @@ exports.compareOr = compareOr;
|
|
|
3865
4589
|
exports.compareValues = compareValues;
|
|
3866
4590
|
exports.debounce = debounce;
|
|
3867
4591
|
exports.evaluateFilter = evaluateFilter;
|
|
4592
|
+
exports.fetchWithSSR = fetchWithSSR;
|
|
3868
4593
|
exports.filterData = filterData;
|
|
3869
4594
|
exports.filterTreeData = filterTreeData;
|
|
4595
|
+
exports.getAppRoute = getAppRoute;
|
|
4596
|
+
exports.getAppRouter = getAppRouter;
|
|
4597
|
+
exports.getHydrationAdapter = getHydrationAdapter;
|
|
4598
|
+
exports.getPlatformApp = getPlatformApp;
|
|
4599
|
+
exports.getSSRData = getSSRData;
|
|
4600
|
+
exports.getSSRPayload = getSSRPayload;
|
|
4601
|
+
exports.onPlatformReady = onPlatformReady;
|
|
4602
|
+
exports.setHydrationAdapter = setHydrationAdapter;
|
|
3870
4603
|
exports.sortData = sortData;
|
|
3871
4604
|
exports.useDebounce = useDebounce;
|
|
3872
4605
|
exports.useFilterLogic = useFilterLogic;
|