<commit_before>/**
 * Solution based on:
 * @link https://github.com/redux-loop/redux-loop
 */
import React from 'react';

import {
    Cmd
} from 'Platform/Cmd';
import {
    Sub
} from 'Platform/Sub';

export interface Subscriber<Msg, T = any> {
    namespace: string;
    key: string;
    tagger(config: T): Msg;
    executor(callback: (config: T) => void): () => void;
}

interface Process<Msg, T = any> {
    mailbox: Array<(config: T) => Msg>;
    kill(): void;
}

abstract class InternalCmd<Msg> extends Cmd<Msg> {
    public static execute<Msg>(cmd: Cmd<Msg>): Array<Promise<Msg>> {
        return super.execute(cmd);
    }
}

abstract class InternalSub<Msg> extends Sub<Msg> {
    public static configure<Msg>(sub: Sub<Msg>): Array<Subscriber<Msg>> {
        return super.configure(sub);
    }
}

export type Dispatch<Msg> = (msg: Msg) => void;

export interface Configuration<Msg, Model> {
    view: React.StatelessComponent<{
        dispatch: Dispatch<Msg>;
        model: Model;
    }>;
    init(): [ Model, Cmd<Msg> ];
    update(msg: Msg, model: Model): [ Model, Cmd<Msg> ];
    subscriptions(model: Model): Sub<Msg>;
}

export class Application<Msg, Model> extends React.Component<Configuration<Msg, Model>, Model> {
    private readonly processes: Map<string, Map<string, Process<Msg>>> = new Map();

    constructor(props: Configuration<Msg, Model>, context: any) {
        super(props, context);

        const [ initialModel, initialCmd ] = props.init();

        this.state = initialModel;

        this.handleCmd(initialCmd);
    }

    public render() {
        return React.createElement(
            this.props.view,
            {
                model: this.state,
                dispatch: (msg: Msg): void => {
                    this.dispatch(msg);
                }
            }
        );
    }

    private handleCmd(cmd: Cmd<Msg>): Promise<Array<Msg>> {
        const promises: Array<Promise<Msg>> = InternalCmd.execute(cmd);
        const result: Array<Promise<Array<Msg>>> = [];

        for (const promise of promises) {
            result.push(promise.then(this.dispatch));
        }

        return Promise.all(result).then((arrayOfArrays: Array<Array<Msg>>): Array<Msg> => {
            const result: Array<Msg> = [];

            for (const arrayOfMsgs of arrayOfArrays) {
                result.push(...arrayOfMsgs);
            }

            return result;
        });
    }

    private applyChanges(nextModel: Model, cmd: Cmd<Msg>): Promise<Array<Msg>> {
        if (this.state !== nextModel) {
            this.setState(nextModel);
        }

        this.manageSubscribers(
            InternalSub.configure(this.props.subscriptions(nextModel))
        );

        return this.handleCmd(cmd);
    }

    private readonly dispatch = (msg: Msg): Promise<Array<Msg>> => {
        const [ nextModel, cmd ] = this.props.update(msg, this.state);

        return this.applyChanges(nextModel, cmd);
    }

    private sequence(msgs: Array<Msg>): Promise<Array<Msg>> {
        if (msgs.length === 0) {
            return Promise.resolve([]);
        }

        let nextModel: Model = this.state;<commit_msg>Console.log for show end of initial Cmd added<commit_after>/**
 * Solution based on:
 * @link https://github.com/redux-loop/redux-loop
 */
import React from 'react';

import {
    Cmd
} from 'Platform/Cmd';
import {
    Sub
} from 'Platform/Sub';

export interface Subscriber<Msg, T = any> {
    namespace: string;
    key: string;
    tagger(config: T): Msg;
    executor(callback: (config: T) => void): () => void;
}

interface Process<Msg, T = any> {
    mailbox: Array<(config: T) => Msg>;
    kill(): void;
}

abstract class InternalCmd<Msg> extends Cmd<Msg> {
    public static execute<Msg>(cmd: Cmd<Msg>): Array<Promise<Msg>> {
        return super.execute(cmd);
    }
}

abstract class InternalSub<Msg> extends Sub<Msg> {
    public static configure<Msg>(sub: Sub<Msg>): Array<Subscriber<Msg>> {
        return super.configure(sub);
    }
}

export type Dispatch<Msg> = (msg: Msg) => void;

export interface Configuration<Msg, Model> {
    view: React.StatelessComponent<{
        dispatch: Dispatch<Msg>;
        model: Model;
    }>;
    init(): [ Model, Cmd<Msg> ];
    update(msg: Msg, model: Model): [ Model, Cmd<Msg> ];
    subscriptions(model: Model): Sub<Msg>;
}

export class Application<Msg, Model> extends React.Component<Configuration<Msg, Model>, Model> {
    private readonly processes: Map<string, Map<string, Process<Msg>>> = new Map();

    constructor(props: Configuration<Msg, Model>, context: any) {
        super(props, context);

        const [ initialModel, initialCmd ] = props.init();

        this.state = initialModel;

        this.executeCmd(initialCmd).then(() => {
            console.log('Initial Cmd has been done'); // tslint:disable-line:no-console
        });
    }

    public render() {
        return React.createElement(
            this.props.view,
            {
                model: this.state,
                dispatch: (msg: Msg): void => {
                    this.dispatch(msg);
                }
            }
        );
    }

    private executeCmd(cmd: Cmd<Msg>): Promise<Array<Msg>> {
        const result: Array<Promise<Array<Msg>>> = [];

        for (const promise of InternalCmd.execute(cmd)) {
            result.push(promise.then(this.dispatch));
        }

        return Promise.all(result).then((arrayOfArrays: Array<Array<Msg>>): Array<Msg> => {
            const result: Array<Msg> = [];

            for (const arrayOfMsgs of arrayOfArrays) {
                result.push(...arrayOfMsgs);
            }

            return result;
        });
    }

    private applyChanges(nextModel: Model, cmd: Cmd<Msg>): Promise<Array<Msg>> {
        if (this.state !== nextModel) {
            this.setState(nextModel);
        }

        this.manageSubscribers(
            InternalSub.configure(this.props.subscriptions(nextModel))
        );

        return this.executeCmd(cmd);
    }

    private readonly dispatch = (msg: Msg): Promise<Array<Msg>> => {
        const [ nextModel, cmd ] = this.props.update(msg, this.state);

        return this.applyChanges(nextModel, cmd);
    }

    private sequence(msgs: Array<Msg>): Promise<Array<Msg>> {
        if (msgs.length === 0) {
            return Promise.resolve([]);
        }

        let nextModel: Model = this.state;
{'fraction_non_alphanumeric': 0.14393108848864528, 'fraction_numerical': 0.00031323414252153485, 'mean_word_length': 2.455627705627706, 'pattern_counts': {'":': 0, '<': 99, '<?xml version=': 0, '>': 114, 'https://': 2, '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': '1949096', 'n_tokens_mistral': 1925, 'n_tokens_neox': 1879, 'n_words': 432}