xshell 1.0.19 → 1.0.20

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 +1 @@
1
- {"version":3,"file":"utils.browser.js","sourceRoot":"","sources":["utils.browser.ts"],"names":[],"mappings":"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","sourcesContent":["import { t } from './i18n/instance.js'\n\nexport function assert (assertion: any, message?: string): never | void {\n if (assertion)\n return\n \n debugger\n \n throw Object.assign(\n new Error(`${t('断言失败')}: ${ message ? `${message}: ` : '' }${assertion}`),\n { assertion }\n )\n}\n\n\nexport async function delay (milliseconds: number) {\n return new Promise<void>( resolve => {\n setTimeout(() => {\n resolve()\n }, milliseconds)\n })\n}\n\n\nexport interface Deferred <TValue> extends Promise<TValue> {\n resolve (value: TValue | PromiseLike<TValue>): void\n reject (reason?: Error): void\n}\n\n/** 创建一个 promise,后续可调用 promise.resolve, promise.reject 方法设置其状态和值 \n - initial?: `undefined` 传入非 undefined 值(包括 null)时直接设置为 resolved 状态 */\nexport function defer <TValue> (initial?: TValue): Deferred<TValue> {\n if (initial === undefined) {\n let resolve: (value: TValue | PromiseLike<TValue>) => void\n let reject: (reason?: Error) => void\n \n let promise = new Promise<TValue>((_resolve, _reject) => {\n resolve = _resolve\n reject = _reject\n })\n \n return Object.assign(promise, { resolve, reject })\n } else\n return Object.assign(Promise.resolve(initial), {\n resolve () { },\n reject () { }\n })\n}\n\n\nexport async function debug (milliseconds: number = 3000) {\n await delay(milliseconds)\n debugger\n}\n\n;(window as any).debug = debug\n\n\n/** 字符串字典序比较 */\nexport function strcmp (l: string, r: string) {\n if (l === r) return 0\n if (l < r) return -1\n return 1\n}\n\n\n/** 拼接 TypedArrays 生成一个完整的 Uint8Array */\nexport function concat (arrays: ArrayBufferView[]) {\n let length = 0\n for (const a of arrays)\n length += a.byteLength\n \n let buf = new Uint8Array(length)\n let offset = 0\n for (const a of arrays) {\n const uint8view = new Uint8Array(a.buffer, a.byteOffset, a.byteLength)\n buf.set(uint8view, offset)\n offset += uint8view.byteLength\n }\n \n return buf\n}\n\n\n/** 时间间隔 (milliseconds) 格式化 */\nexport function delta2str (delta: number) {\n if (delta < 1)\n return '0 ms'\n \n // [1, 1000) ms\n if (delta < 1000)\n return `${delta} ms`\n \n // 1.123 s\n if (1000 <= delta && delta < 1000 * 60)\n return `${(delta / 1000).toFixed(1)} s`\n \n // 1 min 12 s [1 min 0s, 60 min)\n const seconds = Math.trunc(delta / 1000)\n \n if (seconds < 60 * 60)\n return `${Math.trunc(seconds / 60)} min ${seconds % 60} s`\n \n const hour = Math.trunc(seconds / 3600)\n \n return `${hour} h ${Math.trunc((seconds - 3600 * hour) / 60)} min ${seconds % 60} s`\n}\n\n\n/** generate random id */\nexport function genid () {\n return Math.random() * 2**53\n}\n\n\nexport class Timer {\n started = new Date().getTime()\n \n ended: number\n \n stop () {\n this.ended = new Date().getTime()\n }\n \n get () {\n if (!this.ended)\n this.stop()\n \n return this.ended - this.started\n }\n \n getstr () {\n return `(${delta2str(this.get())})`\n }\n \n print () {\n console.log(this.getstr())\n }\n}\n\n"]}
1
+ {"version":3,"file":"utils.browser.js","sourceRoot":"","sources":["utils.browser.ts"],"names":[],"mappings":"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","sourcesContent":["import { t } from './i18n/instance.js'\n\nexport function assert (assertion: any, message?: string): never | void {\n if (assertion)\n return\n \n debugger\n \n throw Object.assign(\n new Error(`${t('断言失败')}: ${ message ? `${message}: ` : '' }${assertion}`),\n { assertion }\n )\n}\n\n\nexport async function delay (milliseconds: number) {\n return new Promise<void>(resolve => {\n setTimeout(resolve, milliseconds)\n })\n}\n\n\nexport async function timeout (milliseconds: number) {\n const error = new Error('超时错误')\n await delay(milliseconds)\n throw error\n}\n\n\n/** https://stackoverflow.com/questions/63297164/how-to-only-accept-arraybuffer-as-parameter */\nexport type StrictArrayBuffer = ArrayBuffer & { buffer?: undefined }\n\n\nexport interface Deferred <TValue> extends Promise<TValue> {\n resolve (value: TValue | PromiseLike<TValue>): void\n reject (reason?: Error): void\n}\n\n/** 创建一个 promise,后续可调用 promise.resolve, promise.reject 方法设置其状态和值 \n - initial?: `undefined` 传入非 undefined 值(包括 null)时直接设置为 resolved 状态 */\nexport function defer <TValue> (initial?: TValue): Deferred<TValue> {\n if (initial === undefined) {\n let resolve: (value: TValue | PromiseLike<TValue>) => void\n let reject: (reason?: Error) => void\n \n let promise = new Promise<TValue>((_resolve, _reject) => {\n resolve = _resolve\n reject = _reject\n })\n \n return Object.assign(promise, { resolve, reject })\n } else\n return Object.assign(Promise.resolve(initial), {\n resolve () { },\n reject () { }\n })\n}\n\n\nexport interface LockedAction <TResource, TResult> {\n (resource: TResource): Promise<TResult>\n}\n\n\n/** @example\n let lock = new Lock(redis)\n \n // 锁定资源后在 action 回调中操作资源,回调 promise 完成后自动释放资源,\n // 三秒内未成功独占资源直接抛出 TimeoutError (开始执行后不受 signal abort 影响)\n await lock.request(async redis => {\n const value = await redis.get('key')\n await redis.set('key', value * 2)\n }, AbortSignal.timeout(3000)) \n \n 参考:\n https://developer.mozilla.org/en-US/docs/Web/API/Web_Locks_API \n https://github.com/metarhia/web-locks \n https://www.npmjs.com/package/async-lock */\nexport class Lock <TResource = void> {\n /** 如果操作不需要独占资源,可以直接通过 lock.resource 访问,否则需要通过 await lock.request() 独占资源后再访问 */\n resource: TResource\n \n /** 等待链,新的 await lock.request() 调用会等待当前等待链尾部的 promise 完成,并作为新的尾部 */\n ptail = defer<void>(null)\n \n /** 查询当前资源是否属于被锁定的状态,方便在资源闲置时做一些可选操作(操作前仍需锁定),或者做一些状态展示 */\n locked = false\n \n \n /** 可以不传 resource,表示管理某个抽象或虚拟的资源 */\n constructor (resource?: TResource) {\n this.resource = resource\n }\n \n \n /** 通过 await lock.request() 锁定资源以便独占访问\n 成功返回之后由调用方负责调用 release 方法释放资源\n 在 signal aborted 时抛出错误结束等待,且由内部实现自动释放资源 */\n // async request (action: (resource: TResource) => Promise<void>, signal?: AbortSignal): Promise<void>\n // async request <TResult> (action: <TResult> (resource: TResource) => Promise<TResult>, signal?: AbortSignal): Promise<TResult>\n async request <TResult> (action: LockedAction<TResource, TResult>, signal?: AbortSignal): Promise<TResult> {\n signal?.throwIfAborted()\n \n const ptail = this.ptail\n \n let pcurrent = this.ptail = defer<void>()\n \n this.locked = true\n \n return new Promise<TResult>((resolve, reject) => {\n // 下面两种情况,先发生的决定 request 返回的 promise 状态\n // 不管是否 aborted, 都要等资源被前一次调用释放,先 aborted 只是将控制权交回给调用者,在锁定资源后不执行 action, 直接释放\n \n /** 防止执行过程中 signal abort */\n let executing = false\n \n signal?.addEventListener('abort', () => {\n if (!executing)\n // 这里不能释放锁,需要等 ptail resolve 后拿到资源再释放\n reject(signal.reason)\n }, { once: true })\n \n ptail.then(async () => {\n // 这里已经能保证独占访问资源\n \n // 如果 aborted, 可以理解为独占资源失败,调用者不会使用资源,直接释放\n if (signal?.aborted)\n reject(signal.reason)\n else\n // 由调用者去操作资源\n try {\n executing = true\n resolve(await action(this.resource))\n } catch (error) {\n reject(error)\n }\n \n \n // 下面开始释放锁\n \n // assert(this.locked)\n if (!this.locked)\n reject(new Error(t('尝试释放未锁定的锁,这不应该发生')))\n \n this.locked = false\n \n pcurrent.resolve()\n }\n )})\n }\n}\n\n\nexport async function debug (milliseconds: number = 3000) {\n await delay(milliseconds)\n debugger\n}\n\nglobalThis.debug = debug\n\n\n/** 字符串字典序比较 */\nexport function strcmp (l: string, r: string) {\n if (l === r) return 0\n if (l < r) return -1\n return 1\n}\n\n\n/** 拼接 TypedArrays 生成一个完整的 Uint8Array */\nexport function concat (arrays: ArrayBufferView[]) {\n let length = 0\n for (const a of arrays)\n length += a.byteLength\n \n let buf = new Uint8Array(length)\n let offset = 0\n for (const a of arrays) {\n const uint8view = new Uint8Array(a.buffer, a.byteOffset, a.byteLength)\n buf.set(uint8view, offset)\n offset += uint8view.byteLength\n }\n \n return buf\n}\n\n\n/** 时间间隔 (milliseconds) 格式化 */\nexport function delta2str (delta: number) {\n if (delta < 1)\n return '0 ms'\n \n // [1, 1000) ms\n if (delta < 1000)\n return `${delta} ms`\n \n // 1.123 s\n if (1000 <= delta && delta < 1000 * 60)\n return `${(delta / 1000).toFixed(1)} s`\n \n // 1 min 12 s [1 min 0s, 60 min)\n const seconds = Math.trunc(delta / 1000)\n \n if (seconds < 60 * 60)\n return `${Math.trunc(seconds / 60)} min ${seconds % 60} s`\n \n const hour = Math.trunc(seconds / 3600)\n \n return `${hour} h ${Math.trunc((seconds - 3600 * hour) / 60)} min ${seconds % 60} s`\n}\n\n\n/** generate random id */\nexport function genid () {\n return Math.random() * 2**53\n}\n\n\nexport class Timer {\n started = new Date().getTime()\n \n ended: number\n \n stop () {\n this.ended = new Date().getTime()\n }\n \n get () {\n if (!this.ended)\n this.stop()\n \n return this.ended - this.started\n }\n \n getstr () {\n return `(${delta2str(this.get())})`\n }\n \n print () {\n console.log(this.getstr())\n }\n}\n\n"]}
package/utils.d.ts CHANGED
@@ -39,7 +39,12 @@ export declare function log_section(message: string, { time, timestamp, color, }
39
39
  color?: 'green' | 'red' | 'yellow';
40
40
  }): void;
