All files / state/src/handler implant.ts

100% Statements 59/59
100% Branches 2/2
100% Functions 0/0
100% Lines 59/59

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 601x 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 49x 13x 49x 49x 1x 1x  
import { from, switchMap } from 'rxjs';
import { Effect } from '../effect/effect';
import { Store } from '../store/store';
import { StateHandler } from './handler';
 
/**
 * The **Implant** decorator, when applied to classes extending the abstract
 * {@link Effect} base class, {@link StateHandler.implant}s the decorated class
 * under the `locate` in the global {@link sgrud.state.effects} namespace to be
 * used within {@link StateHandler.dispatch}ed {@link Store.Action}s.
 *
 * @param locate - The `locate` to address the {@link Effect} by.
 * @typeParam K - The {@link Store.Effect} `locate` type.
 * @typeParam T - An {@link Effect} constructor type.
 * @returns A class constructor decorator.
 *
 * @example
 * An `importScripts` **Effect**:
 * ```ts
 * import { Effect, Implant, type StateWorker, type Store } from '@sgrud/state';
 *
 * declare global {
 *   namespace sgrud.state.effects {
 *     function importScripts(...urls: (string | URL)[]): Promise<void>;
 *   }
 * }
 *
 * ⁠@Implant('importScripts')
 * export class ImportScriptsEffect extends Effect {
 *
 *   public override function(
 *     this: StateWorker
 *   ): Store.Effects['importScripts'] {
 *     return async(...urls) => {
 *       return importScripts(...urls);
 *     };
 *   }
 *
 * }
 * ```
 *
 * @see {@link StateHandler}
 * @see {@link Stateful}
 */
export function Implant<
  T extends new () => Effect<K>,
  K extends Store.Effect
>(locate: K) {
 
  /**
   * @param constructor - The class `constructor` to be decorated.
   */
  return function(constructor: T): void {
    from(StateHandler).pipe(switchMap((handler) => {
      return handler.implant(locate, constructor);
    })).subscribe();
  };
 
}