From 74c4851daaec3715a988a54a66e04b2cfb31c649 Mon Sep 17 00:00:00 2001 From: Arseniy Terekhin Date: Wed, 8 May 2024 09:48:52 +0300 Subject: [PATCH] refactor: replace new decorators with old ones unfortunately, no bundler support TS 5.0 decorators, so we can't deploy them --- src/commands.ts | 29 +++++++-- src/decorators.ts | 153 ++++++++++++++++++++++++++++++++++------------ tsconfig.json | 1 + 3 files changed, 139 insertions(+), 44 deletions(-) diff --git a/src/commands.ts b/src/commands.ts index 498a094..58c60a5 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -140,21 +140,38 @@ const enum Inline { Repository = 1, } +// function command(repository?: 1) { +// return ( +// fn: CommandMethod, +// context: ClassMethodDecoratorContext & { +// name: CommandKey; +// } +// ) => { +// if (repository) { +// fn = makeCommandWithRepository(fn); +// } +// register.push({ +// id: `fossil.${context.name as CommandKey}`, +// method: fn, +// }); +// return fn; +// }; +// } + function command(repository?: 1) { return ( - fn: CommandMethod, - context: ClassMethodDecoratorContext & { - name: CommandKey; - } + _target: any, + key: CommandKey, + descriptor: TypedPropertyDescriptor ) => { + let fn = descriptor.value!; if (repository) { fn = makeCommandWithRepository(fn); } register.push({ - id: `fossil.${context.name as CommandKey}`, + id: `fossil.${key}`, method: fn, }); - return fn; }; } diff --git a/src/decorators.ts b/src/decorators.ts index df461bf..747c1c4 100644 --- a/src/decorators.ts +++ b/src/decorators.ts @@ -6,35 +6,86 @@ import { done } from './util'; -export function memoize( - target: (this: Record) => Return, - context: ClassGetterDecoratorContext +// export function memoize( +// target: (this: Record) => Return, +// context: ClassGetterDecoratorContext +// ) { +// const memoizeKey = `$memoize$${context.name as string}`; +// return function (this: Record): Return { +// if (!this[memoizeKey]) { +// this[memoizeKey] = target.apply(this); +// } +// return this[memoizeKey]; +// }; +// } +export function memoize( + target: any, + key: string, + descriptor: PropertyDescriptor ) { - const memoizeKey = `$memoize$${context.name as string}`; - return function (this: Record): Return { + const memoizeKey = `$memoize$${key}`; + const fn = descriptor.get!; + descriptor.get = function (this: Record): Return { if (!this[memoizeKey]) { - this[memoizeKey] = target.apply(this); + this[memoizeKey] = fn.apply(this); } return this[memoizeKey]; }; } + /** * Decorator to not allow multiple async calls */ -export function throttle( - target: ( - this: Record | undefined>, - ...args: Args - ) => Promise, - context: ClassMethodDecoratorContext -) { - const currentKey = `$thr$c$${String(context.name)}`; // $throttle$current$ - const nextKey = `$thr$n$${String(context.name)}`; // $throttle$next$ +// export function throttle( +// target: ( +// this: Record | undefined>, +// ...args: Args +// ) => Promise, +// context: ClassMethodDecoratorContext +// ) { +// const currentKey = `$thr$c$${String(context.name)}`; // $throttle$current$ +// const nextKey = `$thr$n$${String(context.name)}`; // $throttle$next$ + +// const trigger = function ( +// this: Record | undefined>, +// ...args: Args +// ): Promise { +// if (this[nextKey]) { +// return this[nextKey]!; +// } + +// if (this[currentKey]) { +// this[nextKey] = done(this[currentKey]!).then(() => { +// this[nextKey] = undefined; +// return trigger.apply(this, args); +// }); + +// return this[nextKey]!; +// } + +// this[currentKey] = target.apply(this, args); + +// const clear = () => (this[currentKey] = undefined); +// done(this[currentKey]!).then(clear, clear); - const trigger = function ( - this: Record | undefined>, - ...args: Args - ): Promise { +// return this[currentKey]!; +// }; + +// return trigger; +// } +export function throttle( + target: any, + key: string, + descriptor: PropertyDescriptor +): void { + const currentKey = `$thr$c$${key}`; // $throttle$current$ + const nextKey = `$thr$n$${key}`; // $throttle$next$ + const fn = descriptor.value!; + + descriptor.value = function ( + this: Record | undefined>, + ...args: any + ): Promise { if (this[nextKey]) { return this[nextKey]!; } @@ -42,53 +93,79 @@ export function throttle( if (this[currentKey]) { this[nextKey] = done(this[currentKey]!).then(() => { this[nextKey] = undefined; - return trigger.apply(this, args); + return fn.apply(this, args); }); return this[nextKey]!; } - this[currentKey] = target.apply(this, args); + this[currentKey] = fn.apply(this, args); const clear = () => (this[currentKey] = undefined); done(this[currentKey]!).then(clear, clear); return this[currentKey]!; }; - - return trigger; } // Make sure asynchronous functions are called one after another. -type ThisPromise = Record>; +// type ThisPromise = Record>; -export function sequentialize( - target: (this: ThisPromise, ...args: Args) => Promise, - context: ClassMethodDecoratorContext +// export function sequentialize( +// target: (this: ThisPromise, ...args: Args) => Promise, +// context: ClassMethodDecoratorContext +// ) { +// const currentKey = `$s11e$${context.name as string}`; // sequentialize + +// return function (this: ThisPromise, ...args: Args): Promise { +// const currentPromise = +// (this[currentKey] as Promise) || Promise.resolve(null); +// const run = async () => await target.apply(this, args); +// this[currentKey] = currentPromise.then(run, run); +// return this[currentKey]; +// }; +// } + +export function sequentialize( + target: any, + key: string, + descriptor: PropertyDescriptor ) { - const currentKey = `$s11e$${context.name as string}`; // sequentialize + const currentKey = `$s11e$${key}`; // sequentialize + const fn = descriptor.value!; - return function (this: ThisPromise, ...args: Args): Promise { + descriptor.value = function (this: any, ...args: any): Promise { const currentPromise = (this[currentKey] as Promise) || Promise.resolve(null); - const run = async () => await target.apply(this, args); + const run = async () => await fn.apply(this, args); this[currentKey] = currentPromise.then(run, run); return this[currentKey]; }; } -type ThisTimer = Record>; +// type ThisTimer = Record>; + +// export function debounce(delay: number) { +// return function ( +// target: (this: ThisTimer, ...args: Args) => void, +// context: ClassMemberDecoratorContext +// ) { +// const timerKey = `$d6e$${String(context.name)}`; // debounce +// return function (this: ThisTimer, ...args: Args): void { +// clearTimeout(this[timerKey]); +// this[timerKey] = setTimeout(() => target.apply(this, args), delay); +// }; +// }; +// } export function debounce(delay: number) { - return function ( - target: (this: ThisTimer, ...args: Args) => void, - context: ClassMemberDecoratorContext - ) { - const timerKey = `$d6e$${String(context.name)}`; // debounce + return function (target: any, key: string, descriptor: PropertyDescriptor) { + const timerKey = `$d6e$${key}`; // debounce + const fn = descriptor.value!; - return function (this: ThisTimer, ...args: Args): void { + descriptor.value = function (this: any, ...args: any): void { clearTimeout(this[timerKey]); - this[timerKey] = setTimeout(() => target.apply(this, args), delay); + this[timerKey] = setTimeout(() => fn.apply(this, args), delay); }; }; } diff --git a/tsconfig.json b/tsconfig.json index 1b9a210..a310815 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,6 +16,7 @@ "removeComments": true, "sourceMap": true, "strictNullChecks": true, + "experimentalDecorators": true, }, "include": [ "src/**/*",