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