@zwa73/utils 1.0.106 → 1.0.107

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.
@@ -18,26 +18,30 @@ export declare class Piper<Arg, Result = Arg> {
18
18
  }
19
19
  type StreamOperation<T, U> = (item: T) => Promise<U> | U;
20
20
  /**并行流 */
21
- export declare class Stream<T> {
21
+ export declare class Stream<T> implements Iterable<T> {
22
22
  /**并发数*/
23
23
  private _concurrent;
24
- /**原始列表*/
25
24
  private _list;
26
25
  /**加工函数列表*/
27
26
  private _operation;
28
- constructor(list: Array<T>, concurrent?: number);
27
+ constructor(base?: Array<T> | number, concurrent?: number);
29
28
  /**平分数组
30
29
  * @param count - 份数
31
30
  * @param mode - 模式 average:轮询平均分 chunk:切块均分
32
31
  * @returns 新数组
33
32
  */
34
33
  private divide;
35
- /**映射加工
34
+ /**转换流
35
+ * @param operation - 加工函数
36
+ * @returns 新流
37
+ */
38
+ private trans;
39
+ /**流式的 映射加工
36
40
  * @param operation - 加工函数
37
41
  * @returns 新流
38
42
  */
39
43
  map<U>(operation: StreamOperation<T, U>): Stream<U>;
40
- /**遍历
44
+ /**流式的 遍历
41
45
  * 返回自身
42
46
  * @param operation - 遍历函数
43
47
  * @returns 自身
@@ -47,9 +51,16 @@ export declare class Stream<T> {
47
51
  * @returns 自身
48
52
  */
49
53
  append(): Promise<Stream<T>>;
50
- /**转换为数组
54
+ /**应用加工 并转换为数组
51
55
  * @returns 数组
52
56
  */
53
57
  toArray(): Promise<Array<T>>;
58
+ /**应用加工 并过滤
59
+ * @param func - 过滤函数
60
+ * @returns 自身
61
+ */
62
+ filter(func: (value: T, index: number, array: T[]) => boolean): Promise<Stream<T>>;
63
+ [Symbol.iterator](): Iterator<T>;
64
+ get length(): number;
54
65
  }
55
66
  export {};
package/dist/UtilClass.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Stream = exports.Piper = void 0;
4
+ const QuickFunction_1 = require("./QuickFunction");
4
5
  /**函数管道器 */
5
6
  class Piper {
6
7
  /**管道函数列表 */
@@ -31,12 +32,16 @@ exports.Piper = Piper;
31
32
  class Stream {
32
33
  /**并发数*/
33
34
  _concurrent;
34
- /**原始列表*/
35
35
  _list;
36
36
  /**加工函数列表*/
37
37
  _operation = [];
38
- constructor(list, concurrent = 1) {
39
- this._list = list;
38
+ constructor(base, concurrent = 1) {
39
+ if (base == undefined)
40
+ this._list = new Array();
41
+ else if (typeof base === 'number')
42
+ this._list = new Array(base);
43
+ else
44
+ this._list = new Array(...base);
40
45
  this._concurrent = concurrent;
41
46
  }
42
47
  /**平分数组
@@ -48,22 +53,21 @@ class Stream {
48
53
  if (count <= 0)
49
54
  return [];
50
55
  if (count == 1)
51
- return [[...this._list]];
56
+ return [[...this]];
57
+ const size = this.length;
52
58
  const result = [];
53
- switch (mode) {
59
+ (0, QuickFunction_1.matchProc)(mode, {
54
60
  //轮询平均分
55
- case "average":
61
+ 'average': () => {
56
62
  for (let i = 0; i < count; i++) {
57
63
  const clist = [];
58
- const size = this._list.length;
59
64
  for (let j = i; j < size; j += count)
60
65
  clist.push(this._list[j]);
61
66
  result.push(clist);
62
67
  }
63
- break;
68
+ },
64
69
  //切块均分
65
- case "chunk":
66
- const size = this._list.length;
70
+ 'chunk': () => {
67
71
  const chunkSize = Math.ceil(size / count);
68
72
  for (let i = 0; i < count; i++) {
69
73
  const start = i * chunkSize;
@@ -72,19 +76,28 @@ class Stream {
72
76
  end = size;
73
77
  result.push(this._list.slice(start, end));
74
78
  }
75
- break;
76
- }
79
+ },
80
+ });
77
81
  return result;
78
82
  }
79
- /**映射加工
83
+ /**转换流
84
+ * @param operation - 加工函数
85
+ * @returns 新流
86
+ */
87
+ trans(operation) {
88
+ const ns = new Stream(this._list, this._concurrent);
89
+ ns._operation.push(...this._operation);
90
+ ns._operation.push(operation);
91
+ return ns;
92
+ }
93
+ /**流式的 映射加工
80
94
  * @param operation - 加工函数
81
95
  * @returns 新流
82
96
  */
83
97
  map(operation) {
84
- this._operation.push(operation);
85
- return this;
98
+ return this.trans(operation);
86
99
  }
87
- /**遍历
100
+ /**流式的 遍历
88
101
  * 返回自身
89
102
  * @param operation - 遍历函数
90
103
  * @returns 自身
@@ -94,8 +107,8 @@ class Stream {
94
107
  operation(item);
95
108
  return item;
96
109
  };
97
- this._operation.push(opera);
98
- return this;
110
+ return this.trans(opera);
111
+ ;
99
112
  }
100
113
  //终结操作
101
114
  /**应用加工
@@ -104,14 +117,12 @@ class Stream {
104
117
  async append() {
105
118
  if (this._operation.length == 0)
106
119
  return this;
107
- const promiseList = [];
120
+ const pList = [];
108
121
  //均分处理
109
- const sliceList = this.divide(this._concurrent);
110
- for (let i = 0; i < this._concurrent; i++) {
111
- const subList = sliceList[i];
122
+ this.divide(this._concurrent).forEach((subList) => {
112
123
  if (!subList)
113
- continue;
114
- promiseList.push(new Promise(async (reslove) => {
124
+ return;
125
+ pList.push(new Promise(async (reslove) => {
115
126
  const result = [];
116
127
  for (let item of subList) {
117
128
  if (!item)
@@ -122,28 +133,50 @@ class Stream {
122
133
  }
123
134
  reslove(result);
124
135
  }));
125
- }
126
- const nlist = await Promise.all(promiseList);
136
+ });
137
+ const rlist = await Promise.all(pList);
127
138
  //拼接结果 轮询均分
128
- const result = new Array(this._list.length).fill(undefined);
129
- for (let i = 0; i < this._concurrent; i++) {
130
- const subList = nlist[i];
139
+ const result = new Array(this.length).fill(undefined);
140
+ rlist.forEach((subList, i) => {
131
141
  if (!subList)
132
- continue;
142
+ return;
133
143
  const subSize = subList.length;
134
144
  for (let j = 0; j < subSize; j++)
135
145
  result[i + j * this._concurrent] = subList[j];
136
- }
146
+ });
137
147
  this._list = result;
138
148
  this._operation = [];
139
149
  return this;
140
150
  }
141
- /**转换为数组
151
+ /**应用加工 并转换为数组
142
152
  * @returns 数组
143
153
  */
144
154
  async toArray() {
145
155
  await this.append();
146
- return this._list;
156
+ return [...this];
157
+ }
158
+ /**应用加工 并过滤
159
+ * @param func - 过滤函数
160
+ * @returns 自身
161
+ */
162
+ async filter(func) {
163
+ await this.append();
164
+ return new Stream(this._list.filter(func));
165
+ }
166
+ //迭代器
167
+ [Symbol.iterator]() {
168
+ let index = 0;
169
+ const data = this._list;
170
+ return {
171
+ next: () => ({
172
+ value: data[index++],
173
+ done: index > data.length
174
+ })
175
+ };
176
+ }
177
+ // 创建 length 属性的 getter 和 setter
178
+ get length() {
179
+ return this._list.length;
147
180
  }
148
181
  }
149
182
  exports.Stream = Stream;
@@ -34,10 +34,10 @@ export declare namespace UtilCodec {
34
34
  * @param arr = Token数组
35
35
  * @returns 消息字符串
36
36
  */
37
- function decodeTokenTurbo(arr: Uint32Array): string;
37
+ function decodeTokenTurbo(arr: Uint32Array | number[]): string;
38
38
  /**token解码 Davinci模型
39
39
  * @param arr = Token数组
40
40
  * @returns 消息字符串
41
41
  */
42
- function decodeTokenDavinci(arr: Uint32Array): string;
42
+ function decodeTokenDavinci(arr: Uint32Array | number[]): string;
43
43
  }
@@ -1,10 +1,30 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
4
24
  };
5
25
  Object.defineProperty(exports, "__esModule", { value: true });
6
26
  exports.UtilCodec = void 0;
7
- const html_entities_1 = __importDefault(require("html-entities"));
27
+ const he = __importStar(require("html-entities"));
8
28
  const tiktoken_1 = require("tiktoken");
9
29
  /**编码/解码器 */
10
30
  var UtilCodec;
@@ -17,7 +37,7 @@ var UtilCodec;
17
37
  * @returns 转换后的字符串
18
38
  */
19
39
  function decodeHtmlEntities(str) {
20
- return html_entities_1.default.decode(str);
40
+ return he.decode(str);
21
41
  }
22
42
  UtilCodec.decodeHtmlEntities = decodeHtmlEntities;
23
43
  /**HTML实体编码 将一个字符串中的 需编码字符转换为 HTML实体
@@ -25,7 +45,7 @@ var UtilCodec;
25
45
  * @returns 转换后的字符串
26
46
  */
27
47
  function encodeHtmlEntities(str) {
28
- return html_entities_1.default.encode(str);
48
+ return he.encode(str);
29
49
  }
30
50
  UtilCodec.encodeHtmlEntities = encodeHtmlEntities;
31
51
  //#region LAM
@@ -83,6 +103,8 @@ var UtilCodec;
83
103
  */
84
104
  function decodeTokenTurbo(arr) {
85
105
  initTikTokenEncoder();
106
+ if (Array.isArray(arr))
107
+ arr = new Uint32Array(arr);
86
108
  return textDecoder.decode(encoderTurbo?.decode(arr));
87
109
  }
88
110
  UtilCodec.decodeTokenTurbo = decodeTokenTurbo;
@@ -92,6 +114,8 @@ var UtilCodec;
92
114
  */
93
115
  function decodeTokenDavinci(arr) {
94
116
  initTikTokenEncoder();
117
+ if (Array.isArray(arr))
118
+ arr = new Uint32Array(arr);
95
119
  return textDecoder.decode(encoderDavinci?.decode(arr));
96
120
  }
97
121
  UtilCodec.decodeTokenDavinci = decodeTokenDavinci;
@@ -164,7 +164,7 @@ class SFfmpegTool {
164
164
  static async wav2oggMP(ioMap, quality = 10, cpCount = 16) {
165
165
  await new UtilClass_1.Stream(Object.entries(ioMap))
166
166
  .map(async ([inPath, outPath]) => {
167
- UtilLogger_1.SLogger.info("SFfmpegTool.wav2oggMP 正在处理:" + outPath);
167
+ UtilLogger_1.SLogger.info(`SFfmpegTool.wav2oggMP 正在处理:${outPath}`);
168
168
  await SFfmpegTool.wav2ogg(inPath, outPath, quality);
169
169
  })
170
170
  .append();
@@ -177,7 +177,7 @@ class SFfmpegTool {
177
177
  static async flac2oggMP(ioMap, quality = 10, cpCount = 16) {
178
178
  await new UtilClass_1.Stream(Object.entries(ioMap))
179
179
  .map(async ([inPath, outPath]) => {
180
- UtilLogger_1.SLogger.info("SFfmpegTool.flac2oggMP 正在处理:" + outPath);
180
+ UtilLogger_1.SLogger.info(`SFfmpegTool.flac2oggMP 正在处理:${outPath}`);
181
181
  await SFfmpegTool.flac2ogg(inPath, outPath, quality);
182
182
  })
183
183
  .append();
@@ -190,7 +190,7 @@ class SFfmpegTool {
190
190
  static async trimSilenceMP(ioMap, threshold = -50, silence = 0.2, cpCount = 16) {
191
191
  await new UtilClass_1.Stream(Object.entries(ioMap))
192
192
  .map(async ([inPath, outPath]) => {
193
- UtilLogger_1.SLogger.info("SFfmpegTool.trimSilenceMP 正在处理:" + outPath);
193
+ UtilLogger_1.SLogger.info(`SFfmpegTool.trimSilenceMP 正在处理:${outPath}`);
194
194
  await SFfmpegTool.trimSilence(inPath, outPath, threshold, silence);
195
195
  })
196
196
  .append();
@@ -203,7 +203,7 @@ class SFfmpegTool {
203
203
  static async resampleMP(ioMap, rate = 22050, cpCount = 16) {
204
204
  await new UtilClass_1.Stream(Object.entries(ioMap))
205
205
  .map(async ([inPath, outPath]) => {
206
- UtilLogger_1.SLogger.info("SFfmpegTool.resampleMP 正在处理:" + outPath);
206
+ UtilLogger_1.SLogger.info(`SFfmpegTool.resampleMP 正在处理:${outPath}`);
207
207
  await SFfmpegTool.resample(inPath, outPath, rate);
208
208
  })
209
209
  .append();
@@ -1,4 +1,4 @@
1
- import { AnyFunc, ComposedClass, ComposedMixinable, ExtractOutcome, IJData, JObject, JToken, Keyable, LiteralCheck, Matchable, MatchableFlag, Mixinable, Outcome, PromiseVerifyFn, UnionToIntersection } from "./UtilInterfaces";
1
+ import { AnyFunc, ComposedClass, ComposedMixinable, ComposedCtorMixinable, ExtractOutcome, IJData, JObject, JToken, Keyable, LiteralCheck, Matchable, MatchableFlag, Mixinable, Outcome, PromiseVerifyFn, RefMixinable, UnionToIntersection } from "./UtilInterfaces";
2
2
  import { LogLevel } from "./UtilLogger";
3
3
  import { FailedLike, None, StatusSymbol, Success, SuccessLike, Timeout } from "./UtilSymbol";
4
4
  type SuccessOut<T> = Outcome<Success, T>;
@@ -82,8 +82,12 @@ export declare class UtilFunc {
82
82
  * @returns 混合完成的类
83
83
  */
84
84
  static composeClassPart<Base extends object, Mixin extends object, Field extends keyof Mixin>(base: Base, mixin: Mixin, key: string, ...fields: Field[]): ComposedClass<Base, Mixin, typeof key, Field>;
85
- /**根据 MIXIN_FIELDS 自动混入 */
85
+ /**根据 MIXIN_FIELDS 自动混入
86
+ * @deprecated 请使用 composeRefMixinable
87
+ */
86
88
  static composeMixinable<Base extends object, Mixins extends Mixinable<any>[]>(base: Base, ...mixins: Mixins): ComposedMixinable<Base, Mixins>;
89
+ /**根据 MIXIN_FIELDS 自动混入 */
90
+ static composeRefMixinable<Base extends object, Mixins extends RefMixinable<any, unknown>[]>(base: Base, ...mixins: Mixins): ComposedCtorMixinable<Base, Mixins>;
87
91
  /**对对象的每个属性应用映射函数,并返回一个新的对象。
88
92
  * @template T - 对象的类型
89
93
  * @param obj - 要处理的对象
@@ -279,7 +279,9 @@ class UtilFunc {
279
279
  }
280
280
  return compObj;
281
281
  }
282
- /**根据 MIXIN_FIELDS 自动混入 */
282
+ /**根据 MIXIN_FIELDS 自动混入
283
+ * @deprecated 请使用 composeRefMixinable
284
+ */
283
285
  static composeMixinable(base, ...mixins) {
284
286
  let out = base;
285
287
  const fieldsSet = new Set();
@@ -296,6 +298,23 @@ class UtilFunc {
296
298
  }
297
299
  return out;
298
300
  }
301
+ /**根据 MIXIN_FIELDS 自动混入 */
302
+ static composeRefMixinable(base, ...mixins) {
303
+ let out = base;
304
+ const fieldsSet = new Set();
305
+ for (const mixin of mixins) {
306
+ const ctor = mixin.CTOR;
307
+ for (const field of ctor.MIXIN_FIELDS) {
308
+ const fixField = field;
309
+ if (fieldsSet.has(fixField))
310
+ UtilLogger_1.SLogger.warn(`composeMixinable 出现了重复的 field: ${fixField} 可能会导致问题`);
311
+ else
312
+ fieldsSet.add(fixField);
313
+ }
314
+ out = UtilFunc.composeClassPart(base, mixin, ctor.MIXIN_KEY, ...ctor.MIXIN_FIELDS);
315
+ }
316
+ return out;
317
+ }
299
318
  /**对对象的每个属性应用映射函数,并返回一个新的对象。
300
319
  * @template T - 对象的类型
301
320
  * @param obj - 要处理的对象
@@ -105,8 +105,28 @@ export type Mixinable<Mixin> = {
105
105
  */
106
106
  readonly MIXIN_FIELDS: readonly (keyof Mixin)[];
107
107
  };
108
+ /**是原型构造器类型 */
109
+ export type IsCtor<T> = T extends {
110
+ new (): infer Ins;
111
+ } ? T : never;
112
+ /**可反射的
113
+ * @template Ctor - 构造器类型
114
+ * @template Constraint - 构造器约束
115
+ */
116
+ export type ReflectionAble<Ctor, Constraint = {}> = {
117
+ /**原型构造器 */
118
+ readonly CTOR: Ctor & Constraint;
119
+ };
120
+ /**构造函数是可混入的类
121
+ * @template Ctor - 构造器类型
122
+ * @template Instance - 实例类型
123
+ * @template Constraint - 构造器约束
124
+ */
125
+ export type RefMixinable<Ctor, Instance, Constraint = {}> = ReflectionAble<Ctor, Mixinable<Instance> & Constraint>;
108
126
  /**自动组合可混入的类 */
109
127
  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;
128
+ /**自动组合构造类型是可混入的类 */
129
+ export type ComposedCtorMixinable<B, Ms extends unknown[]> = Ms extends [infer M, ...infer Rest] ? M extends RefMixinable<unknown, M> ? ComposedCtorMixinable<ComposedClass<B, M, M['CTOR']['MIXIN_KEY'], M['CTOR']['MIXIN_FIELDS'][number]>, Rest> : "一个混入类没有实现 RefMixinable<typeof self, self>" & Error : B;
110
130
  /** extends封装
111
131
  * @template B - 基础类型
112
132
  * @template T - 判断的目标类型
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zwa73/utils",
3
- "version": "1.0.106",
3
+ "version": "1.0.107",
4
4
  "description": "my utils",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/src/UtilClass.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { matchProc } from "./QuickFunction";
2
+
1
3
  /**函数管道器 */
2
4
  export class Piper<Arg, Result = Arg> {
3
5
  /**管道函数列表 */
@@ -35,15 +37,16 @@ export class Piper<Arg, Result = Arg> {
35
37
 
36
38
  type StreamOperation<T, U> = (item: T)=>Promise<U>|U;
37
39
  /**并行流 */
38
- export class Stream<T> {
40
+ export class Stream<T> implements Iterable<T>{
39
41
  /**并发数*/
40
42
  private _concurrent: number;
41
- /**原始列表*/
42
43
  private _list: T[];
43
44
  /**加工函数列表*/
44
45
  private _operation: Array<StreamOperation<T, T>> = [];
45
- constructor(list: Array<T>, concurrent: number = 1) {
46
- this._list = list;
46
+ constructor(base?: Array<T>|number, concurrent: number = 1) {
47
+ if(base==undefined) this._list = new Array();
48
+ else if(typeof base === 'number') this._list = new Array(base);
49
+ else this._list = new Array(...base);
47
50
  this._concurrent = concurrent;
48
51
  }
49
52
  /**平分数组
@@ -53,23 +56,22 @@ export class Stream<T> {
53
56
  */
54
57
  private divide(count: number, mode: "average" | "chunk" = "average"): T[][] {
55
58
  if (count <= 0) return [];
56
- if (count == 1) return [[...this._list]];
59
+ if (count == 1) return [[...this]];
60
+ const size = this.length;
61
+ const result:T[][] = [];
57
62
 
58
- const result = [];
59
- switch (mode) {
63
+ matchProc(mode,{
60
64
  //轮询平均分
61
- case "average":
65
+ 'average':()=>{
62
66
  for (let i = 0; i < count; i++) {
63
67
  const clist = [];
64
- const size = this._list.length;
65
68
  for (let j = i; j < size; j += count)
66
69
  clist.push(this._list[j]);
67
70
  result.push(clist);
68
71
  }
69
- break;
72
+ },
70
73
  //切块均分
71
- case "chunk":
72
- const size = this._list.length;
74
+ 'chunk':()=>{
73
75
  const chunkSize = Math.ceil(size / count);
74
76
  for (let i = 0; i < count; i++) {
75
77
  const start = i * chunkSize;
@@ -77,20 +79,29 @@ export class Stream<T> {
77
79
  if (end > size) end = size;
78
80
  result.push(this._list.slice(start, end));
79
81
  }
80
- break;
81
- }
82
+ },
83
+ })
82
84
  return result;
83
85
  }
86
+ /**转换流
87
+ * @param operation - 加工函数
88
+ * @returns 新流
89
+ */
90
+ private trans<U>(operation:StreamOperation<T, U>): Stream<U>{
91
+ const ns = new Stream(this._list,this._concurrent);
92
+ ns._operation.push(...this._operation);
93
+ ns._operation.push(operation as any);
94
+ return ns as any;
95
+ }
84
96
 
85
- /**映射加工
97
+ /**流式的 映射加工
86
98
  * @param operation - 加工函数
87
99
  * @returns 新流
88
100
  */
89
101
  map<U>(operation: StreamOperation<T, U>): Stream<U> {
90
- this._operation.push(operation as any);
91
- return this as any as Stream<U>;
102
+ return this.trans(operation);
92
103
  }
93
- /**遍历
104
+ /**流式的 遍历
94
105
  * 返回自身
95
106
  * @param operation - 遍历函数
96
107
  * @returns 自身
@@ -100,8 +111,7 @@ export class Stream<T> {
100
111
  operation(item);
101
112
  return item;
102
113
  };
103
- this._operation.push(opera);
104
- return this;
114
+ return this.trans(opera);;
105
115
  }
106
116
 
107
117
  //终结操作
@@ -111,13 +121,11 @@ export class Stream<T> {
111
121
  async append(): Promise<Stream<T>> {
112
122
  if (this._operation.length == 0) return this;
113
123
 
114
- const promiseList: Promise<T[]>[] = [];
124
+ const pList: Promise<T[]>[] = [];
115
125
  //均分处理
116
- const sliceList = this.divide(this._concurrent);
117
- for (let i = 0; i < this._concurrent; i++) {
118
- const subList = sliceList[i];
119
- if (!subList) continue;
120
- promiseList.push(
126
+ this.divide(this._concurrent).forEach((subList)=>{
127
+ if (!subList) return;
128
+ pList.push(
121
129
  new Promise(async (reslove) => {
122
130
  const result:T[] = [];
123
131
  for (let item of subList) {
@@ -129,27 +137,52 @@ export class Stream<T> {
129
137
  reslove(result);
130
138
  })
131
139
  );
132
- }
133
- const nlist = await Promise.all(promiseList);
140
+ })
141
+ const rlist = await Promise.all(pList);
142
+
134
143
  //拼接结果 轮询均分
135
- const result = new Array(this._list.length).fill(undefined);
136
- for (let i = 0; i < this._concurrent; i++) {
137
- const subList = nlist[i];
138
- if (!subList) continue;
144
+ const result = new Array(this.length).fill(undefined);
145
+ rlist.forEach((subList,i)=>{
146
+ if (!subList) return;
139
147
  const subSize = subList.length;
140
148
  for (let j = 0; j < subSize; j++)
141
149
  result[i + j * this._concurrent] = subList[j];
142
- }
150
+ });
151
+
143
152
  this._list = result;
144
153
  this._operation = [];
145
154
  return this;
146
155
  }
147
- /**转换为数组
156
+ /**应用加工 并转换为数组
148
157
  * @returns 数组
149
158
  */
150
159
  async toArray(): Promise<Array<T>> {
151
160
  await this.append();
152
- return this._list;
161
+ return [...this];
153
162
  }
154
- }
163
+ /**应用加工 并过滤
164
+ * @param func - 过滤函数
165
+ * @returns 自身
166
+ */
167
+ async filter(func:(value: T, index: number, array: T[])=>boolean): Promise<Stream<T>>{
168
+ await this.append();
169
+ return new Stream(this._list.filter(func));
170
+ }
171
+ //迭代器
172
+ [Symbol.iterator](): Iterator<T> {
173
+ let index = 0;
174
+ const data = this._list;
155
175
 
176
+ return {
177
+ next: () => ({
178
+ value: data[index++],
179
+ done: index > data.length
180
+ })
181
+ };
182
+ }
183
+
184
+ // 创建 length 属性的 getter 和 setter
185
+ get length(): number {
186
+ return this._list.length;
187
+ }
188
+ }
package/src/UtilCodecs.ts CHANGED
@@ -1,4 +1,4 @@
1
- import he from 'html-entities';
1
+ import * as he from 'html-entities';
2
2
  import {get_encoding,Tiktoken} from 'tiktoken';
3
3
 
4
4
 
@@ -81,16 +81,18 @@ export function encodeTokenDavinci(str:string):Uint32Array{
81
81
  * @param arr = Token数组
82
82
  * @returns 消息字符串
83
83
  */
84
- export function decodeTokenTurbo(arr:Uint32Array):string{
84
+ export function decodeTokenTurbo(arr:Uint32Array|number[]):string{
85
85
  initTikTokenEncoder();
86
+ if(Array.isArray(arr)) arr = new Uint32Array(arr);
86
87
  return textDecoder.decode(encoderTurbo?.decode(arr));
87
88
  }
88
89
  /**token解码 Davinci模型
89
90
  * @param arr = Token数组
90
91
  * @returns 消息字符串
91
92
  */
92
- export function decodeTokenDavinci(arr:Uint32Array):string{
93
+ export function decodeTokenDavinci(arr:Uint32Array|number[]):string{
93
94
  initTikTokenEncoder();
95
+ if(Array.isArray(arr)) arr = new Uint32Array(arr);
94
96
  return textDecoder.decode(encoderDavinci?.decode(arr));
95
97
  }
96
98
  //#endregion
@@ -168,7 +168,7 @@ class SFfmpegTool {
168
168
  static async wav2oggMP(ioMap: IOMap, quality = 10, cpCount = 16) {
169
169
  await new Stream(Object.entries(ioMap))
170
170
  .map(async ([inPath, outPath]) => {
171
- SLogger.info("SFfmpegTool.wav2oggMP 正在处理:" + outPath);
171
+ SLogger.info(`SFfmpegTool.wav2oggMP 正在处理:${outPath}`);
172
172
  await SFfmpegTool.wav2ogg(inPath, outPath, quality);
173
173
  })
174
174
  .append();
@@ -185,7 +185,7 @@ class SFfmpegTool {
185
185
  ) {
186
186
  await new Stream(Object.entries(ioMap))
187
187
  .map(async ([inPath, outPath]) => {
188
- SLogger.info("SFfmpegTool.flac2oggMP 正在处理:" + outPath);
188
+ SLogger.info(`SFfmpegTool.flac2oggMP 正在处理:${outPath}`);
189
189
  await SFfmpegTool.flac2ogg(inPath, outPath, quality);
190
190
  })
191
191
  .append();
@@ -203,7 +203,7 @@ class SFfmpegTool {
203
203
  ) {
204
204
  await new Stream(Object.entries(ioMap))
205
205
  .map(async ([inPath, outPath]) => {
206
- SLogger.info("SFfmpegTool.trimSilenceMP 正在处理:" + outPath);
206
+ SLogger.info(`SFfmpegTool.trimSilenceMP 正在处理:${outPath}`);
207
207
  await SFfmpegTool.trimSilence(inPath, outPath, threshold, silence);
208
208
  })
209
209
  .append();
@@ -217,7 +217,7 @@ class SFfmpegTool {
217
217
  static async resampleMP(ioMap: IOMap, rate: number = 22050, cpCount: number = 16) {
218
218
  await new Stream(Object.entries(ioMap))
219
219
  .map(async ([inPath, outPath]) => {
220
- SLogger.info("SFfmpegTool.resampleMP 正在处理:" + outPath);
220
+ SLogger.info(`SFfmpegTool.resampleMP 正在处理:${outPath}`);
221
221
  await SFfmpegTool.resample(inPath, outPath, rate);
222
222
  })
223
223
  .append();
@@ -1,5 +1,5 @@
1
1
  import * as crypto from "crypto";
2
- import { AnyFunc, ComposedClass, ComposedMixinable, ExtractOutcome, IJData, JObject, JToken, Keyable, LiteralCheck, Matchable, MatchableFlag, Mixinable, Outcome, PromiseStat, PromiseVerifyFn, UnionToIntersection } from "@src/UtilInterfaces";
2
+ import { AnyFunc, ComposedClass, ComposedMixinable, ComposedCtorMixinable, ExtractOutcome, IJData, JObject, JToken, Keyable, LiteralCheck, Matchable, MatchableFlag, Mixinable, Outcome, PromiseStat, PromiseVerifyFn, RefMixinable, UnionToIntersection } 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";
@@ -304,7 +304,9 @@ static composeClassPart
304
304
  return compObj;
305
305
  }
306
306
 
307
- /**根据 MIXIN_FIELDS 自动混入 */
307
+ /**根据 MIXIN_FIELDS 自动混入
308
+ * @deprecated 请使用 composeRefMixinable
309
+ */
308
310
  static composeMixinable
309
311
  <Base extends object, Mixins extends Mixinable<any>[]>
310
312
  (base:Base,...mixins:Mixins):
@@ -325,6 +327,27 @@ static composeMixinable
325
327
  return out as any;
326
328
  }
327
329
 
330
+ /**根据 MIXIN_FIELDS 自动混入 */
331
+ static composeRefMixinable
332
+ <Base extends object, Mixins extends RefMixinable<any,unknown>[]>
333
+ (base:Base,...mixins:Mixins):
334
+ ComposedCtorMixinable<Base,Mixins>{
335
+ let out = base;
336
+ const fieldsSet = new Set<string>();
337
+ for(const mixin of mixins){
338
+ const ctor = mixin.CTOR;
339
+ for(const field of ctor.MIXIN_FIELDS) {
340
+ const fixField = field as string;
341
+ if(fieldsSet.has(fixField))
342
+ SLogger.warn(`composeMixinable 出现了重复的 field: ${fixField} 可能会导致问题`);
343
+ else
344
+ fieldsSet.add(fixField);
345
+ }
346
+ out = UtilFunc.composeClassPart(base,mixin,ctor.MIXIN_KEY,...ctor.MIXIN_FIELDS);
347
+ }
348
+ return out as any;
349
+ }
350
+
328
351
 
329
352
  /**对对象的每个属性应用映射函数,并返回一个新的对象。
330
353
  * @template T - 对象的类型
@@ -141,6 +141,25 @@ export type Mixinable<Mixin> = {
141
141
  */
142
142
  readonly MIXIN_FIELDS: readonly (keyof Mixin)[];
143
143
  };
144
+ /**是原型构造器类型 */
145
+ export type IsCtor<T> = T extends {new():infer Ins}
146
+ ? T : never;
147
+ /**可反射的
148
+ * @template Ctor - 构造器类型
149
+ * @template Constraint - 构造器约束
150
+ */
151
+ export type ReflectionAble<Ctor,Constraint={}> = {
152
+ /**原型构造器 */
153
+ readonly CTOR:Ctor&Constraint
154
+ };
155
+ /**构造函数是可混入的类
156
+ * @template Ctor - 构造器类型
157
+ * @template Instance - 实例类型
158
+ * @template Constraint - 构造器约束
159
+ */
160
+ export type RefMixinable<Ctor,Instance,Constraint={}> =
161
+ ReflectionAble<Ctor,Mixinable<Instance>&Constraint>;
162
+
144
163
 
145
164
  /**自动组合可混入的类 */
146
165
  export type ComposedMixinable<B, Ms extends unknown[]> =
@@ -150,6 +169,17 @@ export type ComposedMixinable<B, Ms extends unknown[]> =
150
169
  : "一个混入类没有实现 Mixinable<self>" & Error
151
170
  : B
152
171
 
172
+ /**自动组合构造类型是可混入的类 */
173
+ export type ComposedCtorMixinable<B, Ms extends unknown[]> =
174
+ Ms extends [infer M, ...infer Rest]
175
+ ? M extends RefMixinable<unknown,M>
176
+ ? ComposedCtorMixinable<ComposedClass<B,M,
177
+ M['CTOR']['MIXIN_KEY'],
178
+ M['CTOR']['MIXIN_FIELDS'][number]>,
179
+ Rest>
180
+ : "一个混入类没有实现 RefMixinable<typeof self, self>" & Error
181
+ : B
182
+
153
183
  /** extends封装
154
184
  * @template B - 基础类型
155
185
  * @template T - 判断的目标类型
@@ -214,3 +244,5 @@ export type ExtractOutcome<T,K extends Keyable> =
214
244
  * 输出schema后替换为 ^.*$ 的 string 匹配
215
245
  */
216
246
  export type SchemaString = `${string}SchemaString`;
247
+
248
+