@kylexd/composable-kit 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +91 -0
  2. package/dist/composables/useApi.d.ts +78 -0
  3. package/dist/composables/useCache.d.ts +23 -0
  4. package/dist/composables/useCookies.d.ts +8 -0
  5. package/dist/composables/useCountdown.d.ts +31 -0
  6. package/dist/composables/useCreatedCancelApi.d.ts +41 -0
  7. package/dist/composables/useDownload.d.ts +5 -0
  8. package/dist/composables/useDownloadLink.d.ts +22 -0
  9. package/dist/composables/useForm.d.ts +13 -0
  10. package/dist/composables/useIsMobile.d.ts +7 -0
  11. package/dist/composables/useOpenLink.d.ts +8 -0
  12. package/dist/composables/useParseZod.d.ts +23 -0
  13. package/dist/composables/usePcHtmlToMobile.d.ts +40 -0
  14. package/dist/composables/usePopupQueue.d.ts +22 -0
  15. package/dist/composables/useQrCode.d.ts +6 -0
  16. package/dist/composables/useRsa.d.ts +6 -0
  17. package/dist/composables.d.ts +15 -0
  18. package/dist/composables.js +2 -0
  19. package/dist/dayjs-BXpdKo4H.js +65 -0
  20. package/dist/index.d.ts +34 -0
  21. package/dist/index.js +5 -0
  22. package/dist/sdk/useFirebase.d.ts +12 -0
  23. package/dist/sdk/useIntercom.d.ts +19 -0
  24. package/dist/sdk/useSalesmartly.d.ts +24 -0
  25. package/dist/sdk/useTurbolinkSdk.d.ts +30 -0
  26. package/dist/sdk.d.ts +4 -0
  27. package/dist/sdk.js +2 -0
  28. package/dist/tree-Ck3oXYA2.js +332 -0
  29. package/dist/types/shared.d.ts +11 -0
  30. package/dist/useRsa-aK-vaZUD.js +739 -0
  31. package/dist/useTurbolinkSdk-peRMONxI.js +250 -0
  32. package/dist/utils/copy.d.ts +5 -0
  33. package/dist/utils/dayjs.d.ts +15 -0
  34. package/dist/utils/debounce.d.ts +5 -0
  35. package/dist/utils/deepClone.d.ts +1 -0
  36. package/dist/utils/encryption.d.ts +11 -0
  37. package/dist/utils/formatParams.d.ts +4 -0
  38. package/dist/utils/isNotEmpty.d.ts +1 -0
  39. package/dist/utils/patterns.d.ts +1 -0
  40. package/dist/utils/piniaPersistedState.d.ts +15 -0
  41. package/dist/utils/renderSfc.d.ts +16 -0
  42. package/dist/utils/singleFlight.d.ts +6 -0
  43. package/dist/utils/thumbnail.d.ts +13 -0
  44. package/dist/utils/tree.d.ts +20 -0
  45. package/dist/utils/typeUtils.d.ts +3 -0
  46. package/dist/utils.d.ts +14 -0
  47. package/dist/utils.js +3 -0
  48. package/package.json +135 -0
