"use strict" ; import { Dispatcher } from "./Dispatcher" ; import { DispatchedPayload } from "./Dispatcher" ; import { UseCaseContext } from "./UseCaseContext" ; import { DispatcherPayloadMeta , DispatcherPayloadMetaImpl } from "./DispatcherPayloadMeta" ; import { ErrorPayload , isErrorPayload } from "./payload/ErrorPayload" ; import { UseCaseLike } from "./UseCaseLike" ; import { generateNewId } from "./UseCaseIdGenerator" ; export const defaultUseCaseName = "<Anonymous-UseCase>" ; export const isUseCase = ( v ) : v is UseCase => { if ( v instanceof UseCase ) { return true ; } else if ( typeof v === "object" && typeof v . execute === "function" ) { return true ; } return false ; } ; /**
 * A `UseCase` class is inherited Dispatcher.
 * The user implement own user-case that is inherited UseCase class
 *
 * It similar to ActionCreator on Flux.
 *
 * ### Example
 *
 * ```js
 * import {UseCase} from "almin";
 * class AwesomeUseCase extends UseCase {
 *    execute(){
 *       // implementation own use-case
 *   }
 * }
 * ```
 */ export abstract class UseCase extends Dispatcher implements UseCaseLike { /**
     * Debuggable name if it needed
     */ static displayName ? : string ; /**
     * Return true if the `v` is a UseCase-like.
     */ static isUseCase ( v ) { return isUseCase ( v ) ; } /**
     * Unique id in each UseCase instances.
     */ id : string ; /**
     * The name of the UseCase.
     */ name : string ; /**
     * Constructor not have arguments.
     */ constructor ( ) { super ( ) ; this . id = generateNewId ( ) ; const own = this . constructor as typeof UseCase ; this . name = own . displayName || own . name || defaultUseCaseName ; } /**
     * Get `context` of UseCase.
     * You can execute sub UseCase using UseCaseContext object.
     *
     * See following for more details.
     *
     * - [UseCaseContext](https://almin.js.org/docs/en/usecase-api.html)
     * - [Nesting UseCase](https://almin.js.org/docs/en/nesting-usecase.html)
     *
     * ### Example
     *
     * ```js
     * // Parent -> ChildUseCase
     * export class ParentUseCase extends UseCase {
     *     execute() {
     *         // execute child use-case using UseCaseContext object.
     *         return this.context.useCase(new ChildUseCase()).execute();
     *     }
     * }
     * export class ChildUseCase extends UseCase {
     *     execute() {
     *         this.dispatch({
     *             type: "ChildUseCase"
     *         });
     *     }
     * }
     * ```
     */ get context ( ) : UseCaseContext { return new UseCaseContext ( this ) ; } returns { boolean } shouldExecute ( ... _ ) { return true ; } /**
     * `UseCase#execute()` method should be overwrite by subclass.
     *
     * ### Example
     *
     * ```js
     * class AwesomeUseCase extends UseCase {
     *    execute(){
     *       // implementation own use-case
     *   }
     * }
     * ```
     *
     */ abstract execute ( ... _ ) ; /**
     * Dispatch `payload` object.
     *
     * `Store` or `Context` can receive the `payload` object.n
     */ dispatch ( payload , meta ? ) { const useCaseMeta = meta ? meta : new DispatcherPayloadMetaImpl ( { useCase : this , parentUseCase : null , isTrusted : false , isUseCaseFinished : false } ) ; super . dispatch ( payload , useCaseMeta ) ; } /**
     * `errorHandler` is called with error when error is thrown.
     */ onError ( errorHandler ) { return this . onDispatch ( ( payload ) => { if ( isErrorPayload ( payload ) ) { errorHandler ( payload . error ) ; } } ) ; } /**
     * Throw error payload.
     *
     * You can use it instead of `throw new Error()`
     * This error event is caught by dispatcher.
     */ throwError ( error ? ) { const meta = new DispatcherPayloadMetaImpl ( { useCase : this , isTrusted : true , isUseCaseFinished : false } ) ; const payload = new ErrorPayload ( { error } ) ; this . dispatch ( payload , meta ) ; } } UseCase . prototype . execute = function ( this ) { throw new TypeError ( `${ this . name } should be implemented UseCase#execute(): any` ) ; } ;