Advertisement
legrottagliegionata

Component store wrapper

Feb 8th, 2021
953
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { Inject, Injectable, InjectionToken, OnDestroy, Optional } from "@angular/core";
  2. import { ComponentStore } from "@ngrx/component-store";
  3. import { Observable, Subscription } from "rxjs";
  4. import { globlaInjector, SYNERGY_CONFIG } from "../../base";
  5. import { SReduxDevtools, SReduxDevtoolsInstance } from "./synergy-redux-devtools";
  6.  
  7. export const SSTORE_INITIAL_STATE_TOKEN = new InjectionToken ("s-store Initial State");
  8. export const SSTORE_REDUX_DEVTOOL_NAME = new InjectionToken ("s-store State name");
  9.  
  10. @Injectable ()
  11. export class SStore<S extends object> implements OnDestroy {
  12.  
  13.   constructor (@Optional () @Inject (SSTORE_INITIAL_STATE_TOKEN) defaultState?: S, @Optional () @Inject (SSTORE_REDUX_DEVTOOL_NAME) private reduxDevtoolsName?: string) {
  14.     if (reduxDevtoolsName) {
  15.       if (!environment.production) {
  16.         const reduxDevtools = globlaInjector.get (SReduxDevtools);
  17.         this.devtoolsInstance = reduxDevtools.connect (reduxDevtoolsName);
  18.       } // if
  19.     } // if
  20.    
  21.     this.componentStore = new ComponentStore<S> (defaultState);
  22.     if (this.devtoolsInstance) {
  23.       this.devtoolsInstance.init (defaultState);
  24.     }
  25.   } // constructor
  26.  
  27.   private componentStore: ComponentStore<S>;
  28.   private devtoolsInstance: SReduxDevtoolsInstance;
  29.  
  30.   setState (state: S): void {
  31.     this.componentStore.setState (state);
  32.     if (this.devtoolsInstance) {
  33.       this.devtoolsInstance.init (state);
  34.     } // TODO_ANALISI
  35.   } // setState;
  36.  
  37.   getState (): S {
  38.     return this.get ();
  39.   } // getState
  40.  
  41.   select (): S;
  42.   select<R> (projector: (s: S) => R): R;
  43.   select<R> (projector?: (s: S) => R): R | S {
  44.     return this.get (projector);
  45.   } // select
  46.  
  47.   get (): S;
  48.   get<R> (projector: (s: S) => R): R;
  49.   get<R> (projector?: (s: S) => R): R | S {
  50.     return (this.componentStore as any).get (projector);
  51.   } // get
  52.  
  53.   select$ (): Observable<S>;
  54.   select$<R> (projector: (s: S) => R): Observable<R>;
  55.   select$<R, S1> (s1: Observable<S1>, projector: (s1: S1) => R): Observable<R>;
  56.   select$<R, S1, S2> (s1: Observable<S1>, s2: Observable<S2>, projector: (s1: S1, s2: S2) => R): Observable<R>;
  57.   select$<R, S1, S2, S3> (s1: Observable<S1>, s2: Observable<S2>, s3: Observable<S3>, projector: (s1: S1, s2: S2, s3: S3) => R): Observable<R>;
  58.   select$<R, S1, S2, S3, S4> (s1: Observable<S1>, s2: Observable<S2>, s3: Observable<S3>, s4: Observable<S4>, projector: (s1: S1, s2: S2, s3: S3, s4: S4) => R): Observable<R>;
  59.   select$<O extends Array<Observable<unknown> | ProjectorFn>, R, ProjectorFn = (...a: unknown[]) => R> (...args: O): Observable<R> | Observable<S> {
  60.     if (args && args.length) {
  61.       return (this.componentStore as any).select (...args);
  62.     } else {
  63.       return this.componentStore.state$;
  64.     } // if - else
  65.   } // select$
  66.  
  67.   selectAsync$<R> (projector: (s: S) => R): Observable<R>;
  68.   selectAsync$<O extends Array<Observable<unknown> | ProjectorFn>,
  69.     R,
  70.     ProjectorFn = (...a: unknown[]) => R> (...args: O): Observable<R> {
  71.     (args as any).push ({ debounce: true });
  72.     return (this.componentStore as any).select (...args);
  73.   } // selectSync$
  74.  
  75.   updater<V> (updaterFn: (state: S, value: V) => S, actionName?: string): unknown extends V ? () => void : (t: V | Observable<V>) => Subscription {
  76.     const wrapUpdaterFn = (state: S, value: V) => {
  77.       const newState = updaterFn (state, value);
  78.       if (this.devtoolsInstance) {
  79.         this.devtoolsInstance.send (actionName || this.reduxDevtoolsName, newState);
  80.       } // if
  81.       return newState;
  82.     };
  83.     return this.componentStore.updater (wrapUpdaterFn);
  84.   } // updater
  85.  
  86.   update (updaterFnOrPatch: ((state: S) => S) | Partial<S>, actionName?: string): void {
  87.     let updaterFn: (state: S) => S;
  88.     if (typeof updaterFnOrPatch === "function") {
  89.       updaterFn = updaterFnOrPatch;
  90.     } else {
  91.       updaterFn = (s: S) => ({ ...s, ...updaterFnOrPatch });
  92.     } // if - else
  93.     this.updater (updaterFn, actionName) ();
  94.   } // update
  95.  
  96.   effect<ProvidedType = void,
  97.     OriginType extends Observable<ProvidedType> | unknown = Observable<ProvidedType>,
  98.     ObservableType = OriginType extends Observable<infer A> ? A : never,
  99.     ReturnType = ProvidedType | ObservableType extends void
  100.                  ? () => void
  101.                  : (observableOrValue: ObservableType | Observable<ObservableType>) => Subscription> (generator: (origin$: OriginType) => Observable<unknown>): ReturnType {
  102.     return this.componentStore.effect (generator);
  103.   } // effect
  104.  
  105.   ngOnDestroy (): void {
  106.     this.destroy ();
  107.   } // ngOnDestroy
  108.  
  109.   destroy (): void {
  110.     this.componentStore.ngOnDestroy ();
  111.   } // destroy
  112.  
  113. } // SStore
  114.  
  115. export interface SReduxDevtoolsInstance {
  116.   init (initialState: unknown): void;
  117.   send (actionName: string, state: unknown): void;
  118. } // SReduxDevtoolsInstance
  119.  
  120. @Injectable ({
  121.   providedIn: "root"
  122. })
  123. export class SReduxDevtools {
  124.  
  125.   constructor (
  126.   ) {
  127.     this.reduxDevtoolsExtension = window ? (window as any).__REDUX_DEVTOOLS_EXTENSION__ : null;
  128.   } // constructor
  129.  
  130.   private reduxDevtoolsExtension: { connect: (config: { name: string }) => SReduxDevtoolsInstance };
  131.  
  132.   connect (name: string): SReduxDevtoolsInstance {
  133.     if (this.reduxDevtoolsExtension) {
  134.       return this.reduxDevtoolsExtension.connect ({ name: name });
  135.     } else {
  136.       return null;
  137.     } // if - else
  138.   } // connect
  139.  
  140. } // SReduxDevtools
  141.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement