@zwa73/utils 1.0.76 → 1.0.77

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/UtilCom.js CHANGED
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.UtilCom = void 0;
4
- const UtilInterfaces_1 = require("./UtilInterfaces");
5
4
  const https = require("https");
6
5
  const http = require("http");
7
6
  const UtilLogger_1 = require("./UtilLogger");
@@ -21,7 +20,7 @@ var UtilCom;
21
20
  const hasTimeLimit = (timeLimit >= 10);
22
21
  if (hasTimeLimit)
23
22
  timeLimit *= 1000;
24
- const jsonStr = (0, UtilInterfaces_1.stringifyJToken)(json);
23
+ const jsonStr = UtilFunctions_1.UtilFunc.stringifyJToken(json);
25
24
  const funcName = `s${posttype}Psot`;
26
25
  return new Promise((resolve, rejecte) => {
27
26
  const resFunc = (res) => {
@@ -51,7 +50,7 @@ var UtilCom;
51
50
  }
52
51
  try {
53
52
  let obj = JSON.parse(resdata);
54
- UtilLogger_1.SLogger.http(funcName + " 接受信息:", (0, UtilInterfaces_1.stringifyJToken)(obj));
53
+ UtilLogger_1.SLogger.http(funcName + " 接受信息:", UtilFunctions_1.UtilFunc.stringifyJToken(obj));
55
54
  resolve(obj);
56
55
  return;
57
56
  }
package/dist/UtilFP.js CHANGED
@@ -16,12 +16,14 @@ var UtilFP;
16
16
  });
17
17
  }
18
18
  UtilFP.curry = curry;
19
+ //#endregion
19
20
  function flow(...fs) {
20
21
  return (arg) => {
21
22
  return fs.reduce((value, func) => func(value), arg);
22
23
  };
23
24
  }
24
25
  UtilFP.flow = flow;
26
+ //#endregion
25
27
  function pipe(input, ...fs) {
26
28
  return fs.reduce((value, func) => func(value), input);
27
29
  }
@@ -3,10 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.UtilFT = void 0;
4
4
  const fs = require("fs");
5
5
  const path = require("path");
6
- const UtilInterfaces_1 = require("./UtilInterfaces");
7
6
  const UtilLogger_1 = require("./UtilLogger");
8
7
  const JSON5 = require("json5");
9
8
  const glob_1 = require("glob");
9
+ const UtilFunctions_1 = require("./UtilFunctions");
10
10
  /**文件工具 */
11
11
  var UtilFT;
