@fast-china/utils 2.1.3 → 2.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/README.md +2 -0
- package/README.zh.md +2 -0
- package/dist/array/index.d.mts +19 -12
- package/dist/array/index.mjs +15 -1
- package/dist/array/index.mjs.map +1 -1
- package/dist/async/index.d.mts +13 -14
- package/dist/async/index.mjs +7 -5
- package/dist/async/index.mjs.map +1 -1
- package/dist/base64/index.d.mts +13 -13
- package/dist/color/index.d.mts +10 -11
- package/dist/color/index.mjs.map +1 -1
- package/dist/crypto/index.d.mts +38 -39
- package/dist/crypto/index.mjs +9 -4
- package/dist/crypto/index.mjs.map +1 -1
- package/dist/date/index.d.mts +23 -24
- package/dist/date/index.mjs.map +1 -1
- package/dist/dom/style.d.mts +5 -6
- package/dist/env/index.d.mts +9 -10
- package/dist/env/index.mjs +17 -10
- package/dist/env/index.mjs.map +1 -1
- package/dist/function/index.d.mts +13 -0
- package/dist/function/index.mjs +38 -0
- package/dist/function/index.mjs.map +1 -0
- package/dist/identity/index.d.mts +5 -6
- package/dist/index.d.mts +4 -3
- package/dist/index.global.min.js +2 -2
- package/dist/index.global.min.js.map +1 -1
- package/dist/index.mjs +4 -3
- package/dist/internal/runtime.mjs +12 -0
- package/dist/internal/runtime.mjs.map +1 -0
- package/dist/internal/text.d.mts +1 -2
- package/dist/internal/text.mjs +1 -1
- package/dist/internal/text.mjs.map +1 -1
- package/dist/logger/index.d.mts +7 -8
- package/dist/logger/index.mjs +6 -7
- package/dist/logger/index.mjs.map +1 -1
- package/dist/number/index.d.mts +9 -10
- package/dist/number/index.mjs +4 -3
- package/dist/number/index.mjs.map +1 -1
- package/dist/object/index.d.mts +49 -11
- package/dist/object/index.mjs +258 -14
- package/dist/object/index.mjs.map +1 -1
- package/dist/storage/index.d.mts +10 -11
- package/dist/storage/index.mjs +3 -2
- package/dist/storage/index.mjs.map +1 -1
- package/dist/string/index.d.mts +18 -19
- package/dist/string/index.mjs +15 -13
- package/dist/string/index.mjs.map +1 -1
- package/dist/vue/emits.d.mts +2 -3
- package/dist/vue/emits.mjs.map +1 -1
- package/dist/vue/expose.d.mts +1 -2
- package/dist/vue/func.d.mts +2 -3
- package/dist/vue/install.d.mts +6 -7
- package/dist/vue/install.mjs.map +1 -1
- package/dist/vue/props.d.mts +2 -3
- package/dist/vue/render.d.mts +1 -2
- package/dist/vue/render.mjs.map +1 -1
- package/dist/vue/slots.d.mts +3 -4
- package/dist/vue/with.d.mts +1 -2
- package/docs/API.md +3 -2
- package/docs/API.zh-CN.md +3 -2
- package/package.json +11 -11
package/dist/env/index.d.mts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
//#region src/env/index.d.ts
|
|
2
2
|
/** 可识别的主要 JavaScript 运行环境。 */
|
|
3
|
-
type RuntimeKind = "browser" | "node" | "unknown" | "worker";
|
|
3
|
+
export type RuntimeKind = "browser" | "node" | "unknown" | "worker";
|
|
4
4
|
/**
|
|
5
5
|
* 判断当前运行时是否具有浏览器 `window` 与 `document`。
|
|
6
6
|
*
|
|
7
7
|
* @returns 两项能力均存在时返回 `true`;不读取 DOM 内容。
|
|
8
8
|
*/
|
|
9
|
-
declare function isBrowser(): boolean;
|
|
9
|
+
export declare function isBrowser(): boolean;
|
|
10
10
|
/**
|
|
11
11
|
* 判断当前运行时是否像 Web Worker 且不是 Window。
|
|
12
12
|
*
|
|
@@ -14,19 +14,19 @@ declare function isBrowser(): boolean;
|
|
|
14
14
|
* Worker 中调用它可能抛错,本检测只检查能力存在,不会执行。
|
|
15
15
|
* @returns 具有 `importScripts` 且不是浏览器 Window 时返回 `true`。
|
|
16
16
|
*/
|
|
17
|
-
declare function isWebWorker(): boolean;
|
|
17
|
+
export declare function isWebWorker(): boolean;
|
|
18
18
|
/**
|
|
19
19
|
* 判断当前运行时是否暴露 Node.js 版本标记。
|
|
20
20
|
*
|
|
21
21
|
* @returns `process.versions.node` 为字符串时返回 `true`。
|
|
22
22
|
*/
|
|
23
|
-
declare function isNode(): boolean;
|
|
23
|
+
export declare function isNode(): boolean;
|
|
24
24
|
/**
|
|
25
25
|
* 判断当前运行时是否暴露 uni-app 的 `uni` 全局对象。
|
|
26
26
|
*
|
|
27
27
|
* @returns 全局属性存在且不为 `undefined` 时返回 `true`;不调用任何平台 API。
|
|
28
28
|
*/
|
|
29
|
-
declare function isUniApp(): boolean;
|
|
29
|
+
export declare function isUniApp(): boolean;
|
|
30
30
|
/**
|
|
31
31
|
* 判断当前运行时是否具备本库完整加密 API 所需的 Web Crypto 能力。
|
|
32
32
|
*
|
|
@@ -34,14 +34,14 @@ declare function isUniApp(): boolean;
|
|
|
34
34
|
* 仍会返回 `false`,因为摘要、PBKDF2、AES-GCM、RSA 与 ECC 需要完整的 Web Crypto 能力。
|
|
35
35
|
* @returns 同时提供本库 Web Crypto 功能所需方法时返回 `true`。
|
|
36
36
|
*/
|
|
37
|
-
declare function hasWebCrypto(): boolean;
|
|
37
|
+
export declare function hasWebCrypto(): boolean;
|
|
38
38
|
/**
|
|
39
39
|
* 返回当前主要运行环境。
|
|
40
40
|
*
|
|
41
41
|
* @remarks 在使用 DOM 模拟器的 Node.js 进程中优先报告 `browser`,因为可观察能力比宿主进程名称更有用。
|
|
42
42
|
* @returns `browser`、`worker`、`node` 或无法识别时的 `unknown`。
|
|
43
43
|
*/
|
|
44
|
-
declare function detectRuntime(): RuntimeKind;
|
|
44
|
+
export declare function detectRuntime(): RuntimeKind;
|
|
45
45
|
/**
|
|
46
46
|
* 基于 User-Agent 启发式判断手机设备。
|
|
47
47
|
*
|
|
@@ -49,7 +49,7 @@ declare function detectRuntime(): RuntimeKind;
|
|
|
49
49
|
* @remarks User-Agent 可以被伪造,不得用于鉴权、安全策略或永久功能分流。
|
|
50
50
|
* @returns 命中手机特征时返回 `true`。
|
|
51
51
|
*/
|
|
52
|
-
declare function isMobileUserAgent(userAgent?: string): boolean;
|
|
52
|
+
export declare function isMobileUserAgent(userAgent?: string): boolean;
|
|
53
53
|
/**
|
|
54
54
|
* 基于 User-Agent 与触点数量启发式判断平板设备。
|
|
55
55
|
*
|
|
@@ -57,7 +57,6 @@ declare function isMobileUserAgent(userAgent?: string): boolean;
|
|
|
57
57
|
* @param maxTouchPoints - 用于识别桌面 User-Agent 模式下的 iPadOS,默认读取当前触点数。
|
|
58
58
|
* @returns 命中平板特征时返回 `true`。
|
|
59
59
|
*/
|
|
60
|
-
declare function isTabletUserAgent(userAgent?: string, maxTouchPoints?: number): boolean;
|
|
60
|
+
export declare function isTabletUserAgent(userAgent?: string, maxTouchPoints?: number): boolean;
|
|
61
61
|
//#endregion
|
|
62
|
-
export { RuntimeKind, detectRuntime, hasWebCrypto, isBrowser, isMobileUserAgent, isNode, isTabletUserAgent, isUniApp, isWebWorker };
|
|
63
62
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/env/index.mjs
CHANGED
|
@@ -1,24 +1,30 @@
|
|
|
1
|
+
import { runtimeGlobals } from "../internal/runtime.mjs";
|
|
1
2
|
//#region src/env/index.ts
|
|
2
3
|
/**
|
|
3
4
|
* 延迟读取当前 User-Agent。
|
|
4
5
|
*
|
|
5
6
|
* @returns Navigator 不存在或字段类型异常时返回空字符串。
|
|
6
7
|
*/
|
|
7
|
-
const currentUserAgent = () =>
|
|
8
|
+
const currentUserAgent = () => {
|
|
9
|
+
const userAgent = runtimeGlobals.navigator?.userAgent;
|
|
10
|
+
return typeof userAgent === "string" ? userAgent : "";
|
|
11
|
+
};
|
|
8
12
|
/**
|
|
9
13
|
* 延迟读取当前设备报告的最大触点数。
|
|
10
14
|
*
|
|
11
15
|
* @returns Navigator 不存在或字段类型异常时返回 `0`。
|
|
12
16
|
*/
|
|
13
|
-
const currentTouchPoints = () =>
|
|
17
|
+
const currentTouchPoints = () => {
|
|
18
|
+
const maxTouchPoints = runtimeGlobals.navigator?.maxTouchPoints;
|
|
19
|
+
return typeof maxTouchPoints === "number" ? maxTouchPoints : 0;
|
|
20
|
+
};
|
|
14
21
|
/**
|
|
15
22
|
* 判断当前运行时是否具有浏览器 `window` 与 `document`。
|
|
16
23
|
*
|
|
17
24
|
* @returns 两项能力均存在时返回 `true`;不读取 DOM 内容。
|
|
18
25
|
*/
|
|
19
26
|
function isBrowser() {
|
|
20
|
-
|
|
21
|
-
return window !== void 0 && window !== null && window.document !== null && typeof window.document === "object";
|
|
27
|
+
return runtimeGlobals.window?.document !== void 0;
|
|
22
28
|
}
|
|
23
29
|
/**
|
|
24
30
|
* 判断当前运行时是否像 Web Worker 且不是 Window。
|
|
@@ -28,7 +34,7 @@ function isBrowser() {
|
|
|
28
34
|
* @returns 具有 `importScripts` 且不是浏览器 Window 时返回 `true`。
|
|
29
35
|
*/
|
|
30
36
|
function isWebWorker() {
|
|
31
|
-
return !isBrowser() && typeof
|
|
37
|
+
return !isBrowser() && typeof runtimeGlobals.importScripts === "function";
|
|
32
38
|
}
|
|
33
39
|
/**
|
|
34
40
|
* 判断当前运行时是否暴露 Node.js 版本标记。
|
|
@@ -36,10 +42,11 @@ function isWebWorker() {
|
|
|
36
42
|
* @returns `process.versions.node` 为字符串时返回 `true`。
|
|
37
43
|
*/
|
|
38
44
|
function isNode() {
|
|
39
|
-
const process =
|
|
45
|
+
const process = runtimeGlobals.process;
|
|
40
46
|
if (typeof process !== "object" && typeof process !== "function" || process === null) return false;
|
|
41
|
-
const versions =
|
|
42
|
-
|
|
47
|
+
const versions = process.versions;
|
|
48
|
+
if (typeof versions !== "object" && typeof versions !== "function" || versions === null) return false;
|
|
49
|
+
return typeof versions.node === "string";
|
|
43
50
|
}
|
|
44
51
|
/**
|
|
45
52
|
* 判断当前运行时是否暴露 uni-app 的 `uni` 全局对象。
|
|
@@ -47,7 +54,7 @@ function isNode() {
|
|
|
47
54
|
* @returns 全局属性存在且不为 `undefined` 时返回 `true`;不调用任何平台 API。
|
|
48
55
|
*/
|
|
49
56
|
function isUniApp() {
|
|
50
|
-
return
|
|
57
|
+
return runtimeGlobals.uni !== void 0;
|
|
51
58
|
}
|
|
52
59
|
/**
|
|
53
60
|
* 判断当前运行时是否具备本库完整加密 API 所需的 Web Crypto 能力。
|
|
@@ -57,7 +64,7 @@ function isUniApp() {
|
|
|
57
64
|
* @returns 同时提供本库 Web Crypto 功能所需方法时返回 `true`。
|
|
58
65
|
*/
|
|
59
66
|
function hasWebCrypto() {
|
|
60
|
-
const crypto =
|
|
67
|
+
const crypto = runtimeGlobals.crypto;
|
|
61
68
|
const subtle = crypto?.subtle;
|
|
62
69
|
return typeof crypto?.getRandomValues === "function" && typeof subtle?.decrypt === "function" && typeof subtle.deriveBits === "function" && typeof subtle.deriveKey === "function" && typeof subtle.digest === "function" && typeof subtle.encrypt === "function" && typeof subtle.exportKey === "function" && typeof subtle.generateKey === "function" && typeof subtle.importKey === "function" && typeof subtle.sign === "function" && typeof subtle.verify === "function";
|
|
63
70
|
}
|
package/dist/env/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/env/index.ts"],"sourcesContent":["/** 可识别的主要 JavaScript 运行环境。 */\nexport type RuntimeKind = \"browser\" | \"node\" | \"unknown\" | \"worker\";\n\n/**\n * 延迟读取当前 User-Agent。\n *\n * @returns Navigator 不存在或字段类型异常时返回空字符串。\n */\nconst currentUserAgent = (): string =>
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/env/index.ts"],"sourcesContent":["import { runtimeGlobals } from \"../internal/runtime\";\n\n/** 可识别的主要 JavaScript 运行环境。 */\nexport type RuntimeKind = \"browser\" | \"node\" | \"unknown\" | \"worker\";\n\n/**\n * 延迟读取当前 User-Agent。\n *\n * @returns Navigator 不存在或字段类型异常时返回空字符串。\n */\nconst currentUserAgent = (): string => {\n\tconst userAgent: unknown = runtimeGlobals.navigator?.userAgent;\n\treturn typeof userAgent === \"string\" ? userAgent : \"\";\n};\n/**\n * 延迟读取当前设备报告的最大触点数。\n *\n * @returns Navigator 不存在或字段类型异常时返回 `0`。\n */\nconst currentTouchPoints = (): number => {\n\tconst maxTouchPoints: unknown = runtimeGlobals.navigator?.maxTouchPoints;\n\treturn typeof maxTouchPoints === \"number\" ? maxTouchPoints : 0;\n};\n\n/**\n * 判断当前运行时是否具有浏览器 `window` 与 `document`。\n *\n * @returns 两项能力均存在时返回 `true`;不读取 DOM 内容。\n */\nexport function isBrowser(): boolean {\n\treturn runtimeGlobals.window?.document !== undefined;\n}\n\n/**\n * 判断当前运行时是否像 Web Worker 且不是 Window。\n *\n * @remarks 经典、模块、Shared 与 Service Worker 全局通常都暴露 `importScripts`;模块\n * Worker 中调用它可能抛错,本检测只检查能力存在,不会执行。\n * @returns 具有 `importScripts` 且不是浏览器 Window 时返回 `true`。\n */\nexport function isWebWorker(): boolean {\n\treturn !isBrowser() && typeof runtimeGlobals.importScripts === \"function\";\n}\n\n/**\n * 判断当前运行时是否暴露 Node.js 版本标记。\n *\n * @returns `process.versions.node` 为字符串时返回 `true`。\n */\nexport function isNode(): boolean {\n\tconst process = runtimeGlobals.process;\n\tif ((typeof process !== \"object\" && typeof process !== \"function\") || process === null) return false;\n\tconst versions: unknown = (process as { versions?: unknown }).versions;\n\tif ((typeof versions !== \"object\" && typeof versions !== \"function\") || versions === null) return false;\n\treturn typeof (versions as { node?: unknown }).node === \"string\";\n}\n\n/**\n * 判断当前运行时是否暴露 uni-app 的 `uni` 全局对象。\n *\n * @returns 全局属性存在且不为 `undefined` 时返回 `true`;不调用任何平台 API。\n */\nexport function isUniApp(): boolean {\n\treturn runtimeGlobals.uni !== undefined;\n}\n\n/**\n * 判断当前运行时是否具备本库完整加密 API 所需的 Web Crypto 能力。\n *\n * @remarks 普通随机数、随机字符串和 UUID 在缺少 Web Crypto 时可以回退到 `Math.random()`,但本函数\n * 仍会返回 `false`,因为摘要、PBKDF2、AES-GCM、RSA 与 ECC 需要完整的 Web Crypto 能力。\n * @returns 同时提供本库 Web Crypto 功能所需方法时返回 `true`。\n */\nexport function hasWebCrypto(): boolean {\n\tconst crypto = runtimeGlobals.crypto;\n\tconst subtle = crypto?.subtle;\n\treturn (\n\t\ttypeof crypto?.getRandomValues === \"function\" &&\n\t\ttypeof subtle?.decrypt === \"function\" &&\n\t\ttypeof subtle.deriveBits === \"function\" &&\n\t\ttypeof subtle.deriveKey === \"function\" &&\n\t\ttypeof subtle.digest === \"function\" &&\n\t\ttypeof subtle.encrypt === \"function\" &&\n\t\ttypeof subtle.exportKey === \"function\" &&\n\t\ttypeof subtle.generateKey === \"function\" &&\n\t\ttypeof subtle.importKey === \"function\" &&\n\t\ttypeof subtle.sign === \"function\" &&\n\t\ttypeof subtle.verify === \"function\"\n\t);\n}\n\n/**\n * 返回当前主要运行环境。\n *\n * @remarks 在使用 DOM 模拟器的 Node.js 进程中优先报告 `browser`,因为可观察能力比宿主进程名称更有用。\n * @returns `browser`、`worker`、`node` 或无法识别时的 `unknown`。\n */\nexport function detectRuntime(): RuntimeKind {\n\tif (isBrowser()) return \"browser\";\n\tif (isWebWorker()) return \"worker\";\n\tif (isNode()) return \"node\";\n\treturn \"unknown\";\n}\n\n/**\n * 基于 User-Agent 启发式判断手机设备。\n *\n * @param userAgent - 默认读取当前 `navigator.userAgent`;平台对象不存在时使用空字符串。\n * @remarks User-Agent 可以被伪造,不得用于鉴权、安全策略或永久功能分流。\n * @returns 命中手机特征时返回 `true`。\n */\nexport function isMobileUserAgent(userAgent: string = currentUserAgent()): boolean {\n\treturn /Mobile|iPhone|Android.*Mobile|Windows Phone/iu.test(userAgent);\n}\n\n/**\n * 基于 User-Agent 与触点数量启发式判断平板设备。\n *\n * @param userAgent - 默认读取当前 User-Agent。\n * @param maxTouchPoints - 用于识别桌面 User-Agent 模式下的 iPadOS,默认读取当前触点数。\n * @returns 命中平板特征时返回 `true`。\n */\nexport function isTabletUserAgent(userAgent: string = currentUserAgent(), maxTouchPoints: number = currentTouchPoints()): boolean {\n\treturn /iPad|Android(?!.*Mobile)|Tablet/iu.test(userAgent) || (/Macintosh/iu.test(userAgent) && maxTouchPoints > 1);\n}\n"],"mappings":";;;;;;;AAUA,MAAM,yBAAiC;CACtC,MAAM,YAAqB,eAAe,WAAW;CACrD,OAAO,OAAO,cAAc,WAAW,YAAY;AACpD;;;;;;AAMA,MAAM,2BAAmC;CACxC,MAAM,iBAA0B,eAAe,WAAW;CAC1D,OAAO,OAAO,mBAAmB,WAAW,iBAAiB;AAC9D;;;;;;AAOA,SAAgB,YAAqB;CACpC,OAAO,eAAe,QAAQ,aAAa,KAAA;AAC5C;;;;;;;;AASA,SAAgB,cAAuB;CACtC,OAAO,CAAC,UAAU,KAAK,OAAO,eAAe,kBAAkB;AAChE;;;;;;AAOA,SAAgB,SAAkB;CACjC,MAAM,UAAU,eAAe;CAC/B,IAAK,OAAO,YAAY,YAAY,OAAO,YAAY,cAAe,YAAY,MAAM,OAAO;CAC/F,MAAM,WAAqB,QAAmC;CAC9D,IAAK,OAAO,aAAa,YAAY,OAAO,aAAa,cAAe,aAAa,MAAM,OAAO;CAClG,OAAO,OAAQ,SAAgC,SAAS;AACzD;;;;;;AAOA,SAAgB,WAAoB;CACnC,OAAO,eAAe,QAAQ,KAAA;AAC/B;;;;;;;;AASA,SAAgB,eAAwB;CACvC,MAAM,SAAS,eAAe;CAC9B,MAAM,SAAS,QAAQ;CACvB,OACC,OAAO,QAAQ,oBAAoB,cACnC,OAAO,QAAQ,YAAY,cAC3B,OAAO,OAAO,eAAe,cAC7B,OAAO,OAAO,cAAc,cAC5B,OAAO,OAAO,WAAW,cACzB,OAAO,OAAO,YAAY,cAC1B,OAAO,OAAO,cAAc,cAC5B,OAAO,OAAO,gBAAgB,cAC9B,OAAO,OAAO,cAAc,cAC5B,OAAO,OAAO,SAAS,cACvB,OAAO,OAAO,WAAW;AAE3B;;;;;;;AAQA,SAAgB,gBAA6B;CAC5C,IAAI,UAAU,GAAG,OAAO;CACxB,IAAI,YAAY,GAAG,OAAO;CAC1B,IAAI,OAAO,GAAG,OAAO;CACrB,OAAO;AACR;;;;;;;;AASA,SAAgB,kBAAkB,YAAoB,iBAAiB,GAAY;CAClF,OAAO,gDAAgD,KAAK,SAAS;AACtE;;;;;;;;AASA,SAAgB,kBAAkB,YAAoB,iBAAiB,GAAG,iBAAyB,mBAAmB,GAAY;CACjI,OAAO,oCAAoC,KAAK,SAAS,KAAM,cAAc,KAAK,SAAS,KAAK,iBAAiB;AAClH"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/function/index.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* 创建最多执行一次并缓存首次结果的函数。
|
|
4
|
+
*
|
|
5
|
+
* @remarks 首次成功返回后,后续调用返回同一结果;Promise 会保持引用不变。首次同步抛错时缓存错误,后续调用重新抛出同一错误。
|
|
6
|
+
* 包装函数使用首次调用时的参数和 `this`,之后传入的参数不会再次执行原函数。
|
|
7
|
+
* @param callback - 只允许执行一次的函数。
|
|
8
|
+
* @returns 保持原参数与返回类型的包装函数。
|
|
9
|
+
* @throws `TypeError` 当 `callback` 不是函数。
|
|
10
|
+
*/
|
|
11
|
+
export declare function once<This, Arguments extends unknown[], Result>(callback: (this: This, ...arguments_: Arguments) => Result): (this: This, ...arguments_: Arguments) => Result;
|
|
12
|
+
//#endregion
|
|
13
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
//#region src/function/index.ts
|
|
2
|
+
/**
|
|
3
|
+
* 创建最多执行一次并缓存首次结果的函数。
|
|
4
|
+
*
|
|
5
|
+
* @remarks 首次成功返回后,后续调用返回同一结果;Promise 会保持引用不变。首次同步抛错时缓存错误,后续调用重新抛出同一错误。
|
|
6
|
+
* 包装函数使用首次调用时的参数和 `this`,之后传入的参数不会再次执行原函数。
|
|
7
|
+
* @param callback - 只允许执行一次的函数。
|
|
8
|
+
* @returns 保持原参数与返回类型的包装函数。
|
|
9
|
+
* @throws `TypeError` 当 `callback` 不是函数。
|
|
10
|
+
*/
|
|
11
|
+
function once(callback) {
|
|
12
|
+
if (typeof callback !== "function") throw new TypeError("`callback` 必须是函数。");
|
|
13
|
+
let state = { status: "pending" };
|
|
14
|
+
return function(...arguments_) {
|
|
15
|
+
switch (state.status) {
|
|
16
|
+
case "returned": return state.value;
|
|
17
|
+
case "threw": throw state.error;
|
|
18
|
+
case "pending": try {
|
|
19
|
+
const value = callback.apply(this, arguments_);
|
|
20
|
+
state = {
|
|
21
|
+
status: "returned",
|
|
22
|
+
value
|
|
23
|
+
};
|
|
24
|
+
return value;
|
|
25
|
+
} catch (error) {
|
|
26
|
+
state = {
|
|
27
|
+
error,
|
|
28
|
+
status: "threw"
|
|
29
|
+
};
|
|
30
|
+
throw error;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { once };
|
|
37
|
+
|
|
38
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/function/index.ts"],"sourcesContent":["/** 函数首次调用前的内部状态。 */\ninterface PendingOnceState {\n\treadonly status: \"pending\";\n}\n\n/** 函数成功返回后的内部状态。 */\ninterface ReturnedOnceState<Result> {\n\treadonly status: \"returned\";\n\treadonly value: Result;\n}\n\n/** 函数同步抛错后的内部状态。 */\ninterface ThrewOnceState {\n\treadonly error: unknown;\n\treadonly status: \"threw\";\n}\n\ntype OnceState<Result> = PendingOnceState | ReturnedOnceState<Result> | ThrewOnceState;\n\n/**\n * 创建最多执行一次并缓存首次结果的函数。\n *\n * @remarks 首次成功返回后,后续调用返回同一结果;Promise 会保持引用不变。首次同步抛错时缓存错误,后续调用重新抛出同一错误。\n * 包装函数使用首次调用时的参数和 `this`,之后传入的参数不会再次执行原函数。\n * @param callback - 只允许执行一次的函数。\n * @returns 保持原参数与返回类型的包装函数。\n * @throws `TypeError` 当 `callback` 不是函数。\n */\nexport function once<This, Arguments extends unknown[], Result>(\n\tcallback: (this: This, ...arguments_: Arguments) => Result\n): (this: This, ...arguments_: Arguments) => Result {\n\tif (typeof callback !== \"function\") throw new TypeError(\"`callback` 必须是函数。\");\n\tlet state: OnceState<Result> = { status: \"pending\" };\n\treturn function (this: This, ...arguments_: Arguments): Result {\n\t\tswitch (state.status) {\n\t\t\tcase \"returned\":\n\t\t\t\treturn state.value;\n\t\t\tcase \"threw\":\n\t\t\t\tthrow state.error;\n\t\t\tcase \"pending\":\n\t\t\t\ttry {\n\t\t\t\t\tconst value = callback.apply(this, arguments_);\n\t\t\t\t\tstate = { status: \"returned\", value };\n\t\t\t\t\treturn value;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tstate = { error, status: \"threw\" };\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t}\n\t};\n}\n"],"mappings":";;;;;;;;;;AA4BA,SAAgB,KACf,UACmD;CACnD,IAAI,OAAO,aAAa,YAAY,MAAM,IAAI,UAAU,mBAAmB;CAC3E,IAAI,QAA2B,EAAE,QAAQ,UAAU;CACnD,OAAO,SAAsB,GAAG,YAA+B;EAC9D,QAAQ,MAAM,QAAd;GACC,KAAK,YACJ,OAAO,MAAM;GACd,KAAK,SACJ,MAAM,MAAM;GACb,KAAK,WACJ,IAAI;IACH,MAAM,QAAQ,SAAS,MAAM,MAAM,UAAU;IAC7C,QAAQ;KAAE,QAAQ;KAAY;IAAM;IACpC,OAAO;GACR,SAAS,OAAO;IACf,QAAQ;KAAE;KAAO,QAAQ;IAAQ;IACjC,MAAM;GACP;EACF;CACD;AACD"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//#region src/identity/index.d.ts
|
|
2
2
|
/** {@link configureInstallationIdentity} 接收的安装标识配置。 */
|
|
3
|
-
interface InstallationIdentityConfiguration {
|
|
3
|
+
export interface InstallationIdentityConfiguration {
|
|
4
4
|
/**
|
|
5
5
|
* `Local` 中使用的业务键,默认 `identity:installation-id`。
|
|
6
6
|
*
|
|
@@ -9,7 +9,7 @@ interface InstallationIdentityConfiguration {
|
|
|
9
9
|
cacheKey?: string;
|
|
10
10
|
}
|
|
11
11
|
/** 浏览器或 uni-app 当前安装实例标识。 */
|
|
12
|
-
interface InstallationIdentity {
|
|
12
|
+
export interface InstallationIdentity {
|
|
13
13
|
/**
|
|
14
14
|
* `Local` 中使用的业务键。
|
|
15
15
|
*
|
|
@@ -56,14 +56,14 @@ interface InstallationIdentity {
|
|
|
56
56
|
* @throws `TypeError` 当 `cacheKey` 不是非空字符串或包含外围空白。
|
|
57
57
|
* @throws `Error` 当安装标识已经使用另一个业务键初始化。
|
|
58
58
|
*/
|
|
59
|
-
declare function configureInstallationIdentity(options?: InstallationIdentityConfiguration): void;
|
|
59
|
+
export declare function configureInstallationIdentity(options?: InstallationIdentityConfiguration): void;
|
|
60
60
|
/**
|
|
61
61
|
* 全局安装标识状态。
|
|
62
62
|
*
|
|
63
63
|
* @remarks Storage 未显式配置时会使用其默认值。生成 UUID 时优先使用 Web Crypto,能力缺失时
|
|
64
64
|
* 回退到 `Math.random()`。该值不是硬件标识、认证凭证或安全边界。
|
|
65
65
|
*/
|
|
66
|
-
declare const installationIdentity: InstallationIdentity;
|
|
66
|
+
export declare const installationIdentity: InstallationIdentity;
|
|
67
67
|
/**
|
|
68
68
|
* 返回已有安装标识,否则创建并持久化一个 UUID v4。
|
|
69
69
|
*
|
|
@@ -72,7 +72,6 @@ declare const installationIdentity: InstallationIdentity;
|
|
|
72
72
|
* @throws `TypeError` 当显式值或持久化值不是 UUID v4。
|
|
73
73
|
* @throws `Error` 当当前平台存储不可用。
|
|
74
74
|
*/
|
|
75
|
-
declare function getOrCreateInstallationId(installationId?: string): string;
|
|
75
|
+
export declare function getOrCreateInstallationId(installationId?: string): string;
|
|
76
76
|
//#endregion
|
|
77
|
-
export { InstallationIdentity, InstallationIdentityConfiguration, configureInstallationIdentity, getOrCreateInstallationId, installationIdentity };
|
|
78
77
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { KeySelector, allEqualBy, chunk, difference, groupBy, hasDuplicatesBy, intersection, partition, removeNullishValues, unique, uniqueBy } from "./array/index.mjs";
|
|
1
|
+
import { KeySelector, allEqualBy, chunk, difference, groupBy, hasDuplicatesBy, intersection, partition, removeNullishValues, symmetricDifference, unique, uniqueBy } from "./array/index.mjs";
|
|
2
2
|
import { AbortOptions, ConcurrentMapOptions, DebouncedFunction, RetryContext, RetryOptions, ThrottledFunction, TimeoutOptions, debounce, mapConcurrent, retry, sleep, throttle, withTimeout } from "./async/index.mjs";
|
|
3
3
|
import { DecodedText } from "./internal/text.mjs";
|
|
4
4
|
import { decodeBase64, decodeBase64Bytes, decodeBase64Url, decodeBase64UrlBytes, decodeLatin1Base64, decodeSecureBase64, encodeBase64, encodeBase64Bytes, encodeBase64Url, encodeBase64UrlBytes, encodeLatin1Base64, encodeSecureBase64 } from "./base64/index.mjs";
|
|
@@ -7,10 +7,11 @@ import { AESDecrypt, AESDecryptAuthenticated, AESDecryptWithPassword, AESEncrypt
|
|
|
7
7
|
import { DateInput, DateRangeShortcut, DateShortcut, RelativeTimeOptions, addDays, addMonths, addYears, createDateRangeShortcuts, createDateShortcuts, createOneMonthRangeFromToday, endOfDay, formatChineseRelativeTime, formatRelativeTime, getLocalDayBounds, getLocalTimeGreeting, getStartOfToday, isDateAfterNow, isFuture, isSameDay, isValidDate, isWithinInterval, startOfDay, toDate } from "./date/index.mjs";
|
|
8
8
|
import { StyleInput, StyleObject, StyleValue, addCssUnit, serializeStyle } from "./dom/style.mjs";
|
|
9
9
|
import { RuntimeKind, detectRuntime, hasWebCrypto, isBrowser, isMobileUserAgent, isNode, isTabletUserAgent, isUniApp, isWebWorker } from "./env/index.mjs";
|
|
10
|
+
import { once } from "./function/index.mjs";
|
|
10
11
|
import { InstallationIdentity, InstallationIdentityConfiguration, configureInstallationIdentity, getOrCreateInstallationId, installationIdentity } from "./identity/index.mjs";
|
|
11
12
|
import { LogLevel, Logger, LoggerOptions, LoggerSink, configureLogger, createLogger, logger } from "./logger/index.mjs";
|
|
12
13
|
import { FormatBytesOptions, average, clamp, formatBytes, inRange, lerp, randomInt, roundTo, sum } from "./number/index.mjs";
|
|
13
|
-
import { QueryPrimitive, QueryStringOptions, QueryValue, hasOwn, isPlainObject, mapValues, omit, pick, shallowEqual, toQueryString } from "./object/index.mjs";
|
|
14
|
+
import { QueryPrimitive, QueryStringOptions, QueryValue, cloneDeep, hasOwn, isEqual, isPlainObject, mapValues, omit, omitBy, pick, pickBy, shallowEqual, toQueryString } from "./object/index.mjs";
|
|
14
15
|
import { Local, Session, StorageArea, StorageCodec, StorageConfiguration, StorageReadOptions, StorageWriteOptions, base64StorageCodec, configureStorage, isStorageConfigured } from "./storage/index.mjs";
|
|
15
16
|
import { ParsedQueryParameters, StringLocale, camelCase, copy, decodeURIComponentRepeatedly, escapeHtml, generateUuidV4, isUuidV4, isValidJson, kebabCase, lowerFirst, normalizeWhitespace, parseQueryString, pascalCase, randomString, splitWords, truncateGraphemes, upperFirst } from "./string/index.mjs";
|
|
16
17
|
import { EmitHandlers, useEmits } from "./vue/emits.mjs";
|
|
@@ -22,4 +23,4 @@ import { useRender } from "./vue/render.mjs";
|
|
|
22
23
|
import { TypedSlots, TypedSlotsDeclaration, makeSlots } from "./vue/slots.mjs";
|
|
23
24
|
import { withDefineType } from "./vue/with.mjs";
|
|
24
25
|
import "./vue/index.mjs";
|
|
25
|
-
export { AESDecrypt, AESDecryptAuthenticated, AESDecryptWithPassword, AESEncrypt, AESEncryptAuthenticated, AESEncryptWithPassword, AbortOptions, AesCipherMode, AesPaddingMode, AwaitableFunction, ConcurrentMapOptions, DateInput, DateRangeShortcut, DateShortcut, DebouncedFunction, type DecodedText, DeriveECDHKeySHA256, DeriveECDHSecret, ECDSASign, ECDSAVerify, EcNamedCurve, EmitHandlers, FixedTimeEquals, FormatBytesOptions, GenerateECDHKeyPair, GenerateECDSAKeyPair, GenerateRSAKeyPair, GenerateRandomBytes, HKDFSHA256, HMACSHA256Encrypt, HMACSHA384Encrypt, HMACSHA512Encrypt, HashPasswordPBKDF2SHA256, Installable, InstallationIdentity, InstallationIdentityConfiguration, KeySelector, Local, LogLevel, Logger, LoggerOptions, LoggerSink, MD5Encrypt, PBKDF2SHA256, ParsedQueryParameters, PemKeyPair, QueryPrimitive, QueryStringOptions, QueryValue, RSADecryptOAEP, RSAEncryptOAEP, RSASignPSS, RSAVerifyPSS, RelativeTimeOptions, RetryContext, RetryOptions, RgbColor, RgbaColor, RuntimeKind, SHA1Encrypt, SHA256Bytes, SHA256Encrypt, SHA384Bytes, SHA384Encrypt, SHA512Bytes, SHA512Encrypt, Session, StorageArea, StorageCodec, StorageConfiguration, StorageReadOptions, StorageWriteOptions, StringLocale, StyleInput, StyleObject, StyleValue, TSXWithInstall, ThrottledFunction, TimeoutOptions, TypedSlots, TypedSlotsDeclaration, VerifyPasswordPBKDF2SHA256, VueInstallValue, addCssUnit, addDays, addMonths, addYears, allEqualBy, average, base64StorageCodec, callOptionalFunction, camelCase, chunk, clamp, configureInstallationIdentity, configureLogger, configureStorage, contrastRatio, copy, createDateRangeShortcuts, createDateShortcuts, createLogger, createOneMonthRangeFromToday, debounce, decodeBase64, decodeBase64Bytes, decodeBase64Url, decodeBase64UrlBytes, decodeLatin1Base64, decodeSecureBase64, decodeURIComponentRepeatedly, definePropType, detectRuntime, difference, encodeBase64, encodeBase64Bytes, encodeBase64Url, encodeBase64UrlBytes, encodeLatin1Base64, encodeSecureBase64, endOfDay, escapeHtml, formatBytes, formatChineseRelativeTime, formatHexColor, formatRelativeTime, generateUuidV4, getLocalDayBounds, getLocalTimeGreeting, getOrCreateInstallationId, getStartOfToday, groupBy, hasDuplicatesBy, hasOwn, hasWebCrypto, inRange, installationIdentity, intersection, isBrowser, isDateAfterNow, isFuture, isMobileUserAgent, isNode, isPlainObject, isSameDay, isStorageConfigured, isTabletUserAgent, isUniApp, isUuidV4, isValidDate, isValidJson, isWebWorker, isWithinInterval, kebabCase, lerp, logger, lowerFirst, makeSlots, mapConcurrent, mapValues, mixHexColorWithBlack, mixHexColorWithWhite, mixHexColors, normalizeWhitespace, omit, parseHexColor, parseQueryString, partition, pascalCase, pick, pickHigherContrastColor, randomInt, randomString, relativeLuminance, removeNullishValues, retry, roundTo, serializeStyle, shallowEqual, sleep, splitWords, startOfDay, sum, throttle, toDate, toQueryString, truncateGraphemes, unique, uniqueBy, upperFirst, useEmits, useExpose, useProps, useRender, withDefineType, withInstall, withInstallDirective, withNoopInstall, withTimeout };
|
|
26
|
+
export { AESDecrypt, AESDecryptAuthenticated, AESDecryptWithPassword, AESEncrypt, AESEncryptAuthenticated, AESEncryptWithPassword, AbortOptions, AesCipherMode, AesPaddingMode, AwaitableFunction, ConcurrentMapOptions, DateInput, DateRangeShortcut, DateShortcut, DebouncedFunction, type DecodedText, DeriveECDHKeySHA256, DeriveECDHSecret, ECDSASign, ECDSAVerify, EcNamedCurve, EmitHandlers, FixedTimeEquals, FormatBytesOptions, GenerateECDHKeyPair, GenerateECDSAKeyPair, GenerateRSAKeyPair, GenerateRandomBytes, HKDFSHA256, HMACSHA256Encrypt, HMACSHA384Encrypt, HMACSHA512Encrypt, HashPasswordPBKDF2SHA256, Installable, InstallationIdentity, InstallationIdentityConfiguration, KeySelector, Local, LogLevel, Logger, LoggerOptions, LoggerSink, MD5Encrypt, PBKDF2SHA256, ParsedQueryParameters, PemKeyPair, QueryPrimitive, QueryStringOptions, QueryValue, RSADecryptOAEP, RSAEncryptOAEP, RSASignPSS, RSAVerifyPSS, RelativeTimeOptions, RetryContext, RetryOptions, RgbColor, RgbaColor, RuntimeKind, SHA1Encrypt, SHA256Bytes, SHA256Encrypt, SHA384Bytes, SHA384Encrypt, SHA512Bytes, SHA512Encrypt, Session, StorageArea, StorageCodec, StorageConfiguration, StorageReadOptions, StorageWriteOptions, StringLocale, StyleInput, StyleObject, StyleValue, TSXWithInstall, ThrottledFunction, TimeoutOptions, TypedSlots, TypedSlotsDeclaration, VerifyPasswordPBKDF2SHA256, VueInstallValue, addCssUnit, addDays, addMonths, addYears, allEqualBy, average, base64StorageCodec, callOptionalFunction, camelCase, chunk, clamp, cloneDeep, configureInstallationIdentity, configureLogger, configureStorage, contrastRatio, copy, createDateRangeShortcuts, createDateShortcuts, createLogger, createOneMonthRangeFromToday, debounce, decodeBase64, decodeBase64Bytes, decodeBase64Url, decodeBase64UrlBytes, decodeLatin1Base64, decodeSecureBase64, decodeURIComponentRepeatedly, definePropType, detectRuntime, difference, encodeBase64, encodeBase64Bytes, encodeBase64Url, encodeBase64UrlBytes, encodeLatin1Base64, encodeSecureBase64, endOfDay, escapeHtml, formatBytes, formatChineseRelativeTime, formatHexColor, formatRelativeTime, generateUuidV4, getLocalDayBounds, getLocalTimeGreeting, getOrCreateInstallationId, getStartOfToday, groupBy, hasDuplicatesBy, hasOwn, hasWebCrypto, inRange, installationIdentity, intersection, isBrowser, isDateAfterNow, isEqual, isFuture, isMobileUserAgent, isNode, isPlainObject, isSameDay, isStorageConfigured, isTabletUserAgent, isUniApp, isUuidV4, isValidDate, isValidJson, isWebWorker, isWithinInterval, kebabCase, lerp, logger, lowerFirst, makeSlots, mapConcurrent, mapValues, mixHexColorWithBlack, mixHexColorWithWhite, mixHexColors, normalizeWhitespace, omit, omitBy, once, parseHexColor, parseQueryString, partition, pascalCase, pick, pickBy, pickHigherContrastColor, randomInt, randomString, relativeLuminance, removeNullishValues, retry, roundTo, serializeStyle, shallowEqual, sleep, splitWords, startOfDay, sum, symmetricDifference, throttle, toDate, toQueryString, truncateGraphemes, unique, uniqueBy, upperFirst, useEmits, useExpose, useProps, useRender, withDefineType, withInstall, withInstallDirective, withNoopInstall, withTimeout };
|