All files / state/src/effect dispatch.ts

100% Statements 83/83
83.33% Branches 5/6
100% Functions 2/2
100% Lines 83/83

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 841x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 16x 16x 16x 16x 16x 16x 16x 16x 16x 2x 3x 3x 1x 1x 1x  
import { Bus } from '@sgrud/bus';
import { StateWorker } from '../handler/handler';
import { Implant } from '../handler/implant';
import { Store } from '../store/store';
import { Effect } from './effect';
 
declare global {
  namespace sgrud.state.effects {
 
    /**
     * {@link Implant}ed {@link DispatchEffect} providing a convenient way to
     * **dispatch** {@link Store.Action}s from within {@link Store.Action}s.
     * This {@link DispatchEffect} in combination with the {@link StateEffect}
     * can be used to implement complex interactions between different
     * {@link Store}s.
     *
     * @param handle - The {@link Bus.Handle} representing the {@link Store}.
     * @param action - A type-guarded {@link Store.Action} to **dispatch**.
     * @typeParam T - The extending {@link Store} {@link InstanceType}.
     * @returns The next {@link Store.State} after **dispatch**ing.
     *
     * @example
     * **dispatch** an {@link Store.Action} to another {@link Store}:
     * ```ts
     * import { type Bus } from '@sgrud/bus';
     * import { Stateful, Store } from '@sgrud/state';
     *
     * ⁠@Stateful('io.github.sgrud.store.example', { state: undefined })
     * export class ExampleStore extends Store<ExampleStore> {
     *
     *   public readonly state?: Store.State<Store>;
     *
     *   public async dispatchAction<T extends Store>(
     *     handle: Bus.Handle,
     *     ...action: Store.Action<T>
     *   ): Promise<Store.State<this>> {
     *     const state = await sgrud.state.effects.dispatch<T>(
     *       handle, ...action
     *     );
     *
     *     return { ...this, state };
     *   }
     *
     * }
     * ```
     *
     * @see {@link DispatchEffect}
     */
    function dispatch<T extends Store>(
      handle: Bus.Handle,
      ...action: Store.Action<T>
    ): Promise<Store.State<T>>;
 
  }
}
 
/**
 * Built-in **DispatchEffect** extending the abstract {@link Effect} base class.
 * This **DispatchEffect** is automatically {@link StateWorker.implant}ed when
 * the `@sgrud/state` module is imported and can therefore be always used in
 * {@link Store.Action}s.
 *
 * @decorator {@link Implant}
 *
 * @see {@link Effect}
 */
@Implant('dispatch')
export class DispatchEffect extends Effect {
 
  /**
   * Overridden **function** binding the {@link DispatchEffect} to the
   * polymorphic `this` of the {@link StateWorker}.
   *
   * @param this - The explicit polymorphic `this` parameter.
   * @returns This {@link DispatchEffect} bound to the {@link StateWorker}.
   */
  public override function(this: StateWorker): Store.Effects['dispatch'] {
    return async(handle, ...action) => {
      return await this.dispatch(handle, action);
    };
  }
 
}