12
12
  (function (UtilFT) {
@@ -149,7 +149,7 @@ var UtilFT;
149
149
  * @param token - 所要写入的JToken
150
150
  */
151
151
  async function writeJSONFile(filePath, token) {
152
- let str = (0, UtilInterfaces_1.stringifyJToken)(token);
152
+ let str = UtilFunctions_1.UtilFunc.stringifyJToken(token);
153
153
  if (path.extname(filePath) !== '.json')
154
154
  filePath += '.json';
155
155
  // 判断文件路径是否存在 不存在则创建
@@ -1,4 +1,4 @@
1
- import { ComposedClass, ComposedMixinable, JObject, JToken, Mixinable, PromiseProcFn, PromiseVerifyFn } from "./UtilInterfaces";
1
+ import { ComposedClass, ComposedMixinable, ExtractOutcome, IJData, JObject, JToken, Mixinable, Outcome, PromiseVerifyFn } from "./UtilInterfaces";
2
2
  /**常用函数 */
3
3
  export declare namespace UtilFunc {
4
4
  /**获取当前时间戳
@@ -62,9 +62,9 @@ export declare namespace UtilFunc {
62
62
  * @param verifyFn - 验证函数
63
63
  * @param repeatCount - 重试次数
64
64
  * @param repeatTime - 超时时间/秒 最小为10秒
65
- * @returns - 结果 null 为全部失败/超时
65
+ * @returns 结果 null 为全部失败/超时
66
66
  */
67
- function repeatPromise<T>(procFn: PromiseProcFn<T>, verifyFn?: PromiseVerifyFn<T>, repeatCount?: number, repeatTime?: number): Promise<T | null>;
67
+ function repeatPromise<T>(procFn: () => Promise<T>, verifyFn?: PromiseVerifyFn<T>, repeatCount?: number, repeatTime?: number): Promise<T | null>;
68
68
  /**部分类组合
69
69
  * 将mixin的部分字段混入base
70
70
  * @param base - 基础类
@@ -83,4 +83,30 @@ export declare namespace UtilFunc {
83
83
  * @returns - 一个新的对象,它的属性是原对象的属性经过映射函数处理后的结果
84
84
  */
85
85
  function mapEntries<T extends Object>(obj: T, mapper: (key: keyof T, value: T[keyof T]) => T[keyof T]): T;
86
+ /**处理联合 Outcome
87
+ * @param t - 目标值
88
+ * @param procObj - 所有可能的id组成的处理函数映射
89
+ * @returns 任意处理函数的返回值
90
+ */
91
+ function matchOutcome<T extends Outcome<string, unknown>, P extends {
92
+ [K in T['status']]: (k: K, v: ExtractOutcome<T, K>['result']) => unknown;
93
+ }>(t: T, procObj: P): {
94
+ [K in keyof P]: ReturnType<P[K]>;
95
+ }[keyof P];
96
+ /**处理联合 字符串
97
+ * @param t - 目标值
98
+ * @param procObj - 所有可能的id组成的处理函数映射
99
+ * @returns 任意处理函数的返回值
100
+ */
101
+ function matchStr<T extends string, P extends {
102
+ [K in T]: (k: K) => unknown;
103
+ }>(t: T, procObj: P): {
104
+ [K in keyof P]: ReturnType<P[K]>;
105
+ }[keyof P];
106
+ /**将JToken转换为字符串
107
+ * @param token - 待转换的Token
108
+ * @param space - 插入的空格 数字为空格数量 默认为制表符\t
109
+ * @returns 转换完成的字符串
110
+ */
111
+ function stringifyJToken(token: JToken | IJData, space?: string | number | null | undefined): string;
86
112
  }
@@ -125,71 +125,76 @@ var UtilFunc;
125
125
  * @param verifyFn - 验证函数
126
126
  * @param repeatCount - 重试次数
127
127
  * @param repeatTime - 超时时间/秒 最小为10秒
128
- * @returns - 结果 null 为全部失败/超时
128
+ * @returns 结果 null 为全部失败/超时
129
129
  */
130
130
  async function repeatPromise(procFn, verifyFn, repeatCount = 3, repeatTime = 180) {
131
131
  //计时
132
132
  const timeflag = "repeatPromise " + UtilFunc.genUUID();
133
133
  UtilLogger_1.SLogger.time(timeflag);
134
- //转换为毫秒
134
+ /**是否含有超时时间 */
135
135
  const hasRepeatTime = (repeatTime >= 10);
136
+ //转换为毫秒
136
137
  if (hasRepeatTime)
137
138
  repeatTime *= 1000;
138
139
  //验证处理函数
139
140
  if (verifyFn === undefined)
140
141
  verifyFn = () => "Completed";
141
- //计时器
142
+ /**计时器 */
142
143
  let timer = null;
144
+ /**计时器 Promise */
143
145
  let timerP = null;
146
+ /**计时器 Promise 的返回函数 */
144
147
  let resolveFn = null;
145
148
  /**清理计时器 */
146
149
  const clearTimer = () => {
147
- if (timer != null)
150
+ if (timer)
148
151
  clearInterval(timer);
149
- if (resolveFn != null)
152
+ if (resolveFn)
150
153
  resolveFn("Timeout");
151
- timerP = null;
152
- timer = null;
153
- resolveFn = null;
154
+ timerP = timer = resolveFn = null;
154
155
  };
155
156
  //进行中的请求
156
157
  const plist = [];
157
158
  //开始处理
158
159
  try {
160
+ //根据最大重试次数限制进行循环
159
161
  for (let i = 0; i < repeatCount;) {
160
162
  UtilLogger_1.SLogger.info(`开始第 ${i + 1} 次 repeatPromise`);
161
- //创建当前任务
163
+ //如果 plist 中当前下标的任务还未创建 则 创建当前任务
162
164
  if (plist.length < i + 1) {
163
165
  plist.push(procFn().then(result => ({ result, stat: verifyFn(result), index: i })));
164
166
  }
165
167
  //创建定时器
166
168
  if (timerP == null) {
167
- timerP = new Promise(function (resolve, rejecte) {
169
+ timerP = new Promise((resolve, rejecte) => {
168
170
  resolveFn = resolve;
169
171
  timer = setTimeout(() => resolve("Timeout"), hasRepeatTime ? repeatTime : Infinity); //无限制则无限时间
170
172
  });
171
173
  }
172
- //等待完成
174
+ //等待任意任务 或当前计时器完成
173
175
  const currObj = await Promise.race([...plist, timerP]);
174
176
  //超时处理
175
- if (currObj == "Timeout") {
177
+ if (currObj === "Timeout") {
176
178
  UtilLogger_1.SLogger.warn(`第 ${i + 1} 次 repeatPromise 超时 ${repeatTime} ms 开始重试`);
177
179
  clearTimer();
178
180
  i++;
179
181
  continue;
180
182
  }
183
+ //路由请求状态
181
184
  const poststat = await currObj.stat;
182
- switch (poststat) {
183
- case "Completed": //完成
185
+ const result = matchStr(poststat, {
186
+ Completed() {
184
187
  UtilLogger_1.SLogger.info(`第 ${currObj.index + 1} 次 repeatPromise 成功`);
185
188
  //非当前
186
189
  if (currObj.index != i)
187
190
  UtilLogger_1.SLogger.info(`成功的 promise 非当前 promise 考虑增大重试间隔\n当前index: ${i}\n当前间隔: ${repeatTime}`);
188
191
  return currObj.result;
189
- case "Terminated": //终止
192
+ },
193
+ Terminated() {
190
194
  UtilLogger_1.SLogger.warn(`第 ${currObj.index + 1} 次 repeatPromise 终止 停止重试`);
191
195
  return currObj.result;
192
- case "Failed": //验证失败
196
+ },
197
+ Failed() {
193
198
  //抛弃失败
194
199
  plist[currObj.index] = UtilFunc.getNeverResolvedPromise();
195
200
  //是当前
@@ -197,12 +202,14 @@ var UtilFunc;
197
202
  UtilLogger_1.SLogger.warn(`第 ${currObj.index + 1} 次 repeatPromise 失败 开始重试`);
198
203
  clearTimer();
199
204
  i++;
200
- continue;
205
+ return;
201
206
  }
202
207
  //非当前
203
208
  UtilLogger_1.SLogger.warn(`第 ${currObj.index + 1} 次 repeatPromise 失败`);
204
- continue;
205
- }
209
+ },
210
+ });
211
+ if (result !== undefined)
212
+ return result;
206
213
  }
207
214
  //全部失败或超时则返回null
208
215
  UtilLogger_1.SLogger.warn(`${repeatCount} 次 repeatPromise 尝试均失败`);
@@ -291,4 +298,33 @@ var UtilFunc;
291
298
  }, {});
292
299
  }
293
300
  UtilFunc.mapEntries = mapEntries;
301
+ /**处理联合 Outcome
302
+ * @param t - 目标值
303
+ * @param procObj - 所有可能的id组成的处理函数映射
304
+ * @returns 任意处理函数的返回值
305
+ */
306
+ function matchOutcome(t, procObj) {
307
+ return procObj[t.status](t.status, t?.result);
308
+ }
309
+ UtilFunc.matchOutcome = matchOutcome;
310
+ /**处理联合 字符串
311
+ * @param t - 目标值
312
+ * @param procObj - 所有可能的id组成的处理函数映射
313
+ * @returns 任意处理函数的返回值
314
+ */
315
+ function matchStr(t, procObj) {
316
+ return procObj[t](t);
317
+ }
318
+ UtilFunc.matchStr = matchStr;
319
+ /**将JToken转换为字符串
320
+ * @param token - 待转换的Token
321
+ * @param space - 插入的空格 数字为空格数量 默认为制表符\t
322
+ * @returns 转换完成的字符串
323
+ */
324
+ function stringifyJToken(token, space = "\t") {
325
+ if (space == null)
326
+ space = undefined;
327
+ return JSON.stringify(token, null, space);
328
+ }
329
+ UtilFunc.stringifyJToken = stringifyJToken;
294
330
  })(UtilFunc = exports.UtilFunc || (exports.UtilFunc = {}));
@@ -14,12 +14,6 @@ export interface IJData {
14
14
  */
15
15
  toJSON(): JToken;
16
16
  }
17
- /**将JToken转换为字符串
18
- * @param token - 待转换的Token
19
- * @param space - 插入的空格 数字为空格数量 默认为制表符\t
20
- * @returns 转换完成的字符串
21
- */
22
- export declare function stringifyJToken(token: JToken | IJData, space?: string | number | null | undefined): string;
23
17
  /**转为可写的 */
24
18
  export type Writeable<T> = {
25
19
  -readonly [P in keyof T]: T[P];
@@ -55,24 +49,23 @@ export type ExclusiveRecord<B, T, K extends string[], TMP = ExclusiveRecursive<B
55
49
  /**符合JObject约束的互斥表 */
56
50
  export type ExclusiveJObject<B extends JObject, T extends JToken, K extends string[], TMP extends JArray = ExclusiveRecursive<B, T, K>> = TMP[number];
57
51
  /**请求完成状态 成功/失败/终止
58
- * 成功/终止 将直接返回
52
+ * 成功 将直接返回 结果
53
+ * 终止 将直接返回 null
59
54
  * 失败 将重试
60
55
  */
61
56
  export type PromiseStat = "Completed" | "Failed" | "Terminated";
62
57
  /**promise验证函数 */
63
58
  export type PromiseVerifyFn<T> = (obj: T) => Promise<PromiseStat> | PromiseStat;
64
- /**发起promise的函数 */
65
- export type PromiseProcFn<T> = () => Promise<T>;
66
59
  /**类型中任意函数的字符串名称 */
67
60
  export type FuncPropNames<T> = {
68
- [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never;
61
+ [K in keyof T]: T[K] extends (...args: unknown[]) => unknown ? K : never;
69
62
  }[keyof T];
70
63
  /**部分组合的类
71
64
  * @template Base - 基类
72
65
  * @template Mixin - 待混入的类
73
66
  * @template PropKeys - 需要混入的成员key
74
67
  */
75
- export type ComposedClass<Base extends object, Mixin extends object, Key extends string, PropKeys extends keyof Mixin> = Base & Pick<Mixin, PropKeys> & {
68
+ export type ComposedClass<Base, Mixin, Key extends string, PropKeys extends keyof Mixin> = Base & Pick<Mixin, PropKeys> & {
76
69
  [P in Key]: Mixin;
77
70
  };
78
71
  /**可自动混入的类型 */
@@ -87,5 +80,39 @@ export type Mixinable<Mixin> = {
87
80
  readonly MIXIN_FIELDS: readonly (keyof Mixin)[];
88
81
  };
89
82
  /**自动组合可混入的类 */
90
- export type ComposedMixinable<B extends object, Ms extends unknown[]> = Ms extends [infer M, ...infer Rest] ? M extends Mixinable<M> ? ComposedMixinable<ComposedClass<B, M, M['MIXIN_KEY'], M['MIXIN_FIELDS'][number]>, Rest> : "一个混入类没有实现 Mixinable<self>" & Error : B;
83
+ export type ComposedMixinable<B, Ms extends unknown[]> = Ms extends [infer M, ...infer Rest] ? M extends Mixinable<M> ? ComposedMixinable<ComposedClass<B, M, M['MIXIN_KEY'], M['MIXIN_FIELDS'][number]>, Rest> : "一个混入类没有实现 Mixinable<self>" & Error : B;
84
+ /** extends封装
85
+ * @template B - 基础类型
86
+ * @template T - 判断的目标类型
87
+ * @template Y - 如果为真的返回值
88
+ * @template N - 如果为假的返回值
89
+ */
90
+ export type ExtendThen<B, T, Y, N = never> = B extends T ? Y : N;
91
+ /** 一个联合类型 B 中如果包含 T
92
+ * @template B - 基础类型
93
+ * @template T - 判断的目标类型
94
+ * @template Y - 如果为真的返回值
95
+ * @template N - 如果为假的返回值
96
+ */
97
+ export type UnionInclude<B, T, Y, N = never> = B extends Exclude<B, T> ? Y : N;
98
+ /**排除可选字段 */
99
+ export type RequiredOnly<T> = {
100
+ [K in keyof T as UnionInclude<T[K], undefined, never, K>]: T[K];
101
+ };
102
+ /**添加前缀 */
103
+ export type WithPrefix<T, P extends string> = {
104
+ [K in (keyof T) as K extends string ? `${P}_${K}` : K]: T[K];
105
+ };
106
+ /**返回结果
107
+ * @template K - 类型键值
108
+ * @template V - 值
109
+ */
110
+ export type Outcome<K extends string, V> = {
111
+ /**状态类型 */
112
+ status: K;
113
+ /**值 */
114
+ result: V;
115
+ };
116
+ /**从联合 Outcome 中 根据 id 提取对应 value 的 type */
117
+ export type ExtractOutcome<T, K extends string> = T extends Outcome<K, unknown> ? T : never;
91
118
  export {};
@@ -1,14 +1,2 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.stringifyJToken = void 0;
4
- /**将JToken转换为字符串
5
- * @param token - 待转换的Token
6
- * @param space - 插入的空格 数字为空格数量 默认为制表符\t
7
- * @returns 转换完成的字符串
8
- */
9
- function stringifyJToken(token, space = "\t") {
10
- if (space == null)
11
- space = undefined;
12
- return JSON.stringify(token, null, space);
13
- }
14
- exports.stringifyJToken = stringifyJToken;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zwa73/utils",
3
- "version": "1.0.76",
3
+ "version": "1.0.77",
4
4
  "description": "my utils",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/src/UtilCom.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { JObject, PromiseVerifyFn, stringifyJToken } from "@src/UtilInterfaces";
1
+ import { JObject, PromiseVerifyFn } from "@src/UtilInterfaces";
2
2
  import * as https from 'https';
3
3
  import * as http from 'http';
4
4
  import { SLogger } from "@src/UtilLogger";
@@ -21,7 +21,7 @@ function sPost(posttype:"http"|"https",json:JObject,options:Object,timeLimit:num
21
21
  if(hasTimeLimit)
22
22
  timeLimit*=1000
23
23
 
24
- const jsonStr = stringifyJToken(json);
24
+ const jsonStr = UtilFunc.stringifyJToken(json);
25
25
  const funcName = `s${posttype}Psot`;
26
26
 
27
27
  return new Promise((resolve, rejecte)=>{
@@ -55,7 +55,7 @@ function sPost(posttype:"http"|"https",json:JObject,options:Object,timeLimit:num
55
55
  }
56
56
  try{
57
57
  let obj = JSON.parse(resdata);
58
- SLogger.http(funcName+" 接受信息:",stringifyJToken(obj));
58
+ SLogger.http(funcName+" 接受信息:",UtilFunc.stringifyJToken(obj));
59
59
  resolve(obj);
60
60
  return;
61
61
  }
package/src/UtilFP.ts CHANGED
@@ -29,11 +29,13 @@ export function curry<T extends Function>(fn: T): CurryFunc<T> {
29
29
  /**可组合的函数 */
30
30
  type CompFunc<T, R> = (arg: T) => R;
31
31
 
32
+
32
33
  /**函数管道组合
33
34
  * 从左到右执行
34
35
  * @param fs - 待组合的函数
35
36
  * @returns 组合完成的函数
36
37
  */
38
+ //#region flow重载
37
39
  export function flow<I>(...fs: CompFunc<I, I>[]): CompFunc<I, I>;
38
40
  export function flow<I, R1>(f1: CompFunc<I, R1>,...fs: CompFunc<R1, R1>[]): CompFunc<I, R1>;
39
41
  export function flow<I, R1, R2>(f1: CompFunc<I, R1>, f2: CompFunc<R1, R2>,...fs: CompFunc<R2, R2>[]): CompFunc<I, R2>;
@@ -44,6 +46,7 @@ export function flow<I, R1, R2, R3, R4, R5, R6>(f1: CompFunc<I, R1>, f2: CompFun
44
46
  export function flow<I, R1, R2, R3, R4, R5, R6, R7>(f1: CompFunc<I, R1>, f2: CompFunc<R1, R2>, f3: CompFunc<R2, R3>, f4: CompFunc<R3, R4>, f5: CompFunc<R4, R5>, f6: CompFunc<R5, R6>, f7: CompFunc<R6, R7>,...fs: CompFunc<R7, R7>[]): CompFunc<I, R7>;
45
47
  export function flow<I, R1, R2, R3, R4, R5, R6, R7, R8>(f1: CompFunc<I, R1>, f2: CompFunc<R1, R2>, f3: CompFunc<R2, R3>, f4: CompFunc<R3, R4>, f5: CompFunc<R4, R5>, f6: CompFunc<R5, R6>, f7: CompFunc<R6, R7>, f8: CompFunc<R7, R8>,...fs: CompFunc<R8, R8>[]): CompFunc<I, R8>;
46
48
  export function flow<I, R1, R2, R3, R4, R5, R6, R7, R8, R9>(f1: CompFunc<I, R1>, f2: CompFunc<R1, R2>, f3: CompFunc<R2, R3>, f4: CompFunc<R3, R4>, f5: CompFunc<R4, R5>, f6: CompFunc<R5, R6>, f7: CompFunc<R6, R7>, f8: CompFunc<R7, R8>, f9: CompFunc<R8, R9>,...fs: CompFunc<R9, R9>[]): CompFunc<I, R9>;
49
+ //#endregion
47
50
  export function flow<T>(...fs: ((arg: T) => T)[]): (arg: T) => T {
48
51
  return (arg: T): T => {
49
52
  return fs.reduce((value, func) => func(value), arg);
@@ -56,6 +59,7 @@ export function flow<T>(...fs: ((arg: T) => T)[]): (arg: T) => T {
56
59
  * @param fs - 待组合的函数
57
60
  * @returns 经过所有函数处理后的结果
58
61
  */
62
+ //#region pipe重载
59
63
  export function pipe<I>(input: I, ...fs: CompFunc<I, I>[]): I;
60
64
  export function pipe<I, R1>(input: I, f1: CompFunc<I, R1>,...fs: CompFunc<R1, R1>[]): R1;
61
65
  export function pipe<I, R1, R2>(input: I, f1: CompFunc<I, R1>, f2: CompFunc<R1, R2>,...fs: CompFunc<R2, R2>[]): R2;
@@ -66,6 +70,7 @@ export function pipe<I, R1, R2, R3, R4, R5, R6>(input: I, f1: CompFunc<I, R1>, f
66
70
  export function pipe<I, R1, R2, R3, R4, R5, R6, R7>(input: I, f1: CompFunc<I, R1>, f2: CompFunc<R1, R2>, f3: CompFunc<R2, R3>, f4: CompFunc<R3, R4>, f5: CompFunc<R4, R5>, f6: CompFunc<R5, R6>, f7: CompFunc<R6, R7>,...fs: CompFunc<R7, R7>[]): R7;
67
71
  export function pipe<I, R1, R2, R3, R4, R5, R6, R7, R8>(input: I, f1: CompFunc<I, R1>, f2: CompFunc<R1, R2>, f3: CompFunc<R2, R3>, f4: CompFunc<R3, R4>, f5: CompFunc<R4, R5>, f6: CompFunc<R5, R6>, f7: CompFunc<R6, R7>, f8: CompFunc<R7, R8>,...fs: CompFunc<R8, R8>[]): R8;
68
72
  export function pipe<I, R1, R2, R3, R4, R5, R6, R7, R8, R9>(input: I, f1: CompFunc<I, R1>, f2: CompFunc<R1, R2>, f3: CompFunc<R2, R3>, f4: CompFunc<R3, R4>, f5: CompFunc<R4, R5>, f6: CompFunc<R5, R6>, f7: CompFunc<R6, R7>, f8: CompFunc<R7, R8>, f9: CompFunc<R8, R9>,...fs: CompFunc<R9, R9>[]): R9;
73
+ //#endregion
69
74
  export function pipe<T>(input: T, ...fs: ((arg: T) => T)[]): T {
70
75
  return fs.reduce((value, func) => func(value), input);
71
76
  }
@@ -1,9 +1,10 @@
1
1
  import * as fs from "fs";
2
2
  import * as path from "path";
3
- import { JToken, stringifyJToken } from "@src/UtilInterfaces";
3
+ import { JToken } from "@src/UtilInterfaces";
4
4
  import { SLogger } from "@src/UtilLogger";
5
5
  import * as JSON5 from 'json5';
6
6
  import { globSync } from "glob";
7
+ import { UtilFunc } from "./UtilFunctions";
7
8
 
8
9
  /**文件工具 */
9
10
  export namespace UtilFT{
@@ -178,7 +179,7 @@ export async function writeJSONFile(
178
179
  filePath: string,
179
180
  token: JToken
180
181
  ): Promise<void> {
181
- let str = stringifyJToken(token);
182
+ let str = UtilFunc.stringifyJToken(token);
182
183
  if (path.extname(filePath) !== '.json') filePath += '.json';
183
184
 
184
185
  // 判断文件路径是否存在 不存在则创建
@@ -1,5 +1,5 @@
1
1
  import * as crypto from "crypto";
2
- import { ComposedClass, ComposedMixinable, FuncPropNames, JObject, JToken, Mixinable, PromiseProcFn, PromiseStat, PromiseVerifyFn } from "@src/UtilInterfaces";
2
+ import { ComposedClass, ComposedMixinable, ExtractOutcome, FuncPropNames, IJData, JObject, JToken, Mixinable, Outcome, PromiseStat, PromiseVerifyFn } from "@src/UtilInterfaces";
3
3
  import * as cp from "child_process";
4
4
  import { SLogger } from "@src/UtilLogger";
5
5
 
@@ -133,36 +133,35 @@ type ProcessingPromise<T> = {
133
133
  * @param verifyFn - 验证函数
134
134
  * @param repeatCount - 重试次数
135
135
  * @param repeatTime - 超时时间/秒 最小为10秒
136
- * @returns - 结果 null 为全部失败/超时
136
+ * @returns 结果 null 为全部失败/超时
137
137
  */
138
- export async function repeatPromise<T>(procFn:PromiseProcFn<T>,verifyFn?:PromiseVerifyFn<T>,
138
+ export async function repeatPromise<T>(procFn:()=>Promise<T>,verifyFn?:PromiseVerifyFn<T>,
139
139
  repeatCount:number=3,repeatTime:number=180):Promise<T|null>{
140
140
 
141
141
  //计时
142
142
  const timeflag = "repeatPromise "+UtilFunc.genUUID();
143
143
  SLogger.time(timeflag);
144
144
 
145
- //转换为毫秒
145
+ /**是否含有超时时间 */
146
146
  const hasRepeatTime = (repeatTime>=10);
147
+ //转换为毫秒
147
148
  if(hasRepeatTime) repeatTime*=1000;
148
149
 
149
150
  //验证处理函数
150
151
  if(verifyFn===undefined)
151
152
  verifyFn = ()=>"Completed";
152
153
 
153
- //计时器
154
+ /**计时器 */
154
155
  let timer:NodeJS.Timer|null = null;
156
+ /**计时器 Promise */
155
157
  let timerP:Promise<"Timeout">|null=null;
156
- let resolveFn:((value: "Timeout" | PromiseLike<"Timeout">)=>void)|null = null;
158
+ /**计时器 Promise 的返回函数 */
159
+ let resolveFn:((value: "Timeout")=>void)|null = null;
157
160
  /**清理计时器 */
158
161
  const clearTimer = ()=>{
159
- if(timer!=null)
160
- clearInterval(timer);
161
- if(resolveFn!=null)
162
- resolveFn("Timeout");
163
- timerP=null;
164
- timer=null;
165
- resolveFn=null;
162
+ if(timer) clearInterval(timer);
163
+ if(resolveFn) resolveFn("Timeout");
164
+ timerP = timer = resolveFn = null;
166
165
  }
167
166
 
168
167
  //进行中的请求
@@ -170,9 +169,11 @@ export async function repeatPromise<T>(procFn:PromiseProcFn<T>,verifyFn?:Promise
170
169
 
171
170
  //开始处理
172
171
  try{
172
+ //根据最大重试次数限制进行循环
173
173
  for(let i=0;i<repeatCount;){
174
174
  SLogger.info(`开始第 ${i+1} 次 repeatPromise`);
175
- //创建当前任务
175
+
176
+ //如果 plist 中当前下标的任务还未创建 则 创建当前任务
176
177
  if(plist.length<i+1){
177
178
  plist.push(procFn().then(result =>
178
179
  ({result, stat:verifyFn!(result), index:i})));
@@ -180,46 +181,51 @@ export async function repeatPromise<T>(procFn:PromiseProcFn<T>,verifyFn?:Promise
180
181
 
181
182
  //创建定时器
182
183
  if(timerP==null){
183
- timerP = new Promise<"Timeout">(function(resolve, rejecte){
184
+ timerP = new Promise<"Timeout">((resolve, rejecte)=>{
184
185
  resolveFn = resolve;
185
186
  timer = setTimeout(()=>resolve("Timeout"),
186
- hasRepeatTime? repeatTime:Infinity);//无限制则无限时间
187
+ hasRepeatTime ? repeatTime : Infinity);//无限制则无限时间
187
188
  })
188
189
  }
189
190
 
190
- //等待完成
191
+ //等待任意任务 或当前计时器完成
191
192
  const currObj = await Promise.race([...plist, timerP]);
192
193
 
193
194
  //超时处理
194
- if(currObj=="Timeout"){
195
+ if(currObj==="Timeout"){
195
196
  SLogger.warn(`第 ${i+1} 次 repeatPromise 超时 ${repeatTime} ms 开始重试`);
196
197
  clearTimer(); i++;
197
198
  continue;
198
199
  }
200
+
201
+ //路由请求状态
199
202
  const poststat = await currObj.stat;
200
- switch(poststat){
201
- case "Completed"://完成
203
+ const result = matchStr(poststat,{
204
+ Completed(){
202
205
  SLogger.info(`第 ${currObj.index+1} 次 repeatPromise 成功`);
203
206
  //非当前
204
207
  if(currObj.index!=i)
205
208
  SLogger.info(`成功的 promise 非当前 promise 考虑增大重试间隔\n当前index: ${i}\n当前间隔: ${repeatTime}`);
206
209
  return currObj.result;
207
- case "Terminated"://终止
210
+ },
211
+ Terminated(){
208
212
  SLogger.warn(`第 ${currObj.index+1} 次 repeatPromise 终止 停止重试`);
209
213
  return currObj.result;
210
- case "Failed"://验证失败
214
+ },
215
+ Failed(){
211
216
  //抛弃失败
212
217
  plist[currObj.index] = UtilFunc.getNeverResolvedPromise();
213
218
  //是当前
214
219
  if(currObj.index==i){
215
220
  SLogger.warn(`第 ${currObj.index+1} 次 repeatPromise 失败 开始重试`);
216
221
  clearTimer(); i++;
217
- continue;
222
+ return;
218
223
  }
219
224
  //非当前
220
225
  SLogger.warn(`第 ${currObj.index+1} 次 repeatPromise 失败`);
221
- continue;
222
- }
226
+ },
227
+ });
228
+ if(result !== undefined) return result;
223
229
  }
224
230
  //全部失败或超时则返回null
225
231
  SLogger.warn(`${repeatCount} 次 repeatPromise 尝试均失败`);
@@ -312,4 +318,36 @@ export function mapEntries<T extends Object>
312
318
  }, {} as T);
313
319
  }
314
320
 
321
+ /**处理联合 Outcome
322
+ * @param t - 目标值
323
+ * @param procObj - 所有可能的id组成的处理函数映射
324
+ * @returns 任意处理函数的返回值
325
+ */
326
+ export function matchOutcome<
327
+ T extends Outcome<string,unknown>,
328
+ P extends {[K in T['status']]:(k:K,v:ExtractOutcome<T,K>['result'])=>unknown}>
329
+ (t:T,procObj:P):{[K in keyof P]:ReturnType<P[K]>}[keyof P]{
330
+ return (procObj as any)[t.status](t.status,(t as any)?.result)
331
+ }
332
+ /**处理联合 字符串
333
+ * @param t - 目标值
334
+ * @param procObj - 所有可能的id组成的处理函数映射
335
+ * @returns 任意处理函数的返回值
336
+ */
337
+ export function matchStr<T extends string,P extends {[K in T]:(k:K)=>unknown}>
338
+ (t:T,procObj:P):{[K in keyof P]:ReturnType<P[K]>}[keyof P]{
339
+ return (procObj as any)[t](t)
340
+ }
341
+
342
+ /**将JToken转换为字符串
343
+ * @param token - 待转换的Token
344
+ * @param space - 插入的空格 数字为空格数量 默认为制表符\t
345
+ * @returns 转换完成的字符串
346
+ */
347
+ export function stringifyJToken(token:JToken|IJData,space:string|number|null|undefined="\t"){
348
+ if(space==null)
349
+ space=undefined;
350
+ return JSON.stringify(token,null,space);
351
+ }
352
+
315
353
  }
@@ -16,16 +16,6 @@ export interface IJData{
16
16
  */
17
17
  toJSON():JToken;
18
18
  }
19
- /**将JToken转换为字符串
20
- * @param token - 待转换的Token
21
- * @param space - 插入的空格 数字为空格数量 默认为制表符\t
22
- * @returns 转换完成的字符串
23
- */
24
- export function stringifyJToken(token:JToken|IJData,space:string|number|null|undefined="\t"){
25
- if(space==null)
26
- space=undefined;
27
- return JSON.stringify(token,null,space);
28
- }
29
19
 
30
20
  /**转为可写的 */
31
21
  export type Writeable<T> = {
@@ -73,18 +63,17 @@ export type ExclusiveJObject<B extends JObject,T extends JToken,K extends string
73
63
 
74
64
 
75
65
  /**请求完成状态 成功/失败/终止
76
- * 成功/终止 将直接返回
66
+ * 成功 将直接返回 结果
67
+ * 终止 将直接返回 null
77
68
  * 失败 将重试
78
69
  */
79
70
  export type PromiseStat = "Completed"|"Failed"|"Terminated";
80
71
  /**promise验证函数 */
81
72
  export type PromiseVerifyFn<T> = (obj:T)=>Promise<PromiseStat>|PromiseStat;
82
- /**发起promise的函数 */
83
- export type PromiseProcFn<T> = ()=>Promise<T>;
84
73
 
85
74
  /**类型中任意函数的字符串名称 */
86
75
  export type FuncPropNames<T> = {
87
- [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never;
76
+ [K in keyof T]: T[K] extends (...args: unknown[]) => unknown ? K : never;
88
77
  }[keyof T];
89
78
 
90
79
  /**部分组合的类
@@ -92,7 +81,7 @@ export type FuncPropNames<T> = {
92
81
  * @template Mixin - 待混入的类
93
82
  * @template PropKeys - 需要混入的成员key
94
83
  */
95
- export type ComposedClass<Base extends object, Mixin extends object, Key extends string, PropKeys extends keyof Mixin> =
84
+ export type ComposedClass<Base, Mixin, Key extends string, PropKeys extends keyof Mixin> =
96
85
  Base & Pick<Mixin, PropKeys> & {[P in Key]:Mixin};
97
86
 
98
87
  /**可自动混入的类型 */
@@ -108,9 +97,56 @@ export type Mixinable<Mixin> = {
108
97
  };
109
98
 
110
99
  /**自动组合可混入的类 */
111
- export type ComposedMixinable<B extends object, Ms extends unknown[]> =
100
+ export type ComposedMixinable<B, Ms extends unknown[]> =
112
101
  Ms extends [infer M, ...infer Rest]
113
102
  ? M extends Mixinable<M>
114
103
  ? ComposedMixinable<ComposedClass<B,M,M['MIXIN_KEY'],M['MIXIN_FIELDS'][number]>,Rest>
115
104
  : "一个混入类没有实现 Mixinable<self>" & Error
116
105
  : B
106
+
107
+ /** extends封装
108
+ * @template B - 基础类型
109
+ * @template T - 判断的目标类型
110
+ * @template Y - 如果为真的返回值
111
+ * @template N - 如果为假的返回值
112
+ */
113
+ export type ExtendThen<B,T,Y,N = never> = B extends T ? Y : N;
114
+ /** 一个联合类型 B 中如果包含 T
115
+ * @template B - 基础类型
116
+ * @template T - 判断的目标类型
117
+ * @template Y - 如果为真的返回值
118
+ * @template N - 如果为假的返回值
119
+ */
120
+ export type UnionInclude<B,T,Y,N = never> =
121
+ B extends Exclude<B,T>
122
+ ? Y
123
+ : N
124
+ /**排除可选字段 */
125
+ export type RequiredOnly<T> = {
126
+ [K in keyof T as
127
+ UnionInclude<T[K],undefined,never,K>
128
+ ]: T[K]
129
+ };
130
+ /**添加前缀 */
131
+ export type WithPrefix<T,P extends string> = {
132
+ [K in (keyof T) as
133
+ K extends string
134
+ ? `${P}_${K}`
135
+ : K
136
+ ]: T[K]
137
+ };
138
+ /**返回结果
139
+ * @template K - 类型键值
140
+ * @template V - 值
141
+ */
142
+ export type Outcome<K extends string,V> = {
143
+ /**状态类型 */
144
+ status:K;
145
+ /**值 */
146
+ result:V;
147
+ }
148
+
149
+ /**从联合 Outcome 中 根据 id 提取对应 value 的 type */
150
+ export type ExtractOutcome<T,K extends string> =
151
+ T extends Outcome<K,unknown> ? T : never;
152
+
@@ -104,4 +104,31 @@ let jot = {
104
104
  UtilFunc.initObject(jot,{
105
105
  c:()=>console.log("缺少c"+insd.getNum())
106
106
  })
107
- jot//?
107
+ jot//?
108
+
109
+
110
+ type IfUndefined<T, Y, N> = T extends undefined ? Y : N;
111
+
112
+ type RequiredOnly<T> = {
113
+ [K in (keyof T) as
114
+ T[K] extends Exclude<T[K],undefined>
115
+ ? K
116
+ : never
117
+ ]: T[K]
118
+ };
119
+
120
+
121
+ type WithPrefix<T,P extends string> = {
122
+ [K in (keyof T) as
123
+ K extends string
124
+ ? `${P}_${K}`
125
+ : K
126
+ ]: T[K]
127
+ };
128
+
129
+ type a= {
130
+ abc:123
131
+ def?:1
132
+ }
133
+ type d = RequiredOnly<a>;
134
+ type b = WithPrefix<a,"prefix">;