@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.
- package/dist/{QuickFunction.d.ts → QuickExport.d.ts} +1 -1
- package/dist/{QuickFunction.js → QuickExport.js} +2 -2
- package/dist/UtilClass.d.ts +7 -4
- package/dist/UtilClass.js +6 -3
- package/dist/UtilFP.js +3 -3
- package/dist/UtilFfmpegTools.js +3 -3
- package/dist/UtilFunctions.d.ts +81 -72
- package/dist/UtilFunctions.js +170 -145
- package/dist/UtilInterfaces.d.ts +3 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -2
- package/package.json +1 -1
- package/src/{QuickFunction.ts → QuickExport.ts} +1 -0
- package/src/UtilClass.ts +10 -7
- package/src/UtilFP.ts +1 -1
- package/src/UtilFfmpegTools.ts +1 -1
- package/src/UtilFunctions.ts +194 -172
- package/src/UtilInterfaces.ts +3 -1
- package/src/index.ts +2 -3
- package/dist/LiteFunction.d.ts +0 -9
- package/dist/LiteFunction.js +0 -20
- package/src/LiteFunction.ts +0 -18
package/src/UtilFunctions.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as crypto from "crypto";
|
|
2
|
-
import { PRecord, AnyFunc, ExtractOutcome, IJData, JObject, JToken, Keyable, Literal, Matchable, MatchableFlag, Outcome, ReqStat, ReqVerifyFn, ProperSubsetCheck, UnionToIntersection, AnyRecord, AllExtends, SrtSegment } from "@/src/UtilInterfaces";
|
|
2
|
+
import { PRecord, AnyFunc, ExtractOutcome, IJData, JObject, JToken, Keyable, Literal, Matchable, MatchableFlag, Outcome, ReqStat, ReqVerifyFn, ProperSubsetCheck, UnionToIntersection, AnyRecord, AllExtends, SrtSegment, MPromise } from "@/src/UtilInterfaces";
|
|
3
3
|
import * as cp from "child_process";
|
|
4
4
|
import { LogLevel, SLogger } from "@/src/UtilLogger";
|
|
5
5
|
import { Completed, Failed, FailedLike, None, StatusSymbol, Success, SuccessLike, Terminated, Timeout } from "./UtilSymbol";
|
|
@@ -8,7 +8,6 @@ import opath from 'path';
|
|
|
8
8
|
import { UtilFT } from "./UtilFileTools";
|
|
9
9
|
import {inspect} from 'util';
|
|
10
10
|
import type * as publicIp from 'public-ip';
|
|
11
|
-
import { ivk } from "./LiteFunction";
|
|
12
11
|
|
|
13
12
|
const HashMethodList = ["md5","sha1","sha256","sha512","sha3","blake2","blake3"] as const;
|
|
14
13
|
type HashMethod = typeof HashMethodList[number];
|
|
@@ -74,6 +73,8 @@ type EachFieldCallback = (key: string, value: JToken,parent: JObject) => void;
|
|
|
74
73
|
|
|
75
74
|
/**常用函数 */
|
|
76
75
|
export class UtilFunc{
|
|
76
|
+
|
|
77
|
+
//#region 杂项
|
|
77
78
|
/**获取当前时间戳
|
|
78
79
|
* @returns 时间戳
|
|
79
80
|
*/
|
|
@@ -134,7 +135,6 @@ static calcHash(str:string,method:HashMethod='md5') {
|
|
|
134
135
|
return crypto.createHash(method).update(str).digest('hex');
|
|
135
136
|
}
|
|
136
137
|
|
|
137
|
-
|
|
138
138
|
/**等待 timeMs 毫秒
|
|
139
139
|
* @async
|
|
140
140
|
* @param timeMs - 等待的毫秒数
|
|
@@ -149,8 +149,8 @@ static async sleep<T>(timeMs: number): Promise<void>
|
|
|
149
149
|
*/
|
|
150
150
|
static async sleep<T>(timeMs: number, result:T): Promise<T>
|
|
151
151
|
static async sleep<T>(timeMs: number, result?:T): Promise<T|undefined> {
|
|
152
|
-
return new Promise(
|
|
153
|
-
|
|
152
|
+
return new Promise((resolve, rejecte) => {
|
|
153
|
+
const timer = setTimeout(() => {
|
|
154
154
|
resolve(result);
|
|
155
155
|
}, timeMs);
|
|
156
156
|
});
|
|
@@ -356,7 +356,7 @@ Promise<RepeatPromiseResult<T>>{
|
|
|
356
356
|
* @returns 超时则返回 处理函数委托 完成则返回结果
|
|
357
357
|
*/
|
|
358
358
|
static timelimitPromise<T>
|
|
359
|
-
(func:()=>
|
|
359
|
+
(func:()=>MPromise<T>,timeLimit?:number):Promise<SuccessOut<T>|TimeoutOut<T>>{
|
|
360
360
|
return new Promise<SuccessOut<T>|TimeoutOut<T>>((reslove)=>{
|
|
361
361
|
let clearTimer:(()=>void)| null = null;
|
|
362
362
|
const procer = (async ()=>await func())();
|
|
@@ -457,6 +457,167 @@ static stringifyJToken(token:JToken|IJData,opt?:StringifyOpt){
|
|
|
457
457
|
p1.replace(/\\([\\"])/g, '$1'));
|
|
458
458
|
}
|
|
459
459
|
|
|
460
|
+
/**验证一个变量的类型是否为 T
|
|
461
|
+
* @template T - 验证类型
|
|
462
|
+
* @param t - 验证目标
|
|
463
|
+
*/
|
|
464
|
+
static assertType<T>(t:T):T{return t;}
|
|
465
|
+
|
|
466
|
+
/**验证一个变量的类型是否为字面量
|
|
467
|
+
* 仅限浅层
|
|
468
|
+
* @template T - 验证类型
|
|
469
|
+
* @param t - 验证目标
|
|
470
|
+
*/
|
|
471
|
+
static assertLiteral<T>(t:Literal<T>):T{return t as T;}
|
|
472
|
+
|
|
473
|
+
/**深克隆 序列化并反序列化
|
|
474
|
+
* @template T - JToken类型的泛型
|
|
475
|
+
* @param obj - 克隆目标
|
|
476
|
+
* @returns 克隆结果
|
|
477
|
+
*/
|
|
478
|
+
static deepClone<T extends JToken>(obj: T): T {
|
|
479
|
+
return JSON.parse(JSON.stringify(obj));
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**是否为安全的数字
|
|
483
|
+
* 非NaN 非null/undefined
|
|
484
|
+
* 且是数字
|
|
485
|
+
* @param num - 所要检测的数字
|
|
486
|
+
* @returns 是否安全
|
|
487
|
+
*/
|
|
488
|
+
static isSafeNumber(num: unknown): boolean {
|
|
489
|
+
if (num == null) return false;
|
|
490
|
+
if(typeof num === 'number') {
|
|
491
|
+
if(isNaN(num)) return false;
|
|
492
|
+
return true;
|
|
493
|
+
}
|
|
494
|
+
return false;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/**移除多行字符串中每行开始的最小空格数。
|
|
498
|
+
*
|
|
499
|
+
* @param input - 需要处理的多行 字符串模板 或 字符串。
|
|
500
|
+
* @param values - 插入模板字符串中的值。
|
|
501
|
+
* @returns 返回处理后的字符串,每行开始的空格数已被最小化。
|
|
502
|
+
*
|
|
503
|
+
* @example
|
|
504
|
+
* const name = 'World';
|
|
505
|
+
* const str = dedent`
|
|
506
|
+
* Hello,
|
|
507
|
+
* ${name}!
|
|
508
|
+
* `;
|
|
509
|
+
* console.log(str);
|
|
510
|
+
* // 输出:
|
|
511
|
+
* // Hello,
|
|
512
|
+
* // World!
|
|
513
|
+
*/
|
|
514
|
+
static dedent(input: TemplateStringsArray|string, ...values: any[]): string {
|
|
515
|
+
const str = typeof input === 'string'
|
|
516
|
+
? input
|
|
517
|
+
: input.reduce((result, string, i) => result + string + (values[i] ?? ''), '');
|
|
518
|
+
const lines = str.split('\n');
|
|
519
|
+
const minIndent = Math.min(
|
|
520
|
+
...lines.filter(line => line.trim() !== '').map(line => line.search(/\S/))
|
|
521
|
+
);
|
|
522
|
+
return lines.map(line => line.slice(minIndent)).join('\n');
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/**抛出错误
|
|
526
|
+
* @param message - 错误信息
|
|
527
|
+
* @param lvl - 日志等级
|
|
528
|
+
* @param opt - 额外参数
|
|
529
|
+
*/
|
|
530
|
+
static throwError(message:string,lvl?:LogLevel,opt?:{}):never{
|
|
531
|
+
const e = new Error(message);
|
|
532
|
+
const stackLines = e.stack!.split('\n');
|
|
533
|
+
e.stack = [stackLines[0]].concat(stackLines.slice(2)).join('\n'); // 移除第一行的堆栈信息
|
|
534
|
+
Object.assign(e, opt);
|
|
535
|
+
if(lvl){
|
|
536
|
+
//SLogger.log(lvl,message);
|
|
537
|
+
SLogger.log(lvl,e.stack);
|
|
538
|
+
}
|
|
539
|
+
throw e;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
/**获取函数调用位置 getFunctionLocation
|
|
543
|
+
* @param stack - 深度 默认1, 即getFuncLoc函数被调用的位置
|
|
544
|
+
*/
|
|
545
|
+
static getFuncLoc(stack=1) {
|
|
546
|
+
const stackLines = new Error().stack!.split('\n');
|
|
547
|
+
const regex = /([a-zA-Z]+?:.+?):(\d+?:\d+)/;
|
|
548
|
+
//console.log(stackLines)
|
|
549
|
+
const match = regex.exec(stackLines[stack+1]);
|
|
550
|
+
if(match){
|
|
551
|
+
const filePath = match[1];
|
|
552
|
+
const lineNumber = match[2] as `${number}:${number}`;
|
|
553
|
+
return {filePath,lineNumber}
|
|
554
|
+
}
|
|
555
|
+
return undefined;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
private static publicIp?:typeof publicIp;
|
|
559
|
+
/**获取当前公网ipv4 */
|
|
560
|
+
static async getPublicIpv4(){
|
|
561
|
+
if(UtilFunc.publicIp===undefined)
|
|
562
|
+
UtilFunc.publicIp = await UtilFunc.dynamicImport('public-ip') as typeof publicIp;
|
|
563
|
+
return UtilFunc.publicIp.publicIpv4();
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
/**动态导入模块的函数。这个函数是为了在TypeScript的模块系统配置为CommonJS时,防止动态import被转译为require而设计的。
|
|
567
|
+
* 使用这个函数,你可以在TypeScript中动态地导入模块,而不需要担心import()被转译为require()。
|
|
568
|
+
* 请注意,这个函数使用了eval(),可能会带来安全风险。
|
|
569
|
+
*
|
|
570
|
+
* @param moduleName - 需要导入的模块的名称。
|
|
571
|
+
* @returns 返回一个Promise。当模块被成功导入时,这个Promise会解析为导入的模块。如果导入失败,这个Promise会被拒绝。
|
|
572
|
+
*
|
|
573
|
+
* @example
|
|
574
|
+
* async function main() {
|
|
575
|
+
* const pip = (await dynamicImport('public-ip')).default;
|
|
576
|
+
* console.log(await pip.v4());
|
|
577
|
+
* }
|
|
578
|
+
* main();
|
|
579
|
+
*
|
|
580
|
+
* @since Node.js 13.2,Node.js开始支持动态import。
|
|
581
|
+
*/
|
|
582
|
+
static async dynamicImport(moduleName:string):Promise<any> {
|
|
583
|
+
return await eval(`import('${moduleName}')`);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**缓存池 */
|
|
587
|
+
static cachePool = new WeakMap<Function, Map<string, { result: any, timestamp: number }>>();
|
|
588
|
+
|
|
589
|
+
/**创建一个带有缓存有效期的memoize函数
|
|
590
|
+
* 只在传入值均为JToken时有效
|
|
591
|
+
* @param fn - 需要被memoize的函数
|
|
592
|
+
* @param expiry - 缓存的有效期 毫秒 默认为Infinity, 表示缓存永不过期。
|
|
593
|
+
* @returns 返回一个新的函数,这个函数在调用时会尝试从缓存中获取结果,如果缓存不存在或已过期,就会调用原函数并缓存其结果。
|
|
594
|
+
*/
|
|
595
|
+
static memoize<T extends (...args:any[])=>any> (fn: T, expiry = Infinity):
|
|
596
|
+
T extends (...args:infer In)=>any
|
|
597
|
+
? AllExtends<In,JToken> extends true ? T : never
|
|
598
|
+
: never {
|
|
599
|
+
const cache = UtilFunc.cachePool.get(fn) ?? UtilFunc.ivk(()=>{
|
|
600
|
+
const c = new Map();
|
|
601
|
+
UtilFunc.cachePool.set(fn, c);
|
|
602
|
+
return c;
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
return ((...args: Parameters<T>): ReturnType<T> => {
|
|
606
|
+
const key = JSON.stringify(args);
|
|
607
|
+
const now = Date.now();
|
|
608
|
+
const cached = cache.get(key);
|
|
609
|
+
|
|
610
|
+
if (cached && now - cached.timestamp < expiry)
|
|
611
|
+
return cached.result;
|
|
612
|
+
|
|
613
|
+
const result = fn(...args);
|
|
614
|
+
cache.set(key, { result, timestamp: now });
|
|
615
|
+
return result;
|
|
616
|
+
}) as any;
|
|
617
|
+
}
|
|
618
|
+
//#endregion
|
|
619
|
+
|
|
620
|
+
//#region 队列处理
|
|
460
621
|
/**代办表 用于队列处理等待 */
|
|
461
622
|
static pendingMap:Record<Keyable,AnyFunc[]> = {};
|
|
462
623
|
|
|
@@ -512,6 +673,7 @@ static queueProc<T>(flag: Keyable, task: () => Promise<T>): Promise<T> {
|
|
|
512
673
|
// 返回Promise,以便调用者可以等待任务完成
|
|
513
674
|
return promise;
|
|
514
675
|
}
|
|
676
|
+
|
|
515
677
|
/**队列获取目标的代办事件数
|
|
516
678
|
* @param flag - 队列标签
|
|
517
679
|
*/
|
|
@@ -519,9 +681,9 @@ static queueLength(flag:Keyable){
|
|
|
519
681
|
const pd = UtilFunc.pendingMap[flag]
|
|
520
682
|
return pd!=null ? pd.length : 0;
|
|
521
683
|
}
|
|
684
|
+
//#endregion
|
|
522
685
|
|
|
523
|
-
|
|
524
|
-
|
|
686
|
+
//#region symbol化处理工具
|
|
525
687
|
/**创建一个Outcome */
|
|
526
688
|
static outcome<K extends Keyable,V> (key:K,value:V):Outcome<K,V>{
|
|
527
689
|
return {
|
|
@@ -530,7 +692,6 @@ static outcome<K extends Keyable,V> (key:K,value:V):Outcome<K,V>{
|
|
|
530
692
|
}
|
|
531
693
|
}
|
|
532
694
|
|
|
533
|
-
|
|
534
695
|
/**处理联合值
|
|
535
696
|
* @param t - 目标值
|
|
536
697
|
* @param procObj - 所有可能的id组成的处理函数映射 (status, result)=>any
|
|
@@ -582,8 +743,6 @@ static matchPartialProc<
|
|
|
582
743
|
return undefined;
|
|
583
744
|
}
|
|
584
745
|
|
|
585
|
-
|
|
586
|
-
|
|
587
746
|
/**根据典型的成功或失败状态运行函数
|
|
588
747
|
* @param t - 目标值
|
|
589
748
|
* @param sucessFunc - 成功则运行的函数 (result)=>any
|
|
@@ -606,6 +765,7 @@ static sucesProc<T extends Matchable<StatusSymbol>,
|
|
|
606
765
|
if(t!==None) SLogger.warn(`sucesProc 传入了一个不匹配的值, 将作为None运行: `,t);
|
|
607
766
|
return noneFunc() as any;
|
|
608
767
|
}
|
|
768
|
+
|
|
609
769
|
/**是失败的 */
|
|
610
770
|
static isFailed<T>
|
|
611
771
|
(tg:T):'E' extends ProperSubsetCheck<symbol,T>? boolean
|
|
@@ -655,113 +815,9 @@ static expect<T>(t:T,errLog?:string):Exclude<T,None>{
|
|
|
655
815
|
if(t===None) UtilFunc.throwError(errLog??"expect验证了一个None值","error");
|
|
656
816
|
return t as Exclude<T,None>;
|
|
657
817
|
}
|
|
818
|
+
//#endregion
|
|
658
819
|
|
|
659
|
-
|
|
660
|
-
* @template T - 验证类型
|
|
661
|
-
* @param t - 验证目标
|
|
662
|
-
*/
|
|
663
|
-
static assertType<T>(t:T):T{return t;}
|
|
664
|
-
/**验证一个变量的类型是否为字面量
|
|
665
|
-
* 仅限浅层
|
|
666
|
-
* @template T - 验证类型
|
|
667
|
-
* @param t - 验证目标
|
|
668
|
-
*/
|
|
669
|
-
static assertLiteral<T>(t:Literal<T>):T{return t as T;}
|
|
670
|
-
|
|
671
|
-
/**深克隆 序列化并反序列化
|
|
672
|
-
* @template T - JToken类型的泛型
|
|
673
|
-
* @param obj - 克隆目标
|
|
674
|
-
* @returns 克隆结果
|
|
675
|
-
*/
|
|
676
|
-
static deepClone<T extends JToken>(obj: T): T {
|
|
677
|
-
return JSON.parse(JSON.stringify(obj));
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
/**是否为安全的数字
|
|
681
|
-
* 非NaN 非null/undefined
|
|
682
|
-
* 且是数字
|
|
683
|
-
* @param num - 所要检测的数字
|
|
684
|
-
* @returns 是否安全
|
|
685
|
-
*/
|
|
686
|
-
static isSafeNumber(num: unknown): boolean {
|
|
687
|
-
if (num == null) return false;
|
|
688
|
-
if(typeof num === 'number') {
|
|
689
|
-
if(isNaN(num)) return false;
|
|
690
|
-
return true;
|
|
691
|
-
}
|
|
692
|
-
return false;
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
/**移除多行字符串中每行开始的最小空格数。
|
|
696
|
-
*
|
|
697
|
-
* @param input - 需要处理的多行 字符串模板 或 字符串。
|
|
698
|
-
* @param values - 插入模板字符串中的值。
|
|
699
|
-
* @returns 返回处理后的字符串,每行开始的空格数已被最小化。
|
|
700
|
-
*
|
|
701
|
-
* @example
|
|
702
|
-
* const name = 'World';
|
|
703
|
-
* const str = dedent`
|
|
704
|
-
* Hello,
|
|
705
|
-
* ${name}!
|
|
706
|
-
* `;
|
|
707
|
-
* console.log(str);
|
|
708
|
-
* // 输出:
|
|
709
|
-
* // Hello,
|
|
710
|
-
* // World!
|
|
711
|
-
*/
|
|
712
|
-
static dedent(input: TemplateStringsArray|string, ...values: any[]): string {
|
|
713
|
-
const str = typeof input === 'string'
|
|
714
|
-
? input
|
|
715
|
-
: input.reduce((result, string, i) => result + string + (values[i] ?? ''), '');
|
|
716
|
-
const lines = str.split('\n');
|
|
717
|
-
const minIndent = Math.min(
|
|
718
|
-
...lines.filter(line => line.trim() !== '').map(line => line.search(/\S/))
|
|
719
|
-
);
|
|
720
|
-
return lines.map(line => line.slice(minIndent)).join('\n');
|
|
721
|
-
}
|
|
722
|
-
/**抛出错误
|
|
723
|
-
* @param message - 错误信息
|
|
724
|
-
* @param lvl - 日志等级
|
|
725
|
-
* @param opt - 额外参数
|
|
726
|
-
*/
|
|
727
|
-
static throwError(message:string,lvl?:LogLevel,opt?:{}):never{
|
|
728
|
-
const e = new Error(message);
|
|
729
|
-
const stackLines = e.stack!.split('\n');
|
|
730
|
-
e.stack = [stackLines[0]].concat(stackLines.slice(2)).join('\n'); // 移除第一行的堆栈信息
|
|
731
|
-
Object.assign(e, opt);
|
|
732
|
-
if(lvl){
|
|
733
|
-
//SLogger.log(lvl,message);
|
|
734
|
-
SLogger.log(lvl,e.stack);
|
|
735
|
-
}
|
|
736
|
-
throw e;
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
/**获取函数调用位置 getFunctionLocation
|
|
740
|
-
* @param stack - 深度 默认1, 即getFuncLoc函数被调用的位置
|
|
741
|
-
*/
|
|
742
|
-
static getFuncLoc(stack=1) {
|
|
743
|
-
const stackLines = new Error().stack!.split('\n');
|
|
744
|
-
const regex = /([a-zA-Z]+?:.+?):(\d+?:\d+)/;
|
|
745
|
-
//console.log(stackLines)
|
|
746
|
-
const match = regex.exec(stackLines[stack+1]);
|
|
747
|
-
if(match){
|
|
748
|
-
const filePath = match[1];
|
|
749
|
-
const lineNumber = match[2] as `${number}:${number}`;
|
|
750
|
-
return {filePath,lineNumber}
|
|
751
|
-
}
|
|
752
|
-
return undefined;
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
private static publicIp?:typeof publicIp;
|
|
757
|
-
|
|
758
|
-
/**获取当前公网ipv4 */
|
|
759
|
-
static async getPublicIpv4(){
|
|
760
|
-
if(UtilFunc.publicIp===undefined)
|
|
761
|
-
UtilFunc.publicIp = await UtilFunc.dynamicImport('public-ip') as typeof publicIp;
|
|
762
|
-
return UtilFunc.publicIp.publicIpv4();
|
|
763
|
-
}
|
|
764
|
-
|
|
820
|
+
//#region 显式处理错误工具
|
|
765
821
|
/**将传入函数包装为显式处理错误的函数
|
|
766
822
|
* @param func - 待转换函数
|
|
767
823
|
* @returns 转换完成的函数
|
|
@@ -794,62 +850,9 @@ static taskEitherize<T extends (...args:any)=>Promise<any>>(func:T) {
|
|
|
794
850
|
}
|
|
795
851
|
};
|
|
796
852
|
}
|
|
853
|
+
//#endregion
|
|
797
854
|
|
|
798
|
-
|
|
799
|
-
* 使用这个函数,你可以在TypeScript中动态地导入模块,而不需要担心import()被转译为require()。
|
|
800
|
-
* 请注意,这个函数使用了eval(),可能会带来安全风险。
|
|
801
|
-
*
|
|
802
|
-
* @param moduleName - 需要导入的模块的名称。
|
|
803
|
-
* @returns 返回一个Promise。当模块被成功导入时,这个Promise会解析为导入的模块。如果导入失败,这个Promise会被拒绝。
|
|
804
|
-
*
|
|
805
|
-
* @example
|
|
806
|
-
* async function main() {
|
|
807
|
-
* const pip = (await dynamicImport('public-ip')).default;
|
|
808
|
-
* console.log(await pip.v4());
|
|
809
|
-
* }
|
|
810
|
-
* main();
|
|
811
|
-
*
|
|
812
|
-
* @since Node.js 13.2,Node.js开始支持动态import。
|
|
813
|
-
*/
|
|
814
|
-
static async dynamicImport(moduleName:string):Promise<any> {
|
|
815
|
-
return await eval(`import('${moduleName}')`);
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
/**缓存池 */
|
|
819
|
-
static cachePool = new WeakMap<Function, Map<string, { result: any, timestamp: number }>>();
|
|
820
|
-
|
|
821
|
-
/**创建一个带有缓存有效期的memoize函数
|
|
822
|
-
* 只在传入值均为JToken时有效
|
|
823
|
-
* @param fn - 需要被memoize的函数
|
|
824
|
-
* @param expiry - 缓存的有效期 毫秒 默认为Infinity, 表示缓存永不过期。
|
|
825
|
-
* @returns 返回一个新的函数,这个函数在调用时会尝试从缓存中获取结果,如果缓存不存在或已过期,就会调用原函数并缓存其结果。
|
|
826
|
-
*/
|
|
827
|
-
static memoize<T extends (...args:any[])=>any> (fn: T, expiry = Infinity):
|
|
828
|
-
T extends (...args:infer In)=>any
|
|
829
|
-
? AllExtends<In,JToken> extends true ? T : never
|
|
830
|
-
: never {
|
|
831
|
-
const cache = UtilFunc.cachePool.get(fn) ?? ivk(()=>{
|
|
832
|
-
const c = new Map();
|
|
833
|
-
UtilFunc.cachePool.set(fn, c);
|
|
834
|
-
return c;
|
|
835
|
-
});
|
|
836
|
-
|
|
837
|
-
return ((...args: Parameters<T>): ReturnType<T> => {
|
|
838
|
-
const key = JSON.stringify(args);
|
|
839
|
-
const now = Date.now();
|
|
840
|
-
const cached = cache.get(key);
|
|
841
|
-
|
|
842
|
-
if (cached && now - cached.timestamp < expiry)
|
|
843
|
-
return cached.result;
|
|
844
|
-
|
|
845
|
-
const result = fn(...args);
|
|
846
|
-
cache.set(key, { result, timestamp: now });
|
|
847
|
-
return result;
|
|
848
|
-
}) as any;
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
855
|
+
//#region 解析srt
|
|
853
856
|
/**将hh:mm:ss,ms格式转换为毫秒 */
|
|
854
857
|
static parseSrtTime(time: string): number {
|
|
855
858
|
const [hours, minutes, seconds] = time.split(':');
|
|
@@ -899,5 +902,24 @@ static createSrt(segments: SrtSegment[]): string {
|
|
|
899
902
|
return `${index + 1}\n${UtilFunc.formatSrtTime(segment.start)} --> ${UtilFunc.formatSrtTime(segment.end)}\n${segment.text}\n`;
|
|
900
903
|
}).join('\n');
|
|
901
904
|
}
|
|
905
|
+
//#endregion
|
|
906
|
+
|
|
907
|
+
//#region 常用直传的快速调用函数
|
|
908
|
+
/**立即执行传入的函数
|
|
909
|
+
* @param fn - 需要立即执行的函数。
|
|
910
|
+
* @returns 返回 fn 函数的执行结果。
|
|
911
|
+
*/
|
|
912
|
+
static ivk<T extends ()=>any>(fn:T): ReturnType<T> {
|
|
913
|
+
return fn();
|
|
914
|
+
}
|
|
915
|
+
/**一个可供sort使用的从小到大排序的函数 */
|
|
916
|
+
static s2l(a:number,b:number) {
|
|
917
|
+
return a-b;
|
|
918
|
+
}
|
|
919
|
+
/**一个可供sort使用的从大到小排序的函数 */
|
|
920
|
+
static l2s(a:number,b:number) {
|
|
921
|
+
return b-a;
|
|
922
|
+
}
|
|
923
|
+
//#endregion
|
|
902
924
|
|
|
903
925
|
}
|
package/src/UtilInterfaces.ts
CHANGED
|
@@ -236,8 +236,10 @@ export type NeedInit = {
|
|
|
236
236
|
inited: Promise<any>;
|
|
237
237
|
};
|
|
238
238
|
|
|
239
|
-
/**可选的record */
|
|
239
|
+
/**可选的record PartialRecord */
|
|
240
240
|
export type PRecord<K extends Keyable,V> = Partial<Record<K,V>>;
|
|
241
|
+
/** 可以是Promise MaybePromise*/
|
|
242
|
+
export type MPromise<T> = T | Promise<T>;
|
|
241
243
|
/**任何Record */
|
|
242
244
|
export type AnyRecord = Record<Keyable,any>;
|
|
243
245
|
|
package/src/index.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 './
|
|
13
|
-
export * from './UtilI18n';
|
|
14
|
-
export * from './LiteFunction';
|
|
12
|
+
export * from './QuickExport';
|
|
13
|
+
export * from './UtilI18n';
|
package/dist/LiteFunction.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**立即执行传入的函数
|
|
2
|
-
* @param fn - 需要立即执行的函数。
|
|
3
|
-
* @returns 返回 fn 函数的执行结果。
|
|
4
|
-
*/
|
|
5
|
-
export declare function ivk<T extends () => any>(fn: T): ReturnType<T>;
|
|
6
|
-
/**一个可供sort使用的从小到大排序的函数 */
|
|
7
|
-
export declare function s2l(a: number, b: number): number;
|
|
8
|
-
/**一个可供sort使用的从大到小排序的函数 */
|
|
9
|
-
export declare function l2s(a: number, b: number): number;
|
package/dist/LiteFunction.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ivk = ivk;
|
|
4
|
-
exports.s2l = s2l;
|
|
5
|
-
exports.l2s = l2s;
|
|
6
|
-
/**立即执行传入的函数
|
|
7
|
-
* @param fn - 需要立即执行的函数。
|
|
8
|
-
* @returns 返回 fn 函数的执行结果。
|
|
9
|
-
*/
|
|
10
|
-
function ivk(fn) {
|
|
11
|
-
return fn();
|
|
12
|
-
}
|
|
13
|
-
/**一个可供sort使用的从小到大排序的函数 */
|
|
14
|
-
function s2l(a, b) {
|
|
15
|
-
return a - b;
|
|
16
|
-
}
|
|
17
|
-
/**一个可供sort使用的从大到小排序的函数 */
|
|
18
|
-
function l2s(a, b) {
|
|
19
|
-
return b - a;
|
|
20
|
-
}
|
package/src/LiteFunction.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
/**立即执行传入的函数
|
|
5
|
-
* @param fn - 需要立即执行的函数。
|
|
6
|
-
* @returns 返回 fn 函数的执行结果。
|
|
7
|
-
*/
|
|
8
|
-
export function ivk<T extends ()=>any>(fn:T): ReturnType<T> {
|
|
9
|
-
return fn();
|
|
10
|
-
}
|
|
11
|
-
/**一个可供sort使用的从小到大排序的函数 */
|
|
12
|
-
export function s2l(a:number,b:number) {
|
|
13
|
-
return a-b;
|
|
14
|
-
}
|
|
15
|
-
/**一个可供sort使用的从大到小排序的函数 */
|
|
16
|
-
export function l2s(a:number,b:number) {
|
|
17
|
-
return b-a;
|
|
18
|
-
}
|