@@ -0,0 +1,739 @@
1
+ import { l as formatParams, t as dayjsInstance, u as deepClone } from "./dayjs-BXpdKo4H.js";
2
+ import { nextTick, onBeforeUnmount, reactive, ref, watch } from "vue";
3
+ import Cookies from "js-cookie";
4
+ import isMobile from "ismobilejs";
5
+ import qrcode from "qrcode";
6
+ import JSEncrypt from "jsencrypt";
7
+ //#region src/composables/useCache.ts
8
+ var defaultBaseKey = "hooks-useCache-";
9
+ var defaultMemoryStorage = /* @__PURE__ */ new Map();
10
+ function useCache(options) {
11
+ const { key, time, useMemory = false, storageType = "localStorage", baseKey = defaultBaseKey, memoryStorage = defaultMemoryStorage, exposeMemoryToWindow } = options;
12
+ const cacheKey = baseKey + key;
13
+ if (exposeMemoryToWindow && typeof window !== "undefined") window[exposeMemoryToWindow] = memoryStorage;
14
+ const cacheData = ref(useMemory ? getDataFromMemory(cacheKey, time, memoryStorage) : getDataFromStorage(cacheKey, time, storageType));
15
+ watch(cacheData, (newData) => {
16
+ if (newData !== null && newData !== void 0) if (useMemory) setDataToMemory(cacheKey, newData, time, memoryStorage);
17
+ else setDataToStorage(cacheKey, newData, time, storageType);
18
+ else if (useMemory) memoryStorage.delete(cacheKey);
19
+ else getStorage(storageType).removeItem(cacheKey);
20
+ });
21
+ return {
22
+ cacheData,
23
+ clearCache: () => {
24
+ cacheData.value = null;
25
+ },
26
+ setCacheData: (data) => {
27
+ cacheData.value = data;
28
+ },
29
+ getCacheData: () => cacheData.value
30
+ };
31
+ }
32
+ function clearAllHooksCache(baseKey = defaultBaseKey, storageType = "localStorage") {
33
+ const storage = getStorage(storageType);
34
+ Object.keys(storage).forEach((key) => {
35
+ if (key.startsWith(baseKey)) storage.removeItem(key);
36
+ });
37
+ }
38
+ function clearAllMemoryCache(memoryStorage = defaultMemoryStorage) {
39
+ memoryStorage.clear();
40
+ }
41
+ function getStorage(storageType) {
42
+ return storageType === "localStorage" ? localStorage : sessionStorage;
43
+ }
44
+ function getDataFromStorage(key, time, storageType) {
45
+ const storageData = getStorage(storageType).getItem(key);
46
+ if (!storageData) return null;
47
+ const parsedData = JSON.parse(storageData);
48
+ if (parsedData.data === null || parsedData.data === void 0) return null;
49
+ if (time === 0 || Date.now() - parsedData.createdTime < time) return parsedData.data;
50
+ return null;
51
+ }
52
+ function setDataToStorage(key, data, time, storageType) {
53
+ getStorage(storageType).setItem(key, JSON.stringify({
54
+ data,
55
+ createdTime: Date.now(),
56
+ time
57
+ }));
58
+ }
59
+ function getDataFromMemory(key, time, memoryStorage) {
60
+ const storageData = memoryStorage.get(key);
61
+ if (!storageData?.data) return null;
62
+ if (time === 0 || Date.now() - storageData.createdTime < time) return storageData.data;
63
+ return null;
64
+ }
65
+ function setDataToMemory(key, data, time, memoryStorage) {
66
+ memoryStorage.set(key, {
67
+ data,
68
+ createdTime: Date.now(),
69
+ time
70
+ });
71
+ }
72
+ //#endregion
73
+ //#region src/composables/useApi.ts
74
+ function useDataApi(asyncApi, options) {
75
+ const loading = ref(false);
76
+ const data = ref();
77
+ const cacheDataInfo = options?.cache ? useCache(options.cache) : null;
78
+ const sentDataApi = async (params, asyncApiOptions) => {
79
+ loading.value = true;
80
+ if (cacheDataInfo && !asyncApiOptions?.forceRefresh) {
81
+ const cacheData = cacheDataInfo.cacheData.value;
82
+ if (cacheData) {
83
+ const clonedCache = deepClone(cacheData);
84
+ data.value = options?.format ? options.format({ data: clonedCache }, data.value) : clonedCache;
85
+ loading.value = false;
86
+ return data.value;
87
+ }
88
+ }
89
+ try {
90
+ const apiParams = params ?? options?.query?.value ?? void 0;
91
+ const response = await asyncApi(options?.formatParams ? options.formatParams(apiParams) : apiParams);
92
+ if (cacheDataInfo) cacheDataInfo.cacheData.value = response.data;
93
+ data.value = options?.format ? options.format(response, data.value) : response.data;
94
+ return data.value;
95
+ } catch (error) {
96
+ options?.onError?.(error);
97
+ data.value = options?.catchError ? options.catchError(error, data.value) : void 0;
98
+ throw error;
99
+ } finally {
100
+ loading.value = false;
101
+ }
102
+ };
103
+ watch(data, (newData) => {
104
+ if (!newData && cacheDataInfo) cacheDataInfo.cacheData.value = null;
105
+ });
106
+ return {
107
+ loading,
108
+ data,
109
+ sentDataApi
110
+ };
111
+ }
112
+ function useListApi(asyncApi, options) {
113
+ const loading = ref(false);
114
+ const dataList = ref();
115
+ const data = ref();
116
+ const total = ref(0);
117
+ const getList = async () => {
118
+ loading.value = true;
119
+ try {
120
+ const params = deepClone(options?.query?.value);
121
+ const response = await asyncApi(formatParams(params, options?.formatParamsOptions));
122
+ total.value = response.total;
123
+ dataList.value = options?.format ? options.format(response, dataList.value, params) : response.list;
124
+ data.value = response.data;
125
+ return dataList.value;
126
+ } catch (error) {
127
+ options?.onError?.(error);
128
+ dataList.value = options?.catchError ? options.catchError(error, dataList.value) : void 0;
129
+ loading.value = Boolean(options?.isCancel?.(error));
130
+ throw error;
131
+ } finally {
132
+ if (!loading.value) loading.value = false;
133
+ }
134
+ };
135
+ return {
136
+ loading,
137
+ dataList,
138
+ getList,
139
+ total,
140
+ data
141
+ };
142
+ }
143
+ function useScrollList(asyncApi, options) {
144
+ const loading = ref(false);
145
+ const dataList = ref();
146
+ const data = ref();
147
+ const total = ref(0);
148
+ const isError = ref(false);
149
+ const isNoMore = ref(false);
150
+ const getList = async () => {
151
+ loading.value = true;
152
+ try {
153
+ isError.value = false;
154
+ isNoMore.value = false;
155
+ const params = deepClone(options?.query?.value);
156
+ const response = await asyncApi(formatParams(params, options?.formatParamsOptions));
157
+ data.value = response.data;
158
+ total.value = response.total;
159
+ const oldList = dataList.value;
160
+ const newList = options?.format ? options.format(response, params) : response.list;
161
+ const mergeList = [...oldList || [], ...newList ?? []];
162
+ dataList.value = (options?.query?.value?.pageNum ?? 1) === 1 ? newList : mergeList;
163
+ if (!response.list || response.list.length < (options?.query?.value?.pageSize ?? 10)) isNoMore.value = true;
164
+ if (options?.query?.value && "pageNum" in options.query.value) options.query.value.pageNum = (options.query.value.pageNum ?? 1) + 1;
165
+ return dataList.value;
166
+ } catch (error) {
167
+ options?.onError?.(error);
168
+ isError.value = true;
169
+ dataList.value = options?.catchError ? options.catchError(error, dataList.value) : dataList.value;
170
+ throw error;
171
+ } finally {
172
+ loading.value = false;
173
+ }
174
+ };
175
+ return {
176
+ loading,
177
+ dataList,
178
+ getList,
179
+ total,
180
+ data,
181
+ isError,
182
+ isNoMore
183
+ };
184
+ }
185
+ //#endregion
186
+ //#region src/composables/useCountdown.ts
187
+ function createCountdownDate(value) {
188
+ return ref(value);
189
+ }
190
+ function useCountdown() {
191
+ const getDiff = (targetTime, unit) => {
192
+ if (!targetTime) return 0;
193
+ return dayjsInstance.utc(targetTime).diff(dayjsInstance(), unit);
194
+ };
195
+ const getCurrentDurationOfDays = (targetTime, options) => {
196
+ const date = createCountdownDate({
197
+ s: 0,
198
+ m: 0,
199
+ h: 0,
200
+ d: 0,
201
+ asSeconds: 0
202
+ });
203
+ let timer;
204
+ const stop = () => {
205
+ if (timer) clearInterval(timer);
206
+ timer = void 0;
207
+ };
208
+ const update = () => {
209
+ const seconds = getDiff(targetTime, "seconds");
210
+ if (seconds <= 0) {
211
+ stop();
212
+ date.value = {
213
+ s: 0,
214
+ m: 0,
215
+ h: 0,
216
+ d: 0,
217
+ asSeconds: 0
218
+ };
219
+ options?.stopCallback?.();
220
+ return;
221
+ }
222
+ date.value = {
223
+ s: seconds % 60,
224
+ m: getDiff(targetTime, "minutes") % 60,
225
+ h: getDiff(targetTime, "hours") % 24,
226
+ d: getDiff(targetTime, "days"),
227
+ asSeconds: seconds
228
+ };
229
+ };
230
+ const start = () => {
231
+ stop();
232
+ if (getDiff(targetTime, "seconds") > 0) {
233
+ update();
234
+ timer = setInterval(update, 1e3);
235
+ }
236
+ };
237
+ const updateTargetTime = (newTargetTime) => {
238
+ targetTime = newTargetTime;
239
+ start();
240
+ };
241
+ start();
242
+ return {
243
+ date,
244
+ stop,
245
+ updateTargetTime
246
+ };
247
+ };
248
+ const getCurrentDurationOfHours = (targetTime, options) => {
249
+ const date = createCountdownDate({
250
+ s: 0,
251
+ m: 0,
252
+ h: 0,
253
+ asSeconds: 0
254
+ });
255
+ let timer;
256
+ const stop = () => {
257
+ if (timer) clearInterval(timer);
258
+ timer = void 0;
259
+ };
260
+ const update = () => {
261
+ const seconds = getDiff(targetTime, "seconds");
262
+ if (seconds <= 0) {
263
+ stop();
264
+ date.value = {
265
+ s: 0,
266
+ m: 0,
267
+ h: 0,
268
+ asSeconds: 0
269
+ };
270
+ options?.stopCallback?.();
271
+ return;
272
+ }
273
+ date.value = {
274
+ s: seconds % 60,
275
+ m: getDiff(targetTime, "minutes") % 60,
276
+ h: getDiff(targetTime, "hours"),
277
+ asSeconds: seconds
278
+ };
279
+ };
280
+ const start = () => {
281
+ stop();
282
+ if (getDiff(targetTime, "seconds") > 0) {
283
+ update();
284
+ timer = setInterval(update, 1e3);
285
+ }
286
+ };
287
+ const updateTargetTime = (newTargetTime) => {
288
+ targetTime = newTargetTime;
289
+ start();
290
+ };
291
+ start();
292
+ return {
293
+ date,
294
+ stop,
295
+ updateTargetTime
296
+ };
297
+ };
298
+ return {
299
+ getCurrentDurationOfDays,
300
+ getCurrentDurationOfHours,
301
+ getDiff
302
+ };
303
+ }
304
+ //#endregion
305
+ //#region src/composables/useCookies.ts
306
+ function useCookies(options) {
307
+ const getDomain = () => typeof options?.domain === "function" ? options.domain() : options?.domain;
308
+ const setCookie = (key, value, expires) => {
309
+ Cookies.set(key, value, {
310
+ domain: getDomain(),
311
+ expires
312
+ });
313
+ };
314
+ const getCookie = (key) => Cookies.get(key);
315
+ const removeCookie = (key) => Cookies.remove(key, { domain: getDomain() });
316
+ return {
317
+ setCookie,
318
+ getCookie,
319
+ removeCookie
320
+ };
321
+ }
322
+ //#endregion
323
+ //#region src/composables/useCreatedCancelApi.ts
324
+ function useCreatedCancelApi(api) {
325
+ const cancel = ref(null);
326
+ const wrappedApi = (params) => {
327
+ cancel.value?.abort();
328
+ return api(params, { useAbortController: (controller) => {
329
+ cancel.value = controller;
330
+ } });
331
+ };
332
+ return {
333
+ api: wrappedApi,
334
+ cancel
335
+ };
336
+ }
337
+ //#endregion
338
+ //#region src/composables/useDownload.ts
339
+ function useDownload() {
340
+ const downloadBase64File = (base64, name) => downloadByHref(base64, name);
341
+ const downloadUrlFile = (url, name) => downloadByHref(url, name);
342
+ const downloadBlobFile = (blob, name) => {
343
+ const url = URL.createObjectURL(blob);
344
+ downloadByHref(url, name);
345
+ URL.revokeObjectURL(url);
346
+ };
347
+ return {
348
+ downloadBase64File,
349
+ downloadBlobFile,
350
+ downloadUrlFile
351
+ };
352
+ }
353
+ function downloadByHref(href, name) {
354
+ const link = document.createElement("a");
355
+ link.href = href;
356
+ link.download = name;
357
+ link.click();
358
+ link.remove();
359
+ }
360
+ //#endregion
361
+ //#region src/composables/useIsMobile.ts
362
+ function useIsMobile(userAgent = window.navigator.userAgent) {
363
+ const result = isMobile(userAgent);
364
+ return {
365
+ any: result.any,
366
+ phone: result.phone,
367
+ tablet: result.tablet,
368
+ isIOS: result.apple.device,
369
+ raw: result
370
+ };
371
+ }
372
+ //#endregion
373
+ //#region src/composables/useDownloadLink.ts
374
+ function useDownloadLink(options) {
375
+ const { setCookie, getCookie } = useCookies(options.cookies);
376
+ const keys = {
377
+ appleURL: options.cookieKeys?.appleURL ?? "downloadLink-turbo-apple",
378
+ googleURL: options.cookieKeys?.googleURL ?? "downloadLink-turbo-google"
379
+ };
380
+ function setDownloadLinkToCookie(links) {
381
+ setCookie(keys.appleURL, links.appleURL, options.expires ?? 36500);
382
+ setCookie(keys.googleURL, links.googleURL, options.expires ?? 36500);
383
+ }
384
+ function getDownloadLinkFromCookie() {
385
+ return {
386
+ appleURL: getCookie(keys.appleURL),
387
+ googleURL: getCookie(keys.googleURL)
388
+ };
389
+ }
390
+ function getDownloadLink() {
391
+ const cookieLinks = getDownloadLinkFromCookie();
392
+ return {
393
+ appleURL: cookieLinks.appleURL || options.defaultLinks.appleURL,
394
+ googleURL: cookieLinks.googleURL || options.defaultLinks.googleURL
395
+ };
396
+ }
397
+ function getPlatformDownloadAppLink() {
398
+ const links = getDownloadLink();
399
+ return useIsMobile(options.userAgent ?? window.navigator.userAgent).isIOS ? links.appleURL : links.googleURL;
400
+ }
401
+ function downloadApp() {
402
+ window.location.href = getPlatformDownloadAppLink();
403
+ }
404
+ return {
405
+ setDownloadLinkToCookie,
406
+ getDownloadLinkFromCookie,
407
+ getDownloadLink,
408
+ downloadApp,
409
+ getPlatformDownloadAppLink
410
+ };
411
+ }
412
+ //#endregion
413
+ //#region src/composables/useForm.ts
414
+ function useForm(formData, formRef, options) {
415
+ const originalData = deepClone(formData.value);
416
+ function resetForm(excludeKeys = options?.excludeKeys ?? []) {
417
+ const newData = deepClone(originalData);
418
+ excludeKeys.forEach((key) => {
419
+ if (key in formData.value) newData[key] = formData.value[key];
420
+ });
421
+ if ("pageSize" in formData.value) newData.pageSize = formData.value.pageSize;
422
+ formData.value = newData;
423
+ formRef?.value?.resetValidation?.();
424
+ nextTick(() => formRef?.value?.resetValidation?.());
425
+ }
426
+ return { resetForm };
427
+ }
428
+ //#endregion
429
+ //#region src/composables/useOpenLink.ts
430
+ function useOpenLink(options) {
431
+ const open = options.open ?? ((url, target) => window.open(url, target));
432
+ const getBaseUrl = () => typeof options.baseUrl === "function" ? options.baseUrl() : options.baseUrl;
433
+ const openLink = (link) => {
434
+ if (link.startsWith("http")) {
435
+ open(link, "_self");
436
+ return;
437
+ }
438
+ const fullLink = `${getBaseUrl()}${link}`;
439
+ const path = new URL(fullLink).pathname;
440
+ open(options.isInternalRoute?.(path) ? link : fullLink, "_self");
441
+ };
442
+ return { openLink };
443
+ }
444
+ //#endregion
445
+ //#region src/composables/useParseZod.ts
446
+ function useParseZod(defaultOptions) {
447
+ const parseZod = (schema, data, options) => {
448
+ const result = schema.safeParse(data);
449
+ if (!result.success) {
450
+ const firstError = result.error.issues[0];
451
+ if (firstError) (options?.onError ?? defaultOptions?.onError)?.(firstError, result.error);
452
+ return false;
453
+ }
454
+ return true;
455
+ };
456
+ const asyncParseZod = async (schema, data, options) => {
457
+ const result = schema.safeParse(data);
458
+ if (!result.success) {
459
+ const firstError = result.error.issues[0];
460
+ if (firstError) (options?.onError ?? defaultOptions?.onError)?.(firstError, result.error);
461
+ throw firstError ?? result.error;
462
+ }
463
+ return result;
464
+ };
465
+ return {
466
+ parseZod,
467
+ asyncParseZod
468
+ };
469
+ }
470
+ //#endregion
471
+ //#region src/composables/usePcHtmlToMobile.ts
472
+ function parseStyle(styleStr) {
473
+ return styleStr.split(";").reduce((style, current) => {
474
+ const [key, value] = current.split(":");
475
+ if (key && value) style[key.trim()] = value.trim();
476
+ return style;
477
+ }, {});
478
+ }
479
+ function parsePixelWidth(width) {
480
+ if (!width || width === "100%") return void 0;
481
+ const value = Number(width.replace("px", ""));
482
+ return Number.isFinite(value) ? value : void 0;
483
+ }
484
+ function usePcHtmlToMobile(options = {}) {
485
+ const baseWidth = options.baseWidth ?? 750;
486
+ const heightOffset = options.heightOffset ?? 50;
487
+ const containerRef = ref(null);
488
+ const adaptedHtml = ref("");
489
+ const contentHeight = ref(0);
490
+ const transformStyle = reactive({
491
+ scale: 1,
492
+ translateX: 0,
493
+ translateY: 0
494
+ });
495
+ let measureNode;
496
+ let imageLoadCleanups = [];
497
+ function clearImageLoadListeners() {
498
+ imageLoadCleanups.forEach((cleanup) => cleanup());
499
+ imageLoadCleanups = [];
500
+ }
501
+ function removeMeasureNode() {
502
+ clearImageLoadListeners();
503
+ measureNode?.remove();
504
+ measureNode = void 0;
505
+ }
506
+ function createMeasureNode() {
507
+ removeMeasureNode();
508
+ const node = document.createElement("div");
509
+ if (options.hiddenContainerId) node.id = options.hiddenContainerId;
510
+ node.setAttribute("style", "width: 0px; height: 0px; overflow: hidden;");
511
+ document.body.appendChild(node);
512
+ measureNode = node;
513
+ return node;
514
+ }
515
+ function normalizeLinks(content) {
516
+ content.querySelectorAll("a").forEach((anchor, index) => {
517
+ options.transformLink?.(anchor, {
518
+ index,
519
+ href: anchor.getAttribute("href"),
520
+ content
521
+ });
522
+ if (!options.transformLink) anchor.setAttribute("href", "javascript:void(0)");
523
+ });
524
+ }
525
+ function normalizeImages(content) {
526
+ const images = content.querySelectorAll("img");
527
+ let contentWidth = baseWidth;
528
+ images.forEach((image, index) => {
529
+ const src = image.getAttribute("src");
530
+ const style = parseStyle(image.getAttribute("style") || "");
531
+ const width = style.width || null;
532
+ const pixelWidth = parsePixelWidth(width);
533
+ if (pixelWidth) contentWidth = Math.max(contentWidth, pixelWidth);
534
+ options.transformImage?.(image, {
535
+ index,
536
+ src,
537
+ width,
538
+ style,
539
+ content
540
+ });
541
+ if (src) {
542
+ image.removeAttribute("src");
543
+ image.setAttribute("src", src);
544
+ }
545
+ });
546
+ return contentWidth;
547
+ }
548
+ function updateLayout() {
549
+ const visibleWidth = containerRef.value?.offsetWidth || 0;
550
+ if (!visibleWidth || !measureNode) return;
551
+ const sourceWidth = measureNode.scrollWidth;
552
+ if (!sourceWidth || sourceWidth < visibleWidth) {
553
+ transformStyle.scale = 1;
554
+ contentHeight.value = measureNode.scrollHeight + heightOffset;
555
+ return;
556
+ }
557
+ const scale = visibleWidth / sourceWidth;
558
+ transformStyle.scale = scale;
559
+ contentHeight.value = measureNode.scrollHeight * scale + heightOffset;
560
+ measureNode.querySelectorAll("a").forEach((anchor) => {
561
+ anchor.setAttribute("href", "javascript:void(0)");
562
+ });
563
+ }
564
+ function bindImageLoadUpdate(node) {
565
+ clearImageLoadListeners();
566
+ node.querySelectorAll("img").forEach((image) => {
567
+ const onLoad = () => updateLayout();
568
+ image.addEventListener("load", onLoad);
569
+ imageLoadCleanups.push(() => image.removeEventListener("load", onLoad));
570
+ });
571
+ }
572
+ function preventRenderedLinks() {
573
+ containerRef.value?.querySelectorAll("a").forEach((anchor) => {
574
+ anchor.addEventListener("click", (event) => {
575
+ event.preventDefault();
576
+ }, { once: false });
577
+ });
578
+ }
579
+ async function formatHtml(html) {
580
+ const node = createMeasureNode();
581
+ const box = document.createElement("div");
582
+ const template = document.createElement("template");
583
+ template.innerHTML = html;
584
+ const content = template.content;
585
+ normalizeLinks(content);
586
+ const contentWidth = normalizeImages(content);
587
+ box.setAttribute("style", `width: ${contentWidth}px; height: max-content;`);
588
+ box.appendChild(content);
589
+ node.appendChild(box);
590
+ await nextTick();
591
+ updateLayout();
592
+ bindImageLoadUpdate(node);
593
+ adaptedHtml.value = node.innerHTML;
594
+ await nextTick();
595
+ preventRenderedLinks();
596
+ return adaptedHtml.value;
597
+ }
598
+ function getClickedImageSrcList(event) {
599
+ const images = containerRef.value?.querySelectorAll("img") || [];
600
+ const x = event.clientX;
601
+ const y = event.clientY;
602
+ const srcList = [];
603
+ images.forEach((image) => {
604
+ const rect = image.getBoundingClientRect();
605
+ const inX = x >= rect.left && x <= rect.right;
606
+ const inY = y >= rect.top && y <= rect.bottom;
607
+ if (inX && inY) {
608
+ const src = image.getAttribute("src");
609
+ if (src) srcList.push(src);
610
+ }
611
+ });
612
+ return srcList;
613
+ }
614
+ function handleClick(event) {
615
+ event.preventDefault();
616
+ const srcList = getClickedImageSrcList(event);
617
+ if (srcList.length) options.onImageClick?.(srcList);
618
+ return srcList;
619
+ }
620
+ function cleanup() {
621
+ removeMeasureNode();
622
+ }
623
+ onBeforeUnmount(cleanup);
624
+ return {
625
+ containerRef,
626
+ adaptedHtml,
627
+ contentHeight,
628
+ transformStyle,
629
+ formatHtml,
630
+ updateLayout,
631
+ handleClick,
632
+ cleanup
633
+ };
634
+ }
635
+ //#endregion
636
+ //#region src/composables/usePopupQueue.ts
637
+ var popupQueueMap = /* @__PURE__ */ new Map();
638
+ function usePopupQueue(options) {
639
+ const key = Symbol(options.key);
640
+ const queue = popupQueueMap.get(options.key) || [];
641
+ const getCurrentItem = () => queue.find((item) => item.key === key);
642
+ const cleanup = (item) => {
643
+ if (item.timer) {
644
+ clearTimeout(item.timer);
645
+ item.timer = void 0;
646
+ }
647
+ };
648
+ const updateStatus = (item, status) => {
649
+ if (item.status === status) return;
650
+ cleanup(item);
651
+ item.status = status;
652
+ item.onStateChange?.(status);
653
+ };
654
+ const cleanupQueue = (queueKey) => {
655
+ const list = popupQueueMap.get(queueKey);
656
+ if (!list) return;
657
+ const activeItems = list.filter((item) => {
658
+ if (item.status === "success" || item.status === "cancel") cleanup(item);
659
+ return item.status !== "success" && item.status !== "cancel";
660
+ });
661
+ if (activeItems.length === 0) popupQueueMap.delete(queueKey);
662
+ else popupQueueMap.set(queueKey, activeItems);
663
+ };
664
+ const next = () => {
665
+ cleanupQueue(options.key);
666
+ queue.find((item) => item.status === "pending")?.start();
667
+ };
668
+ const end = () => {
669
+ const item = getCurrentItem();
670
+ if (!item || item.status === "success" || item.status === "cancel") return;
671
+ if (item.status === "processing") {
672
+ updateStatus(item, "success");
673
+ cleanupQueue(options.key);
674
+ next();
675
+ }
676
+ };
677
+ const setupTimeout = (item) => {
678
+ if (!item.timeout || item.timeout <= 0) return;
679
+ item.timer = window.setTimeout(() => {
680
+ if (item.status === "processing") {
681
+ options.onTimeout?.();
682
+ end();
683
+ }
684
+ }, item.timeout);
685
+ };
686
+ const hookStart = () => {
687
+ const item = getCurrentItem();
688
+ if (item?.status === "pending") {
689
+ updateStatus(item, "processing");
690
+ setupTimeout(item);
691
+ options.start();
692
+ }
693
+ };
694
+ const cancel = () => {
695
+ const item = getCurrentItem();
696
+ if (!item || item.status === "success" || item.status === "cancel") return;
697
+ const wasProcessing = item.status === "processing";
698
+ updateStatus(item, "cancel");
699
+ if (wasProcessing) {
700
+ cleanupQueue(options.key);
701
+ next();
702
+ }
703
+ };
704
+ queue.push({
705
+ start: hookStart,
706
+ status: "pending",
707
+ key,
708
+ timeout: options.timeout,
709
+ onStateChange: options.onStateChange
710
+ });
711
+ popupQueueMap.set(options.key, queue);
712
+ if (queue.length === 1) hookStart();
713
+ return {
714
+ end,
715
+ cancel,
716
+ getStatus: () => getCurrentItem()?.status
717
+ };
718
+ }
719
+ //#endregion
720
+ //#region src/composables/useQrCode.ts
721
+ function useQrCode(defaultOptions) {
722
+ const generateQrCode = async (text, options) => {
723
+ return await qrcode.toDataURL(text, { width: options?.width ?? defaultOptions?.width ?? 480 });
724
+ };
725
+ return { generateQrCode };
726
+ }
727
+ //#endregion
728
+ //#region src/composables/useRsa.ts
729
+ function useRsa(options) {
730
+ async function encrypt(needEncryptData) {
731
+ const publicKey = await options.getPublicKey();
732
+ const jse = new JSEncrypt();
733
+ jse.setPublicKey(publicKey);
734
+ return jse.encrypt(needEncryptData) || "";
735
+ }
736
+ return { encrypt };
737
+ }
738
+ //#endregion
739
+ export { clearAllHooksCache as _, useParseZod as a, useDownloadLink as c, useCreatedCancelApi as d, useCookies as f, useScrollList as g, useListApi as h, usePcHtmlToMobile as i, useIsMobile as l, useDataApi as m, useQrCode as n, useOpenLink as o, useCountdown as p, usePopupQueue as r, useForm as s, useRsa as t, useDownload as u, clearAllMemoryCache as v, useCache as y };