@zwa73/utils 1.0.131 → 1.0.134

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.
@@ -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, eitherify: typeof UtilFunc.eitherify, taskEitherify: typeof UtilFunc.taskEitherify;
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;
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.taskEitherify = exports.eitherify = 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.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.eitherify = UtilFunctions_1.UtilFunc.eitherify, exports.taskEitherify = UtilFunctions_1.UtilFunc.taskEitherify;
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;
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 });
@@ -1,3 +1,4 @@
1
+ import { NeedInit } from "./UtilInterfaces";
1
2
  type TDTg<T> = (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T>;
2
3
  type DTg = (target: Object, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
3
4
  /**用于打印方法运行时间
@@ -26,4 +27,6 @@ export declare function DeferAsync<T extends (...args: any) => Promise<any>>(def
26
27
  export declare function Catch<T extends (...args: any) => any>(catchLogic: (error: any, ...args: Parameters<T>) => ReturnType<T>): TDTg<T>;
27
28
  /**异步的try-catch包装 */
28
29
  export declare function CatchAsync<T extends (...args: any) => Promise<any>>(catchLogic: (error: any, ...args: Parameters<T>) => ReturnType<T>): TDTg<T>;
30
+ /**等待完成init */
31
+ export declare function AwaitInited<T extends NeedInit>(target: T, propertyKey: string, descriptor: TypedPropertyDescriptor<(...args: any[]) => Promise<any>>): TypedPropertyDescriptor<(...args: any[]) => Promise<any>>;
29
32
  export {};
@@ -9,7 +9,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.CatchAsync = exports.Catch = exports.DeferAsync = exports.Defer = exports.LogErrAsync = exports.LogErr = exports.LogCallAsync = exports.LogCall = exports.LogTimeAsync = exports.LogTime = void 0;
12
+ exports.AwaitInited = exports.CatchAsync = exports.Catch = exports.DeferAsync = exports.Defer = exports.LogErrAsync = exports.LogErr = exports.LogCallAsync = exports.LogCall = exports.LogTimeAsync = exports.LogTime = void 0;
13
13
  const UtilFunctions_1 = require("./UtilFunctions");
14
14
  const UtilLogger_1 = require("./UtilLogger");
15
15
  /**用于打印方法运行时间
@@ -179,6 +179,16 @@ function CatchAsync(catchLogic) {
179
179
  };
180
180
  }
181
181
  exports.CatchAsync = CatchAsync;
182
+ /**等待完成init */
183
+ function AwaitInited(target, propertyKey, descriptor) {
184
+ const originalMethod = descriptor.value;
185
+ descriptor.value = async function (...args) {
186
+ await this.inited;
187
+ return await originalMethod.apply(this, args);
188
+ };
189
+ return descriptor;
190
+ }
191
+ exports.AwaitInited = AwaitInited;
182
192
  function AddNumberDecorator(n) {
183
193
  return function (target, propertyKey, descriptor) {
184
194
  const originalMethod = descriptor.value;
@@ -237,25 +237,24 @@ export declare class UtilFunc {
237
237
  lineNumber: `${number}:${number}`;
238
238
  } | undefined;
239
239
  private static publicIp?;
240
- /**获取当前公网ipv4
241
- */
240
+ /**获取当前公网ipv4 */
242
241
  static getPublicIpv4(): Promise<string>;
243
- /**将传入函数包装为显示处理错误的函数
242
+ /**将传入函数包装为显式处理错误的函数
244
243
  * @param func - 待转换函数
245
244
  * @returns 转换完成的函数
246
245
  */
247
- static eitherify<T extends AnyFunc>(func: T): (...args: Parameters<T>) => Outcome<typeof Success, ReturnType<T>> | Outcome<typeof Failed, Error>;
248
- /**将传入的异步函数包装为显示处理错误的函数
246
+ static eitherize<T extends AnyFunc>(func: T): (...args: Parameters<T>) => Outcome<typeof Success, ReturnType<T>> | Outcome<typeof Failed, Error>;
247
+ /**将传入的异步函数包装为显式处理错误的函数
249
248
  * @param func - 待转换函数
250
249
  * @returns 转换完成的函数
251
250
  */
252
- static taskEitherify<T extends (...args: any) => Promise<any>>(func: T): (...args: Parameters<T>) => Promise<Outcome<typeof Failed, Error> | Outcome<typeof Success, Await<ReturnType<T>>>>;
251
+ static taskEitherize<T extends (...args: any) => Promise<any>>(func: T): (...args: Parameters<T>) => Promise<Outcome<typeof Failed, Error> | Outcome<typeof Success, Await<ReturnType<T>>>>;
253
252
  /**动态导入模块的函数。这个函数是为了在TypeScript的模块系统配置为CommonJS时,防止动态import被转译为require而设计的。
254
253
  * 使用这个函数,你可以在TypeScript中动态地导入模块,而不需要担心import()被转译为require()。
255
254
  * 请注意,这个函数使用了eval(),可能会带来安全风险。
256
255
  *
257
- * @param {string} moduleName - 需要导入的模块的名称。
258
- * @returns {Promise<any>} 返回一个Promise。当模块被成功导入时,这个Promise会解析为导入的模块。如果导入失败,这个Promise会被拒绝。
256
+ * @param moduleName - 需要导入的模块的名称。
257
+ * @returns 返回一个Promise。当模块被成功导入时,这个Promise会解析为导入的模块。如果导入失败,这个Promise会被拒绝。
259
258
  *
260
259
  * @example
261
260
  * async function main() {
@@ -267,5 +266,22 @@ export declare class UtilFunc {
267
266
  * @since Node.js 13.2,Node.js开始支持动态import。
268
267
  */
269
268
  static dynamicImport(moduleName: string): Promise<any>;
269
+ /**缓存池 */
270
+ static cachePool: WeakMap<Function, Map<string, {
271
+ result: any;
272
+ timestamp: number;
273
+ }>>;
274
+ /**立即执行传入的函数
275
+ * @param fn - 需要立即执行的函数。
276
+ * @returns 返回 fn 函数的执行结果。
277
+ */
278
+ static ivk<T extends () => any>(fn: T): ReturnType<T>;
279
+ /**创建一个带有缓存有效期的memoize函数
280
+ * 只在传入值均为JToken时有效
281
+ * @param fn - 需要被memoize的函数
282
+ * @param expiry - 缓存的有效期 毫秒 默认为Infinity, 表示缓存永不过期。
283
+ * @returns 返回一个新的函数,这个函数在调用时会尝试从缓存中获取结果,如果缓存不存在或已过期,就会调用原函数并缓存其结果。
284
+ */
285
+ static memoize<T extends (...args: JToken[]) => any>(fn: T, expiry?: number): T;
270
286
  }
271
287
  export {};
@@ -623,18 +623,17 @@ class UtilFunc {
623
623
  return undefined;
624
624
  }
625
625
  static publicIp;
626
- /**获取当前公网ipv4
627
- */
626
+ /**获取当前公网ipv4 */
628
627
  static async getPublicIpv4() {
629
628
  if (UtilFunc.publicIp === undefined)
630
629
  UtilFunc.publicIp = await UtilFunc.dynamicImport('public-ip');
631
630
  return UtilFunc.publicIp.publicIpv4();
632
631
  }
633
- /**将传入函数包装为显示处理错误的函数
632
+ /**将传入函数包装为显式处理错误的函数
634
633
  * @param func - 待转换函数
635
634
  * @returns 转换完成的函数
636
635
  */
637
- static eitherify(func) {
636
+ static eitherize(func) {
638
637
  return (...args) => {
639
638
  try {
640
639
  const result = func(...args);
@@ -647,11 +646,11 @@ class UtilFunc {
647
646
  }
648
647
  };
649
648
  }
650
- /**将传入的异步函数包装为显示处理错误的函数
649
+ /**将传入的异步函数包装为显式处理错误的函数
651
650
  * @param func - 待转换函数
652
651
  * @returns 转换完成的函数
653
652
  */
654
- static taskEitherify(func) {
653
+ static taskEitherize(func) {
655
654
  return async (...args) => {
656
655
  try {
657
656
  const result = await func(...args);
@@ -668,8 +667,8 @@ class UtilFunc {
668
667
  * 使用这个函数,你可以在TypeScript中动态地导入模块,而不需要担心import()被转译为require()。
669
668
  * 请注意,这个函数使用了eval(),可能会带来安全风险。
670
669
  *
671
- * @param {string} moduleName - 需要导入的模块的名称。
672
- * @returns {Promise<any>} 返回一个Promise。当模块被成功导入时,这个Promise会解析为导入的模块。如果导入失败,这个Promise会被拒绝。
670
+ * @param moduleName - 需要导入的模块的名称。
671
+ * @returns 返回一个Promise。当模块被成功导入时,这个Promise会解析为导入的模块。如果导入失败,这个Promise会被拒绝。
673
672
  *
674
673
  * @example
675
674
  * async function main() {
@@ -683,6 +682,38 @@ class UtilFunc {
683
682
  static async dynamicImport(moduleName) {
684
683
  return await eval(`import('${moduleName}')`);
685
684
  }
685
+ /**缓存池 */
686
+ static cachePool = new WeakMap();
687
+ /**立即执行传入的函数
688
+ * @param fn - 需要立即执行的函数。
689
+ * @returns 返回 fn 函数的执行结果。
690
+ */
691
+ static ivk(fn) {
692
+ return fn();
693
+ }
694
+ /**创建一个带有缓存有效期的memoize函数
695
+ * 只在传入值均为JToken时有效
696
+ * @param fn - 需要被memoize的函数
697
+ * @param expiry - 缓存的有效期 毫秒 默认为Infinity, 表示缓存永不过期。
698
+ * @returns 返回一个新的函数,这个函数在调用时会尝试从缓存中获取结果,如果缓存不存在或已过期,就会调用原函数并缓存其结果。
699
+ */
700
+ static memoize(fn, expiry = Infinity) {
701
+ const cache = UtilFunc.cachePool.get(fn) ?? UtilFunc.ivk(() => {
702
+ const c = new Map();
703
+ UtilFunc.cachePool.set(fn, c);
704
+ return c;
705
+ });
706
+ return ((...args) => {
707
+ const key = JSON.stringify(args);
708
+ const now = Date.now();
709
+ const cached = cache.get(key);
710
+ if (cached && now - cached.timestamp < expiry)
711
+ return cached.result;
712
+ const result = fn(...args);
713
+ cache.set(key, { result, timestamp: now });
714
+ return result;
715
+ });
716
+ }
686
717
  }
687
718
  exports.UtilFunc = UtilFunc;
688
719
  __decorate([
@@ -187,4 +187,11 @@ export type ExtractOutcome<T, K extends Keyable> = T extends Outcome<infer O, un
187
187
  * 输出schema后替换为 ^.*$ 的 string 匹配
188
188
  */
189
189
  export type SchemaString = `${string}SchemaString`;
190
+ /**需要初始化 */
191
+ export type NeedInit = {
192
+ /**完成初始化的标记 */
193
+ inited: Promise<void>;
194
+ };
195
+ /**可选的record */
196
+ export type PRecord<K extends Keyable, V> = Partial<Record<K, V>>;
190
197
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zwa73/utils",
3
- "version": "1.0.131",
3
+ "version": "1.0.134",
4
4
  "description": "my utils",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -32,7 +32,7 @@ function showUpgradeMessages(prevVersion, currentVersion) {
32
32
  // 遍历infoTable中的所有版本
33
33
  for (const version in INFO_TABLE) {
34
34
  const versionNumber = versionToNumber(version);
35
- console.log(versionNumber,prevVersionNumber,currentVersionNumber)
35
+ //console.log(versionNumber,prevVersionNumber,currentVersionNumber)
36
36
  // 如果用户的上一个版本低于这个版本,而当前版本高于或等于这个版本
37
37
  if (versionNumber > prevVersionNumber && versionNumber <= currentVersionNumber) {
38
38
  // 显示这个版本的提示信息
@@ -21,8 +21,10 @@ export const {
21
21
  mapEntries,
22
22
  dedent,
23
23
  throwError,
24
- eitherify,
25
- taskEitherify,
24
+ eitherize,
25
+ taskEitherize,
26
+ memoize,
27
+ ivk,
26
28
  } = UtilFunc;
27
29
 
28
30
  export const {
@@ -1,5 +1,5 @@
1
1
  import { UtilFunc } from "./UtilFunctions";
2
- import { Await } from "./UtilInterfaces";
2
+ import { Await, NeedInit } from "./UtilInterfaces";
3
3
  import { SLogger } from "./UtilLogger";
4
4
 
5
5
  type TDTg<T> =
@@ -169,7 +169,18 @@ export function CatchAsync<T extends (...args:any)=>Promise<any>>
169
169
  };
170
170
  }
171
171
 
172
+ /**等待完成init */
173
+ export function AwaitInited<T extends NeedInit>
174
+ (target:T, propertyKey: string, descriptor: TypedPropertyDescriptor<(...args: any[]) => Promise<any>>) {
175
+ const originalMethod = descriptor.value!;
172
176
 
177
+ descriptor.value = async function(this:T,...args: any[]) {
178
+ await this.inited;
179
+ return await originalMethod.apply(this, args);
180
+ };
181
+
182
+ return descriptor;
183
+ }
173
184
 
174
185
 
175
186
  function AddNumberDecorator(n: number) {
@@ -190,6 +201,8 @@ function AddNumberDecorator(n: number) {
190
201
  }
191
202
 
192
203
 
204
+
205
+
193
206
  class Example {
194
207
  @AddNumberDecorator(10)
195
208
  myMethod(num: number): number {
@@ -1,9 +1,9 @@
1
1
  import * as crypto from "crypto";
2
- import { AnyFunc, ComposedClass, ComposedMixinable, ComposedRefMixinable, ExtractOutcome, IJData, JObject, JToken, Keyable, Literal, Matchable, MatchableFlag, Mixinable, Outcome, ReqStat, ReqVerifyFn, ProperSubset, ProperSubsetCheck, RefMixinable, UnionToIntersection, Await } from "@src/UtilInterfaces";
2
+ import { AnyFunc, ComposedClass, ComposedMixinable, ComposedRefMixinable, ExtractOutcome, IJData, JObject, JToken, Keyable, Literal, Matchable, MatchableFlag, Mixinable, Outcome, ReqStat, ReqVerifyFn, ProperSubsetCheck, RefMixinable, UnionToIntersection, Await } 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";
6
- import { Catch, DeferAsync, LogTimeAsync } from "./UtilDecorators";
6
+ import { LogTimeAsync } from "./UtilDecorators";
7
7
  import opath from 'path';
8
8
  import { UtilFT } from "./UtilFileTools";
9
9
  import {inspect} from 'util';
@@ -715,19 +715,18 @@ static getFuncLoc(stack=1) {
715
715
 
716
716
  private static publicIp?:typeof publicIp;
717
717
 
718
- /**获取当前公网ipv4
719
- */
718
+ /**获取当前公网ipv4 */
720
719
  static async getPublicIpv4(){
721
720
  if(UtilFunc.publicIp===undefined)
722
721
  UtilFunc.publicIp = await UtilFunc.dynamicImport('public-ip') as typeof publicIp;
723
722
  return UtilFunc.publicIp.publicIpv4();
724
723
  }
725
724
 
726
- /**将传入函数包装为显示处理错误的函数
725
+ /**将传入函数包装为显式处理错误的函数
727
726
  * @param func - 待转换函数
728
727
  * @returns 转换完成的函数
729
728
  */
730
- static eitherify<T extends AnyFunc>(func:T) {
729
+ static eitherize<T extends AnyFunc>(func:T) {
731
730
  return (...args: Parameters<T>) => {
732
731
  try {
733
732
  const result:ReturnType<T> = func(...args as any);
@@ -739,11 +738,11 @@ static eitherify<T extends AnyFunc>(func:T) {
739
738
  }
740
739
  };
741
740
  }
742
- /**将传入的异步函数包装为显示处理错误的函数
741
+ /**将传入的异步函数包装为显式处理错误的函数
743
742
  * @param func - 待转换函数
744
743
  * @returns 转换完成的函数
745
744
  */
746
- static taskEitherify<T extends (...args:any)=>Promise<any>>(func:T) {
745
+ static taskEitherize<T extends (...args:any)=>Promise<any>>(func:T) {
747
746
  return async (...args: Parameters<T>) => {
748
747
  try {
749
748
  const result:Await<ReturnType<T>> = await func(...args as any);
@@ -760,8 +759,8 @@ static taskEitherify<T extends (...args:any)=>Promise<any>>(func:T) {
760
759
  * 使用这个函数,你可以在TypeScript中动态地导入模块,而不需要担心import()被转译为require()。
761
760
  * 请注意,这个函数使用了eval(),可能会带来安全风险。
762
761
  *
763
- * @param {string} moduleName - 需要导入的模块的名称。
764
- * @returns {Promise<any>} 返回一个Promise。当模块被成功导入时,这个Promise会解析为导入的模块。如果导入失败,这个Promise会被拒绝。
762
+ * @param moduleName - 需要导入的模块的名称。
763
+ * @returns 返回一个Promise。当模块被成功导入时,这个Promise会解析为导入的模块。如果导入失败,这个Promise会被拒绝。
765
764
  *
766
765
  * @example
767
766
  * async function main() {
@@ -776,4 +775,45 @@ static async dynamicImport(moduleName:string):Promise<any> {
776
775
  return await eval(`import('${moduleName}')`);
777
776
  }
778
777
 
778
+ /**缓存池 */
779
+ static cachePool = new WeakMap<Function, Map<string, { result: any, timestamp: number }>>();
780
+
781
+
782
+
783
+ /**立即执行传入的函数
784
+ * @param fn - 需要立即执行的函数。
785
+ * @returns 返回 fn 函数的执行结果。
786
+ */
787
+ static ivk<T extends ()=>any>(fn:T): ReturnType<T> {
788
+ return fn();
789
+ }
790
+
791
+ /**创建一个带有缓存有效期的memoize函数
792
+ * 只在传入值均为JToken时有效
793
+ * @param fn - 需要被memoize的函数
794
+ * @param expiry - 缓存的有效期 毫秒 默认为Infinity, 表示缓存永不过期。
795
+ * @returns 返回一个新的函数,这个函数在调用时会尝试从缓存中获取结果,如果缓存不存在或已过期,就会调用原函数并缓存其结果。
796
+ */
797
+ static memoize<T extends (...args:JToken[])=>any> (fn: T, expiry = Infinity): T {
798
+ const cache = UtilFunc.cachePool.get(fn) ?? UtilFunc.ivk(()=>{
799
+ const c = new Map();
800
+ UtilFunc.cachePool.set(fn, c);
801
+ return c;
802
+ });
803
+
804
+ return ((...args: Parameters<T>): ReturnType<T> => {
805
+ const key = JSON.stringify(args);
806
+ const now = Date.now();
807
+ const cached = cache.get(key);
808
+
809
+ if (cached && now - cached.timestamp < expiry)
810
+ return cached.result;
811
+
812
+ const result = fn(...args);
813
+ cache.set(key, { result, timestamp: now });
814
+ return result;
815
+ }) as T;
816
+ }
817
+
818
+
779
819
  }
@@ -277,4 +277,11 @@ export type ExtractOutcome<T,K extends Keyable> =
277
277
  */
278
278
  export type SchemaString = `${string}SchemaString`;
279
279
 
280
+ /**需要初始化 */
281
+ export type NeedInit = {
282
+ /**完成初始化的标记 */
283
+ inited: Promise<void>;
284
+ };
280
285
 
286
+ /**可选的record */
287
+ export type PRecord<K extends Keyable,V> = Partial<Record<K,V>>;