@alibarbar/common 1.0.9 → 1.0.10
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/{chunk-O3O67R4I.js → algorithm.cjs} +0 -2
- package/dist/algorithm.js +130 -44
- package/dist/{chunk-LOAZSPGQ.js → array.cjs} +0 -2
- package/dist/array.js +135 -84
- package/dist/{chunk-Y364QIQH.js → color.cjs} +0 -2
- package/dist/color.js +127 -40
- package/dist/{chunk-DYBSRI7V.js → crypto.cjs} +0 -2
- package/dist/crypto.js +172 -60
- package/dist/{chunk-BHCRFURU.js → data-structure.cjs} +0 -2
- package/dist/data-structure.js +481 -32
- package/dist/{chunk-I3L42475.js → date.cjs} +0 -2
- package/dist/date.js +125 -72
- package/dist/{chunk-JK2SE3I2.js → dom.cjs} +0 -2
- package/dist/dom.js +84 -56
- package/dist/{chunk-7V5UQXIO.js → file.cjs} +0 -2
- package/dist/file.js +79 -32
- package/dist/{chunk-OX5PLOWB.js → i18n.cjs} +0 -2
- package/dist/i18n.js +78 -40
- package/dist/index.cjs +4132 -0
- package/dist/index.d.mts +3 -159
- package/dist/index.d.ts +3 -159
- package/dist/index.js +3364 -17427
- package/dist/{chunk-4RGXV4SJ.js → network.cjs} +0 -2
- package/dist/network.js +97 -28
- package/dist/{chunk-3FRYJPHG.js → number.cjs} +0 -2
- package/dist/number.js +77 -56
- package/dist/{chunk-27UDDVLZ.js → object.cjs} +0 -2
- package/dist/object.js +237 -80
- package/dist/{chunk-JQZBPAPO.js → performance.cjs} +0 -2
- package/dist/performance.js +145 -40
- package/dist/services.cjs +291 -0
- package/dist/services.d.mts +161 -0
- package/dist/services.d.ts +161 -0
- package/dist/services.js +281 -0
- package/dist/{chunk-WZDOPUJW.js → storage.cjs} +216 -17
- package/dist/storage.js +550 -31
- package/dist/{chunk-D7CS5EKF.js → string.cjs} +0 -2
- package/dist/string.js +91 -68
- package/dist/{chunk-56W6YECK.js → tracking.cjs} +0 -2
- package/dist/tracking.js +359 -52
- package/dist/{chunk-ZDMFMUDR.js → transform.cjs} +0 -2
- package/dist/transform.js +299 -32
- package/dist/{chunk-NJARVI6X.mjs → upload.cjs} +41 -14
- package/dist/upload.js +402 -20
- package/dist/{chunk-KGFTD255.js → url.cjs} +0 -2
- package/dist/url.js +91 -44
- package/dist/{chunk-TQN37HIN.js → validation.cjs} +0 -2
- package/dist/validation.js +77 -60
- package/package.json +7 -2
- package/dist/algorithm.js.map +0 -1
- package/dist/algorithm.mjs +0 -4
- package/dist/algorithm.mjs.map +0 -1
- package/dist/array.js.map +0 -1
- package/dist/array.mjs +0 -4
- package/dist/array.mjs.map +0 -1
- package/dist/chunk-27UDDVLZ.js.map +0 -1
- package/dist/chunk-2R2QWFJC.mjs +0 -138
- package/dist/chunk-2R2QWFJC.mjs.map +0 -1
- package/dist/chunk-3FRYJPHG.js.map +0 -1
- package/dist/chunk-4RGXV4SJ.js.map +0 -1
- package/dist/chunk-56W6YECK.js.map +0 -1
- package/dist/chunk-5BGSUGTI.mjs +0 -128
- package/dist/chunk-5BGSUGTI.mjs.map +0 -1
- package/dist/chunk-7E6GELHJ.mjs +0 -302
- package/dist/chunk-7E6GELHJ.mjs.map +0 -1
- package/dist/chunk-7V5UQXIO.js.map +0 -1
- package/dist/chunk-A4SWQXX7.mjs +0 -484
- package/dist/chunk-A4SWQXX7.mjs.map +0 -1
- package/dist/chunk-BHCRFURU.js.map +0 -1
- package/dist/chunk-CDSGEAOK.mjs +0 -80
- package/dist/chunk-CDSGEAOK.mjs.map +0 -1
- package/dist/chunk-D7CS5EKF.js.map +0 -1
- package/dist/chunk-DYBSRI7V.js.map +0 -1
- package/dist/chunk-FEBKPX5A.js +0 -386
- package/dist/chunk-FEBKPX5A.js.map +0 -1
- package/dist/chunk-FJ6ZGZIA.mjs +0 -39
- package/dist/chunk-FJ6ZGZIA.mjs.map +0 -1
- package/dist/chunk-HLDFI7R2.mjs +0 -175
- package/dist/chunk-HLDFI7R2.mjs.map +0 -1
- package/dist/chunk-I3L42475.js.map +0 -1
- package/dist/chunk-JBLX27WD.mjs +0 -240
- package/dist/chunk-JBLX27WD.mjs.map +0 -1
- package/dist/chunk-JHZ7M2MR.mjs +0 -133
- package/dist/chunk-JHZ7M2MR.mjs.map +0 -1
- package/dist/chunk-JK2SE3I2.js.map +0 -1
- package/dist/chunk-JQZBPAPO.js.map +0 -1
- package/dist/chunk-JXYGC2C5.mjs +0 -100
- package/dist/chunk-JXYGC2C5.mjs.map +0 -1
- package/dist/chunk-KGFTD255.js.map +0 -1
- package/dist/chunk-LBHBNPNJ.mjs +0 -148
- package/dist/chunk-LBHBNPNJ.mjs.map +0 -1
- package/dist/chunk-LF4CILQS.mjs +0 -87
- package/dist/chunk-LF4CILQS.mjs.map +0 -1
- package/dist/chunk-LOAZSPGQ.js.map +0 -1
- package/dist/chunk-NJARVI6X.mjs.map +0 -1
- package/dist/chunk-NSSDYX2U.mjs +0 -80
- package/dist/chunk-NSSDYX2U.mjs.map +0 -1
- package/dist/chunk-O3O67R4I.js.map +0 -1
- package/dist/chunk-OIXQ3E6W.mjs +0 -354
- package/dist/chunk-OIXQ3E6W.mjs.map +0 -1
- package/dist/chunk-OX5PLOWB.js.map +0 -1
- package/dist/chunk-PJ7UCTX4.mjs +0 -362
- package/dist/chunk-PJ7UCTX4.mjs.map +0 -1
- package/dist/chunk-PR4QN5HX.js +0 -44
- package/dist/chunk-PR4QN5HX.js.map +0 -1
- package/dist/chunk-QIBE7GVN.mjs +0 -81
- package/dist/chunk-QIBE7GVN.mjs.map +0 -1
- package/dist/chunk-QIOC54LQ.mjs +0 -130
- package/dist/chunk-QIOC54LQ.mjs.map +0 -1
- package/dist/chunk-TQN37HIN.js.map +0 -1
- package/dist/chunk-WZDOPUJW.js.map +0 -1
- package/dist/chunk-XJTZDXSR.mjs +0 -94
- package/dist/chunk-XJTZDXSR.mjs.map +0 -1
- package/dist/chunk-Y364QIQH.js.map +0 -1
- package/dist/chunk-YXM6Q4JS.mjs +0 -94
- package/dist/chunk-YXM6Q4JS.mjs.map +0 -1
- package/dist/chunk-ZDMFMUDR.js.map +0 -1
- package/dist/chunk-ZVJ6NQUM.mjs +0 -82
- package/dist/chunk-ZVJ6NQUM.mjs.map +0 -1
- package/dist/color.js.map +0 -1
- package/dist/color.mjs +0 -4
- package/dist/color.mjs.map +0 -1
- package/dist/crypto.js.map +0 -1
- package/dist/crypto.mjs +0 -4
- package/dist/crypto.mjs.map +0 -1
- package/dist/data-structure.js.map +0 -1
- package/dist/data-structure.mjs +0 -4
- package/dist/data-structure.mjs.map +0 -1
- package/dist/date.js.map +0 -1
- package/dist/date.mjs +0 -4
- package/dist/date.mjs.map +0 -1
- package/dist/dom.js.map +0 -1
- package/dist/dom.mjs +0 -4
- package/dist/dom.mjs.map +0 -1
- package/dist/file.js.map +0 -1
- package/dist/file.mjs +0 -4
- package/dist/file.mjs.map +0 -1
- package/dist/i18n.js.map +0 -1
- package/dist/i18n.mjs +0 -4
- package/dist/i18n.mjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -17155
- package/dist/index.mjs.map +0 -1
- package/dist/network.js.map +0 -1
- package/dist/network.mjs +0 -4
- package/dist/network.mjs.map +0 -1
- package/dist/number.js.map +0 -1
- package/dist/number.mjs +0 -4
- package/dist/number.mjs.map +0 -1
- package/dist/object.js.map +0 -1
- package/dist/object.mjs +0 -4
- package/dist/object.mjs.map +0 -1
- package/dist/performance.js.map +0 -1
- package/dist/performance.mjs +0 -4
- package/dist/performance.mjs.map +0 -1
- package/dist/storage.js.map +0 -1
- package/dist/storage.mjs +0 -5
- package/dist/storage.mjs.map +0 -1
- package/dist/string.js.map +0 -1
- package/dist/string.mjs +0 -4
- package/dist/string.mjs.map +0 -1
- package/dist/tracking.js.map +0 -1
- package/dist/tracking.mjs +0 -4
- package/dist/tracking.mjs.map +0 -1
- package/dist/transform.js.map +0 -1
- package/dist/transform.mjs +0 -4
- package/dist/transform.mjs.map +0 -1
- package/dist/upload.js.map +0 -1
- package/dist/upload.mjs +0 -5
- package/dist/upload.mjs.map +0 -1
- package/dist/url.js.map +0 -1
- package/dist/url.mjs +0 -4
- package/dist/url.mjs.map +0 -1
- package/dist/validation.js.map +0 -1
- package/dist/validation.mjs +0 -4
- package/dist/validation.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/data/algorithm.ts"],"names":[],"mappings":"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","file":"chunk-JHZ7M2MR.mjs","sourcesContent":["/**\n * 算法工具函数\n */\n\n/**\n * 二分查找\n * @param array - 已排序的数组\n * @param target - 目标值\n * @param compareFn - 比较函数(可选)\n * @returns 目标值的索引,如果未找到返回 -1\n */\nexport function binarySearch<T>(array: T[], target: T, compareFn?: (a: T, b: T) => number): number {\n let left = 0;\n let right = array.length - 1;\n\n const compare = compareFn || ((a: T, b: T) => (a < b ? -1 : a > b ? 1 : 0));\n\n while (left <= right) {\n const mid = Math.floor((left + right) / 2);\n const comparison = compare(array[mid], target);\n\n if (comparison === 0) {\n return mid;\n } else if (comparison < 0) {\n left = mid + 1;\n } else {\n right = mid - 1;\n }\n }\n\n return -1;\n}\n\n/**\n * 快速排序\n * @param array - 要排序的数组\n * @param compareFn - 比较函数(可选)\n * @returns 排序后的新数组\n */\nexport function quickSort<T>(array: T[], compareFn?: (a: T, b: T) => number): T[] {\n if (array.length <= 1) {\n return [...array];\n }\n\n const compare = compareFn || ((a: T, b: T) => (a < b ? -1 : a > b ? 1 : 0));\n const pivot = array[Math.floor(array.length / 2)];\n const left: T[] = [];\n const right: T[] = [];\n const equal: T[] = [];\n\n for (const item of array) {\n const comparison = compare(item, pivot);\n if (comparison < 0) {\n left.push(item);\n } else if (comparison > 0) {\n right.push(item);\n } else {\n equal.push(item);\n }\n }\n\n return [...quickSort(left, compareFn), ...equal, ...quickSort(right, compareFn)];\n}\n\n/**\n * 归并排序\n * @param array - 要排序的数组\n * @param compareFn - 比较函数(可选)\n * @returns 排序后的新数组\n */\nexport function mergeSort<T>(array: T[], compareFn?: (a: T, b: T) => number): T[] {\n if (array.length <= 1) {\n return [...array];\n }\n\n const compare = compareFn || ((a: T, b: T) => (a < b ? -1 : a > b ? 1 : 0));\n const mid = Math.floor(array.length / 2);\n const left = mergeSort(array.slice(0, mid), compareFn);\n const right = mergeSort(array.slice(mid), compareFn);\n\n return merge(left, right, compare);\n}\n\n/**\n * 合并两个已排序的数组\n */\nfunction merge<T>(left: T[], right: T[], compareFn: (a: T, b: T) => number): T[] {\n const result: T[] = [];\n let i = 0;\n let j = 0;\n\n while (i < left.length && j < right.length) {\n if (compareFn(left[i], right[j]) <= 0) {\n result.push(left[i]);\n i++;\n } else {\n result.push(right[j]);\n j++;\n }\n }\n\n return result.concat(left.slice(i)).concat(right.slice(j));\n}\n\n/**\n * 冒泡排序\n * @param array - 要排序的数组\n * @param compareFn - 比较函数(可选)\n * @returns 排序后的新数组\n */\nexport function bubbleSort<T>(array: T[], compareFn?: (a: T, b: T) => number): T[] {\n const result = [...array];\n const compare = compareFn || ((a: T, b: T) => (a < b ? -1 : a > b ? 1 : 0));\n const n = result.length;\n\n for (let i = 0; i < n - 1; i++) {\n let swapped = false;\n\n for (let j = 0; j < n - i - 1; j++) {\n if (compare(result[j], result[j + 1]) > 0) {\n [result[j], result[j + 1]] = [result[j + 1], result[j]];\n swapped = true;\n }\n }\n\n // 如果没有交换,说明已经排序完成\n if (!swapped) {\n break;\n }\n }\n\n return result;\n}\n\n/**\n * 计算斐波那契数列的第n项\n * @param n - 位置(从0开始)\n * @returns 斐波那契数\n */\nexport function fibonacci(n: number): number {\n if (n < 0) {\n throw new Error('n must be non-negative');\n }\n\n if (n === 0) return 0;\n if (n === 1) return 1;\n\n // 使用动态规划优化\n let a = 0;\n let b = 1;\n\n for (let i = 2; i <= n; i++) {\n [a, b] = [b, a + b];\n }\n\n return b;\n}\n\n/**\n * 计算斐波那契数列(返回前n项)\n * @param n - 项数\n * @returns 斐波那契数列数组\n */\nexport function fibonacciSequence(n: number): number[] {\n if (n <= 0) return [];\n if (n === 1) return [0];\n if (n === 2) return [0, 1];\n\n const sequence = [0, 1];\n for (let i = 2; i < n; i++) {\n sequence.push(sequence[i - 1] + sequence[i - 2]);\n }\n\n return sequence;\n}\n\n/**\n * 计算阶乘\n * @param n - 非负整数\n * @returns 阶乘结果\n */\nexport function factorial(n: number): number {\n if (n < 0) {\n throw new Error('n must be non-negative');\n }\n\n if (n === 0 || n === 1) {\n return 1;\n }\n\n let result = 1;\n for (let i = 2; i <= n; i++) {\n result *= i;\n }\n\n return result;\n}\n\n/**\n * 计算最大公约数(GCD)\n * @param a - 第一个数\n * @param b - 第二个数\n * @returns 最大公约数\n */\nexport function gcd(a: number, b: number): number {\n a = Math.abs(a);\n b = Math.abs(b);\n\n while (b !== 0) {\n [a, b] = [b, a % b];\n }\n\n return a;\n}\n\n/**\n * 计算最小公倍数(LCM)\n * @param a - 第一个数\n * @param b - 第二个数\n * @returns 最小公倍数\n */\nexport function lcm(a: number, b: number): number {\n return Math.abs(a * b) / gcd(a, b);\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/browser/dom.ts"],"names":[],"mappings":"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","file":"chunk-JK2SE3I2.js","sourcesContent":["/**\n * DOM工具函数\n */\n\n/**\n * 选择器封装\n * @param selector - CSS选择器\n * @param context - 上下文元素,默认为 document\n * @returns 匹配的元素或元素数组\n */\nexport function $<T extends Element = Element>(\n selector: string,\n context: Document | Element = document\n): T | null {\n return context.querySelector<T>(selector);\n}\n\n/**\n * 选择器封装(返回所有匹配元素)\n * @param selector - CSS选择器\n * @param context - 上下文元素,默认为 document\n * @returns 匹配的元素数组\n */\nexport function $$<T extends Element = Element>(\n selector: string,\n context: Document | Element = document\n): T[] {\n return Array.from(context.querySelectorAll<T>(selector));\n}\n\n/**\n * 添加类名\n * @param element - DOM元素\n * @param className - 类名\n */\nexport function addClass(element: Element, className: string): void {\n element.classList.add(className);\n}\n\n/**\n * 移除类名\n * @param element - DOM元素\n * @param className - 类名\n */\nexport function removeClass(element: Element, className: string): void {\n element.classList.remove(className);\n}\n\n/**\n * 切换类名\n * @param element - DOM元素\n * @param className - 类名\n * @returns 是否包含该类名\n */\nexport function toggleClass(element: Element, className: string): boolean {\n return element.classList.toggle(className);\n}\n\n/**\n * 获取样式\n * @param element - DOM元素\n * @param property - CSS属性名\n * @returns 样式值\n */\nexport function getStyle(element: HTMLElement, property: string): string {\n return window.getComputedStyle(element).getPropertyValue(property);\n}\n\n/**\n * 设置样式\n * @param element - DOM元素\n * @param property - CSS属性名或样式对象\n * @param value - 样式值(当property为字符串时)\n */\nexport function setStyle(\n element: HTMLElement,\n property: string | Record<string, string>,\n value?: string\n): void {\n if (typeof property === 'string' && value !== undefined) {\n element.style.setProperty(property, value);\n } else if (typeof property === 'object') {\n Object.keys(property).forEach(key => {\n element.style.setProperty(key, property[key]);\n });\n }\n}\n\n/**\n * 平滑滚动\n * @param target - 目标位置(元素、选择器或数字)\n * @param options - 滚动选项\n */\nexport function scrollTo(\n target: Element | string | number,\n options: {\n behavior?: ScrollBehavior;\n block?: ScrollLogicalPosition;\n inline?: ScrollLogicalPosition;\n } = {}\n): void {\n if (typeof window === 'undefined') return;\n\n const { behavior = 'smooth', block = 'start', inline = 'nearest' } = options;\n\n if (typeof target === 'number') {\n window.scrollTo({ top: target, behavior });\n return;\n }\n\n const element = typeof target === 'string' ? $(target) : target;\n if (element) {\n element.scrollIntoView({ behavior, block, inline });\n }\n}\n\n/**\n * 获取滚动位置\n * @returns 滚动位置对象\n */\nexport function getScrollPosition(): { x: number; y: number } {\n if (typeof window === 'undefined') return { x: 0, y: 0 };\n return {\n x: window.pageXOffset || document.documentElement.scrollLeft || 0,\n y: window.pageYOffset || document.documentElement.scrollTop || 0,\n };\n}\n\n/**\n * 判断元素是否在视口内\n * @param element - DOM元素\n * @param threshold - 阈值(0-1),默认为 0\n * @returns 是否在视口内\n */\nexport function isInViewport(element: Element, threshold = 0): boolean {\n if (typeof window === 'undefined') return false;\n\n const rect = element.getBoundingClientRect();\n const windowHeight = window.innerHeight || document.documentElement.clientHeight;\n const windowWidth = window.innerWidth || document.documentElement.clientWidth;\n\n return (\n rect.top >= -threshold * rect.height &&\n rect.left >= -threshold * rect.width &&\n rect.bottom <= windowHeight + threshold * rect.height &&\n rect.right <= windowWidth + threshold * rect.width\n );\n}\n\n/**\n * 获取元素偏移量\n * @param element - DOM元素\n * @returns 偏移量对象\n */\nexport function getElementOffset(element: Element): { top: number; left: number } {\n const rect = element.getBoundingClientRect();\n return {\n top: rect.top + (window.pageYOffset || document.documentElement.scrollTop),\n left: rect.left + (window.pageXOffset || document.documentElement.scrollLeft),\n };\n}\n\n/**\n * 复制到剪贴板\n * @param text - 要复制的文本\n * @returns Promise<void>\n */\nexport async function copyToClipboard(text: string): Promise<void> {\n if (typeof navigator === 'undefined' || !navigator.clipboard) {\n // 降级方案\n const textArea = document.createElement('textarea');\n textArea.value = text;\n textArea.style.position = 'fixed';\n textArea.style.opacity = '0';\n document.body.appendChild(textArea);\n textArea.select();\n try {\n document.execCommand('copy');\n } catch (error) {\n throw new Error('Failed to copy text');\n }\n document.body.removeChild(textArea);\n return;\n }\n\n try {\n await navigator.clipboard.writeText(text);\n } catch (error) {\n throw new Error('Failed to copy text');\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/helper/performance.ts"],"names":["timeout","batch"],"mappings":"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","file":"chunk-JQZBPAPO.js","sourcesContent":["/**\n * 性能工具函数\n */\n\n/**\n * 防抖函数\n * @param fn - 要防抖的函数\n * @param delay - 延迟时间(毫秒)\n * @returns 防抖后的函数\n */\nexport function debounce<T extends (...args: unknown[]) => unknown>(\n fn: T,\n delay: number\n): (...args: Parameters<T>) => void {\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n return function (this: unknown, ...args: Parameters<T>) {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n timeoutId = setTimeout(() => {\n fn.apply(this, args);\n timeoutId = null;\n }, delay);\n };\n}\n\n/**\n * 节流函数\n * @param fn - 要节流的函数\n * @param delay - 延迟时间(毫秒)\n * @returns 节流后的函数\n */\nexport function throttle<T extends (...args: unknown[]) => unknown>(\n fn: T,\n delay: number\n): (...args: Parameters<T>) => void {\n let lastCall = 0;\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n return function (this: unknown, ...args: Parameters<T>) {\n const now = Date.now();\n const timeSinceLastCall = now - lastCall;\n\n if (timeSinceLastCall >= delay) {\n lastCall = now;\n fn.apply(this, args);\n } else {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n timeoutId = setTimeout(() => {\n lastCall = Date.now();\n fn.apply(this, args);\n timeoutId = null;\n }, delay - timeSinceLastCall);\n }\n };\n}\n\n/**\n * 函数记忆化\n * @param fn - 要记忆化的函数\n * @param keyFn - 缓存键生成函数,可选\n * @returns 记忆化后的函数\n */\nexport function memoize<T extends (...args: unknown[]) => unknown>(\n fn: T,\n keyFn?: (...args: Parameters<T>) => string\n): T {\n const cache = new Map<string, ReturnType<T>>();\n\n return ((...args: Parameters<T>): ReturnType<T> => {\n const key = keyFn ? keyFn(...args) : JSON.stringify(args);\n if (cache.has(key)) {\n return cache.get(key)!;\n }\n const result = fn(...args) as ReturnType<T>;\n cache.set(key, result);\n return result;\n }) as T;\n}\n\n/**\n * 只执行一次的函数\n * @param fn - 要执行的函数\n * @returns 包装后的函数\n */\nexport function once<T extends (...args: unknown[]) => unknown>(fn: T): T {\n let called = false;\n let result: ReturnType<T>;\n\n return ((...args: Parameters<T>): ReturnType<T> => {\n if (!called) {\n called = true;\n result = fn(...args) as ReturnType<T>;\n }\n return result;\n }) as T;\n}\n\n/**\n * 重试机制\n * @param fn - 要重试的函数\n * @param retryCount - 重试次数,默认为 3\n * @param retryDelay - 重试延迟(毫秒),默认为 1000\n * @returns Promise<T>\n */\nexport async function retry<T>(\n fn: () => Promise<T>,\n retryCount = 3,\n retryDelay = 1000\n): Promise<T> {\n let lastError: Error | null = null;\n\n for (let i = 0; i <= retryCount; i++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n if (i < retryCount) {\n await new Promise(resolve => setTimeout(resolve, retryDelay));\n }\n }\n }\n\n throw lastError || new Error('Retry failed');\n}\n\n/**\n * 超时控制\n * @param fn - 要执行的函数\n * @param timeout - 超时时间(毫秒)\n * @returns Promise<T>\n */\nexport async function timeout<T>(fn: () => Promise<T>, timeout: number): Promise<T> {\n return Promise.race([\n fn(),\n new Promise<T>((_, reject) => {\n setTimeout(() => reject(new Error(`Operation timeout after ${timeout}ms`)), timeout);\n }),\n ]);\n}\n\n/**\n * 批量处理\n * @param items - 要处理的项数组\n * @param fn - 处理函数\n * @param batchSize - 每批大小,默认为 10\n * @returns Promise<T[]>\n */\nexport async function batch<T, R>(\n items: T[],\n fn: (item: T) => Promise<R>,\n batchSize = 10\n): Promise<R[]> {\n const results: R[] = [];\n\n for (let i = 0; i < items.length; i += batchSize) {\n const batch = items.slice(i, i + batchSize);\n const batchResults = await Promise.all(batch.map(fn));\n results.push(...batchResults);\n }\n\n return results;\n}\n\n/**\n * 队列处理\n */\nexport class Queue<T> {\n private items: T[] = [];\n private processing = false;\n private processor?: (item: T) => Promise<void>;\n\n /**\n * 添加项到队列\n * @param item - 要添加的项\n */\n enqueue(item: T): void {\n this.items.push(item);\n if (!this.processing && this.processor) {\n this.processItems();\n }\n }\n\n /**\n * 设置处理函数并开始处理\n * @param processor - 处理函数\n */\n async start(processor: (item: T) => Promise<void>): Promise<void> {\n this.processor = processor;\n if (!this.processing) {\n await this.processItems();\n }\n }\n\n /**\n * 处理队列\n */\n private async processItems(): Promise<void> {\n if (!this.processor || this.processing) return;\n\n this.processing = true;\n\n while (this.items.length > 0) {\n const item = this.items.shift();\n if (item && this.processor) {\n try {\n await this.processor(item);\n } catch (error) {\n console.error('Queue processing error:', error);\n }\n }\n }\n\n this.processing = false;\n }\n\n /**\n * 清空队列\n */\n clear(): void {\n this.items = [];\n }\n\n /**\n * 获取队列长度\n */\n get length(): number {\n return this.items.length;\n }\n}\n"]}
|
package/dist/chunk-JXYGC2C5.mjs
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
// src/browser/network.ts
|
|
2
|
-
async function fetchWithRetry(url, options = {}, retryCount = 3, retryDelay = 1e3) {
|
|
3
|
-
let lastError = null;
|
|
4
|
-
for (let i = 0; i <= retryCount; i++) {
|
|
5
|
-
try {
|
|
6
|
-
const response = await fetch(url, options);
|
|
7
|
-
if (response.ok) {
|
|
8
|
-
return response;
|
|
9
|
-
}
|
|
10
|
-
if (i < retryCount) {
|
|
11
|
-
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
12
|
-
continue;
|
|
13
|
-
}
|
|
14
|
-
return response;
|
|
15
|
-
} catch (error) {
|
|
16
|
-
lastError = error instanceof Error ? error : new Error(String(error));
|
|
17
|
-
if (i < retryCount) {
|
|
18
|
-
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
throw lastError || new Error("Fetch failed after retries");
|
|
23
|
-
}
|
|
24
|
-
async function fetchWithTimeout(url, options = {}, timeout = 5e3) {
|
|
25
|
-
const controller = new AbortController();
|
|
26
|
-
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
27
|
-
try {
|
|
28
|
-
const response = await fetch(url, {
|
|
29
|
-
...options,
|
|
30
|
-
signal: controller.signal
|
|
31
|
-
});
|
|
32
|
-
clearTimeout(timeoutId);
|
|
33
|
-
return response;
|
|
34
|
-
} catch (error) {
|
|
35
|
-
clearTimeout(timeoutId);
|
|
36
|
-
if (error instanceof Error && error.name === "AbortError") {
|
|
37
|
-
throw new Error(`Request timeout after ${timeout}ms`);
|
|
38
|
-
}
|
|
39
|
-
throw error;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
async function downloadFile(url, filename) {
|
|
43
|
-
if (typeof window === "undefined") {
|
|
44
|
-
throw new Error("downloadFile is only available in browser environment");
|
|
45
|
-
}
|
|
46
|
-
try {
|
|
47
|
-
const response = await fetch(url);
|
|
48
|
-
if (!response.ok) {
|
|
49
|
-
throw new Error(`Failed to download file: ${response.statusText}`);
|
|
50
|
-
}
|
|
51
|
-
const blob = await response.blob();
|
|
52
|
-
const downloadUrl = window.URL.createObjectURL(blob);
|
|
53
|
-
const link = document.createElement("a");
|
|
54
|
-
link.href = downloadUrl;
|
|
55
|
-
link.download = filename || url.split("/").pop() || "download";
|
|
56
|
-
document.body.appendChild(link);
|
|
57
|
-
link.click();
|
|
58
|
-
document.body.removeChild(link);
|
|
59
|
-
window.URL.revokeObjectURL(downloadUrl);
|
|
60
|
-
} catch (error) {
|
|
61
|
-
throw error instanceof Error ? error : new Error(String(error));
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
function checkOnline() {
|
|
65
|
-
if (typeof navigator === "undefined") return true;
|
|
66
|
-
return navigator.onLine;
|
|
67
|
-
}
|
|
68
|
-
async function request(url, options = {}) {
|
|
69
|
-
const { method = "GET", headers = {}, body, timeout, retry = 0 } = options;
|
|
70
|
-
const fetchOptions = {
|
|
71
|
-
method,
|
|
72
|
-
headers: {
|
|
73
|
-
"Content-Type": "application/json",
|
|
74
|
-
...headers
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
if (body) {
|
|
78
|
-
fetchOptions.body = typeof body === "string" ? body : JSON.stringify(body);
|
|
79
|
-
}
|
|
80
|
-
let fetchFn = fetch;
|
|
81
|
-
if (timeout) {
|
|
82
|
-
fetchFn = (url2, opts) => fetchWithTimeout(url2, opts, timeout);
|
|
83
|
-
}
|
|
84
|
-
if (retry > 0) {
|
|
85
|
-
fetchFn = (url2, opts) => fetchWithRetry(url2, opts, retry);
|
|
86
|
-
}
|
|
87
|
-
const response = await fetchFn(url, fetchOptions);
|
|
88
|
-
if (!response.ok) {
|
|
89
|
-
throw new Error(`HTTP error! status: ${response.status}`);
|
|
90
|
-
}
|
|
91
|
-
const contentType = response.headers.get("content-type");
|
|
92
|
-
if (contentType && contentType.includes("application/json")) {
|
|
93
|
-
return response.json();
|
|
94
|
-
}
|
|
95
|
-
return response.text();
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export { checkOnline, downloadFile, fetchWithRetry, fetchWithTimeout, request };
|
|
99
|
-
//# sourceMappingURL=chunk-JXYGC2C5.mjs.map
|
|
100
|
-
//# sourceMappingURL=chunk-JXYGC2C5.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/browser/network.ts"],"names":["url"],"mappings":"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","file":"chunk-JXYGC2C5.mjs","sourcesContent":["/**\n * 网络工具函数\n */\n\n/**\n * 带重试的fetch\n * @param url - 请求URL\n * @param options - fetch选项\n * @param retryCount - 重试次数,默认为 3\n * @param retryDelay - 重试延迟(毫秒),默认为 1000\n * @returns Promise<Response>\n */\nexport async function fetchWithRetry(\n url: string,\n options: RequestInit = {},\n retryCount = 3,\n retryDelay = 1000\n): Promise<Response> {\n let lastError: Error | null = null;\n\n for (let i = 0; i <= retryCount; i++) {\n try {\n const response = await fetch(url, options);\n if (response.ok) {\n return response;\n }\n // 如果不是最后一次尝试,继续重试\n if (i < retryCount) {\n await new Promise(resolve => setTimeout(resolve, retryDelay));\n continue;\n }\n return response;\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n if (i < retryCount) {\n await new Promise(resolve => setTimeout(resolve, retryDelay));\n }\n }\n }\n\n throw lastError || new Error('Fetch failed after retries');\n}\n\n/**\n * 带超时的fetch\n * @param url - 请求URL\n * @param options - fetch选项\n * @param timeout - 超时时间(毫秒),默认为 5000\n * @returns Promise<Response>\n */\nexport async function fetchWithTimeout(\n url: string,\n options: RequestInit = {},\n timeout = 5000\n): Promise<Response> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(url, {\n ...options,\n signal: controller.signal,\n });\n clearTimeout(timeoutId);\n return response;\n } catch (error) {\n clearTimeout(timeoutId);\n if (error instanceof Error && error.name === 'AbortError') {\n throw new Error(`Request timeout after ${timeout}ms`);\n }\n throw error;\n }\n}\n\n/**\n * 文件下载\n * @param url - 文件URL\n * @param filename - 文件名,可选\n * @returns Promise<void>\n */\nexport async function downloadFile(url: string, filename?: string): Promise<void> {\n if (typeof window === 'undefined') {\n throw new Error('downloadFile is only available in browser environment');\n }\n\n try {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to download file: ${response.statusText}`);\n }\n\n const blob = await response.blob();\n const downloadUrl = window.URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = downloadUrl;\n link.download = filename || url.split('/').pop() || 'download';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n window.URL.revokeObjectURL(downloadUrl);\n } catch (error) {\n throw error instanceof Error ? error : new Error(String(error));\n }\n}\n\n/**\n * 检查网络状态\n * @returns 是否在线\n */\nexport function checkOnline(): boolean {\n if (typeof navigator === 'undefined') return true;\n return navigator.onLine;\n}\n\n/**\n * 统一的HTTP请求封装\n * @param url - 请求URL\n * @param options - 请求选项\n * @returns Promise<T>\n */\nexport async function request<T = unknown>(\n url: string,\n options: {\n method?: string;\n headers?: Record<string, string>;\n body?: unknown;\n timeout?: number;\n retry?: number;\n } = {}\n): Promise<T> {\n const { method = 'GET', headers = {}, body, timeout, retry = 0 } = options;\n\n const fetchOptions: RequestInit = {\n method,\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n };\n\n if (body) {\n fetchOptions.body = typeof body === 'string' ? body : JSON.stringify(body);\n }\n\n let fetchFn: (url: string, options: RequestInit) => Promise<Response> = fetch;\n\n if (timeout) {\n fetchFn = (url, opts) => fetchWithTimeout(url, opts, timeout);\n }\n\n if (retry > 0) {\n fetchFn = (url, opts) => fetchWithRetry(url, opts, retry);\n }\n\n const response = await fetchFn(url, fetchOptions);\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const contentType = response.headers.get('content-type');\n if (contentType && contentType.includes('application/json')) {\n return response.json() as Promise<T>;\n }\n\n return response.text() as Promise<T>;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/format/url.ts"],"names":[],"mappings":"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","file":"chunk-KGFTD255.js","sourcesContent":["/**\n * URL工具函数\n */\n\n/**\n * URL解析结果\n */\nexport interface ParsedUrl {\n protocol: string;\n host: string;\n hostname: string;\n port: string;\n pathname: string;\n search: string;\n hash: string;\n origin: string;\n}\n\n/**\n * URL解析\n * @param url - URL字符串\n * @returns 解析后的URL对象\n */\nexport function parseUrl(url: string): ParsedUrl {\n try {\n const urlObj = new URL(url);\n return {\n protocol: urlObj.protocol,\n host: urlObj.host,\n hostname: urlObj.hostname,\n port: urlObj.port,\n pathname: urlObj.pathname,\n search: urlObj.search,\n hash: urlObj.hash,\n origin: urlObj.origin,\n };\n } catch {\n throw new Error(`Invalid URL: ${url}`);\n }\n}\n\n/**\n * URL构建\n * @param parts - URL组成部分\n * @returns 构建后的URL字符串\n */\nexport function buildUrl(parts: {\n protocol?: string;\n host?: string;\n pathname?: string;\n search?: string;\n hash?: string;\n}): string {\n const { protocol = 'https:', host = '', pathname = '/', search = '', hash = '' } = parts;\n return `${protocol}//${host}${pathname}${search}${hash}`;\n}\n\n/**\n * 获取查询参数\n * @param url - URL字符串,默认为当前页面URL\n * @returns 查询参数对象\n */\nexport function getQueryParams(url?: string): Record<string, string> {\n const searchParams = url\n ? new URL(url).searchParams\n : new URLSearchParams(window.location.search);\n const params: Record<string, string> = {};\n searchParams.forEach((value, key) => {\n params[key] = value;\n });\n return params;\n}\n\n/**\n * 设置查询参数\n * @param url - URL字符串\n * @param params - 查询参数对象\n * @returns 设置后的URL字符串\n */\nexport function setQueryParams(\n url: string,\n params: Record<string, string | number | boolean>\n): string {\n try {\n const urlObj = new URL(url);\n Object.keys(params).forEach(key => {\n urlObj.searchParams.set(key, String(params[key]));\n });\n return urlObj.toString();\n } catch {\n throw new Error(`Invalid URL: ${url}`);\n }\n}\n\n/**\n * 移除查询参数\n * @param url - URL字符串\n * @param keys - 要移除的查询参数键数组\n * @returns 移除后的URL字符串\n */\nexport function removeQueryParams(url: string, keys: string[]): string {\n try {\n const urlObj = new URL(url);\n keys.forEach(key => {\n urlObj.searchParams.delete(key);\n });\n return urlObj.toString();\n } catch {\n throw new Error(`Invalid URL: ${url}`);\n }\n}\n\n/**\n * 更新查询参数\n * @param url - URL字符串\n * @param params - 要更新的查询参数对象\n * @returns 更新后的URL字符串\n */\nexport function updateQueryParams(\n url: string,\n params: Record<string, string | number | boolean | null>\n): string {\n try {\n const urlObj = new URL(url);\n Object.keys(params).forEach(key => {\n const value = params[key];\n if (value === null) {\n urlObj.searchParams.delete(key);\n } else {\n urlObj.searchParams.set(key, String(value));\n }\n });\n return urlObj.toString();\n } catch {\n throw new Error(`Invalid URL: ${url}`);\n }\n}\n\n/**\n * 判断是否为绝对URL\n * @param url - URL字符串\n * @returns 是否为绝对URL\n */\nexport function isAbsoluteUrl(url: string): boolean {\n try {\n new URL(url);\n return true;\n } catch {\n return /^https?:\\/\\//i.test(url);\n }\n}\n\n/**\n * URL拼接\n * @param baseUrl - 基础URL\n * @param ...paths - 路径片段\n * @returns 拼接后的URL\n */\nexport function joinUrl(baseUrl: string, ...paths: string[]): string {\n const base = baseUrl.replace(/\\/+$/, '');\n const joinedPaths = paths\n .map(path => path.replace(/^\\/+|\\/+$/g, ''))\n .filter(path => path.length > 0)\n .join('/');\n return `${base}/${joinedPaths}`;\n}\n\n/**\n * URL标准化\n * @param url - URL字符串\n * @returns 标准化后的URL\n */\nexport function normalizeUrl(url: string): string {\n try {\n const urlObj = new URL(url);\n urlObj.pathname = urlObj.pathname.replace(/\\/+/g, '/');\n return urlObj.toString();\n } catch {\n return url;\n }\n}\n"]}
|
package/dist/chunk-LBHBNPNJ.mjs
DELETED
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
// src/helper/performance.ts
|
|
2
|
-
function debounce(fn, delay) {
|
|
3
|
-
let timeoutId = null;
|
|
4
|
-
return function(...args) {
|
|
5
|
-
if (timeoutId) {
|
|
6
|
-
clearTimeout(timeoutId);
|
|
7
|
-
}
|
|
8
|
-
timeoutId = setTimeout(() => {
|
|
9
|
-
fn.apply(this, args);
|
|
10
|
-
timeoutId = null;
|
|
11
|
-
}, delay);
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
function throttle(fn, delay) {
|
|
15
|
-
let lastCall = 0;
|
|
16
|
-
let timeoutId = null;
|
|
17
|
-
return function(...args) {
|
|
18
|
-
const now = Date.now();
|
|
19
|
-
const timeSinceLastCall = now - lastCall;
|
|
20
|
-
if (timeSinceLastCall >= delay) {
|
|
21
|
-
lastCall = now;
|
|
22
|
-
fn.apply(this, args);
|
|
23
|
-
} else {
|
|
24
|
-
if (timeoutId) {
|
|
25
|
-
clearTimeout(timeoutId);
|
|
26
|
-
}
|
|
27
|
-
timeoutId = setTimeout(() => {
|
|
28
|
-
lastCall = Date.now();
|
|
29
|
-
fn.apply(this, args);
|
|
30
|
-
timeoutId = null;
|
|
31
|
-
}, delay - timeSinceLastCall);
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
function memoize(fn, keyFn) {
|
|
36
|
-
const cache = /* @__PURE__ */ new Map();
|
|
37
|
-
return ((...args) => {
|
|
38
|
-
const key = keyFn ? keyFn(...args) : JSON.stringify(args);
|
|
39
|
-
if (cache.has(key)) {
|
|
40
|
-
return cache.get(key);
|
|
41
|
-
}
|
|
42
|
-
const result = fn(...args);
|
|
43
|
-
cache.set(key, result);
|
|
44
|
-
return result;
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
function once(fn) {
|
|
48
|
-
let called = false;
|
|
49
|
-
let result;
|
|
50
|
-
return ((...args) => {
|
|
51
|
-
if (!called) {
|
|
52
|
-
called = true;
|
|
53
|
-
result = fn(...args);
|
|
54
|
-
}
|
|
55
|
-
return result;
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
async function retry(fn, retryCount = 3, retryDelay = 1e3) {
|
|
59
|
-
let lastError = null;
|
|
60
|
-
for (let i = 0; i <= retryCount; i++) {
|
|
61
|
-
try {
|
|
62
|
-
return await fn();
|
|
63
|
-
} catch (error) {
|
|
64
|
-
lastError = error instanceof Error ? error : new Error(String(error));
|
|
65
|
-
if (i < retryCount) {
|
|
66
|
-
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
throw lastError || new Error("Retry failed");
|
|
71
|
-
}
|
|
72
|
-
async function timeout(fn, timeout2) {
|
|
73
|
-
return Promise.race([
|
|
74
|
-
fn(),
|
|
75
|
-
new Promise((_, reject) => {
|
|
76
|
-
setTimeout(() => reject(new Error(`Operation timeout after ${timeout2}ms`)), timeout2);
|
|
77
|
-
})
|
|
78
|
-
]);
|
|
79
|
-
}
|
|
80
|
-
async function batch(items, fn, batchSize = 10) {
|
|
81
|
-
const results = [];
|
|
82
|
-
for (let i = 0; i < items.length; i += batchSize) {
|
|
83
|
-
const batch2 = items.slice(i, i + batchSize);
|
|
84
|
-
const batchResults = await Promise.all(batch2.map(fn));
|
|
85
|
-
results.push(...batchResults);
|
|
86
|
-
}
|
|
87
|
-
return results;
|
|
88
|
-
}
|
|
89
|
-
var Queue = class {
|
|
90
|
-
constructor() {
|
|
91
|
-
this.items = [];
|
|
92
|
-
this.processing = false;
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* 添加项到队列
|
|
96
|
-
* @param item - 要添加的项
|
|
97
|
-
*/
|
|
98
|
-
enqueue(item) {
|
|
99
|
-
this.items.push(item);
|
|
100
|
-
if (!this.processing && this.processor) {
|
|
101
|
-
this.processItems();
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* 设置处理函数并开始处理
|
|
106
|
-
* @param processor - 处理函数
|
|
107
|
-
*/
|
|
108
|
-
async start(processor) {
|
|
109
|
-
this.processor = processor;
|
|
110
|
-
if (!this.processing) {
|
|
111
|
-
await this.processItems();
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* 处理队列
|
|
116
|
-
*/
|
|
117
|
-
async processItems() {
|
|
118
|
-
if (!this.processor || this.processing) return;
|
|
119
|
-
this.processing = true;
|
|
120
|
-
while (this.items.length > 0) {
|
|
121
|
-
const item = this.items.shift();
|
|
122
|
-
if (item && this.processor) {
|
|
123
|
-
try {
|
|
124
|
-
await this.processor(item);
|
|
125
|
-
} catch (error) {
|
|
126
|
-
console.error("Queue processing error:", error);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
this.processing = false;
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* 清空队列
|
|
134
|
-
*/
|
|
135
|
-
clear() {
|
|
136
|
-
this.items = [];
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* 获取队列长度
|
|
140
|
-
*/
|
|
141
|
-
get length() {
|
|
142
|
-
return this.items.length;
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
export { Queue, batch, debounce, memoize, once, retry, throttle, timeout };
|
|
147
|
-
//# sourceMappingURL=chunk-LBHBNPNJ.mjs.map
|
|
148
|
-
//# sourceMappingURL=chunk-LBHBNPNJ.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/helper/performance.ts"],"names":["timeout","batch"],"mappings":"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","file":"chunk-LBHBNPNJ.mjs","sourcesContent":["/**\n * 性能工具函数\n */\n\n/**\n * 防抖函数\n * @param fn - 要防抖的函数\n * @param delay - 延迟时间(毫秒)\n * @returns 防抖后的函数\n */\nexport function debounce<T extends (...args: unknown[]) => unknown>(\n fn: T,\n delay: number\n): (...args: Parameters<T>) => void {\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n return function (this: unknown, ...args: Parameters<T>) {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n timeoutId = setTimeout(() => {\n fn.apply(this, args);\n timeoutId = null;\n }, delay);\n };\n}\n\n/**\n * 节流函数\n * @param fn - 要节流的函数\n * @param delay - 延迟时间(毫秒)\n * @returns 节流后的函数\n */\nexport function throttle<T extends (...args: unknown[]) => unknown>(\n fn: T,\n delay: number\n): (...args: Parameters<T>) => void {\n let lastCall = 0;\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n return function (this: unknown, ...args: Parameters<T>) {\n const now = Date.now();\n const timeSinceLastCall = now - lastCall;\n\n if (timeSinceLastCall >= delay) {\n lastCall = now;\n fn.apply(this, args);\n } else {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n timeoutId = setTimeout(() => {\n lastCall = Date.now();\n fn.apply(this, args);\n timeoutId = null;\n }, delay - timeSinceLastCall);\n }\n };\n}\n\n/**\n * 函数记忆化\n * @param fn - 要记忆化的函数\n * @param keyFn - 缓存键生成函数,可选\n * @returns 记忆化后的函数\n */\nexport function memoize<T extends (...args: unknown[]) => unknown>(\n fn: T,\n keyFn?: (...args: Parameters<T>) => string\n): T {\n const cache = new Map<string, ReturnType<T>>();\n\n return ((...args: Parameters<T>): ReturnType<T> => {\n const key = keyFn ? keyFn(...args) : JSON.stringify(args);\n if (cache.has(key)) {\n return cache.get(key)!;\n }\n const result = fn(...args) as ReturnType<T>;\n cache.set(key, result);\n return result;\n }) as T;\n}\n\n/**\n * 只执行一次的函数\n * @param fn - 要执行的函数\n * @returns 包装后的函数\n */\nexport function once<T extends (...args: unknown[]) => unknown>(fn: T): T {\n let called = false;\n let result: ReturnType<T>;\n\n return ((...args: Parameters<T>): ReturnType<T> => {\n if (!called) {\n called = true;\n result = fn(...args) as ReturnType<T>;\n }\n return result;\n }) as T;\n}\n\n/**\n * 重试机制\n * @param fn - 要重试的函数\n * @param retryCount - 重试次数,默认为 3\n * @param retryDelay - 重试延迟(毫秒),默认为 1000\n * @returns Promise<T>\n */\nexport async function retry<T>(\n fn: () => Promise<T>,\n retryCount = 3,\n retryDelay = 1000\n): Promise<T> {\n let lastError: Error | null = null;\n\n for (let i = 0; i <= retryCount; i++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n if (i < retryCount) {\n await new Promise(resolve => setTimeout(resolve, retryDelay));\n }\n }\n }\n\n throw lastError || new Error('Retry failed');\n}\n\n/**\n * 超时控制\n * @param fn - 要执行的函数\n * @param timeout - 超时时间(毫秒)\n * @returns Promise<T>\n */\nexport async function timeout<T>(fn: () => Promise<T>, timeout: number): Promise<T> {\n return Promise.race([\n fn(),\n new Promise<T>((_, reject) => {\n setTimeout(() => reject(new Error(`Operation timeout after ${timeout}ms`)), timeout);\n }),\n ]);\n}\n\n/**\n * 批量处理\n * @param items - 要处理的项数组\n * @param fn - 处理函数\n * @param batchSize - 每批大小,默认为 10\n * @returns Promise<T[]>\n */\nexport async function batch<T, R>(\n items: T[],\n fn: (item: T) => Promise<R>,\n batchSize = 10\n): Promise<R[]> {\n const results: R[] = [];\n\n for (let i = 0; i < items.length; i += batchSize) {\n const batch = items.slice(i, i + batchSize);\n const batchResults = await Promise.all(batch.map(fn));\n results.push(...batchResults);\n }\n\n return results;\n}\n\n/**\n * 队列处理\n */\nexport class Queue<T> {\n private items: T[] = [];\n private processing = false;\n private processor?: (item: T) => Promise<void>;\n\n /**\n * 添加项到队列\n * @param item - 要添加的项\n */\n enqueue(item: T): void {\n this.items.push(item);\n if (!this.processing && this.processor) {\n this.processItems();\n }\n }\n\n /**\n * 设置处理函数并开始处理\n * @param processor - 处理函数\n */\n async start(processor: (item: T) => Promise<void>): Promise<void> {\n this.processor = processor;\n if (!this.processing) {\n await this.processItems();\n }\n }\n\n /**\n * 处理队列\n */\n private async processItems(): Promise<void> {\n if (!this.processor || this.processing) return;\n\n this.processing = true;\n\n while (this.items.length > 0) {\n const item = this.items.shift();\n if (item && this.processor) {\n try {\n await this.processor(item);\n } catch (error) {\n console.error('Queue processing error:', error);\n }\n }\n }\n\n this.processing = false;\n }\n\n /**\n * 清空队列\n */\n clear(): void {\n this.items = [];\n }\n\n /**\n * 获取队列长度\n */\n get length(): number {\n return this.items.length;\n }\n}\n"]}
|
package/dist/chunk-LF4CILQS.mjs
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
// src/browser/dom.ts
|
|
2
|
-
function $(selector, context = document) {
|
|
3
|
-
return context.querySelector(selector);
|
|
4
|
-
}
|
|
5
|
-
function $$(selector, context = document) {
|
|
6
|
-
return Array.from(context.querySelectorAll(selector));
|
|
7
|
-
}
|
|
8
|
-
function addClass(element, className) {
|
|
9
|
-
element.classList.add(className);
|
|
10
|
-
}
|
|
11
|
-
function removeClass(element, className) {
|
|
12
|
-
element.classList.remove(className);
|
|
13
|
-
}
|
|
14
|
-
function toggleClass(element, className) {
|
|
15
|
-
return element.classList.toggle(className);
|
|
16
|
-
}
|
|
17
|
-
function getStyle(element, property) {
|
|
18
|
-
return window.getComputedStyle(element).getPropertyValue(property);
|
|
19
|
-
}
|
|
20
|
-
function setStyle(element, property, value) {
|
|
21
|
-
if (typeof property === "string" && value !== void 0) {
|
|
22
|
-
element.style.setProperty(property, value);
|
|
23
|
-
} else if (typeof property === "object") {
|
|
24
|
-
Object.keys(property).forEach((key) => {
|
|
25
|
-
element.style.setProperty(key, property[key]);
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
function scrollTo(target, options = {}) {
|
|
30
|
-
if (typeof window === "undefined") return;
|
|
31
|
-
const { behavior = "smooth", block = "start", inline = "nearest" } = options;
|
|
32
|
-
if (typeof target === "number") {
|
|
33
|
-
window.scrollTo({ top: target, behavior });
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
const element = typeof target === "string" ? $(target) : target;
|
|
37
|
-
if (element) {
|
|
38
|
-
element.scrollIntoView({ behavior, block, inline });
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
function getScrollPosition() {
|
|
42
|
-
if (typeof window === "undefined") return { x: 0, y: 0 };
|
|
43
|
-
return {
|
|
44
|
-
x: window.pageXOffset || document.documentElement.scrollLeft || 0,
|
|
45
|
-
y: window.pageYOffset || document.documentElement.scrollTop || 0
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
function isInViewport(element, threshold = 0) {
|
|
49
|
-
if (typeof window === "undefined") return false;
|
|
50
|
-
const rect = element.getBoundingClientRect();
|
|
51
|
-
const windowHeight = window.innerHeight || document.documentElement.clientHeight;
|
|
52
|
-
const windowWidth = window.innerWidth || document.documentElement.clientWidth;
|
|
53
|
-
return rect.top >= -threshold * rect.height && rect.left >= -threshold * rect.width && rect.bottom <= windowHeight + threshold * rect.height && rect.right <= windowWidth + threshold * rect.width;
|
|
54
|
-
}
|
|
55
|
-
function getElementOffset(element) {
|
|
56
|
-
const rect = element.getBoundingClientRect();
|
|
57
|
-
return {
|
|
58
|
-
top: rect.top + (window.pageYOffset || document.documentElement.scrollTop),
|
|
59
|
-
left: rect.left + (window.pageXOffset || document.documentElement.scrollLeft)
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
async function copyToClipboard(text) {
|
|
63
|
-
if (typeof navigator === "undefined" || !navigator.clipboard) {
|
|
64
|
-
const textArea = document.createElement("textarea");
|
|
65
|
-
textArea.value = text;
|
|
66
|
-
textArea.style.position = "fixed";
|
|
67
|
-
textArea.style.opacity = "0";
|
|
68
|
-
document.body.appendChild(textArea);
|
|
69
|
-
textArea.select();
|
|
70
|
-
try {
|
|
71
|
-
document.execCommand("copy");
|
|
72
|
-
} catch (error) {
|
|
73
|
-
throw new Error("Failed to copy text");
|
|
74
|
-
}
|
|
75
|
-
document.body.removeChild(textArea);
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
try {
|
|
79
|
-
await navigator.clipboard.writeText(text);
|
|
80
|
-
} catch (error) {
|
|
81
|
-
throw new Error("Failed to copy text");
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export { $, $$, addClass, copyToClipboard, getElementOffset, getScrollPosition, getStyle, isInViewport, removeClass, scrollTo, setStyle, toggleClass };
|
|
86
|
-
//# sourceMappingURL=chunk-LF4CILQS.mjs.map
|
|
87
|
-
//# sourceMappingURL=chunk-LF4CILQS.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/browser/dom.ts"],"names":[],"mappings":"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","file":"chunk-LF4CILQS.mjs","sourcesContent":["/**\n * DOM工具函数\n */\n\n/**\n * 选择器封装\n * @param selector - CSS选择器\n * @param context - 上下文元素,默认为 document\n * @returns 匹配的元素或元素数组\n */\nexport function $<T extends Element = Element>(\n selector: string,\n context: Document | Element = document\n): T | null {\n return context.querySelector<T>(selector);\n}\n\n/**\n * 选择器封装(返回所有匹配元素)\n * @param selector - CSS选择器\n * @param context - 上下文元素,默认为 document\n * @returns 匹配的元素数组\n */\nexport function $$<T extends Element = Element>(\n selector: string,\n context: Document | Element = document\n): T[] {\n return Array.from(context.querySelectorAll<T>(selector));\n}\n\n/**\n * 添加类名\n * @param element - DOM元素\n * @param className - 类名\n */\nexport function addClass(element: Element, className: string): void {\n element.classList.add(className);\n}\n\n/**\n * 移除类名\n * @param element - DOM元素\n * @param className - 类名\n */\nexport function removeClass(element: Element, className: string): void {\n element.classList.remove(className);\n}\n\n/**\n * 切换类名\n * @param element - DOM元素\n * @param className - 类名\n * @returns 是否包含该类名\n */\nexport function toggleClass(element: Element, className: string): boolean {\n return element.classList.toggle(className);\n}\n\n/**\n * 获取样式\n * @param element - DOM元素\n * @param property - CSS属性名\n * @returns 样式值\n */\nexport function getStyle(element: HTMLElement, property: string): string {\n return window.getComputedStyle(element).getPropertyValue(property);\n}\n\n/**\n * 设置样式\n * @param element - DOM元素\n * @param property - CSS属性名或样式对象\n * @param value - 样式值(当property为字符串时)\n */\nexport function setStyle(\n element: HTMLElement,\n property: string | Record<string, string>,\n value?: string\n): void {\n if (typeof property === 'string' && value !== undefined) {\n element.style.setProperty(property, value);\n } else if (typeof property === 'object') {\n Object.keys(property).forEach(key => {\n element.style.setProperty(key, property[key]);\n });\n }\n}\n\n/**\n * 平滑滚动\n * @param target - 目标位置(元素、选择器或数字)\n * @param options - 滚动选项\n */\nexport function scrollTo(\n target: Element | string | number,\n options: {\n behavior?: ScrollBehavior;\n block?: ScrollLogicalPosition;\n inline?: ScrollLogicalPosition;\n } = {}\n): void {\n if (typeof window === 'undefined') return;\n\n const { behavior = 'smooth', block = 'start', inline = 'nearest' } = options;\n\n if (typeof target === 'number') {\n window.scrollTo({ top: target, behavior });\n return;\n }\n\n const element = typeof target === 'string' ? $(target) : target;\n if (element) {\n element.scrollIntoView({ behavior, block, inline });\n }\n}\n\n/**\n * 获取滚动位置\n * @returns 滚动位置对象\n */\nexport function getScrollPosition(): { x: number; y: number } {\n if (typeof window === 'undefined') return { x: 0, y: 0 };\n return {\n x: window.pageXOffset || document.documentElement.scrollLeft || 0,\n y: window.pageYOffset || document.documentElement.scrollTop || 0,\n };\n}\n\n/**\n * 判断元素是否在视口内\n * @param element - DOM元素\n * @param threshold - 阈值(0-1),默认为 0\n * @returns 是否在视口内\n */\nexport function isInViewport(element: Element, threshold = 0): boolean {\n if (typeof window === 'undefined') return false;\n\n const rect = element.getBoundingClientRect();\n const windowHeight = window.innerHeight || document.documentElement.clientHeight;\n const windowWidth = window.innerWidth || document.documentElement.clientWidth;\n\n return (\n rect.top >= -threshold * rect.height &&\n rect.left >= -threshold * rect.width &&\n rect.bottom <= windowHeight + threshold * rect.height &&\n rect.right <= windowWidth + threshold * rect.width\n );\n}\n\n/**\n * 获取元素偏移量\n * @param element - DOM元素\n * @returns 偏移量对象\n */\nexport function getElementOffset(element: Element): { top: number; left: number } {\n const rect = element.getBoundingClientRect();\n return {\n top: rect.top + (window.pageYOffset || document.documentElement.scrollTop),\n left: rect.left + (window.pageXOffset || document.documentElement.scrollLeft),\n };\n}\n\n/**\n * 复制到剪贴板\n * @param text - 要复制的文本\n * @returns Promise<void>\n */\nexport async function copyToClipboard(text: string): Promise<void> {\n if (typeof navigator === 'undefined' || !navigator.clipboard) {\n // 降级方案\n const textArea = document.createElement('textarea');\n textArea.value = text;\n textArea.style.position = 'fixed';\n textArea.style.opacity = '0';\n document.body.appendChild(textArea);\n textArea.select();\n try {\n document.execCommand('copy');\n } catch (error) {\n throw new Error('Failed to copy text');\n }\n document.body.removeChild(textArea);\n return;\n }\n\n try {\n await navigator.clipboard.writeText(text);\n } catch (error) {\n throw new Error('Failed to copy text');\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/array.ts"],"names":["shuffled"],"mappings":"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","file":"chunk-LOAZSPGQ.js","sourcesContent":["/**\n * 数组工具函数\n */\n\n/**\n * 数组去重\n * @param arr - 输入数组\n * @returns 去重后的数组\n */\nexport function unique<T>(arr: T[]): T[] {\n return Array.from(new Set(arr));\n}\n\n/**\n * 数组分组\n * @param arr - 输入数组\n * @param keyFn - 分组键函数或属性名\n * @returns 分组后的对象\n */\nexport function groupBy<T, K extends string | number>(\n arr: T[],\n keyFn: ((item: T) => K) | string\n): Record<K, T[]> {\n const getKey =\n typeof keyFn === 'string' ? (item: T) => (item as Record<string, K>)[keyFn] as K : keyFn;\n\n return arr.reduce(\n (acc, item) => {\n const key = getKey(item);\n if (!acc[key]) {\n acc[key] = [];\n }\n acc[key].push(item);\n return acc;\n },\n {} as Record<K, T[]>\n );\n}\n\n/**\n * 数组分块\n * @param arr - 输入数组\n * @param size - 每块大小\n * @returns 分块后的二维数组\n */\nexport function chunk<T>(arr: T[], size: number): T[][] {\n const chunks: T[][] = [];\n for (let i = 0; i < arr.length; i += size) {\n chunks.push(arr.slice(i, i + size));\n }\n return chunks;\n}\n\n/**\n * 数组扁平化\n * @param arr - 输入数组\n * @param depth - 扁平化深度,默认为 1\n * @returns 扁平化后的数组\n */\nexport function flatten<T>(arr: (T | T[])[], depth = 1): T[] {\n return depth > 0\n ? arr.reduce<T[]>(\n (acc, val) => acc.concat(Array.isArray(val) ? flatten(val, depth - 1) : val),\n []\n )\n : (arr as T[]);\n}\n\n/**\n * 数组随机打乱(Fisher-Yates算法)\n * @param arr - 输入数组\n * @returns 打乱后的新数组\n */\nexport function shuffle<T>(arr: T[]): T[] {\n const result = [...arr];\n for (let i = result.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [result[i], result[j]] = [result[j], result[i]];\n }\n return result;\n}\n\n/**\n * 随机取样\n * @param arr - 输入数组\n * @param count - 取样数量,默认为 1。当 count=1 时返回单个元素,否则返回数组\n * @returns 随机取样的数组或单个元素\n */\nexport function sample<T>(arr: T[]): T;\nexport function sample<T>(arr: T[], count: number): T | T[];\nexport function sample<T>(arr: T[], count = 1): T | T[] {\n if (arr.length === 0) {\n throw new Error('Cannot sample from empty array');\n }\n\n if (count === 1) {\n const shuffled = shuffle(arr);\n return shuffled[0];\n }\n\n if (count >= arr.length) return [...arr];\n const shuffled = shuffle(arr);\n return shuffled.slice(0, count);\n}\n\n/**\n * 数组差集(在arr1中但不在arr2中的元素)\n * @param arr1 - 第一个数组\n * @param arr2 - 第二个数组\n * @returns 差集数组\n */\nexport function difference<T>(arr1: T[], arr2: T[]): T[] {\n const set2 = new Set(arr2);\n return arr1.filter(item => !set2.has(item));\n}\n\n/**\n * 数组交集\n * @param arr1 - 第一个数组\n * @param arr2 - 第二个数组\n * @returns 交集数组\n */\nexport function intersection<T>(arr1: T[], arr2: T[]): T[] {\n const set2 = new Set(arr2);\n return arr1.filter(item => set2.has(item));\n}\n\n/**\n * 数组并集\n * @param arr1 - 第一个数组\n * @param arr2 - 第二个数组\n * @returns 并集数组\n */\nexport function union<T>(arr1: T[], arr2: T[]): T[] {\n return unique([...arr1, ...arr2]);\n}\n\n/**\n * 按属性排序\n * @param arr - 输入数组\n * @param keyFn - 获取排序键的函数或属性名\n * @param order - 排序顺序,'asc' 或 'desc',默认为 'asc'\n * @returns 排序后的新数组\n */\nexport function sortBy<T, K extends string | number>(\n arr: T[],\n keyFn: ((item: T) => K) | string,\n order: 'asc' | 'desc' = 'asc'\n): T[] {\n const getKey =\n typeof keyFn === 'string' ? (item: T) => (item as Record<string, K>)[keyFn] as K : keyFn;\n\n const result = [...arr];\n result.sort((a, b) => {\n const keyA = getKey(a);\n const keyB = getKey(b);\n if (keyA < keyB) return order === 'asc' ? -1 : 1;\n if (keyA > keyB) return order === 'asc' ? 1 : -1;\n return 0;\n });\n return result;\n}\n\n/**\n * 按条件查找索引\n * @param arr - 输入数组\n * @param predicate - 条件函数\n * @returns 找到的索引,未找到返回 -1\n */\nexport function findIndexBy<T>(arr: T[], predicate: (item: T) => boolean): number {\n return arr.findIndex(predicate);\n}\n\n/**\n * 数组分割(满足条件/不满足条件)\n * @param arr - 输入数组\n * @param predicate - 条件函数\n * @returns 包含两个数组的元组:[满足条件的数组, 不满足条件的数组]\n */\nexport function partition<T>(arr: T[], predicate: (item: T) => boolean): [T[], T[]] {\n const truthy: T[] = [];\n const falsy: T[] = [];\n arr.forEach(item => {\n if (predicate(item)) {\n truthy.push(item);\n } else {\n falsy.push(item);\n }\n });\n return [truthy, falsy];\n}\n\n/**\n * 数组压缩(将多个数组合并成元组数组)\n * @param arrays - 要压缩的数组\n * @returns 压缩后的元组数组\n */\nexport function zip<T extends readonly unknown[]>(\n ...arrays: T\n): Array<{ [K in keyof T]: T[K] extends readonly (infer U)[] ? U : never }> {\n const maxLength = Math.max(...arrays.map(arr => (arr as unknown[]).length));\n const result: Array<{ [K in keyof T]: T[K] extends readonly (infer U)[] ? U : never }> = [];\n for (let i = 0; i < maxLength; i++) {\n result.push(\n arrays.map(arr => (arr as unknown[])[i]) as {\n [K in keyof T]: T[K] extends readonly (infer U)[] ? U : never;\n }\n );\n }\n return result;\n}\n\n/**\n * 数组解压(将元组数组拆分成多个数组)\n * @param array - 要解压的数组\n * @returns 解压后的数组元组\n */\nexport function unzip<T extends readonly unknown[]>(\n array: Array<{ [K in keyof T]: T[number] extends readonly (infer U)[] ? U : never }>\n): T {\n if (array.length === 0) return [] as unknown as T;\n const length = (array[0] as unknown[]).length;\n const result = Array.from({ length }, () => []) as unknown as unknown[][];\n array.forEach(item => {\n (item as unknown[]).forEach((val, index) => {\n result[index].push(val);\n });\n });\n return result as unknown as T;\n}\n\n/**\n * 移除假值(null, undefined, false, 0, '')\n * @param arr - 输入数组\n * @returns 移除假值后的数组\n */\nexport function compact<T>(arr: (T | null | undefined | false | 0 | '')[]): T[] {\n return arr.filter((item): item is T => Boolean(item));\n}\n\n/**\n * 取前N个元素\n * @param arr - 输入数组\n * @param n - 要取的元素数量\n * @returns 前N个元素的数组\n */\nexport function take<T>(arr: T[], n: number): T[] {\n return arr.slice(0, n);\n}\n\n/**\n * 跳过前N个元素\n * @param arr - 输入数组\n * @param n - 要跳过的元素数量\n * @returns 跳过后的数组\n */\nexport function drop<T>(arr: T[], n: number): T[] {\n return arr.slice(n);\n}\n\n/**\n * 条件取元素(直到条件不满足)\n * @param arr - 输入数组\n * @param predicate - 条件函数\n * @returns 满足条件的连续元素数组\n */\nexport function takeWhile<T>(arr: T[], predicate: (item: T) => boolean): T[] {\n const result: T[] = [];\n for (const item of arr) {\n if (!predicate(item)) break;\n result.push(item);\n }\n return result;\n}\n\n/**\n * 条件跳过元素(直到条件不满足)\n * @param arr - 输入数组\n * @param predicate - 条件函数\n * @returns 跳过后的数组\n */\nexport function dropWhile<T>(arr: T[], predicate: (item: T) => boolean): T[] {\n let index = 0;\n while (index < arr.length && predicate(arr[index])) {\n index++;\n }\n return arr.slice(index);\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types/upload.ts","../src/browser/upload.ts"],"names":["UploadStatus"],"mappings":"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","file":"chunk-NJARVI6X.mjs","sourcesContent":["/**\n * 文件上传相关类型定义\n */\n\n/**\n * 上传初始化请求参数\n */\nexport interface UploadInitRequest {\n fileName: string;\n fileSize: number;\n fileMd5: string;\n chunkSize?: number;\n}\n\n/**\n * 上传初始化响应\n */\nexport interface UploadInitResponse {\n taskId: string;\n totalChunks: number;\n existingChunks: number[];\n instantUpload: boolean;\n fileUrl?: string;\n chunkSize: number;\n}\n\n/**\n * 分片上传响应\n */\nexport interface ChunkUploadResponse {\n chunkIndex: number;\n success: boolean;\n message: string;\n chunkMd5: string;\n}\n\n/**\n * 完成上传响应\n */\nexport interface CompleteUploadResponse {\n taskId: string;\n fileUrl: string;\n fileName: string;\n fileSize: number;\n fileMd5: string;\n success: boolean;\n message: string;\n}\n\n/**\n * 上传进度信息\n */\nexport interface UploadProgress {\n taskId: string;\n fileName: string;\n fileSize: number;\n totalChunks: number;\n uploadedChunks: number;\n percentage: number;\n status: string;\n uploadedSize: number;\n}\n\n/**\n * API响应包装类型\n */\nexport interface ApiResponse<T> {\n code: number;\n message: string;\n data: T;\n timestamp: number;\n}\n\n/**\n * 上传配置选项\n */\nexport interface UploadOptions {\n /** 分片大小(字节),默认 2MB */\n chunkSize?: number;\n /** 并发上传数量,默认 3 */\n concurrency?: number;\n /** 重试次数,默认 3 */\n retryCount?: number;\n /** 重试延迟(毫秒),默认 1000 */\n retryDelay?: number;\n /** 基础API地址 */\n baseURL?: string;\n /** 请求头 */\n headers?: Record<string, string>;\n /** 上传进度回调 */\n onProgress?: (progress: UploadProgress) => void;\n /** 上传完成回调 */\n onComplete?: (result: CompleteUploadResponse) => void;\n /** 上传错误回调 */\n onError?: (error: Error) => void;\n}\n\n/**\n * 上传状态\n */\nexport enum UploadStatus {\n PENDING = 'pending',\n UPLOADING = 'uploading',\n PAUSED = 'paused',\n COMPLETED = 'completed',\n FAILED = 'failed',\n CANCELLED = 'cancelled',\n}\n\n/**\n * 文件分片信息\n */\nexport interface ChunkInfo {\n index: number;\n start: number;\n end: number;\n blob: Blob;\n md5?: string;\n}\n","/**\n * 文件分片上传工具类\n * 支持分片上传、断点续传、进度追踪、暂停/恢复/取消\n *\n * @example\n * ```typescript\n * import { createUploader } from '@alibarbar/common/upload';\n *\n * const uploader = createUploader(file, {\n * chunkSize: 2 * 1024 * 1024, // 2MB\n * concurrency: 3,\n * baseURL: 'https://api.example.com',\n * onProgress: (progress) => {\n * console.log(`进度:${progress.percentage}%`);\n * },\n * onComplete: (result) => {\n * console.log('上传完成:', result.fileUrl);\n * },\n * onError: (error) => {\n * console.error('上传失败:', error);\n * }\n * });\n *\n * // 开始上传\n * await uploader.upload();\n * ```\n */\n\nimport {\n UploadOptions,\n UploadInitRequest,\n UploadInitResponse,\n ChunkUploadResponse,\n CompleteUploadResponse,\n UploadProgress,\n UploadStatus,\n ChunkInfo,\n ApiResponse,\n} from '../types/upload';\nimport { calculateBlobMD5, splitFileIntoChunks } from './file';\n\n/**\n * 文件上传器类\n */\nexport class ChunkUploader {\n private file: File;\n private options: Required<UploadOptions>;\n private taskId: string | null = null;\n private chunks: ChunkInfo[] = [];\n private uploadedChunks: Set<number> = new Set();\n private status: UploadStatus = UploadStatus.PENDING;\n private abortController: AbortController | null = null;\n\n constructor(file: File, options: UploadOptions = {}) {\n this.file = file;\n this.options = {\n chunkSize: options.chunkSize || 2 * 1024 * 1024, // 默认2MB\n concurrency: options.concurrency || 3,\n retryCount: options.retryCount || 3,\n retryDelay: options.retryDelay || 1000,\n baseURL: options.baseURL || '',\n headers: options.headers || {},\n onProgress: options.onProgress || (() => {}),\n onComplete: options.onComplete || (() => {}),\n onError: options.onError || (() => {}),\n };\n }\n\n /**\n * 初始化上传\n */\n private async initUpload(): Promise<UploadInitResponse> {\n const fileMd5 = await this.calculateFileMD5();\n const request: UploadInitRequest = {\n fileName: this.file.name,\n fileSize: this.file.size,\n fileMd5,\n chunkSize: this.options.chunkSize,\n };\n\n const response = await this.request<ApiResponse<UploadInitResponse>>('/api/files/common/init', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...this.options.headers,\n },\n body: JSON.stringify(request),\n });\n\n if (response.code !== 200) {\n throw new Error(response.message || '初始化上传失败');\n }\n\n return response.data;\n }\n\n /**\n * 计算文件MD5\n */\n private async calculateFileMD5(): Promise<string> {\n const chunks = splitFileIntoChunks(this.file, this.options.chunkSize);\n const md5Promises = chunks.map((chunk, index) =>\n calculateBlobMD5(chunk).then(md5 => ({ index, md5 }))\n );\n const md5Results = await Promise.all(md5Promises);\n return md5Results.map(r => r.md5).join('');\n }\n\n /**\n * 准备分片\n */\n private prepareChunks(): void {\n const blobChunks = splitFileIntoChunks(this.file, this.options.chunkSize);\n this.chunks = blobChunks.map((blob, index) => ({\n index,\n start: index * this.options.chunkSize,\n end: Math.min((index + 1) * this.options.chunkSize, this.file.size),\n blob,\n }));\n }\n\n /**\n * 获取已上传的分片列表(用于断点续传)\n */\n private async getUploadedChunks(): Promise<number[]> {\n if (!this.taskId) return [];\n\n try {\n const response = await this.request<ApiResponse<number[]>>(\n `/api/files/common/chunks/${this.taskId}`,\n {\n method: 'GET',\n headers: this.options.headers,\n }\n );\n\n if (response.code === 200) {\n return response.data || [];\n }\n } catch (error) {\n console.warn('获取已上传分片失败:', error);\n }\n\n return [];\n }\n\n /**\n * 上传单个分片\n */\n private async uploadChunk(chunkInfo: ChunkInfo, retryCount = 0): Promise<void> {\n if (!this.taskId) {\n throw new Error('任务ID不存在');\n }\n\n if (this.uploadedChunks.has(chunkInfo.index)) {\n return; // 已上传,跳过\n }\n\n try {\n const chunkMd5 = await calculateBlobMD5(chunkInfo.blob);\n const formData = new FormData();\n formData.append('file', chunkInfo.blob, this.file.name);\n\n const url = `/api/files/common/chunk?taskId=${this.taskId}&chunkIndex=${chunkInfo.index}&chunkMd5=${chunkMd5}`;\n\n const response = await this.request<ApiResponse<ChunkUploadResponse>>(url, {\n method: 'POST',\n headers: this.options.headers,\n body: formData,\n });\n\n if (response.code === 200 && response.data.success) {\n this.uploadedChunks.add(chunkInfo.index);\n // 每上传一个分片,更新进度\n await this.updateProgress();\n } else {\n throw new Error(response.message || '分片上传失败');\n }\n } catch (error) {\n if (retryCount < this.options.retryCount) {\n await this.delay(this.options.retryDelay);\n return this.uploadChunk(chunkInfo, retryCount + 1);\n }\n throw error;\n }\n }\n\n /**\n * 并发上传分片\n */\n private async uploadChunksConcurrently(): Promise<void> {\n const chunksToUpload = this.chunks.filter(chunk => !this.uploadedChunks.has(chunk.index));\n\n if (chunksToUpload.length === 0) {\n return; // 所有分片已上传\n }\n\n let currentIndex = 0;\n const uploadNext = async (): Promise<void> => {\n while (this.status === UploadStatus.UPLOADING) {\n const chunkIndex = currentIndex++;\n if (chunkIndex >= chunksToUpload.length) {\n break;\n }\n const chunk = chunksToUpload[chunkIndex];\n await this.uploadChunk(chunk);\n }\n };\n\n // 启动并发任务\n const tasks = Array(this.options.concurrency)\n .fill(null)\n .map(() => uploadNext());\n await Promise.all(tasks);\n }\n\n /**\n * 更新上传进度(仅用于回调前端显示)\n */\n private async updateProgress(): Promise<void> {\n if (!this.taskId) return;\n\n try {\n const response = await this.request<ApiResponse<UploadProgress>>(\n `/api/files/common/progress/${this.taskId}`,\n {\n method: 'GET',\n headers: this.options.headers,\n }\n );\n\n if (response.code === 200 && response.data) {\n this.options.onProgress(response.data);\n }\n } catch (error) {\n console.warn('获取上传进度失败:', error);\n }\n }\n\n /**\n * 获取上传进度\n */\n private async getUploadProgress(): Promise<UploadProgress | null> {\n if (!this.taskId) {\n return null;\n }\n\n try {\n const response = await this.request<ApiResponse<UploadProgress>>(\n `/api/files/common/progress/${this.taskId}`,\n {\n method: 'GET',\n headers: this.options.headers,\n }\n );\n\n if (response.code === 200 && response.data) {\n console.log('[获取进度]', response.data);\n return response.data;\n }\n } catch (error) {\n console.warn('获取上传进度失败:', error);\n }\n\n return null;\n }\n\n /**\n * 完成上传(调用后端合并分片接口)\n */\n private async completeUpload(): Promise<CompleteUploadResponse> {\n if (!this.taskId) {\n throw new Error('任务ID不存在');\n }\n\n console.log('[完成上传] 调用完成接口:', `/api/files/common/complete/${this.taskId}`);\n\n const response = await this.request<ApiResponse<CompleteUploadResponse>>(\n `/api/files/common/complete/${this.taskId}`,\n {\n method: 'POST',\n headers: this.options.headers,\n }\n );\n\n console.log('[完成上传] 接口响应:', response);\n\n if (response.code !== 200) {\n throw new Error(response.message || '完成上传失败');\n }\n\n return response.data;\n }\n\n /**\n * 开始上传\n */\n async upload(): Promise<CompleteUploadResponse> {\n try {\n this.status = UploadStatus.UPLOADING;\n this.abortController = new AbortController();\n\n // 1. 初始化上传\n console.log('[上传流程] 1. 初始化上传');\n const initResponse = await this.initUpload();\n this.taskId = initResponse.taskId;\n\n // 2. 检查是否秒传\n if (initResponse.instantUpload && initResponse.fileUrl) {\n console.log('[上传流程] 秒传成功');\n this.status = UploadStatus.COMPLETED;\n const result: CompleteUploadResponse = {\n taskId: this.taskId,\n fileUrl: initResponse.fileUrl,\n fileName: this.file.name,\n fileSize: this.file.size,\n fileMd5: '',\n success: true,\n message: '文件已存在,秒传成功',\n };\n this.options.onComplete(result);\n return result;\n }\n\n // 3. 准备分片\n console.log('[上传流程] 2. 准备分片');\n this.prepareChunks();\n const totalChunks = this.chunks.length;\n console.log(`[上传流程] 共 ${totalChunks} 个分片`);\n\n // 4. 获取已上传的分片(断点续传)\n console.log('[上传流程] 3. 检查已上传分片');\n const existingChunks = await this.getUploadedChunks();\n existingChunks.forEach(index => this.uploadedChunks.add(index));\n console.log(\n `[上传流程] 已上传 ${existingChunks.length} 个分片,还需上传 ${totalChunks - existingChunks.length} 个`\n );\n\n // 5. 上传分片\n console.log('[上传流程] 4. 开始上传分片');\n await this.uploadChunksConcurrently();\n console.log('[上传流程] 5. 所有分片上传完成');\n\n // 6. 验证所有分片都已上传\n const uploadedCount = this.uploadedChunks.size;\n if (uploadedCount < totalChunks) {\n throw new Error(`上传验证失败:已上传 ${uploadedCount}/${totalChunks} 个分片`);\n }\n console.log(`[上传流程] 6. 验证通过:${uploadedCount}/${totalChunks} 个分片已上传`);\n\n // 7. 计算本地进度\n const localPercentage = Math.round((uploadedCount / totalChunks) * 100);\n console.log(`[上传流程] 7. 本地进度:${localPercentage}%`);\n\n // 8. 获取服务端进度\n console.log('[上传流程] 8. 获取服务端进度');\n const serverProgress = await this.getUploadProgress();\n const serverPercentage = serverProgress?.percentage ?? 0;\n console.log(`[上传流程] 服务端进度:${serverPercentage}%`);\n\n // 9. 计算最终进度(优先使用服务端进度)\n const finalPercentage = serverProgress?.percentage ?? localPercentage;\n console.log(`[上传流程] 9. 最终进度:${finalPercentage}%`);\n\n // 10. 判断是否可以调用完成接口\n if (finalPercentage >= 100) {\n console.log('[上传流程] 10. ✅ 进度达到100%,调用完成接口');\n const result = await this.completeUpload();\n\n this.status = UploadStatus.COMPLETED;\n this.options.onComplete(result);\n\n console.log('[上传流程] ✅ 上传完成');\n return result;\n } else {\n console.error(`[上传流程] ❌ 进度不足100%:${finalPercentage}%`);\n throw new Error(`上传未完成:当前进度 ${finalPercentage.toFixed(2)}%`);\n }\n } catch (error) {\n this.status = UploadStatus.FAILED;\n const err = error instanceof Error ? error : new Error(String(error));\n this.options.onError(err);\n console.error('[上传流程] ❌ 上传失败:', err);\n throw err;\n }\n }\n\n /**\n * 暂停上传\n */\n pause(): void {\n if (this.status === UploadStatus.UPLOADING) {\n this.status = UploadStatus.PAUSED;\n if (this.abortController) {\n this.abortController.abort();\n }\n }\n }\n\n /**\n * 恢复上传\n */\n async resume(): Promise<CompleteUploadResponse> {\n if (this.status === UploadStatus.PAUSED) {\n return this.upload();\n }\n throw new Error('当前状态无法恢复上传');\n }\n\n /**\n * 取消上传\n */\n async cancel(): Promise<void> {\n if (this.taskId && this.status === UploadStatus.UPLOADING) {\n try {\n await this.request<ApiResponse<null>>(`/api/files/common/cancel/${this.taskId}`, {\n method: 'POST',\n headers: this.options.headers,\n });\n } catch (error) {\n console.warn('取消上传失败:', error);\n }\n }\n\n this.status = UploadStatus.CANCELLED;\n if (this.abortController) {\n this.abortController.abort();\n }\n }\n\n /**\n * 获取当前状态\n */\n getStatus(): UploadStatus {\n return this.status;\n }\n\n /**\n * 获取任务ID\n */\n getTaskId(): string | null {\n return this.taskId;\n }\n\n /**\n * HTTP请求封装\n */\n private async request<T>(url: string, options: RequestInit = {}): Promise<T> {\n const fullUrl = `${this.options.baseURL}${url}`;\n const signal = this.abortController?.signal;\n\n const response = await fetch(fullUrl, {\n ...options,\n signal,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP错误: ${response.status} ${response.statusText}`);\n }\n\n return response.json();\n }\n\n /**\n * 延迟函数\n */\n private delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n}\n\n/**\n * 创建文件上传器实例\n * @param file - 文件对象\n * @param options - 上传配置选项\n * @returns 上传器实例\n */\nexport function createUploader(file: File, options?: UploadOptions): ChunkUploader {\n return new ChunkUploader(file, options);\n}\n\n/**\n * 简单的文件上传函数(Promise风格)\n * @param file - 文件对象\n * @param options - 上传配置选项\n * @returns Promise<CompleteUploadResponse>\n */\nexport async function uploadFile(\n file: File,\n options?: UploadOptions\n): Promise<CompleteUploadResponse> {\n const uploader = createUploader(file, options);\n return uploader.upload();\n}\n"]}
|