@opensumi/ide-utils 2.21.13 → 2.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/arrays.d.ts +3 -3
- package/lib/arrays.d.ts.map +1 -1
- package/lib/arrays.js.map +1 -1
- package/lib/async.d.ts +3 -3
- package/lib/async.d.ts.map +1 -1
- package/lib/buffer.js +4 -4
- package/lib/buffer.js.map +1 -1
- package/lib/character-classifier.js +3 -3
- package/lib/character-classifier.js.map +1 -1
- package/lib/decorators.d.ts +1 -1
- package/lib/decorators.d.ts.map +1 -1
- package/lib/encoding.d.ts +7 -1
- package/lib/encoding.d.ts.map +1 -1
- package/lib/encoding.js +15 -2
- package/lib/encoding.js.map +1 -1
- package/lib/errors.d.ts +2 -2
- package/lib/errors.d.ts.map +1 -1
- package/lib/event.d.ts +2 -2
- package/lib/event.d.ts.map +1 -1
- package/lib/filters.d.ts +3 -3
- package/lib/filters.d.ts.map +1 -1
- package/lib/filters.js +25 -25
- package/lib/filters.js.map +1 -1
- package/lib/glob.d.ts +2 -2
- package/lib/glob.d.ts.map +1 -1
- package/lib/glob.js +1 -1
- package/lib/glob.js.map +1 -1
- package/lib/hash.js +10 -10
- package/lib/hash.js.map +1 -1
- package/lib/iterator.d.ts +1 -1
- package/lib/iterator.d.ts.map +1 -1
- package/lib/linked-text.d.ts +1 -1
- package/lib/linked-text.d.ts.map +1 -1
- package/lib/linked-text.js.map +1 -1
- package/lib/map.js +17 -17
- package/lib/map.js.map +1 -1
- package/lib/objects.d.ts +1 -0
- package/lib/objects.d.ts.map +1 -1
- package/lib/objects.js +38 -1
- package/lib/objects.js.map +1 -1
- package/lib/os.d.ts +1 -8
- package/lib/os.d.ts.map +1 -1
- package/lib/os.js +4 -8
- package/lib/os.js.map +1 -1
- package/lib/path.d.ts +1 -1
- package/lib/path.d.ts.map +1 -1
- package/lib/path.js +29 -29
- package/lib/path.js.map +1 -1
- package/lib/platform.js +8 -8
- package/lib/platform.js.map +1 -1
- package/lib/process.d.ts.map +1 -1
- package/lib/process.js +28 -13
- package/lib/process.js.map +1 -1
- package/lib/progress.js +3 -3
- package/lib/progress.js.map +1 -1
- package/lib/strings.js +9 -9
- package/lib/strings.js.map +1 -1
- package/lib/types.d.ts +5 -1
- package/lib/types.d.ts.map +1 -1
- package/lib/types.js +8 -1
- package/lib/types.js.map +1 -1
- package/lib/uint.js +4 -4
- package/lib/uint.js.map +1 -1
- package/lib/uri.js +8 -8
- package/lib/uri.js.map +1 -1
- package/lib/uuid.d.ts +1 -1
- package/lib/uuid.d.ts.map +1 -1
- package/lib/uuid.js +3 -2
- package/lib/uuid.js.map +1 -1
- package/package.json +8 -6
- package/src/ansi.ts +10 -0
- package/src/argv.ts +57 -0
- package/src/arrays.ts +328 -0
- package/src/async.ts +580 -0
- package/src/buffer.ts +290 -0
- package/src/cache.ts +37 -0
- package/src/cancellation.ts +136 -0
- package/src/charCode.ts +425 -0
- package/src/character-classifier.ts +82 -0
- package/src/const/encoding.ts +242 -0
- package/src/const/index.ts +1 -0
- package/src/date.ts +36 -0
- package/src/decorators.ts +166 -0
- package/src/disposable.ts +377 -0
- package/src/encoding.ts +278 -0
- package/src/errors.ts +192 -0
- package/src/event.ts +1024 -0
- package/src/file-uri.ts +41 -0
- package/src/filters.ts +887 -0
- package/src/functional.ts +43 -0
- package/src/glob.ts +752 -0
- package/src/hash.ts +336 -0
- package/src/iconLabels.ts +149 -0
- package/src/index.ts +40 -0
- package/src/iterator.ts +36 -0
- package/src/lifecycle.ts +48 -0
- package/src/linked-list.ts +144 -0
- package/src/linked-text.ts +55 -0
- package/src/lru-map.ts +133 -0
- package/src/map.ts +934 -0
- package/src/marshalling.ts +62 -0
- package/src/objects.ts +145 -0
- package/src/os.ts +76 -0
- package/src/path.ts +1885 -0
- package/src/platform.ts +194 -0
- package/src/process.ts +43 -0
- package/src/progress.ts +83 -0
- package/src/promises.ts +23 -0
- package/src/sequence.ts +28 -0
- package/src/strings.ts +1002 -0
- package/src/types.ts +214 -0
- package/src/uint.ts +59 -0
- package/src/uri.ts +298 -0
- package/src/uuid.ts +6 -0
package/src/buffer.ts
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
// Some code copied and modified from https://github.com/microsoft/vscode/blob/1.44.0/src/vs/base/common/arrays.ts
|
|
6
|
+
import { toCanonicalName, iconvDecode, UTF8 } from './encoding';
|
|
7
|
+
import * as strings from './strings';
|
|
8
|
+
|
|
9
|
+
let textEncoder: TextEncoder | null;
|
|
10
|
+
|
|
11
|
+
const hasBuffer = typeof Buffer !== 'undefined';
|
|
12
|
+
const hasTextEncoder = typeof TextEncoder !== 'undefined';
|
|
13
|
+
const hasTextDecoder = typeof TextDecoder !== 'undefined';
|
|
14
|
+
|
|
15
|
+
export class BinaryBuffer {
|
|
16
|
+
static alloc(byteLength: number): BinaryBuffer {
|
|
17
|
+
if (hasBuffer) {
|
|
18
|
+
return new BinaryBuffer(Buffer.allocUnsafe(byteLength));
|
|
19
|
+
} else {
|
|
20
|
+
return new BinaryBuffer(new Uint8Array(byteLength));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
static wrap(actual: Uint8Array): BinaryBuffer {
|
|
25
|
+
if (hasBuffer && !Buffer.isBuffer(actual)) {
|
|
26
|
+
// https://nodejs.org/dist/latest-v10.x/docs/api/buffer.html#buffer_class_method_buffer_from_arraybuffer_byteoffset_length
|
|
27
|
+
// Create a zero-copy Buffer wrapper around the ArrayBuffer pointed to by the Uint8Array
|
|
28
|
+
actual = Buffer.from(actual.buffer, actual.byteOffset, actual.byteLength);
|
|
29
|
+
}
|
|
30
|
+
return new BinaryBuffer(actual);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* fromString 产生的 BinaryBuffer 的 encoding 都是 utf8
|
|
35
|
+
* @param source source string
|
|
36
|
+
*/
|
|
37
|
+
static fromString(source: string): BinaryBuffer {
|
|
38
|
+
if (hasBuffer) {
|
|
39
|
+
return new BinaryBuffer(Buffer.from(source));
|
|
40
|
+
} else if (hasTextEncoder) {
|
|
41
|
+
if (!textEncoder) {
|
|
42
|
+
textEncoder = new TextEncoder();
|
|
43
|
+
}
|
|
44
|
+
return new BinaryBuffer(textEncoder.encode(source));
|
|
45
|
+
} else {
|
|
46
|
+
return new BinaryBuffer(strings.encodeUTF8(source));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static concat(buffers: BinaryBuffer[], totalLength?: number): BinaryBuffer {
|
|
51
|
+
if (typeof totalLength === 'undefined') {
|
|
52
|
+
totalLength = 0;
|
|
53
|
+
for (let i = 0, len = buffers.length; i < len; i++) {
|
|
54
|
+
totalLength += buffers[i].byteLength;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const ret = BinaryBuffer.alloc(totalLength);
|
|
59
|
+
let offset = 0;
|
|
60
|
+
for (let i = 0, len = buffers.length; i < len; i++) {
|
|
61
|
+
const element = buffers[i];
|
|
62
|
+
ret.set(element, offset);
|
|
63
|
+
offset += element.byteLength;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return ret;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
readonly buffer: Uint8Array;
|
|
70
|
+
readonly byteLength: number;
|
|
71
|
+
|
|
72
|
+
private constructor(buffer: Uint8Array) {
|
|
73
|
+
this.buffer = buffer;
|
|
74
|
+
this.byteLength = this.buffer.byteLength;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* 将 BinaryBuffer 转为字符串
|
|
79
|
+
* @param encoding 字节编码,不传默认为 utf8。需要传入 `SUPPORTED_ENCODINGS` 已有的键值。
|
|
80
|
+
*/
|
|
81
|
+
toString(encoding?: string): string {
|
|
82
|
+
if (hasBuffer) {
|
|
83
|
+
// 可能原生 toString 比 iconv.decode 要快
|
|
84
|
+
if (encoding === undefined || encoding === 'utf8') {
|
|
85
|
+
return (this.buffer as Buffer).toString();
|
|
86
|
+
}
|
|
87
|
+
return iconvDecode(this.buffer as Buffer, encoding);
|
|
88
|
+
} else if (hasTextDecoder) {
|
|
89
|
+
encoding = toCanonicalName(encoding || UTF8);
|
|
90
|
+
return new TextDecoder(encoding).decode(this.buffer);
|
|
91
|
+
} else {
|
|
92
|
+
return strings.decodeUTF8(this.buffer);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
slice(start?: number, end?: number): BinaryBuffer {
|
|
97
|
+
// IMPORTANT: use subarray instead of slice because TypedArray#slice
|
|
98
|
+
// creates shallow copy and NodeBuffer#slice doesn't. The use of subarray
|
|
99
|
+
// ensures the same, performant, behaviour.
|
|
100
|
+
return new BinaryBuffer(this.buffer.subarray(start! /* bad lib.d.ts*/, end));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
set(array: BinaryBuffer | Uint8Array, offset?: number): void {
|
|
104
|
+
if (array instanceof BinaryBuffer) {
|
|
105
|
+
this.buffer.set(array.buffer, offset);
|
|
106
|
+
} else {
|
|
107
|
+
this.buffer.set(array, offset);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
readUInt32BE(offset: number): number {
|
|
112
|
+
return readUInt32BE(this.buffer, offset);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
writeUInt32BE(value: number, offset: number): void {
|
|
116
|
+
writeUInt32BE(this.buffer, value, offset);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
readUInt32LE(offset: number): number {
|
|
120
|
+
return readUInt32LE(this.buffer, offset);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
writeUInt32LE(value: number, offset: number): void {
|
|
124
|
+
writeUInt32LE(this.buffer, value, offset);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
readUInt8(offset: number): number {
|
|
128
|
+
return readUInt8(this.buffer, offset);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
writeUInt8(value: number, offset: number): void {
|
|
132
|
+
writeUInt8(this.buffer, value, offset);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function readUInt16LE(source: Uint8Array, offset: number): number {
|
|
137
|
+
return ((source[offset + 0] << 0) >>> 0) | ((source[offset + 1] << 8) >>> 0);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function writeUInt16LE(destination: Uint8Array, value: number, offset: number): void {
|
|
141
|
+
destination[offset + 0] = value & 0b11111111;
|
|
142
|
+
value = value >>> 8;
|
|
143
|
+
destination[offset + 1] = value & 0b11111111;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function readUInt32BE(source: Uint8Array, offset: number): number {
|
|
147
|
+
return source[offset] * 2 ** 24 + source[offset + 1] * 2 ** 16 + source[offset + 2] * 2 ** 8 + source[offset + 3];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function writeUInt32BE(destination: Uint8Array, value: number, offset: number): void {
|
|
151
|
+
destination[offset + 3] = value;
|
|
152
|
+
value = value >>> 8;
|
|
153
|
+
destination[offset + 2] = value;
|
|
154
|
+
value = value >>> 8;
|
|
155
|
+
destination[offset + 1] = value;
|
|
156
|
+
value = value >>> 8;
|
|
157
|
+
destination[offset] = value;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export function readUInt32LE(source: Uint8Array, offset: number): number {
|
|
161
|
+
return (
|
|
162
|
+
((source[offset + 0] << 0) >>> 0) |
|
|
163
|
+
((source[offset + 1] << 8) >>> 0) |
|
|
164
|
+
((source[offset + 2] << 16) >>> 0) |
|
|
165
|
+
((source[offset + 3] << 24) >>> 0)
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export function writeUInt32LE(destination: Uint8Array, value: number, offset: number): void {
|
|
170
|
+
destination[offset + 0] = value & 0b11111111;
|
|
171
|
+
value = value >>> 8;
|
|
172
|
+
destination[offset + 1] = value & 0b11111111;
|
|
173
|
+
value = value >>> 8;
|
|
174
|
+
destination[offset + 2] = value & 0b11111111;
|
|
175
|
+
value = value >>> 8;
|
|
176
|
+
destination[offset + 3] = value & 0b11111111;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export function readUInt8(source: Uint8Array, offset: number): number {
|
|
180
|
+
return source[offset];
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export function writeUInt8(destination: Uint8Array, value: number, offset: number): void {
|
|
184
|
+
destination[offset] = value;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** Decodes base64 to a uint8 array. URL-encoded and unpadded base64 is allowed. */
|
|
188
|
+
export function decodeBase64(encoded: string) {
|
|
189
|
+
let building = 0;
|
|
190
|
+
let remainder = 0;
|
|
191
|
+
let bufi = 0;
|
|
192
|
+
|
|
193
|
+
// The simpler way to do this is `Uint8Array.from(atob(str), c => c.charCodeAt(0))`,
|
|
194
|
+
// but that's about 10-20x slower than this function in current Chromium versions.
|
|
195
|
+
|
|
196
|
+
const buffer = new Uint8Array(Math.floor((encoded.length / 4) * 3));
|
|
197
|
+
const append = (value: number) => {
|
|
198
|
+
switch (remainder) {
|
|
199
|
+
case 3:
|
|
200
|
+
buffer[bufi++] = building | value;
|
|
201
|
+
remainder = 0;
|
|
202
|
+
break;
|
|
203
|
+
case 2:
|
|
204
|
+
buffer[bufi++] = building | (value >>> 2);
|
|
205
|
+
building = value << 6;
|
|
206
|
+
remainder = 3;
|
|
207
|
+
break;
|
|
208
|
+
case 1:
|
|
209
|
+
buffer[bufi++] = building | (value >>> 4);
|
|
210
|
+
building = value << 4;
|
|
211
|
+
remainder = 2;
|
|
212
|
+
break;
|
|
213
|
+
default:
|
|
214
|
+
building = value << 2;
|
|
215
|
+
remainder = 1;
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
for (let i = 0; i < encoded.length; i++) {
|
|
220
|
+
const code = encoded.charCodeAt(i);
|
|
221
|
+
// See https://datatracker.ietf.org/doc/html/rfc4648#section-4
|
|
222
|
+
// This branchy code is about 3x faster than an indexOf on a base64 char string.
|
|
223
|
+
if (code >= 65 && code <= 90) {
|
|
224
|
+
append(code - 65); // A-Z starts ranges from char code 65 to 90
|
|
225
|
+
} else if (code >= 97 && code <= 122) {
|
|
226
|
+
append(code - 97 + 26); // a-z starts ranges from char code 97 to 122, starting at byte 26
|
|
227
|
+
} else if (code >= 48 && code <= 57) {
|
|
228
|
+
append(code - 48 + 52); // 0-9 starts ranges from char code 48 to 58, starting at byte 52
|
|
229
|
+
} else if (code === 43 || code === 45) {
|
|
230
|
+
append(62); // "+" or "-" for URLS
|
|
231
|
+
} else if (code === 47 || code === 95) {
|
|
232
|
+
append(63); // "/" or "_" for URLS
|
|
233
|
+
} else if (code === 61) {
|
|
234
|
+
break; // "="
|
|
235
|
+
} else {
|
|
236
|
+
throw new SyntaxError(`Unexpected base64 character ${encoded[i]}`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const unpadded = bufi;
|
|
241
|
+
while (remainder > 0) {
|
|
242
|
+
append(0);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// slice is needed to account for overestimation due to padding
|
|
246
|
+
return BinaryBuffer.wrap(buffer).slice(0, unpadded);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const base64Alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
250
|
+
const base64UrlSafeAlphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
|
|
251
|
+
|
|
252
|
+
/** Encodes a buffer to a base64 string. */
|
|
253
|
+
export function encodeBase64({ buffer }: BinaryBuffer, padded = true, urlSafe = false) {
|
|
254
|
+
const dictionary = urlSafe ? base64UrlSafeAlphabet : base64Alphabet;
|
|
255
|
+
let output = '';
|
|
256
|
+
|
|
257
|
+
const remainder = buffer.byteLength % 3;
|
|
258
|
+
|
|
259
|
+
let i = 0;
|
|
260
|
+
for (; i < buffer.byteLength - remainder; i += 3) {
|
|
261
|
+
const a = buffer[i + 0];
|
|
262
|
+
const b = buffer[i + 1];
|
|
263
|
+
const c = buffer[i + 2];
|
|
264
|
+
|
|
265
|
+
output += dictionary[a >>> 2];
|
|
266
|
+
output += dictionary[((a << 4) | (b >>> 4)) & 0b111111];
|
|
267
|
+
output += dictionary[((b << 2) | (c >>> 6)) & 0b111111];
|
|
268
|
+
output += dictionary[c & 0b111111];
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (remainder === 1) {
|
|
272
|
+
const a = buffer[i + 0];
|
|
273
|
+
output += dictionary[a >>> 2];
|
|
274
|
+
output += dictionary[(a << 4) & 0b111111];
|
|
275
|
+
if (padded) {
|
|
276
|
+
output += '==';
|
|
277
|
+
}
|
|
278
|
+
} else if (remainder === 2) {
|
|
279
|
+
const a = buffer[i + 0];
|
|
280
|
+
const b = buffer[i + 1];
|
|
281
|
+
output += dictionary[a >>> 2];
|
|
282
|
+
output += dictionary[((a << 4) | (b >>> 4)) & 0b111111];
|
|
283
|
+
output += dictionary[(b << 2) & 0b111111];
|
|
284
|
+
if (padded) {
|
|
285
|
+
output += '=';
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return output;
|
|
290
|
+
}
|
package/src/cache.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
|
|
6
|
+
export class Cache<T> {
|
|
7
|
+
private static readonly enableDebugLogging = false;
|
|
8
|
+
|
|
9
|
+
private readonly _data = new Map<number, readonly T[]>();
|
|
10
|
+
private _idPool = 1;
|
|
11
|
+
|
|
12
|
+
constructor(private readonly id: string) {}
|
|
13
|
+
|
|
14
|
+
add(item: readonly T[]): number {
|
|
15
|
+
const id = this._idPool++;
|
|
16
|
+
this._data.set(id, item);
|
|
17
|
+
this.logDebugInfo();
|
|
18
|
+
return id;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
get(pid: number, id: number): T | undefined {
|
|
22
|
+
return this._data.has(pid) ? this._data.get(pid)![id] : undefined;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
delete(id: number) {
|
|
26
|
+
this._data.delete(id);
|
|
27
|
+
this.logDebugInfo();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
private logDebugInfo() {
|
|
31
|
+
if (!Cache.enableDebugLogging) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
// eslint-disable-next-line no-console
|
|
35
|
+
console.log(`${this.id} cache size — ${this._data.size}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
// Some code copied and modified from https://github.com/microsoft/vscode/blob/1.44.0/src/vs/base/common/cancellation.ts
|
|
6
|
+
|
|
7
|
+
import { IDisposable } from './disposable';
|
|
8
|
+
import { Emitter, Event } from './event';
|
|
9
|
+
|
|
10
|
+
export interface CancellationToken {
|
|
11
|
+
readonly isCancellationRequested: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* An event emitted when cancellation is requested
|
|
14
|
+
* @event
|
|
15
|
+
*/
|
|
16
|
+
readonly onCancellationRequested: Event<any>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const shortcutEvent = Object.freeze(function (callback, context?): IDisposable {
|
|
20
|
+
const handle = setTimeout(callback.bind(context), 0);
|
|
21
|
+
return {
|
|
22
|
+
dispose() {
|
|
23
|
+
clearTimeout(handle);
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
} as Event<any>);
|
|
27
|
+
|
|
28
|
+
export namespace CancellationToken {
|
|
29
|
+
export function isCancellationToken(thing: any): thing is CancellationToken {
|
|
30
|
+
if (thing === CancellationToken.None || thing === CancellationToken.Cancelled) {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
if (thing instanceof MutableToken) {
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
if (!thing || typeof thing !== 'object') {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
return (
|
|
40
|
+
typeof (thing as CancellationToken).isCancellationRequested === 'boolean' &&
|
|
41
|
+
typeof (thing as CancellationToken).onCancellationRequested === 'function'
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export const None: CancellationToken = Object.freeze({
|
|
46
|
+
isCancellationRequested: false,
|
|
47
|
+
onCancellationRequested: Event.None,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export const Cancelled: CancellationToken = Object.freeze({
|
|
51
|
+
isCancellationRequested: true,
|
|
52
|
+
onCancellationRequested: shortcutEvent,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
class MutableToken implements CancellationToken {
|
|
57
|
+
private _isCancelled = false;
|
|
58
|
+
private _emitter: Emitter<any> | null = null;
|
|
59
|
+
|
|
60
|
+
public cancel() {
|
|
61
|
+
if (!this._isCancelled) {
|
|
62
|
+
this._isCancelled = true;
|
|
63
|
+
if (this._emitter) {
|
|
64
|
+
this._emitter.fire(undefined);
|
|
65
|
+
this.dispose();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
get isCancellationRequested(): boolean {
|
|
71
|
+
return this._isCancelled;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
get onCancellationRequested(): Event<any> {
|
|
75
|
+
if (this._isCancelled) {
|
|
76
|
+
return shortcutEvent;
|
|
77
|
+
}
|
|
78
|
+
if (!this._emitter) {
|
|
79
|
+
this._emitter = new Emitter<any>();
|
|
80
|
+
}
|
|
81
|
+
return this._emitter.event;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public dispose(): void {
|
|
85
|
+
if (this._emitter) {
|
|
86
|
+
this._emitter.dispose();
|
|
87
|
+
this._emitter = null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export class CancellationTokenSource {
|
|
93
|
+
private _token?: CancellationToken = undefined;
|
|
94
|
+
private _parentListener?: IDisposable = undefined;
|
|
95
|
+
|
|
96
|
+
constructor(parent?: CancellationToken) {
|
|
97
|
+
this._parentListener = parent && parent.onCancellationRequested(this.cancel, this);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
get token(): CancellationToken {
|
|
101
|
+
if (!this._token) {
|
|
102
|
+
// be lazy and create the token only when
|
|
103
|
+
// actually needed
|
|
104
|
+
this._token = new MutableToken();
|
|
105
|
+
}
|
|
106
|
+
return this._token;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
cancel(): void {
|
|
110
|
+
if (!this._token) {
|
|
111
|
+
// save an object by returning the default
|
|
112
|
+
// cancelled token when cancellation happens
|
|
113
|
+
// before someone asks for the token
|
|
114
|
+
this._token = CancellationToken.Cancelled;
|
|
115
|
+
} else if (this._token instanceof MutableToken) {
|
|
116
|
+
// actually cancel
|
|
117
|
+
this._token.cancel();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
dispose(cancel = false): void {
|
|
122
|
+
if (cancel) {
|
|
123
|
+
this.cancel();
|
|
124
|
+
}
|
|
125
|
+
if (this._parentListener) {
|
|
126
|
+
this._parentListener.dispose();
|
|
127
|
+
}
|
|
128
|
+
if (!this._token) {
|
|
129
|
+
// ensure to initialize with an empty token if we had none
|
|
130
|
+
this._token = CancellationToken.None;
|
|
131
|
+
} else if (this._token instanceof MutableToken) {
|
|
132
|
+
// actually dispose
|
|
133
|
+
this._token.dispose();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|