41
41
  export declare function log_line(): void;
42
- export declare function delay(milliseconds: number): Promise<unknown>;
42
+ export declare function delay(milliseconds: number): Promise<void>;
43
+ export declare function timeout(milliseconds: number): Promise<void>;
44
+ /** https://stackoverflow.com/questions/63297164/how-to-only-accept-arraybuffer-as-parameter */
45
+ export type StrictArrayBuffer = ArrayBuffer & {
46
+ buffer?: undefined;
47
+ };
43
48
  export interface Deferred<TValue> extends Promise<TValue> {
44
49
  resolve(value: TValue | PromiseLike<TValue>): void;
45
50
  reject(reason?: Error): void;
@@ -47,6 +52,37 @@ export interface Deferred<TValue> extends Promise<TValue> {
47
52
  /** 创建一个 promise,后续可调用 promise.resolve, promise.reject 方法设置其状态和值
48
53
  - initial?: `undefined` 传入非 undefined 值(包括 null)时直接设置为 resolved 状态 */
49
54
  export declare function defer<TValue>(initial?: TValue): Deferred<TValue>;
55
+ export interface LockedAction<TResource, TResult> {
56
+ (resource: TResource): Promise<TResult>;
57
+ }
58
+ /** @example
59
+ let lock = new Lock(redis)
60
+
61
+ // 锁定资源后在 action 回调中操作资源,回调 promise 完成后自动释放资源,
62
+ // 三秒内未成功独占资源直接抛出 TimeoutError (开始执行后不受 signal abort 影响)
63
+ await lock.request(async (redis) => {
64
+ const value = await redis.get('key')
65
+ await redis.set('key', value * 2)
66
+ }, AbortSignal.timeout(3000))
67
+
68
+ 参考:
69
+ https://developer.mozilla.org/en-US/docs/Web/API/Web_Locks_API
70
+ https://github.com/metarhia/web-locks
71
+ https://www.npmjs.com/package/async-lock */
72
+ export declare class Lock<TResource = void> {
73
+ /** 如果操作不需要独占资源,可以直接通过 lock.resource 访问,否则需要通过 await lock.request() 独占资源后再访问 */
74
+ resource: TResource;
75
+ /** 等待链,新的 await lock.request() 调用会等待当前等待链尾部的 promise 完成,并作为新的尾部 */
76
+ ptail: Deferred<void>;
77
+ /** 查询当前资源是否属于被锁定的状态,方便在资源闲置时做一些可选操作(操作前仍需锁定),或者做一些状态展示 */
78
+ locked: boolean;
79
+ /** 可以不传 resource,表示管理某个抽象或虚拟的资源 */
80
+ constructor(resource?: TResource);
81
+ /** 通过 await lock.request() 锁定资源以便独占访问
82
+ 成功返回之后由调用方负责调用 release 方法释放资源
83
+ 在 signal aborted 时抛出错误结束等待,且由内部实现自动释放资源 */
84
+ request<TResult>(action: LockedAction<TResource, TResult>, signal?: AbortSignal): Promise<TResult>;
85
+ }
50
86
  export declare function has_chinese(str: string): boolean;
51
87
  export declare function escape_line_feed(str: string): string;
52
88
  /** util.inspect(obj)
package/utils.js CHANGED
@@ -158,6 +158,11 @@ export async function delay(milliseconds) {
158
158
  setTimeout(resolve, milliseconds);
159
159
  });
160
160
  }
161
+ export async function timeout(milliseconds) {
162
+ const error = new Error('超时错误');
163
+ await delay(milliseconds);
164
+ throw error;
165
+ }
161
166
  /** 创建一个 promise,后续可调用 promise.resolve, promise.reject 方法设置其状态和值
162
167
  - initial?: `undefined` 传入非 undefined 值(包括 null)时直接设置为 resolved 状态 */
163
168
  export function defer(initial) {
@@ -176,6 +181,75 @@ export function defer(initial) {
176
181
  reject() { }
177
182
  });
178
183
  }
184
+ /** @example
185
+ let lock = new Lock(redis)
186
+
187
+ // 锁定资源后在 action 回调中操作资源,回调 promise 完成后自动释放资源,
188
+ // 三秒内未成功独占资源直接抛出 TimeoutError (开始执行后不受 signal abort 影响)
189
+ await lock.request(async (redis) => {
190
+ const value = await redis.get('key')
191
+ await redis.set('key', value * 2)
192
+ }, AbortSignal.timeout(3000))
193
+
194
+ 参考:
195
+ https://developer.mozilla.org/en-US/docs/Web/API/Web_Locks_API
196
+ https://github.com/metarhia/web-locks
197
+ https://www.npmjs.com/package/async-lock */
198
+ export class Lock {
199
+ /** 如果操作不需要独占资源,可以直接通过 lock.resource 访问,否则需要通过 await lock.request() 独占资源后再访问 */
200
+ resource;
201
+ /** 等待链,新的 await lock.request() 调用会等待当前等待链尾部的 promise 完成,并作为新的尾部 */
202
+ ptail = defer(null);
203
+ /** 查询当前资源是否属于被锁定的状态,方便在资源闲置时做一些可选操作(操作前仍需锁定),或者做一些状态展示 */
204
+ locked = false;
205
+ /** 可以不传 resource,表示管理某个抽象或虚拟的资源 */
206
+ constructor(resource) {
207
+ this.resource = resource;
208
+ }
209
+ /** 通过 await lock.request() 锁定资源以便独占访问
210
+ 成功返回之后由调用方负责调用 release 方法释放资源
211
+ 在 signal aborted 时抛出错误结束等待,且由内部实现自动释放资源 */
212
+ // async request (action: (resource: TResource) => Promise<void>, signal?: AbortSignal): Promise<void>
213
+ // async request <TResult> (action: <TResult> (resource: TResource) => Promise<TResult>, signal?: AbortSignal): Promise<TResult>
214
+ async request(action, signal) {
215
+ signal?.throwIfAborted();
216
+ const ptail = this.ptail;
217
+ let pcurrent = this.ptail = defer();
218
+ this.locked = true;
219
+ return new Promise((resolve, reject) => {
220
+ // 下面两种情况,先发生的决定 request 返回的 promise 状态
221
+ // 不管是否 aborted, 都要等资源被前一次调用释放,先 aborted 只是将控制权交回给调用者,在锁定资源后不执行 action, 直接释放
222
+ /** 防止执行过程中 signal abort */
223
+ let executing = false;
224
+ signal?.addEventListener('abort', () => {
225
+ if (!executing)
226
+ // 这里不能释放锁,需要等 ptail resolve 后拿到资源再释放
227
+ reject(signal.reason);
228
+ }, { once: true });
229
+ ptail.then(async () => {
230
+ // 这里已经能保证独占访问资源
231
+ // 如果 aborted, 可以理解为独占资源失败,调用者不会使用资源,直接释放
232
+ if (signal?.aborted)
233
+ reject(signal.reason);
234
+ else
235
+ // 由调用者去操作资源
236
+ try {
237
+ executing = true;
238
+ resolve(await action(this.resource));
239
+ }
240
+ catch (error) {
241
+ reject(error);
242
+ }
243
+ // 下面开始释放锁
244
+ // assert(this.locked)
245
+ if (!this.locked)
246
+ reject(new Error(t('尝试释放未锁定的锁,这不应该发生')));
247
+ this.locked = false;
248
+ pcurrent.resolve();
249
+ });
250
+ });
251
+ }
252
+ }
179
253
  // ------------ text
180
254
  export function has_chinese(str) {
181
255
  return /[\u4E00-\u9FA5]/.test(str);
package/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { Stream, Writable, Transform, type Readable, type Duplex, type TransformCallback } from 'stream'\nimport util from 'util'\n\nimport type Vinyl from 'vinyl'\nimport omit from 'lodash/omit.js'\n\nimport { t } from './i18n/instance.js'\nimport './prototype.js'\n\n\n/** `230` term 字符宽度 (实际上有 240) */\nexport const output_width = 230\n\n\nexport function set_inspect_options () {\n util.inspect.defaultOptions.maxArrayLength = 40\n util.inspect.defaultOptions.maxStringLength = 10000\n util.inspect.defaultOptions.breakLength = output_width\n util.inspect.defaultOptions.colors = true\n util.inspect.defaultOptions.compact = false\n util.inspect.defaultOptions.getters = true\n util.inspect.defaultOptions.depth = 2\n util.inspect.defaultOptions.sorted = false\n util.inspect.defaultOptions.showProxy = true\n \n util.inspect.styles.number = 'green'\n util.inspect.styles.string = 'cyan'\n util.inspect.styles.boolean = 'blue'\n util.inspect.styles.date = 'magenta'\n util.inspect.styles.special = 'white'\n}\n\n\nexport function assert (assertion: any, message?: string): never | void {\n if (!assertion) {\n debugger\n throw new Error(`${t('断言失败')}: ${ message ? `${message}: ` : '' }${inspect(assertion)}`)\n }\n}\n\n\nexport function dedent (\n templ: TemplateStringsArray | string,\n ...values: any[]\n): string {\n let strings = Array.from(typeof templ === 'string' ? [templ] : templ.raw)\n \n // 1. remove trailing whitespace\n strings[strings.length - 1] = strings[strings.length - 1].replace(\n /\\r?\\n([\\t ]*)$/,\n '',\n )\n \n // 2. find all line breaks to determine the highest common indentation level\n const indent_lengths = strings.reduce<number[]>(\n (arr, str) => {\n const matches = str.match(/\\n[\\t ]+/g)\n if (matches) \n return arr.concat(\n matches.map(match => \n match.length - 1)\n )\n \n return arr\n },\n [],\n )\n \n // 3. remove the common indentation from all strings\n if (indent_lengths.length) {\n const pattern = new RegExp(`\\n[\\t ]{${Math.min(...indent_lengths)}}`, 'g')\n \n strings = strings.map(str => str.replace(pattern, '\\n'))\n }\n \n // 4. remove leading whitespace\n strings[0] = strings[0].replace(/^\\r?\\n/, '')\n \n // 5. perform interpolation\n let string = strings[0]\n \n values.forEach((value, i) => {\n string += value + strings[i + 1]\n })\n \n string += '\\n'\n \n return string\n}\n\n\n/** 数组或 iterable 去重(可按 selector 去重) \n - selector?: 可以是 key (string) 或 (obj: any) => any\n*/\nexport function unique <T> (iterable: T[] | Iterable<T>, selector?: string | ((obj: T) => any)) {\n if (!selector)\n return [...new Set(iterable)]\n \n let map = new Map()\n const is_str_selector = typeof selector === 'string'\n for (const x of iterable)\n map.set(\n is_str_selector ? x[selector] : selector(x),\n x\n )\n \n return [...map.values()]\n}\n\n/** 排序对象中 key 的顺序,返回新的对象 */\nexport function sort_keys <T> (obj: T) {\n return Object.fromEntries(\n Object.entries(obj)\n .sort(([key_l], [key_r]) => \n strcmp(key_l, key_r))\n ) as T\n}\n\n\n/** 字符串字典序比较 */\nexport function strcmp (l: string, r: string) {\n if (l === r) return 0\n if (l < r) return -1\n return 1\n}\n\n\n/** 拼接 TypedArrays 生成一个完整的 Uint8Array */\nexport function concat (arrays: ArrayBufferView[]) {\n let length = 0\n for (const a of arrays)\n length += a.byteLength\n \n let buf = new Uint8Array(length)\n let offset = 0\n for (const a of arrays) {\n const uint8view = new Uint8Array(a.buffer, a.byteOffset, a.byteLength)\n buf.set(uint8view, offset)\n offset += uint8view.byteLength\n }\n \n return buf\n}\n\n\nexport function typed_array_to_buffer (view: ArrayBufferView) {\n return Buffer.from(view.buffer, view.byteOffset, view.byteLength)\n}\n\n\n/** 时间间隔 (milliseconds) 格式化 */\nexport function delta2str (delta: number) {\n if (delta < 1)\n return '0 ms'\n \n // [1, 1000) ms\n if (delta < 1000)\n return `${delta} ms`\n \n // 1.123 s\n if (1000 <= delta && delta < 1000 * 60)\n return `${(delta / 1000).toFixed(1)} s`\n \n // 1 min 12 s [1 min 0s, 60 min)\n const seconds = Math.trunc(delta / 1000)\n \n if (seconds < 60 * 60)\n return `${Math.trunc(seconds / 60)} min ${seconds % 60} s`\n \n const hour = Math.trunc(seconds / 3600)\n \n return `${hour} h ${Math.trunc((seconds - 3600 * hour) / 60)} min ${seconds % 60} s`\n}\n\n\n/** generate random id */\nexport function genid () {\n return Math.random() * 2**53\n}\n\n\nexport class Timer {\n started = new Date().getTime()\n \n ended: number\n \n stop () {\n this.ended = new Date().getTime()\n }\n \n get () {\n if (!this.ended)\n this.stop()\n \n return this.ended - this.started\n }\n \n getstr () {\n return `(${delta2str(this.get())})`\n }\n \n print () {\n console.log(this.getstr())\n }\n}\n\n\nexport function log_section (\n message: string, \n {\n time = false,\n timestamp = false,\n color = undefined,\n }: {\n time?: boolean\n timestamp?: boolean | Date\n color?: 'green' | 'red' | 'yellow'\n } = { }\n) {\n const stime = (() => {\n if (time)\n return delta2str(\n new Date().getTime() - global.started_at.getTime()\n ).pad(4, { position: 'left' })\n if (timestamp)\n if (typeof timestamp === 'object')\n return `${timestamp.to_str()}`\n else\n return `${new Date().to_str()}`\n return ''\n })()\n \n message = `${`${message} `.pad(39)} ${stime}`\n \n if (color)\n message = message[color]\n \n console.log(message)\n}\n\n\nexport function log_line () {\n console.log('---')\n}\n\n\nexport async function delay (milliseconds: number) {\n return new Promise(resolve => {\n setTimeout(resolve, milliseconds)\n })\n}\n\n\nexport interface Deferred <TValue> extends Promise<TValue> {\n resolve (value: TValue | PromiseLike<TValue>): void\n reject (reason?: Error): void\n}\n\n/** 创建一个 promise,后续可调用 promise.resolve, promise.reject 方法设置其状态和值 \n - initial?: `undefined` 传入非 undefined 值(包括 null)时直接设置为 resolved 状态 */\nexport function defer <TValue> (initial?: TValue): Deferred<TValue> {\n if (initial === undefined) {\n let resolve: (value: TValue | PromiseLike<TValue>) => void\n let reject: (reason?: Error) => void\n \n let promise = new Promise<TValue>((_resolve, _reject) => {\n resolve = _resolve\n reject = _reject\n })\n \n return Object.assign(promise, { resolve, reject })\n } else\n return Object.assign(Promise.resolve(initial), {\n resolve () { },\n reject () { }\n })\n}\n\n\n// ------------ text\nexport function has_chinese (str: string) {\n return /[\\u4E00-\\u9FA5]/.test(str)\n}\n\n\nexport function escape_line_feed (str: string) {\n return str.replace(/\\n/g, '\\\\n')\n}\n\n/** util.inspect(obj) \n - options\n - limit?: `10000`\n - omit?: string[] */\nexport function inspect (\n obj: any, \n options: util.InspectOptions & {\n limit?: number\n omit?: string[]\n } = { }\n) {\n if (options.omit)\n obj = omit(obj, [inspect.custom, ...(options.omit || [])])\n \n let text = util.inspect(obj, options)\n \n if (!('limit' in options))\n options.limit = 10000\n if (options.limit && text.length > options.limit)\n return `${text.slice(0, options.limit)}……'\\u001b[39m\\n`\n else\n return text\n}\n\nexport namespace inspect {\n export const custom: typeof util.inspect.custom = util.inspect.custom\n}\n\n\n// ------------------------------------ stream\n/** npm map-stream \n filter will reemit the data if cb(err,pass) pass is truthy \n \n reduce is more tricky \n maybe we want to group the reductions or emit progress updates occasionally \n the most basic reduce just emits one 'data' event after it has recieved 'end'\n \n create an event stream and apply function to each .write, \n emitting each response as data unless it's an empty callback\n */\nexport function map_stream <Out, In = Vinyl> (\n mapper: (obj: In, cb: Function) => any, \n options?: { failures?: boolean }\n) {\n options = options || { }\n \n let inputs = 0,\n outputs = 0,\n ended = false,\n paused = false,\n destroyed = false,\n last_written = 0,\n in_next = false\n \n \n let stream = Object.assign(new Stream(), {\n readable: true, \n writable: true,\n \n write (data?: any) {\n if (ended) throw new Error('map stream is not writable')\n in_next = false\n inputs++\n \n try {\n // catch sync errors and handle them like async errors\n const written = wrapped_mapper(data, inputs, next)\n paused = (written === false)\n return !paused\n } catch (err) {\n // if the callback has been called syncronously, and the error has occured in an listener, throw it again.\n if (in_next)\n throw err\n next(err)\n return !paused\n }\n },\n \n end (data?: any) {\n if (ended) return\n _end(data)\n },\n \n destroy () {\n ended = destroyed = true\n stream.writable = stream.readable = paused = false\n process.nextTick(function () {\n stream.emit('close')\n })\n },\n \n pause () {\n paused = true\n },\n \n resume () {\n paused = false\n }\n })\n \n \n let error_event_name = options.failures ? 'failure' : 'error'\n \n // Items that are not ready to be written yet (because they would come out of order) get stuck in a queue for later.\n let write_queue = { }\n \n \n function queue_data (data, number) {\n let next_to_write = last_written + 1\n \n if (number === next_to_write) {\n // If it's next, and its not undefined write it\n if (data !== undefined) \n stream.emit('data', data)\n \n last_written++\n next_to_write++\n } else \n // Otherwise queue it for later.\n write_queue[number] = data\n \n \n // If the next value is in the queue, write it\n if (Object.prototype.hasOwnProperty.call(write_queue, next_to_write)) {\n let data_to_write = write_queue[next_to_write]\n delete write_queue[next_to_write]\n return queue_data(data_to_write, next_to_write)\n }\n \n outputs++\n if (inputs === outputs) {\n if (paused) {\n paused = false\n stream.emit('drain') // written all the incoming events\n }\n if (ended) _end()\n }\n }\n \n function next (err?: Error, data?: any, number?: number) {\n if (destroyed) return\n in_next = true\n \n if (!err || options.failures)\n queue_data(data, number)\n \n if (err)\n stream.emit(error_event_name, err)\n \n in_next = false\n }\n \n /** Wrap the mapper function by calling its callback with the order number of the item in the stream. */ \n function wrapped_mapper (input, number, callback) {\n return mapper.call(null, input, function (err, data) {\n callback(err, data, number)\n })\n }\n \n function _end (data?: any) {\n // if end was called with args, write it, \n ended = true // write will emit 'end' if ended is true\n stream.writable = false\n if (data !== undefined) \n return queue_data(data, inputs)\n else if (inputs === outputs) { // wait for processing \n stream.readable = false\n stream.emit('end')\n stream.destroy() \n }\n }\n \n return stream as Duplex\n}\n\n\nexport async function stream_to_buffer (stream: Readable) {\n let chunks = [ ]\n for await (const chunk of stream as AsyncIterable<Buffer>)\n chunks.push(chunk)\n return Buffer.concat(chunks)\n}\n\n\nexport async function * stream_to_lines (stream: Readable) {\n let buf = ''\n for await (const chunk of stream as AsyncIterable<string>) {\n let i = 0, j = 0\n for (; (i = chunk.indexOf('\\n', j)) >= 0; ) {\n let line = chunk.slice(j, i)\n if (buf) {\n line = buf + line\n buf = ''\n }\n j = i + 1\n yield line\n }\n buf = chunk.slice(j)\n }\n}\n\n\nexport class WritableMemoryStream extends Writable {\n chunks: Buffer[] = [ ]\n \n pbuffer = defer<Buffer>()\n \n \n constructor () {\n super({ highWaterMark: 2 ** 30, decodeStrings: false })\n }\n \n \n override _write (chunk: Buffer, encoding: BufferEncoding, callback: (error?: Error) => void) {\n this.chunks.push(chunk as Buffer)\n callback()\n }\n \n \n override _writev (chunks: { chunk: any; encoding: BufferEncoding }[], callback: (error?: Error) => void): void {\n for (const { chunk } of chunks)\n this.chunks.push(chunk)\n callback()\n }\n \n \n override _final (callback: (error?: Error) => void): void {\n this.pbuffer.resolve(\n Buffer.concat(this.chunks)\n )\n this.chunks = null\n callback()\n }\n}\n\n\n/** 用 TextDecoder 通过 .pipe 方法持续的解码 process.stdout 等流, \n 主要在 process.ts#start 中使用 \n https://nodejs.org/api/stream.html#implementing-a-transform-stream */\nexport class DecoderStream extends Transform {\n decoder: TextDecoder\n \n \n constructor (encoding: 'gb18030' | 'shift-jis' | 'utf-16le') {\n super({ encoding: 'utf-8' })\n this.decoder = new TextDecoder(encoding)\n }\n \n \n override _transform (chunk: Uint8Array, encoding: BufferEncoding, callback: TransformCallback) {\n assert(chunk instanceof Uint8Array)\n \n const str = this.decoder.decode(chunk, { stream: true })\n \n if (str.length)\n this.push(str, 'utf-8')\n \n callback()\n }\n \n \n override _flush (callback: TransformCallback) {\n const str = this.decoder.decode()\n \n if (str.length)\n this.push(str, 'utf-8')\n \n callback()\n }\n}\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { Stream, Writable, Transform, type Readable, type Duplex, type TransformCallback } from 'stream'\nimport util from 'util'\n\nimport type Vinyl from 'vinyl'\nimport omit from 'lodash/omit.js'\n\nimport { t } from './i18n/instance.js'\nimport './prototype.js'\n\n\n/** `230` term 字符宽度 (实际上有 240) */\nexport const output_width = 230\n\n\nexport function set_inspect_options () {\n util.inspect.defaultOptions.maxArrayLength = 40\n util.inspect.defaultOptions.maxStringLength = 10000\n util.inspect.defaultOptions.breakLength = output_width\n util.inspect.defaultOptions.colors = true\n util.inspect.defaultOptions.compact = false\n util.inspect.defaultOptions.getters = true\n util.inspect.defaultOptions.depth = 2\n util.inspect.defaultOptions.sorted = false\n util.inspect.defaultOptions.showProxy = true\n \n util.inspect.styles.number = 'green'\n util.inspect.styles.string = 'cyan'\n util.inspect.styles.boolean = 'blue'\n util.inspect.styles.date = 'magenta'\n util.inspect.styles.special = 'white'\n}\n\n\nexport function assert (assertion: any, message?: string): never | void {\n if (!assertion) {\n debugger\n throw new Error(`${t('断言失败')}: ${ message ? `${message}: ` : '' }${inspect(assertion)}`)\n }\n}\n\n\nexport function dedent (\n templ: TemplateStringsArray | string,\n ...values: any[]\n): string {\n let strings = Array.from(typeof templ === 'string' ? [templ] : templ.raw)\n \n // 1. remove trailing whitespace\n strings[strings.length - 1] = strings[strings.length - 1].replace(\n /\\r?\\n([\\t ]*)$/,\n '',\n )\n \n // 2. find all line breaks to determine the highest common indentation level\n const indent_lengths = strings.reduce<number[]>(\n (arr, str) => {\n const matches = str.match(/\\n[\\t ]+/g)\n if (matches) \n return arr.concat(\n matches.map(match => \n match.length - 1)\n )\n \n return arr\n },\n [],\n )\n \n // 3. remove the common indentation from all strings\n if (indent_lengths.length) {\n const pattern = new RegExp(`\\n[\\t ]{${Math.min(...indent_lengths)}}`, 'g')\n \n strings = strings.map(str => str.replace(pattern, '\\n'))\n }\n \n // 4. remove leading whitespace\n strings[0] = strings[0].replace(/^\\r?\\n/, '')\n \n // 5. perform interpolation\n let string = strings[0]\n \n values.forEach((value, i) => {\n string += value + strings[i + 1]\n })\n \n string += '\\n'\n \n return string\n}\n\n\n/** 数组或 iterable 去重(可按 selector 去重) \n - selector?: 可以是 key (string) 或 (obj: any) => any\n*/\nexport function unique <T> (iterable: T[] | Iterable<T>, selector?: string | ((obj: T) => any)) {\n if (!selector)\n return [...new Set(iterable)]\n \n let map = new Map()\n const is_str_selector = typeof selector === 'string'\n for (const x of iterable)\n map.set(\n is_str_selector ? x[selector] : selector(x),\n x\n )\n \n return [...map.values()]\n}\n\n/** 排序对象中 key 的顺序,返回新的对象 */\nexport function sort_keys <T> (obj: T) {\n return Object.fromEntries(\n Object.entries(obj)\n .sort(([key_l], [key_r]) => \n strcmp(key_l, key_r))\n ) as T\n}\n\n\n/** 字符串字典序比较 */\nexport function strcmp (l: string, r: string) {\n if (l === r) return 0\n if (l < r) return -1\n return 1\n}\n\n\n/** 拼接 TypedArrays 生成一个完整的 Uint8Array */\nexport function concat (arrays: ArrayBufferView[]) {\n let length = 0\n for (const a of arrays)\n length += a.byteLength\n \n let buf = new Uint8Array(length)\n let offset = 0\n for (const a of arrays) {\n const uint8view = new Uint8Array(a.buffer, a.byteOffset, a.byteLength)\n buf.set(uint8view, offset)\n offset += uint8view.byteLength\n }\n \n return buf\n}\n\n\nexport function typed_array_to_buffer (view: ArrayBufferView) {\n return Buffer.from(view.buffer, view.byteOffset, view.byteLength)\n}\n\n\n/** 时间间隔 (milliseconds) 格式化 */\nexport function delta2str (delta: number) {\n if (delta < 1)\n return '0 ms'\n \n // [1, 1000) ms\n if (delta < 1000)\n return `${delta} ms`\n \n // 1.123 s\n if (1000 <= delta && delta < 1000 * 60)\n return `${(delta / 1000).toFixed(1)} s`\n \n // 1 min 12 s [1 min 0s, 60 min)\n const seconds = Math.trunc(delta / 1000)\n \n if (seconds < 60 * 60)\n return `${Math.trunc(seconds / 60)} min ${seconds % 60} s`\n \n const hour = Math.trunc(seconds / 3600)\n \n return `${hour} h ${Math.trunc((seconds - 3600 * hour) / 60)} min ${seconds % 60} s`\n}\n\n\n/** generate random id */\nexport function genid () {\n return Math.random() * 2**53\n}\n\n\nexport class Timer {\n started = new Date().getTime()\n \n ended: number\n \n stop () {\n this.ended = new Date().getTime()\n }\n \n get () {\n if (!this.ended)\n this.stop()\n \n return this.ended - this.started\n }\n \n getstr () {\n return `(${delta2str(this.get())})`\n }\n \n print () {\n console.log(this.getstr())\n }\n}\n\n\nexport function log_section (\n message: string, \n {\n time = false,\n timestamp = false,\n color = undefined,\n }: {\n time?: boolean\n timestamp?: boolean | Date\n color?: 'green' | 'red' | 'yellow'\n } = { }\n) {\n const stime = (() => {\n if (time)\n return delta2str(\n new Date().getTime() - global.started_at.getTime()\n ).pad(4, { position: 'left' })\n if (timestamp)\n if (typeof timestamp === 'object')\n return `${timestamp.to_str()}`\n else\n return `${new Date().to_str()}`\n return ''\n })()\n \n message = `${`${message} `.pad(39)} ${stime}`\n \n if (color)\n message = message[color]\n \n console.log(message)\n}\n\n\nexport function log_line () {\n console.log('---')\n}\n\n\nexport async function delay (milliseconds: number) {\n return new Promise<void>(resolve => {\n setTimeout(resolve, milliseconds)\n })\n}\n\n\nexport async function timeout (milliseconds: number) {\n const error = new Error('超时错误')\n await delay(milliseconds)\n throw error\n}\n\n\n/** https://stackoverflow.com/questions/63297164/how-to-only-accept-arraybuffer-as-parameter */\nexport type StrictArrayBuffer = ArrayBuffer & { buffer?: undefined }\n\n\nexport interface Deferred <TValue> extends Promise<TValue> {\n resolve (value: TValue | PromiseLike<TValue>): void\n reject (reason?: Error): void\n}\n\n/** 创建一个 promise,后续可调用 promise.resolve, promise.reject 方法设置其状态和值 \n - initial?: `undefined` 传入非 undefined 值(包括 null)时直接设置为 resolved 状态 */\nexport function defer <TValue> (initial?: TValue): Deferred<TValue> {\n if (initial === undefined) {\n let resolve: (value: TValue | PromiseLike<TValue>) => void\n let reject: (reason?: Error) => void\n \n let promise = new Promise<TValue>((_resolve, _reject) => {\n resolve = _resolve\n reject = _reject\n })\n \n return Object.assign(promise, { resolve, reject })\n } else\n return Object.assign(Promise.resolve(initial), {\n resolve () { },\n reject () { }\n })\n}\n\n\nexport interface LockedAction <TResource, TResult> {\n (resource: TResource): Promise<TResult>\n}\n\n\n/** @example\n let lock = new Lock(redis)\n \n // 锁定资源后在 action 回调中操作资源,回调 promise 完成后自动释放资源,\n // 三秒内未成功独占资源直接抛出 TimeoutError (开始执行后不受 signal abort 影响)\n await lock.request(async (redis) => {\n const value = await redis.get('key')\n await redis.set('key', value * 2)\n }, AbortSignal.timeout(3000)) \n \n 参考:\n https://developer.mozilla.org/en-US/docs/Web/API/Web_Locks_API \n https://github.com/metarhia/web-locks \n https://www.npmjs.com/package/async-lock */\nexport class Lock <TResource = void> {\n /** 如果操作不需要独占资源,可以直接通过 lock.resource 访问,否则需要通过 await lock.request() 独占资源后再访问 */\n resource: TResource\n \n /** 等待链,新的 await lock.request() 调用会等待当前等待链尾部的 promise 完成,并作为新的尾部 */\n ptail = defer<void>(null)\n \n /** 查询当前资源是否属于被锁定的状态,方便在资源闲置时做一些可选操作(操作前仍需锁定),或者做一些状态展示 */\n locked = false\n \n \n /** 可以不传 resource,表示管理某个抽象或虚拟的资源 */\n constructor (resource?: TResource) {\n this.resource = resource\n }\n \n \n /** 通过 await lock.request() 锁定资源以便独占访问\n 成功返回之后由调用方负责调用 release 方法释放资源\n 在 signal aborted 时抛出错误结束等待,且由内部实现自动释放资源 */\n // async request (action: (resource: TResource) => Promise<void>, signal?: AbortSignal): Promise<void>\n // async request <TResult> (action: <TResult> (resource: TResource) => Promise<TResult>, signal?: AbortSignal): Promise<TResult>\n async request <TResult> (action: LockedAction<TResource, TResult>, signal?: AbortSignal): Promise<TResult> {\n signal?.throwIfAborted()\n \n const ptail = this.ptail\n \n let pcurrent = this.ptail = defer<void>()\n \n this.locked = true\n \n return new Promise<TResult>((resolve, reject) => {\n // 下面两种情况,先发生的决定 request 返回的 promise 状态\n // 不管是否 aborted, 都要等资源被前一次调用释放,先 aborted 只是将控制权交回给调用者,在锁定资源后不执行 action, 直接释放\n \n /** 防止执行过程中 signal abort */\n let executing = false\n \n signal?.addEventListener('abort', () => {\n if (!executing)\n // 这里不能释放锁,需要等 ptail resolve 后拿到资源再释放\n reject(signal.reason)\n }, { once: true })\n \n ptail.then(async () => {\n // 这里已经能保证独占访问资源\n \n // 如果 aborted, 可以理解为独占资源失败,调用者不会使用资源,直接释放\n if (signal?.aborted)\n reject(signal.reason)\n else\n // 由调用者去操作资源\n try {\n executing = true\n resolve(await action(this.resource))\n } catch (error) {\n reject(error)\n }\n \n \n // 下面开始释放锁\n \n // assert(this.locked)\n if (!this.locked)\n reject(new Error(t('尝试释放未锁定的锁,这不应该发生')))\n \n this.locked = false\n \n pcurrent.resolve()\n }\n )})\n }\n}\n\n\n// ------------ text\nexport function has_chinese (str: string) {\n return /[\\u4E00-\\u9FA5]/.test(str)\n}\n\n\nexport function escape_line_feed (str: string) {\n return str.replace(/\\n/g, '\\\\n')\n}\n\n/** util.inspect(obj) \n - options\n - limit?: `10000`\n - omit?: string[] */\nexport function inspect (\n obj: any, \n options: util.InspectOptions & {\n limit?: number\n omit?: string[]\n } = { }\n) {\n if (options.omit)\n obj = omit(obj, [inspect.custom, ...(options.omit || [])])\n \n let text = util.inspect(obj, options)\n \n if (!('limit' in options))\n options.limit = 10000\n if (options.limit && text.length > options.limit)\n return `${text.slice(0, options.limit)}……'\\u001b[39m\\n`\n else\n return text\n}\n\nexport namespace inspect {\n export const custom: typeof util.inspect.custom = util.inspect.custom\n}\n\n\n// ------------------------------------ stream\n/** npm map-stream \n filter will reemit the data if cb(err,pass) pass is truthy \n \n reduce is more tricky \n maybe we want to group the reductions or emit progress updates occasionally \n the most basic reduce just emits one 'data' event after it has recieved 'end'\n \n create an event stream and apply function to each .write, \n emitting each response as data unless it's an empty callback\n */\nexport function map_stream <Out, In = Vinyl> (\n mapper: (obj: In, cb: Function) => any, \n options?: { failures?: boolean }\n) {\n options = options || { }\n \n let inputs = 0,\n outputs = 0,\n ended = false,\n paused = false,\n destroyed = false,\n last_written = 0,\n in_next = false\n \n \n let stream = Object.assign(new Stream(), {\n readable: true, \n writable: true,\n \n write (data?: any) {\n if (ended) throw new Error('map stream is not writable')\n in_next = false\n inputs++\n \n try {\n // catch sync errors and handle them like async errors\n const written = wrapped_mapper(data, inputs, next)\n paused = (written === false)\n return !paused\n } catch (err) {\n // if the callback has been called syncronously, and the error has occured in an listener, throw it again.\n if (in_next)\n throw err\n next(err)\n return !paused\n }\n },\n \n end (data?: any) {\n if (ended) return\n _end(data)\n },\n \n destroy () {\n ended = destroyed = true\n stream.writable = stream.readable = paused = false\n process.nextTick(function () {\n stream.emit('close')\n })\n },\n \n pause () {\n paused = true\n },\n \n resume () {\n paused = false\n }\n })\n \n \n let error_event_name = options.failures ? 'failure' : 'error'\n \n // Items that are not ready to be written yet (because they would come out of order) get stuck in a queue for later.\n let write_queue = { }\n \n \n function queue_data (data, number) {\n let next_to_write = last_written + 1\n \n if (number === next_to_write) {\n // If it's next, and its not undefined write it\n if (data !== undefined) \n stream.emit('data', data)\n \n last_written++\n next_to_write++\n } else \n // Otherwise queue it for later.\n write_queue[number] = data\n \n \n // If the next value is in the queue, write it\n if (Object.prototype.hasOwnProperty.call(write_queue, next_to_write)) {\n let data_to_write = write_queue[next_to_write]\n delete write_queue[next_to_write]\n return queue_data(data_to_write, next_to_write)\n }\n \n outputs++\n if (inputs === outputs) {\n if (paused) {\n paused = false\n stream.emit('drain') // written all the incoming events\n }\n if (ended) _end()\n }\n }\n \n function next (err?: Error, data?: any, number?: number) {\n if (destroyed) return\n in_next = true\n \n if (!err || options.failures)\n queue_data(data, number)\n \n if (err)\n stream.emit(error_event_name, err)\n \n in_next = false\n }\n \n /** Wrap the mapper function by calling its callback with the order number of the item in the stream. */ \n function wrapped_mapper (input, number, callback) {\n return mapper.call(null, input, function (err, data) {\n callback(err, data, number)\n })\n }\n \n function _end (data?: any) {\n // if end was called with args, write it, \n ended = true // write will emit 'end' if ended is true\n stream.writable = false\n if (data !== undefined) \n return queue_data(data, inputs)\n else if (inputs === outputs) { // wait for processing \n stream.readable = false\n stream.emit('end')\n stream.destroy() \n }\n }\n \n return stream as Duplex\n}\n\n\nexport async function stream_to_buffer (stream: Readable) {\n let chunks = [ ]\n for await (const chunk of stream as AsyncIterable<Buffer>)\n chunks.push(chunk)\n return Buffer.concat(chunks)\n}\n\n\nexport async function * stream_to_lines (stream: Readable) {\n let buf = ''\n for await (const chunk of stream as AsyncIterable<string>) {\n let i = 0, j = 0\n for (; (i = chunk.indexOf('\\n', j)) >= 0; ) {\n let line = chunk.slice(j, i)\n if (buf) {\n line = buf + line\n buf = ''\n }\n j = i + 1\n yield line\n }\n buf = chunk.slice(j)\n }\n}\n\n\nexport class WritableMemoryStream extends Writable {\n chunks: Buffer[] = [ ]\n \n pbuffer = defer<Buffer>()\n \n \n constructor () {\n super({ highWaterMark: 2 ** 30, decodeStrings: false })\n }\n \n \n override _write (chunk: Buffer, encoding: BufferEncoding, callback: (error?: Error) => void) {\n this.chunks.push(chunk as Buffer)\n callback()\n }\n \n \n override _writev (chunks: { chunk: any; encoding: BufferEncoding }[], callback: (error?: Error) => void): void {\n for (const { chunk } of chunks)\n this.chunks.push(chunk)\n callback()\n }\n \n \n override _final (callback: (error?: Error) => void): void {\n this.pbuffer.resolve(\n Buffer.concat(this.chunks)\n )\n this.chunks = null\n callback()\n }\n}\n\n\n/** 用 TextDecoder 通过 .pipe 方法持续的解码 process.stdout 等流, \n 主要在 process.ts#start 中使用 \n https://nodejs.org/api/stream.html#implementing-a-transform-stream */\nexport class DecoderStream extends Transform {\n decoder: TextDecoder\n \n \n constructor (encoding: 'gb18030' | 'shift-jis' | 'utf-16le') {\n super({ encoding: 'utf-8' })\n this.decoder = new TextDecoder(encoding)\n }\n \n \n override _transform (chunk: Uint8Array, encoding: BufferEncoding, callback: TransformCallback) {\n assert(chunk instanceof Uint8Array)\n \n const str = this.decoder.decode(chunk, { stream: true })\n \n if (str.length)\n this.push(str, 'utf-8')\n \n callback()\n }\n \n \n override _flush (callback: TransformCallback) {\n const str = this.decoder.decode()\n \n if (str.length)\n this.push(str, 'utf-8')\n \n callback()\n }\n}\n"]}