@nickyzj2023/utils 1.0.46 → 1.0.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/docs/assets/highlight.css +99 -92
  2. package/docs/assets/navigation.js +1 -1
  3. package/docs/assets/search.js +1 -1
  4. package/docs/functions/camelToSnake.html +178 -178
  5. package/docs/functions/capitalize.html +178 -178
  6. package/docs/functions/compactStr.html +182 -182
  7. package/docs/functions/debounce.html +187 -187
  8. package/docs/functions/decapitalize.html +178 -178
  9. package/docs/functions/fetcher.html +189 -188
  10. package/docs/functions/getRealURL.html +175 -175
  11. package/docs/functions/imageUrlToBase64.html +187 -184
  12. package/docs/functions/isFalsy.html +178 -178
  13. package/docs/functions/isNil.html +178 -178
  14. package/docs/functions/isObject.html +178 -178
  15. package/docs/functions/isPrimitive.html +178 -178
  16. package/docs/functions/isTruthy.html +178 -178
  17. package/docs/functions/loopUntil.html +180 -180
  18. package/docs/functions/mapKeys.html +180 -180
  19. package/docs/functions/mapValues.html +182 -182
  20. package/docs/functions/mergeObjects.html +184 -184
  21. package/docs/functions/randomInt.html +178 -178
  22. package/docs/functions/sleep.html +179 -179
  23. package/docs/functions/snakeToCamel.html +178 -178
  24. package/docs/functions/throttle.html +187 -187
  25. package/docs/functions/timeLog.html +178 -178
  26. package/docs/functions/to.html +180 -180
  27. package/docs/functions/withCache.html +185 -185
  28. package/docs/modules.html +174 -174
  29. package/docs/types/CamelToSnake.html +174 -174
  30. package/docs/types/Capitalize.html +174 -174
  31. package/docs/types/Decapitalize.html +174 -174
  32. package/docs/types/DeepMapKeys.html +174 -174
  33. package/docs/types/DeepMapValues.html +174 -174
  34. package/docs/types/Falsy.html +174 -174
  35. package/docs/types/ImageCompressionOptions.html +184 -0
  36. package/docs/types/Primitive.html +174 -174
  37. package/docs/types/RequestInit.html +174 -174
  38. package/docs/types/SetTtl.html +174 -174
  39. package/docs/types/SnakeToCamel.html +174 -174
  40. package/package.json +8 -11
  41. package/src/{network.ts → network/fetcher.ts} +2 -37
  42. package/src/network/getRealURL.ts +18 -0
  43. package/src/network/image.ts +202 -0
  44. package/src/network/index.ts +4 -0
  45. package/src/network/to.ts +17 -0
  46. package/src/string/case.ts +71 -0
  47. package/src/string/compact.ts +56 -0
  48. package/src/string/index.ts +12 -0
  49. package/dist/dom.d.ts +0 -8
  50. package/dist/function.d.ts +0 -22
  51. package/dist/hoc.d.ts +0 -42
  52. package/dist/index.d.ts +0 -9
  53. package/dist/index.js +0 -2
  54. package/dist/is.d.ts +0 -43
  55. package/dist/lru-cache.d.ts +0 -18
  56. package/dist/network.d.ts +0 -57
  57. package/dist/number.d.ts +0 -7
  58. package/dist/object.d.ts +0 -50
  59. package/dist/string.d.ts +0 -70
  60. package/dist/time.d.ts +0 -47
  61. package/dist/tsdoc-metadata.json +0 -11
  62. package/src/string.ts +0 -259
