@fast-china/utils 2.1.8 → 2.1.9

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 CHANGED
@@ -1,6 +1,23 @@
1
1
  # Changelog
2
2
 
3
- All notable changes to Fast.Utils are documented in this file.
3
+ All notable changes to this project are documented in this file.
4
+
5
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and releases should follow [Semantic Versioning](https://semver.org/).
6
+
7
+ ## [2.1.9] - 2026-09-22
8
+
9
+ ### Fixed
10
+
11
+ - Preserve shared ArrayBuffer/view relationships, sparse array holes and enumerable extra/Symbol properties in cloneDeep.
12
+ - Distinguish known key tuples from dynamic key arrays in pick/omit return types; reject synchronous once reentry without invoking the callback twice.
13
+ - Keep browser-source globals separate from Node tooling and update consumer type/regression coverage.
14
+ - Keep the byte unit for nonnegative fractional inputs to `formatBytes`.
15
+
16
+ ### Documentation and Tooling
17
+
18
+ - Correct localized Fast.Docs links and retain minimal README examples.
19
+ - Align public-contract comments and agent guidance.
20
+ - Keep ESLint and Prettier skill-file ignores separate and add regression checks.
4
21
 
5
22
  ## [2.1.8] - 2026-09-14
6
23
 
@@ -55,7 +72,7 @@ All notable changes to Fast.Utils are documented in this file.
55
72
  - Added chainable `.parseJson<T = any>()` access to primitive string results from Base64 and Crypto text decoding APIs.
56
73
  - Added `configureLogger` for the default Logger and allowed Logger severity methods to emit data without a message string.
57
74
 
58
- ### Breaking Changes
75
+ ### Changed
59
76
 
60
77
  - Replaced Logger's `info` method and level with `log`; `logger.log()` now maps directly to `sink.log()` and `console.log()`, and the default minimum level is now `debug`.
61
78
  - Changed the default type parameter of `StorageArea.get` from `unknown` to `string`; runtime codec results remain unchanged and may still be objects or other JSON values.
@@ -81,7 +98,7 @@ All notable changes to Fast.Utils are documented in this file.
81
98
  - Standardized every random generation entry to prefer Web Crypto and fall back to `Math.random()` when unavailable.
82
99
  - Accessed standard runtime capabilities directly through `globalThis` instead of maintaining asserted global-object views.
83
100
 
84
- ### Breaking Changes
101
+ ### Removed
85
102
 
86
103
  - Removed `secureRandomInt` and `secureRandomString`; use `randomInt` and `randomString` instead.
87
104
 
@@ -132,16 +149,17 @@ All notable changes to Fast.Utils are documented in this file.
132
149
 
133
150
  - Added authenticated ciphertext validation, bounded crypto parameters and payloads, unbiased Web Crypto randomness, prototype-safe query/object transforms, and namespace-scoped Storage cleanup.
134
151
 
135
- [2.1.8]: https://github.com/China-xiaoFang/Fast.Utils/compare/v2.1.7...v2.1.8
136
- [2.1.7]: https://github.com/China-xiaoFang/Fast.Utils/compare/v2.1.6...v2.1.7
137
- [2.1.6]: https://github.com/China-xiaoFang/Fast.Utils/compare/v2.1.5...v2.1.6
138
- [2.1.5]: https://github.com/China-xiaoFang/Fast.Utils/compare/v2.1.4...v2.1.5
139
- [2.1.4]: https://github.com/China-xiaoFang/Fast.Utils/compare/v2.1.3...v2.1.4
140
- [2.1.3]: https://github.com/China-xiaoFang/Fast.Utils/compare/v2.1.2...v2.1.3
141
- [2.1.2]: https://github.com/China-xiaoFang/Fast.Utils/compare/v2.1.1...v2.1.2
142
- [2.1.1]: https://github.com/China-xiaoFang/Fast.Utils/compare/v2.1.0...v2.1.1
143
- [2.1.0]: https://github.com/China-xiaoFang/Fast.Utils/compare/v2.0.3...v2.1.0
144
- [2.0.3]: https://github.com/China-xiaoFang/Fast.Utils/releases/tag/v2.0.3
145
- [2.0.2]: https://github.com/China-xiaoFang/Fast.Utils/releases/tag/v2.0.2
146
- [2.0.1]: https://github.com/China-xiaoFang/Fast.Utils/releases/tag/v2.0.1
147
- [2.0.0]: https://github.com/China-xiaoFang/Fast.Utils/releases/tag/v2.0.0
152
+ [2.1.9]: https://gitee.com/FastDotnet/fast.utils/compare/v2.1.8...v2.1.9
153
+ [2.1.8]: https://gitee.com/FastDotnet/fast.utils/compare/v2.1.7...v2.1.8
154
+ [2.1.7]: https://gitee.com/FastDotnet/fast.utils/compare/v2.1.6...v2.1.7
155
+ [2.1.6]: https://gitee.com/FastDotnet/fast.utils/compare/v2.1.5...v2.1.6
156
+ [2.1.5]: https://gitee.com/FastDotnet/fast.utils/compare/v2.1.4...v2.1.5
157
+ [2.1.4]: https://gitee.com/FastDotnet/fast.utils/compare/v2.1.3...v2.1.4
158
+ [2.1.3]: https://gitee.com/FastDotnet/fast.utils/compare/v2.1.2...v2.1.3
159
+ [2.1.2]: https://gitee.com/FastDotnet/fast.utils/compare/v2.1.1...v2.1.2
160
+ [2.1.1]: https://gitee.com/FastDotnet/fast.utils/compare/v2.1.0...v2.1.1
161
+ [2.1.0]: https://gitee.com/FastDotnet/fast.utils/compare/v2.0.3...v2.1.0
162
+ [2.0.3]: https://gitee.com/FastDotnet/fast.utils/compare/v2.0.2...v2.0.3
163
+ [2.0.2]: https://gitee.com/FastDotnet/fast.utils/compare/v2.0.1...v2.0.2
164
+ [2.0.1]: https://gitee.com/FastDotnet/fast.utils/compare/v2.0.0...v2.0.1
165
+ [2.0.0]: https://gitee.com/FastDotnet/fast.utils/releases/tag/v2.0.0
package/README.md CHANGED
@@ -1,16 +1,20 @@
1
- <p align="left">
2
- <a href="./README.zh.md">简体中文</a> | <strong>English</strong>
3
- </p>
1
+ [简体中文](./README.zh.md) | **English**
4
2
 
5
3
  <p align="center">
6
- <img src="./Fast.png" alt="logo" width="160" />
4
+ <img src="./Fast.png" width="128" alt="Fast.Utils Logo" />
7
5
  </p>
8
6
 
9
- # @fast-china/utils
7
+ <h1 align="center">Fast.Utils</h1>
8
+
9
+ <p align="center">
10
+ <a href="https://www.npmjs.com/package/@fast-china/utils"><img src="https://img.shields.io/npm/v/@fast-china/utils?logo=npm" alt="npm version" /></a>
11
+ <a href="https://www.npmjs.com/package/@fast-china/utils"><img src="https://img.shields.io/npm/dm/@fast-china/utils" alt="npm downloads" /></a>
12
+ <a href="./LICENSE"><img src="https://img.shields.io/npm/l/@fast-china/utils" alt="License" /></a>
13
+ </p>
10
14
 
11
- Browser-first TypeScript utilities for modern browsers, WebViews, Vue 3, and uni-app.
15
+ A TypeScript utility SDK for modern browsers, WebViews, Vue 3 and uni-app.
12
16
 
13
- [![npm version](https://img.shields.io/npm/v/@fast-china/utils?color=orange)](https://www.npmjs.com/package/@fast-china/utils) [![node](https://img.shields.io/badge/node-%5E22.18%20%7C%7C%20%5E24.18-brightgreen)](https://nodejs.org/) [![vue](https://img.shields.io/badge/vue-%5E3.5.11-42b883)](https://vuejs.org/) [![license](https://img.shields.io/npm/l/@fast-china/utils)](./LICENSE)
17
+ **[Documentation](http://docs.fastdotnet.cn/en-US/frontend/utils/) · [Official website](http://fastdotnet.com)**
14
18
 
15
19
  ## Highlights
16
20
 
@@ -27,136 +31,46 @@ pnpm add @fast-china/utils
27
31
 
28
32
  ### CDN
29
33
 
30
- The `unpkg` and `jsdelivr` fields select the minified `dist/index.global.min.js` browser file, which exposes the `FastUtils` global.
31
-
32
- ## Storage
33
-
34
- `Local` and `Session` work without configuration. The default prefix is `fast__`, values use JSON, and entries do not expire unless a TTL is supplied:
35
-
36
- ```ts
37
- import { Local, Session } from "@fast-china/utils";
38
-
39
- Local.set("user", { id: 1 }, { ttlMs: 30 * 60 * 1000 });
40
- const user = Local.get<{ id: number }>("user");
41
-
42
- Local.set("private-user", { id: 2 }, { crypto: true });
43
- const privateUser = Local.get<{ id: number }>("private-user", { crypto: true });
44
-
45
- Session.set("redirect", "/home");
46
- const redirect = Session.get("redirect"); // string | undefined
47
- ```
48
-
49
- `get<Value = string>()` returns `string | undefined` when its generic is omitted, so string values require no type argument. Storage codecs still deserialize JSON at runtime; pass an explicit generic for an accurate type when the stored value is an object, array, or another non-string value.
50
-
51
- Call `configureStorage` before the first Storage operation only when overriding defaults. The legacy-compatible `crypto` option applies reversible Base64 obfuscation; it is not encryption and must not protect secrets:
52
-
53
- ```ts
54
- import { configureStorage } from "@fast-china/utils";
55
-
56
- configureStorage({
57
- prefix: "my-app:",
58
- crypto: true,
59
- });
60
- ```
61
-
62
- The active global configuration is immutable. Repeating the same configuration is idempotent; a conflicting configuration throws. The `crypto` option on `set/get` overrides only that operation and must match when writing and reading the same entry; it does not mutate global configuration. A custom `codec` may be supplied instead of global `crypto`. In uni-app, `Local` automatically resolves the runtime-injected `uni` object and uses its synchronous Storage API; `Session` throws because uni-app has no sessionStorage equivalent. `clear()` removes only keys inside the active prefix.
63
-
64
- ## Base64
65
-
66
- Prefer the UTF-8 or Base64URL APIs in new code:
67
-
68
- ```ts
69
- import { decodeBase64, encodeBase64, encodeBase64Url } from "@fast-china/utils";
70
-
71
- const encoded = encodeBase64('{"name":"Fast utilities"}');
72
- const decoded = decodeBase64(encoded);
73
- decoded;
74
- decoded.parseJson<{ name: string }>();
75
- encodeBase64Url("path/value");
76
- ```
77
-
78
- `encodeSecureBase64` and `decodeSecureBase64` exist only for the legacy dictionary format. Given the same default six-character prefix, valid legacy payloads remain byte-for-byte identical. A historical Base64-length 101–124 dictionary gap uses a one-character fallback that the legacy removal flow understands. This format is not encryption and must not protect passwords, tokens, or other secrets.
79
-
80
- ## Copy text
34
+ The jsDelivr entry uses the minified `dist/index.global.min.js` browser file, which exposes the `FastUtils` global.
81
35
 
82
- ```ts
83
- import { copy } from "@fast-china/utils";
36
+ | Resource | jsDelivr | unpkg |
37
+ | -------------------------------------------- | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
38
+ | `vue@3.5.11/dist/vue.global.prod.js` | [jsDelivr](https://cdn.jsdelivr.net/npm/vue@3.5.11/dist/vue.global.prod.js) | [unpkg](https://unpkg.com/vue@3.5.11/dist/vue.global.prod.js) |
39
+ | `@fast-china/utils/dist/index.global.min.js` | [jsDelivr](https://cdn.jsdelivr.net/npm/@fast-china/utils/dist/index.global.min.js) | [unpkg](https://unpkg.com/@fast-china/utils/dist/index.global.min.js) |
84
40
 
85
- await copy("Fast utilities");
86
- ```
41
+ ## Quick start
87
42
 
88
- uni-app uses `setClipboardData`. Browsers prefer the Clipboard API and fall back to the legacy browser copy capability when it is unavailable. Unsupported platforms and denied clipboard access throw errors.
89
-
90
- ## Identity
43
+ The default namespace is `fast__`; store and retrieve business data with an optional TTL:
91
44
 
92
45
  ```ts
93
- import { configureInstallationIdentity, getOrCreateInstallationId } from "@fast-china/utils";
94
-
95
- configureInstallationIdentity({ cacheKey: "account:installation-id" });
46
+ import { Local } from "@fast-china/utils";
96
47
 
97
- const installationId = getOrCreateInstallationId();
48
+ Local.set("profile", { name: "Fast" }, { ttlMs: 30 * 60 * 1000 });
49
+ const profile = Local.get<{ name: string }>("profile");
50
+ console.log(profile?.name);
98
51
  ```
99
52
 
100
- Call `configureInstallationIdentity` in the application entry before first use. The default business key is `identity:installation-id`; repeated identical configuration is idempotent and conflicting configuration throws. Installation Identity UUID generation prefers Web Crypto and falls back to `Math.random()` when unavailable.
53
+ Without a TTL, entries do not expire. Configure a custom namespace or codec before the first storage operation. The legacy `crypto` option is Base64 obfuscation, not encryption. uni-app supports `Local`, not `Session`.
101
54
 
102
- ## Logger
55
+ ## Common usage
103
56
 
104
- The default `logger` works without construction and has a minimum level of `debug`. Enable split mode at application startup when uni-app App-Plus needs HBuilderX-compatible object output:
57
+ Import utilities by name from the package root:
105
58
 
106
59
  ```ts
107
- import { configureLogger, logger } from "@fast-china/utils";
60
+ import { encodeBase64, formatBytes, sleep } from "@fast-china/utils";
108
61
 
109
- configureLogger({ uniAppPlusSplit: true });
110
- logger.log("Launch", { code: 200, data: { id: 1 } });
111
- logger.error("Request", "request failed", error);
62
+ const encoded = encodeBase64("Fast");
63
+ const size = formatBytes(1536);
64
+ await sleep(100);
65
+ console.log(encoded, size);
112
66
  ```
113
67
 
114
- Log messages are optional, so objects, arrays, errors, and other values may be passed directly. Normal runtimes preserve the original values; App-Plus
115
- split mode converts additional values into readable text one at a time. Use `createLogger` for an isolated configuration unaffected by the default Logger.
116
-
117
- ## Crypto
118
-
119
- The TypeScript Crypto API mirrors the public methods and algorithm casing of .NET `CryptoUtil`. AES-GCM payloads, password-based AES payloads, PBKDF2 password hashes, and PEM keys interoperate across both implementations.
120
-
121
- ```ts
122
- import { AESDecryptWithPassword, AESEncryptWithPassword } from "@fast-china/utils";
123
-
124
- const payload = await AESEncryptWithPassword("protected content", "correct horse battery staple");
125
- const plaintext = await AESDecryptWithPassword(payload, "correct horse battery staple");
126
- plaintext;
127
-
128
- const jsonPayload = await AESEncryptWithPassword('{"id":1}', "correct horse battery staple");
129
- const result = (await AESDecryptWithPassword(jsonPayload, "correct horse battery staple")).parseJson<{ id: number }>();
130
- ```
131
-
132
- Base64 and Crypto text decoding/decryption functions return the primitive-string `DecodedText` type, which can be used directly as a `string`; an explicit `.parseJson<T = any>()` call attempts JSON parsing and returns the original string when parsing fails. The first text decode lazily installs a non-enumerable `String.prototype.parseJson`; a foreign method with the same name causes an explicit conflict error. The generic type does not validate untrusted JSON or guarantee an object result at runtime.
133
-
134
- Store passwords with `HashPasswordPBKDF2SHA256` and `VerifyPasswordPBKDF2SHA256`. MD5, SHA-1, AES-CBC, and AES-ECB do not provide password-storage or authenticated-encryption guarantees. See the [API reference](./docs/API.md#crypto) for the complete method list and security boundaries.
135
-
136
- CryptoJS is bundled into the ESM and CDN artifacts for the compatibility hash and AES APIs. Consumers do not install or resolve `crypto-js` subpaths; applications that do not use Crypto APIs can still remove the independent crypto module through Tree Shaking.
137
-
138
- ## Vue 3
139
-
140
- ```ts
141
- import { useBreakpoints, useElementSize, useEventListener, useNow, useWindowSize } from "@fast-china/utils";
142
- import { useTemplateRef } from "vue";
143
-
144
- const elementRef = useTemplateRef<HTMLElement>("element");
145
- const { width: windowWidth } = useWindowSize();
146
- const { width: elementWidth } = useElementSize(elementRef);
147
- const now = useNow();
148
- const breakpoints = useBreakpoints({ desktop: 1280, mobile: 0, tablet: 768 });
149
- useEventListener(document, "visibilitychange", () => console.log(document.visibilityState));
150
- ```
151
-
152
- The package provides lightweight native-backed browser composables, Vue 3 `app.use()` registration, typed props/emits/slots, and TSX rendering. Browser composables clean up with the current Vue scope; advanced scheduling, controls, SSR configuration, and device APIs remain outside this package. Vue remains external to the build and is required as a peer dependency.
68
+ Parameter validation or a pre-aborted signal may throw synchronously; cancellation during the wait rejects the returned Promise.
153
69
 
154
70
  ## Modules
155
71
 
156
72
  `@fast-china/utils` is the only public entry and exposes every API as a named export. Source modules remain separate in `dist/` so modern bundlers can remove unused exports; those internal files are not public package subpaths.
157
73
 
158
- Historical aggregate objects are not public. Supported behavior is exposed through named functions, improving auto-imports and Tree Shaking; this major version does not preserve every former convenience method.
159
-
160
74
  The `object` module includes dependency-free deep cloning and equality plus predicate-based property selection. Array utilities include a SameValueZero symmetric difference, while `once` preserves the first return value, Promise identity, or synchronous error.
161
75
 
162
76
  ## Runtime contract
@@ -170,8 +84,8 @@ The `object` module includes dependency-free deep cloning and equality plus pred
170
84
 
171
85
  ## Documentation
172
86
 
173
- - [API reference](./docs/API.md)
174
- - [Runtime contract](./docs/RUNTIME_CONTRACT.md)
87
+ - [API reference](http://docs.fastdotnet.cn/en-US/frontend/utils/api/)
88
+ - [Runtime contract](http://docs.fastdotnet.cn/en-US/frontend/utils/runtime-contract)
175
89
  - [Development and release guide (Chinese)](./docs/DEVELOPMENT_RELEASE.zh-CN.md)
176
90
  - [Security policy](./SECURITY.md)
177
91
  - [Contributing guide](./CONTRIBUTING.md)
@@ -188,6 +102,12 @@ pnpm check
188
102
 
189
103
  Use `pnpm dev` for a long-running tsdown watch build while editing source files.
190
104
 
191
- ## License
105
+ ## Copyright, license and use
106
+
107
+ Copyright © 2018-Now 小方. This project uses [Apache License 2.0](./LICENSE). Use, modification, distribution and commercial use are permitted subject to its terms.
108
+
109
+ When redistributing, provide the license, mark modified files and preserve applicable copyright, attribution and supplied NOTICE information as required. This summary does not replace the license or impose additional UI attribution.
110
+
111
+ Users are responsible for the legal compliance and authorization of their own modifications, deployment, data processing and operations. This reminder is not an additional license condition.
192
112
 
193
- [Apache-2.0](./LICENSE)
113
+ Except as required by applicable law or agreed in writing, the software is provided on an "AS IS" basis. Sections 7 and 8 govern warranty disclaimers and liability limits. Providing the project does not endorse downstream activities or assume users' contractual commitments. This statement does not exclude liability that cannot lawfully be excluded.
package/README.zh.md CHANGED
@@ -1,16 +1,20 @@
1
- <p align="left">
2
- <strong>简体中文</strong> | <a href="./README.md">English</a>
3
- </p>
1
+ **简体中文** | [English](./README.md)
4
2
 
5
3
  <p align="center">
6
- <img src="./Fast.png" alt="logo" width="160" />
4
+ <img src="./Fast.png" width="128" alt="Fast.Utils Logo" />
7
5
  </p>
8
6
 
9
- # @fast-china/utils
7
+ <h1 align="center">Fast.Utils</h1>
8
+
9
+ <p align="center">
10
+ <a href="https://www.npmjs.com/package/@fast-china/utils"><img src="https://img.shields.io/npm/v/@fast-china/utils?logo=npm" alt="npm version" /></a>
11
+ <a href="https://www.npmjs.com/package/@fast-china/utils"><img src="https://img.shields.io/npm/dm/@fast-china/utils" alt="npm downloads" /></a>
12
+ <a href="./LICENSE"><img src="https://img.shields.io/npm/l/@fast-china/utils" alt="License" /></a>
13
+ </p>
10
14
 
11
- 面向现代浏览器、WebView、Vue 3 与 uni-app 的 TypeScript 前端工具库。
15
+ 面向现代浏览器、WebView、Vue 3 与 uni-app 的 TypeScript 工具 SDK。
12
16
 
13
- [![npm 版本](https://img.shields.io/npm/v/@fast-china/utils?color=orange)](https://www.npmjs.com/package/@fast-china/utils) [![node](https://img.shields.io/badge/node-%5E22.18%20%7C%7C%20%5E24.18-brightgreen)](https://nodejs.org/) [![Vue](https://img.shields.io/badge/vue-%5E3.5.11-42b883)](https://vuejs.org/) [![开源协议](https://img.shields.io/npm/l/@fast-china/utils)](./LICENSE)
17
+ **[使用文档](http://docs.fastdotnet.cn/zh-CN/frontend/utils/) · [官方网站](http://fastdotnet.com)**
14
18
 
15
19
  ## 特性
16
20
 
@@ -27,136 +31,46 @@ pnpm add @fast-china/utils
27
31
 
28
32
  ### CDN
29
33
 
30
- `unpkg` 和 `jsdelivr` 字段都指向压缩后的浏览器文件 `dist/index.global.min.js`,全局变量为 `FastUtils`。
31
-
32
- ## Storage
33
-
34
- `Local` 和 `Session` 无需配置即可使用。默认前缀为 `fast__`,值使用 JSON 编码,未指定 TTL 时永久有效:
35
-
36
- ```ts
37
- import { Local, Session } from "@fast-china/utils";
38
-
39
- Local.set("user", { id: 1 }, { ttlMs: 30 * 60 * 1000 });
40
- const user = Local.get<{ id: number }>("user");
41
-
42
- Local.set("private-user", { id: 2 }, { crypto: true });
43
- const privateUser = Local.get<{ id: number }>("private-user", { crypto: true });
44
-
45
- Session.set("redirect", "/home");
46
- const redirect = Session.get("redirect"); // string | undefined
47
- ```
48
-
49
- `get<Value = string>()` 未传泛型时默认返回 `string | undefined`,因此字符串场景可以直接调用。Storage Codec 仍会在运行时执行 JSON 反序列化;若存储的是对象、数组或其他非字符串值,建议显式传入对应泛型以获得准确类型。
50
-
51
- 只有需要覆盖默认值时,才需在首次 Storage 操作前调用 `configureStorage`。兼容旧版的 `crypto` 选项只执行可逆 Base64 混淆,不是加密,不能保护敏感数据:
52
-
53
- ```ts
54
- import { configureStorage } from "@fast-china/utils";
55
-
56
- configureStorage({
57
- prefix: "my-app:",
58
- crypto: true,
59
- });
60
- ```
61
-
62
- 激活后的全局配置不可变;相同配置重复调用保持幂等,不同配置会抛错。`set/get` 的 `crypto` 选项只覆盖单次操作,读写同一条目时必须保持一致,不会改变全局配置。自定义 `codec` 与全局 `crypto` 不能同时使用。uni-app 中 `Local` 会自动解析运行时注入的 `uni` 对象并使用其同步 Storage API;由于没有等价的 sessionStorage,`Session` 会明确抛错。`clear()` 只清理当前前缀。
63
-
64
- ## Base64
65
-
66
- 新代码优先使用 UTF-8 或 Base64URL API:
67
-
68
- ```ts
69
- import { decodeBase64, encodeBase64, encodeBase64Url } from "@fast-china/utils";
70
-
71
- const encoded = encodeBase64('{"name":"Fast 工具库"}');
72
- const decoded = decodeBase64(encoded);
73
- decoded;
74
- decoded.parseJson<{ name: string }>();
75
- encodeBase64Url("path/参数");
76
- ```
77
-
78
- `encodeSecureBase64` / `decodeSecureBase64` 仅用于兼容旧字典格式。给定相同的默认 6 字符前缀时,有效旧载荷保持逐字符一致;历史字典无法自解码的 101–124 字符 Base64 区间使用旧删除流程可识别的单字符回退。它不是加密,不应用于密码、Token 或其他秘密。
79
-
80
- ## 复制文本
34
+ jsDelivr 入口为压缩后的浏览器文件 `dist/index.global.min.js`,全局变量为 `FastUtils`。
81
35
 
82
- ```ts
83
- import { copy } from "@fast-china/utils";
36
+ | 资源 | jsDelivr | unpkg |
37
+ | -------------------------------------------- | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
38
+ | `vue@3.5.11/dist/vue.global.prod.js` | [jsDelivr](https://cdn.jsdelivr.net/npm/vue@3.5.11/dist/vue.global.prod.js) | [unpkg](https://unpkg.com/vue@3.5.11/dist/vue.global.prod.js) |
39
+ | `@fast-china/utils/dist/index.global.min.js` | [jsDelivr](https://cdn.jsdelivr.net/npm/@fast-china/utils/dist/index.global.min.js) | [unpkg](https://unpkg.com/@fast-china/utils/dist/index.global.min.js) |
84
40
 
85
- await copy("Fast 工具库");
86
- ```
41
+ ## 快速开始
87
42
 
88
- uni-app 使用 `setClipboardData`;浏览器优先使用 Clipboard API,不可用时回退到旧版浏览器复制能力。平台不支持或拒绝访问剪贴板时会抛出错误。
89
-
90
- ## 安装实例标识
43
+ 默认命名空间为 `fast__`,可直接存取带过期时间的业务数据:
91
44
 
92
45
  ```ts
93
- import { configureInstallationIdentity, getOrCreateInstallationId } from "@fast-china/utils";
94
-
95
- configureInstallationIdentity({ cacheKey: "account:installation-id" });
46
+ import { Local } from "@fast-china/utils";
96
47
 
97
- const installationId = getOrCreateInstallationId();
48
+ Local.set("profile", { name: "Fast" }, { ttlMs: 30 * 60 * 1000 });
49
+ const profile = Local.get<{ name: string }>("profile");
50
+ console.log(profile?.name);
98
51
  ```
99
52
 
100
- 在程序入口、首次使用安装标识前调用 `configureInstallationIdentity`。默认业务键是 `identity:installation-id`;相同配置可幂等重复调用,不同配置会抛错。安装标识 UUID 优先使用 Web Crypto 生成,能力缺失时回退到 `Math.random()`。它不是硬件 ID、认证凭证或风控信号。
53
+ 省略 TTL 时永久有效。自定义命名空间或 Codec 必须在首次存储操作之前配置;`crypto` 仅为 Base64 混淆,不是加密。uni-app 使用 `Local`,不支持 `Session`。
101
54
 
102
- ## Logger
55
+ ## 常见用法
103
56
 
104
- 默认 `logger` 可以直接使用,最低输出级别为 `debug`。uni-app App-Plus 需要兼容 HBuilderX 对象输出时,在应用入口配置拆分模式:
57
+ 普通工具从包根具名导入:
105
58
 
106
59
  ```ts
107
- import { configureLogger, logger } from "@fast-china/utils";
60
+ import { encodeBase64, formatBytes, sleep } from "@fast-china/utils";
108
61
 
109
- configureLogger({ uniAppPlusSplit: true });
110
- logger.log("Launch", { code: 200, data: { id: 1 } });
111
- logger.error("Request", "请求失败", error);
62
+ const encoded = encodeBase64("Fast");
63
+ const size = formatBytes(1536);
64
+ await sleep(100);
65
+ console.log(encoded, size);
112
66
  ```
113
67
 
114
- 日志消息可以省略,对象、数组和错误等值可以直接传入。普通环境保留原始值;App-Plus 拆分模式会将附加值逐条转换为可读文本。
115
- 需要独立配置且不受默认 Logger 影响时使用 `createLogger`。
116
-
117
- ## Crypto
118
-
119
- TypeScript Crypto API 与 .NET `CryptoUtil` 的公开方法及算法名称大小写保持一致。AES-GCM、密码 AES 载荷、PBKDF2 密码哈希和 PEM 密钥支持两端互操作。
120
-
121
- ```ts
122
- import { AESDecryptWithPassword, AESEncryptWithPassword } from "@fast-china/utils";
123
-
124
- const payload = await AESEncryptWithPassword("受保护内容", "correct horse battery staple");
125
- const plaintext = await AESDecryptWithPassword(payload, "correct horse battery staple");
126
- plaintext;
127
-
128
- const jsonPayload = await AESEncryptWithPassword('{"id":1}', "correct horse battery staple");
129
- const result = (await AESDecryptWithPassword(jsonPayload, "correct horse battery staple")).parseJson<{ id: number }>();
130
- ```
131
-
132
- Base64 与 Crypto 的文本解码/解密入口返回原始字符串类型 `DecodedText`,可以直接作为 `string` 使用;只有显式调用 `.parseJson<T = any>()` 才尝试解析 JSON,解析失败时直接返回原始字符串。首次文本解码会按需安装不可枚举的 `String.prototype.parseJson`,若同名方法已被其他实现占用则明确抛错。泛型不会验证不可信 JSON 的实际结构,也不保证运行时结果一定是对象。
133
-
134
- 密码存储使用 `HashPasswordPBKDF2SHA256` 和 `VerifyPasswordPBKDF2SHA256`。MD5、SHA-1、AES-CBC 与 AES-ECB 不提供密码存储或认证加密保证。完整方法列表和安全边界见 [API 文档](./docs/API.zh-CN.md#crypto)。
135
-
136
- 兼容哈希与 AES API 使用的 CryptoJS 已内联到 ESM 和 CDN 产物,消费项目无需安装或解析 `crypto-js` 子路径;未使用 Crypto API 的应用仍可通过 Tree Shaking 移除独立的加密模块。
137
-
138
- ## Vue 3
139
-
140
- ```ts
141
- import { useBreakpoints, useElementSize, useEventListener, useNow, useWindowSize } from "@fast-china/utils";
142
- import { useTemplateRef } from "vue";
143
-
144
- const elementRef = useTemplateRef<HTMLElement>("element");
145
- const { width: windowWidth } = useWindowSize();
146
- const { width: elementWidth } = useElementSize(elementRef);
147
- const now = useNow();
148
- const breakpoints = useBreakpoints({ desktop: 1280, mobile: 0, tablet: 768 });
149
- useEventListener(document, "visibilitychange", () => console.log(document.visibilityState));
150
- ```
151
-
152
- 包内提供基于原生浏览器 API 的轻量 Composable、Vue 3 `app.use()` 注册、Props/Emits/Slots 类型和 TSX 渲染。浏览器 Composable 随当前 Vue 作用域自动清理;高级调度、控制、SSR 配置和设备 API 不在本包范围内。Vue 不会打进构建产物,并作为必须安装的 Peer Dependency。
68
+ 同步参数校验和已取消信号可能在调用时抛错;等待期间的取消通过 Promise 拒绝,不将二者混为一谈。
153
69
 
154
70
  ## 模块
155
71
 
156
72
  `@fast-china/utils` 是唯一公开入口,全部 API 都通过具名导出提供。源码模块仍会在 `dist/` 中独立保留,便于现代打包器移除未使用代码,但这些内部文件不是公开子路径。
157
73
 
158
- 历史聚合对象不再公开,继续支持的能力通过具名函数提供,便于自动导入与 Tree Shaking;当前大版本并未保留每一个旧版便捷方法。
159
-
160
74
  `object` 模块提供不依赖第三方库的深复制、深度比较和按条件筛选属性能力。数组工具支持 SameValueZero 对称差集,`once` 则会保留第一次调用的返回值、Promise 引用或同步错误。
161
75
 
162
76
  ## 运行时契约
@@ -170,8 +84,8 @@ useEventListener(document, "visibilitychange", () => console.log(document.visibi
170
84
 
171
85
  ## 文档
172
86
 
173
- - [API 文档](./docs/API.zh-CN.md)
174
- - [运行时契约](./docs/RUNTIME_CONTRACT.md)
87
+ - [API 文档](http://docs.fastdotnet.cn/zh-CN/frontend/utils/api/)
88
+ - [运行时契约](http://docs.fastdotnet.cn/zh-CN/frontend/utils/runtime-contract)
175
89
  - [开发与发布](./docs/DEVELOPMENT_RELEASE.zh-CN.md)
176
90
  - [安全策略](./SECURITY.md)
177
91
  - [贡献指南](./CONTRIBUTING.md)
@@ -188,6 +102,12 @@ pnpm check
188
102
 
189
103
  修改源码时可使用 `pnpm dev` 启动长期运行的 tsdown 监听构建。
190
104
 
191
- ## 许可证
105
+ ## 版权、许可证与使用声明
106
+
107
+ 版权所有 © 2018-Now 小方。本项目依据 [Apache License 2.0](./LICENSE) 开源;在遵守许可证的前提下,可以使用、修改和分发本软件,包括商业使用。
108
+
109
+ 再分发时,应按许可证要求提供许可证副本、对修改的文件作出显著说明,并保留适用的版权和归属声明;包含需要保留的 NOTICE 信息时一并处理。本说明不替代正式许可证,也不额外要求在产品界面展示作者或项目标识。
110
+
111
+ 使用者应就自身使用、二次开发、部署、数据处理及运营活动遵守适用法律和第三方合法权益,自行取得依法需要的授权。上述内容为合规提醒,不构成附加许可条件。
192
112
 
193
- [Apache-2.0](./LICENSE)
113
+ 除适用法律另有规定或另有书面约定外,本软件按“原样”提供;保证排除与责任限制以许可证第 7、8 条为准。提供本项目不代表原作者为使用者的二次开发和运营活动背书,也不当然承担其对第三方作出的合同承诺。本说明不排除依法不得排除的责任。
@@ -38,7 +38,7 @@ const assertDelay = (milliseconds, name = "milliseconds") => {
38
38
  * @param milliseconds - 0 至 2,147,483,647 的有限毫秒数。
39
39
  * @param options - 可选取消信号。
40
40
  * @returns 到期后完成的 Promise。
41
- * @throws 取消时抛出名称为 `AbortError` 的 `Error`;参数非法时抛出 `RangeError`。
41
+ * @throws 参数非法时同步抛出 `RangeError`;信号已取消时同步抛出 `AbortError`。运行期间取消则拒绝返回的 Promise。
42
42
  */
43
43
  function sleep(milliseconds, options = {}) {
44
44
  const delay = assertDelay(milliseconds);
@@ -68,7 +68,7 @@ function sleep(milliseconds, options = {}) {
68
68
  * @param timeoutMs - 0 至 2,147,483,647 的有限等待时间。
69
69
  * @param options - 取消信号与自定义消息。
70
70
  * @returns 底层 Promise 的结果。
71
- * @throws 超时抛出 `Error`,取消时抛出名称为 `AbortError` 的 `Error`;等待时间非法时抛出 `RangeError`。
71
+ * @throws 等待时间非法或信号已取消时同步抛错;运行期间的超时、取消及源 Promise 失败通过返回的 Promise 拒绝。
72
72
  */
73
73
  function withTimeout(promise, timeoutMs, options = {}) {
74
74
  const delay = assertDelay(timeoutMs, "timeoutMs");