xshell 1.2.72 → 1.2.74

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,86 +1,3 @@
1
- import { emoji_regex, cjk, to_getter_property_descriptors, to_method_property_descriptors, is_codepoint_fullwidth } from "./prototype.common.js";
1
+ import "./platform.browser.js";
2
2
  export * from "./prototype.common.js";
3
- if (!globalThis.my_prototype_defined) {
4
- // ------------------------------------ String.prototype
5
- Object.defineProperties(String.prototype, {
6
- ...to_getter_property_descriptors({
7
- width() {
8
- const s = this.replace(emoji_regex, ' ');
9
- let width = 0;
10
- for (let i = 0; i < s.length; i++) {
11
- const code = s.codePointAt(i);
12
- if ((code <= 0x1f || (code >= 0x7f && code <= 0x9f)) || // ignore control characters
13
- code >= 0x300 && code <= 0x36f // ignore combining characters
14
- )
15
- continue;
16
- // surrogates
17
- if (code > 0xffff)
18
- i++;
19
- width += is_codepoint_fullwidth(code) ? 2 : 1;
20
- }
21
- return width;
22
- }
23
- }),
24
- // ------------ 文本处理工具方法
25
- ...to_method_property_descriptors({
26
- truncate(width, storage = false) {
27
- if (storage)
28
- return this.length <= width ?
29
- this
30
- :
31
- this.slice(0, width - 2) + '··';
32
- const color_bak = this.startsWith('\u001b') ? this.slice(0, 5) : '';
33
- if (width <= 2)
34
- return this.slice(0, width);
35
- let i_fitted = 0;
36
- let fitted_width = 0;
37
- let cur_width = 0;
38
- for (let i = 0; i < this.length; i++) {
39
- const code = this.codePointAt(i);
40
- if ((code <= 0x1F || (code >= 0x7F && code <= 0x9F)) || // Ignore control characters
41
- code >= 0x300 && code <= 0x36F // Ignore combining characters
42
- )
43
- continue;
44
- // surrogates (codepoint 需要用两个 utf-16 编码单位表示,因此这里跳过第二个编码单位,防止重复计算显示宽度)
45
- if (code > 0xFFFF)
46
- i++;
47
- const w = is_codepoint_fullwidth(code) ? 2 : 1;
48
- if (cur_width + w + 2 <= width) {
49
- i_fitted = i;
50
- fitted_width += w;
51
- }
52
- cur_width += w;
53
- if (cur_width > width) {
54
- const i_fitted_next = i_fitted + 1;
55
- const t = this.slice(0, i_fitted_next) + ' '.repeat(width - 2 - fitted_width) + '··';
56
- return color_bak ? color_bak + t + '\u001b[39m' : t;
57
- }
58
- }
59
- return this;
60
- },
61
- space() {
62
- if (!this)
63
- return this;
64
- let text_;
65
- text_ = this
66
- .replace(new RegExp(cjk + '([\'"])', 'g'), '$1 $2')
67
- .replace(new RegExp('([\'"])' + cjk, 'g'), '$1 $2')
68
- .replace(/(["']+)\s*(.+?)\s*(["']+)/g, '$1$2$3')
69
- .replace(new RegExp(cjk + '([\\+\\-\\*\\/=&\\\\\\|<>])([A-Za-z0-9])', 'g'), '$1 $2 $3')
70
- .replace(new RegExp('([A-Za-z0-9])([\\+\\-\\*\\/=&\\\\\\|<>])' + cjk, 'g'), '$1 $2 $3');
71
- const text_bak = text_;
72
- text_ = text_.replace(new RegExp(cjk + '([\\(\\[\\{<\u201c]+(.*?)[\\)\\]\\}>\u201d]+)' + cjk, 'g'), '$1 $2 $4');
73
- if (text_ === text_bak)
74
- text_ = text_
75
- .replace(new RegExp(cjk + '([\\(\\[\\{<\u201c>])', 'g'), '$1 $2')
76
- .replace(new RegExp('([\\)\\]\\}>\u201d<])' + cjk, 'g'), '$1 $2');
77
- return text_
78
- .replace(/([\(\[\{<\u201c]+)(\s*)(.+?)(\s*)([\)\]\}>\u201d]+)/g, '$1$3$5')
79
- .replace(new RegExp(cjk + '([~!;:,\\.\\?\u2026])([A-Za-z0-9])', 'g'), '$1$2 $3')
80
- .replace(new RegExp(cjk + '([A-Za-z0-9`\\$%\\^&\\*\\-=\\+\\\\\\|\\/@\u00a1-\u00ff\u2022\u2027\u2150-\u218f])', 'g'), '$1 $2')
81
- .replace(new RegExp('([A-Za-z0-9`\\$%\\^&\\*\\-=\\+\\\\\\|\\/@\u00a1-\u00ff\u2022\u2027\u2150-\u218f])' + cjk, 'g'), '$1 $2');
82
- }
83
- })
84
- });
85
- }
86
3
  //# sourceMappingURL=prototype.browser.js.map
@@ -228,6 +228,7 @@ export declare const select: <TObj = any, TKey extends keyof TObj = keyof TObj>(
228
228
  export type Mapper<TObj = any, TKey extends keyof TObj = keyof TObj> = (obj: TObj) => TObj[TKey];
229
229
  /** value 不为 null 或 undefined */
230
230
  export declare const not_empty: (value: any) => boolean;
231
+ /** value 为 null 或 undefined */
231
232
  export declare const empty: (value: any) => boolean;
232
233
  export declare const is_key_type: IsKeyType;
233
234
  type IsKeyType = (key: any) => key is string | number | symbol;
@@ -1,11 +1,13 @@
1
1
  import EmojiRegex from 'emoji-regex';
2
2
  import { t } from "./i18n/instance.js";
3
3
  export const emoji_regex = EmojiRegex();
4
+ import { platform } from "./platform.common.js";
4
5
  export const noop = () => { };
5
6
  export const ident = (x) => x;
6
7
  export const select = (key) => (obj) => obj[key];
7
8
  /** value 不为 null 或 undefined */
8
9
  export const not_empty = (value) => value !== null && value !== undefined;
10
+ /** value 为 null 或 undefined */
9
11
  export const empty = (value) => value === undefined || value === null;
10
12
  const key_types = ['string', 'number', 'symbol'];
11
13
  export const is_key_type = ((key) => key_types.includes(typeof key));
@@ -57,10 +59,104 @@ export const brackets = {
57
59
  tortoise_shell: ['〔', '〕'],
58
60
  };
59
61
  if (!globalThis.my_prototype_defined) {
60
- // ------------------------------------ String.prototype
61
62
  Object.defineProperties(String.prototype, {
63
+ ...to_getter_property_descriptors({
64
+ width() {
65
+ const s = platform.strip_ansi(this.replace(emoji_regex, ' '));
66
+ let width = 0;
67
+ for (let i = 0; i < s.length; ++i) {
68
+ const code = s.codePointAt(i);
69
+ if ((code <= 0x1f || (code >= 0x7f && code <= 0x9f)) || // ignore control characters
70
+ code >= 0x300 && code <= 0x36f // ignore combining characters
71
+ )
72
+ continue;
73
+ // surrogates
74
+ if (code > 0xffff)
75
+ ++i;
76
+ width += is_codepoint_fullwidth(code) ? 2 : 1;
77
+ }
78
+ return width;
79
+ },
80
+ // ------------ 文件路径操作
81
+ isdir() {
82
+ return this.endsWith('/');
83
+ },
84
+ fp() {
85
+ if (!this)
86
+ return this;
87
+ const fp = this.replaceAll('\\', '/');
88
+ // 转换小写盘符开头的路径
89
+ return fp[1] === ':' && 'a' <= fp[0] && fp[0] <= 'z'
90
+ ? fp[0].toUpperCase() + fp.slice(1)
91
+ : fp;
92
+ },
93
+ fpd() {
94
+ const { fp } = this;
95
+ return fp.endsWith('/') ? fp : `${fp}/`;
96
+ },
97
+ fdir() {
98
+ return this.fp.strip_end(this.fname);
99
+ },
100
+ fname() {
101
+ const { fp } = this;
102
+ const ilast = fp.lastIndexOf('/');
103
+ if (ilast === -1)
104
+ return fp; // 没有斜杠时返回整个字符串
105
+ // 以斜杠结尾的情况
106
+ if (ilast === fp.length - 1) {
107
+ const iprev = fp.lastIndexOf('/', ilast - 1);
108
+ return iprev === -1
109
+ ? fp // 只有一个斜杠且在末尾
110
+ : fp.slice(iprev + 1);
111
+ }
112
+ // 返回最后一个斜杠后的内容
113
+ return fp.slice(ilast + 1);
114
+ },
115
+ fext() {
116
+ const { fname } = this;
117
+ const index = fname.lastIndexOf('.');
118
+ return index <= 0 ? '' : fname.slice(index + 1);
119
+ }
120
+ }),
62
121
  // ------------ 文本处理工具方法
63
122
  ...to_method_property_descriptors({
123
+ truncate(width, storage = false) {
124
+ if (storage)
125
+ return this.length <= width ?
126
+ this
127
+ :
128
+ this.slice(0, width - 2) + '··';
129
+ const color_bak = this.startsWith('\u001b') ? this.slice(0, 5) : '';
130
+ const s = platform.strip_ansi(this);
131
+ if (width <= 2)
132
+ return this.slice(0, width);
133
+ let i_fitted = 0;
134
+ let fitted_width = 0;
135
+ let cur_width = 0;
136
+ for (let i = 0; i < s.length; i++) {
137
+ const code = s.codePointAt(i);
138
+ if ((code <= 0x1F || (code >= 0x7F && code <= 0x9F)) || // Ignore control characters
139
+ code >= 0x300 && code <= 0x36F // Ignore combining characters
140
+ )
141
+ continue;
142
+ // surrogates (codepoint 需要用两个 utf-16 编码单位表示,因此这里跳过第二个编码单位,防止重复计算显示宽度)
143
+ if (code > 0xFFFF)
144
+ i++;
145
+ const w = is_codepoint_fullwidth(code) ? 2 : 1;
146
+ if (cur_width + w + 2 <= width) {
147
+ i_fitted = i;
148
+ fitted_width += w;
149
+ }
150
+ cur_width += w;
151
+ if (cur_width > width) {
152
+ const i_fitted_next = i_fitted + 1;
153
+ // … 在 winterm 中对不齐,使用 ·· 代替
154
+ const t = s.slice(0, i_fitted_next) + ' '.repeat(width - 2 - fitted_width) + '··';
155
+ return color_bak ? color_bak + t + '\u001b[39m' : t;
156
+ }
157
+ }
158
+ return this;
159
+ },
64
160
  pad(width, { character = ' ', position = 'right' } = {}) {
65
161
  const _width = this.width;
66
162
  if (_width >= width)
@@ -284,53 +380,44 @@ if (!globalThis.my_prototype_defined) {
284
380
  else
285
381
  return this.slice(0, include ? i + search.length : i);
286
382
  },
287
- }),
288
- // ------------ 文件路径操作
289
- ...to_getter_property_descriptors({
290
- isdir() {
291
- return this.endsWith('/');
292
- },
293
- fp() {
383
+ space() {
294
384
  if (!this)
295
385
  return this;
296
- const fp = this.replaceAll('\\', '/');
297
- // 转换小写盘符开头的路径
298
- return fp[1] === ':' && 'a' <= fp[0] && fp[0] <= 'z'
299
- ? fp[0].toUpperCase() + fp.slice(1)
300
- : fp;
301
- },
302
- fpd() {
303
- const { fp } = this;
304
- return fp.endsWith('/') ? fp : `${fp}/`;
305
- },
306
- fdir() {
307
- return this.fp.strip_end(this.fname);
308
- },
309
- fname() {
310
- const { fp } = this;
311
- const ilast = fp.lastIndexOf('/');
312
- if (ilast === -1)
313
- return fp; // 没有斜杠时返回整个字符串
314
- // 以斜杠结尾的情况
315
- if (ilast === fp.length - 1) {
316
- const iprev = fp.lastIndexOf('/', ilast - 1);
317
- return iprev === -1
318
- ? fp // 只有一个斜杠且在末尾
319
- : fp.slice(iprev + 1);
320
- }
321
- // 返回最后一个斜杠后的内容
322
- return fp.slice(ilast + 1);
323
- },
324
- fext() {
325
- const { fname } = this;
326
- const index = fname.lastIndexOf('.');
327
- return index <= 0
328
- ? ''
329
- : fname.slice(index + 1);
386
+ let text_;
387
+ text_ = this
388
+ .replace(space_patterns[0], '$1 $2')
389
+ .replace(space_patterns[1], '$1 $2')
390
+ .replace(space_patterns[2], '$1$2$3')
391
+ .replace(space_patterns[3], '$1 $2 $3')
392
+ .replace(space_patterns[4], '$1 $2 $3');
393
+ const text_bak = text_;
394
+ text_ = text_.replace(space_patterns[5], '$1 $2 $4');
395
+ if (text_ === text_bak)
396
+ text_ = text_
397
+ .replace(space_patterns[6], '$1 $2')
398
+ .replace(space_patterns[7], '$1 $2');
399
+ return text_
400
+ .replace(space_patterns[8], '$1$3$5')
401
+ .replace(space_patterns[9], '$1$2 $3')
402
+ .replace(space_patterns[10], '$1 $2')
403
+ .replace(space_patterns[11], '$1 $2');
330
404
  }
331
405
  })
332
406
  });
333
- // ------------------------------------ Date.prototype
407
+ const space_patterns = [
408
+ new RegExp(cjk + '([\'"])', 'g'),
409
+ new RegExp('([\'"])' + cjk, 'g'),
410
+ /(["']+)\s*(.+?)\s*(["']+)/g,
411
+ new RegExp(cjk + '([\\+\\-\\*\\/=&\\\\\\|<>])([A-Za-z0-9])', 'g'),
412
+ new RegExp('([A-Za-z0-9])([\\+\\-\\*\\/=&\\\\\\|<>])' + cjk, 'g'),
413
+ new RegExp(cjk + '([\\(\\[\\{<\u201c]+(.*?)[\\)\\]\\}>\u201d]+)' + cjk, 'g'),
414
+ new RegExp(cjk + '([\\(\\[\\{<\u201c>])', 'g'),
415
+ new RegExp('([\\)\\]\\}>\u201d<])' + cjk, 'g'),
416
+ /([\(\[\{<\u201c]+)(\s*)(.+?)(\s*)([\)\]\}>\u201d]+)/g,
417
+ new RegExp(cjk + '([~!;:,\\.\\?\u2026])([A-Za-z0-9])', 'g'),
418
+ new RegExp(cjk + '([A-Za-z0-9`\\$%\\^&\\*\\-=\\+\\\\\\|\\/@\u00a1-\u00ff\u2022\u2027\u2150-\u218f])', 'g'),
419
+ new RegExp('([A-Za-z0-9`\\$%\\^&\\*\\-=\\+\\\\\\|\\/@\u00a1-\u00ff\u2022\u2027\u2150-\u218f])' + cjk, 'g')
420
+ ];
334
421
  Object.defineProperties(Date.prototype, to_method_property_descriptors({
335
422
  to_str(ms) {
336
423
  return `${this.to_date_str()} ${this.to_time_str(ms)}`;
@@ -388,7 +475,6 @@ if (!globalThis.my_prototype_defined) {
388
475
  ? '.' + String(date.getMilliseconds()).padStart(3, '0')
389
476
  : '');
390
477
  }
391
- // ------------------------------------ Number.prototype
392
478
  Object.defineProperties(Number.prototype, to_method_property_descriptors({
393
479
  to_fsize_str() {
394
480
  return byte_size(this);
@@ -407,14 +493,12 @@ if (!globalThis.my_prototype_defined) {
407
493
  return `0o${this.toString(8)}`;
408
494
  },
409
495
  }));
410
- // ------------------------------------ Array.prototype
411
496
  Object.defineProperties(Array.prototype, {
412
497
  ...to_getter_property_descriptors({
413
498
  last() {
414
499
  return this.at(-1);
415
500
  }
416
501
  }),
417
- // --- 文本处理工具方法
418
502
  ...to_method_property_descriptors({
419
503
  trim_lines({ trim_line = true, rm_empty_lines = true, rm_last_empty_lines = false } = {}) {
420
504
  if (!this.length)
package/prototype.js CHANGED
@@ -1,67 +1,10 @@
1
1
  import util from 'util';
2
- import strip_ansi from 'strip-ansi';
3
- import { to_getter_property_descriptors, to_method_property_descriptors, cjk, is_codepoint_fullwidth, emoji_regex } from "./prototype.common.js";
2
+ import { platform } from "./platform.js";
3
+ import { to_method_property_descriptors } from "./prototype.common.js";
4
4
  export * from "./prototype.common.js";
5
5
  if (!globalThis.my_prototype_defined) {
6
- // ------------------------------------ String.prototype
7
6
  Object.defineProperties(String.prototype, {
8
- ...to_getter_property_descriptors({
9
- width() {
10
- const s = strip_ansi(this.replace(emoji_regex, ' '));
11
- let width = 0;
12
- for (let i = 0; i < s.length; i++) {
13
- const code = s.codePointAt(i);
14
- if ((code <= 0x1f || (code >= 0x7f && code <= 0x9f)) || // ignore control characters
15
- code >= 0x300 && code <= 0x36f // ignore combining characters
16
- )
17
- continue;
18
- // surrogates
19
- if (code > 0xffff)
20
- i++;
21
- width += is_codepoint_fullwidth(code) ? 2 : 1;
22
- }
23
- return width;
24
- }
25
- }),
26
- // ------------ 文本处理工具方法
27
7
  ...to_method_property_descriptors({
28
- truncate(width, storage = false) {
29
- if (storage)
30
- return this.length <= width ?
31
- this
32
- :
33
- this.slice(0, width - 2) + '··';
34
- const color_bak = this.startsWith('\u001b') ? this.slice(0, 5) : '';
35
- const s = strip_ansi(this);
36
- if (width <= 2)
37
- return this.slice(0, width);
38
- let i_fitted = 0;
39
- let fitted_width = 0;
40
- let cur_width = 0;
41
- for (let i = 0; i < s.length; i++) {
42
- const code = s.codePointAt(i);
43
- if ((code <= 0x1F || (code >= 0x7F && code <= 0x9F)) || // Ignore control characters
44
- code >= 0x300 && code <= 0x36F // Ignore combining characters
45
- )
46
- continue;
47
- // surrogates (codepoint 需要用两个 utf-16 编码单位表示,因此这里跳过第二个编码单位,防止重复计算显示宽度)
48
- if (code > 0xFFFF)
49
- i++;
50
- const w = is_codepoint_fullwidth(code) ? 2 : 1;
51
- if (cur_width + w + 2 <= width) {
52
- i_fitted = i;
53
- fitted_width += w;
54
- }
55
- cur_width += w;
56
- if (cur_width > width) {
57
- const i_fitted_next = i_fitted + 1;
58
- // … 在 winterm 中对不齐,使用 ·· 代替
59
- const t = s.slice(0, i_fitted_next) + ' '.repeat(width - 2 - fitted_width) + '··';
60
- return color_bak ? color_bak + t + '\u001b[39m' : t;
61
- }
62
- }
63
- return this;
64
- },
65
8
  quote_if_space(type = 'single') {
66
9
  return this.includes(' ') ? this.quote(type) : this;
67
10
  },
@@ -78,32 +21,10 @@ if (!globalThis.my_prototype_defined) {
78
21
  return buf.toString();
79
22
  },
80
23
  strip_ansi() {
81
- return strip_ansi(this);
24
+ return platform.strip_ansi(this);
82
25
  },
83
26
  to_backslash() {
84
27
  return this.replaceAll('/', '\\');
85
- },
86
- space() {
87
- if (!this)
88
- return this;
89
- let text_;
90
- text_ = this
91
- .replace(new RegExp(cjk + '([\'"])', 'g'), '$1 $2')
92
- .replace(new RegExp('([\'"])' + cjk, 'g'), '$1 $2')
93
- .replace(/(["']+)\s*(.+?)\s*(["']+)/g, '$1$2$3')
94
- .replace(new RegExp(cjk + '([\\+\\-\\*\\/=&\\\\\\|<>])([A-Za-z0-9])', 'g'), '$1 $2 $3')
95
- .replace(new RegExp('([A-Za-z0-9])([\\+\\-\\*\\/=&\\\\\\|<>])' + cjk, 'g'), '$1 $2 $3');
96
- const text_bak = text_;
97
- text_ = text_.replace(new RegExp(cjk + '([\\(\\[\\{<\u201c]+(.*?)[\\)\\]\\}>\u201d]+)' + cjk, 'g'), '$1 $2 $4');
98
- if (text_ === text_bak)
99
- text_ = text_
100
- .replace(new RegExp(cjk + '([\\(\\[\\{<\u201c>])', 'g'), '$1 $2')
101
- .replace(new RegExp('([\\)\\]\\}>\u201d<])' + cjk, 'g'), '$1 $2');
102
- return text_
103
- .replace(/([\(\[\{<\u201c]+)(\s*)(.+?)(\s*)([\)\]\}>\u201d]+)/g, '$1$3$5')
104
- .replace(new RegExp(cjk + '([~!;:,\\.\\?\u2026])([A-Za-z0-9])', 'g'), '$1$2 $3')
105
- .replace(new RegExp(cjk + '([A-Za-z0-9`\\$%\\^&\\*\\-=\\+\\\\\\|\\/@\u00a1-\u00ff\u2022\u2027\u2150-\u218f])', 'g'), '$1 $2')
106
- .replace(new RegExp('([A-Za-z0-9`\\$%\\^&\\*\\-=\\+\\\\\\|\\/@\u00a1-\u00ff\u2022\u2027\u2150-\u218f])' + cjk, 'g'), '$1 $2');
107
28
  }
108
29
  }),
109
30
  // ------------ colors
@@ -127,35 +48,31 @@ if (!globalThis.my_prototype_defined) {
127
48
  }];
128
49
  }))
129
50
  });
130
- // ------------------------------------ Array.prototype
131
- Object.defineProperties(Array.prototype, {
132
- // --- 文本处理工具方法
133
- ...to_method_property_descriptors({
134
- log(limit = 10000) {
135
- const text = this.join('\n') + '\n';
136
- if (limit === -1 || this.length <= limit)
137
- console.log(text);
138
- else if (limit > 0)
139
- console.log(text.slice(0, limit) + '\n...'.blue);
140
- else
141
- console.log('...\n'.blue + text.slice(limit));
142
- },
143
- trim_license() {
144
- const i = this.indexOf('/*');
145
- const j = this.indexOf('*/');
146
- if (i === 0 && this[i + 1].includes('License'))
147
- return this.slice(j + 1);
148
- else
149
- return this;
150
- },
151
- split_indents() {
152
- return this.map(line => line.split_indent());
153
- },
154
- indent2to4() {
155
- return this.split_indents()
156
- .map(line => ' '.repeat(line.indent * 2) + line.text);
157
- },
158
- })
159
- });
51
+ Object.defineProperties(Array.prototype, to_method_property_descriptors({
52
+ log(limit = 10000) {
53
+ const text = this.join('\n') + '\n';
54
+ if (limit === -1 || this.length <= limit)
55
+ console.log(text);
56
+ else if (limit > 0)
57
+ console.log(text.slice(0, limit) + '\n...'.blue);
58
+ else
59
+ console.log('...\n'.blue + text.slice(limit));
60
+ },
61
+ trim_license() {
62
+ const i = this.indexOf('/*');
63
+ const j = this.indexOf('*/');
64
+ if (i === 0 && this[i + 1].includes('License'))
65
+ return this.slice(j + 1);
66
+ else
67
+ return this;
68
+ },
69
+ split_indents() {
70
+ return this.map(line => line.split_indent());
71
+ },
72
+ indent2to4() {
73
+ return this.split_indents()
74
+ .map(line => ' '.repeat(line.indent * 2) + line.text);
75
+ }
76
+ }));
160
77
  }
161
78
  //# sourceMappingURL=prototype.js.map
@@ -1,25 +1,4 @@
1
1
  import './prototype.browser.ts';
2
+ import './platform.browser.ts';
2
3
  export * from './utils.common.ts';
3
- export declare function delay(milliseconds: number, { signal }?: {
4
- signal?: AbortSignal;
5
- }): Promise<void>;
6
- /** 在指定的时间 (milliseconds) 内运行某个任务,超时之后抛出错误或调用 on_timeout
7
- - milliseconds: 限时毫秒数
8
- - action?: 要等待运行的任务, async function 或 promise
9
- - on_timeout?: 超时后调用的函数
10
- - 如果传入了 on_timeout 参数: 调用 on_timeout,然后 timeout 函数正常返回 null
11
- - 如果没传入 on_timeout 参数: 抛出 TimeoutError
12
- - print?: 打印已超时任务的错误 */
13
- export declare function timeout<TReturn>(milliseconds: number, action: Promise<TReturn> | (() => Promise<TReturn>), on_timeout?: () => void | Promise<void>, print?: boolean): Promise<TReturn>;
14
4
  export declare function pause(milliseconds?: number): Promise<void>;
15
- /** 将字符串简单的编码为 utf-8 的 buffer (Uint8Array)。高频使用或者在流式处理时,考虑使用 TextEncoder 的 encodeInto 方法 */
16
- export declare function encode(str: string): Uint8Array<ArrayBuffer>;
17
- /** 拼接 TypedArrays 生成一个完整的 Uint8Array */
18
- export declare function concat(arrays: ArrayBufferView[]): Uint8Array<ArrayBuffer>;
19
- /** 轮询尝试 action 共 times 次,每次间隔 duration
20
- action 返回 trusy 值时认为成功,返回 action 的结果
21
- 如果次数用尽仍然失败,返回 null */
22
- export declare function poll<TResult>(duration: number, times: number, action: (breaker: () => void) => Promise<TResult>): Promise<TResult>;
23
- /** 比较两个 buffer 内容是否相同,第二个可以传入 string 自动编码转换后比较,
24
- 高频调用时建议提前编码 right 并缓存 */
25
- export declare function buffer_equals(left: Uint8Array, right: Uint8Array | string): boolean;
package/utils.browser.js CHANGED
@@ -1,124 +1,10 @@
1
1
  import "./prototype.browser.js";
2
- import { encoder, TimeoutError } from "./utils.common.js";
2
+ import "./platform.browser.js";
3
+ import { delay } from "./utils.common.js";
3
4
  export * from "./utils.common.js";
4
- export async function delay(milliseconds, { signal } = {}) {
5
- signal?.throwIfAborted();
6
- return new Promise((resolve, reject) => {
7
- function on_signal_abort() {
8
- clearTimeout(timeout);
9
- reject(signal.reason);
10
- }
11
- signal?.addEventListener('abort', on_signal_abort);
12
- let timeout = setTimeout(() => {
13
- signal?.removeEventListener('abort', on_signal_abort);
14
- resolve();
15
- }, milliseconds);
16
- });
17
- }
18
- /** 在指定的时间 (milliseconds) 内运行某个任务,超时之后抛出错误或调用 on_timeout
19
- - milliseconds: 限时毫秒数
20
- - action?: 要等待运行的任务, async function 或 promise
21
- - on_timeout?: 超时后调用的函数
22
- - 如果传入了 on_timeout 参数: 调用 on_timeout,然后 timeout 函数正常返回 null
23
- - 如果没传入 on_timeout 参数: 抛出 TimeoutError
24
- - print?: 打印已超时任务的错误 */
25
- export async function timeout(milliseconds, action, on_timeout, print = true) {
26
- const error = new TimeoutError();
27
- return new Promise((resolve, reject) => {
28
- let done = false;
29
- let rejected = false;
30
- (async () => {
31
- await delay(milliseconds);
32
- if (!done)
33
- if (on_timeout)
34
- try {
35
- await on_timeout();
36
- resolve(null);
37
- }
38
- catch (error) {
39
- if (rejected)
40
- throw error; // 会成为 unhandled rejection
41
- else {
42
- rejected = true;
43
- reject(error);
44
- }
45
- }
46
- else {
47
- rejected = true;
48
- reject(error);
49
- }
50
- })();
51
- (async () => {
52
- try {
53
- resolve(await (typeof action === 'function' ? action() : action));
54
- }
55
- catch (error) {
56
- if (rejected) {
57
- if (print)
58
- console.log(`已超时任务的错误: ${error.message}`);
59
- }
60
- else {
61
- rejected = true;
62
- reject(error);
63
- }
64
- }
65
- finally {
66
- done = true;
67
- }
68
- })();
69
- });
70
- }
71
5
  export async function pause(milliseconds = 3000) {
72
6
  await delay(milliseconds);
73
7
  debugger;
74
8
  }
75
9
  globalThis.pause = pause;
76
- /** 将字符串简单的编码为 utf-8 的 buffer (Uint8Array)。高频使用或者在流式处理时,考虑使用 TextEncoder 的 encodeInto 方法 */
77
- export function encode(str) {
78
- return encoder.encode(str);
79
- }
80
- /** 拼接 TypedArrays 生成一个完整的 Uint8Array */
81
- export function concat(arrays) {
82
- let length = 0;
83
- for (const a of arrays)
84
- length += a.byteLength;
85
- let buf = new Uint8Array(length);
86
- let offset = 0;
87
- for (const a of arrays) {
88
- const uint8view = new Uint8Array(a.buffer, a.byteOffset, a.byteLength);
89
- buf.set(uint8view, offset);
90
- offset += uint8view.byteLength;
91
- }
92
- return buf;
93
- }
94
- /** 轮询尝试 action 共 times 次,每次间隔 duration
95
- action 返回 trusy 值时认为成功,返回 action 的结果
96
- 如果次数用尽仍然失败,返回 null */
97
- export async function poll(duration, times, action) {
98
- let break_flag = false;
99
- function _break() {
100
- break_flag = true;
101
- }
102
- for (let i = 0; i < times; ++i) {
103
- const result = await action(_break);
104
- if (result)
105
- return result;
106
- if (break_flag)
107
- break;
108
- await delay(duration);
109
- }
110
- return null;
111
- }
112
- /** 比较两个 buffer 内容是否相同,第二个可以传入 string 自动编码转换后比较,
113
- 高频调用时建议提前编码 right 并缓存 */
114
- export function buffer_equals(left, right) {
115
- if (typeof right === 'string')
116
- right = encode(right);
117
- if (left.length !== right.length)
118
- return false;
119
- for (let i = 0; i < left.length; i++)
120
- if (left[i] !== right[i])
121
- return false;
122
- return true;
123
- }
124
10
  //# sourceMappingURL=utils.browser.js.map