@zwa73/utils 1.0.193 → 1.0.195

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.
@@ -44,12 +44,12 @@ const UtilDecorators_1 = require("./UtilDecorators");
44
44
  const path_1 = __importDefault(require("path"));
45
45
  const UtilFileTools_1 = require("./UtilFileTools");
46
46
  const util_1 = require("util");
47
- const LiteFunction_1 = require("./LiteFunction");
48
47
  const HashMethodList = ["md5", "sha1", "sha256", "sha512", "sha3", "blake2", "blake3"];
49
48
  /**永不完成的Promise单例 */
50
49
  const NeverResolvedPromise = new Promise(() => { });
51
50
  /**常用函数 */
52
51
  class UtilFunc {
52
+ //#region 杂项
53
53
  /**获取当前时间戳
54
54
  * @returns 时间戳
55
55
  */
@@ -104,8 +104,8 @@ class UtilFunc {
104
104
  return crypto.createHash(method).update(str).digest('hex');
105
105
  }
106
106
  static async sleep(timeMs, result) {
107
- return new Promise(function (resolve, rejecte) {
108
- let timer = setTimeout(function () {
107
+ return new Promise((resolve, rejecte) => {
108
+ const timer = setTimeout(() => {
109
109
  resolve(result);
110
110
  }, timeMs);
111
111
  });
@@ -386,6 +386,150 @@ class UtilFunc {
386
386
  return JSON.stringify(token, compressReplacer, space)
387
387
  .replace(new RegExp(`"${ec}(.*?)${ec}"`, 'g'), (match, p1) => p1.replace(/\\([\\"])/g, '$1'));
388
388
  }
389
+ /**验证一个变量的类型是否为 T
390
+ * @template T - 验证类型
391
+ * @param t - 验证目标
392
+ */
393
+ static assertType(t) { return t; }
394
+ /**验证一个变量的类型是否为字面量
395
+ * 仅限浅层
396
+ * @template T - 验证类型
397
+ * @param t - 验证目标
398
+ */
399
+ static assertLiteral(t) { return t; }
400
+ /**深克隆 序列化并反序列化
401
+ * @template T - JToken类型的泛型
402
+ * @param obj - 克隆目标
403
+ * @returns 克隆结果
404
+ */
405
+ static deepClone(obj) {
406
+ return JSON.parse(JSON.stringify(obj));
407
+ }
408
+ /**是否为安全的数字
409
+ * 非NaN 非null/undefined
410
+ * 且是数字
411
+ * @param num - 所要检测的数字
412
+ * @returns 是否安全
413
+ */
414
+ static isSafeNumber(num) {
415
+ if (num == null)
416
+ return false;
417
+ if (typeof num === 'number') {
418
+ if (isNaN(num))
419
+ return false;
420
+ return true;
421
+ }
422
+ return false;
423
+ }
424
+ /**移除多行字符串中每行开始的最小空格数。
425
+ *
426
+ * @param input - 需要处理的多行 字符串模板 或 字符串。
427
+ * @param values - 插入模板字符串中的值。
428
+ * @returns 返回处理后的字符串,每行开始的空格数已被最小化。
429
+ *
430
+ * @example
431
+ * const name = 'World';
432
+ * const str = dedent`
433
+ * Hello,
434
+ * ${name}!
435
+ * `;
436
+ * console.log(str);
437
+ * // 输出:
438
+ * // Hello,
439
+ * // World!
440
+ */
441
+ static dedent(input, ...values) {
442
+ const str = typeof input === 'string'
443
+ ? input
444
+ : input.reduce((result, string, i) => result + string + (values[i] ?? ''), '');
445
+ const lines = str.split('\n');
446
+ const minIndent = Math.min(...lines.filter(line => line.trim() !== '').map(line => line.search(/\S/)));
447
+ return lines.map(line => line.slice(minIndent)).join('\n');
448
+ }
449
+ /**抛出错误
450
+ * @param message - 错误信息
451
+ * @param lvl - 日志等级
452
+ * @param opt - 额外参数
453
+ */
454
+ static throwError(message, lvl, opt) {
455
+ const e = new Error(message);
456
+ const stackLines = e.stack.split('\n');
457
+ e.stack = [stackLines[0]].concat(stackLines.slice(2)).join('\n'); // 移除第一行的堆栈信息
458
+ Object.assign(e, opt);
459
+ if (lvl) {
460
+ //SLogger.log(lvl,message);
461
+ UtilLogger_1.SLogger.log(lvl, e.stack);
462
+ }
463
+ throw e;
464
+ }
465
+ /**获取函数调用位置 getFunctionLocation
466
+ * @param stack - 深度 默认1, 即getFuncLoc函数被调用的位置
467
+ */
468
+ static getFuncLoc(stack = 1) {
469
+ const stackLines = new Error().stack.split('\n');
470
+ const regex = /([a-zA-Z]+?:.+?):(\d+?:\d+)/;
471
+ //console.log(stackLines)
472
+ const match = regex.exec(stackLines[stack + 1]);
473
+ if (match) {
474
+ const filePath = match[1];
475
+ const lineNumber = match[2];
476
+ return { filePath, lineNumber };
477
+ }
478
+ return undefined;
479
+ }
480
+ static publicIp;
481
+ /**获取当前公网ipv4 */
482
+ static async getPublicIpv4() {
483
+ if (UtilFunc.publicIp === undefined)
484
+ UtilFunc.publicIp = await UtilFunc.dynamicImport('public-ip');
485
+ return UtilFunc.publicIp.publicIpv4();
486
+ }
487
+ /**动态导入模块的函数。这个函数是为了在TypeScript的模块系统配置为CommonJS时,防止动态import被转译为require而设计的。
488
+ * 使用这个函数,你可以在TypeScript中动态地导入模块,而不需要担心import()被转译为require()。
489
+ * 请注意,这个函数使用了eval(),可能会带来安全风险。
490
+ *
491
+ * @param moduleName - 需要导入的模块的名称。
492
+ * @returns 返回一个Promise。当模块被成功导入时,这个Promise会解析为导入的模块。如果导入失败,这个Promise会被拒绝。
493
+ *
494
+ * @example
495
+ * async function main() {
496
+ * const pip = (await dynamicImport('public-ip')).default;
497
+ * console.log(await pip.v4());
498
+ * }
499
+ * main();
500
+ *
501
+ * @since Node.js 13.2,Node.js开始支持动态import。
502
+ */
503
+ static async dynamicImport(moduleName) {
504
+ return await eval(`import('${moduleName}')`);
505
+ }
506
+ /**缓存池 */
507
+ static cachePool = new WeakMap();
508
+ /**创建一个带有缓存有效期的memoize函数
509
+ * 只在传入值均为JToken时有效
510
+ * @param fn - 需要被memoize的函数
511
+ * @param expiry - 缓存的有效期 毫秒 默认为Infinity, 表示缓存永不过期。
512
+ * @returns 返回一个新的函数,这个函数在调用时会尝试从缓存中获取结果,如果缓存不存在或已过期,就会调用原函数并缓存其结果。
513
+ */
514
+ static memoize(fn, expiry = Infinity) {
515
+ const cache = UtilFunc.cachePool.get(fn) ?? UtilFunc.ivk(() => {
516
+ const c = new Map();
517
+ UtilFunc.cachePool.set(fn, c);
518
+ return c;
519
+ });
520
+ return ((...args) => {
521
+ const key = JSON.stringify(args);
522
+ const now = Date.now();
523
+ const cached = cache.get(key);
524
+ if (cached && now - cached.timestamp < expiry)
525
+ return cached.result;
526
+ const result = fn(...args);
527
+ cache.set(key, { result, timestamp: now });
528
+ return result;
529
+ });
530
+ }
531
+ //#endregion
532
+ //#region 队列处理
389
533
  /**代办表 用于队列处理等待 */
390
534
  static pendingMap = {};
391
535
  /**队列处理
@@ -448,6 +592,8 @@ class UtilFunc {
448
592
  const pd = UtilFunc.pendingMap[flag];
449
593
  return pd != null ? pd.length : 0;
450
594
  }
595
+ //#endregion
596
+ //#region symbol化处理工具
451
597
  /**创建一个Outcome */
452
598
  static outcome(key, value) {
453
599
  return {
@@ -545,104 +691,8 @@ class UtilFunc {
545
691
  UtilFunc.throwError(errLog ?? "expect验证了一个None值", "error");
546
692
  return t;
547
693
  }
548
- /**验证一个变量的类型是否为 T
549
- * @template T - 验证类型
550
- * @param t - 验证目标
551
- */
552
- static assertType(t) { return t; }
553
- /**验证一个变量的类型是否为字面量
554
- * 仅限浅层
555
- * @template T - 验证类型
556
- * @param t - 验证目标
557
- */
558
- static assertLiteral(t) { return t; }
559
- /**深克隆 序列化并反序列化
560
- * @template T - JToken类型的泛型
561
- * @param obj - 克隆目标
562
- * @returns 克隆结果
563
- */
564
- static deepClone(obj) {
565
- return JSON.parse(JSON.stringify(obj));
566
- }
567
- /**是否为安全的数字
568
- * 非NaN 非null/undefined
569
- * 且是数字
570
- * @param num - 所要检测的数字
571
- * @returns 是否安全
572
- */
573
- static isSafeNumber(num) {
574
- if (num == null)
575
- return false;
576
- if (typeof num === 'number') {
577
- if (isNaN(num))
578
- return false;
579
- return true;
580
- }
581
- return false;
582
- }
583
- /**移除多行字符串中每行开始的最小空格数。
584
- *
585
- * @param input - 需要处理的多行 字符串模板 或 字符串。
586
- * @param values - 插入模板字符串中的值。
587
- * @returns 返回处理后的字符串,每行开始的空格数已被最小化。
588
- *
589
- * @example
590
- * const name = 'World';
591
- * const str = dedent`
592
- * Hello,
593
- * ${name}!
594
- * `;
595
- * console.log(str);
596
- * // 输出:
597
- * // Hello,
598
- * // World!
599
- */
600
- static dedent(input, ...values) {
601
- const str = typeof input === 'string'
602
- ? input
603
- : input.reduce((result, string, i) => result + string + (values[i] ?? ''), '');
604
- const lines = str.split('\n');
605
- const minIndent = Math.min(...lines.filter(line => line.trim() !== '').map(line => line.search(/\S/)));
606
- return lines.map(line => line.slice(minIndent)).join('\n');
607
- }
608
- /**抛出错误
609
- * @param message - 错误信息
610
- * @param lvl - 日志等级
611
- * @param opt - 额外参数
612
- */
613
- static throwError(message, lvl, opt) {
614
- const e = new Error(message);
615
- const stackLines = e.stack.split('\n');
616
- e.stack = [stackLines[0]].concat(stackLines.slice(2)).join('\n'); // 移除第一行的堆栈信息
617
- Object.assign(e, opt);
618
- if (lvl) {
619
- //SLogger.log(lvl,message);
620
- UtilLogger_1.SLogger.log(lvl, e.stack);
621
- }
622
- throw e;
623
- }
624
- /**获取函数调用位置 getFunctionLocation
625
- * @param stack - 深度 默认1, 即getFuncLoc函数被调用的位置
626
- */
627
- static getFuncLoc(stack = 1) {
628
- const stackLines = new Error().stack.split('\n');
629
- const regex = /([a-zA-Z]+?:.+?):(\d+?:\d+)/;
630
- //console.log(stackLines)
631
- const match = regex.exec(stackLines[stack + 1]);
632
- if (match) {
633
- const filePath = match[1];
634
- const lineNumber = match[2];
635
- return { filePath, lineNumber };
636
- }
637
- return undefined;
638
- }
639
- static publicIp;
640
- /**获取当前公网ipv4 */
641
- static async getPublicIpv4() {
642
- if (UtilFunc.publicIp === undefined)
643
- UtilFunc.publicIp = await UtilFunc.dynamicImport('public-ip');
644
- return UtilFunc.publicIp.publicIpv4();
645
- }
694
+ //#endregion
695
+ //#region 显式处理错误工具
646
696
  /**将传入函数包装为显式处理错误的函数
647
697
  * @param func - 待转换函数
648
698
  * @returns 转换完成的函数
@@ -677,50 +727,8 @@ class UtilFunc {
677
727
  }
678
728
  };
679
729
  }
680
- /**动态导入模块的函数。这个函数是为了在TypeScript的模块系统配置为CommonJS时,防止动态import被转译为require而设计的。
681
- * 使用这个函数,你可以在TypeScript中动态地导入模块,而不需要担心import()被转译为require()。
682
- * 请注意,这个函数使用了eval(),可能会带来安全风险。
683
- *
684
- * @param moduleName - 需要导入的模块的名称。
685
- * @returns 返回一个Promise。当模块被成功导入时,这个Promise会解析为导入的模块。如果导入失败,这个Promise会被拒绝。
686
- *
687
- * @example
688
- * async function main() {
689
- * const pip = (await dynamicImport('public-ip')).default;
690
- * console.log(await pip.v4());
691
- * }
692
- * main();
693
- *
694
- * @since Node.js 13.2,Node.js开始支持动态import。
695
- */
696
- static async dynamicImport(moduleName) {
697
- return await eval(`import('${moduleName}')`);
698
- }
699
- /**缓存池 */
700
- static cachePool = new WeakMap();
701
- /**创建一个带有缓存有效期的memoize函数
702
- * 只在传入值均为JToken时有效
703
- * @param fn - 需要被memoize的函数
704
- * @param expiry - 缓存的有效期 毫秒 默认为Infinity, 表示缓存永不过期。
705
- * @returns 返回一个新的函数,这个函数在调用时会尝试从缓存中获取结果,如果缓存不存在或已过期,就会调用原函数并缓存其结果。
706
- */
707
- static memoize(fn, expiry = Infinity) {
708
- const cache = UtilFunc.cachePool.get(fn) ?? (0, LiteFunction_1.ivk)(() => {
709
- const c = new Map();
710
- UtilFunc.cachePool.set(fn, c);
711
- return c;
712
- });
713
- return ((...args) => {
714
- const key = JSON.stringify(args);
715
- const now = Date.now();
716
- const cached = cache.get(key);
717
- if (cached && now - cached.timestamp < expiry)
718
- return cached.result;
719
- const result = fn(...args);
720
- cache.set(key, { result, timestamp: now });
721
- return result;
722
- });
723
- }
730
+ //#endregion
731
+ //#region 解析srt
724
732
  /**将hh:mm:ss,ms格式转换为毫秒 */
725
733
  static parseSrtTime(time) {
726
734
  const [hours, minutes, seconds] = time.split(':');
@@ -764,6 +772,23 @@ class UtilFunc {
764
772
  return `${index + 1}\n${UtilFunc.formatSrtTime(segment.start)} --> ${UtilFunc.formatSrtTime(segment.end)}\n${segment.text}\n`;
765
773
  }).join('\n');
766
774
  }
775
+ //#endregion
776
+ //#region 常用直传的快速调用函数
777
+ /**立即执行传入的函数
778
+ * @param fn - 需要立即执行的函数。
779
+ * @returns 返回 fn 函数的执行结果。
780
+ */
781
+ static ivk(fn) {
782
+ return fn();
783
+ }
784
+ /**一个可供sort使用的从小到大排序的函数 */
785
+ static s2l(a, b) {
786
+ return a - b;
787
+ }
788
+ /**一个可供sort使用的从大到小排序的函数 */
789
+ static l2s(a, b) {
790
+ return b - a;
791
+ }
767
792
  }
768
793
  exports.UtilFunc = UtilFunc;
769
794
  __decorate([
@@ -154,8 +154,10 @@ export type NeedInit = {
154
154
  /**完成初始化的标记 */
155
155
  inited: Promise<any>;
156
156
  };
157
- /**可选的record */
157
+ /**可选的record PartialRecord */
158
158
  export type PRecord<K extends Keyable, V> = Partial<Record<K, V>>;
159
+ /** 可以是Promise MaybePromise*/
160
+ export type MPromise<T> = T | Promise<T>;
159
161
  /**任何Record */
160
162
  export type AnyRecord = Record<Keyable, any>;
161
163
  /**注释元组
package/dist/index.d.ts CHANGED
@@ -9,6 +9,5 @@ export * from './UtilDecorators';
9
9
  export * from './UtilFileTools';
10
10
  export * from './UtilLogger';
11
11
  export * from './UtilFP';
12
- export * from './QuickFunction';
12
+ export * from './QuickExport';
13
13
  export * from './UtilI18n';
14
- export * from './LiteFunction';
package/dist/index.js CHANGED
@@ -25,6 +25,5 @@ __exportStar(require("./UtilDecorators"), exports);
25
25
  __exportStar(require("./UtilFileTools"), exports);
26
26
  __exportStar(require("./UtilLogger"), exports);
27
27
  __exportStar(require("./UtilFP"), exports);
28
- __exportStar(require("./QuickFunction"), exports);
28
+ __exportStar(require("./QuickExport"), exports);
29
29
  __exportStar(require("./UtilI18n"), exports);
30
- __exportStar(require("./LiteFunction"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zwa73/utils",
3
- "version": "1.0.193",
3
+ "version": "1.0.195",
4
4
  "description": "my utils",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -24,6 +24,7 @@ export const {
24
24
  eitherize,
25
25
  taskEitherize,
26
26
  memoize,
27
+ ivk,l2s,s2l,
27
28
  } = UtilFunc;
28
29
 
29
30
  export const {
package/src/UtilClass.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { matchProc } from "./QuickFunction";
2
- import { Keyable, Literal } from "./UtilInterfaces";
1
+ import { matchProc } from "./QuickExport";
2
+ import { Keyable, Literal, MPromise } from "./UtilInterfaces";
3
3
  import Handlebars from 'handlebars';
4
4
  import { SLogger } from "./UtilLogger";
5
5
 
@@ -38,7 +38,7 @@ export class Piper<Arg, Result = Arg> {
38
38
  }
39
39
 
40
40
 
41
- type StreamOperation<T, U> = (item: T)=>Promise<U>|U;
41
+ type StreamOperation<T, U> = (item: T)=>MPromise<U>;
42
42
  /**并行流 */
43
43
  export class Stream<T> implements Iterable<T>{
44
44
  /**并发数*/
@@ -52,13 +52,16 @@ export class Stream<T> implements Iterable<T>{
52
52
  else this._list = new Array(...base);
53
53
  this._concurrent = concurrent;
54
54
  }
55
- /**从arraylike创建流 */
56
- static from<T>(args:Parameters<typeof Array.from<T>>[0],concurrent:number=1){
57
- return new Stream<T>(Array.from(args),concurrent);
55
+ /**从arraylike创建流
56
+ * @param args - arraylike
57
+ * @param concurrent - 并发数 默认 1
58
+ */
59
+ static from<T>(args:ArrayLike<T>,concurrent:number=1){
60
+ return new Stream(Array.from(args),concurrent);
58
61
  }
59
62
  /**从数组创建流 */
60
63
  static of<T>(...args:T[]){
61
- return new Stream<T>(args);
64
+ return new Stream(args);
62
65
  }
63
66
  /**设置并发数 */
64
67
  concurrent(count: number): Stream<T> {
package/src/UtilFP.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { isFailed, likeNone } from "./QuickFunction";
1
+ import { isFailed, likeNone } from "./QuickExport";
2
2
  import { AnyRecord, Keyable, Literal, Matchable, MatchableFlag, ProperSubset, ProperSubsetCheck } from "./UtilInterfaces";
3
3
  import { Failed, FailedLike, None } from "./UtilSymbol";
4
4
 
@@ -4,7 +4,7 @@ import path from "pathe";
4
4
  import * as fs from "fs";
5
5
  import { SLogger } from "@/src/UtilLogger";
6
6
  import { Stream } from "./UtilClass";
7
- import { throwError } from "./QuickFunction";
7
+ import { throwError } from "./QuickExport";
8
8
 
9
9
  /**输入输出路径映射
10
10
  * 输入路径:输入路径