<commit_before>const _defer = <T>(): DeferredPromise<T> => {
    const promise: any = {}
    promise.promise = new Promise<any>((resolve, reject) => {
        promise.resolve = resolve
        promise.reject = reject
    })

    return (promise as DeferredPromise<T>)
}

export interface DeferredPromise<T> {
    resolve: (value: T) => void;
    reject: (error: Error) => void;
    promise: Promise<T>;
}

type PromiseProcessor<T> = (
    resolve: (value: T) => void,
    reject: (error: Error) => void,
    onAbort: (aborter: () => void) => void,
    notifier: (message: any) => void
) => Promise<T>|void

export default class ProgressPromise<T>
{
    static defer<T>()
    {
        const pp: any = {}
        pp.promise = new ProgressPromise((resolve, reject, onAbort, notifier) => {
            pp.resolve = resolve
            pp.reject = reject
            pp.onAbort = onAbort
            pp.notifier = notifier
        })

        return (pp as DeferredPromise<T>)
    }

    private _promise: DeferredPromise<any> = _defer<T>()

    private _abortCallbacks: Function[]|null = []
    private _progressListeners: Function[] = []

    constructor(executor: PromiseProcessor<T>)
    {
        const onAbort = (callback: () => void) => {
            this._abortCallbacks!.push(callback)
        }

        const notifier = (progress: () => void) => {
            this._progressListeners.forEach(listener => listener(progress))
        }

        try {
            const returnValue = executor(this._promise.resolve, this._promise.reject, onAbort, notifier)
            if (returnValue && typeof returnValue.then === 'function') { returnValue.then(this._promise.resolve)}
            if (returnValue && typeof returnValue.catch === 'function') { returnValue.catch(this._promise.reject)}
        } catch (e) {
            this._promise.reject(e)
        }
    }

    then(onFulfilled: (value: any) => void, onFailed: (value: Error) => void): this
    {
        this._promise.promise.then(onFulfilled, onFailed);
        return this
    }

    catch(onFailed: (e: Error) => void): this
    {
        this._promise.promise.catch(onFailed)
        return this
    }

    abort(): this
    {
        if (this._abortCallbacks) {
            this._abortCallbacks.forEach(abort => abort())
            this._abortCallbacks = null
        }
        return this
    }

    progress(listener: (progress: any) => void): this
    {
        this._progressListeners.push(listener)
        return this
    }
}
<commit_msg>Fix two ProgressPromise bugs<commit_after>const _defer = <T>(): DeferredPromise<T> => {
    const promise: any = {}
    promise.promise = new Promise<any>((resolve, reject) => {
        promise.resolve = resolve
        promise.reject = reject
    })

    return (promise as DeferredPromise<T>)
}

export interface DeferredPromise<T> {
    resolve: (value: T) => void;
    reject: (error: Error) => void;
    promise: Promise<T>;
}

type PromiseProcessor<T> = (
    resolve: (value: T) => void,
    reject: (error: Error) => void,
    onAbort: (aborter: () => void) => void,
    notifier: (message: any) => void
) => Promise<T>|void

export default class ProgressPromise<T>
{
    static defer<T>()
    {
        const pp: any = {}
        pp.promise = new ProgressPromise((resolve, reject, onAbort, notifier) => {
            pp.resolve = resolve
            pp.reject = reject
            pp.onAbort = onAbort
            pp.notifier = notifier
        })

        return (pp as DeferredPromise<T>)
    }

    private _promise: DeferredPromise<any> = _defer<T>()

    private _isCompleted: boolean = false
    private _abortCallbacks: Function[]|null = []
    private _progressListeners: Function[] = []

    constructor(executor: PromiseProcessor<T>)
    {
        const onAbort = (callback: () => void) => {
            this._abortCallbacks!.push(callback)
        }

        const notifier = (progress: () => void) => {
            if (this._isCompleted) return
            this._progressListeners.forEach(listener => listener(progress))
        }

        this._promise.promise.then(() => this._isCompleted = true)

        try {
            const returnValue = executor(this._promise.resolve, this._promise.reject, onAbort, notifier)
        } catch (e) {
            this._promise.reject(e)
        }
    }

    then(onFulfilled: (value: any) => void, onFailed: (value: Error) => void): this
    {
        this._promise.promise.then(onFulfilled, onFailed);
        return this
    }

    catch(onFailed: (e: Error) => void): this
    {
        this._promise.promise.catch(onFailed)
        return this
    }

    abort(): this
    {
        if (this._abortCallbacks) {
            this._abortCallbacks.forEach(abort => abort())
            this._abortCallbacks = null
        }
        return this
    }

    progress(listener: (progress: any) => void): this
    {
        this._progressListeners.push(listener)
        return this
    }
}

{'fraction_non_alphanumeric': 0.13236481033091202, 'fraction_numerical': 0.0, 'mean_word_length': 2.3157190635451506, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 74, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '361705', 'n_tokens_mistral': 1488, 'n_tokens_neox': 1488, 'n_words': 325}