@i.un/libs 0.0.13 → 0.0.15

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.
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * 表示 DOM 中可能的子元素类型。
3
3
  */
4
- export type ChildrenType = DomOptionsType | HTMLElement | SVGElement | Text | string;
4
+ export type ChildrenType = DomOptionsType | Element | string;
5
5
  /**
6
6
  * 表示创建 DOM 元素的选项类型。
7
7
  */
@@ -48,7 +48,7 @@ export type DomOptionsType = {
48
48
  * document.body.appendChild(element);
49
49
  * ```
50
50
  */
51
- export declare function createElement({ tag, children, props, attrs, styles, }?: DomOptionsType): HTMLElement;
51
+ export declare function createElement({ tag, children, props, attrs, styles, }?: DomOptionsType): Element;
52
52
  type SvgElement = {
53
53
  tag: string;
54
54
  attributes?: Record<string, string>;
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- function t(t){return"function"==typeof(null==t?void 0:t.clone)}function e(t){var e=typeof t;return null===t||"string"===e||"number"===e||"boolean"===e||"undefined"===e}function n(t){return e(t)?String(t):JSON.stringify(t,function(t,e){return"object"!=typeof e||null===e||Array.isArray(e)?e:Object.keys(e).sort().reduce(function(t,n){return t[n]=e[n],t},{})})}function r(e){if(null===e||"object"!=typeof e)return e;if(t(e))return e.clone();if(Array.isArray(e))return e.map(function(t){return r(t)});var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(n[i]=r(e[i]));return n}var i={};function o(t){return i[t]}var a={timeout:6e4,timeoutResult:{code:408,msg:"请求超时"},identifier:""};function u(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=Array(e);n<e;n++)r[n]=t[n];return r}function l(t,e,n,r){if(void 0===r&&(r=!1),e in t.style)t.style[e]=n;else{var i=r?"important":"";t.style.setProperty(e,String(n),i)}}function c(t){var e=t.attributes,n=t.children,r=document.createElementNS("http://www.w3.org/2000/svg",t.tag);if(e)for(var i=0,o=Object.entries(e);i<o.length;i++){var a=o[i];r.setAttribute(a[0],a[1])}return"string"==typeof n?r.textContent=n:n&&(Array.isArray(n)?n:[n]).forEach(function(t){r.appendChild(c(t))}),r}function s(t){t&&setTimeout(function(){t.scrollTop=t.scrollHeight},0)}exports.cacheWrapper=function(t,e){return void 0===e&&(e=a),function(){var u=[].slice.call(arguments),l=n(u)+t.name+(e.identifier||"");if(i[l])return Promise.resolve(r(o(l)));var c=l+"_l_o_a_d_i_n_g_";if(i[c]){var s=Object.assign({},a,e);return new Promise(function(t){var e=Date.now(),n=setInterval(function(){i[l]?(clearInterval(n),t(r(o(l)))):Date.now()-e>s.timeout&&(i[c]=!1,clearInterval(n),t(r(s.timeoutResult)))},100)})}return i[c]=!0,t.apply(void 0,u).then(function(t){return i[l]=t,r(i[l])}).catch(function(t){throw t}).finally(function(){i[c]=!1})}},exports.cloneDeep=r,exports.createElement=function t(e){var n=void 0===e?{}:e,r=n.tag,i=n.children,o=void 0===i?[]:i,a=n.props,c=void 0===a?{}:a,s=n.attrs,f=void 0===s?{}:s,d=n.styles,p=void 0===d?{}:d,v=document.createElement(void 0===r?"div":r);Object.assign(v,c);for(var g=0,y=Object.entries(f);g<y.length;g++){var h=y[g],m=h[1];!1!==m&&v.setAttribute(h[0],m)}for(var b=0,x=Object.entries(p);b<x.length;b++){var w=x[b];l(v,w[0],w[1])}for(var A,E=function(t){var e="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(e)return(e=e.call(t)).next.bind(e);if(Array.isArray(t)||(e=function(t,e){if(t){if("string"==typeof t)return u(t,e);var n={}.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?u(t,e):void 0}}(t))){e&&(t=e);var n=0;return function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(Array.isArray(o)?o:[o]);!(A=E()).done;){var S=A.value;S&&("object"==typeof S?S instanceof HTMLElement||S instanceof Text?v.appendChild(S):v.appendChild(t(S)):v.appendChild(document.createTextNode(S)))}return v},exports.createSvg=function(t,e){var n=e||{},r=n.width,i=void 0===r?32:r,o=n.height,a=void 0===o?32:o,u=document.createElementNS("http://www.w3.org/2000/svg","svg");return u.setAttribute("width",i.toString()),u.setAttribute("height",a.toString()),u.setAttribute("viewBox","0 0 "+i+" "+a),"string"==typeof t?u.innerHTML=t:(Array.isArray(t)?t:[t]).forEach(function(t){u.appendChild(c(t))}),u},exports.debounce=function(t,e){var n=null;return function(){var r=arguments,i=this;null!==n&&clearTimeout(n),n=setTimeout(function(){t.apply(i,[].slice.call(r)),n=null},e)}},exports.delayExecution=function(t,e){return void 0===e&&(e=0),new Promise(function(n){0===e?n(t()):setTimeout(function(){n(t())},e)})},exports.generateStableUniqueKey=n,exports.getGlobal=function(){return"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:this},exports.isCloneable=t,exports.isPrimitive=e,exports.scrollToBottom=s,exports.scrollToBottomIfNeeded=function(t){t&&("true"!==t.dataset.isListeningForUserScroll&&(function(t){t&&t.addEventListener("scroll",function(){!function(t,e){t.dataset.userInteracted=e?"true":"false"}(t,t.scrollTop+t.clientHeight<t.scrollHeight-5)})}(t),t.dataset.isListeningForUserScroll="true"),"true"!==t.dataset.userInteracted&&s(t))},exports.singleExecutionWrapper=function(t){var e=function(){if(!e.isExecuting){var n;e.isExecuting=!0;try{(n=t.apply(void 0,[].slice.call(arguments)))instanceof Promise?n.finally(function(){e.isExecuting=!1}):e.isExecuting=!1}catch(t){throw e.isExecuting=!1,t}return n}console.log("Function("+t.name+") is executing.")};return e.isExecuting=!1,e},exports.throttle=function(t,e){var n=0;return function(){var r=Date.now();r-n>=e&&(t.apply(this,[].slice.call(arguments)),n=r)}};
1
+ function t(t){return"function"==typeof(null==t?void 0:t.clone)}function e(t){var e=typeof t;return null===t||"string"===e||"number"===e||"boolean"===e||"undefined"===e}function n(t){return e(t)?String(t):JSON.stringify(t,function(t,e){return"object"!=typeof e||null===e||Array.isArray(e)?e:Object.keys(e).sort().reduce(function(t,n){return t[n]=e[n],t},{})})}function r(e){if(null===e||"object"!=typeof e)return e;if(t(e))return e.clone();if(Array.isArray(e))return e.map(function(t){return r(t)});var n={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(n[i]=r(e[i]));return n}var i={};function o(t){return i[t]}var a={timeout:6e4,timeoutResult:{code:408,msg:"请求超时"},identifier:""};function u(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=Array(e);n<e;n++)r[n]=t[n];return r}function l(t,e,n,r){if(void 0===r&&(r=!1),e in t.style)t.style[e]=n;else{var i=r?"important":"";t.style.setProperty(e,String(n),i)}}function c(t){var e=t.attributes,n=t.children,r=document.createElementNS("http://www.w3.org/2000/svg",t.tag);if(e)for(var i=0,o=Object.entries(e);i<o.length;i++){var a=o[i];r.setAttribute(a[0],a[1])}return"string"==typeof n?r.textContent=n:n&&(Array.isArray(n)?n:[n]).forEach(function(t){r.appendChild(c(t))}),r}function s(t){t&&setTimeout(function(){t.scrollTop=t.scrollHeight},0)}exports.cacheWrapper=function(t,e){return void 0===e&&(e=a),function(){var u=[].slice.call(arguments),l=n(u)+t.name+(e.identifier||"");if(i[l])return Promise.resolve(r(o(l)));var c=l+"_l_o_a_d_i_n_g_";if(i[c]){var s=Object.assign({},a,e);return new Promise(function(t){var e=Date.now(),n=setInterval(function(){i[l]?(clearInterval(n),t(r(o(l)))):Date.now()-e>s.timeout&&(i[c]=!1,clearInterval(n),t(r(s.timeoutResult)))},100)})}return i[c]=!0,t.apply(void 0,u).then(function(t){return i[l]=t,r(i[l])}).catch(function(t){throw t}).finally(function(){i[c]=!1})}},exports.cloneDeep=r,exports.createElement=function t(e){var n=void 0===e?{}:e,r=n.tag,i=n.children,o=void 0===i?[]:i,a=n.props,c=void 0===a?{}:a,s=n.attrs,f=void 0===s?{}:s,d=n.styles,p=void 0===d?{}:d,v=document.createElement(void 0===r?"div":r);Object.assign(v,c);for(var g=0,y=Object.entries(f);g<y.length;g++){var h=y[g],m=h[1];!1!==m&&v.setAttribute(h[0],m)}for(var b=0,x=Object.entries(p);b<x.length;b++){var w=x[b];l(v,w[0],w[1])}for(var A,E=function(t){var e="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(e)return(e=e.call(t)).next.bind(e);if(Array.isArray(t)||(e=function(t,e){if(t){if("string"==typeof t)return u(t,e);var n={}.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?u(t,e):void 0}}(t))){e&&(t=e);var n=0;return function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(Array.isArray(o)?o:[o]);!(A=E()).done;){var S=A.value;S&&("object"==typeof S?S instanceof Element?v.appendChild(S):v.appendChild(t(S)):v.appendChild(document.createTextNode(S)))}return v},exports.createSvg=function(t,e){var n=e||{},r=n.width,i=void 0===r?32:r,o=n.height,a=void 0===o?32:o,u=document.createElementNS("http://www.w3.org/2000/svg","svg");return u.setAttribute("width",i.toString()),u.setAttribute("height",a.toString()),u.setAttribute("viewBox","0 0 "+i+" "+a),"string"==typeof t?u.innerHTML=t:(Array.isArray(t)?t:[t]).forEach(function(t){u.appendChild(c(t))}),u},exports.debounce=function(t,e){var n=null;return function(){var r=arguments,i=this;null!==n&&clearTimeout(n),n=setTimeout(function(){t.apply(i,[].slice.call(r)),n=null},e)}},exports.delayExecution=function(t,e){return void 0===e&&(e=0),new Promise(function(n){0===e?n(t()):setTimeout(function(){n(t())},e)})},exports.generateStableUniqueKey=n,exports.getGlobal=function(){return"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:this},exports.isCloneable=t,exports.isPrimitive=e,exports.scrollToBottom=s,exports.scrollToBottomIfNeeded=function(t){t&&("true"!==t.dataset.isListeningForUserScroll&&(function(t){t&&t.addEventListener("scroll",function(){!function(t,e){t.dataset.userInteracted=e?"true":"false"}(t,t.scrollTop+t.clientHeight<t.scrollHeight-5)})}(t),t.dataset.isListeningForUserScroll="true"),"true"!==t.dataset.userInteracted&&s(t))},exports.singleExecutionWrapper=function(t){var e=function(){if(!e.isExecuting){var n;e.isExecuting=!0;try{(n=t.apply(void 0,[].slice.call(arguments)))instanceof Promise?n.finally(function(){e.isExecuting=!1}):e.isExecuting=!1}catch(t){throw e.isExecuting=!1,t}return n}console.log("Function("+t.name+") is executing.")};return e.isExecuting=!1,e},exports.throttle=function(t,e){var n=0;return function(){var r=Date.now();r-n>=e&&(t.apply(this,[].slice.call(arguments)),n=r)}};
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/common/type.ts","../src/common/generateStableUniqueKey.ts","../src/common/cloneDeep.ts","../src/common/cacheWrapper.ts","../src/browser/dom.ts","../src/browser/scroll.ts","../src/common/utils.ts","../src/common/getGlobal.ts","../src/common/singleExecutionWrapper.ts"],"sourcesContent":["/**\n * 异步函数类型。\n *\n * @template Args - 表示函数参数的类型数组。\n * @template T - 表示函数返回的 Promise 解析后的类型。\n *\n * @param args - 函数的参数。\n * @returns 一个 Promise 对象,解析后的值类型为 T。\n */\nexport type AsyncFunction<Args extends any[], T> = (\n ...args: Args\n) => Promise<T>;\n\n/**\n * 表示一个可以克隆自身的对象接口。\n *\n * @interface Cloneable\n */\nexport interface Cloneable {\n /**\n * 创建并返回当前对象的一个副本。\n *\n * @returns {this} 当前对象的一个副本。\n */\n clone(): this;\n}\n\n/**\n *\n * 检查一个对象是否实现了 Cloneable 接口。\n *\n * 这个函数是一个类型保护函数,它会在类型检查时将传入的对象类型缩小为 Cloneable。\n *\n * @param {any} obj - 要检查的对象。\n * @returns {obj is Cloneable} 如果对象实现了 Cloneable 接口,则返回 true;否则返回 false。\n */\nexport function isCloneable(obj: any): obj is Cloneable {\n return typeof obj?.clone === \"function\";\n}\n\n/**\n * 检查一个值是否是原始类型(primitive type)。\n *\n * 这个函数是一个类型保护函数,它会在类型检查时将传入的值类型缩小为原始类型之一:string, number, boolean, null 或 undefined。\n *\n * @param {any} value - 要检查的值。\n * @returns {value is string | number | boolean | null | undefined} 如果值是原始类型,则返回 true;否则返回 false。\n */\nexport function isPrimitive(\n value: any\n): value is string | number | boolean | null | undefined {\n const type = typeof value;\n return (\n value === null ||\n type === \"string\" ||\n type === \"number\" ||\n type === \"boolean\" ||\n type === \"undefined\"\n );\n}\n","import { isPrimitive } from \"./type\";\n\n/**\n * 为给定的参数生成一个稳定且唯一的键。\n *\n * 该函数确保生成的键是确定性的,即相同的输入总是会生成相同的输出。\n * 这在缓存、记忆化或任何需要一致键的场景中非常有用。\n *\n * @param params - 用于生成键的参数。可以是任何类型。\n * @returns 表示输入参数的稳定且唯一的字符串键。\n */\nexport function generateStableUniqueKey(params: any) {\n if (isPrimitive(params)) {\n return String(params);\n }\n return JSON.stringify(params, function (_key: string | number, value: any) {\n if (typeof value === \"object\" && value !== null && !Array.isArray(value)) {\n return Object.keys(value)\n .sort()\n .reduce((pre: any, cur: string) => {\n pre[cur] = value[cur];\n return pre;\n }, {});\n }\n return value;\n });\n}\n","import { isCloneable } from \"./type\";\n\n/**\n * 深度克隆一个对象或数组。\n *\n * @param {T} obj - 要克隆的对象或数组。\n * @returns {T} 克隆后的对象或数组。\n */\nexport function cloneDeep<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n\n if (isCloneable(obj)) {\n return obj.clone();\n }\n\n // 处理数组\n if (Array.isArray(obj)) {\n return obj.map((item) => cloneDeep(item)) as unknown as T;\n }\n\n const newObj: { [key: string]: any } = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n newObj[key] = cloneDeep(obj[key]);\n }\n }\n return newObj as T;\n}\n","import { generateStableUniqueKey } from \"./generateStableUniqueKey\";\nimport { cloneDeep } from \"./cloneDeep\";\nimport { AsyncFunction } from \"./type\";\n\nconst cache: Record<string, any> = {};\nfunction getCachedData<T = any>(apiKey: string) {\n return cache[apiKey] as T;\n}\n\nexport interface Setting {\n timeout?: number;\n timeoutResult?: any;\n identifier?: string;\n}\n\nconst defalutSetting: Setting = {\n timeout: 60000,\n timeoutResult: { code: 408, msg: \"请求超时\" },\n identifier: \"\",\n};\n\n/**\n * 为异步函数添加缓存功能。\n *\n * 该函数根据函数参数、函数名和一个可选的标识符来缓存异步函数的结果。\n * 如果结果已经缓存,则返回缓存的结果。如果函数正在执行中,则等待结果返回,并使用一个超时机制防止无限等待。\n *\n * @template Args - 函数参数的类型。\n * @template Promise<T> - 函数返回值的类型。\n * @param {AsyncFunction<Args, T>} func - 需要包装的异步函数。\n * @param {Setting} [setting=defalutSetting] - 可选的缓存设置。\n * @returns {AsyncFunction<Args, T>} - 带有缓存功能的包装函数,返回类型为 `Promise<T>`。\n */\nexport function cacheWrapper<Args extends any[], T>(\n func: AsyncFunction<Args, T>,\n setting: Setting = defalutSetting\n): AsyncFunction<Args, T> {\n return function (...args: Args): Promise<T> {\n const apiKey: string =\n generateStableUniqueKey(args) + func.name + (setting.identifier || \"\"); //缓存key\n\n if (cache[apiKey]) {\n return Promise.resolve(cloneDeep(getCachedData<T>(apiKey)));\n }\n\n const apiLoadingKey: string = apiKey + \"_l_o_a_d_i_n_g_\"; //缓存loading key\n\n if (cache[apiLoadingKey]) {\n const _setting = Object.assign({}, defalutSetting, setting);\n return new Promise((resolve) => {\n const startTime = Date.now();\n const timer = setInterval(() => {\n if (cache[apiKey]) {\n clearInterval(timer);\n resolve(cloneDeep(getCachedData<T>(apiKey)));\n } else if (Date.now() - startTime > _setting.timeout!) {\n cache[apiLoadingKey] = false;\n clearInterval(timer);\n resolve(cloneDeep(_setting.timeoutResult));\n }\n }, 100);\n });\n }\n cache[apiLoadingKey] = true;\n\n return func(...args)\n .then((res) => {\n // 缓存原始数据或其克隆,避免数据被释放\n cache[apiKey] = res;\n return cloneDeep(cache[apiKey]);\n })\n .catch((error: any) => {\n throw error;\n })\n .finally(() => {\n cache[apiLoadingKey] = false;\n });\n };\n}\n","/**\n * 表示 DOM 中可能的子元素类型。\n */\nexport type ChildrenType =\n | DomOptionsType\n | HTMLElement\n | SVGElement\n | Text\n | string;\n\n/**\n * 表示创建 DOM 元素的选项类型。\n */\nexport type DomOptionsType = {\n /**\n * 要创建的元素的标签名。默认为 \"div\"。\n */\n tag?: string;\n\n /**\n * 要附加到创建的元素的子元素。可以是单个子元素或子元素数组。\n */\n children?: ChildrenType | ChildrenType[];\n\n /**\n * 要设置在创建的元素上的属性。\n */\n props?: Record<string, any>;\n\n /**\n * 要设置在创建的元素上的属性。\n */\n attrs?: Record<string, string | boolean>;\n\n /**\n * 要应用于创建的元素的样式。\n */\n styles?: Record<string, string | number>;\n};\n\n/**\n * 设置 HTML 元素的样式属性。\n *\n * @param element - 要设置样式的 HTML 元素。\n * @param property - CSS 属性名,可以是驼峰命名法(camelCase)或连字符命名法(kebab-case)。\n * @param value - 要设置的属性值。\n * @param important - 可选参数,布尔值,表示是否将属性设置为 `important` 优先级,默认为 `false`。\n */\nfunction setStyle(\n element: HTMLElement,\n property: string,\n value: string | number,\n important: boolean = false\n): void {\n if (property in element.style) {\n (element.style as any)[property] = value;\n } else {\n const priority = important ? \"important\" : \"\";\n element.style.setProperty(property, String(value), priority);\n }\n}\n\n/**\n * 使用指定选项创建一个 DOM 元素。\n *\n * @param options - 创建 DOM 元素的选项。\n *\n * @returns 创建的 DOM 元素。\n *\n * @remarks\n * 此函数旨在浏览器环境中使用。\n *\n * @example\n * ```typescript\n * const element = createElement({\n * tag: 'button',\n * children: '点击我',\n * attrs: { id: 'myButton' },\n * styles: { color: 'red' }\n * });\n * document.body.appendChild(element);\n * ```\n */\nexport function createElement({\n tag = \"div\",\n children = [],\n props = {},\n attrs = {},\n styles = {},\n}: DomOptionsType = {}): HTMLElement {\n const ele = document.createElement(tag);\n\n // 设置属性\n Object.assign(ele, props);\n\n // 设置属性\n for (const [key, value] of Object.entries(attrs)) {\n if (value !== false) {\n ele.setAttribute(key, value as string);\n }\n }\n\n // 设置样式\n for (const [key, value] of Object.entries(styles)) {\n setStyle(ele, key, value);\n }\n\n // 处理子元素\n const childArray = Array.isArray(children) ? children : [children];\n for (const child of childArray) {\n if (!child) continue;\n\n if (typeof child === \"object\") {\n if (child instanceof HTMLElement || child instanceof Text) {\n ele.appendChild(child);\n } else {\n ele.appendChild(createElement(child as DomOptionsType));\n }\n } else {\n ele.appendChild(document.createTextNode(child));\n }\n }\n\n return ele;\n}\n\ntype SvgElement = {\n tag: string;\n attributes?: Record<string, string>;\n children?: SvgElement | SvgElement[] | string;\n};\n\ntype SvgOptions = {\n width?: number;\n height?: number;\n};\n\n/**\n * 创建一个 SVG 元素。\n *\n * @param {SvgElement[] | SvgElement | string} elements - 要创建的 SVG 元素,可以是对象数组、单个对象或 innerHTML 字符串。\n * @param {SvgOptions} [options] - SVG 的配置选项,包括宽度和高度。\n * @returns {SVGElement} - 创建的 SVG 元素。\n *\n * @example\n * // 使用嵌套对象\n * const svg1 = createSvg(\n * {\n * tag: 'svg',\n * children: [\n * { tag: 'circle', attributes: { cx: '16', cy: '16', r: '10', fill: 'red' } },\n * { tag: 'g', children:\n * { tag: 'text', attributes: { x: '10', y: '20', fill: 'black' }, children: 'Hello' }\n * }\n * ]\n * },\n * { width: 64, height: 64 }\n * );\n * document.body.appendChild(svg1);\n *\n * @example\n * // 使用 innerHTML\n * const svg2 = createSvg(\n * `<circle cx=\"16\" cy=\"16\" r=\"10\" fill=\"red\"></circle>\n * <text x=\"10\" y=\"20\" fill=\"black\">Hello</text>`\n * );\n * document.body.appendChild(svg2);\n */\nexport function createSvg(\n elements: SvgElement[] | SvgElement | string,\n options?: SvgOptions\n) {\n // 默认宽度和高度\n const { width = 32, height = 32 } = options || {};\n\n // 创建一个 SVG 元素\n const svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n\n // 设置 SVG 的宽度和高度\n svg.setAttribute(\"width\", width.toString());\n svg.setAttribute(\"height\", height.toString());\n svg.setAttribute(\"viewBox\", `0 0 ${width} ${height}`);\n\n if (typeof elements === \"string\") {\n // 如果 elements 是字符串,直接设置为 SVG 的 innerHTML\n svg.innerHTML = elements;\n } else {\n // 处理 SvgElement 或 SvgElement[]\n const elementArray = Array.isArray(elements) ? elements : [elements];\n\n elementArray.forEach((element) => {\n svg.appendChild(createSvgElement(element));\n });\n }\n\n // 返回创建好的 SVG 元素\n return svg;\n}\n\n/**\n * 递归创建 SVG 子元素。\n *\n * @param {SvgElement} element - 要创建的 SVG 子元素。\n * @returns {SVGElement} - 创建的 SVG 子元素。\n */\nfunction createSvgElement(element: SvgElement) {\n const { tag, attributes, children } = element;\n const el = document.createElementNS(\"http://www.w3.org/2000/svg\", tag);\n\n if (attributes) {\n for (const [key, value] of Object.entries(attributes)) {\n el.setAttribute(key, value);\n }\n }\n\n if (typeof children === \"string\") {\n el.textContent = children;\n } else if (children) {\n const childArray = Array.isArray(children) ? children : [children];\n childArray.forEach((child) => {\n el.appendChild(createSvgElement(child));\n });\n }\n\n return el;\n}\n","/**\n * 将指定的 DOM 元素滚动到底部。\n * 使用 setTimeout 确保在当前调用栈之后执行。\n *\n * @param {HTMLElement} dom - 要滚动的 DOM 元素。\n */\nexport function scrollToBottom(dom: HTMLElement) {\n if (dom) {\n setTimeout(() => {\n // 设置滚动条位置为元素的最大滚动高度,滚动到底部\n dom.scrollTop = dom.scrollHeight;\n }, 0);\n }\n}\n\n/**\n * 如果用户未与 DOM 元素交互,则将其滚动到底部。\n * 如果尚未设置事件监听器,则设置一个以跟踪用户滚动交互。\n *\n * @param {HTMLElement} dom - 可能需要滚动的 DOM 元素。\n */\nexport function scrollToBottomIfNeeded(dom: HTMLElement): void {\n if (!dom) {\n return;\n }\n // 检查是否已设置滚动监听器\n if (dom.dataset.isListeningForUserScroll !== \"true\") {\n listenForUserScroll(dom);\n dom.dataset.isListeningForUserScroll = \"true\";\n }\n\n // 如果用户未与滚动条交互,则滚动到底部\n if (dom.dataset.userInteracted !== \"true\") {\n scrollToBottom(dom);\n }\n}\n\n/**\n * 更新用户是否与滚动条交互的状态。\n *\n * @param {HTMLElement} dom - 要更新状态的 DOM 元素。\n * @param {boolean} inter - 用户是否与滚动条交互。\n */\nfunction userInteractedWithScroll(dom: HTMLElement, inter: boolean): void {\n // 根据用户交互状态更新数据属性\n dom.dataset.userInteracted = inter ? \"true\" : \"false\";\n}\n\n/**\n * 为 DOM 元素设置滚动事件监听器。\n * 当用户滚动时,更新交互状态。\n *\n * @param {HTMLElement} dom - 要监听滚动事件的 DOM 元素。\n */\nfunction listenForUserScroll(dom: HTMLElement): void {\n if (!dom) {\n return;\n }\n dom.addEventListener(\"scroll\", () => {\n // 检查用户是否滚动到接近底部\n if (dom.scrollTop + dom.clientHeight < dom.scrollHeight - 5) {\n // 用户已滚动,更新交互状态\n userInteractedWithScroll(dom, true);\n } else {\n // 用户未滚动到接近底部\n userInteractedWithScroll(dom, false);\n }\n });\n}\n","/**\n * 创建一个防抖函数,该函数会在最后一次调用后的指定时间间隔后执行。\n *\n * @param func - 需要防抖处理的函数。\n * @param wait - 延迟的毫秒数。\n * @returns 一个新的防抖函数。\n */\nexport function debounce<T extends (...args: any[]) => void>(\n func: T,\n wait: number\n): T {\n let timeout: ReturnType<typeof setTimeout> | null = null;\n\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n const context = this;\n\n // 如果已经设定了调用,取消之前的调用\n if (timeout !== null) {\n clearTimeout(timeout);\n }\n\n // 设定一个新的调用,等待指定的时间后执行\n timeout = setTimeout(() => {\n func.apply(context, args);\n timeout = null; // 确保能够在下次触发时重新设定定时器\n }, wait);\n } as T;\n}\n\n/**\n * 创建一个节流函数,该函数会在每个指定的时间间隔内最多执行一次。\n *\n * @param func - 需要节流处理的函数。\n * @param delay - 时间间隔的毫秒数。\n * @returns 一个新的节流函数。\n */\nexport function throttle<T extends (...agrs: any[]) => any>(\n func: T,\n delay: number\n): T {\n let lastExecutedTime: number = 0;\n\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n const context = this;\n const currentTime = Date.now();\n\n if (currentTime - lastExecutedTime >= delay) {\n func.apply(context, args);\n lastExecutedTime = currentTime;\n }\n } as T;\n}\n\n/**\n * 创建一个延迟执行回调函数并返回 Promise 的函数。\n *\n * @param callback - 需要执行的回调函数。\n * @param delay - 延迟的毫秒数,默认为 0。\n * @returns 一个 Promise 对象,该对象在回调函数执行后解析。\n */\nexport function delayExecution<T>(\n callback: () => T,\n delay: number = 0\n): Promise<T> {\n return new Promise<T>((resolve) => {\n if (delay === 0) {\n resolve(callback());\n } else {\n setTimeout(() => {\n resolve(callback());\n }, delay);\n }\n });\n}\n","declare var global: typeof globalThis;\n\n/**\n * 获取当前环境的全局对象。\n *\n * 在不同的 JavaScript 运行环境中,全局对象的名称不同:\n * - 在浏览器环境中,全局对象是 `window`。\n * - 在 Node.js 环境中,全局对象是 `global`。\n * - 在 Web Worker 环境中,全局对象是 `self`。\n *\n * 这个函数提供了一种统一的方式来获取当前环境的全局对象。\n *\n * @returns 当前环境的全局对象。\n */\nexport function getGlobal(this: any) {\n if (typeof globalThis !== \"undefined\") {\n return globalThis;\n }\n\n if (typeof self !== \"undefined\") {\n return self;\n }\n\n if (typeof window !== \"undefined\") {\n return window;\n }\n\n if (typeof global !== \"undefined\") {\n return global;\n }\n\n // 如果以上都不符合,则返回 this\n return this;\n}\n","/**\n * 定义一个类型,用于扩展函数类型,增加一个可选的 isExecuting 属性\n */\nexport type SingleExecutionFunction<T extends (...args: any[]) => any> = T & {\n isExecuting?: boolean;\n};\n\n/**\n * 创建一个有执行状态的函数,该函数在前一次调用未完成时不会被再次调用。\n *\n * @param func - 需要包裹的函数。\n * @returns 一个增强版的函数,该函数具有 isExecuting 属性。\n */\nexport function singleExecutionWrapper<T extends (...args: any[]) => any>(\n func: T\n): SingleExecutionFunction<T> {\n const singleExecutionFn: SingleExecutionFunction<T> = function (\n ...args: Parameters<T>\n ): ReturnType<T> | undefined {\n if (singleExecutionFn.isExecuting) {\n console.log(`Function(${func.name}) is executing.`);\n return;\n }\n singleExecutionFn.isExecuting = true;\n\n let result: ReturnType<T>;\n\n try {\n result = func(...args);\n if ((result as any) instanceof Promise) {\n result.finally(() => {\n singleExecutionFn.isExecuting = false;\n });\n } else {\n singleExecutionFn.isExecuting = false;\n }\n } catch (error) {\n singleExecutionFn.isExecuting = false;\n throw error;\n }\n\n return result;\n } as SingleExecutionFunction<T>;\n\n singleExecutionFn.isExecuting = false;\n\n return singleExecutionFn;\n}\n"],"names":["isCloneable","obj","clone","isPrimitive","value","type","generateStableUniqueKey","params","String","JSON","stringify","_key","Array","isArray","Object","keys","sort","reduce","pre","cur","cloneDeep","map","item","newObj","key","prototype","hasOwnProperty","call","cache","getCachedData","apiKey","defalutSetting","timeout","timeoutResult","code","msg","identifier","setStyle","element","property","important","style","priority","setProperty","createSvgElement","attributes","children","el","document","createElementNS","tag","_i3","_Object$entries3","entries","length","_Object$entries3$_i","setAttribute","textContent","forEach","child","appendChild","scrollToBottom","dom","setTimeout","scrollTop","scrollHeight","func","setting","args","slice","arguments","name","Promise","resolve","apiLoadingKey","_setting","assign","startTime","Date","now","timer","setInterval","clearInterval","apply","then","res","error","createElement","_temp","_ref","_ref$tag","_ref$children","_ref$props","props","_ref$attrs","attrs","_ref$styles","styles","ele","_i","_Object$entries","_Object$entries$_i","_i2","_Object$entries2","_Object$entries2$_i","_step","_iterator","_createForOfIteratorHelperLoose","done","HTMLElement","Text","createTextNode","elements","options","_ref2","_ref2$width","width","_ref2$height","height","svg","toString","innerHTML","wait","_arguments","context","this","clearTimeout","callback","delay","globalThis","self","window","global","dataset","isListeningForUserScroll","addEventListener","inter","userInteracted","userInteractedWithScroll","clientHeight","listenForUserScroll","singleExecutionFn","isExecuting","result","console","log","lastExecutedTime","currentTime"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/common/type.ts","../src/common/generateStableUniqueKey.ts","../src/common/cloneDeep.ts","../src/common/cacheWrapper.ts","../src/browser/dom.ts","../src/browser/scroll.ts","../src/common/utils.ts","../src/common/getGlobal.ts","../src/common/singleExecutionWrapper.ts"],"sourcesContent":["/**\n * 异步函数类型。\n *\n * @template Args - 表示函数参数的类型数组。\n * @template T - 表示函数返回的 Promise 解析后的类型。\n *\n * @param args - 函数的参数。\n * @returns 一个 Promise 对象,解析后的值类型为 T。\n */\nexport type AsyncFunction<Args extends any[], T> = (\n ...args: Args\n) => Promise<T>;\n\n/**\n * 表示一个可以克隆自身的对象接口。\n *\n * @interface Cloneable\n */\nexport interface Cloneable {\n /**\n * 创建并返回当前对象的一个副本。\n *\n * @returns {this} 当前对象的一个副本。\n */\n clone(): this;\n}\n\n/**\n *\n * 检查一个对象是否实现了 Cloneable 接口。\n *\n * 这个函数是一个类型保护函数,它会在类型检查时将传入的对象类型缩小为 Cloneable。\n *\n * @param {any} obj - 要检查的对象。\n * @returns {obj is Cloneable} 如果对象实现了 Cloneable 接口,则返回 true;否则返回 false。\n */\nexport function isCloneable(obj: any): obj is Cloneable {\n return typeof obj?.clone === \"function\";\n}\n\n/**\n * 检查一个值是否是原始类型(primitive type)。\n *\n * 这个函数是一个类型保护函数,它会在类型检查时将传入的值类型缩小为原始类型之一:string, number, boolean, null 或 undefined。\n *\n * @param {any} value - 要检查的值。\n * @returns {value is string | number | boolean | null | undefined} 如果值是原始类型,则返回 true;否则返回 false。\n */\nexport function isPrimitive(\n value: any\n): value is string | number | boolean | null | undefined {\n const type = typeof value;\n return (\n value === null ||\n type === \"string\" ||\n type === \"number\" ||\n type === \"boolean\" ||\n type === \"undefined\"\n );\n}\n","import { isPrimitive } from \"./type\";\n\n/**\n * 为给定的参数生成一个稳定且唯一的键。\n *\n * 该函数确保生成的键是确定性的,即相同的输入总是会生成相同的输出。\n * 这在缓存、记忆化或任何需要一致键的场景中非常有用。\n *\n * @param params - 用于生成键的参数。可以是任何类型。\n * @returns 表示输入参数的稳定且唯一的字符串键。\n */\nexport function generateStableUniqueKey(params: any) {\n if (isPrimitive(params)) {\n return String(params);\n }\n return JSON.stringify(params, function (_key: string | number, value: any) {\n if (typeof value === \"object\" && value !== null && !Array.isArray(value)) {\n return Object.keys(value)\n .sort()\n .reduce((pre: any, cur: string) => {\n pre[cur] = value[cur];\n return pre;\n }, {});\n }\n return value;\n });\n}\n","import { isCloneable } from \"./type\";\n\n/**\n * 深度克隆一个对象或数组。\n *\n * @param {T} obj - 要克隆的对象或数组。\n * @returns {T} 克隆后的对象或数组。\n */\nexport function cloneDeep<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n\n if (isCloneable(obj)) {\n return obj.clone();\n }\n\n // 处理数组\n if (Array.isArray(obj)) {\n return obj.map((item) => cloneDeep(item)) as unknown as T;\n }\n\n const newObj: { [key: string]: any } = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n newObj[key] = cloneDeep(obj[key]);\n }\n }\n return newObj as T;\n}\n","import { generateStableUniqueKey } from \"./generateStableUniqueKey\";\nimport { cloneDeep } from \"./cloneDeep\";\nimport { AsyncFunction } from \"./type\";\n\nconst cache: Record<string, any> = {};\nfunction getCachedData<T = any>(apiKey: string) {\n return cache[apiKey] as T;\n}\n\nexport interface Setting {\n timeout?: number;\n timeoutResult?: any;\n identifier?: string;\n}\n\nconst defalutSetting: Setting = {\n timeout: 60000,\n timeoutResult: { code: 408, msg: \"请求超时\" },\n identifier: \"\",\n};\n\n/**\n * 为异步函数添加缓存功能。\n *\n * 该函数根据函数参数、函数名和一个可选的标识符来缓存异步函数的结果。\n * 如果结果已经缓存,则返回缓存的结果。如果函数正在执行中,则等待结果返回,并使用一个超时机制防止无限等待。\n *\n * @template Args - 函数参数的类型。\n * @template Promise<T> - 函数返回值的类型。\n * @param {AsyncFunction<Args, T>} func - 需要包装的异步函数。\n * @param {Setting} [setting=defalutSetting] - 可选的缓存设置。\n * @returns {AsyncFunction<Args, T>} - 带有缓存功能的包装函数,返回类型为 `Promise<T>`。\n */\nexport function cacheWrapper<Args extends any[], T>(\n func: AsyncFunction<Args, T>,\n setting: Setting = defalutSetting\n): AsyncFunction<Args, T> {\n return function (...args: Args): Promise<T> {\n const apiKey: string =\n generateStableUniqueKey(args) + func.name + (setting.identifier || \"\"); //缓存key\n\n if (cache[apiKey]) {\n return Promise.resolve(cloneDeep(getCachedData<T>(apiKey)));\n }\n\n const apiLoadingKey: string = apiKey + \"_l_o_a_d_i_n_g_\"; //缓存loading key\n\n if (cache[apiLoadingKey]) {\n const _setting = Object.assign({}, defalutSetting, setting);\n return new Promise((resolve) => {\n const startTime = Date.now();\n const timer = setInterval(() => {\n if (cache[apiKey]) {\n clearInterval(timer);\n resolve(cloneDeep(getCachedData<T>(apiKey)));\n } else if (Date.now() - startTime > _setting.timeout!) {\n cache[apiLoadingKey] = false;\n clearInterval(timer);\n resolve(cloneDeep(_setting.timeoutResult));\n }\n }, 100);\n });\n }\n cache[apiLoadingKey] = true;\n\n return func(...args)\n .then((res) => {\n // 缓存原始数据或其克隆,避免数据被释放\n cache[apiKey] = res;\n return cloneDeep(cache[apiKey]);\n })\n .catch((error: any) => {\n throw error;\n })\n .finally(() => {\n cache[apiLoadingKey] = false;\n });\n };\n}\n","/**\n * 表示 DOM 中可能的子元素类型。\n */\nexport type ChildrenType =\n | DomOptionsType\n | Element\n | string;\n\n/**\n * 表示创建 DOM 元素的选项类型。\n */\nexport type DomOptionsType = {\n /**\n * 要创建的元素的标签名。默认为 \"div\"。\n */\n tag?: string;\n\n /**\n * 要附加到创建的元素的子元素。可以是单个子元素或子元素数组。\n */\n children?: ChildrenType | ChildrenType[];\n\n /**\n * 要设置在创建的元素上的属性。\n */\n props?: Record<string, any>;\n\n /**\n * 要设置在创建的元素上的属性。\n */\n attrs?: Record<string, string | boolean>;\n\n /**\n * 要应用于创建的元素的样式。\n */\n styles?: Record<string, string | number>;\n};\n\n/**\n * 设置 HTML 元素的样式属性。\n *\n * @param element - 要设置样式的 HTML 元素。\n * @param property - CSS 属性名,可以是驼峰命名法(camelCase)或连字符命名法(kebab-case)。\n * @param value - 要设置的属性值。\n * @param important - 可选参数,布尔值,表示是否将属性设置为 `important` 优先级,默认为 `false`。\n */\nfunction setStyle(\n element: HTMLElement | SVGElement,\n property: string,\n value: string | number,\n important: boolean = false\n): void {\n if (property in element.style) {\n (element.style as any)[property] = value;\n } else {\n const priority = important ? \"important\" : \"\";\n element.style.setProperty(property, String(value), priority);\n }\n}\n\n/**\n * 使用指定选项创建一个 DOM 元素。\n *\n * @param options - 创建 DOM 元素的选项。\n *\n * @returns 创建的 DOM 元素。\n *\n * @remarks\n * 此函数旨在浏览器环境中使用。\n *\n * @example\n * ```typescript\n * const element = createElement({\n * tag: 'button',\n * children: '点击我',\n * attrs: { id: 'myButton' },\n * styles: { color: 'red' }\n * });\n * document.body.appendChild(element);\n * ```\n */\nexport function createElement({\n tag = \"div\",\n children = [],\n props = {},\n attrs = {},\n styles = {},\n}: DomOptionsType = {}): Element {\n const ele = document.createElement(tag);\n\n // 设置属性\n Object.assign(ele, props);\n\n // 设置属性\n for (const [key, value] of Object.entries(attrs)) {\n if (value !== false) {\n ele.setAttribute(key, value as string);\n }\n }\n\n // 设置样式\n for (const [key, value] of Object.entries(styles)) {\n setStyle(ele, key, value);\n }\n\n // 处理子元素\n const childArray = Array.isArray(children) ? children : [children];\n for (const child of childArray) {\n if (!child) continue;\n\n if (typeof child === \"object\") {\n if (child instanceof Element) {\n ele.appendChild(child);\n } else {\n ele.appendChild(createElement(child as DomOptionsType));\n }\n } else {\n ele.appendChild(document.createTextNode(child));\n }\n }\n\n return ele;\n}\n\ntype SvgElement = {\n tag: string;\n attributes?: Record<string, string>;\n children?: SvgElement | SvgElement[] | string;\n};\n\ntype SvgOptions = {\n width?: number;\n height?: number;\n};\n\n/**\n * 创建一个 SVG 元素。\n *\n * @param {SvgElement[] | SvgElement | string} elements - 要创建的 SVG 元素,可以是对象数组、单个对象或 innerHTML 字符串。\n * @param {SvgOptions} [options] - SVG 的配置选项,包括宽度和高度。\n * @returns {SVGElement} - 创建的 SVG 元素。\n *\n * @example\n * // 使用嵌套对象\n * const svg1 = createSvg(\n * {\n * tag: 'svg',\n * children: [\n * { tag: 'circle', attributes: { cx: '16', cy: '16', r: '10', fill: 'red' } },\n * { tag: 'g', children:\n * { tag: 'text', attributes: { x: '10', y: '20', fill: 'black' }, children: 'Hello' }\n * }\n * ]\n * },\n * { width: 64, height: 64 }\n * );\n * document.body.appendChild(svg1);\n *\n * @example\n * // 使用 innerHTML\n * const svg2 = createSvg(\n * `<circle cx=\"16\" cy=\"16\" r=\"10\" fill=\"red\"></circle>\n * <text x=\"10\" y=\"20\" fill=\"black\">Hello</text>`\n * );\n * document.body.appendChild(svg2);\n */\nexport function createSvg(\n elements: SvgElement[] | SvgElement | string,\n options?: SvgOptions\n) {\n // 默认宽度和高度\n const { width = 32, height = 32 } = options || {};\n\n // 创建一个 SVG 元素\n const svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n\n // 设置 SVG 的宽度和高度\n svg.setAttribute(\"width\", width.toString());\n svg.setAttribute(\"height\", height.toString());\n svg.setAttribute(\"viewBox\", `0 0 ${width} ${height}`);\n\n if (typeof elements === \"string\") {\n // 如果 elements 是字符串,直接设置为 SVG 的 innerHTML\n svg.innerHTML = elements;\n } else {\n // 处理 SvgElement 或 SvgElement[]\n const elementArray = Array.isArray(elements) ? elements : [elements];\n\n elementArray.forEach((element) => {\n svg.appendChild(createSvgElement(element));\n });\n }\n\n // 返回创建好的 SVG 元素\n return svg;\n}\n\n/**\n * 递归创建 SVG 子元素。\n *\n * @param {SvgElement} element - 要创建的 SVG 子元素。\n * @returns {SVGElement} - 创建的 SVG 子元素。\n */\nfunction createSvgElement(element: SvgElement) {\n const { tag, attributes, children } = element;\n const el = document.createElementNS(\"http://www.w3.org/2000/svg\", tag);\n\n if (attributes) {\n for (const [key, value] of Object.entries(attributes)) {\n el.setAttribute(key, value);\n }\n }\n\n if (typeof children === \"string\") {\n el.textContent = children;\n } else if (children) {\n const childArray = Array.isArray(children) ? children : [children];\n childArray.forEach((child) => {\n el.appendChild(createSvgElement(child));\n });\n }\n\n return el;\n}\n","/**\n * 将指定的 DOM 元素滚动到底部。\n * 使用 setTimeout 确保在当前调用栈之后执行。\n *\n * @param {HTMLElement} dom - 要滚动的 DOM 元素。\n */\nexport function scrollToBottom(dom: HTMLElement) {\n if (dom) {\n setTimeout(() => {\n // 设置滚动条位置为元素的最大滚动高度,滚动到底部\n dom.scrollTop = dom.scrollHeight;\n }, 0);\n }\n}\n\n/**\n * 如果用户未与 DOM 元素交互,则将其滚动到底部。\n * 如果尚未设置事件监听器,则设置一个以跟踪用户滚动交互。\n *\n * @param {HTMLElement} dom - 可能需要滚动的 DOM 元素。\n */\nexport function scrollToBottomIfNeeded(dom: HTMLElement): void {\n if (!dom) {\n return;\n }\n // 检查是否已设置滚动监听器\n if (dom.dataset.isListeningForUserScroll !== \"true\") {\n listenForUserScroll(dom);\n dom.dataset.isListeningForUserScroll = \"true\";\n }\n\n // 如果用户未与滚动条交互,则滚动到底部\n if (dom.dataset.userInteracted !== \"true\") {\n scrollToBottom(dom);\n }\n}\n\n/**\n * 更新用户是否与滚动条交互的状态。\n *\n * @param {HTMLElement} dom - 要更新状态的 DOM 元素。\n * @param {boolean} inter - 用户是否与滚动条交互。\n */\nfunction userInteractedWithScroll(dom: HTMLElement, inter: boolean): void {\n // 根据用户交互状态更新数据属性\n dom.dataset.userInteracted = inter ? \"true\" : \"false\";\n}\n\n/**\n * 为 DOM 元素设置滚动事件监听器。\n * 当用户滚动时,更新交互状态。\n *\n * @param {HTMLElement} dom - 要监听滚动事件的 DOM 元素。\n */\nfunction listenForUserScroll(dom: HTMLElement): void {\n if (!dom) {\n return;\n }\n dom.addEventListener(\"scroll\", () => {\n // 检查用户是否滚动到接近底部\n if (dom.scrollTop + dom.clientHeight < dom.scrollHeight - 5) {\n // 用户已滚动,更新交互状态\n userInteractedWithScroll(dom, true);\n } else {\n // 用户未滚动到接近底部\n userInteractedWithScroll(dom, false);\n }\n });\n}\n","/**\n * 创建一个防抖函数,该函数会在最后一次调用后的指定时间间隔后执行。\n *\n * @param func - 需要防抖处理的函数。\n * @param wait - 延迟的毫秒数。\n * @returns 一个新的防抖函数。\n */\nexport function debounce<T extends (...args: any[]) => void>(\n func: T,\n wait: number\n): T {\n let timeout: ReturnType<typeof setTimeout> | null = null;\n\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n const context = this;\n\n // 如果已经设定了调用,取消之前的调用\n if (timeout !== null) {\n clearTimeout(timeout);\n }\n\n // 设定一个新的调用,等待指定的时间后执行\n timeout = setTimeout(() => {\n func.apply(context, args);\n timeout = null; // 确保能够在下次触发时重新设定定时器\n }, wait);\n } as T;\n}\n\n/**\n * 创建一个节流函数,该函数会在每个指定的时间间隔内最多执行一次。\n *\n * @param func - 需要节流处理的函数。\n * @param delay - 时间间隔的毫秒数。\n * @returns 一个新的节流函数。\n */\nexport function throttle<T extends (...agrs: any[]) => any>(\n func: T,\n delay: number\n): T {\n let lastExecutedTime: number = 0;\n\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n const context = this;\n const currentTime = Date.now();\n\n if (currentTime - lastExecutedTime >= delay) {\n func.apply(context, args);\n lastExecutedTime = currentTime;\n }\n } as T;\n}\n\n/**\n * 创建一个延迟执行回调函数并返回 Promise 的函数。\n *\n * @param callback - 需要执行的回调函数。\n * @param delay - 延迟的毫秒数,默认为 0。\n * @returns 一个 Promise 对象,该对象在回调函数执行后解析。\n */\nexport function delayExecution<T>(\n callback: () => T,\n delay: number = 0\n): Promise<T> {\n return new Promise<T>((resolve) => {\n if (delay === 0) {\n resolve(callback());\n } else {\n setTimeout(() => {\n resolve(callback());\n }, delay);\n }\n });\n}\n","declare var global: typeof globalThis;\n\n/**\n * 获取当前环境的全局对象。\n *\n * 在不同的 JavaScript 运行环境中,全局对象的名称不同:\n * - 在浏览器环境中,全局对象是 `window`。\n * - 在 Node.js 环境中,全局对象是 `global`。\n * - 在 Web Worker 环境中,全局对象是 `self`。\n *\n * 这个函数提供了一种统一的方式来获取当前环境的全局对象。\n *\n * @returns 当前环境的全局对象。\n */\nexport function getGlobal(this: any) {\n if (typeof globalThis !== \"undefined\") {\n return globalThis;\n }\n\n if (typeof self !== \"undefined\") {\n return self;\n }\n\n if (typeof window !== \"undefined\") {\n return window;\n }\n\n if (typeof global !== \"undefined\") {\n return global;\n }\n\n // 如果以上都不符合,则返回 this\n return this;\n}\n","/**\n * 定义一个类型,用于扩展函数类型,增加一个可选的 isExecuting 属性\n */\nexport type SingleExecutionFunction<T extends (...args: any[]) => any> = T & {\n isExecuting?: boolean;\n};\n\n/**\n * 创建一个有执行状态的函数,该函数在前一次调用未完成时不会被再次调用。\n *\n * @param func - 需要包裹的函数。\n * @returns 一个增强版的函数,该函数具有 isExecuting 属性。\n */\nexport function singleExecutionWrapper<T extends (...args: any[]) => any>(\n func: T\n): SingleExecutionFunction<T> {\n const singleExecutionFn: SingleExecutionFunction<T> = function (\n ...args: Parameters<T>\n ): ReturnType<T> | undefined {\n if (singleExecutionFn.isExecuting) {\n console.log(`Function(${func.name}) is executing.`);\n return;\n }\n singleExecutionFn.isExecuting = true;\n\n let result: ReturnType<T>;\n\n try {\n result = func(...args);\n if ((result as any) instanceof Promise) {\n result.finally(() => {\n singleExecutionFn.isExecuting = false;\n });\n } else {\n singleExecutionFn.isExecuting = false;\n }\n } catch (error) {\n singleExecutionFn.isExecuting = false;\n throw error;\n }\n\n return result;\n } as SingleExecutionFunction<T>;\n\n singleExecutionFn.isExecuting = false;\n\n return singleExecutionFn;\n}\n"],"names":["isCloneable","obj","clone","isPrimitive","value","type","generateStableUniqueKey","params","String","JSON","stringify","_key","Array","isArray","Object","keys","sort","reduce","pre","cur","cloneDeep","map","item","newObj","key","prototype","hasOwnProperty","call","cache","getCachedData","apiKey","defalutSetting","timeout","timeoutResult","code","msg","identifier","setStyle","element","property","important","style","priority","setProperty","createSvgElement","attributes","children","el","document","createElementNS","tag","_i3","_Object$entries3","entries","length","_Object$entries3$_i","setAttribute","textContent","forEach","child","appendChild","scrollToBottom","dom","setTimeout","scrollTop","scrollHeight","func","setting","args","slice","arguments","name","Promise","resolve","apiLoadingKey","_setting","assign","startTime","Date","now","timer","setInterval","clearInterval","apply","then","res","error","createElement","_temp","_ref","_ref$tag","_ref$children","_ref$props","props","_ref$attrs","attrs","_ref$styles","styles","ele","_i","_Object$entries","_Object$entries$_i","_i2","_Object$entries2","_Object$entries2$_i","_step","_iterator","_createForOfIteratorHelperLoose","done","Element","createTextNode","elements","options","_ref2","_ref2$width","width","_ref2$height","height","svg","toString","innerHTML","wait","_arguments","context","this","clearTimeout","callback","delay","globalThis","self","window","global","dataset","isListeningForUserScroll","addEventListener","inter","userInteracted","userInteractedWithScroll","clientHeight","listenForUserScroll","singleExecutionFn","isExecuting","result","console","log","lastExecutedTime","currentTime"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- function t(t){return"function"==typeof(null==t?void 0:t.clone)}function e(t){const e=typeof t;return null===t||"string"===e||"number"===e||"boolean"===e||"undefined"===e}function n(){return"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:this}function r(t){return e(t)?String(t):JSON.stringify(t,function(t,e){return"object"!=typeof e||null===e||Array.isArray(e)?e:Object.keys(e).sort().reduce((t,n)=>(t[n]=e[n],t),{})})}function o(e){if(null===e||"object"!=typeof e)return e;if(t(e))return e.clone();if(Array.isArray(e))return e.map(t=>o(t));const n={};for(const t in e)Object.prototype.hasOwnProperty.call(e,t)&&(n[t]=o(e[t]));return n}function i(t,e){let n=null;return function(...r){const o=this;null!==n&&clearTimeout(n),n=setTimeout(()=>{t.apply(o,r),n=null},e)}}function s(t,e){let n=0;return function(...r){const o=Date.now();o-n>=e&&(t.apply(this,r),n=o)}}function c(t,e=0){return new Promise(n=>{0===e?n(t()):setTimeout(()=>{n(t())},e)})}const u={};function l(t){return u[t]}const f={timeout:6e4,timeoutResult:{code:408,msg:"请求超时"},identifier:""};function a(t,e=f){return function(...n){const i=r(n)+t.name+(e.identifier||"");if(u[i])return Promise.resolve(o(l(i)));const s=i+"_l_o_a_d_i_n_g_";if(u[s]){const t=Object.assign({},f,e);return new Promise(e=>{const n=Date.now(),r=setInterval(()=>{u[i]?(clearInterval(r),e(o(l(i)))):Date.now()-n>t.timeout&&(u[s]=!1,clearInterval(r),e(o(t.timeoutResult)))},100)})}return u[s]=!0,t(...n).then(t=>(u[i]=t,o(u[i]))).catch(t=>{throw t}).finally(()=>{u[s]=!1})}}function d(t){const e=function e(...n){if(e.isExecuting)return void console.log(`Function(${t.name}) is executing.`);let r;e.isExecuting=!0;try{r=t(...n),r instanceof Promise?r.finally(()=>{e.isExecuting=!1}):e.isExecuting=!1}catch(t){throw e.isExecuting=!1,t}return r};return e.isExecuting=!1,e}function g(t,e,n,r=!1){if(e in t.style)t.style[e]=n;else{const o=r?"important":"";t.style.setProperty(e,String(n),o)}}function p({tag:t="div",children:e=[],props:n={},attrs:r={},styles:o={}}={}){const i=document.createElement(t);Object.assign(i,n);for(const[t,e]of Object.entries(r))!1!==e&&i.setAttribute(t,e);for(const[t,e]of Object.entries(o))g(i,t,e);const s=Array.isArray(e)?e:[e];for(const t of s)t&&("object"==typeof t?t instanceof HTMLElement||t instanceof Text?i.appendChild(t):i.appendChild(p(t)):i.appendChild(document.createTextNode(t)));return i}function y(t,e){const{width:n=32,height:r=32}=e||{},o=document.createElementNS("http://www.w3.org/2000/svg","svg");return o.setAttribute("width",n.toString()),o.setAttribute("height",r.toString()),o.setAttribute("viewBox",`0 0 ${n} ${r}`),"string"==typeof t?o.innerHTML=t:(Array.isArray(t)?t:[t]).forEach(t=>{o.appendChild(h(t))}),o}function h(t){const{tag:e,attributes:n,children:r}=t,o=document.createElementNS("http://www.w3.org/2000/svg",e);if(n)for(const[t,e]of Object.entries(n))o.setAttribute(t,e);return"string"==typeof r?o.textContent=r:r&&(Array.isArray(r)?r:[r]).forEach(t=>{o.appendChild(h(t))}),o}function m(t){t&&setTimeout(()=>{t.scrollTop=t.scrollHeight},0)}function w(t){t&&("true"!==t.dataset.isListeningForUserScroll&&(function(t){t&&t.addEventListener("scroll",()=>{!function(t,e){t.dataset.userInteracted=e?"true":"false"}(t,t.scrollTop+t.clientHeight<t.scrollHeight-5)})}(t),t.dataset.isListeningForUserScroll="true"),"true"!==t.dataset.userInteracted&&m(t))}export{a as cacheWrapper,o as cloneDeep,p as createElement,y as createSvg,i as debounce,c as delayExecution,r as generateStableUniqueKey,n as getGlobal,t as isCloneable,e as isPrimitive,m as scrollToBottom,w as scrollToBottomIfNeeded,d as singleExecutionWrapper,s as throttle};
1
+ function t(t){return"function"==typeof(null==t?void 0:t.clone)}function e(t){const e=typeof t;return null===t||"string"===e||"number"===e||"boolean"===e||"undefined"===e}function n(){return"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:this}function r(t){return e(t)?String(t):JSON.stringify(t,function(t,e){return"object"!=typeof e||null===e||Array.isArray(e)?e:Object.keys(e).sort().reduce((t,n)=>(t[n]=e[n],t),{})})}function o(e){if(null===e||"object"!=typeof e)return e;if(t(e))return e.clone();if(Array.isArray(e))return e.map(t=>o(t));const n={};for(const t in e)Object.prototype.hasOwnProperty.call(e,t)&&(n[t]=o(e[t]));return n}function i(t,e){let n=null;return function(...r){const o=this;null!==n&&clearTimeout(n),n=setTimeout(()=>{t.apply(o,r),n=null},e)}}function s(t,e){let n=0;return function(...r){const o=Date.now();o-n>=e&&(t.apply(this,r),n=o)}}function c(t,e=0){return new Promise(n=>{0===e?n(t()):setTimeout(()=>{n(t())},e)})}const u={};function l(t){return u[t]}const f={timeout:6e4,timeoutResult:{code:408,msg:"请求超时"},identifier:""};function a(t,e=f){return function(...n){const i=r(n)+t.name+(e.identifier||"");if(u[i])return Promise.resolve(o(l(i)));const s=i+"_l_o_a_d_i_n_g_";if(u[s]){const t=Object.assign({},f,e);return new Promise(e=>{const n=Date.now(),r=setInterval(()=>{u[i]?(clearInterval(r),e(o(l(i)))):Date.now()-n>t.timeout&&(u[s]=!1,clearInterval(r),e(o(t.timeoutResult)))},100)})}return u[s]=!0,t(...n).then(t=>(u[i]=t,o(u[i]))).catch(t=>{throw t}).finally(()=>{u[s]=!1})}}function d(t){const e=function e(...n){if(e.isExecuting)return void console.log(`Function(${t.name}) is executing.`);let r;e.isExecuting=!0;try{r=t(...n),r instanceof Promise?r.finally(()=>{e.isExecuting=!1}):e.isExecuting=!1}catch(t){throw e.isExecuting=!1,t}return r};return e.isExecuting=!1,e}function g(t,e,n,r=!1){if(e in t.style)t.style[e]=n;else{const o=r?"important":"";t.style.setProperty(e,String(n),o)}}function p({tag:t="div",children:e=[],props:n={},attrs:r={},styles:o={}}={}){const i=document.createElement(t);Object.assign(i,n);for(const[t,e]of Object.entries(r))!1!==e&&i.setAttribute(t,e);for(const[t,e]of Object.entries(o))g(i,t,e);const s=Array.isArray(e)?e:[e];for(const t of s)t&&("object"==typeof t?t instanceof Element?i.appendChild(t):i.appendChild(p(t)):i.appendChild(document.createTextNode(t)));return i}function y(t,e){const{width:n=32,height:r=32}=e||{},o=document.createElementNS("http://www.w3.org/2000/svg","svg");return o.setAttribute("width",n.toString()),o.setAttribute("height",r.toString()),o.setAttribute("viewBox",`0 0 ${n} ${r}`),"string"==typeof t?o.innerHTML=t:(Array.isArray(t)?t:[t]).forEach(t=>{o.appendChild(h(t))}),o}function h(t){const{tag:e,attributes:n,children:r}=t,o=document.createElementNS("http://www.w3.org/2000/svg",e);if(n)for(const[t,e]of Object.entries(n))o.setAttribute(t,e);return"string"==typeof r?o.textContent=r:r&&(Array.isArray(r)?r:[r]).forEach(t=>{o.appendChild(h(t))}),o}function m(t){t&&setTimeout(()=>{t.scrollTop=t.scrollHeight},0)}function w(t){t&&("true"!==t.dataset.isListeningForUserScroll&&(function(t){t&&t.addEventListener("scroll",()=>{!function(t,e){t.dataset.userInteracted=e?"true":"false"}(t,t.scrollTop+t.clientHeight<t.scrollHeight-5)})}(t),t.dataset.isListeningForUserScroll="true"),"true"!==t.dataset.userInteracted&&m(t))}export{a as cacheWrapper,o as cloneDeep,p as createElement,y as createSvg,i as debounce,c as delayExecution,r as generateStableUniqueKey,n as getGlobal,t as isCloneable,e as isPrimitive,m as scrollToBottom,w as scrollToBottomIfNeeded,d as singleExecutionWrapper,s as throttle};
2
2
  //# sourceMappingURL=index.modern.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.modern.js","sources":["../src/common/type.ts","../src/common/getGlobal.ts","../src/common/generateStableUniqueKey.ts","../src/common/cloneDeep.ts","../src/common/utils.ts","../src/common/cacheWrapper.ts","../src/common/singleExecutionWrapper.ts","../src/browser/dom.ts","../src/browser/scroll.ts"],"sourcesContent":["/**\n * 异步函数类型。\n *\n * @template Args - 表示函数参数的类型数组。\n * @template T - 表示函数返回的 Promise 解析后的类型。\n *\n * @param args - 函数的参数。\n * @returns 一个 Promise 对象,解析后的值类型为 T。\n */\nexport type AsyncFunction<Args extends any[], T> = (\n ...args: Args\n) => Promise<T>;\n\n/**\n * 表示一个可以克隆自身的对象接口。\n *\n * @interface Cloneable\n */\nexport interface Cloneable {\n /**\n * 创建并返回当前对象的一个副本。\n *\n * @returns {this} 当前对象的一个副本。\n */\n clone(): this;\n}\n\n/**\n *\n * 检查一个对象是否实现了 Cloneable 接口。\n *\n * 这个函数是一个类型保护函数,它会在类型检查时将传入的对象类型缩小为 Cloneable。\n *\n * @param {any} obj - 要检查的对象。\n * @returns {obj is Cloneable} 如果对象实现了 Cloneable 接口,则返回 true;否则返回 false。\n */\nexport function isCloneable(obj: any): obj is Cloneable {\n return typeof obj?.clone === \"function\";\n}\n\n/**\n * 检查一个值是否是原始类型(primitive type)。\n *\n * 这个函数是一个类型保护函数,它会在类型检查时将传入的值类型缩小为原始类型之一:string, number, boolean, null 或 undefined。\n *\n * @param {any} value - 要检查的值。\n * @returns {value is string | number | boolean | null | undefined} 如果值是原始类型,则返回 true;否则返回 false。\n */\nexport function isPrimitive(\n value: any\n): value is string | number | boolean | null | undefined {\n const type = typeof value;\n return (\n value === null ||\n type === \"string\" ||\n type === \"number\" ||\n type === \"boolean\" ||\n type === \"undefined\"\n );\n}\n","declare var global: typeof globalThis;\n\n/**\n * 获取当前环境的全局对象。\n *\n * 在不同的 JavaScript 运行环境中,全局对象的名称不同:\n * - 在浏览器环境中,全局对象是 `window`。\n * - 在 Node.js 环境中,全局对象是 `global`。\n * - 在 Web Worker 环境中,全局对象是 `self`。\n *\n * 这个函数提供了一种统一的方式来获取当前环境的全局对象。\n *\n * @returns 当前环境的全局对象。\n */\nexport function getGlobal(this: any) {\n if (typeof globalThis !== \"undefined\") {\n return globalThis;\n }\n\n if (typeof self !== \"undefined\") {\n return self;\n }\n\n if (typeof window !== \"undefined\") {\n return window;\n }\n\n if (typeof global !== \"undefined\") {\n return global;\n }\n\n // 如果以上都不符合,则返回 this\n return this;\n}\n","import { isPrimitive } from \"./type\";\n\n/**\n * 为给定的参数生成一个稳定且唯一的键。\n *\n * 该函数确保生成的键是确定性的,即相同的输入总是会生成相同的输出。\n * 这在缓存、记忆化或任何需要一致键的场景中非常有用。\n *\n * @param params - 用于生成键的参数。可以是任何类型。\n * @returns 表示输入参数的稳定且唯一的字符串键。\n */\nexport function generateStableUniqueKey(params: any) {\n if (isPrimitive(params)) {\n return String(params);\n }\n return JSON.stringify(params, function (_key: string | number, value: any) {\n if (typeof value === \"object\" && value !== null && !Array.isArray(value)) {\n return Object.keys(value)\n .sort()\n .reduce((pre: any, cur: string) => {\n pre[cur] = value[cur];\n return pre;\n }, {});\n }\n return value;\n });\n}\n","import { isCloneable } from \"./type\";\n\n/**\n * 深度克隆一个对象或数组。\n *\n * @param {T} obj - 要克隆的对象或数组。\n * @returns {T} 克隆后的对象或数组。\n */\nexport function cloneDeep<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n\n if (isCloneable(obj)) {\n return obj.clone();\n }\n\n // 处理数组\n if (Array.isArray(obj)) {\n return obj.map((item) => cloneDeep(item)) as unknown as T;\n }\n\n const newObj: { [key: string]: any } = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n newObj[key] = cloneDeep(obj[key]);\n }\n }\n return newObj as T;\n}\n","/**\n * 创建一个防抖函数,该函数会在最后一次调用后的指定时间间隔后执行。\n *\n * @param func - 需要防抖处理的函数。\n * @param wait - 延迟的毫秒数。\n * @returns 一个新的防抖函数。\n */\nexport function debounce<T extends (...args: any[]) => void>(\n func: T,\n wait: number\n): T {\n let timeout: ReturnType<typeof setTimeout> | null = null;\n\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n const context = this;\n\n // 如果已经设定了调用,取消之前的调用\n if (timeout !== null) {\n clearTimeout(timeout);\n }\n\n // 设定一个新的调用,等待指定的时间后执行\n timeout = setTimeout(() => {\n func.apply(context, args);\n timeout = null; // 确保能够在下次触发时重新设定定时器\n }, wait);\n } as T;\n}\n\n/**\n * 创建一个节流函数,该函数会在每个指定的时间间隔内最多执行一次。\n *\n * @param func - 需要节流处理的函数。\n * @param delay - 时间间隔的毫秒数。\n * @returns 一个新的节流函数。\n */\nexport function throttle<T extends (...agrs: any[]) => any>(\n func: T,\n delay: number\n): T {\n let lastExecutedTime: number = 0;\n\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n const context = this;\n const currentTime = Date.now();\n\n if (currentTime - lastExecutedTime >= delay) {\n func.apply(context, args);\n lastExecutedTime = currentTime;\n }\n } as T;\n}\n\n/**\n * 创建一个延迟执行回调函数并返回 Promise 的函数。\n *\n * @param callback - 需要执行的回调函数。\n * @param delay - 延迟的毫秒数,默认为 0。\n * @returns 一个 Promise 对象,该对象在回调函数执行后解析。\n */\nexport function delayExecution<T>(\n callback: () => T,\n delay: number = 0\n): Promise<T> {\n return new Promise<T>((resolve) => {\n if (delay === 0) {\n resolve(callback());\n } else {\n setTimeout(() => {\n resolve(callback());\n }, delay);\n }\n });\n}\n","import { generateStableUniqueKey } from \"./generateStableUniqueKey\";\nimport { cloneDeep } from \"./cloneDeep\";\nimport { AsyncFunction } from \"./type\";\n\nconst cache: Record<string, any> = {};\nfunction getCachedData<T = any>(apiKey: string) {\n return cache[apiKey] as T;\n}\n\nexport interface Setting {\n timeout?: number;\n timeoutResult?: any;\n identifier?: string;\n}\n\nconst defalutSetting: Setting = {\n timeout: 60000,\n timeoutResult: { code: 408, msg: \"请求超时\" },\n identifier: \"\",\n};\n\n/**\n * 为异步函数添加缓存功能。\n *\n * 该函数根据函数参数、函数名和一个可选的标识符来缓存异步函数的结果。\n * 如果结果已经缓存,则返回缓存的结果。如果函数正在执行中,则等待结果返回,并使用一个超时机制防止无限等待。\n *\n * @template Args - 函数参数的类型。\n * @template Promise<T> - 函数返回值的类型。\n * @param {AsyncFunction<Args, T>} func - 需要包装的异步函数。\n * @param {Setting} [setting=defalutSetting] - 可选的缓存设置。\n * @returns {AsyncFunction<Args, T>} - 带有缓存功能的包装函数,返回类型为 `Promise<T>`。\n */\nexport function cacheWrapper<Args extends any[], T>(\n func: AsyncFunction<Args, T>,\n setting: Setting = defalutSetting\n): AsyncFunction<Args, T> {\n return function (...args: Args): Promise<T> {\n const apiKey: string =\n generateStableUniqueKey(args) + func.name + (setting.identifier || \"\"); //缓存key\n\n if (cache[apiKey]) {\n return Promise.resolve(cloneDeep(getCachedData<T>(apiKey)));\n }\n\n const apiLoadingKey: string = apiKey + \"_l_o_a_d_i_n_g_\"; //缓存loading key\n\n if (cache[apiLoadingKey]) {\n const _setting = Object.assign({}, defalutSetting, setting);\n return new Promise((resolve) => {\n const startTime = Date.now();\n const timer = setInterval(() => {\n if (cache[apiKey]) {\n clearInterval(timer);\n resolve(cloneDeep(getCachedData<T>(apiKey)));\n } else if (Date.now() - startTime > _setting.timeout!) {\n cache[apiLoadingKey] = false;\n clearInterval(timer);\n resolve(cloneDeep(_setting.timeoutResult));\n }\n }, 100);\n });\n }\n cache[apiLoadingKey] = true;\n\n return func(...args)\n .then((res) => {\n // 缓存原始数据或其克隆,避免数据被释放\n cache[apiKey] = res;\n return cloneDeep(cache[apiKey]);\n })\n .catch((error: any) => {\n throw error;\n })\n .finally(() => {\n cache[apiLoadingKey] = false;\n });\n };\n}\n","/**\n * 定义一个类型,用于扩展函数类型,增加一个可选的 isExecuting 属性\n */\nexport type SingleExecutionFunction<T extends (...args: any[]) => any> = T & {\n isExecuting?: boolean;\n};\n\n/**\n * 创建一个有执行状态的函数,该函数在前一次调用未完成时不会被再次调用。\n *\n * @param func - 需要包裹的函数。\n * @returns 一个增强版的函数,该函数具有 isExecuting 属性。\n */\nexport function singleExecutionWrapper<T extends (...args: any[]) => any>(\n func: T\n): SingleExecutionFunction<T> {\n const singleExecutionFn: SingleExecutionFunction<T> = function (\n ...args: Parameters<T>\n ): ReturnType<T> | undefined {\n if (singleExecutionFn.isExecuting) {\n console.log(`Function(${func.name}) is executing.`);\n return;\n }\n singleExecutionFn.isExecuting = true;\n\n let result: ReturnType<T>;\n\n try {\n result = func(...args);\n if ((result as any) instanceof Promise) {\n result.finally(() => {\n singleExecutionFn.isExecuting = false;\n });\n } else {\n singleExecutionFn.isExecuting = false;\n }\n } catch (error) {\n singleExecutionFn.isExecuting = false;\n throw error;\n }\n\n return result;\n } as SingleExecutionFunction<T>;\n\n singleExecutionFn.isExecuting = false;\n\n return singleExecutionFn;\n}\n","/**\n * 表示 DOM 中可能的子元素类型。\n */\nexport type ChildrenType =\n | DomOptionsType\n | HTMLElement\n | SVGElement\n | Text\n | string;\n\n/**\n * 表示创建 DOM 元素的选项类型。\n */\nexport type DomOptionsType = {\n /**\n * 要创建的元素的标签名。默认为 \"div\"。\n */\n tag?: string;\n\n /**\n * 要附加到创建的元素的子元素。可以是单个子元素或子元素数组。\n */\n children?: ChildrenType | ChildrenType[];\n\n /**\n * 要设置在创建的元素上的属性。\n */\n props?: Record<string, any>;\n\n /**\n * 要设置在创建的元素上的属性。\n */\n attrs?: Record<string, string | boolean>;\n\n /**\n * 要应用于创建的元素的样式。\n */\n styles?: Record<string, string | number>;\n};\n\n/**\n * 设置 HTML 元素的样式属性。\n *\n * @param element - 要设置样式的 HTML 元素。\n * @param property - CSS 属性名,可以是驼峰命名法(camelCase)或连字符命名法(kebab-case)。\n * @param value - 要设置的属性值。\n * @param important - 可选参数,布尔值,表示是否将属性设置为 `important` 优先级,默认为 `false`。\n */\nfunction setStyle(\n element: HTMLElement,\n property: string,\n value: string | number,\n important: boolean = false\n): void {\n if (property in element.style) {\n (element.style as any)[property] = value;\n } else {\n const priority = important ? \"important\" : \"\";\n element.style.setProperty(property, String(value), priority);\n }\n}\n\n/**\n * 使用指定选项创建一个 DOM 元素。\n *\n * @param options - 创建 DOM 元素的选项。\n *\n * @returns 创建的 DOM 元素。\n *\n * @remarks\n * 此函数旨在浏览器环境中使用。\n *\n * @example\n * ```typescript\n * const element = createElement({\n * tag: 'button',\n * children: '点击我',\n * attrs: { id: 'myButton' },\n * styles: { color: 'red' }\n * });\n * document.body.appendChild(element);\n * ```\n */\nexport function createElement({\n tag = \"div\",\n children = [],\n props = {},\n attrs = {},\n styles = {},\n}: DomOptionsType = {}): HTMLElement {\n const ele = document.createElement(tag);\n\n // 设置属性\n Object.assign(ele, props);\n\n // 设置属性\n for (const [key, value] of Object.entries(attrs)) {\n if (value !== false) {\n ele.setAttribute(key, value as string);\n }\n }\n\n // 设置样式\n for (const [key, value] of Object.entries(styles)) {\n setStyle(ele, key, value);\n }\n\n // 处理子元素\n const childArray = Array.isArray(children) ? children : [children];\n for (const child of childArray) {\n if (!child) continue;\n\n if (typeof child === \"object\") {\n if (child instanceof HTMLElement || child instanceof Text) {\n ele.appendChild(child);\n } else {\n ele.appendChild(createElement(child as DomOptionsType));\n }\n } else {\n ele.appendChild(document.createTextNode(child));\n }\n }\n\n return ele;\n}\n\ntype SvgElement = {\n tag: string;\n attributes?: Record<string, string>;\n children?: SvgElement | SvgElement[] | string;\n};\n\ntype SvgOptions = {\n width?: number;\n height?: number;\n};\n\n/**\n * 创建一个 SVG 元素。\n *\n * @param {SvgElement[] | SvgElement | string} elements - 要创建的 SVG 元素,可以是对象数组、单个对象或 innerHTML 字符串。\n * @param {SvgOptions} [options] - SVG 的配置选项,包括宽度和高度。\n * @returns {SVGElement} - 创建的 SVG 元素。\n *\n * @example\n * // 使用嵌套对象\n * const svg1 = createSvg(\n * {\n * tag: 'svg',\n * children: [\n * { tag: 'circle', attributes: { cx: '16', cy: '16', r: '10', fill: 'red' } },\n * { tag: 'g', children:\n * { tag: 'text', attributes: { x: '10', y: '20', fill: 'black' }, children: 'Hello' }\n * }\n * ]\n * },\n * { width: 64, height: 64 }\n * );\n * document.body.appendChild(svg1);\n *\n * @example\n * // 使用 innerHTML\n * const svg2 = createSvg(\n * `<circle cx=\"16\" cy=\"16\" r=\"10\" fill=\"red\"></circle>\n * <text x=\"10\" y=\"20\" fill=\"black\">Hello</text>`\n * );\n * document.body.appendChild(svg2);\n */\nexport function createSvg(\n elements: SvgElement[] | SvgElement | string,\n options?: SvgOptions\n) {\n // 默认宽度和高度\n const { width = 32, height = 32 } = options || {};\n\n // 创建一个 SVG 元素\n const svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n\n // 设置 SVG 的宽度和高度\n svg.setAttribute(\"width\", width.toString());\n svg.setAttribute(\"height\", height.toString());\n svg.setAttribute(\"viewBox\", `0 0 ${width} ${height}`);\n\n if (typeof elements === \"string\") {\n // 如果 elements 是字符串,直接设置为 SVG 的 innerHTML\n svg.innerHTML = elements;\n } else {\n // 处理 SvgElement 或 SvgElement[]\n const elementArray = Array.isArray(elements) ? elements : [elements];\n\n elementArray.forEach((element) => {\n svg.appendChild(createSvgElement(element));\n });\n }\n\n // 返回创建好的 SVG 元素\n return svg;\n}\n\n/**\n * 递归创建 SVG 子元素。\n *\n * @param {SvgElement} element - 要创建的 SVG 子元素。\n * @returns {SVGElement} - 创建的 SVG 子元素。\n */\nfunction createSvgElement(element: SvgElement) {\n const { tag, attributes, children } = element;\n const el = document.createElementNS(\"http://www.w3.org/2000/svg\", tag);\n\n if (attributes) {\n for (const [key, value] of Object.entries(attributes)) {\n el.setAttribute(key, value);\n }\n }\n\n if (typeof children === \"string\") {\n el.textContent = children;\n } else if (children) {\n const childArray = Array.isArray(children) ? children : [children];\n childArray.forEach((child) => {\n el.appendChild(createSvgElement(child));\n });\n }\n\n return el;\n}\n","/**\n * 将指定的 DOM 元素滚动到底部。\n * 使用 setTimeout 确保在当前调用栈之后执行。\n *\n * @param {HTMLElement} dom - 要滚动的 DOM 元素。\n */\nexport function scrollToBottom(dom: HTMLElement) {\n if (dom) {\n setTimeout(() => {\n // 设置滚动条位置为元素的最大滚动高度,滚动到底部\n dom.scrollTop = dom.scrollHeight;\n }, 0);\n }\n}\n\n/**\n * 如果用户未与 DOM 元素交互,则将其滚动到底部。\n * 如果尚未设置事件监听器,则设置一个以跟踪用户滚动交互。\n *\n * @param {HTMLElement} dom - 可能需要滚动的 DOM 元素。\n */\nexport function scrollToBottomIfNeeded(dom: HTMLElement): void {\n if (!dom) {\n return;\n }\n // 检查是否已设置滚动监听器\n if (dom.dataset.isListeningForUserScroll !== \"true\") {\n listenForUserScroll(dom);\n dom.dataset.isListeningForUserScroll = \"true\";\n }\n\n // 如果用户未与滚动条交互,则滚动到底部\n if (dom.dataset.userInteracted !== \"true\") {\n scrollToBottom(dom);\n }\n}\n\n/**\n * 更新用户是否与滚动条交互的状态。\n *\n * @param {HTMLElement} dom - 要更新状态的 DOM 元素。\n * @param {boolean} inter - 用户是否与滚动条交互。\n */\nfunction userInteractedWithScroll(dom: HTMLElement, inter: boolean): void {\n // 根据用户交互状态更新数据属性\n dom.dataset.userInteracted = inter ? \"true\" : \"false\";\n}\n\n/**\n * 为 DOM 元素设置滚动事件监听器。\n * 当用户滚动时,更新交互状态。\n *\n * @param {HTMLElement} dom - 要监听滚动事件的 DOM 元素。\n */\nfunction listenForUserScroll(dom: HTMLElement): void {\n if (!dom) {\n return;\n }\n dom.addEventListener(\"scroll\", () => {\n // 检查用户是否滚动到接近底部\n if (dom.scrollTop + dom.clientHeight < dom.scrollHeight - 5) {\n // 用户已滚动,更新交互状态\n userInteractedWithScroll(dom, true);\n } else {\n // 用户未滚动到接近底部\n userInteractedWithScroll(dom, false);\n }\n });\n}\n"],"names":["isCloneable","obj","clone","isPrimitive","value","type","getGlobal","globalThis","self","window","global","this","generateStableUniqueKey","params","String","JSON","stringify","_key","Array","isArray","Object","keys","sort","reduce","pre","cur","cloneDeep","map","item","newObj","key","prototype","hasOwnProperty","call","debounce","func","wait","timeout","args","context","clearTimeout","setTimeout","apply","throttle","delay","lastExecutedTime","currentTime","Date","now","delayExecution","callback","Promise","resolve","cache","getCachedData","apiKey","defalutSetting","timeoutResult","code","msg","identifier","cacheWrapper","setting","name","apiLoadingKey","_setting","assign","startTime","timer","setInterval","clearInterval","then","res","catch","error","finally","singleExecutionWrapper","singleExecutionFn","isExecuting","console","log","result","setStyle","element","property","important","style","priority","setProperty","createElement","tag","children","props","attrs","styles","ele","document","entries","setAttribute","childArray","child","HTMLElement","Text","appendChild","createTextNode","createSvg","elements","options","width","height","svg","createElementNS","toString","innerHTML","forEach","createSvgElement","attributes","el","textContent","scrollToBottom","dom","scrollTop","scrollHeight","scrollToBottomIfNeeded","dataset","isListeningForUserScroll","addEventListener","inter","userInteracted","userInteractedWithScroll","clientHeight","listenForUserScroll"],"mappings":"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"}
1
+ {"version":3,"file":"index.modern.js","sources":["../src/common/type.ts","../src/common/getGlobal.ts","../src/common/generateStableUniqueKey.ts","../src/common/cloneDeep.ts","../src/common/utils.ts","../src/common/cacheWrapper.ts","../src/common/singleExecutionWrapper.ts","../src/browser/dom.ts","../src/browser/scroll.ts"],"sourcesContent":["/**\n * 异步函数类型。\n *\n * @template Args - 表示函数参数的类型数组。\n * @template T - 表示函数返回的 Promise 解析后的类型。\n *\n * @param args - 函数的参数。\n * @returns 一个 Promise 对象,解析后的值类型为 T。\n */\nexport type AsyncFunction<Args extends any[], T> = (\n ...args: Args\n) => Promise<T>;\n\n/**\n * 表示一个可以克隆自身的对象接口。\n *\n * @interface Cloneable\n */\nexport interface Cloneable {\n /**\n * 创建并返回当前对象的一个副本。\n *\n * @returns {this} 当前对象的一个副本。\n */\n clone(): this;\n}\n\n/**\n *\n * 检查一个对象是否实现了 Cloneable 接口。\n *\n * 这个函数是一个类型保护函数,它会在类型检查时将传入的对象类型缩小为 Cloneable。\n *\n * @param {any} obj - 要检查的对象。\n * @returns {obj is Cloneable} 如果对象实现了 Cloneable 接口,则返回 true;否则返回 false。\n */\nexport function isCloneable(obj: any): obj is Cloneable {\n return typeof obj?.clone === \"function\";\n}\n\n/**\n * 检查一个值是否是原始类型(primitive type)。\n *\n * 这个函数是一个类型保护函数,它会在类型检查时将传入的值类型缩小为原始类型之一:string, number, boolean, null 或 undefined。\n *\n * @param {any} value - 要检查的值。\n * @returns {value is string | number | boolean | null | undefined} 如果值是原始类型,则返回 true;否则返回 false。\n */\nexport function isPrimitive(\n value: any\n): value is string | number | boolean | null | undefined {\n const type = typeof value;\n return (\n value === null ||\n type === \"string\" ||\n type === \"number\" ||\n type === \"boolean\" ||\n type === \"undefined\"\n );\n}\n","declare var global: typeof globalThis;\n\n/**\n * 获取当前环境的全局对象。\n *\n * 在不同的 JavaScript 运行环境中,全局对象的名称不同:\n * - 在浏览器环境中,全局对象是 `window`。\n * - 在 Node.js 环境中,全局对象是 `global`。\n * - 在 Web Worker 环境中,全局对象是 `self`。\n *\n * 这个函数提供了一种统一的方式来获取当前环境的全局对象。\n *\n * @returns 当前环境的全局对象。\n */\nexport function getGlobal(this: any) {\n if (typeof globalThis !== \"undefined\") {\n return globalThis;\n }\n\n if (typeof self !== \"undefined\") {\n return self;\n }\n\n if (typeof window !== \"undefined\") {\n return window;\n }\n\n if (typeof global !== \"undefined\") {\n return global;\n }\n\n // 如果以上都不符合,则返回 this\n return this;\n}\n","import { isPrimitive } from \"./type\";\n\n/**\n * 为给定的参数生成一个稳定且唯一的键。\n *\n * 该函数确保生成的键是确定性的,即相同的输入总是会生成相同的输出。\n * 这在缓存、记忆化或任何需要一致键的场景中非常有用。\n *\n * @param params - 用于生成键的参数。可以是任何类型。\n * @returns 表示输入参数的稳定且唯一的字符串键。\n */\nexport function generateStableUniqueKey(params: any) {\n if (isPrimitive(params)) {\n return String(params);\n }\n return JSON.stringify(params, function (_key: string | number, value: any) {\n if (typeof value === \"object\" && value !== null && !Array.isArray(value)) {\n return Object.keys(value)\n .sort()\n .reduce((pre: any, cur: string) => {\n pre[cur] = value[cur];\n return pre;\n }, {});\n }\n return value;\n });\n}\n","import { isCloneable } from \"./type\";\n\n/**\n * 深度克隆一个对象或数组。\n *\n * @param {T} obj - 要克隆的对象或数组。\n * @returns {T} 克隆后的对象或数组。\n */\nexport function cloneDeep<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n\n if (isCloneable(obj)) {\n return obj.clone();\n }\n\n // 处理数组\n if (Array.isArray(obj)) {\n return obj.map((item) => cloneDeep(item)) as unknown as T;\n }\n\n const newObj: { [key: string]: any } = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n newObj[key] = cloneDeep(obj[key]);\n }\n }\n return newObj as T;\n}\n","/**\n * 创建一个防抖函数,该函数会在最后一次调用后的指定时间间隔后执行。\n *\n * @param func - 需要防抖处理的函数。\n * @param wait - 延迟的毫秒数。\n * @returns 一个新的防抖函数。\n */\nexport function debounce<T extends (...args: any[]) => void>(\n func: T,\n wait: number\n): T {\n let timeout: ReturnType<typeof setTimeout> | null = null;\n\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n const context = this;\n\n // 如果已经设定了调用,取消之前的调用\n if (timeout !== null) {\n clearTimeout(timeout);\n }\n\n // 设定一个新的调用,等待指定的时间后执行\n timeout = setTimeout(() => {\n func.apply(context, args);\n timeout = null; // 确保能够在下次触发时重新设定定时器\n }, wait);\n } as T;\n}\n\n/**\n * 创建一个节流函数,该函数会在每个指定的时间间隔内最多执行一次。\n *\n * @param func - 需要节流处理的函数。\n * @param delay - 时间间隔的毫秒数。\n * @returns 一个新的节流函数。\n */\nexport function throttle<T extends (...agrs: any[]) => any>(\n func: T,\n delay: number\n): T {\n let lastExecutedTime: number = 0;\n\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n const context = this;\n const currentTime = Date.now();\n\n if (currentTime - lastExecutedTime >= delay) {\n func.apply(context, args);\n lastExecutedTime = currentTime;\n }\n } as T;\n}\n\n/**\n * 创建一个延迟执行回调函数并返回 Promise 的函数。\n *\n * @param callback - 需要执行的回调函数。\n * @param delay - 延迟的毫秒数,默认为 0。\n * @returns 一个 Promise 对象,该对象在回调函数执行后解析。\n */\nexport function delayExecution<T>(\n callback: () => T,\n delay: number = 0\n): Promise<T> {\n return new Promise<T>((resolve) => {\n if (delay === 0) {\n resolve(callback());\n } else {\n setTimeout(() => {\n resolve(callback());\n }, delay);\n }\n });\n}\n","import { generateStableUniqueKey } from \"./generateStableUniqueKey\";\nimport { cloneDeep } from \"./cloneDeep\";\nimport { AsyncFunction } from \"./type\";\n\nconst cache: Record<string, any> = {};\nfunction getCachedData<T = any>(apiKey: string) {\n return cache[apiKey] as T;\n}\n\nexport interface Setting {\n timeout?: number;\n timeoutResult?: any;\n identifier?: string;\n}\n\nconst defalutSetting: Setting = {\n timeout: 60000,\n timeoutResult: { code: 408, msg: \"请求超时\" },\n identifier: \"\",\n};\n\n/**\n * 为异步函数添加缓存功能。\n *\n * 该函数根据函数参数、函数名和一个可选的标识符来缓存异步函数的结果。\n * 如果结果已经缓存,则返回缓存的结果。如果函数正在执行中,则等待结果返回,并使用一个超时机制防止无限等待。\n *\n * @template Args - 函数参数的类型。\n * @template Promise<T> - 函数返回值的类型。\n * @param {AsyncFunction<Args, T>} func - 需要包装的异步函数。\n * @param {Setting} [setting=defalutSetting] - 可选的缓存设置。\n * @returns {AsyncFunction<Args, T>} - 带有缓存功能的包装函数,返回类型为 `Promise<T>`。\n */\nexport function cacheWrapper<Args extends any[], T>(\n func: AsyncFunction<Args, T>,\n setting: Setting = defalutSetting\n): AsyncFunction<Args, T> {\n return function (...args: Args): Promise<T> {\n const apiKey: string =\n generateStableUniqueKey(args) + func.name + (setting.identifier || \"\"); //缓存key\n\n if (cache[apiKey]) {\n return Promise.resolve(cloneDeep(getCachedData<T>(apiKey)));\n }\n\n const apiLoadingKey: string = apiKey + \"_l_o_a_d_i_n_g_\"; //缓存loading key\n\n if (cache[apiLoadingKey]) {\n const _setting = Object.assign({}, defalutSetting, setting);\n return new Promise((resolve) => {\n const startTime = Date.now();\n const timer = setInterval(() => {\n if (cache[apiKey]) {\n clearInterval(timer);\n resolve(cloneDeep(getCachedData<T>(apiKey)));\n } else if (Date.now() - startTime > _setting.timeout!) {\n cache[apiLoadingKey] = false;\n clearInterval(timer);\n resolve(cloneDeep(_setting.timeoutResult));\n }\n }, 100);\n });\n }\n cache[apiLoadingKey] = true;\n\n return func(...args)\n .then((res) => {\n // 缓存原始数据或其克隆,避免数据被释放\n cache[apiKey] = res;\n return cloneDeep(cache[apiKey]);\n })\n .catch((error: any) => {\n throw error;\n })\n .finally(() => {\n cache[apiLoadingKey] = false;\n });\n };\n}\n","/**\n * 定义一个类型,用于扩展函数类型,增加一个可选的 isExecuting 属性\n */\nexport type SingleExecutionFunction<T extends (...args: any[]) => any> = T & {\n isExecuting?: boolean;\n};\n\n/**\n * 创建一个有执行状态的函数,该函数在前一次调用未完成时不会被再次调用。\n *\n * @param func - 需要包裹的函数。\n * @returns 一个增强版的函数,该函数具有 isExecuting 属性。\n */\nexport function singleExecutionWrapper<T extends (...args: any[]) => any>(\n func: T\n): SingleExecutionFunction<T> {\n const singleExecutionFn: SingleExecutionFunction<T> = function (\n ...args: Parameters<T>\n ): ReturnType<T> | undefined {\n if (singleExecutionFn.isExecuting) {\n console.log(`Function(${func.name}) is executing.`);\n return;\n }\n singleExecutionFn.isExecuting = true;\n\n let result: ReturnType<T>;\n\n try {\n result = func(...args);\n if ((result as any) instanceof Promise) {\n result.finally(() => {\n singleExecutionFn.isExecuting = false;\n });\n } else {\n singleExecutionFn.isExecuting = false;\n }\n } catch (error) {\n singleExecutionFn.isExecuting = false;\n throw error;\n }\n\n return result;\n } as SingleExecutionFunction<T>;\n\n singleExecutionFn.isExecuting = false;\n\n return singleExecutionFn;\n}\n","/**\n * 表示 DOM 中可能的子元素类型。\n */\nexport type ChildrenType =\n | DomOptionsType\n | Element\n | string;\n\n/**\n * 表示创建 DOM 元素的选项类型。\n */\nexport type DomOptionsType = {\n /**\n * 要创建的元素的标签名。默认为 \"div\"。\n */\n tag?: string;\n\n /**\n * 要附加到创建的元素的子元素。可以是单个子元素或子元素数组。\n */\n children?: ChildrenType | ChildrenType[];\n\n /**\n * 要设置在创建的元素上的属性。\n */\n props?: Record<string, any>;\n\n /**\n * 要设置在创建的元素上的属性。\n */\n attrs?: Record<string, string | boolean>;\n\n /**\n * 要应用于创建的元素的样式。\n */\n styles?: Record<string, string | number>;\n};\n\n/**\n * 设置 HTML 元素的样式属性。\n *\n * @param element - 要设置样式的 HTML 元素。\n * @param property - CSS 属性名,可以是驼峰命名法(camelCase)或连字符命名法(kebab-case)。\n * @param value - 要设置的属性值。\n * @param important - 可选参数,布尔值,表示是否将属性设置为 `important` 优先级,默认为 `false`。\n */\nfunction setStyle(\n element: HTMLElement | SVGElement,\n property: string,\n value: string | number,\n important: boolean = false\n): void {\n if (property in element.style) {\n (element.style as any)[property] = value;\n } else {\n const priority = important ? \"important\" : \"\";\n element.style.setProperty(property, String(value), priority);\n }\n}\n\n/**\n * 使用指定选项创建一个 DOM 元素。\n *\n * @param options - 创建 DOM 元素的选项。\n *\n * @returns 创建的 DOM 元素。\n *\n * @remarks\n * 此函数旨在浏览器环境中使用。\n *\n * @example\n * ```typescript\n * const element = createElement({\n * tag: 'button',\n * children: '点击我',\n * attrs: { id: 'myButton' },\n * styles: { color: 'red' }\n * });\n * document.body.appendChild(element);\n * ```\n */\nexport function createElement({\n tag = \"div\",\n children = [],\n props = {},\n attrs = {},\n styles = {},\n}: DomOptionsType = {}): Element {\n const ele = document.createElement(tag);\n\n // 设置属性\n Object.assign(ele, props);\n\n // 设置属性\n for (const [key, value] of Object.entries(attrs)) {\n if (value !== false) {\n ele.setAttribute(key, value as string);\n }\n }\n\n // 设置样式\n for (const [key, value] of Object.entries(styles)) {\n setStyle(ele, key, value);\n }\n\n // 处理子元素\n const childArray = Array.isArray(children) ? children : [children];\n for (const child of childArray) {\n if (!child) continue;\n\n if (typeof child === \"object\") {\n if (child instanceof Element) {\n ele.appendChild(child);\n } else {\n ele.appendChild(createElement(child as DomOptionsType));\n }\n } else {\n ele.appendChild(document.createTextNode(child));\n }\n }\n\n return ele;\n}\n\ntype SvgElement = {\n tag: string;\n attributes?: Record<string, string>;\n children?: SvgElement | SvgElement[] | string;\n};\n\ntype SvgOptions = {\n width?: number;\n height?: number;\n};\n\n/**\n * 创建一个 SVG 元素。\n *\n * @param {SvgElement[] | SvgElement | string} elements - 要创建的 SVG 元素,可以是对象数组、单个对象或 innerHTML 字符串。\n * @param {SvgOptions} [options] - SVG 的配置选项,包括宽度和高度。\n * @returns {SVGElement} - 创建的 SVG 元素。\n *\n * @example\n * // 使用嵌套对象\n * const svg1 = createSvg(\n * {\n * tag: 'svg',\n * children: [\n * { tag: 'circle', attributes: { cx: '16', cy: '16', r: '10', fill: 'red' } },\n * { tag: 'g', children:\n * { tag: 'text', attributes: { x: '10', y: '20', fill: 'black' }, children: 'Hello' }\n * }\n * ]\n * },\n * { width: 64, height: 64 }\n * );\n * document.body.appendChild(svg1);\n *\n * @example\n * // 使用 innerHTML\n * const svg2 = createSvg(\n * `<circle cx=\"16\" cy=\"16\" r=\"10\" fill=\"red\"></circle>\n * <text x=\"10\" y=\"20\" fill=\"black\">Hello</text>`\n * );\n * document.body.appendChild(svg2);\n */\nexport function createSvg(\n elements: SvgElement[] | SvgElement | string,\n options?: SvgOptions\n) {\n // 默认宽度和高度\n const { width = 32, height = 32 } = options || {};\n\n // 创建一个 SVG 元素\n const svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n\n // 设置 SVG 的宽度和高度\n svg.setAttribute(\"width\", width.toString());\n svg.setAttribute(\"height\", height.toString());\n svg.setAttribute(\"viewBox\", `0 0 ${width} ${height}`);\n\n if (typeof elements === \"string\") {\n // 如果 elements 是字符串,直接设置为 SVG 的 innerHTML\n svg.innerHTML = elements;\n } else {\n // 处理 SvgElement 或 SvgElement[]\n const elementArray = Array.isArray(elements) ? elements : [elements];\n\n elementArray.forEach((element) => {\n svg.appendChild(createSvgElement(element));\n });\n }\n\n // 返回创建好的 SVG 元素\n return svg;\n}\n\n/**\n * 递归创建 SVG 子元素。\n *\n * @param {SvgElement} element - 要创建的 SVG 子元素。\n * @returns {SVGElement} - 创建的 SVG 子元素。\n */\nfunction createSvgElement(element: SvgElement) {\n const { tag, attributes, children } = element;\n const el = document.createElementNS(\"http://www.w3.org/2000/svg\", tag);\n\n if (attributes) {\n for (const [key, value] of Object.entries(attributes)) {\n el.setAttribute(key, value);\n }\n }\n\n if (typeof children === \"string\") {\n el.textContent = children;\n } else if (children) {\n const childArray = Array.isArray(children) ? children : [children];\n childArray.forEach((child) => {\n el.appendChild(createSvgElement(child));\n });\n }\n\n return el;\n}\n","/**\n * 将指定的 DOM 元素滚动到底部。\n * 使用 setTimeout 确保在当前调用栈之后执行。\n *\n * @param {HTMLElement} dom - 要滚动的 DOM 元素。\n */\nexport function scrollToBottom(dom: HTMLElement) {\n if (dom) {\n setTimeout(() => {\n // 设置滚动条位置为元素的最大滚动高度,滚动到底部\n dom.scrollTop = dom.scrollHeight;\n }, 0);\n }\n}\n\n/**\n * 如果用户未与 DOM 元素交互,则将其滚动到底部。\n * 如果尚未设置事件监听器,则设置一个以跟踪用户滚动交互。\n *\n * @param {HTMLElement} dom - 可能需要滚动的 DOM 元素。\n */\nexport function scrollToBottomIfNeeded(dom: HTMLElement): void {\n if (!dom) {\n return;\n }\n // 检查是否已设置滚动监听器\n if (dom.dataset.isListeningForUserScroll !== \"true\") {\n listenForUserScroll(dom);\n dom.dataset.isListeningForUserScroll = \"true\";\n }\n\n // 如果用户未与滚动条交互,则滚动到底部\n if (dom.dataset.userInteracted !== \"true\") {\n scrollToBottom(dom);\n }\n}\n\n/**\n * 更新用户是否与滚动条交互的状态。\n *\n * @param {HTMLElement} dom - 要更新状态的 DOM 元素。\n * @param {boolean} inter - 用户是否与滚动条交互。\n */\nfunction userInteractedWithScroll(dom: HTMLElement, inter: boolean): void {\n // 根据用户交互状态更新数据属性\n dom.dataset.userInteracted = inter ? \"true\" : \"false\";\n}\n\n/**\n * 为 DOM 元素设置滚动事件监听器。\n * 当用户滚动时,更新交互状态。\n *\n * @param {HTMLElement} dom - 要监听滚动事件的 DOM 元素。\n */\nfunction listenForUserScroll(dom: HTMLElement): void {\n if (!dom) {\n return;\n }\n dom.addEventListener(\"scroll\", () => {\n // 检查用户是否滚动到接近底部\n if (dom.scrollTop + dom.clientHeight < dom.scrollHeight - 5) {\n // 用户已滚动,更新交互状态\n userInteractedWithScroll(dom, true);\n } else {\n // 用户未滚动到接近底部\n userInteractedWithScroll(dom, false);\n }\n });\n}\n"],"names":["isCloneable","obj","clone","isPrimitive","value","type","getGlobal","globalThis","self","window","global","this","generateStableUniqueKey","params","String","JSON","stringify","_key","Array","isArray","Object","keys","sort","reduce","pre","cur","cloneDeep","map","item","newObj","key","prototype","hasOwnProperty","call","debounce","func","wait","timeout","args","context","clearTimeout","setTimeout","apply","throttle","delay","lastExecutedTime","currentTime","Date","now","delayExecution","callback","Promise","resolve","cache","getCachedData","apiKey","defalutSetting","timeoutResult","code","msg","identifier","cacheWrapper","setting","name","apiLoadingKey","_setting","assign","startTime","timer","setInterval","clearInterval","then","res","catch","error","finally","singleExecutionWrapper","singleExecutionFn","isExecuting","console","log","result","setStyle","element","property","important","style","priority","setProperty","createElement","tag","children","props","attrs","styles","ele","document","entries","setAttribute","childArray","child","Element","appendChild","createTextNode","createSvg","elements","options","width","height","svg","createElementNS","toString","innerHTML","forEach","createSvgElement","attributes","el","textContent","scrollToBottom","dom","scrollTop","scrollHeight","scrollToBottomIfNeeded","dataset","isListeningForUserScroll","addEventListener","inter","userInteracted","userInteractedWithScroll","clientHeight","listenForUserScroll"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- function t(t){return"function"==typeof(null==t?void 0:t.clone)}function e(t){var e=typeof t;return null===t||"string"===e||"number"===e||"boolean"===e||"undefined"===e}function n(){return"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:this}function r(t){return e(t)?String(t):JSON.stringify(t,function(t,e){return"object"!=typeof e||null===e||Array.isArray(e)?e:Object.keys(e).sort().reduce(function(t,n){return t[n]=e[n],t},{})})}function i(e){if(null===e||"object"!=typeof e)return e;if(t(e))return e.clone();if(Array.isArray(e))return e.map(function(t){return i(t)});var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=i(e[r]));return n}function o(t,e){var n=null;return function(){var r=arguments,i=this;null!==n&&clearTimeout(n),n=setTimeout(function(){t.apply(i,[].slice.call(r)),n=null},e)}}function a(t,e){var n=0;return function(){var r=Date.now();r-n>=e&&(t.apply(this,[].slice.call(arguments)),n=r)}}function u(t,e){return void 0===e&&(e=0),new Promise(function(n){0===e?n(t()):setTimeout(function(){n(t())},e)})}var c={};function l(t){return c[t]}var s={timeout:6e4,timeoutResult:{code:408,msg:"请求超时"},identifier:""};function f(t,e){return void 0===e&&(e=s),function(){var n=[].slice.call(arguments),o=r(n)+t.name+(e.identifier||"");if(c[o])return Promise.resolve(i(l(o)));var a=o+"_l_o_a_d_i_n_g_";if(c[a]){var u=Object.assign({},s,e);return new Promise(function(t){var e=Date.now(),n=setInterval(function(){c[o]?(clearInterval(n),t(i(l(o)))):Date.now()-e>u.timeout&&(c[a]=!1,clearInterval(n),t(i(u.timeoutResult)))},100)})}return c[a]=!0,t.apply(void 0,n).then(function(t){return c[o]=t,i(c[o])}).catch(function(t){throw t}).finally(function(){c[a]=!1})}}function d(t){var e=function(){if(!e.isExecuting){var n;e.isExecuting=!0;try{(n=t.apply(void 0,[].slice.call(arguments)))instanceof Promise?n.finally(function(){e.isExecuting=!1}):e.isExecuting=!1}catch(t){throw e.isExecuting=!1,t}return n}console.log("Function("+t.name+") is executing.")};return e.isExecuting=!1,e}function v(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=Array(e);n<e;n++)r[n]=t[n];return r}function y(t,e,n,r){if(void 0===r&&(r=!1),e in t.style)t.style[e]=n;else{var i=r?"important":"";t.style.setProperty(e,String(n),i)}}function p(t){var e=void 0===t?{}:t,n=e.tag,r=e.children,i=void 0===r?[]:r,o=e.props,a=void 0===o?{}:o,u=e.attrs,c=void 0===u?{}:u,l=e.styles,s=void 0===l?{}:l,f=document.createElement(void 0===n?"div":n);Object.assign(f,a);for(var d=0,g=Object.entries(c);d<g.length;d++){var h=g[d],m=h[1];!1!==m&&f.setAttribute(h[0],m)}for(var b=0,w=Object.entries(s);b<w.length;b++){var A=w[b];y(f,A[0],A[1])}for(var E,S=function(t){var e="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(e)return(e=e.call(t)).next.bind(e);if(Array.isArray(t)||(e=function(t,e){if(t){if("string"==typeof t)return v(t,e);var n={}.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?v(t,e):void 0}}(t))){e&&(t=e);var n=0;return function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(Array.isArray(i)?i:[i]);!(E=S()).done;){var x=E.value;x&&("object"==typeof x?x instanceof HTMLElement||x instanceof Text?f.appendChild(x):f.appendChild(p(x)):f.appendChild(document.createTextNode(x)))}return f}function g(t,e){var n=e||{},r=n.width,i=void 0===r?32:r,o=n.height,a=void 0===o?32:o,u=document.createElementNS("http://www.w3.org/2000/svg","svg");return u.setAttribute("width",i.toString()),u.setAttribute("height",a.toString()),u.setAttribute("viewBox","0 0 "+i+" "+a),"string"==typeof t?u.innerHTML=t:(Array.isArray(t)?t:[t]).forEach(function(t){u.appendChild(h(t))}),u}function h(t){var e=t.attributes,n=t.children,r=document.createElementNS("http://www.w3.org/2000/svg",t.tag);if(e)for(var i=0,o=Object.entries(e);i<o.length;i++){var a=o[i];r.setAttribute(a[0],a[1])}return"string"==typeof n?r.textContent=n:n&&(Array.isArray(n)?n:[n]).forEach(function(t){r.appendChild(h(t))}),r}function m(t){t&&setTimeout(function(){t.scrollTop=t.scrollHeight},0)}function b(t){t&&("true"!==t.dataset.isListeningForUserScroll&&(function(t){t&&t.addEventListener("scroll",function(){!function(t,e){t.dataset.userInteracted=e?"true":"false"}(t,t.scrollTop+t.clientHeight<t.scrollHeight-5)})}(t),t.dataset.isListeningForUserScroll="true"),"true"!==t.dataset.userInteracted&&m(t))}export{f as cacheWrapper,i as cloneDeep,p as createElement,g as createSvg,o as debounce,u as delayExecution,r as generateStableUniqueKey,n as getGlobal,t as isCloneable,e as isPrimitive,m as scrollToBottom,b as scrollToBottomIfNeeded,d as singleExecutionWrapper,a as throttle};
1
+ function t(t){return"function"==typeof(null==t?void 0:t.clone)}function e(t){var e=typeof t;return null===t||"string"===e||"number"===e||"boolean"===e||"undefined"===e}function n(){return"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:this}function r(t){return e(t)?String(t):JSON.stringify(t,function(t,e){return"object"!=typeof e||null===e||Array.isArray(e)?e:Object.keys(e).sort().reduce(function(t,n){return t[n]=e[n],t},{})})}function i(e){if(null===e||"object"!=typeof e)return e;if(t(e))return e.clone();if(Array.isArray(e))return e.map(function(t){return i(t)});var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=i(e[r]));return n}function o(t,e){var n=null;return function(){var r=arguments,i=this;null!==n&&clearTimeout(n),n=setTimeout(function(){t.apply(i,[].slice.call(r)),n=null},e)}}function u(t,e){var n=0;return function(){var r=Date.now();r-n>=e&&(t.apply(this,[].slice.call(arguments)),n=r)}}function a(t,e){return void 0===e&&(e=0),new Promise(function(n){0===e?n(t()):setTimeout(function(){n(t())},e)})}var c={};function l(t){return c[t]}var s={timeout:6e4,timeoutResult:{code:408,msg:"请求超时"},identifier:""};function f(t,e){return void 0===e&&(e=s),function(){var n=[].slice.call(arguments),o=r(n)+t.name+(e.identifier||"");if(c[o])return Promise.resolve(i(l(o)));var u=o+"_l_o_a_d_i_n_g_";if(c[u]){var a=Object.assign({},s,e);return new Promise(function(t){var e=Date.now(),n=setInterval(function(){c[o]?(clearInterval(n),t(i(l(o)))):Date.now()-e>a.timeout&&(c[u]=!1,clearInterval(n),t(i(a.timeoutResult)))},100)})}return c[u]=!0,t.apply(void 0,n).then(function(t){return c[o]=t,i(c[o])}).catch(function(t){throw t}).finally(function(){c[u]=!1})}}function d(t){var e=function(){if(!e.isExecuting){var n;e.isExecuting=!0;try{(n=t.apply(void 0,[].slice.call(arguments)))instanceof Promise?n.finally(function(){e.isExecuting=!1}):e.isExecuting=!1}catch(t){throw e.isExecuting=!1,t}return n}console.log("Function("+t.name+") is executing.")};return e.isExecuting=!1,e}function v(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=Array(e);n<e;n++)r[n]=t[n];return r}function y(t,e,n,r){if(void 0===r&&(r=!1),e in t.style)t.style[e]=n;else{var i=r?"important":"";t.style.setProperty(e,String(n),i)}}function p(t){var e=void 0===t?{}:t,n=e.tag,r=e.children,i=void 0===r?[]:r,o=e.props,u=void 0===o?{}:o,a=e.attrs,c=void 0===a?{}:a,l=e.styles,s=void 0===l?{}:l,f=document.createElement(void 0===n?"div":n);Object.assign(f,u);for(var d=0,g=Object.entries(c);d<g.length;d++){var h=g[d],m=h[1];!1!==m&&f.setAttribute(h[0],m)}for(var b=0,w=Object.entries(s);b<w.length;b++){var A=w[b];y(f,A[0],A[1])}for(var E,S=function(t){var e="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(e)return(e=e.call(t)).next.bind(e);if(Array.isArray(t)||(e=function(t,e){if(t){if("string"==typeof t)return v(t,e);var n={}.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?v(t,e):void 0}}(t))){e&&(t=e);var n=0;return function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(Array.isArray(i)?i:[i]);!(E=S()).done;){var j=E.value;j&&("object"==typeof j?j instanceof Element?f.appendChild(j):f.appendChild(p(j)):f.appendChild(document.createTextNode(j)))}return f}function g(t,e){var n=e||{},r=n.width,i=void 0===r?32:r,o=n.height,u=void 0===o?32:o,a=document.createElementNS("http://www.w3.org/2000/svg","svg");return a.setAttribute("width",i.toString()),a.setAttribute("height",u.toString()),a.setAttribute("viewBox","0 0 "+i+" "+u),"string"==typeof t?a.innerHTML=t:(Array.isArray(t)?t:[t]).forEach(function(t){a.appendChild(h(t))}),a}function h(t){var e=t.attributes,n=t.children,r=document.createElementNS("http://www.w3.org/2000/svg",t.tag);if(e)for(var i=0,o=Object.entries(e);i<o.length;i++){var u=o[i];r.setAttribute(u[0],u[1])}return"string"==typeof n?r.textContent=n:n&&(Array.isArray(n)?n:[n]).forEach(function(t){r.appendChild(h(t))}),r}function m(t){t&&setTimeout(function(){t.scrollTop=t.scrollHeight},0)}function b(t){t&&("true"!==t.dataset.isListeningForUserScroll&&(function(t){t&&t.addEventListener("scroll",function(){!function(t,e){t.dataset.userInteracted=e?"true":"false"}(t,t.scrollTop+t.clientHeight<t.scrollHeight-5)})}(t),t.dataset.isListeningForUserScroll="true"),"true"!==t.dataset.userInteracted&&m(t))}export{f as cacheWrapper,i as cloneDeep,p as createElement,g as createSvg,o as debounce,a as delayExecution,r as generateStableUniqueKey,n as getGlobal,t as isCloneable,e as isPrimitive,m as scrollToBottom,b as scrollToBottomIfNeeded,d as singleExecutionWrapper,u as throttle};
2
2
  //# sourceMappingURL=index.module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.module.js","sources":["../src/common/type.ts","../src/common/getGlobal.ts","../src/common/generateStableUniqueKey.ts","../src/common/cloneDeep.ts","../src/common/utils.ts","../src/common/cacheWrapper.ts","../src/common/singleExecutionWrapper.ts","../src/browser/dom.ts","../src/browser/scroll.ts"],"sourcesContent":["/**\n * 异步函数类型。\n *\n * @template Args - 表示函数参数的类型数组。\n * @template T - 表示函数返回的 Promise 解析后的类型。\n *\n * @param args - 函数的参数。\n * @returns 一个 Promise 对象,解析后的值类型为 T。\n */\nexport type AsyncFunction<Args extends any[], T> = (\n ...args: Args\n) => Promise<T>;\n\n/**\n * 表示一个可以克隆自身的对象接口。\n *\n * @interface Cloneable\n */\nexport interface Cloneable {\n /**\n * 创建并返回当前对象的一个副本。\n *\n * @returns {this} 当前对象的一个副本。\n */\n clone(): this;\n}\n\n/**\n *\n * 检查一个对象是否实现了 Cloneable 接口。\n *\n * 这个函数是一个类型保护函数,它会在类型检查时将传入的对象类型缩小为 Cloneable。\n *\n * @param {any} obj - 要检查的对象。\n * @returns {obj is Cloneable} 如果对象实现了 Cloneable 接口,则返回 true;否则返回 false。\n */\nexport function isCloneable(obj: any): obj is Cloneable {\n return typeof obj?.clone === \"function\";\n}\n\n/**\n * 检查一个值是否是原始类型(primitive type)。\n *\n * 这个函数是一个类型保护函数,它会在类型检查时将传入的值类型缩小为原始类型之一:string, number, boolean, null 或 undefined。\n *\n * @param {any} value - 要检查的值。\n * @returns {value is string | number | boolean | null | undefined} 如果值是原始类型,则返回 true;否则返回 false。\n */\nexport function isPrimitive(\n value: any\n): value is string | number | boolean | null | undefined {\n const type = typeof value;\n return (\n value === null ||\n type === \"string\" ||\n type === \"number\" ||\n type === \"boolean\" ||\n type === \"undefined\"\n );\n}\n","declare var global: typeof globalThis;\n\n/**\n * 获取当前环境的全局对象。\n *\n * 在不同的 JavaScript 运行环境中,全局对象的名称不同:\n * - 在浏览器环境中,全局对象是 `window`。\n * - 在 Node.js 环境中,全局对象是 `global`。\n * - 在 Web Worker 环境中,全局对象是 `self`。\n *\n * 这个函数提供了一种统一的方式来获取当前环境的全局对象。\n *\n * @returns 当前环境的全局对象。\n */\nexport function getGlobal(this: any) {\n if (typeof globalThis !== \"undefined\") {\n return globalThis;\n }\n\n if (typeof self !== \"undefined\") {\n return self;\n }\n\n if (typeof window !== \"undefined\") {\n return window;\n }\n\n if (typeof global !== \"undefined\") {\n return global;\n }\n\n // 如果以上都不符合,则返回 this\n return this;\n}\n","import { isPrimitive } from \"./type\";\n\n/**\n * 为给定的参数生成一个稳定且唯一的键。\n *\n * 该函数确保生成的键是确定性的,即相同的输入总是会生成相同的输出。\n * 这在缓存、记忆化或任何需要一致键的场景中非常有用。\n *\n * @param params - 用于生成键的参数。可以是任何类型。\n * @returns 表示输入参数的稳定且唯一的字符串键。\n */\nexport function generateStableUniqueKey(params: any) {\n if (isPrimitive(params)) {\n return String(params);\n }\n return JSON.stringify(params, function (_key: string | number, value: any) {\n if (typeof value === \"object\" && value !== null && !Array.isArray(value)) {\n return Object.keys(value)\n .sort()\n .reduce((pre: any, cur: string) => {\n pre[cur] = value[cur];\n return pre;\n }, {});\n }\n return value;\n });\n}\n","import { isCloneable } from \"./type\";\n\n/**\n * 深度克隆一个对象或数组。\n *\n * @param {T} obj - 要克隆的对象或数组。\n * @returns {T} 克隆后的对象或数组。\n */\nexport function cloneDeep<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n\n if (isCloneable(obj)) {\n return obj.clone();\n }\n\n // 处理数组\n if (Array.isArray(obj)) {\n return obj.map((item) => cloneDeep(item)) as unknown as T;\n }\n\n const newObj: { [key: string]: any } = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n newObj[key] = cloneDeep(obj[key]);\n }\n }\n return newObj as T;\n}\n","/**\n * 创建一个防抖函数,该函数会在最后一次调用后的指定时间间隔后执行。\n *\n * @param func - 需要防抖处理的函数。\n * @param wait - 延迟的毫秒数。\n * @returns 一个新的防抖函数。\n */\nexport function debounce<T extends (...args: any[]) => void>(\n func: T,\n wait: number\n): T {\n let timeout: ReturnType<typeof setTimeout> | null = null;\n\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n const context = this;\n\n // 如果已经设定了调用,取消之前的调用\n if (timeout !== null) {\n clearTimeout(timeout);\n }\n\n // 设定一个新的调用,等待指定的时间后执行\n timeout = setTimeout(() => {\n func.apply(context, args);\n timeout = null; // 确保能够在下次触发时重新设定定时器\n }, wait);\n } as T;\n}\n\n/**\n * 创建一个节流函数,该函数会在每个指定的时间间隔内最多执行一次。\n *\n * @param func - 需要节流处理的函数。\n * @param delay - 时间间隔的毫秒数。\n * @returns 一个新的节流函数。\n */\nexport function throttle<T extends (...agrs: any[]) => any>(\n func: T,\n delay: number\n): T {\n let lastExecutedTime: number = 0;\n\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n const context = this;\n const currentTime = Date.now();\n\n if (currentTime - lastExecutedTime >= delay) {\n func.apply(context, args);\n lastExecutedTime = currentTime;\n }\n } as T;\n}\n\n/**\n * 创建一个延迟执行回调函数并返回 Promise 的函数。\n *\n * @param callback - 需要执行的回调函数。\n * @param delay - 延迟的毫秒数,默认为 0。\n * @returns 一个 Promise 对象,该对象在回调函数执行后解析。\n */\nexport function delayExecution<T>(\n callback: () => T,\n delay: number = 0\n): Promise<T> {\n return new Promise<T>((resolve) => {\n if (delay === 0) {\n resolve(callback());\n } else {\n setTimeout(() => {\n resolve(callback());\n }, delay);\n }\n });\n}\n","import { generateStableUniqueKey } from \"./generateStableUniqueKey\";\nimport { cloneDeep } from \"./cloneDeep\";\nimport { AsyncFunction } from \"./type\";\n\nconst cache: Record<string, any> = {};\nfunction getCachedData<T = any>(apiKey: string) {\n return cache[apiKey] as T;\n}\n\nexport interface Setting {\n timeout?: number;\n timeoutResult?: any;\n identifier?: string;\n}\n\nconst defalutSetting: Setting = {\n timeout: 60000,\n timeoutResult: { code: 408, msg: \"请求超时\" },\n identifier: \"\",\n};\n\n/**\n * 为异步函数添加缓存功能。\n *\n * 该函数根据函数参数、函数名和一个可选的标识符来缓存异步函数的结果。\n * 如果结果已经缓存,则返回缓存的结果。如果函数正在执行中,则等待结果返回,并使用一个超时机制防止无限等待。\n *\n * @template Args - 函数参数的类型。\n * @template Promise<T> - 函数返回值的类型。\n * @param {AsyncFunction<Args, T>} func - 需要包装的异步函数。\n * @param {Setting} [setting=defalutSetting] - 可选的缓存设置。\n * @returns {AsyncFunction<Args, T>} - 带有缓存功能的包装函数,返回类型为 `Promise<T>`。\n */\nexport function cacheWrapper<Args extends any[], T>(\n func: AsyncFunction<Args, T>,\n setting: Setting = defalutSetting\n): AsyncFunction<Args, T> {\n return function (...args: Args): Promise<T> {\n const apiKey: string =\n generateStableUniqueKey(args) + func.name + (setting.identifier || \"\"); //缓存key\n\n if (cache[apiKey]) {\n return Promise.resolve(cloneDeep(getCachedData<T>(apiKey)));\n }\n\n const apiLoadingKey: string = apiKey + \"_l_o_a_d_i_n_g_\"; //缓存loading key\n\n if (cache[apiLoadingKey]) {\n const _setting = Object.assign({}, defalutSetting, setting);\n return new Promise((resolve) => {\n const startTime = Date.now();\n const timer = setInterval(() => {\n if (cache[apiKey]) {\n clearInterval(timer);\n resolve(cloneDeep(getCachedData<T>(apiKey)));\n } else if (Date.now() - startTime > _setting.timeout!) {\n cache[apiLoadingKey] = false;\n clearInterval(timer);\n resolve(cloneDeep(_setting.timeoutResult));\n }\n }, 100);\n });\n }\n cache[apiLoadingKey] = true;\n\n return func(...args)\n .then((res) => {\n // 缓存原始数据或其克隆,避免数据被释放\n cache[apiKey] = res;\n return cloneDeep(cache[apiKey]);\n })\n .catch((error: any) => {\n throw error;\n })\n .finally(() => {\n cache[apiLoadingKey] = false;\n });\n };\n}\n","/**\n * 定义一个类型,用于扩展函数类型,增加一个可选的 isExecuting 属性\n */\nexport type SingleExecutionFunction<T extends (...args: any[]) => any> = T & {\n isExecuting?: boolean;\n};\n\n/**\n * 创建一个有执行状态的函数,该函数在前一次调用未完成时不会被再次调用。\n *\n * @param func - 需要包裹的函数。\n * @returns 一个增强版的函数,该函数具有 isExecuting 属性。\n */\nexport function singleExecutionWrapper<T extends (...args: any[]) => any>(\n func: T\n): SingleExecutionFunction<T> {\n const singleExecutionFn: SingleExecutionFunction<T> = function (\n ...args: Parameters<T>\n ): ReturnType<T> | undefined {\n if (singleExecutionFn.isExecuting) {\n console.log(`Function(${func.name}) is executing.`);\n return;\n }\n singleExecutionFn.isExecuting = true;\n\n let result: ReturnType<T>;\n\n try {\n result = func(...args);\n if ((result as any) instanceof Promise) {\n result.finally(() => {\n singleExecutionFn.isExecuting = false;\n });\n } else {\n singleExecutionFn.isExecuting = false;\n }\n } catch (error) {\n singleExecutionFn.isExecuting = false;\n throw error;\n }\n\n return result;\n } as SingleExecutionFunction<T>;\n\n singleExecutionFn.isExecuting = false;\n\n return singleExecutionFn;\n}\n","/**\n * 表示 DOM 中可能的子元素类型。\n */\nexport type ChildrenType =\n | DomOptionsType\n | HTMLElement\n | SVGElement\n | Text\n | string;\n\n/**\n * 表示创建 DOM 元素的选项类型。\n */\nexport type DomOptionsType = {\n /**\n * 要创建的元素的标签名。默认为 \"div\"。\n */\n tag?: string;\n\n /**\n * 要附加到创建的元素的子元素。可以是单个子元素或子元素数组。\n */\n children?: ChildrenType | ChildrenType[];\n\n /**\n * 要设置在创建的元素上的属性。\n */\n props?: Record<string, any>;\n\n /**\n * 要设置在创建的元素上的属性。\n */\n attrs?: Record<string, string | boolean>;\n\n /**\n * 要应用于创建的元素的样式。\n */\n styles?: Record<string, string | number>;\n};\n\n/**\n * 设置 HTML 元素的样式属性。\n *\n * @param element - 要设置样式的 HTML 元素。\n * @param property - CSS 属性名,可以是驼峰命名法(camelCase)或连字符命名法(kebab-case)。\n * @param value - 要设置的属性值。\n * @param important - 可选参数,布尔值,表示是否将属性设置为 `important` 优先级,默认为 `false`。\n */\nfunction setStyle(\n element: HTMLElement,\n property: string,\n value: string | number,\n important: boolean = false\n): void {\n if (property in element.style) {\n (element.style as any)[property] = value;\n } else {\n const priority = important ? \"important\" : \"\";\n element.style.setProperty(property, String(value), priority);\n }\n}\n\n/**\n * 使用指定选项创建一个 DOM 元素。\n *\n * @param options - 创建 DOM 元素的选项。\n *\n * @returns 创建的 DOM 元素。\n *\n * @remarks\n * 此函数旨在浏览器环境中使用。\n *\n * @example\n * ```typescript\n * const element = createElement({\n * tag: 'button',\n * children: '点击我',\n * attrs: { id: 'myButton' },\n * styles: { color: 'red' }\n * });\n * document.body.appendChild(element);\n * ```\n */\nexport function createElement({\n tag = \"div\",\n children = [],\n props = {},\n attrs = {},\n styles = {},\n}: DomOptionsType = {}): HTMLElement {\n const ele = document.createElement(tag);\n\n // 设置属性\n Object.assign(ele, props);\n\n // 设置属性\n for (const [key, value] of Object.entries(attrs)) {\n if (value !== false) {\n ele.setAttribute(key, value as string);\n }\n }\n\n // 设置样式\n for (const [key, value] of Object.entries(styles)) {\n setStyle(ele, key, value);\n }\n\n // 处理子元素\n const childArray = Array.isArray(children) ? children : [children];\n for (const child of childArray) {\n if (!child) continue;\n\n if (typeof child === \"object\") {\n if (child instanceof HTMLElement || child instanceof Text) {\n ele.appendChild(child);\n } else {\n ele.appendChild(createElement(child as DomOptionsType));\n }\n } else {\n ele.appendChild(document.createTextNode(child));\n }\n }\n\n return ele;\n}\n\ntype SvgElement = {\n tag: string;\n attributes?: Record<string, string>;\n children?: SvgElement | SvgElement[] | string;\n};\n\ntype SvgOptions = {\n width?: number;\n height?: number;\n};\n\n/**\n * 创建一个 SVG 元素。\n *\n * @param {SvgElement[] | SvgElement | string} elements - 要创建的 SVG 元素,可以是对象数组、单个对象或 innerHTML 字符串。\n * @param {SvgOptions} [options] - SVG 的配置选项,包括宽度和高度。\n * @returns {SVGElement} - 创建的 SVG 元素。\n *\n * @example\n * // 使用嵌套对象\n * const svg1 = createSvg(\n * {\n * tag: 'svg',\n * children: [\n * { tag: 'circle', attributes: { cx: '16', cy: '16', r: '10', fill: 'red' } },\n * { tag: 'g', children:\n * { tag: 'text', attributes: { x: '10', y: '20', fill: 'black' }, children: 'Hello' }\n * }\n * ]\n * },\n * { width: 64, height: 64 }\n * );\n * document.body.appendChild(svg1);\n *\n * @example\n * // 使用 innerHTML\n * const svg2 = createSvg(\n * `<circle cx=\"16\" cy=\"16\" r=\"10\" fill=\"red\"></circle>\n * <text x=\"10\" y=\"20\" fill=\"black\">Hello</text>`\n * );\n * document.body.appendChild(svg2);\n */\nexport function createSvg(\n elements: SvgElement[] | SvgElement | string,\n options?: SvgOptions\n) {\n // 默认宽度和高度\n const { width = 32, height = 32 } = options || {};\n\n // 创建一个 SVG 元素\n const svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n\n // 设置 SVG 的宽度和高度\n svg.setAttribute(\"width\", width.toString());\n svg.setAttribute(\"height\", height.toString());\n svg.setAttribute(\"viewBox\", `0 0 ${width} ${height}`);\n\n if (typeof elements === \"string\") {\n // 如果 elements 是字符串,直接设置为 SVG 的 innerHTML\n svg.innerHTML = elements;\n } else {\n // 处理 SvgElement 或 SvgElement[]\n const elementArray = Array.isArray(elements) ? elements : [elements];\n\n elementArray.forEach((element) => {\n svg.appendChild(createSvgElement(element));\n });\n }\n\n // 返回创建好的 SVG 元素\n return svg;\n}\n\n/**\n * 递归创建 SVG 子元素。\n *\n * @param {SvgElement} element - 要创建的 SVG 子元素。\n * @returns {SVGElement} - 创建的 SVG 子元素。\n */\nfunction createSvgElement(element: SvgElement) {\n const { tag, attributes, children } = element;\n const el = document.createElementNS(\"http://www.w3.org/2000/svg\", tag);\n\n if (attributes) {\n for (const [key, value] of Object.entries(attributes)) {\n el.setAttribute(key, value);\n }\n }\n\n if (typeof children === \"string\") {\n el.textContent = children;\n } else if (children) {\n const childArray = Array.isArray(children) ? children : [children];\n childArray.forEach((child) => {\n el.appendChild(createSvgElement(child));\n });\n }\n\n return el;\n}\n","/**\n * 将指定的 DOM 元素滚动到底部。\n * 使用 setTimeout 确保在当前调用栈之后执行。\n *\n * @param {HTMLElement} dom - 要滚动的 DOM 元素。\n */\nexport function scrollToBottom(dom: HTMLElement) {\n if (dom) {\n setTimeout(() => {\n // 设置滚动条位置为元素的最大滚动高度,滚动到底部\n dom.scrollTop = dom.scrollHeight;\n }, 0);\n }\n}\n\n/**\n * 如果用户未与 DOM 元素交互,则将其滚动到底部。\n * 如果尚未设置事件监听器,则设置一个以跟踪用户滚动交互。\n *\n * @param {HTMLElement} dom - 可能需要滚动的 DOM 元素。\n */\nexport function scrollToBottomIfNeeded(dom: HTMLElement): void {\n if (!dom) {\n return;\n }\n // 检查是否已设置滚动监听器\n if (dom.dataset.isListeningForUserScroll !== \"true\") {\n listenForUserScroll(dom);\n dom.dataset.isListeningForUserScroll = \"true\";\n }\n\n // 如果用户未与滚动条交互,则滚动到底部\n if (dom.dataset.userInteracted !== \"true\") {\n scrollToBottom(dom);\n }\n}\n\n/**\n * 更新用户是否与滚动条交互的状态。\n *\n * @param {HTMLElement} dom - 要更新状态的 DOM 元素。\n * @param {boolean} inter - 用户是否与滚动条交互。\n */\nfunction userInteractedWithScroll(dom: HTMLElement, inter: boolean): void {\n // 根据用户交互状态更新数据属性\n dom.dataset.userInteracted = inter ? \"true\" : \"false\";\n}\n\n/**\n * 为 DOM 元素设置滚动事件监听器。\n * 当用户滚动时,更新交互状态。\n *\n * @param {HTMLElement} dom - 要监听滚动事件的 DOM 元素。\n */\nfunction listenForUserScroll(dom: HTMLElement): void {\n if (!dom) {\n return;\n }\n dom.addEventListener(\"scroll\", () => {\n // 检查用户是否滚动到接近底部\n if (dom.scrollTop + dom.clientHeight < dom.scrollHeight - 5) {\n // 用户已滚动,更新交互状态\n userInteractedWithScroll(dom, true);\n } else {\n // 用户未滚动到接近底部\n userInteractedWithScroll(dom, false);\n }\n });\n}\n"],"names":["isCloneable","obj","clone","isPrimitive","value","type","getGlobal","globalThis","self","window","global","this","generateStableUniqueKey","params","String","JSON","stringify","_key","Array","isArray","Object","keys","sort","reduce","pre","cur","cloneDeep","map","item","newObj","key","prototype","hasOwnProperty","call","debounce","func","wait","timeout","_arguments","arguments","context","clearTimeout","setTimeout","apply","slice","throttle","delay","lastExecutedTime","currentTime","Date","now","delayExecution","callback","Promise","resolve","cache","getCachedData","apiKey","defalutSetting","timeoutResult","code","msg","identifier","cacheWrapper","setting","args","name","apiLoadingKey","_setting","assign","startTime","timer","setInterval","clearInterval","then","res","error","singleExecutionWrapper","singleExecutionFn","isExecuting","result","console","log","setStyle","element","property","important","style","priority","setProperty","createElement","_temp","_ref","_ref$tag","tag","_ref$children","children","_ref$props","props","_ref$attrs","attrs","_ref$styles","styles","ele","document","_i","_Object$entries","entries","length","_Object$entries$_i","setAttribute","_i2","_Object$entries2","_Object$entries2$_i","_step","_iterator","_createForOfIteratorHelperLoose","done","child","HTMLElement","Text","appendChild","createTextNode","createSvg","elements","options","_ref2","_ref2$width","width","_ref2$height","height","svg","createElementNS","toString","innerHTML","forEach","createSvgElement","attributes","el","_i3","_Object$entries3","_Object$entries3$_i","textContent","scrollToBottom","dom","scrollTop","scrollHeight","scrollToBottomIfNeeded","dataset","isListeningForUserScroll","addEventListener","inter","userInteracted","userInteractedWithScroll","clientHeight","listenForUserScroll"],"mappings":"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"}
1
+ {"version":3,"file":"index.module.js","sources":["../src/common/type.ts","../src/common/getGlobal.ts","../src/common/generateStableUniqueKey.ts","../src/common/cloneDeep.ts","../src/common/utils.ts","../src/common/cacheWrapper.ts","../src/common/singleExecutionWrapper.ts","../src/browser/dom.ts","../src/browser/scroll.ts"],"sourcesContent":["/**\n * 异步函数类型。\n *\n * @template Args - 表示函数参数的类型数组。\n * @template T - 表示函数返回的 Promise 解析后的类型。\n *\n * @param args - 函数的参数。\n * @returns 一个 Promise 对象,解析后的值类型为 T。\n */\nexport type AsyncFunction<Args extends any[], T> = (\n ...args: Args\n) => Promise<T>;\n\n/**\n * 表示一个可以克隆自身的对象接口。\n *\n * @interface Cloneable\n */\nexport interface Cloneable {\n /**\n * 创建并返回当前对象的一个副本。\n *\n * @returns {this} 当前对象的一个副本。\n */\n clone(): this;\n}\n\n/**\n *\n * 检查一个对象是否实现了 Cloneable 接口。\n *\n * 这个函数是一个类型保护函数,它会在类型检查时将传入的对象类型缩小为 Cloneable。\n *\n * @param {any} obj - 要检查的对象。\n * @returns {obj is Cloneable} 如果对象实现了 Cloneable 接口,则返回 true;否则返回 false。\n */\nexport function isCloneable(obj: any): obj is Cloneable {\n return typeof obj?.clone === \"function\";\n}\n\n/**\n * 检查一个值是否是原始类型(primitive type)。\n *\n * 这个函数是一个类型保护函数,它会在类型检查时将传入的值类型缩小为原始类型之一:string, number, boolean, null 或 undefined。\n *\n * @param {any} value - 要检查的值。\n * @returns {value is string | number | boolean | null | undefined} 如果值是原始类型,则返回 true;否则返回 false。\n */\nexport function isPrimitive(\n value: any\n): value is string | number | boolean | null | undefined {\n const type = typeof value;\n return (\n value === null ||\n type === \"string\" ||\n type === \"number\" ||\n type === \"boolean\" ||\n type === \"undefined\"\n );\n}\n","declare var global: typeof globalThis;\n\n/**\n * 获取当前环境的全局对象。\n *\n * 在不同的 JavaScript 运行环境中,全局对象的名称不同:\n * - 在浏览器环境中,全局对象是 `window`。\n * - 在 Node.js 环境中,全局对象是 `global`。\n * - 在 Web Worker 环境中,全局对象是 `self`。\n *\n * 这个函数提供了一种统一的方式来获取当前环境的全局对象。\n *\n * @returns 当前环境的全局对象。\n */\nexport function getGlobal(this: any) {\n if (typeof globalThis !== \"undefined\") {\n return globalThis;\n }\n\n if (typeof self !== \"undefined\") {\n return self;\n }\n\n if (typeof window !== \"undefined\") {\n return window;\n }\n\n if (typeof global !== \"undefined\") {\n return global;\n }\n\n // 如果以上都不符合,则返回 this\n return this;\n}\n","import { isPrimitive } from \"./type\";\n\n/**\n * 为给定的参数生成一个稳定且唯一的键。\n *\n * 该函数确保生成的键是确定性的,即相同的输入总是会生成相同的输出。\n * 这在缓存、记忆化或任何需要一致键的场景中非常有用。\n *\n * @param params - 用于生成键的参数。可以是任何类型。\n * @returns 表示输入参数的稳定且唯一的字符串键。\n */\nexport function generateStableUniqueKey(params: any) {\n if (isPrimitive(params)) {\n return String(params);\n }\n return JSON.stringify(params, function (_key: string | number, value: any) {\n if (typeof value === \"object\" && value !== null && !Array.isArray(value)) {\n return Object.keys(value)\n .sort()\n .reduce((pre: any, cur: string) => {\n pre[cur] = value[cur];\n return pre;\n }, {});\n }\n return value;\n });\n}\n","import { isCloneable } from \"./type\";\n\n/**\n * 深度克隆一个对象或数组。\n *\n * @param {T} obj - 要克隆的对象或数组。\n * @returns {T} 克隆后的对象或数组。\n */\nexport function cloneDeep<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n\n if (isCloneable(obj)) {\n return obj.clone();\n }\n\n // 处理数组\n if (Array.isArray(obj)) {\n return obj.map((item) => cloneDeep(item)) as unknown as T;\n }\n\n const newObj: { [key: string]: any } = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n newObj[key] = cloneDeep(obj[key]);\n }\n }\n return newObj as T;\n}\n","/**\n * 创建一个防抖函数,该函数会在最后一次调用后的指定时间间隔后执行。\n *\n * @param func - 需要防抖处理的函数。\n * @param wait - 延迟的毫秒数。\n * @returns 一个新的防抖函数。\n */\nexport function debounce<T extends (...args: any[]) => void>(\n func: T,\n wait: number\n): T {\n let timeout: ReturnType<typeof setTimeout> | null = null;\n\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n const context = this;\n\n // 如果已经设定了调用,取消之前的调用\n if (timeout !== null) {\n clearTimeout(timeout);\n }\n\n // 设定一个新的调用,等待指定的时间后执行\n timeout = setTimeout(() => {\n func.apply(context, args);\n timeout = null; // 确保能够在下次触发时重新设定定时器\n }, wait);\n } as T;\n}\n\n/**\n * 创建一个节流函数,该函数会在每个指定的时间间隔内最多执行一次。\n *\n * @param func - 需要节流处理的函数。\n * @param delay - 时间间隔的毫秒数。\n * @returns 一个新的节流函数。\n */\nexport function throttle<T extends (...agrs: any[]) => any>(\n func: T,\n delay: number\n): T {\n let lastExecutedTime: number = 0;\n\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n const context = this;\n const currentTime = Date.now();\n\n if (currentTime - lastExecutedTime >= delay) {\n func.apply(context, args);\n lastExecutedTime = currentTime;\n }\n } as T;\n}\n\n/**\n * 创建一个延迟执行回调函数并返回 Promise 的函数。\n *\n * @param callback - 需要执行的回调函数。\n * @param delay - 延迟的毫秒数,默认为 0。\n * @returns 一个 Promise 对象,该对象在回调函数执行后解析。\n */\nexport function delayExecution<T>(\n callback: () => T,\n delay: number = 0\n): Promise<T> {\n return new Promise<T>((resolve) => {\n if (delay === 0) {\n resolve(callback());\n } else {\n setTimeout(() => {\n resolve(callback());\n }, delay);\n }\n });\n}\n","import { generateStableUniqueKey } from \"./generateStableUniqueKey\";\nimport { cloneDeep } from \"./cloneDeep\";\nimport { AsyncFunction } from \"./type\";\n\nconst cache: Record<string, any> = {};\nfunction getCachedData<T = any>(apiKey: string) {\n return cache[apiKey] as T;\n}\n\nexport interface Setting {\n timeout?: number;\n timeoutResult?: any;\n identifier?: string;\n}\n\nconst defalutSetting: Setting = {\n timeout: 60000,\n timeoutResult: { code: 408, msg: \"请求超时\" },\n identifier: \"\",\n};\n\n/**\n * 为异步函数添加缓存功能。\n *\n * 该函数根据函数参数、函数名和一个可选的标识符来缓存异步函数的结果。\n * 如果结果已经缓存,则返回缓存的结果。如果函数正在执行中,则等待结果返回,并使用一个超时机制防止无限等待。\n *\n * @template Args - 函数参数的类型。\n * @template Promise<T> - 函数返回值的类型。\n * @param {AsyncFunction<Args, T>} func - 需要包装的异步函数。\n * @param {Setting} [setting=defalutSetting] - 可选的缓存设置。\n * @returns {AsyncFunction<Args, T>} - 带有缓存功能的包装函数,返回类型为 `Promise<T>`。\n */\nexport function cacheWrapper<Args extends any[], T>(\n func: AsyncFunction<Args, T>,\n setting: Setting = defalutSetting\n): AsyncFunction<Args, T> {\n return function (...args: Args): Promise<T> {\n const apiKey: string =\n generateStableUniqueKey(args) + func.name + (setting.identifier || \"\"); //缓存key\n\n if (cache[apiKey]) {\n return Promise.resolve(cloneDeep(getCachedData<T>(apiKey)));\n }\n\n const apiLoadingKey: string = apiKey + \"_l_o_a_d_i_n_g_\"; //缓存loading key\n\n if (cache[apiLoadingKey]) {\n const _setting = Object.assign({}, defalutSetting, setting);\n return new Promise((resolve) => {\n const startTime = Date.now();\n const timer = setInterval(() => {\n if (cache[apiKey]) {\n clearInterval(timer);\n resolve(cloneDeep(getCachedData<T>(apiKey)));\n } else if (Date.now() - startTime > _setting.timeout!) {\n cache[apiLoadingKey] = false;\n clearInterval(timer);\n resolve(cloneDeep(_setting.timeoutResult));\n }\n }, 100);\n });\n }\n cache[apiLoadingKey] = true;\n\n return func(...args)\n .then((res) => {\n // 缓存原始数据或其克隆,避免数据被释放\n cache[apiKey] = res;\n return cloneDeep(cache[apiKey]);\n })\n .catch((error: any) => {\n throw error;\n })\n .finally(() => {\n cache[apiLoadingKey] = false;\n });\n };\n}\n","/**\n * 定义一个类型,用于扩展函数类型,增加一个可选的 isExecuting 属性\n */\nexport type SingleExecutionFunction<T extends (...args: any[]) => any> = T & {\n isExecuting?: boolean;\n};\n\n/**\n * 创建一个有执行状态的函数,该函数在前一次调用未完成时不会被再次调用。\n *\n * @param func - 需要包裹的函数。\n * @returns 一个增强版的函数,该函数具有 isExecuting 属性。\n */\nexport function singleExecutionWrapper<T extends (...args: any[]) => any>(\n func: T\n): SingleExecutionFunction<T> {\n const singleExecutionFn: SingleExecutionFunction<T> = function (\n ...args: Parameters<T>\n ): ReturnType<T> | undefined {\n if (singleExecutionFn.isExecuting) {\n console.log(`Function(${func.name}) is executing.`);\n return;\n }\n singleExecutionFn.isExecuting = true;\n\n let result: ReturnType<T>;\n\n try {\n result = func(...args);\n if ((result as any) instanceof Promise) {\n result.finally(() => {\n singleExecutionFn.isExecuting = false;\n });\n } else {\n singleExecutionFn.isExecuting = false;\n }\n } catch (error) {\n singleExecutionFn.isExecuting = false;\n throw error;\n }\n\n return result;\n } as SingleExecutionFunction<T>;\n\n singleExecutionFn.isExecuting = false;\n\n return singleExecutionFn;\n}\n","/**\n * 表示 DOM 中可能的子元素类型。\n */\nexport type ChildrenType =\n | DomOptionsType\n | Element\n | string;\n\n/**\n * 表示创建 DOM 元素的选项类型。\n */\nexport type DomOptionsType = {\n /**\n * 要创建的元素的标签名。默认为 \"div\"。\n */\n tag?: string;\n\n /**\n * 要附加到创建的元素的子元素。可以是单个子元素或子元素数组。\n */\n children?: ChildrenType | ChildrenType[];\n\n /**\n * 要设置在创建的元素上的属性。\n */\n props?: Record<string, any>;\n\n /**\n * 要设置在创建的元素上的属性。\n */\n attrs?: Record<string, string | boolean>;\n\n /**\n * 要应用于创建的元素的样式。\n */\n styles?: Record<string, string | number>;\n};\n\n/**\n * 设置 HTML 元素的样式属性。\n *\n * @param element - 要设置样式的 HTML 元素。\n * @param property - CSS 属性名,可以是驼峰命名法(camelCase)或连字符命名法(kebab-case)。\n * @param value - 要设置的属性值。\n * @param important - 可选参数,布尔值,表示是否将属性设置为 `important` 优先级,默认为 `false`。\n */\nfunction setStyle(\n element: HTMLElement | SVGElement,\n property: string,\n value: string | number,\n important: boolean = false\n): void {\n if (property in element.style) {\n (element.style as any)[property] = value;\n } else {\n const priority = important ? \"important\" : \"\";\n element.style.setProperty(property, String(value), priority);\n }\n}\n\n/**\n * 使用指定选项创建一个 DOM 元素。\n *\n * @param options - 创建 DOM 元素的选项。\n *\n * @returns 创建的 DOM 元素。\n *\n * @remarks\n * 此函数旨在浏览器环境中使用。\n *\n * @example\n * ```typescript\n * const element = createElement({\n * tag: 'button',\n * children: '点击我',\n * attrs: { id: 'myButton' },\n * styles: { color: 'red' }\n * });\n * document.body.appendChild(element);\n * ```\n */\nexport function createElement({\n tag = \"div\",\n children = [],\n props = {},\n attrs = {},\n styles = {},\n}: DomOptionsType = {}): Element {\n const ele = document.createElement(tag);\n\n // 设置属性\n Object.assign(ele, props);\n\n // 设置属性\n for (const [key, value] of Object.entries(attrs)) {\n if (value !== false) {\n ele.setAttribute(key, value as string);\n }\n }\n\n // 设置样式\n for (const [key, value] of Object.entries(styles)) {\n setStyle(ele, key, value);\n }\n\n // 处理子元素\n const childArray = Array.isArray(children) ? children : [children];\n for (const child of childArray) {\n if (!child) continue;\n\n if (typeof child === \"object\") {\n if (child instanceof Element) {\n ele.appendChild(child);\n } else {\n ele.appendChild(createElement(child as DomOptionsType));\n }\n } else {\n ele.appendChild(document.createTextNode(child));\n }\n }\n\n return ele;\n}\n\ntype SvgElement = {\n tag: string;\n attributes?: Record<string, string>;\n children?: SvgElement | SvgElement[] | string;\n};\n\ntype SvgOptions = {\n width?: number;\n height?: number;\n};\n\n/**\n * 创建一个 SVG 元素。\n *\n * @param {SvgElement[] | SvgElement | string} elements - 要创建的 SVG 元素,可以是对象数组、单个对象或 innerHTML 字符串。\n * @param {SvgOptions} [options] - SVG 的配置选项,包括宽度和高度。\n * @returns {SVGElement} - 创建的 SVG 元素。\n *\n * @example\n * // 使用嵌套对象\n * const svg1 = createSvg(\n * {\n * tag: 'svg',\n * children: [\n * { tag: 'circle', attributes: { cx: '16', cy: '16', r: '10', fill: 'red' } },\n * { tag: 'g', children:\n * { tag: 'text', attributes: { x: '10', y: '20', fill: 'black' }, children: 'Hello' }\n * }\n * ]\n * },\n * { width: 64, height: 64 }\n * );\n * document.body.appendChild(svg1);\n *\n * @example\n * // 使用 innerHTML\n * const svg2 = createSvg(\n * `<circle cx=\"16\" cy=\"16\" r=\"10\" fill=\"red\"></circle>\n * <text x=\"10\" y=\"20\" fill=\"black\">Hello</text>`\n * );\n * document.body.appendChild(svg2);\n */\nexport function createSvg(\n elements: SvgElement[] | SvgElement | string,\n options?: SvgOptions\n) {\n // 默认宽度和高度\n const { width = 32, height = 32 } = options || {};\n\n // 创建一个 SVG 元素\n const svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n\n // 设置 SVG 的宽度和高度\n svg.setAttribute(\"width\", width.toString());\n svg.setAttribute(\"height\", height.toString());\n svg.setAttribute(\"viewBox\", `0 0 ${width} ${height}`);\n\n if (typeof elements === \"string\") {\n // 如果 elements 是字符串,直接设置为 SVG 的 innerHTML\n svg.innerHTML = elements;\n } else {\n // 处理 SvgElement 或 SvgElement[]\n const elementArray = Array.isArray(elements) ? elements : [elements];\n\n elementArray.forEach((element) => {\n svg.appendChild(createSvgElement(element));\n });\n }\n\n // 返回创建好的 SVG 元素\n return svg;\n}\n\n/**\n * 递归创建 SVG 子元素。\n *\n * @param {SvgElement} element - 要创建的 SVG 子元素。\n * @returns {SVGElement} - 创建的 SVG 子元素。\n */\nfunction createSvgElement(element: SvgElement) {\n const { tag, attributes, children } = element;\n const el = document.createElementNS(\"http://www.w3.org/2000/svg\", tag);\n\n if (attributes) {\n for (const [key, value] of Object.entries(attributes)) {\n el.setAttribute(key, value);\n }\n }\n\n if (typeof children === \"string\") {\n el.textContent = children;\n } else if (children) {\n const childArray = Array.isArray(children) ? children : [children];\n childArray.forEach((child) => {\n el.appendChild(createSvgElement(child));\n });\n }\n\n return el;\n}\n","/**\n * 将指定的 DOM 元素滚动到底部。\n * 使用 setTimeout 确保在当前调用栈之后执行。\n *\n * @param {HTMLElement} dom - 要滚动的 DOM 元素。\n */\nexport function scrollToBottom(dom: HTMLElement) {\n if (dom) {\n setTimeout(() => {\n // 设置滚动条位置为元素的最大滚动高度,滚动到底部\n dom.scrollTop = dom.scrollHeight;\n }, 0);\n }\n}\n\n/**\n * 如果用户未与 DOM 元素交互,则将其滚动到底部。\n * 如果尚未设置事件监听器,则设置一个以跟踪用户滚动交互。\n *\n * @param {HTMLElement} dom - 可能需要滚动的 DOM 元素。\n */\nexport function scrollToBottomIfNeeded(dom: HTMLElement): void {\n if (!dom) {\n return;\n }\n // 检查是否已设置滚动监听器\n if (dom.dataset.isListeningForUserScroll !== \"true\") {\n listenForUserScroll(dom);\n dom.dataset.isListeningForUserScroll = \"true\";\n }\n\n // 如果用户未与滚动条交互,则滚动到底部\n if (dom.dataset.userInteracted !== \"true\") {\n scrollToBottom(dom);\n }\n}\n\n/**\n * 更新用户是否与滚动条交互的状态。\n *\n * @param {HTMLElement} dom - 要更新状态的 DOM 元素。\n * @param {boolean} inter - 用户是否与滚动条交互。\n */\nfunction userInteractedWithScroll(dom: HTMLElement, inter: boolean): void {\n // 根据用户交互状态更新数据属性\n dom.dataset.userInteracted = inter ? \"true\" : \"false\";\n}\n\n/**\n * 为 DOM 元素设置滚动事件监听器。\n * 当用户滚动时,更新交互状态。\n *\n * @param {HTMLElement} dom - 要监听滚动事件的 DOM 元素。\n */\nfunction listenForUserScroll(dom: HTMLElement): void {\n if (!dom) {\n return;\n }\n dom.addEventListener(\"scroll\", () => {\n // 检查用户是否滚动到接近底部\n if (dom.scrollTop + dom.clientHeight < dom.scrollHeight - 5) {\n // 用户已滚动,更新交互状态\n userInteractedWithScroll(dom, true);\n } else {\n // 用户未滚动到接近底部\n userInteractedWithScroll(dom, false);\n }\n });\n}\n"],"names":["isCloneable","obj","clone","isPrimitive","value","type","getGlobal","globalThis","self","window","global","this","generateStableUniqueKey","params","String","JSON","stringify","_key","Array","isArray","Object","keys","sort","reduce","pre","cur","cloneDeep","map","item","newObj","key","prototype","hasOwnProperty","call","debounce","func","wait","timeout","_arguments","arguments","context","clearTimeout","setTimeout","apply","slice","throttle","delay","lastExecutedTime","currentTime","Date","now","delayExecution","callback","Promise","resolve","cache","getCachedData","apiKey","defalutSetting","timeoutResult","code","msg","identifier","cacheWrapper","setting","args","name","apiLoadingKey","_setting","assign","startTime","timer","setInterval","clearInterval","then","res","error","singleExecutionWrapper","singleExecutionFn","isExecuting","result","console","log","setStyle","element","property","important","style","priority","setProperty","createElement","_temp","_ref","_ref$tag","tag","_ref$children","children","_ref$props","props","_ref$attrs","attrs","_ref$styles","styles","ele","document","_i","_Object$entries","entries","length","_Object$entries$_i","setAttribute","_i2","_Object$entries2","_Object$entries2$_i","_step","_iterator","_createForOfIteratorHelperLoose","done","child","Element","appendChild","createTextNode","createSvg","elements","options","_ref2","_ref2$width","width","_ref2$height","height","svg","createElementNS","toString","innerHTML","forEach","createSvgElement","attributes","el","_i3","_Object$entries3","_Object$entries3$_i","textContent","scrollToBottom","dom","scrollTop","scrollHeight","scrollToBottomIfNeeded","dataset","isListeningForUserScroll","addEventListener","inter","userInteracted","userInteractedWithScroll","clientHeight","listenForUserScroll"],"mappings":"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"}
package/dist/index.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t||self).iunLibs={})}(this,function(t){function e(t){return"function"==typeof(null==t?void 0:t.clone)}function n(t){var e=typeof t;return null===t||"string"===e||"number"===e||"boolean"===e||"undefined"===e}function r(t){return n(t)?String(t):JSON.stringify(t,function(t,e){return"object"!=typeof e||null===e||Array.isArray(e)?e:Object.keys(e).sort().reduce(function(t,n){return t[n]=e[n],t},{})})}function i(t){if(null===t||"object"!=typeof t)return t;if(e(t))return t.clone();if(Array.isArray(t))return t.map(function(t){return i(t)});var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=i(t[r]));return n}var o={};function a(t){return o[t]}var u={timeout:6e4,timeoutResult:{code:408,msg:"请求超时"},identifier:""};function l(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=Array(e);n<e;n++)r[n]=t[n];return r}function c(t,e,n,r){if(void 0===r&&(r=!1),e in t.style)t.style[e]=n;else{var i=r?"important":"";t.style.setProperty(e,String(n),i)}}function s(t){var e=t.attributes,n=t.children,r=document.createElementNS("http://www.w3.org/2000/svg",t.tag);if(e)for(var i=0,o=Object.entries(e);i<o.length;i++){var a=o[i];r.setAttribute(a[0],a[1])}return"string"==typeof n?r.textContent=n:n&&(Array.isArray(n)?n:[n]).forEach(function(t){r.appendChild(s(t))}),r}function f(t){t&&setTimeout(function(){t.scrollTop=t.scrollHeight},0)}t.cacheWrapper=function(t,e){return void 0===e&&(e=u),function(){var n=[].slice.call(arguments),l=r(n)+t.name+(e.identifier||"");if(o[l])return Promise.resolve(i(a(l)));var c=l+"_l_o_a_d_i_n_g_";if(o[c]){var s=Object.assign({},u,e);return new Promise(function(t){var e=Date.now(),n=setInterval(function(){o[l]?(clearInterval(n),t(i(a(l)))):Date.now()-e>s.timeout&&(o[c]=!1,clearInterval(n),t(i(s.timeoutResult)))},100)})}return o[c]=!0,t.apply(void 0,n).then(function(t){return o[l]=t,i(o[l])}).catch(function(t){throw t}).finally(function(){o[c]=!1})}},t.cloneDeep=i,t.createElement=function t(e){var n=void 0===e?{}:e,r=n.tag,i=n.children,o=void 0===i?[]:i,a=n.props,u=void 0===a?{}:a,s=n.attrs,f=void 0===s?{}:s,d=n.styles,v=void 0===d?{}:d,p=document.createElement(void 0===r?"div":r);Object.assign(p,u);for(var y=0,g=Object.entries(f);y<g.length;y++){var h=g[y],m=h[1];!1!==m&&p.setAttribute(h[0],m)}for(var b=0,w=Object.entries(v);b<w.length;b++){var A=w[b];c(p,A[0],A[1])}for(var x,E=function(t){var e="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(e)return(e=e.call(t)).next.bind(e);if(Array.isArray(t)||(e=function(t,e){if(t){if("string"==typeof t)return l(t,e);var n={}.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?l(t,e):void 0}}(t))){e&&(t=e);var n=0;return function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(Array.isArray(o)?o:[o]);!(x=E()).done;){var T=x.value;T&&("object"==typeof T?T instanceof HTMLElement||T instanceof Text?p.appendChild(T):p.appendChild(t(T)):p.appendChild(document.createTextNode(T)))}return p},t.createSvg=function(t,e){var n=e||{},r=n.width,i=void 0===r?32:r,o=n.height,a=void 0===o?32:o,u=document.createElementNS("http://www.w3.org/2000/svg","svg");return u.setAttribute("width",i.toString()),u.setAttribute("height",a.toString()),u.setAttribute("viewBox","0 0 "+i+" "+a),"string"==typeof t?u.innerHTML=t:(Array.isArray(t)?t:[t]).forEach(function(t){u.appendChild(s(t))}),u},t.debounce=function(t,e){var n=null;return function(){var r=arguments,i=this;null!==n&&clearTimeout(n),n=setTimeout(function(){t.apply(i,[].slice.call(r)),n=null},e)}},t.delayExecution=function(t,e){return void 0===e&&(e=0),new Promise(function(n){0===e?n(t()):setTimeout(function(){n(t())},e)})},t.generateStableUniqueKey=r,t.getGlobal=function(){return"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:this},t.isCloneable=e,t.isPrimitive=n,t.scrollToBottom=f,t.scrollToBottomIfNeeded=function(t){t&&("true"!==t.dataset.isListeningForUserScroll&&(function(t){t&&t.addEventListener("scroll",function(){!function(t,e){t.dataset.userInteracted=e?"true":"false"}(t,t.scrollTop+t.clientHeight<t.scrollHeight-5)})}(t),t.dataset.isListeningForUserScroll="true"),"true"!==t.dataset.userInteracted&&f(t))},t.singleExecutionWrapper=function(t){var e=function(){if(!e.isExecuting){var n;e.isExecuting=!0;try{(n=t.apply(void 0,[].slice.call(arguments)))instanceof Promise?n.finally(function(){e.isExecuting=!1}):e.isExecuting=!1}catch(t){throw e.isExecuting=!1,t}return n}console.log("Function("+t.name+") is executing.")};return e.isExecuting=!1,e},t.throttle=function(t,e){var n=0;return function(){var r=Date.now();r-n>=e&&(t.apply(this,[].slice.call(arguments)),n=r)}}});
1
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t||self).iunLibs={})}(this,function(t){function e(t){return"function"==typeof(null==t?void 0:t.clone)}function n(t){var e=typeof t;return null===t||"string"===e||"number"===e||"boolean"===e||"undefined"===e}function r(t){return n(t)?String(t):JSON.stringify(t,function(t,e){return"object"!=typeof e||null===e||Array.isArray(e)?e:Object.keys(e).sort().reduce(function(t,n){return t[n]=e[n],t},{})})}function i(t){if(null===t||"object"!=typeof t)return t;if(e(t))return t.clone();if(Array.isArray(t))return t.map(function(t){return i(t)});var n={};for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=i(t[r]));return n}var o={};function a(t){return o[t]}var u={timeout:6e4,timeoutResult:{code:408,msg:"请求超时"},identifier:""};function l(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=Array(e);n<e;n++)r[n]=t[n];return r}function c(t,e,n,r){if(void 0===r&&(r=!1),e in t.style)t.style[e]=n;else{var i=r?"important":"";t.style.setProperty(e,String(n),i)}}function s(t){var e=t.attributes,n=t.children,r=document.createElementNS("http://www.w3.org/2000/svg",t.tag);if(e)for(var i=0,o=Object.entries(e);i<o.length;i++){var a=o[i];r.setAttribute(a[0],a[1])}return"string"==typeof n?r.textContent=n:n&&(Array.isArray(n)?n:[n]).forEach(function(t){r.appendChild(s(t))}),r}function f(t){t&&setTimeout(function(){t.scrollTop=t.scrollHeight},0)}t.cacheWrapper=function(t,e){return void 0===e&&(e=u),function(){var n=[].slice.call(arguments),l=r(n)+t.name+(e.identifier||"");if(o[l])return Promise.resolve(i(a(l)));var c=l+"_l_o_a_d_i_n_g_";if(o[c]){var s=Object.assign({},u,e);return new Promise(function(t){var e=Date.now(),n=setInterval(function(){o[l]?(clearInterval(n),t(i(a(l)))):Date.now()-e>s.timeout&&(o[c]=!1,clearInterval(n),t(i(s.timeoutResult)))},100)})}return o[c]=!0,t.apply(void 0,n).then(function(t){return o[l]=t,i(o[l])}).catch(function(t){throw t}).finally(function(){o[c]=!1})}},t.cloneDeep=i,t.createElement=function t(e){var n=void 0===e?{}:e,r=n.tag,i=n.children,o=void 0===i?[]:i,a=n.props,u=void 0===a?{}:a,s=n.attrs,f=void 0===s?{}:s,d=n.styles,v=void 0===d?{}:d,p=document.createElement(void 0===r?"div":r);Object.assign(p,u);for(var y=0,g=Object.entries(f);y<g.length;y++){var h=g[y],m=h[1];!1!==m&&p.setAttribute(h[0],m)}for(var b=0,w=Object.entries(v);b<w.length;b++){var A=w[b];c(p,A[0],A[1])}for(var E,x=function(t){var e="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(e)return(e=e.call(t)).next.bind(e);if(Array.isArray(t)||(e=function(t,e){if(t){if("string"==typeof t)return l(t,e);var n={}.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?l(t,e):void 0}}(t))){e&&(t=e);var n=0;return function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(Array.isArray(o)?o:[o]);!(E=x()).done;){var S=E.value;S&&("object"==typeof S?S instanceof Element?p.appendChild(S):p.appendChild(t(S)):p.appendChild(document.createTextNode(S)))}return p},t.createSvg=function(t,e){var n=e||{},r=n.width,i=void 0===r?32:r,o=n.height,a=void 0===o?32:o,u=document.createElementNS("http://www.w3.org/2000/svg","svg");return u.setAttribute("width",i.toString()),u.setAttribute("height",a.toString()),u.setAttribute("viewBox","0 0 "+i+" "+a),"string"==typeof t?u.innerHTML=t:(Array.isArray(t)?t:[t]).forEach(function(t){u.appendChild(s(t))}),u},t.debounce=function(t,e){var n=null;return function(){var r=arguments,i=this;null!==n&&clearTimeout(n),n=setTimeout(function(){t.apply(i,[].slice.call(r)),n=null},e)}},t.delayExecution=function(t,e){return void 0===e&&(e=0),new Promise(function(n){0===e?n(t()):setTimeout(function(){n(t())},e)})},t.generateStableUniqueKey=r,t.getGlobal=function(){return"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:this},t.isCloneable=e,t.isPrimitive=n,t.scrollToBottom=f,t.scrollToBottomIfNeeded=function(t){t&&("true"!==t.dataset.isListeningForUserScroll&&(function(t){t&&t.addEventListener("scroll",function(){!function(t,e){t.dataset.userInteracted=e?"true":"false"}(t,t.scrollTop+t.clientHeight<t.scrollHeight-5)})}(t),t.dataset.isListeningForUserScroll="true"),"true"!==t.dataset.userInteracted&&f(t))},t.singleExecutionWrapper=function(t){var e=function(){if(!e.isExecuting){var n;e.isExecuting=!0;try{(n=t.apply(void 0,[].slice.call(arguments)))instanceof Promise?n.finally(function(){e.isExecuting=!1}):e.isExecuting=!1}catch(t){throw e.isExecuting=!1,t}return n}console.log("Function("+t.name+") is executing.")};return e.isExecuting=!1,e},t.throttle=function(t,e){var n=0;return function(){var r=Date.now();r-n>=e&&(t.apply(this,[].slice.call(arguments)),n=r)}}});
2
2
  //# sourceMappingURL=index.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../src/common/type.ts","../src/common/generateStableUniqueKey.ts","../src/common/cloneDeep.ts","../src/common/cacheWrapper.ts","../src/browser/dom.ts","../src/browser/scroll.ts","../src/common/utils.ts","../src/common/getGlobal.ts","../src/common/singleExecutionWrapper.ts"],"sourcesContent":["/**\n * 异步函数类型。\n *\n * @template Args - 表示函数参数的类型数组。\n * @template T - 表示函数返回的 Promise 解析后的类型。\n *\n * @param args - 函数的参数。\n * @returns 一个 Promise 对象,解析后的值类型为 T。\n */\nexport type AsyncFunction<Args extends any[], T> = (\n ...args: Args\n) => Promise<T>;\n\n/**\n * 表示一个可以克隆自身的对象接口。\n *\n * @interface Cloneable\n */\nexport interface Cloneable {\n /**\n * 创建并返回当前对象的一个副本。\n *\n * @returns {this} 当前对象的一个副本。\n */\n clone(): this;\n}\n\n/**\n *\n * 检查一个对象是否实现了 Cloneable 接口。\n *\n * 这个函数是一个类型保护函数,它会在类型检查时将传入的对象类型缩小为 Cloneable。\n *\n * @param {any} obj - 要检查的对象。\n * @returns {obj is Cloneable} 如果对象实现了 Cloneable 接口,则返回 true;否则返回 false。\n */\nexport function isCloneable(obj: any): obj is Cloneable {\n return typeof obj?.clone === \"function\";\n}\n\n/**\n * 检查一个值是否是原始类型(primitive type)。\n *\n * 这个函数是一个类型保护函数,它会在类型检查时将传入的值类型缩小为原始类型之一:string, number, boolean, null 或 undefined。\n *\n * @param {any} value - 要检查的值。\n * @returns {value is string | number | boolean | null | undefined} 如果值是原始类型,则返回 true;否则返回 false。\n */\nexport function isPrimitive(\n value: any\n): value is string | number | boolean | null | undefined {\n const type = typeof value;\n return (\n value === null ||\n type === \"string\" ||\n type === \"number\" ||\n type === \"boolean\" ||\n type === \"undefined\"\n );\n}\n","import { isPrimitive } from \"./type\";\n\n/**\n * 为给定的参数生成一个稳定且唯一的键。\n *\n * 该函数确保生成的键是确定性的,即相同的输入总是会生成相同的输出。\n * 这在缓存、记忆化或任何需要一致键的场景中非常有用。\n *\n * @param params - 用于生成键的参数。可以是任何类型。\n * @returns 表示输入参数的稳定且唯一的字符串键。\n */\nexport function generateStableUniqueKey(params: any) {\n if (isPrimitive(params)) {\n return String(params);\n }\n return JSON.stringify(params, function (_key: string | number, value: any) {\n if (typeof value === \"object\" && value !== null && !Array.isArray(value)) {\n return Object.keys(value)\n .sort()\n .reduce((pre: any, cur: string) => {\n pre[cur] = value[cur];\n return pre;\n }, {});\n }\n return value;\n });\n}\n","import { isCloneable } from \"./type\";\n\n/**\n * 深度克隆一个对象或数组。\n *\n * @param {T} obj - 要克隆的对象或数组。\n * @returns {T} 克隆后的对象或数组。\n */\nexport function cloneDeep<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n\n if (isCloneable(obj)) {\n return obj.clone();\n }\n\n // 处理数组\n if (Array.isArray(obj)) {\n return obj.map((item) => cloneDeep(item)) as unknown as T;\n }\n\n const newObj: { [key: string]: any } = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n newObj[key] = cloneDeep(obj[key]);\n }\n }\n return newObj as T;\n}\n","import { generateStableUniqueKey } from \"./generateStableUniqueKey\";\nimport { cloneDeep } from \"./cloneDeep\";\nimport { AsyncFunction } from \"./type\";\n\nconst cache: Record<string, any> = {};\nfunction getCachedData<T = any>(apiKey: string) {\n return cache[apiKey] as T;\n}\n\nexport interface Setting {\n timeout?: number;\n timeoutResult?: any;\n identifier?: string;\n}\n\nconst defalutSetting: Setting = {\n timeout: 60000,\n timeoutResult: { code: 408, msg: \"请求超时\" },\n identifier: \"\",\n};\n\n/**\n * 为异步函数添加缓存功能。\n *\n * 该函数根据函数参数、函数名和一个可选的标识符来缓存异步函数的结果。\n * 如果结果已经缓存,则返回缓存的结果。如果函数正在执行中,则等待结果返回,并使用一个超时机制防止无限等待。\n *\n * @template Args - 函数参数的类型。\n * @template Promise<T> - 函数返回值的类型。\n * @param {AsyncFunction<Args, T>} func - 需要包装的异步函数。\n * @param {Setting} [setting=defalutSetting] - 可选的缓存设置。\n * @returns {AsyncFunction<Args, T>} - 带有缓存功能的包装函数,返回类型为 `Promise<T>`。\n */\nexport function cacheWrapper<Args extends any[], T>(\n func: AsyncFunction<Args, T>,\n setting: Setting = defalutSetting\n): AsyncFunction<Args, T> {\n return function (...args: Args): Promise<T> {\n const apiKey: string =\n generateStableUniqueKey(args) + func.name + (setting.identifier || \"\"); //缓存key\n\n if (cache[apiKey]) {\n return Promise.resolve(cloneDeep(getCachedData<T>(apiKey)));\n }\n\n const apiLoadingKey: string = apiKey + \"_l_o_a_d_i_n_g_\"; //缓存loading key\n\n if (cache[apiLoadingKey]) {\n const _setting = Object.assign({}, defalutSetting, setting);\n return new Promise((resolve) => {\n const startTime = Date.now();\n const timer = setInterval(() => {\n if (cache[apiKey]) {\n clearInterval(timer);\n resolve(cloneDeep(getCachedData<T>(apiKey)));\n } else if (Date.now() - startTime > _setting.timeout!) {\n cache[apiLoadingKey] = false;\n clearInterval(timer);\n resolve(cloneDeep(_setting.timeoutResult));\n }\n }, 100);\n });\n }\n cache[apiLoadingKey] = true;\n\n return func(...args)\n .then((res) => {\n // 缓存原始数据或其克隆,避免数据被释放\n cache[apiKey] = res;\n return cloneDeep(cache[apiKey]);\n })\n .catch((error: any) => {\n throw error;\n })\n .finally(() => {\n cache[apiLoadingKey] = false;\n });\n };\n}\n","/**\n * 表示 DOM 中可能的子元素类型。\n */\nexport type ChildrenType =\n | DomOptionsType\n | HTMLElement\n | SVGElement\n | Text\n | string;\n\n/**\n * 表示创建 DOM 元素的选项类型。\n */\nexport type DomOptionsType = {\n /**\n * 要创建的元素的标签名。默认为 \"div\"。\n */\n tag?: string;\n\n /**\n * 要附加到创建的元素的子元素。可以是单个子元素或子元素数组。\n */\n children?: ChildrenType | ChildrenType[];\n\n /**\n * 要设置在创建的元素上的属性。\n */\n props?: Record<string, any>;\n\n /**\n * 要设置在创建的元素上的属性。\n */\n attrs?: Record<string, string | boolean>;\n\n /**\n * 要应用于创建的元素的样式。\n */\n styles?: Record<string, string | number>;\n};\n\n/**\n * 设置 HTML 元素的样式属性。\n *\n * @param element - 要设置样式的 HTML 元素。\n * @param property - CSS 属性名,可以是驼峰命名法(camelCase)或连字符命名法(kebab-case)。\n * @param value - 要设置的属性值。\n * @param important - 可选参数,布尔值,表示是否将属性设置为 `important` 优先级,默认为 `false`。\n */\nfunction setStyle(\n element: HTMLElement,\n property: string,\n value: string | number,\n important: boolean = false\n): void {\n if (property in element.style) {\n (element.style as any)[property] = value;\n } else {\n const priority = important ? \"important\" : \"\";\n element.style.setProperty(property, String(value), priority);\n }\n}\n\n/**\n * 使用指定选项创建一个 DOM 元素。\n *\n * @param options - 创建 DOM 元素的选项。\n *\n * @returns 创建的 DOM 元素。\n *\n * @remarks\n * 此函数旨在浏览器环境中使用。\n *\n * @example\n * ```typescript\n * const element = createElement({\n * tag: 'button',\n * children: '点击我',\n * attrs: { id: 'myButton' },\n * styles: { color: 'red' }\n * });\n * document.body.appendChild(element);\n * ```\n */\nexport function createElement({\n tag = \"div\",\n children = [],\n props = {},\n attrs = {},\n styles = {},\n}: DomOptionsType = {}): HTMLElement {\n const ele = document.createElement(tag);\n\n // 设置属性\n Object.assign(ele, props);\n\n // 设置属性\n for (const [key, value] of Object.entries(attrs)) {\n if (value !== false) {\n ele.setAttribute(key, value as string);\n }\n }\n\n // 设置样式\n for (const [key, value] of Object.entries(styles)) {\n setStyle(ele, key, value);\n }\n\n // 处理子元素\n const childArray = Array.isArray(children) ? children : [children];\n for (const child of childArray) {\n if (!child) continue;\n\n if (typeof child === \"object\") {\n if (child instanceof HTMLElement || child instanceof Text) {\n ele.appendChild(child);\n } else {\n ele.appendChild(createElement(child as DomOptionsType));\n }\n } else {\n ele.appendChild(document.createTextNode(child));\n }\n }\n\n return ele;\n}\n\ntype SvgElement = {\n tag: string;\n attributes?: Record<string, string>;\n children?: SvgElement | SvgElement[] | string;\n};\n\ntype SvgOptions = {\n width?: number;\n height?: number;\n};\n\n/**\n * 创建一个 SVG 元素。\n *\n * @param {SvgElement[] | SvgElement | string} elements - 要创建的 SVG 元素,可以是对象数组、单个对象或 innerHTML 字符串。\n * @param {SvgOptions} [options] - SVG 的配置选项,包括宽度和高度。\n * @returns {SVGElement} - 创建的 SVG 元素。\n *\n * @example\n * // 使用嵌套对象\n * const svg1 = createSvg(\n * {\n * tag: 'svg',\n * children: [\n * { tag: 'circle', attributes: { cx: '16', cy: '16', r: '10', fill: 'red' } },\n * { tag: 'g', children:\n * { tag: 'text', attributes: { x: '10', y: '20', fill: 'black' }, children: 'Hello' }\n * }\n * ]\n * },\n * { width: 64, height: 64 }\n * );\n * document.body.appendChild(svg1);\n *\n * @example\n * // 使用 innerHTML\n * const svg2 = createSvg(\n * `<circle cx=\"16\" cy=\"16\" r=\"10\" fill=\"red\"></circle>\n * <text x=\"10\" y=\"20\" fill=\"black\">Hello</text>`\n * );\n * document.body.appendChild(svg2);\n */\nexport function createSvg(\n elements: SvgElement[] | SvgElement | string,\n options?: SvgOptions\n) {\n // 默认宽度和高度\n const { width = 32, height = 32 } = options || {};\n\n // 创建一个 SVG 元素\n const svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n\n // 设置 SVG 的宽度和高度\n svg.setAttribute(\"width\", width.toString());\n svg.setAttribute(\"height\", height.toString());\n svg.setAttribute(\"viewBox\", `0 0 ${width} ${height}`);\n\n if (typeof elements === \"string\") {\n // 如果 elements 是字符串,直接设置为 SVG 的 innerHTML\n svg.innerHTML = elements;\n } else {\n // 处理 SvgElement 或 SvgElement[]\n const elementArray = Array.isArray(elements) ? elements : [elements];\n\n elementArray.forEach((element) => {\n svg.appendChild(createSvgElement(element));\n });\n }\n\n // 返回创建好的 SVG 元素\n return svg;\n}\n\n/**\n * 递归创建 SVG 子元素。\n *\n * @param {SvgElement} element - 要创建的 SVG 子元素。\n * @returns {SVGElement} - 创建的 SVG 子元素。\n */\nfunction createSvgElement(element: SvgElement) {\n const { tag, attributes, children } = element;\n const el = document.createElementNS(\"http://www.w3.org/2000/svg\", tag);\n\n if (attributes) {\n for (const [key, value] of Object.entries(attributes)) {\n el.setAttribute(key, value);\n }\n }\n\n if (typeof children === \"string\") {\n el.textContent = children;\n } else if (children) {\n const childArray = Array.isArray(children) ? children : [children];\n childArray.forEach((child) => {\n el.appendChild(createSvgElement(child));\n });\n }\n\n return el;\n}\n","/**\n * 将指定的 DOM 元素滚动到底部。\n * 使用 setTimeout 确保在当前调用栈之后执行。\n *\n * @param {HTMLElement} dom - 要滚动的 DOM 元素。\n */\nexport function scrollToBottom(dom: HTMLElement) {\n if (dom) {\n setTimeout(() => {\n // 设置滚动条位置为元素的最大滚动高度,滚动到底部\n dom.scrollTop = dom.scrollHeight;\n }, 0);\n }\n}\n\n/**\n * 如果用户未与 DOM 元素交互,则将其滚动到底部。\n * 如果尚未设置事件监听器,则设置一个以跟踪用户滚动交互。\n *\n * @param {HTMLElement} dom - 可能需要滚动的 DOM 元素。\n */\nexport function scrollToBottomIfNeeded(dom: HTMLElement): void {\n if (!dom) {\n return;\n }\n // 检查是否已设置滚动监听器\n if (dom.dataset.isListeningForUserScroll !== \"true\") {\n listenForUserScroll(dom);\n dom.dataset.isListeningForUserScroll = \"true\";\n }\n\n // 如果用户未与滚动条交互,则滚动到底部\n if (dom.dataset.userInteracted !== \"true\") {\n scrollToBottom(dom);\n }\n}\n\n/**\n * 更新用户是否与滚动条交互的状态。\n *\n * @param {HTMLElement} dom - 要更新状态的 DOM 元素。\n * @param {boolean} inter - 用户是否与滚动条交互。\n */\nfunction userInteractedWithScroll(dom: HTMLElement, inter: boolean): void {\n // 根据用户交互状态更新数据属性\n dom.dataset.userInteracted = inter ? \"true\" : \"false\";\n}\n\n/**\n * 为 DOM 元素设置滚动事件监听器。\n * 当用户滚动时,更新交互状态。\n *\n * @param {HTMLElement} dom - 要监听滚动事件的 DOM 元素。\n */\nfunction listenForUserScroll(dom: HTMLElement): void {\n if (!dom) {\n return;\n }\n dom.addEventListener(\"scroll\", () => {\n // 检查用户是否滚动到接近底部\n if (dom.scrollTop + dom.clientHeight < dom.scrollHeight - 5) {\n // 用户已滚动,更新交互状态\n userInteractedWithScroll(dom, true);\n } else {\n // 用户未滚动到接近底部\n userInteractedWithScroll(dom, false);\n }\n });\n}\n","/**\n * 创建一个防抖函数,该函数会在最后一次调用后的指定时间间隔后执行。\n *\n * @param func - 需要防抖处理的函数。\n * @param wait - 延迟的毫秒数。\n * @returns 一个新的防抖函数。\n */\nexport function debounce<T extends (...args: any[]) => void>(\n func: T,\n wait: number\n): T {\n let timeout: ReturnType<typeof setTimeout> | null = null;\n\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n const context = this;\n\n // 如果已经设定了调用,取消之前的调用\n if (timeout !== null) {\n clearTimeout(timeout);\n }\n\n // 设定一个新的调用,等待指定的时间后执行\n timeout = setTimeout(() => {\n func.apply(context, args);\n timeout = null; // 确保能够在下次触发时重新设定定时器\n }, wait);\n } as T;\n}\n\n/**\n * 创建一个节流函数,该函数会在每个指定的时间间隔内最多执行一次。\n *\n * @param func - 需要节流处理的函数。\n * @param delay - 时间间隔的毫秒数。\n * @returns 一个新的节流函数。\n */\nexport function throttle<T extends (...agrs: any[]) => any>(\n func: T,\n delay: number\n): T {\n let lastExecutedTime: number = 0;\n\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n const context = this;\n const currentTime = Date.now();\n\n if (currentTime - lastExecutedTime >= delay) {\n func.apply(context, args);\n lastExecutedTime = currentTime;\n }\n } as T;\n}\n\n/**\n * 创建一个延迟执行回调函数并返回 Promise 的函数。\n *\n * @param callback - 需要执行的回调函数。\n * @param delay - 延迟的毫秒数,默认为 0。\n * @returns 一个 Promise 对象,该对象在回调函数执行后解析。\n */\nexport function delayExecution<T>(\n callback: () => T,\n delay: number = 0\n): Promise<T> {\n return new Promise<T>((resolve) => {\n if (delay === 0) {\n resolve(callback());\n } else {\n setTimeout(() => {\n resolve(callback());\n }, delay);\n }\n });\n}\n","declare var global: typeof globalThis;\n\n/**\n * 获取当前环境的全局对象。\n *\n * 在不同的 JavaScript 运行环境中,全局对象的名称不同:\n * - 在浏览器环境中,全局对象是 `window`。\n * - 在 Node.js 环境中,全局对象是 `global`。\n * - 在 Web Worker 环境中,全局对象是 `self`。\n *\n * 这个函数提供了一种统一的方式来获取当前环境的全局对象。\n *\n * @returns 当前环境的全局对象。\n */\nexport function getGlobal(this: any) {\n if (typeof globalThis !== \"undefined\") {\n return globalThis;\n }\n\n if (typeof self !== \"undefined\") {\n return self;\n }\n\n if (typeof window !== \"undefined\") {\n return window;\n }\n\n if (typeof global !== \"undefined\") {\n return global;\n }\n\n // 如果以上都不符合,则返回 this\n return this;\n}\n","/**\n * 定义一个类型,用于扩展函数类型,增加一个可选的 isExecuting 属性\n */\nexport type SingleExecutionFunction<T extends (...args: any[]) => any> = T & {\n isExecuting?: boolean;\n};\n\n/**\n * 创建一个有执行状态的函数,该函数在前一次调用未完成时不会被再次调用。\n *\n * @param func - 需要包裹的函数。\n * @returns 一个增强版的函数,该函数具有 isExecuting 属性。\n */\nexport function singleExecutionWrapper<T extends (...args: any[]) => any>(\n func: T\n): SingleExecutionFunction<T> {\n const singleExecutionFn: SingleExecutionFunction<T> = function (\n ...args: Parameters<T>\n ): ReturnType<T> | undefined {\n if (singleExecutionFn.isExecuting) {\n console.log(`Function(${func.name}) is executing.`);\n return;\n }\n singleExecutionFn.isExecuting = true;\n\n let result: ReturnType<T>;\n\n try {\n result = func(...args);\n if ((result as any) instanceof Promise) {\n result.finally(() => {\n singleExecutionFn.isExecuting = false;\n });\n } else {\n singleExecutionFn.isExecuting = false;\n }\n } catch (error) {\n singleExecutionFn.isExecuting = false;\n throw error;\n }\n\n return result;\n } as SingleExecutionFunction<T>;\n\n singleExecutionFn.isExecuting = false;\n\n return singleExecutionFn;\n}\n"],"names":["isCloneable","obj","clone","isPrimitive","value","type","generateStableUniqueKey","params","String","JSON","stringify","_key","Array","isArray","Object","keys","sort","reduce","pre","cur","cloneDeep","map","item","newObj","key","prototype","hasOwnProperty","call","cache","getCachedData","apiKey","defalutSetting","timeout","timeoutResult","code","msg","identifier","setStyle","element","property","important","style","priority","setProperty","createSvgElement","attributes","children","el","document","createElementNS","tag","_i3","_Object$entries3","entries","length","_Object$entries3$_i","setAttribute","textContent","forEach","child","appendChild","scrollToBottom","dom","setTimeout","scrollTop","scrollHeight","func","setting","args","slice","arguments","name","Promise","resolve","apiLoadingKey","_setting","assign","startTime","Date","now","timer","setInterval","clearInterval","apply","then","res","error","createElement","_temp","_ref","_ref$tag","_ref$children","_ref$props","props","_ref$attrs","attrs","_ref$styles","styles","ele","_i","_Object$entries","_Object$entries$_i","_i2","_Object$entries2","_Object$entries2$_i","_step","_iterator","_createForOfIteratorHelperLoose","done","HTMLElement","Text","createTextNode","elements","options","_ref2","_ref2$width","width","_ref2$height","height","svg","toString","innerHTML","wait","_arguments","context","this","clearTimeout","callback","delay","globalThis","self","window","global","dataset","isListeningForUserScroll","addEventListener","inter","userInteracted","userInteractedWithScroll","clientHeight","listenForUserScroll","singleExecutionFn","isExecuting","result","console","log","lastExecutedTime","currentTime"],"mappings":"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"}
1
+ {"version":3,"file":"index.umd.js","sources":["../src/common/type.ts","../src/common/generateStableUniqueKey.ts","../src/common/cloneDeep.ts","../src/common/cacheWrapper.ts","../src/browser/dom.ts","../src/browser/scroll.ts","../src/common/utils.ts","../src/common/getGlobal.ts","../src/common/singleExecutionWrapper.ts"],"sourcesContent":["/**\n * 异步函数类型。\n *\n * @template Args - 表示函数参数的类型数组。\n * @template T - 表示函数返回的 Promise 解析后的类型。\n *\n * @param args - 函数的参数。\n * @returns 一个 Promise 对象,解析后的值类型为 T。\n */\nexport type AsyncFunction<Args extends any[], T> = (\n ...args: Args\n) => Promise<T>;\n\n/**\n * 表示一个可以克隆自身的对象接口。\n *\n * @interface Cloneable\n */\nexport interface Cloneable {\n /**\n * 创建并返回当前对象的一个副本。\n *\n * @returns {this} 当前对象的一个副本。\n */\n clone(): this;\n}\n\n/**\n *\n * 检查一个对象是否实现了 Cloneable 接口。\n *\n * 这个函数是一个类型保护函数,它会在类型检查时将传入的对象类型缩小为 Cloneable。\n *\n * @param {any} obj - 要检查的对象。\n * @returns {obj is Cloneable} 如果对象实现了 Cloneable 接口,则返回 true;否则返回 false。\n */\nexport function isCloneable(obj: any): obj is Cloneable {\n return typeof obj?.clone === \"function\";\n}\n\n/**\n * 检查一个值是否是原始类型(primitive type)。\n *\n * 这个函数是一个类型保护函数,它会在类型检查时将传入的值类型缩小为原始类型之一:string, number, boolean, null 或 undefined。\n *\n * @param {any} value - 要检查的值。\n * @returns {value is string | number | boolean | null | undefined} 如果值是原始类型,则返回 true;否则返回 false。\n */\nexport function isPrimitive(\n value: any\n): value is string | number | boolean | null | undefined {\n const type = typeof value;\n return (\n value === null ||\n type === \"string\" ||\n type === \"number\" ||\n type === \"boolean\" ||\n type === \"undefined\"\n );\n}\n","import { isPrimitive } from \"./type\";\n\n/**\n * 为给定的参数生成一个稳定且唯一的键。\n *\n * 该函数确保生成的键是确定性的,即相同的输入总是会生成相同的输出。\n * 这在缓存、记忆化或任何需要一致键的场景中非常有用。\n *\n * @param params - 用于生成键的参数。可以是任何类型。\n * @returns 表示输入参数的稳定且唯一的字符串键。\n */\nexport function generateStableUniqueKey(params: any) {\n if (isPrimitive(params)) {\n return String(params);\n }\n return JSON.stringify(params, function (_key: string | number, value: any) {\n if (typeof value === \"object\" && value !== null && !Array.isArray(value)) {\n return Object.keys(value)\n .sort()\n .reduce((pre: any, cur: string) => {\n pre[cur] = value[cur];\n return pre;\n }, {});\n }\n return value;\n });\n}\n","import { isCloneable } from \"./type\";\n\n/**\n * 深度克隆一个对象或数组。\n *\n * @param {T} obj - 要克隆的对象或数组。\n * @returns {T} 克隆后的对象或数组。\n */\nexport function cloneDeep<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n\n if (isCloneable(obj)) {\n return obj.clone();\n }\n\n // 处理数组\n if (Array.isArray(obj)) {\n return obj.map((item) => cloneDeep(item)) as unknown as T;\n }\n\n const newObj: { [key: string]: any } = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n newObj[key] = cloneDeep(obj[key]);\n }\n }\n return newObj as T;\n}\n","import { generateStableUniqueKey } from \"./generateStableUniqueKey\";\nimport { cloneDeep } from \"./cloneDeep\";\nimport { AsyncFunction } from \"./type\";\n\nconst cache: Record<string, any> = {};\nfunction getCachedData<T = any>(apiKey: string) {\n return cache[apiKey] as T;\n}\n\nexport interface Setting {\n timeout?: number;\n timeoutResult?: any;\n identifier?: string;\n}\n\nconst defalutSetting: Setting = {\n timeout: 60000,\n timeoutResult: { code: 408, msg: \"请求超时\" },\n identifier: \"\",\n};\n\n/**\n * 为异步函数添加缓存功能。\n *\n * 该函数根据函数参数、函数名和一个可选的标识符来缓存异步函数的结果。\n * 如果结果已经缓存,则返回缓存的结果。如果函数正在执行中,则等待结果返回,并使用一个超时机制防止无限等待。\n *\n * @template Args - 函数参数的类型。\n * @template Promise<T> - 函数返回值的类型。\n * @param {AsyncFunction<Args, T>} func - 需要包装的异步函数。\n * @param {Setting} [setting=defalutSetting] - 可选的缓存设置。\n * @returns {AsyncFunction<Args, T>} - 带有缓存功能的包装函数,返回类型为 `Promise<T>`。\n */\nexport function cacheWrapper<Args extends any[], T>(\n func: AsyncFunction<Args, T>,\n setting: Setting = defalutSetting\n): AsyncFunction<Args, T> {\n return function (...args: Args): Promise<T> {\n const apiKey: string =\n generateStableUniqueKey(args) + func.name + (setting.identifier || \"\"); //缓存key\n\n if (cache[apiKey]) {\n return Promise.resolve(cloneDeep(getCachedData<T>(apiKey)));\n }\n\n const apiLoadingKey: string = apiKey + \"_l_o_a_d_i_n_g_\"; //缓存loading key\n\n if (cache[apiLoadingKey]) {\n const _setting = Object.assign({}, defalutSetting, setting);\n return new Promise((resolve) => {\n const startTime = Date.now();\n const timer = setInterval(() => {\n if (cache[apiKey]) {\n clearInterval(timer);\n resolve(cloneDeep(getCachedData<T>(apiKey)));\n } else if (Date.now() - startTime > _setting.timeout!) {\n cache[apiLoadingKey] = false;\n clearInterval(timer);\n resolve(cloneDeep(_setting.timeoutResult));\n }\n }, 100);\n });\n }\n cache[apiLoadingKey] = true;\n\n return func(...args)\n .then((res) => {\n // 缓存原始数据或其克隆,避免数据被释放\n cache[apiKey] = res;\n return cloneDeep(cache[apiKey]);\n })\n .catch((error: any) => {\n throw error;\n })\n .finally(() => {\n cache[apiLoadingKey] = false;\n });\n };\n}\n","/**\n * 表示 DOM 中可能的子元素类型。\n */\nexport type ChildrenType =\n | DomOptionsType\n | Element\n | string;\n\n/**\n * 表示创建 DOM 元素的选项类型。\n */\nexport type DomOptionsType = {\n /**\n * 要创建的元素的标签名。默认为 \"div\"。\n */\n tag?: string;\n\n /**\n * 要附加到创建的元素的子元素。可以是单个子元素或子元素数组。\n */\n children?: ChildrenType | ChildrenType[];\n\n /**\n * 要设置在创建的元素上的属性。\n */\n props?: Record<string, any>;\n\n /**\n * 要设置在创建的元素上的属性。\n */\n attrs?: Record<string, string | boolean>;\n\n /**\n * 要应用于创建的元素的样式。\n */\n styles?: Record<string, string | number>;\n};\n\n/**\n * 设置 HTML 元素的样式属性。\n *\n * @param element - 要设置样式的 HTML 元素。\n * @param property - CSS 属性名,可以是驼峰命名法(camelCase)或连字符命名法(kebab-case)。\n * @param value - 要设置的属性值。\n * @param important - 可选参数,布尔值,表示是否将属性设置为 `important` 优先级,默认为 `false`。\n */\nfunction setStyle(\n element: HTMLElement | SVGElement,\n property: string,\n value: string | number,\n important: boolean = false\n): void {\n if (property in element.style) {\n (element.style as any)[property] = value;\n } else {\n const priority = important ? \"important\" : \"\";\n element.style.setProperty(property, String(value), priority);\n }\n}\n\n/**\n * 使用指定选项创建一个 DOM 元素。\n *\n * @param options - 创建 DOM 元素的选项。\n *\n * @returns 创建的 DOM 元素。\n *\n * @remarks\n * 此函数旨在浏览器环境中使用。\n *\n * @example\n * ```typescript\n * const element = createElement({\n * tag: 'button',\n * children: '点击我',\n * attrs: { id: 'myButton' },\n * styles: { color: 'red' }\n * });\n * document.body.appendChild(element);\n * ```\n */\nexport function createElement({\n tag = \"div\",\n children = [],\n props = {},\n attrs = {},\n styles = {},\n}: DomOptionsType = {}): Element {\n const ele = document.createElement(tag);\n\n // 设置属性\n Object.assign(ele, props);\n\n // 设置属性\n for (const [key, value] of Object.entries(attrs)) {\n if (value !== false) {\n ele.setAttribute(key, value as string);\n }\n }\n\n // 设置样式\n for (const [key, value] of Object.entries(styles)) {\n setStyle(ele, key, value);\n }\n\n // 处理子元素\n const childArray = Array.isArray(children) ? children : [children];\n for (const child of childArray) {\n if (!child) continue;\n\n if (typeof child === \"object\") {\n if (child instanceof Element) {\n ele.appendChild(child);\n } else {\n ele.appendChild(createElement(child as DomOptionsType));\n }\n } else {\n ele.appendChild(document.createTextNode(child));\n }\n }\n\n return ele;\n}\n\ntype SvgElement = {\n tag: string;\n attributes?: Record<string, string>;\n children?: SvgElement | SvgElement[] | string;\n};\n\ntype SvgOptions = {\n width?: number;\n height?: number;\n};\n\n/**\n * 创建一个 SVG 元素。\n *\n * @param {SvgElement[] | SvgElement | string} elements - 要创建的 SVG 元素,可以是对象数组、单个对象或 innerHTML 字符串。\n * @param {SvgOptions} [options] - SVG 的配置选项,包括宽度和高度。\n * @returns {SVGElement} - 创建的 SVG 元素。\n *\n * @example\n * // 使用嵌套对象\n * const svg1 = createSvg(\n * {\n * tag: 'svg',\n * children: [\n * { tag: 'circle', attributes: { cx: '16', cy: '16', r: '10', fill: 'red' } },\n * { tag: 'g', children:\n * { tag: 'text', attributes: { x: '10', y: '20', fill: 'black' }, children: 'Hello' }\n * }\n * ]\n * },\n * { width: 64, height: 64 }\n * );\n * document.body.appendChild(svg1);\n *\n * @example\n * // 使用 innerHTML\n * const svg2 = createSvg(\n * `<circle cx=\"16\" cy=\"16\" r=\"10\" fill=\"red\"></circle>\n * <text x=\"10\" y=\"20\" fill=\"black\">Hello</text>`\n * );\n * document.body.appendChild(svg2);\n */\nexport function createSvg(\n elements: SvgElement[] | SvgElement | string,\n options?: SvgOptions\n) {\n // 默认宽度和高度\n const { width = 32, height = 32 } = options || {};\n\n // 创建一个 SVG 元素\n const svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n\n // 设置 SVG 的宽度和高度\n svg.setAttribute(\"width\", width.toString());\n svg.setAttribute(\"height\", height.toString());\n svg.setAttribute(\"viewBox\", `0 0 ${width} ${height}`);\n\n if (typeof elements === \"string\") {\n // 如果 elements 是字符串,直接设置为 SVG 的 innerHTML\n svg.innerHTML = elements;\n } else {\n // 处理 SvgElement 或 SvgElement[]\n const elementArray = Array.isArray(elements) ? elements : [elements];\n\n elementArray.forEach((element) => {\n svg.appendChild(createSvgElement(element));\n });\n }\n\n // 返回创建好的 SVG 元素\n return svg;\n}\n\n/**\n * 递归创建 SVG 子元素。\n *\n * @param {SvgElement} element - 要创建的 SVG 子元素。\n * @returns {SVGElement} - 创建的 SVG 子元素。\n */\nfunction createSvgElement(element: SvgElement) {\n const { tag, attributes, children } = element;\n const el = document.createElementNS(\"http://www.w3.org/2000/svg\", tag);\n\n if (attributes) {\n for (const [key, value] of Object.entries(attributes)) {\n el.setAttribute(key, value);\n }\n }\n\n if (typeof children === \"string\") {\n el.textContent = children;\n } else if (children) {\n const childArray = Array.isArray(children) ? children : [children];\n childArray.forEach((child) => {\n el.appendChild(createSvgElement(child));\n });\n }\n\n return el;\n}\n","/**\n * 将指定的 DOM 元素滚动到底部。\n * 使用 setTimeout 确保在当前调用栈之后执行。\n *\n * @param {HTMLElement} dom - 要滚动的 DOM 元素。\n */\nexport function scrollToBottom(dom: HTMLElement) {\n if (dom) {\n setTimeout(() => {\n // 设置滚动条位置为元素的最大滚动高度,滚动到底部\n dom.scrollTop = dom.scrollHeight;\n }, 0);\n }\n}\n\n/**\n * 如果用户未与 DOM 元素交互,则将其滚动到底部。\n * 如果尚未设置事件监听器,则设置一个以跟踪用户滚动交互。\n *\n * @param {HTMLElement} dom - 可能需要滚动的 DOM 元素。\n */\nexport function scrollToBottomIfNeeded(dom: HTMLElement): void {\n if (!dom) {\n return;\n }\n // 检查是否已设置滚动监听器\n if (dom.dataset.isListeningForUserScroll !== \"true\") {\n listenForUserScroll(dom);\n dom.dataset.isListeningForUserScroll = \"true\";\n }\n\n // 如果用户未与滚动条交互,则滚动到底部\n if (dom.dataset.userInteracted !== \"true\") {\n scrollToBottom(dom);\n }\n}\n\n/**\n * 更新用户是否与滚动条交互的状态。\n *\n * @param {HTMLElement} dom - 要更新状态的 DOM 元素。\n * @param {boolean} inter - 用户是否与滚动条交互。\n */\nfunction userInteractedWithScroll(dom: HTMLElement, inter: boolean): void {\n // 根据用户交互状态更新数据属性\n dom.dataset.userInteracted = inter ? \"true\" : \"false\";\n}\n\n/**\n * 为 DOM 元素设置滚动事件监听器。\n * 当用户滚动时,更新交互状态。\n *\n * @param {HTMLElement} dom - 要监听滚动事件的 DOM 元素。\n */\nfunction listenForUserScroll(dom: HTMLElement): void {\n if (!dom) {\n return;\n }\n dom.addEventListener(\"scroll\", () => {\n // 检查用户是否滚动到接近底部\n if (dom.scrollTop + dom.clientHeight < dom.scrollHeight - 5) {\n // 用户已滚动,更新交互状态\n userInteractedWithScroll(dom, true);\n } else {\n // 用户未滚动到接近底部\n userInteractedWithScroll(dom, false);\n }\n });\n}\n","/**\n * 创建一个防抖函数,该函数会在最后一次调用后的指定时间间隔后执行。\n *\n * @param func - 需要防抖处理的函数。\n * @param wait - 延迟的毫秒数。\n * @returns 一个新的防抖函数。\n */\nexport function debounce<T extends (...args: any[]) => void>(\n func: T,\n wait: number\n): T {\n let timeout: ReturnType<typeof setTimeout> | null = null;\n\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n const context = this;\n\n // 如果已经设定了调用,取消之前的调用\n if (timeout !== null) {\n clearTimeout(timeout);\n }\n\n // 设定一个新的调用,等待指定的时间后执行\n timeout = setTimeout(() => {\n func.apply(context, args);\n timeout = null; // 确保能够在下次触发时重新设定定时器\n }, wait);\n } as T;\n}\n\n/**\n * 创建一个节流函数,该函数会在每个指定的时间间隔内最多执行一次。\n *\n * @param func - 需要节流处理的函数。\n * @param delay - 时间间隔的毫秒数。\n * @returns 一个新的节流函数。\n */\nexport function throttle<T extends (...agrs: any[]) => any>(\n func: T,\n delay: number\n): T {\n let lastExecutedTime: number = 0;\n\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n const context = this;\n const currentTime = Date.now();\n\n if (currentTime - lastExecutedTime >= delay) {\n func.apply(context, args);\n lastExecutedTime = currentTime;\n }\n } as T;\n}\n\n/**\n * 创建一个延迟执行回调函数并返回 Promise 的函数。\n *\n * @param callback - 需要执行的回调函数。\n * @param delay - 延迟的毫秒数,默认为 0。\n * @returns 一个 Promise 对象,该对象在回调函数执行后解析。\n */\nexport function delayExecution<T>(\n callback: () => T,\n delay: number = 0\n): Promise<T> {\n return new Promise<T>((resolve) => {\n if (delay === 0) {\n resolve(callback());\n } else {\n setTimeout(() => {\n resolve(callback());\n }, delay);\n }\n });\n}\n","declare var global: typeof globalThis;\n\n/**\n * 获取当前环境的全局对象。\n *\n * 在不同的 JavaScript 运行环境中,全局对象的名称不同:\n * - 在浏览器环境中,全局对象是 `window`。\n * - 在 Node.js 环境中,全局对象是 `global`。\n * - 在 Web Worker 环境中,全局对象是 `self`。\n *\n * 这个函数提供了一种统一的方式来获取当前环境的全局对象。\n *\n * @returns 当前环境的全局对象。\n */\nexport function getGlobal(this: any) {\n if (typeof globalThis !== \"undefined\") {\n return globalThis;\n }\n\n if (typeof self !== \"undefined\") {\n return self;\n }\n\n if (typeof window !== \"undefined\") {\n return window;\n }\n\n if (typeof global !== \"undefined\") {\n return global;\n }\n\n // 如果以上都不符合,则返回 this\n return this;\n}\n","/**\n * 定义一个类型,用于扩展函数类型,增加一个可选的 isExecuting 属性\n */\nexport type SingleExecutionFunction<T extends (...args: any[]) => any> = T & {\n isExecuting?: boolean;\n};\n\n/**\n * 创建一个有执行状态的函数,该函数在前一次调用未完成时不会被再次调用。\n *\n * @param func - 需要包裹的函数。\n * @returns 一个增强版的函数,该函数具有 isExecuting 属性。\n */\nexport function singleExecutionWrapper<T extends (...args: any[]) => any>(\n func: T\n): SingleExecutionFunction<T> {\n const singleExecutionFn: SingleExecutionFunction<T> = function (\n ...args: Parameters<T>\n ): ReturnType<T> | undefined {\n if (singleExecutionFn.isExecuting) {\n console.log(`Function(${func.name}) is executing.`);\n return;\n }\n singleExecutionFn.isExecuting = true;\n\n let result: ReturnType<T>;\n\n try {\n result = func(...args);\n if ((result as any) instanceof Promise) {\n result.finally(() => {\n singleExecutionFn.isExecuting = false;\n });\n } else {\n singleExecutionFn.isExecuting = false;\n }\n } catch (error) {\n singleExecutionFn.isExecuting = false;\n throw error;\n }\n\n return result;\n } as SingleExecutionFunction<T>;\n\n singleExecutionFn.isExecuting = false;\n\n return singleExecutionFn;\n}\n"],"names":["isCloneable","obj","clone","isPrimitive","value","type","generateStableUniqueKey","params","String","JSON","stringify","_key","Array","isArray","Object","keys","sort","reduce","pre","cur","cloneDeep","map","item","newObj","key","prototype","hasOwnProperty","call","cache","getCachedData","apiKey","defalutSetting","timeout","timeoutResult","code","msg","identifier","setStyle","element","property","important","style","priority","setProperty","createSvgElement","attributes","children","el","document","createElementNS","tag","_i3","_Object$entries3","entries","length","_Object$entries3$_i","setAttribute","textContent","forEach","child","appendChild","scrollToBottom","dom","setTimeout","scrollTop","scrollHeight","func","setting","args","slice","arguments","name","Promise","resolve","apiLoadingKey","_setting","assign","startTime","Date","now","timer","setInterval","clearInterval","apply","then","res","error","createElement","_temp","_ref","_ref$tag","_ref$children","_ref$props","props","_ref$attrs","attrs","_ref$styles","styles","ele","_i","_Object$entries","_Object$entries$_i","_i2","_Object$entries2","_Object$entries2$_i","_step","_iterator","_createForOfIteratorHelperLoose","done","Element","createTextNode","elements","options","_ref2","_ref2$width","width","_ref2$height","height","svg","toString","innerHTML","wait","_arguments","context","this","clearTimeout","callback","delay","globalThis","self","window","global","dataset","isListeningForUserScroll","addEventListener","inter","userInteracted","userInteractedWithScroll","clientHeight","listenForUserScroll","singleExecutionFn","isExecuting","result","console","log","lastExecutedTime","currentTime"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@i.un/libs",
3
- "version": "0.0.13",
3
+ "version": "0.0.15",
4
4
  "description": "一个实用的ts函数库",
5
5
  "type": "module",
6
6
  "source": "src/index.ts",