@zwa73/utils 1.0.192 → 1.0.194
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.js +11 -17
- package/dist/UtilFP.js +3 -3
- package/dist/UtilFfmpegTools.js +3 -3
- package/dist/UtilFunctions.d.ts +79 -75
- package/dist/UtilFunctions.js +170 -151
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/{QuickFunction.ts → QuickExport.ts} +2 -3
- package/src/UtilClass.ts +5 -11
- package/src/UtilFP.ts +1 -1
- package/src/UtilFfmpegTools.ts +1 -1
- package/src/UtilFunctions.ts +192 -179
- package/src/index.ts +1 -1
- package/dist/ServiceManager.d.ts +0 -0
- package/dist/ServiceManager.js +0 -1
- package/src/ServiceManager.ts +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { UtilFT } from "./UtilFileTools";
|
|
2
2
|
import { UtilFunc } from "./UtilFunctions";
|
|
3
|
-
export declare const outcome: typeof UtilFunc.outcome, matchProc: typeof UtilFunc.matchProc, sucesProc: typeof UtilFunc.sucesProc, isFailed: typeof UtilFunc.isFailed, isSafeNumber: typeof UtilFunc.isSafeNumber, isSuccess: typeof UtilFunc.isSuccess, likeNone: typeof UtilFunc.likeNone, expect: typeof UtilFunc.expect, assertType: typeof UtilFunc.assertType, assertLiteral: typeof UtilFunc.assertLiteral, deepClone: typeof UtilFunc.deepClone, sleep: typeof UtilFunc.sleep, stringifyJToken: typeof UtilFunc.stringifyJToken, getTime: typeof UtilFunc.getTime, mapEntries: typeof UtilFunc.mapEntries, dedent: typeof UtilFunc.dedent, throwError: typeof UtilFunc.throwError, eitherize: typeof UtilFunc.eitherize, taskEitherize: typeof UtilFunc.taskEitherize, memoize: typeof UtilFunc.memoize, ivk: typeof UtilFunc.ivk;
|
|
3
|
+
export declare const outcome: typeof UtilFunc.outcome, matchProc: typeof UtilFunc.matchProc, sucesProc: typeof UtilFunc.sucesProc, isFailed: typeof UtilFunc.isFailed, isSafeNumber: typeof UtilFunc.isSafeNumber, isSuccess: typeof UtilFunc.isSuccess, likeNone: typeof UtilFunc.likeNone, expect: typeof UtilFunc.expect, assertType: typeof UtilFunc.assertType, assertLiteral: typeof UtilFunc.assertLiteral, deepClone: typeof UtilFunc.deepClone, sleep: typeof UtilFunc.sleep, stringifyJToken: typeof UtilFunc.stringifyJToken, getTime: typeof UtilFunc.getTime, mapEntries: typeof UtilFunc.mapEntries, dedent: typeof UtilFunc.dedent, throwError: typeof UtilFunc.throwError, eitherize: typeof UtilFunc.eitherize, taskEitherize: typeof UtilFunc.taskEitherize, memoize: typeof UtilFunc.memoize, ivk: typeof UtilFunc.ivk, l2s: typeof UtilFunc.l2s, s2l: typeof UtilFunc.s2l;
|
|
4
4
|
export declare const stylizePath: typeof UtilFT.stylizePath, posixizePath: typeof UtilFT.posixizePath, win32izePath: typeof UtilFT.win32izePath, currosizePath: typeof UtilFT.currosizePath;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.currosizePath = exports.win32izePath = exports.posixizePath = exports.stylizePath = exports.ivk = exports.memoize = exports.taskEitherize = exports.eitherize = exports.throwError = exports.dedent = exports.mapEntries = exports.getTime = exports.stringifyJToken = exports.sleep = exports.deepClone = exports.assertLiteral = exports.assertType = exports.expect = exports.likeNone = exports.isSuccess = exports.isSafeNumber = exports.isFailed = exports.sucesProc = exports.matchProc = exports.outcome = void 0;
|
|
3
|
+
exports.currosizePath = exports.win32izePath = exports.posixizePath = exports.stylizePath = exports.s2l = exports.l2s = exports.ivk = exports.memoize = exports.taskEitherize = exports.eitherize = exports.throwError = exports.dedent = exports.mapEntries = exports.getTime = exports.stringifyJToken = exports.sleep = exports.deepClone = exports.assertLiteral = exports.assertType = exports.expect = exports.likeNone = exports.isSuccess = exports.isSafeNumber = exports.isFailed = exports.sucesProc = exports.matchProc = exports.outcome = void 0;
|
|
4
4
|
const UtilFileTools_1 = require("./UtilFileTools");
|
|
5
5
|
const UtilFunctions_1 = require("./UtilFunctions");
|
|
6
6
|
const UtilSymbol_1 = require("./UtilSymbol");
|
|
7
|
-
exports.outcome = UtilFunctions_1.UtilFunc.outcome, exports.matchProc = UtilFunctions_1.UtilFunc.matchProc, exports.sucesProc = UtilFunctions_1.UtilFunc.sucesProc, exports.isFailed = UtilFunctions_1.UtilFunc.isFailed, exports.isSafeNumber = UtilFunctions_1.UtilFunc.isSafeNumber, exports.isSuccess = UtilFunctions_1.UtilFunc.isSuccess, exports.likeNone = UtilFunctions_1.UtilFunc.likeNone, exports.expect = UtilFunctions_1.UtilFunc.expect, exports.assertType = UtilFunctions_1.UtilFunc.assertType, exports.assertLiteral = UtilFunctions_1.UtilFunc.assertLiteral, exports.deepClone = UtilFunctions_1.UtilFunc.deepClone, exports.sleep = UtilFunctions_1.UtilFunc.sleep, exports.stringifyJToken = UtilFunctions_1.UtilFunc.stringifyJToken, exports.getTime = UtilFunctions_1.UtilFunc.getTime, exports.mapEntries = UtilFunctions_1.UtilFunc.mapEntries, exports.dedent = UtilFunctions_1.UtilFunc.dedent, exports.throwError = UtilFunctions_1.UtilFunc.throwError, exports.eitherize = UtilFunctions_1.UtilFunc.eitherize, exports.taskEitherize = UtilFunctions_1.UtilFunc.taskEitherize, exports.memoize = UtilFunctions_1.UtilFunc.memoize, exports.ivk = UtilFunctions_1.UtilFunc.ivk;
|
|
7
|
+
exports.outcome = UtilFunctions_1.UtilFunc.outcome, exports.matchProc = UtilFunctions_1.UtilFunc.matchProc, exports.sucesProc = UtilFunctions_1.UtilFunc.sucesProc, exports.isFailed = UtilFunctions_1.UtilFunc.isFailed, exports.isSafeNumber = UtilFunctions_1.UtilFunc.isSafeNumber, exports.isSuccess = UtilFunctions_1.UtilFunc.isSuccess, exports.likeNone = UtilFunctions_1.UtilFunc.likeNone, exports.expect = UtilFunctions_1.UtilFunc.expect, exports.assertType = UtilFunctions_1.UtilFunc.assertType, exports.assertLiteral = UtilFunctions_1.UtilFunc.assertLiteral, exports.deepClone = UtilFunctions_1.UtilFunc.deepClone, exports.sleep = UtilFunctions_1.UtilFunc.sleep, exports.stringifyJToken = UtilFunctions_1.UtilFunc.stringifyJToken, exports.getTime = UtilFunctions_1.UtilFunc.getTime, exports.mapEntries = UtilFunctions_1.UtilFunc.mapEntries, exports.dedent = UtilFunctions_1.UtilFunc.dedent, exports.throwError = UtilFunctions_1.UtilFunc.throwError, exports.eitherize = UtilFunctions_1.UtilFunc.eitherize, exports.taskEitherize = UtilFunctions_1.UtilFunc.taskEitherize, exports.memoize = UtilFunctions_1.UtilFunc.memoize, exports.ivk = UtilFunctions_1.UtilFunc.ivk, exports.l2s = UtilFunctions_1.UtilFunc.l2s, exports.s2l = UtilFunctions_1.UtilFunc.s2l;
|
|
8
8
|
exports.stylizePath = UtilFileTools_1.UtilFT.stylizePath, exports.posixizePath = UtilFileTools_1.UtilFT.posixizePath, exports.win32izePath = UtilFileTools_1.UtilFT.win32izePath, exports.currosizePath = UtilFileTools_1.UtilFT.currosizePath;
|
|
9
9
|
if (false) {
|
|
10
10
|
let aaser = (0, exports.assertLiteral)({ a: 1 });
|
package/dist/UtilClass.js
CHANGED
|
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.Hbs = exports.Stream = exports.Piper = void 0;
|
|
7
|
-
const
|
|
7
|
+
const QuickExport_1 = require("./QuickExport");
|
|
8
8
|
const handlebars_1 = __importDefault(require("handlebars"));
|
|
9
9
|
const UtilLogger_1 = require("./UtilLogger");
|
|
10
10
|
/**函数管道器 */
|
|
@@ -74,7 +74,7 @@ class Stream {
|
|
|
74
74
|
return [[...this]];
|
|
75
75
|
const size = this.length;
|
|
76
76
|
const result = [];
|
|
77
|
-
(0,
|
|
77
|
+
(0, QuickExport_1.matchProc)(mode, {
|
|
78
78
|
//轮询平均分
|
|
79
79
|
'average': () => {
|
|
80
80
|
for (let i = 0; i < count; i++) {
|
|
@@ -135,22 +135,16 @@ class Stream {
|
|
|
135
135
|
async append() {
|
|
136
136
|
if (this._operation.length == 0)
|
|
137
137
|
return this;
|
|
138
|
-
const pList = [];
|
|
139
138
|
//均分处理
|
|
140
|
-
this.divide(this._concurrent)
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
item = await operation(item);
|
|
150
|
-
result.push(item);
|
|
151
|
-
}
|
|
152
|
-
reslove(result);
|
|
153
|
-
}));
|
|
139
|
+
const pList = this.divide(this._concurrent)
|
|
140
|
+
.map(async (subList) => {
|
|
141
|
+
const result = [];
|
|
142
|
+
for (let item of subList) {
|
|
143
|
+
for (const operation of this._operation)
|
|
144
|
+
item = await operation(item);
|
|
145
|
+
result.push(item);
|
|
146
|
+
}
|
|
147
|
+
return (result);
|
|
154
148
|
});
|
|
155
149
|
const rlist = await Promise.all(pList);
|
|
156
150
|
//拼接结果 轮询均分
|
package/dist/UtilFP.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.UtilFP = void 0;
|
|
4
|
-
const
|
|
4
|
+
const QuickExport_1 = require("./QuickExport");
|
|
5
5
|
/**常用函数式编程库 */
|
|
6
6
|
var UtilFP;
|
|
7
7
|
(function (UtilFP) {
|
|
@@ -55,9 +55,9 @@ var UtilFP;
|
|
|
55
55
|
}
|
|
56
56
|
UtilFP.map = map;
|
|
57
57
|
/**创建在传入值为失败时不运行的函数 */
|
|
58
|
-
UtilFP.chain = (f) => (arg) => (0,
|
|
58
|
+
UtilFP.chain = (f) => (arg) => (0, QuickExport_1.isFailed)(arg) ? arg : f(arg);
|
|
59
59
|
/**创建在传入值为失败时才会尝试运行的函数 */
|
|
60
|
-
UtilFP.alt = (f) => (arg) => (0,
|
|
60
|
+
UtilFP.alt = (f) => (arg) => (0, QuickExport_1.isFailed)(arg) ? f(arg) : arg;
|
|
61
61
|
/**
|
|
62
62
|
let asd = bindTo("sss",123,{abc:223});//?
|
|
63
63
|
let sumvoid = ()=>10;
|
package/dist/UtilFfmpegTools.js
CHANGED
|
@@ -32,7 +32,7 @@ const pathe_1 = __importDefault(require("pathe"));
|
|
|
32
32
|
const fs = __importStar(require("fs"));
|
|
33
33
|
const UtilLogger_1 = require("./UtilLogger");
|
|
34
34
|
const UtilClass_1 = require("./UtilClass");
|
|
35
|
-
const
|
|
35
|
+
const QuickExport_1 = require("./QuickExport");
|
|
36
36
|
/**ffmpeg工具类
|
|
37
37
|
*/
|
|
38
38
|
class SFfmpegTool {
|
|
@@ -193,11 +193,11 @@ class SFfmpegTool {
|
|
|
193
193
|
static async isMono(filePath) {
|
|
194
194
|
const metadata = await SFfmpegTool.getAudioMetaData(filePath);
|
|
195
195
|
if (metadata == null)
|
|
196
|
-
(0,
|
|
196
|
+
(0, QuickExport_1.throwError)("SFfmpegTool.isMono 获取音频元数据失败");
|
|
197
197
|
// 检查音频流的声道数
|
|
198
198
|
const audioStream = metadata.streams.find(stream => stream.codec_type === 'audio');
|
|
199
199
|
if (audioStream == null)
|
|
200
|
-
(0,
|
|
200
|
+
(0, QuickExport_1.throwError)("SFfmpegTool.isMono 未找到音频流");
|
|
201
201
|
return audioStream.channels === 1;
|
|
202
202
|
}
|
|
203
203
|
//多线程处理
|
package/dist/UtilFunctions.d.ts
CHANGED
|
@@ -141,66 +141,6 @@ export declare class UtilFunc {
|
|
|
141
141
|
* @returns 转换完成的字符串
|
|
142
142
|
*/
|
|
143
143
|
static stringifyJToken(token: JToken | IJData, opt?: StringifyOpt): string;
|
|
144
|
-
/**代办表 用于队列处理等待 */
|
|
145
|
-
static pendingMap: Record<Keyable, AnyFunc[]>;
|
|
146
|
-
/**队列处理
|
|
147
|
-
* 等待标签为 flag 的队列
|
|
148
|
-
* 直到排在之前的任务全部完成再处理当前Promise
|
|
149
|
-
* @param flag - 队列标签
|
|
150
|
-
* @param task - 任务逻辑
|
|
151
|
-
* @returns 处理结果
|
|
152
|
-
*/
|
|
153
|
-
static queueProc<T>(flag: Keyable, task: () => Promise<T>): Promise<T>;
|
|
154
|
-
/**队列获取目标的代办事件数
|
|
155
|
-
* @param flag - 队列标签
|
|
156
|
-
*/
|
|
157
|
-
static queueLength(flag: Keyable): number;
|
|
158
|
-
/**创建一个Outcome */
|
|
159
|
-
static outcome<K extends Keyable, V>(key: K, value: V): Outcome<K, V>;
|
|
160
|
-
/**处理联合值
|
|
161
|
-
* @param t - 目标值
|
|
162
|
-
* @param procObj - 所有可能的id组成的处理函数映射 (status, result)=>any
|
|
163
|
-
* @returns 任意处理函数的返回值
|
|
164
|
-
*/
|
|
165
|
-
static matchProc<T extends Matchable<Keyable>, P extends UnionToIntersection<{
|
|
166
|
-
[K in MatchableFlag<T>]: (k: K, v: ExtractOutcome<T, MatchableFlag<K>>['result']) => unknown;
|
|
167
|
-
}>>(t: T, procObj: P): P extends Record<any, AnyFunc> ? {
|
|
168
|
-
[K in keyof P]: ReturnType<P[K]>;
|
|
169
|
-
}[keyof P] : never;
|
|
170
|
-
/**处理部分联合值
|
|
171
|
-
* @param t - 目标值
|
|
172
|
-
* @param procObj - 所有可能的id组成的处理函数映射 (status, result)=>any
|
|
173
|
-
* @returns 任意处理函数的返回值
|
|
174
|
-
*/
|
|
175
|
-
static matchPartialProc<T extends Matchable<Keyable>, P extends Partial<{
|
|
176
|
-
[K in MatchableFlag<T>]: (k: K, v: ExtractOutcome<T, MatchableFlag<K>>['result']) => unknown;
|
|
177
|
-
}>>(t: T, procObj: P): (P extends PRecord<Keyable, AnyFunc> ? {
|
|
178
|
-
[K in keyof P]: P[K] extends AnyFunc ? ReturnType<P[K]> : undefined;
|
|
179
|
-
}[keyof P] : never) | undefined;
|
|
180
|
-
/**根据典型的成功或失败状态运行函数
|
|
181
|
-
* @param t - 目标值
|
|
182
|
-
* @param sucessFunc - 成功则运行的函数 (result)=>any
|
|
183
|
-
* @param failedFunc - 失败则运行的函数 (result)=>any
|
|
184
|
-
* @param noneFunc - 无结果或不匹配时运行的函数 ()=>any
|
|
185
|
-
* @returns 非成功或失败时返回 None
|
|
186
|
-
*/
|
|
187
|
-
static sucesProc<T extends Matchable<StatusSymbol>, S extends (arg: ExtractOutcome<T, SuccessLike>['result']) => unknown, F extends (arg: ExtractOutcome<T, FailedLike>['result']) => unknown = (arg: ExtractOutcome<T, FailedLike>['result']) => None, N extends () => unknown = () => None>(t: T, sucessFunc: S, failedFunc?: F, noneFunc?: N): ReturnType<S> | ReturnType<F> | ReturnType<N>;
|
|
188
|
-
/**是失败的 */
|
|
189
|
-
static isFailed<T>(tg: T): 'E' extends ProperSubsetCheck<symbol, T> ? boolean : T extends Matchable<FailedLike> ? true : MatchableFlag<T> extends Exclude<MatchableFlag<T>, FailedLike> ? false : boolean;
|
|
190
|
-
/**是成功的 */
|
|
191
|
-
static isSuccess<T>(tg: T): 'E' extends ProperSubsetCheck<symbol, T> ? boolean : T extends Matchable<SuccessLike> ? true : MatchableFlag<T> extends Exclude<MatchableFlag<T>, SuccessLike> ? false : boolean;
|
|
192
|
-
/**类似空值 undefined null None
|
|
193
|
-
* @param t - 检测目标
|
|
194
|
-
* @param strictLog - 应该严格等于None 否则将输出警告 但任然返回true
|
|
195
|
-
*/
|
|
196
|
-
static likeNone(t: unknown, strictLog?: boolean): t is None;
|
|
197
|
-
/**验证一个值是否为空
|
|
198
|
-
* 为空则抛异
|
|
199
|
-
* @param t - 验证目标
|
|
200
|
-
* @param errLog - 异常信息
|
|
201
|
-
* @returns 排除None的原值
|
|
202
|
-
*/
|
|
203
|
-
static expect<T>(t: T, errLog?: string): Exclude<T, None>;
|
|
204
144
|
/**验证一个变量的类型是否为 T
|
|
205
145
|
* @template T - 验证类型
|
|
206
146
|
* @param t - 验证目标
|
|
@@ -259,16 +199,6 @@ export declare class UtilFunc {
|
|
|
259
199
|
private static publicIp?;
|
|
260
200
|
/**获取当前公网ipv4 */
|
|
261
201
|
static getPublicIpv4(): Promise<string>;
|
|
262
|
-
/**将传入函数包装为显式处理错误的函数
|
|
263
|
-
* @param func - 待转换函数
|
|
264
|
-
* @returns 转换完成的函数
|
|
265
|
-
*/
|
|
266
|
-
static eitherize<T extends AnyFunc>(func: T): (...args: Parameters<T>) => Outcome<typeof Success, ReturnType<T>> | Outcome<typeof Failed, Error>;
|
|
267
|
-
/**将传入的异步函数包装为显式处理错误的函数
|
|
268
|
-
* @param func - 待转换函数
|
|
269
|
-
* @returns 转换完成的函数
|
|
270
|
-
*/
|
|
271
|
-
static taskEitherize<T extends (...args: any) => Promise<any>>(func: T): (...args: Parameters<T>) => Promise<Outcome<typeof Failed, Error> | Outcome<typeof Success, Awaited<ReturnType<T>>>>;
|
|
272
202
|
/**动态导入模块的函数。这个函数是为了在TypeScript的模块系统配置为CommonJS时,防止动态import被转译为require而设计的。
|
|
273
203
|
* 使用这个函数,你可以在TypeScript中动态地导入模块,而不需要担心import()被转译为require()。
|
|
274
204
|
* 请注意,这个函数使用了eval(),可能会带来安全风险。
|
|
@@ -291,11 +221,6 @@ export declare class UtilFunc {
|
|
|
291
221
|
result: any;
|
|
292
222
|
timestamp: number;
|
|
293
223
|
}>>;
|
|
294
|
-
/**立即执行传入的函数
|
|
295
|
-
* @param fn - 需要立即执行的函数。
|
|
296
|
-
* @returns 返回 fn 函数的执行结果。
|
|
297
|
-
*/
|
|
298
|
-
static ivk<T extends () => any>(fn: T): ReturnType<T>;
|
|
299
224
|
/**创建一个带有缓存有效期的memoize函数
|
|
300
225
|
* 只在传入值均为JToken时有效
|
|
301
226
|
* @param fn - 需要被memoize的函数
|
|
@@ -303,6 +228,76 @@ export declare class UtilFunc {
|
|
|
303
228
|
* @returns 返回一个新的函数,这个函数在调用时会尝试从缓存中获取结果,如果缓存不存在或已过期,就会调用原函数并缓存其结果。
|
|
304
229
|
*/
|
|
305
230
|
static memoize<T extends (...args: any[]) => any>(fn: T, expiry?: number): T extends (...args: infer In) => any ? AllExtends<In, JToken> extends true ? T : never : never;
|
|
231
|
+
/**代办表 用于队列处理等待 */
|
|
232
|
+
static pendingMap: Record<Keyable, AnyFunc[]>;
|
|
233
|
+
/**队列处理
|
|
234
|
+
* 等待标签为 flag 的队列
|
|
235
|
+
* 直到排在之前的任务全部完成再处理当前Promise
|
|
236
|
+
* @param flag - 队列标签
|
|
237
|
+
* @param task - 任务逻辑
|
|
238
|
+
* @returns 处理结果
|
|
239
|
+
*/
|
|
240
|
+
static queueProc<T>(flag: Keyable, task: () => Promise<T>): Promise<T>;
|
|
241
|
+
/**队列获取目标的代办事件数
|
|
242
|
+
* @param flag - 队列标签
|
|
243
|
+
*/
|
|
244
|
+
static queueLength(flag: Keyable): number;
|
|
245
|
+
/**创建一个Outcome */
|
|
246
|
+
static outcome<K extends Keyable, V>(key: K, value: V): Outcome<K, V>;
|
|
247
|
+
/**处理联合值
|
|
248
|
+
* @param t - 目标值
|
|
249
|
+
* @param procObj - 所有可能的id组成的处理函数映射 (status, result)=>any
|
|
250
|
+
* @returns 任意处理函数的返回值
|
|
251
|
+
*/
|
|
252
|
+
static matchProc<T extends Matchable<Keyable>, P extends UnionToIntersection<{
|
|
253
|
+
[K in MatchableFlag<T>]: (k: K, v: ExtractOutcome<T, MatchableFlag<K>>['result']) => unknown;
|
|
254
|
+
}>>(t: T, procObj: P): P extends Record<any, AnyFunc> ? {
|
|
255
|
+
[K in keyof P]: ReturnType<P[K]>;
|
|
256
|
+
}[keyof P] : never;
|
|
257
|
+
/**处理部分联合值
|
|
258
|
+
* @param t - 目标值
|
|
259
|
+
* @param procObj - 所有可能的id组成的处理函数映射 (status, result)=>any
|
|
260
|
+
* @returns 任意处理函数的返回值
|
|
261
|
+
*/
|
|
262
|
+
static matchPartialProc<T extends Matchable<Keyable>, P extends Partial<{
|
|
263
|
+
[K in MatchableFlag<T>]: (k: K, v: ExtractOutcome<T, MatchableFlag<K>>['result']) => unknown;
|
|
264
|
+
}>>(t: T, procObj: P): (P extends PRecord<Keyable, AnyFunc> ? {
|
|
265
|
+
[K in keyof P]: P[K] extends AnyFunc ? ReturnType<P[K]> : undefined;
|
|
266
|
+
}[keyof P] : never) | undefined;
|
|
267
|
+
/**根据典型的成功或失败状态运行函数
|
|
268
|
+
* @param t - 目标值
|
|
269
|
+
* @param sucessFunc - 成功则运行的函数 (result)=>any
|
|
270
|
+
* @param failedFunc - 失败则运行的函数 (result)=>any
|
|
271
|
+
* @param noneFunc - 无结果或不匹配时运行的函数 ()=>any
|
|
272
|
+
* @returns 非成功或失败时返回 None
|
|
273
|
+
*/
|
|
274
|
+
static sucesProc<T extends Matchable<StatusSymbol>, S extends (arg: ExtractOutcome<T, SuccessLike>['result']) => unknown, F extends (arg: ExtractOutcome<T, FailedLike>['result']) => unknown = (arg: ExtractOutcome<T, FailedLike>['result']) => None, N extends () => unknown = () => None>(t: T, sucessFunc: S, failedFunc?: F, noneFunc?: N): ReturnType<S> | ReturnType<F> | ReturnType<N>;
|
|
275
|
+
/**是失败的 */
|
|
276
|
+
static isFailed<T>(tg: T): 'E' extends ProperSubsetCheck<symbol, T> ? boolean : T extends Matchable<FailedLike> ? true : MatchableFlag<T> extends Exclude<MatchableFlag<T>, FailedLike> ? false : boolean;
|
|
277
|
+
/**是成功的 */
|
|
278
|
+
static isSuccess<T>(tg: T): 'E' extends ProperSubsetCheck<symbol, T> ? boolean : T extends Matchable<SuccessLike> ? true : MatchableFlag<T> extends Exclude<MatchableFlag<T>, SuccessLike> ? false : boolean;
|
|
279
|
+
/**类似空值 undefined null None
|
|
280
|
+
* @param t - 检测目标
|
|
281
|
+
* @param strictLog - 应该严格等于None 否则将输出警告 但任然返回true
|
|
282
|
+
*/
|
|
283
|
+
static likeNone(t: unknown, strictLog?: boolean): t is None;
|
|
284
|
+
/**验证一个值是否为空
|
|
285
|
+
* 为空则抛异
|
|
286
|
+
* @param t - 验证目标
|
|
287
|
+
* @param errLog - 异常信息
|
|
288
|
+
* @returns 排除None的原值
|
|
289
|
+
*/
|
|
290
|
+
static expect<T>(t: T, errLog?: string): Exclude<T, None>;
|
|
291
|
+
/**将传入函数包装为显式处理错误的函数
|
|
292
|
+
* @param func - 待转换函数
|
|
293
|
+
* @returns 转换完成的函数
|
|
294
|
+
*/
|
|
295
|
+
static eitherize<T extends AnyFunc>(func: T): (...args: Parameters<T>) => Outcome<typeof Success, ReturnType<T>> | Outcome<typeof Failed, Error>;
|
|
296
|
+
/**将传入的异步函数包装为显式处理错误的函数
|
|
297
|
+
* @param func - 待转换函数
|
|
298
|
+
* @returns 转换完成的函数
|
|
299
|
+
*/
|
|
300
|
+
static taskEitherize<T extends (...args: any) => Promise<any>>(func: T): (...args: Parameters<T>) => Promise<Outcome<typeof Failed, Error> | Outcome<typeof Success, Awaited<ReturnType<T>>>>;
|
|
306
301
|
/**将hh:mm:ss,ms格式转换为毫秒 */
|
|
307
302
|
static parseSrtTime(time: string): number;
|
|
308
303
|
/**将毫秒转换为hh:mm:ss,ms格式 */
|
|
@@ -311,5 +306,14 @@ export declare class UtilFunc {
|
|
|
311
306
|
static parseSrt(srtText: string): SrtSegment[];
|
|
312
307
|
/**转换json为srt文本 */
|
|
313
308
|
static createSrt(segments: SrtSegment[]): string;
|
|
309
|
+
/**立即执行传入的函数
|
|
310
|
+
* @param fn - 需要立即执行的函数。
|
|
311
|
+
* @returns 返回 fn 函数的执行结果。
|
|
312
|
+
*/
|
|
313
|
+
static ivk<T extends () => any>(fn: T): ReturnType<T>;
|
|
314
|
+
/**一个可供sort使用的从小到大排序的函数 */
|
|
315
|
+
static s2l(a: number, b: number): number;
|
|
316
|
+
/**一个可供sort使用的从大到小排序的函数 */
|
|
317
|
+
static l2s(a: number, b: number): number;
|
|
314
318
|
}
|
|
315
319
|
export {};
|
package/dist/UtilFunctions.js
CHANGED
|
@@ -49,6 +49,7 @@ const HashMethodList = ["md5", "sha1", "sha256", "sha512", "sha3", "blake2", "bl
|
|
|
49
49
|
const NeverResolvedPromise = new Promise(() => { });
|
|
50
50
|
/**常用函数 */
|
|
51
51
|
class UtilFunc {
|
|
52
|
+
//#region 杂项
|
|
52
53
|
/**获取当前时间戳
|
|
53
54
|
* @returns 时间戳
|
|
54
55
|
*/
|
|
@@ -103,8 +104,8 @@ class UtilFunc {
|
|
|
103
104
|
return crypto.createHash(method).update(str).digest('hex');
|
|
104
105
|
}
|
|
105
106
|
static async sleep(timeMs, result) {
|
|
106
|
-
return new Promise(
|
|
107
|
-
|
|
107
|
+
return new Promise((resolve, rejecte) => {
|
|
108
|
+
const timer = setTimeout(() => {
|
|
108
109
|
resolve(result);
|
|
109
110
|
}, timeMs);
|
|
110
111
|
});
|
|
@@ -385,6 +386,150 @@ class UtilFunc {
|
|
|
385
386
|
return JSON.stringify(token, compressReplacer, space)
|
|
386
387
|
.replace(new RegExp(`"${ec}(.*?)${ec}"`, 'g'), (match, p1) => p1.replace(/\\([\\"])/g, '$1'));
|
|
387
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 队列处理
|
|
388
533
|
/**代办表 用于队列处理等待 */
|
|
389
534
|
static pendingMap = {};
|
|
390
535
|
/**队列处理
|
|
@@ -447,6 +592,8 @@ class UtilFunc {
|
|
|
447
592
|
const pd = UtilFunc.pendingMap[flag];
|
|
448
593
|
return pd != null ? pd.length : 0;
|
|
449
594
|
}
|
|
595
|
+
//#endregion
|
|
596
|
+
//#region symbol化处理工具
|
|
450
597
|
/**创建一个Outcome */
|
|
451
598
|
static outcome(key, value) {
|
|
452
599
|
return {
|
|
@@ -544,104 +691,8 @@ class UtilFunc {
|
|
|
544
691
|
UtilFunc.throwError(errLog ?? "expect验证了一个None值", "error");
|
|
545
692
|
return t;
|
|
546
693
|
}
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
* @param t - 验证目标
|
|
550
|
-
*/
|
|
551
|
-
static assertType(t) { return t; }
|
|
552
|
-
/**验证一个变量的类型是否为字面量
|
|
553
|
-
* 仅限浅层
|
|
554
|
-
* @template T - 验证类型
|
|
555
|
-
* @param t - 验证目标
|
|
556
|
-
*/
|
|
557
|
-
static assertLiteral(t) { return t; }
|
|
558
|
-
/**深克隆 序列化并反序列化
|
|
559
|
-
* @template T - JToken类型的泛型
|
|
560
|
-
* @param obj - 克隆目标
|
|
561
|
-
* @returns 克隆结果
|
|
562
|
-
*/
|
|
563
|
-
static deepClone(obj) {
|
|
564
|
-
return JSON.parse(JSON.stringify(obj));
|
|
565
|
-
}
|
|
566
|
-
/**是否为安全的数字
|
|
567
|
-
* 非NaN 非null/undefined
|
|
568
|
-
* 且是数字
|
|
569
|
-
* @param num - 所要检测的数字
|
|
570
|
-
* @returns 是否安全
|
|
571
|
-
*/
|
|
572
|
-
static isSafeNumber(num) {
|
|
573
|
-
if (num == null)
|
|
574
|
-
return false;
|
|
575
|
-
if (typeof num === 'number') {
|
|
576
|
-
if (isNaN(num))
|
|
577
|
-
return false;
|
|
578
|
-
return true;
|
|
579
|
-
}
|
|
580
|
-
return false;
|
|
581
|
-
}
|
|
582
|
-
/**移除多行字符串中每行开始的最小空格数。
|
|
583
|
-
*
|
|
584
|
-
* @param input - 需要处理的多行 字符串模板 或 字符串。
|
|
585
|
-
* @param values - 插入模板字符串中的值。
|
|
586
|
-
* @returns 返回处理后的字符串,每行开始的空格数已被最小化。
|
|
587
|
-
*
|
|
588
|
-
* @example
|
|
589
|
-
* const name = 'World';
|
|
590
|
-
* const str = dedent`
|
|
591
|
-
* Hello,
|
|
592
|
-
* ${name}!
|
|
593
|
-
* `;
|
|
594
|
-
* console.log(str);
|
|
595
|
-
* // 输出:
|
|
596
|
-
* // Hello,
|
|
597
|
-
* // World!
|
|
598
|
-
*/
|
|
599
|
-
static dedent(input, ...values) {
|
|
600
|
-
const str = typeof input === 'string'
|
|
601
|
-
? input
|
|
602
|
-
: input.reduce((result, string, i) => result + string + (values[i] ?? ''), '');
|
|
603
|
-
const lines = str.split('\n');
|
|
604
|
-
const minIndent = Math.min(...lines.filter(line => line.trim() !== '').map(line => line.search(/\S/)));
|
|
605
|
-
return lines.map(line => line.slice(minIndent)).join('\n');
|
|
606
|
-
}
|
|
607
|
-
/**抛出错误
|
|
608
|
-
* @param message - 错误信息
|
|
609
|
-
* @param lvl - 日志等级
|
|
610
|
-
* @param opt - 额外参数
|
|
611
|
-
*/
|
|
612
|
-
static throwError(message, lvl, opt) {
|
|
613
|
-
const e = new Error(message);
|
|
614
|
-
const stackLines = e.stack.split('\n');
|
|
615
|
-
e.stack = [stackLines[0]].concat(stackLines.slice(2)).join('\n'); // 移除第一行的堆栈信息
|
|
616
|
-
Object.assign(e, opt);
|
|
617
|
-
if (lvl) {
|
|
618
|
-
//SLogger.log(lvl,message);
|
|
619
|
-
UtilLogger_1.SLogger.log(lvl, e.stack);
|
|
620
|
-
}
|
|
621
|
-
throw e;
|
|
622
|
-
}
|
|
623
|
-
/**获取函数调用位置 getFunctionLocation
|
|
624
|
-
* @param stack - 深度 默认1, 即getFuncLoc函数被调用的位置
|
|
625
|
-
*/
|
|
626
|
-
static getFuncLoc(stack = 1) {
|
|
627
|
-
const stackLines = new Error().stack.split('\n');
|
|
628
|
-
const regex = /([a-zA-Z]+?:.+?):(\d+?:\d+)/;
|
|
629
|
-
//console.log(stackLines)
|
|
630
|
-
const match = regex.exec(stackLines[stack + 1]);
|
|
631
|
-
if (match) {
|
|
632
|
-
const filePath = match[1];
|
|
633
|
-
const lineNumber = match[2];
|
|
634
|
-
return { filePath, lineNumber };
|
|
635
|
-
}
|
|
636
|
-
return undefined;
|
|
637
|
-
}
|
|
638
|
-
static publicIp;
|
|
639
|
-
/**获取当前公网ipv4 */
|
|
640
|
-
static async getPublicIpv4() {
|
|
641
|
-
if (UtilFunc.publicIp === undefined)
|
|
642
|
-
UtilFunc.publicIp = await UtilFunc.dynamicImport('public-ip');
|
|
643
|
-
return UtilFunc.publicIp.publicIpv4();
|
|
644
|
-
}
|
|
694
|
+
//#endregion
|
|
695
|
+
//#region 显式处理错误工具
|
|
645
696
|
/**将传入函数包装为显式处理错误的函数
|
|
646
697
|
* @param func - 待转换函数
|
|
647
698
|
* @returns 转换完成的函数
|
|
@@ -676,57 +727,8 @@ class UtilFunc {
|
|
|
676
727
|
}
|
|
677
728
|
};
|
|
678
729
|
}
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
* 请注意,这个函数使用了eval(),可能会带来安全风险。
|
|
682
|
-
*
|
|
683
|
-
* @param moduleName - 需要导入的模块的名称。
|
|
684
|
-
* @returns 返回一个Promise。当模块被成功导入时,这个Promise会解析为导入的模块。如果导入失败,这个Promise会被拒绝。
|
|
685
|
-
*
|
|
686
|
-
* @example
|
|
687
|
-
* async function main() {
|
|
688
|
-
* const pip = (await dynamicImport('public-ip')).default;
|
|
689
|
-
* console.log(await pip.v4());
|
|
690
|
-
* }
|
|
691
|
-
* main();
|
|
692
|
-
*
|
|
693
|
-
* @since Node.js 13.2,Node.js开始支持动态import。
|
|
694
|
-
*/
|
|
695
|
-
static async dynamicImport(moduleName) {
|
|
696
|
-
return await eval(`import('${moduleName}')`);
|
|
697
|
-
}
|
|
698
|
-
/**缓存池 */
|
|
699
|
-
static cachePool = new WeakMap();
|
|
700
|
-
/**立即执行传入的函数
|
|
701
|
-
* @param fn - 需要立即执行的函数。
|
|
702
|
-
* @returns 返回 fn 函数的执行结果。
|
|
703
|
-
*/
|
|
704
|
-
static ivk(fn) {
|
|
705
|
-
return fn();
|
|
706
|
-
}
|
|
707
|
-
/**创建一个带有缓存有效期的memoize函数
|
|
708
|
-
* 只在传入值均为JToken时有效
|
|
709
|
-
* @param fn - 需要被memoize的函数
|
|
710
|
-
* @param expiry - 缓存的有效期 毫秒 默认为Infinity, 表示缓存永不过期。
|
|
711
|
-
* @returns 返回一个新的函数,这个函数在调用时会尝试从缓存中获取结果,如果缓存不存在或已过期,就会调用原函数并缓存其结果。
|
|
712
|
-
*/
|
|
713
|
-
static memoize(fn, expiry = Infinity) {
|
|
714
|
-
const cache = UtilFunc.cachePool.get(fn) ?? UtilFunc.ivk(() => {
|
|
715
|
-
const c = new Map();
|
|
716
|
-
UtilFunc.cachePool.set(fn, c);
|
|
717
|
-
return c;
|
|
718
|
-
});
|
|
719
|
-
return ((...args) => {
|
|
720
|
-
const key = JSON.stringify(args);
|
|
721
|
-
const now = Date.now();
|
|
722
|
-
const cached = cache.get(key);
|
|
723
|
-
if (cached && now - cached.timestamp < expiry)
|
|
724
|
-
return cached.result;
|
|
725
|
-
const result = fn(...args);
|
|
726
|
-
cache.set(key, { result, timestamp: now });
|
|
727
|
-
return result;
|
|
728
|
-
});
|
|
729
|
-
}
|
|
730
|
+
//#endregion
|
|
731
|
+
//#region 解析srt
|
|
730
732
|
/**将hh:mm:ss,ms格式转换为毫秒 */
|
|
731
733
|
static parseSrtTime(time) {
|
|
732
734
|
const [hours, minutes, seconds] = time.split(':');
|
|
@@ -770,6 +772,23 @@ class UtilFunc {
|
|
|
770
772
|
return `${index + 1}\n${UtilFunc.formatSrtTime(segment.start)} --> ${UtilFunc.formatSrtTime(segment.end)}\n${segment.text}\n`;
|
|
771
773
|
}).join('\n');
|
|
772
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
|
+
}
|
|
773
792
|
}
|
|
774
793
|
exports.UtilFunc = UtilFunc;
|
|
775
794
|
__decorate([
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -25,5 +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("./
|
|
28
|
+
__exportStar(require("./QuickExport"), exports);
|
|
29
29
|
__exportStar(require("./UtilI18n"), exports);
|
package/package.json
CHANGED
package/src/UtilClass.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { matchProc } from "./
|
|
1
|
+
import { matchProc } from "./QuickExport";
|
|
2
2
|
import { Keyable, Literal } from "./UtilInterfaces";
|
|
3
3
|
import Handlebars from 'handlebars';
|
|
4
4
|
import { SLogger } from "./UtilLogger";
|
|
@@ -137,23 +137,17 @@ export class Stream<T> implements Iterable<T>{
|
|
|
137
137
|
async append(): Promise<Stream<T>> {
|
|
138
138
|
if (this._operation.length == 0) return this;
|
|
139
139
|
|
|
140
|
-
const pList: Promise<T[]>[] = [];
|
|
141
140
|
//均分处理
|
|
142
|
-
this.divide(this._concurrent)
|
|
143
|
-
|
|
144
|
-
pList.push(
|
|
145
|
-
new Promise(async (reslove) => {
|
|
141
|
+
const pList = this.divide(this._concurrent)
|
|
142
|
+
.map(async (subList)=>{
|
|
146
143
|
const result:T[] = [];
|
|
147
144
|
for (let item of subList) {
|
|
148
|
-
if (!item) continue;
|
|
149
145
|
for (const operation of this._operation)
|
|
150
146
|
item = await operation(item);
|
|
151
147
|
result.push(item);
|
|
152
148
|
}
|
|
153
|
-
|
|
154
|
-
})
|
|
155
|
-
);
|
|
156
|
-
})
|
|
149
|
+
return (result);
|
|
150
|
+
});
|
|
157
151
|
const rlist = await Promise.all(pList);
|
|
158
152
|
|
|
159
153
|
//拼接结果 轮询均分
|
package/src/UtilFP.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isFailed, likeNone } from "./
|
|
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
|
|
package/src/UtilFfmpegTools.ts
CHANGED
package/src/UtilFunctions.ts
CHANGED
|
@@ -73,6 +73,8 @@ type EachFieldCallback = (key: string, value: JToken,parent: JObject) => void;
|
|
|
73
73
|
|
|
74
74
|
/**常用函数 */
|
|
75
75
|
export class UtilFunc{
|
|
76
|
+
|
|
77
|
+
//#region 杂项
|
|
76
78
|
/**获取当前时间戳
|
|
77
79
|
* @returns 时间戳
|
|
78
80
|
*/
|
|
@@ -133,7 +135,6 @@ static calcHash(str:string,method:HashMethod='md5') {
|
|
|
133
135
|
return crypto.createHash(method).update(str).digest('hex');
|
|
134
136
|
}
|
|
135
137
|
|
|
136
|
-
|
|
137
138
|
/**等待 timeMs 毫秒
|
|
138
139
|
* @async
|
|
139
140
|
* @param timeMs - 等待的毫秒数
|
|
@@ -148,8 +149,8 @@ static async sleep<T>(timeMs: number): Promise<void>
|
|
|
148
149
|
*/
|
|
149
150
|
static async sleep<T>(timeMs: number, result:T): Promise<T>
|
|
150
151
|
static async sleep<T>(timeMs: number, result?:T): Promise<T|undefined> {
|
|
151
|
-
return new Promise(
|
|
152
|
-
|
|
152
|
+
return new Promise((resolve, rejecte) => {
|
|
153
|
+
const timer = setTimeout(() => {
|
|
153
154
|
resolve(result);
|
|
154
155
|
}, timeMs);
|
|
155
156
|
});
|
|
@@ -456,6 +457,167 @@ static stringifyJToken(token:JToken|IJData,opt?:StringifyOpt){
|
|
|
456
457
|
p1.replace(/\\([\\"])/g, '$1'));
|
|
457
458
|
}
|
|
458
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 队列处理
|
|
459
621
|
/**代办表 用于队列处理等待 */
|
|
460
622
|
static pendingMap:Record<Keyable,AnyFunc[]> = {};
|
|
461
623
|
|
|
@@ -511,6 +673,7 @@ static queueProc<T>(flag: Keyable, task: () => Promise<T>): Promise<T> {
|
|
|
511
673
|
// 返回Promise,以便调用者可以等待任务完成
|
|
512
674
|
return promise;
|
|
513
675
|
}
|
|
676
|
+
|
|
514
677
|
/**队列获取目标的代办事件数
|
|
515
678
|
* @param flag - 队列标签
|
|
516
679
|
*/
|
|
@@ -518,9 +681,9 @@ static queueLength(flag:Keyable){
|
|
|
518
681
|
const pd = UtilFunc.pendingMap[flag]
|
|
519
682
|
return pd!=null ? pd.length : 0;
|
|
520
683
|
}
|
|
684
|
+
//#endregion
|
|
521
685
|
|
|
522
|
-
|
|
523
|
-
|
|
686
|
+
//#region symbol化处理工具
|
|
524
687
|
/**创建一个Outcome */
|
|
525
688
|
static outcome<K extends Keyable,V> (key:K,value:V):Outcome<K,V>{
|
|
526
689
|
return {
|
|
@@ -529,7 +692,6 @@ static outcome<K extends Keyable,V> (key:K,value:V):Outcome<K,V>{
|
|
|
529
692
|
}
|
|
530
693
|
}
|
|
531
694
|
|
|
532
|
-
|
|
533
695
|
/**处理联合值
|
|
534
696
|
* @param t - 目标值
|
|
535
697
|
* @param procObj - 所有可能的id组成的处理函数映射 (status, result)=>any
|
|
@@ -581,8 +743,6 @@ static matchPartialProc<
|
|
|
581
743
|
return undefined;
|
|
582
744
|
}
|
|
583
745
|
|
|
584
|
-
|
|
585
|
-
|
|
586
746
|
/**根据典型的成功或失败状态运行函数
|
|
587
747
|
* @param t - 目标值
|
|
588
748
|
* @param sucessFunc - 成功则运行的函数 (result)=>any
|
|
@@ -605,6 +765,7 @@ static sucesProc<T extends Matchable<StatusSymbol>,
|
|
|
605
765
|
if(t!==None) SLogger.warn(`sucesProc 传入了一个不匹配的值, 将作为None运行: `,t);
|
|
606
766
|
return noneFunc() as any;
|
|
607
767
|
}
|
|
768
|
+
|
|
608
769
|
/**是失败的 */
|
|
609
770
|
static isFailed<T>
|
|
610
771
|
(tg:T):'E' extends ProperSubsetCheck<symbol,T>? boolean
|
|
@@ -654,113 +815,9 @@ static expect<T>(t:T,errLog?:string):Exclude<T,None>{
|
|
|
654
815
|
if(t===None) UtilFunc.throwError(errLog??"expect验证了一个None值","error");
|
|
655
816
|
return t as Exclude<T,None>;
|
|
656
817
|
}
|
|
818
|
+
//#endregion
|
|
657
819
|
|
|
658
|
-
|
|
659
|
-
* @template T - 验证类型
|
|
660
|
-
* @param t - 验证目标
|
|
661
|
-
*/
|
|
662
|
-
static assertType<T>(t:T):T{return t;}
|
|
663
|
-
/**验证一个变量的类型是否为字面量
|
|
664
|
-
* 仅限浅层
|
|
665
|
-
* @template T - 验证类型
|
|
666
|
-
* @param t - 验证目标
|
|
667
|
-
*/
|
|
668
|
-
static assertLiteral<T>(t:Literal<T>):T{return t as T;}
|
|
669
|
-
|
|
670
|
-
/**深克隆 序列化并反序列化
|
|
671
|
-
* @template T - JToken类型的泛型
|
|
672
|
-
* @param obj - 克隆目标
|
|
673
|
-
* @returns 克隆结果
|
|
674
|
-
*/
|
|
675
|
-
static deepClone<T extends JToken>(obj: T): T {
|
|
676
|
-
return JSON.parse(JSON.stringify(obj));
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
/**是否为安全的数字
|
|
680
|
-
* 非NaN 非null/undefined
|
|
681
|
-
* 且是数字
|
|
682
|
-
* @param num - 所要检测的数字
|
|
683
|
-
* @returns 是否安全
|
|
684
|
-
*/
|
|
685
|
-
static isSafeNumber(num: unknown): boolean {
|
|
686
|
-
if (num == null) return false;
|
|
687
|
-
if(typeof num === 'number') {
|
|
688
|
-
if(isNaN(num)) return false;
|
|
689
|
-
return true;
|
|
690
|
-
}
|
|
691
|
-
return false;
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
/**移除多行字符串中每行开始的最小空格数。
|
|
695
|
-
*
|
|
696
|
-
* @param input - 需要处理的多行 字符串模板 或 字符串。
|
|
697
|
-
* @param values - 插入模板字符串中的值。
|
|
698
|
-
* @returns 返回处理后的字符串,每行开始的空格数已被最小化。
|
|
699
|
-
*
|
|
700
|
-
* @example
|
|
701
|
-
* const name = 'World';
|
|
702
|
-
* const str = dedent`
|
|
703
|
-
* Hello,
|
|
704
|
-
* ${name}!
|
|
705
|
-
* `;
|
|
706
|
-
* console.log(str);
|
|
707
|
-
* // 输出:
|
|
708
|
-
* // Hello,
|
|
709
|
-
* // World!
|
|
710
|
-
*/
|
|
711
|
-
static dedent(input: TemplateStringsArray|string, ...values: any[]): string {
|
|
712
|
-
const str = typeof input === 'string'
|
|
713
|
-
? input
|
|
714
|
-
: input.reduce((result, string, i) => result + string + (values[i] ?? ''), '');
|
|
715
|
-
const lines = str.split('\n');
|
|
716
|
-
const minIndent = Math.min(
|
|
717
|
-
...lines.filter(line => line.trim() !== '').map(line => line.search(/\S/))
|
|
718
|
-
);
|
|
719
|
-
return lines.map(line => line.slice(minIndent)).join('\n');
|
|
720
|
-
}
|
|
721
|
-
/**抛出错误
|
|
722
|
-
* @param message - 错误信息
|
|
723
|
-
* @param lvl - 日志等级
|
|
724
|
-
* @param opt - 额外参数
|
|
725
|
-
*/
|
|
726
|
-
static throwError(message:string,lvl?:LogLevel,opt?:{}):never{
|
|
727
|
-
const e = new Error(message);
|
|
728
|
-
const stackLines = e.stack!.split('\n');
|
|
729
|
-
e.stack = [stackLines[0]].concat(stackLines.slice(2)).join('\n'); // 移除第一行的堆栈信息
|
|
730
|
-
Object.assign(e, opt);
|
|
731
|
-
if(lvl){
|
|
732
|
-
//SLogger.log(lvl,message);
|
|
733
|
-
SLogger.log(lvl,e.stack);
|
|
734
|
-
}
|
|
735
|
-
throw e;
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
/**获取函数调用位置 getFunctionLocation
|
|
739
|
-
* @param stack - 深度 默认1, 即getFuncLoc函数被调用的位置
|
|
740
|
-
*/
|
|
741
|
-
static getFuncLoc(stack=1) {
|
|
742
|
-
const stackLines = new Error().stack!.split('\n');
|
|
743
|
-
const regex = /([a-zA-Z]+?:.+?):(\d+?:\d+)/;
|
|
744
|
-
//console.log(stackLines)
|
|
745
|
-
const match = regex.exec(stackLines[stack+1]);
|
|
746
|
-
if(match){
|
|
747
|
-
const filePath = match[1];
|
|
748
|
-
const lineNumber = match[2] as `${number}:${number}`;
|
|
749
|
-
return {filePath,lineNumber}
|
|
750
|
-
}
|
|
751
|
-
return undefined;
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
private static publicIp?:typeof publicIp;
|
|
756
|
-
|
|
757
|
-
/**获取当前公网ipv4 */
|
|
758
|
-
static async getPublicIpv4(){
|
|
759
|
-
if(UtilFunc.publicIp===undefined)
|
|
760
|
-
UtilFunc.publicIp = await UtilFunc.dynamicImport('public-ip') as typeof publicIp;
|
|
761
|
-
return UtilFunc.publicIp.publicIpv4();
|
|
762
|
-
}
|
|
763
|
-
|
|
820
|
+
//#region 显式处理错误工具
|
|
764
821
|
/**将传入函数包装为显式处理错误的函数
|
|
765
822
|
* @param func - 待转换函数
|
|
766
823
|
* @returns 转换完成的函数
|
|
@@ -793,72 +850,9 @@ static taskEitherize<T extends (...args:any)=>Promise<any>>(func:T) {
|
|
|
793
850
|
}
|
|
794
851
|
};
|
|
795
852
|
}
|
|
853
|
+
//#endregion
|
|
796
854
|
|
|
797
|
-
|
|
798
|
-
* 使用这个函数,你可以在TypeScript中动态地导入模块,而不需要担心import()被转译为require()。
|
|
799
|
-
* 请注意,这个函数使用了eval(),可能会带来安全风险。
|
|
800
|
-
*
|
|
801
|
-
* @param moduleName - 需要导入的模块的名称。
|
|
802
|
-
* @returns 返回一个Promise。当模块被成功导入时,这个Promise会解析为导入的模块。如果导入失败,这个Promise会被拒绝。
|
|
803
|
-
*
|
|
804
|
-
* @example
|
|
805
|
-
* async function main() {
|
|
806
|
-
* const pip = (await dynamicImport('public-ip')).default;
|
|
807
|
-
* console.log(await pip.v4());
|
|
808
|
-
* }
|
|
809
|
-
* main();
|
|
810
|
-
*
|
|
811
|
-
* @since Node.js 13.2,Node.js开始支持动态import。
|
|
812
|
-
*/
|
|
813
|
-
static async dynamicImport(moduleName:string):Promise<any> {
|
|
814
|
-
return await eval(`import('${moduleName}')`);
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
/**缓存池 */
|
|
818
|
-
static cachePool = new WeakMap<Function, Map<string, { result: any, timestamp: number }>>();
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
/**立即执行传入的函数
|
|
823
|
-
* @param fn - 需要立即执行的函数。
|
|
824
|
-
* @returns 返回 fn 函数的执行结果。
|
|
825
|
-
*/
|
|
826
|
-
static ivk<T extends ()=>any>(fn:T): ReturnType<T> {
|
|
827
|
-
return fn();
|
|
828
|
-
}
|
|
829
|
-
|
|
830
|
-
/**创建一个带有缓存有效期的memoize函数
|
|
831
|
-
* 只在传入值均为JToken时有效
|
|
832
|
-
* @param fn - 需要被memoize的函数
|
|
833
|
-
* @param expiry - 缓存的有效期 毫秒 默认为Infinity, 表示缓存永不过期。
|
|
834
|
-
* @returns 返回一个新的函数,这个函数在调用时会尝试从缓存中获取结果,如果缓存不存在或已过期,就会调用原函数并缓存其结果。
|
|
835
|
-
*/
|
|
836
|
-
static memoize<T extends (...args:any[])=>any> (fn: T, expiry = Infinity):
|
|
837
|
-
T extends (...args:infer In)=>any
|
|
838
|
-
? AllExtends<In,JToken> extends true ? T : never
|
|
839
|
-
: never {
|
|
840
|
-
const cache = UtilFunc.cachePool.get(fn) ?? UtilFunc.ivk(()=>{
|
|
841
|
-
const c = new Map();
|
|
842
|
-
UtilFunc.cachePool.set(fn, c);
|
|
843
|
-
return c;
|
|
844
|
-
});
|
|
845
|
-
|
|
846
|
-
return ((...args: Parameters<T>): ReturnType<T> => {
|
|
847
|
-
const key = JSON.stringify(args);
|
|
848
|
-
const now = Date.now();
|
|
849
|
-
const cached = cache.get(key);
|
|
850
|
-
|
|
851
|
-
if (cached && now - cached.timestamp < expiry)
|
|
852
|
-
return cached.result;
|
|
853
|
-
|
|
854
|
-
const result = fn(...args);
|
|
855
|
-
cache.set(key, { result, timestamp: now });
|
|
856
|
-
return result;
|
|
857
|
-
}) as any;
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
855
|
+
//#region 解析srt
|
|
862
856
|
/**将hh:mm:ss,ms格式转换为毫秒 */
|
|
863
857
|
static parseSrtTime(time: string): number {
|
|
864
858
|
const [hours, minutes, seconds] = time.split(':');
|
|
@@ -908,5 +902,24 @@ static createSrt(segments: SrtSegment[]): string {
|
|
|
908
902
|
return `${index + 1}\n${UtilFunc.formatSrtTime(segment.start)} --> ${UtilFunc.formatSrtTime(segment.end)}\n${segment.text}\n`;
|
|
909
903
|
}).join('\n');
|
|
910
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
|
|
911
924
|
|
|
912
925
|
}
|
package/src/index.ts
CHANGED
package/dist/ServiceManager.d.ts
DELETED
|
File without changes
|
package/dist/ServiceManager.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";
|
package/src/ServiceManager.ts
DELETED
|
File without changes
|