package/dist/string.d.ts DELETED
@@ -1,70 +0,0 @@
1
- export type SnakeToCamel<S extends string> = S extends `${infer Before}_${infer After}` ? After extends `${infer First}${infer Rest}` ? `${Before}${Uppercase<First>}${SnakeToCamel<Rest>}` : Before : S;
2
- /**
3
- * 下划线命名法转为驼峰命名法
4
- *
5
- * @example
6
- * snakeToCamel("user_name") // "userName"
7
- */
8
- export declare const snakeToCamel: <S extends string>(str: S) => SnakeToCamel<S>;
9
- export type CamelToSnake<S extends string> = S extends `${infer First}${infer Rest}` ? Rest extends Uncapitalize<Rest> ? `${Lowercase<First>}${CamelToSnake<Rest>}` : `${Lowercase<First>}_${CamelToSnake<Rest>}` : Lowercase<S>;
10
- /**
11
- * 驼峰命名法转为下划线命名法
12
- *
13
- * @example
14
- * camelToSnake("shouldComponentUpdate") // "should_component_update"
15
- */
16
- export declare const camelToSnake: <S extends string>(str: S) => CamelToSnake<S>;
17
- export type Capitalize<S extends string> = S extends `${infer P1}${infer Rest}` ? P1 extends Capitalize<P1> ? S : `${Uppercase<P1>}${Rest}` : S;
18
- /**
19
- * 字符串首字母大写
20
- *
21
- * @example
22
- * capitalize("hello") // "Hello"
23
- */
24
- export declare const capitalize: <S extends string>(s: S) => Capitalize<S>;
25
- export type Decapitalize<S extends string> = S extends `${infer P1}${infer Rest}` ? P1 extends Lowercase<P1> ? P1 : `${Lowercase<P1>}${Rest}` : S;
26
- /**
27
- * 字符串首字母小写
28
- *
29
- * @example
30
- * decapitalize("Hello") // "hello"
31
- */
32
- export declare const decapitalize: <S extends string>(s: S) => Decapitalize<S>;
33
- /**
34
- * 图片地址转 base64 数据
35
- *
36
- * @param imageUrl 图片地址
37
- * @param options 可选配置
38
- * @param options.quality 压缩比率,默认 0.92(仅在浏览器支持 canvas 压缩时有效)
39
- *
40
- * @example
41
- * imageUrlToBase64("https://example.com/image.gif"); // "data:image/gif;base64,..."
42
- *
43
- * @example
44
- * imageUrlToBase64("https://example.com/image.jpg", { quality: 0.8 }); // 压缩至 80% 质量
45
- */
46
- export declare const imageUrlToBase64: (imageUrl: string, { quality }?: {
47
- quality?: number;
48
- }) => Promise<string>;
49
- /**
50
- * 将字符串压缩为单行精简格式
51
- *
52
- * @example
53
- * // "Hello, world."
54
- * compactStr(`
55
- * Hello,
56
- * world!
57
- * `, {
58
- * disableNewLineReplace: false,
59
- * });
60
- */
61
- export declare const compactStr: (text?: string, options?: {
62
- /** 最大保留长度,设为 0 或 Infinity 则不截断,默认 Infinity */
63
- maxLength?: number;
64
- /** 是否将换行符替换为字面量 \n,默认开启 */
65
- disableNewLineReplace?: boolean;
66
- /** 是否合并连续的空格/制表符为一个空格,默认开启 */
67
- disableWhitespaceCollapse?: boolean;
68
- /** 截断后的后缀,默认为 "..." */
69
- omission?: string;
70
- }) => string;
package/dist/time.d.ts DELETED
@@ -1,47 +0,0 @@
1
- /**
2
- * 延迟一段时间再执行后续代码
3
- * @param time 延迟时间,默认 150ms
4
- * @example
5
- * await sleep(1000); // 等待 1 秒执行后续代码
6
- */
7
- export declare const sleep: (time?: number) => Promise<unknown>;
8
- /**
9
- * 防抖:在指定时间内只执行最后一次调用
10
- * @param fn 要防抖的函数
11
- * @param delay 延迟时间,默认 300ms
12
- *
13
- * @remarks
14
- * 连续触发时,只有最后一次会执行。适合用于搜索框输入、窗口大小调整等场景。
15
- * 例如:用户输入"hello"过程中,不会触发搜索,只有停下来时才执行。
16
- *
17
- * 防抖 vs 节流:
18
- * - 防抖:等待触发停止后才执行(最后一次)
19
- * - 节流:按固定节奏执行(每隔多久执行一次)
20
- *
21
- * @example
22
- * const search = debounce((keyword: string) => {
23
- * console.log('搜索:', keyword);
24
- * });
25
- * search('hello'); // 300ms 后执行
26
- */
27
- export declare const debounce: <T extends (...args: any[]) => any>(fn: T, delay?: number) => (...args: Parameters<T>) => void;
28
- /**
29
- * 节流函数 - 在指定时间间隔内最多执行一次调用
30
- * @param fn 要节流的函数
31
- * @param delay 间隔时间,默认 300ms
32
- *
33
- * @remarks
34
- * 节流:连续触发时,按照固定间隔执行。适合用于滚动、拖拽等高频触发场景。
35
- * 例如:滚动页面时,每300ms最多执行一次回调,而不是每次滚动都执行。
36
- *
37
- * 防抖 vs 节流:
38
- * - 防抖:等待触发停止后才执行(最后一次)
39
- * - 节流:按固定节奏执行(每隔多久执行一次)
40
- *
41
- * @example
42
- * const handleScroll = throttle(() => {
43
- * console.log('滚动位置:', window.scrollY);
44
- * }, 200);
45
- * window.addEventListener('scroll', handleScroll);
46
- */
47
- export declare const throttle: <T extends (...args: any[]) => any>(fn: T, delay?: number) => (this: any, ...args: Parameters<T>) => void;
@@ -1,11 +0,0 @@
1
- // This file is read by tools that parse documentation comments conforming to the TSDoc standard.
2
- // It should be published with your NPM package. It should not be tracked by Git.
3
- {
4
- "tsdocVersion": "0.12",
5
- "toolPackages": [
6
- {
7
- "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.55.0"
9
- }
10
- ]
11
- }
package/src/string.ts DELETED
@@ -1,259 +0,0 @@
1
- export type SnakeToCamel<S extends string> =
2
- S extends `${infer Before}_${infer After}`
3
- ? After extends `${infer First}${infer Rest}`
4
- ? `${Before}${Uppercase<First>}${SnakeToCamel<Rest>}`
5
- : Before
6
- : S;
7
-
8
- /**
9
- * 下划线命名法转为驼峰命名法
10
- *
11
- * @example
12
- * snakeToCamel("user_name") // "userName"
13
- */
14
- export const snakeToCamel = <S extends string>(str: S): SnakeToCamel<S> => {
15
- return str.replace(/_([a-zA-Z])/g, (match, pattern) =>
16
- pattern.toUpperCase(),
17
- ) as SnakeToCamel<S>;
18
- };
19
-
20
- export type CamelToSnake<S extends string> =
21
- S extends `${infer First}${infer Rest}`
22
- ? Rest extends Uncapitalize<Rest>
23
- ? `${Lowercase<First>}${CamelToSnake<Rest>}`
24
- : `${Lowercase<First>}_${CamelToSnake<Rest>}`
25
- : Lowercase<S>;
26
-
27
- /**
28
- * 驼峰命名法转为下划线命名法
29
- *
30
- * @example
31
- * camelToSnake("shouldComponentUpdate") // "should_component_update"
32
- */
33
- export const camelToSnake = <S extends string>(str: S): CamelToSnake<S> => {
34
- return str.replace(
35
- /([A-Z])/g,
36
- (match, pattern) => `_${pattern.toLowerCase()}`,
37
- ) as CamelToSnake<S>;
38
- };
39
-
40
- export type Capitalize<S extends string> = S extends `${infer P1}${infer Rest}`
41
- ? P1 extends Capitalize<P1>
42
- ? S
43
- : `${Uppercase<P1>}${Rest}`
44
- : S;
45
-
46
- /**
47
- * 字符串首字母大写
48
- *
49
- * @example
50
- * capitalize("hello") // "Hello"
51
- */
52
- export const capitalize = <S extends string>(s: S): Capitalize<S> => {
53
- return (s.charAt(0).toUpperCase() + s.slice(1)) as Capitalize<S>;
54
- };
55
-
56
- export type Decapitalize<S extends string> =
57
- S extends `${infer P1}${infer Rest}`
58
- ? P1 extends Lowercase<P1>
59
- ? P1
60
- : `${Lowercase<P1>}${Rest}`
61
- : S;
62
-
63
- /**
64
- * 字符串首字母小写
65
- *
66
- * @example
67
- * decapitalize("Hello") // "hello"
68
- */
69
- export const decapitalize = <S extends string>(s: S): Decapitalize<S> => {
70
- return (s.charAt(0).toLowerCase() + s.slice(1)) as Decapitalize<S>;
71
- };
72
-
73
- /**
74
- * 将 ArrayBuffer 转换为 base64 字符串
75
- * 兼容浏览器、Bun 和 Node.js
76
- */
77
- const arrayBufferToBase64 = (buffer: ArrayBuffer): string => {
78
- const bytes = new Uint8Array(buffer);
79
- let binary = "";
80
- for (let i = 0; i < bytes.byteLength; i++) {
81
- binary += String.fromCharCode(bytes[i]!);
82
- }
83
- return btoa(binary);
84
- };
85
-
86
- /**
87
- * 图片压缩选项
88
- */
89
- export type ImageCompressionOptions = {
90
- /** 压缩比率,默认 0.92 */
91
- quality?: number;
92
- /**
93
- * 自定义压缩函数,用于非浏览器环境(Node.js/Bun)
94
- * 如果提供,将使用此函数替代默认的 canvas 压缩
95
- * @param arrayBuffer 图片的 ArrayBuffer 数据
96
- * @param mime 图片的 MIME 类型
97
- * @param quality 压缩质量
98
- * @returns 压缩后的 base64 字符串
99
- */
100
- compressor?: (
101
- arrayBuffer: ArrayBuffer,
102
- mime: string,
103
- quality: number,
104
- ) => Promise<string> | string;
105
- };
106
-
107
- /**
108
- * 图片地址转 base64 数据
109
- *
110
- * @param imageUrl 图片地址
111
- * @param options 可选配置
112
- * @param options.quality 压缩比率,默认 0.92
113
- * @param options.compressor 自定义压缩函数,用于 Node.js/Bun 环境
114
- *
115
- * @example
116
- * // 基本用法(浏览器自动使用 Canvas 压缩)
117
- * imageUrlToBase64("https://example.com/image.jpg");
118
- *
119
- * @example
120
- * // Node.js/Bun 使用 sharp 压缩
121
- * import sharp from "sharp";
122
- *
123
- * imageUrlToBase64("https://example.com/image.jpg", {
124
- * quality: 0.8,
125
- * compressor: async (buffer, mime, quality) => {
126
- * const compressed = await sharp(Buffer.from(buffer))
127
- * .jpeg({ quality: Math.round(quality * 100) })
128
- * .toBuffer();
129
- * return `data:${mime};base64,${compressed.toString("base64")}`;
130
- * }
131
- * });
132
- */
133
- export const imageUrlToBase64 = async (
134
- imageUrl: string,
135
- options: ImageCompressionOptions = {},
136
- ): Promise<string> => {
137
- const { quality = 0.92, compressor } = options;
138
-
139
- if (!imageUrl.startsWith("http")) {
140
- throw new Error("图片地址必须以http或https开头");
141
- }
142
-
143
- // 使用 fetch 获取图片数据
144
- const response = await fetch(imageUrl);
145
- if (!response.ok) {
146
- throw new Error(`获取图片失败: ${response.statusText}`);
147
- }
148
-
149
- const mime = response.headers.get("Content-Type") || "image/jpeg";
150
- const arrayBuffer = await response.arrayBuffer();
151
-
152
- // 对于非 JPEG/PNG 图片,直接返回 base64,不做压缩
153
- if (mime !== "image/jpeg" && mime !== "image/png") {
154
- const base64 = arrayBufferToBase64(arrayBuffer);
155
- return `data:${mime};base64,${base64}`;
156
- }
157
-
158
- // 如果提供了自定义压缩函数(用于 Node.js/Bun 环境),使用它
159
- if (compressor) {
160
- return await compressor(arrayBuffer, mime, quality);
161
- }
162
-
163
- // 浏览器环境:使用 OffscreenCanvas 压缩(Chrome 69+, Firefox 105+, Safari 16.4+)
164
- if (typeof OffscreenCanvas !== "undefined") {
165
- let bitmap: ImageBitmap | null = null;
166
-
167
- try {
168
- const blob = new Blob([arrayBuffer], { type: mime });
169
- bitmap = await createImageBitmap(blob);
170
-
171
- const canvas = new OffscreenCanvas(bitmap.width, bitmap.height);
172
- const ctx = canvas.getContext("2d");
173
- if (!ctx) {
174
- throw new Error("无法获取 canvas context");
175
- }
176
-
177
- ctx.drawImage(bitmap, 0, 0);
178
- bitmap.close();
179
- bitmap = null;
180
-
181
- // OffscreenCanvas 使用 convertToBlob 获取压缩后的图片
182
- const compressedBlob = await canvas.convertToBlob({
183
- type: mime,
184
- quality: quality,
185
- });
186
-
187
- // 将 Blob 转换为 base64
188
- const compressedArrayBuffer = await compressedBlob.arrayBuffer();
189
- const base64 = arrayBufferToBase64(compressedArrayBuffer);
190
- return `data:${mime};base64,${base64}`;
191
- } catch {
192
- // Canvas 压缩失败,返回原始 base64
193
- bitmap?.close();
194
- const base64 = arrayBufferToBase64(arrayBuffer);
195
- return `data:${mime};base64,${base64}`;
196
- }
197
- }
198
-
199
- // 非浏览器环境且没有提供压缩器,直接返回原始 base64
200
- const base64 = arrayBufferToBase64(arrayBuffer);
201
- return `data:${mime};base64,${base64}`;
202
- };
203
-
204
- /**
205
- * 将字符串压缩为单行精简格式
206
- *
207
- * @example
208
- * // "Hello, world."
209
- * compactStr(`
210
- * Hello,
211
- * world!
212
- * `, {
213
- * disableNewLineReplace: false,
214
- * });
215
- */
216
- export const compactStr = (
217
- text: string = "",
218
- options?: {
219
- /** 最大保留长度,设为 0 或 Infinity 则不截断,默认 Infinity */
220
- maxLength?: number;
221
- /** 是否将换行符替换为字面量 \n,默认开启 */
222
- disableNewLineReplace?: boolean;
223
- /** 是否合并连续的空格/制表符为一个空格,默认开启 */
224
- disableWhitespaceCollapse?: boolean;
225
- /** 截断后的后缀,默认为 "..." */
226
- omission?: string;
227
- },
228
- ): string => {
229
- if (!text) return "";
230
-
231
- const {
232
- maxLength = Infinity,
233
- disableNewLineReplace = false,
234
- disableWhitespaceCollapse = false,
235
- omission = "...",
236
- } = options ?? {};
237
-
238
- let result = text;
239
-
240
- // 处理换行符
241
- if (!disableNewLineReplace) {
242
- result = result.replace(/\r?\n/g, "\\n");
243
- } else {
244
- result = result.replace(/\r?\n/g, " ");
245
- }
246
-
247
- // 合并连续空格
248
- if (!disableWhitespaceCollapse) {
249
- result = result.replace(/\s+/g, " ");
250
- }
251
- result = result.trim();
252
-
253
- // 截断多出来的文字
254
- if (maxLength > 0 && result.length > maxLength) {
255
- return result.slice(0, maxLength) + omission;
256
- }
257
-
258
- return result;
259
- };