Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/git/src/decorators.ts
5221 views
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
import { done } from './util';
7
8
function decorate(decorator: (fn: Function, key: string) => Function): Function {
9
return (_target: any, key: string, descriptor: PropertyDescriptor): void => {
10
if (typeof descriptor.value === 'function') {
11
descriptor.value = decorator(descriptor.value, key);
12
} else if (typeof descriptor.get === 'function') {
13
descriptor.get = decorator(descriptor.get, key) as () => any;
14
} else {
15
throw new Error('not supported');
16
}
17
};
18
}
19
20
function _memoize(fn: Function, key: string): Function {
21
const memoizeKey = `$memoize$${key}`;
22
23
return function (this: any, ...args: any[]) {
24
if (!this.hasOwnProperty(memoizeKey)) {
25
Object.defineProperty(this, memoizeKey, {
26
configurable: false,
27
enumerable: false,
28
writable: false,
29
value: fn.apply(this, args)
30
});
31
}
32
33
return this[memoizeKey];
34
};
35
}
36
37
export const memoize = decorate(_memoize);
38
39
function _throttle<T>(fn: Function, key: string): Function {
40
const currentKey = `$throttle$current$${key}`;
41
const nextKey = `$throttle$next$${key}`;
42
43
const trigger = function (this: any, ...args: any[]) {
44
if (this[nextKey]) {
45
return this[nextKey];
46
}
47
48
if (this[currentKey]) {
49
this[nextKey] = done(this[currentKey]).then(() => {
50
this[nextKey] = undefined;
51
return trigger.apply(this, args);
52
});
53
54
return this[nextKey];
55
}
56
57
this[currentKey] = fn.apply(this, args) as Promise<T>;
58
59
const clear = () => this[currentKey] = undefined;
60
done(this[currentKey]).then(clear, clear);
61
62
return this[currentKey];
63
};
64
65
return trigger;
66
}
67
68
export const throttle = decorate(_throttle);
69
70
function _sequentialize(fn: Function, key: string): Function {
71
const currentKey = `__$sequence$${key}`;
72
73
return function (this: any, ...args: any[]) {
74
const currentPromise = this[currentKey] as Promise<any> || Promise.resolve(null);
75
const run = async () => await fn.apply(this, args);
76
this[currentKey] = currentPromise.then(run, run);
77
return this[currentKey];
78
};
79
}
80
81
export const sequentialize = decorate(_sequentialize);
82
83
export function debounce(delay: number): Function {
84
return decorate((fn, key) => {
85
const timerKey = `$debounce$${key}`;
86
87
return function (this: any, ...args: any[]) {
88
clearTimeout(this[timerKey]);
89
this[timerKey] = setTimeout(() => fn.apply(this, args), delay);
90
};
91
}) as MethodDecorator;
92
}
93
94