import { Observable } from 'rxjs'; import { Type } from '@angular/core'; export { Type } from '@angular/core'; export { Action } from '@ngrx/store'; import { State } from '../reducers'; import { Reducer } from '../reducers/reducers'; export interface Obj { [k: string]: T; } export type AppState = State; export type SimpleSelector = (state: T) => any; export type CombinedSelector = [string[], (...args: any[]) => any]; // const genFn = (hasError, hasFail, hasComplete) => ` // (v: T) => { // obs: Observable${hasError && ' | Observable'}, // ${hasComplete && 'complete: V,'} // ${hasFail && 'fail: W,'} // } // `; export interface NgrxDomain { // object of classes for Dependency Injection in effect classes (key -> property name) di?: Obj>; // initial state value init?: TState; reducers?: Obj>; // selector functions from state$, probably using `obs.select`, `R.map(R.prop(k))` or `combineSelectors` // selectors combining previous selectors, supplied as tuple of [deps, fn] // - deps: combined selectors, names matching selectors defined above // - fn: combining function, array param ordered as above // simple selectors selectors?: Obj< CombinedSelector | SimpleSelector >; effects?: Obj<{ // Effect // initial payload value init?: /*T*/any, // limit effect calling interval (default: 0, unlimited) debounce?: number, // whether this is a read operation (ignore all but last) read?: boolean, // fallback value to use instead of emitting failure, define either this or `fail`. type matches fn.obs value, along with `ok` reducer param if no `fn.ok`. fallback?: /*U*/any, // fn: effect function returning different possible results, param type matching `init` (if specified) and effect action payload. fn: (pl: /*T*/any) => (Observable | { // obs: observable with the result (or error) for the given payload. result will be passed to `ok` reducer unless overridden by `fn.ok`. obs: Observable, // ok: // optional value to pass as a parameter to the `ok` reducer, with matching type. if not specified, the default or value of `fn.obs` (if successful) is passed instead. used to e.g. pass the effect param to the failure error instead of the error (such as the book the user attempted to add/remove, but couldn't). ok?: (v: /*U*/any) => /*V*/any, // fail: // optional value to pass as a parameter to the `fail` reducer, with matching type. if not specified, the error is passed instead. used to e.g. pass the effect param to the failure error instead of the error (such as the book the user attempted to add/remove, but couldn't). fail?: (e: Error) => /*W*/any, }), // reducer triggered on effect completion, with param type matching `fn.ok` (if available) or `fallback` + `fn.ok`. ok?: Reducer, // reducer triggered on effect failure, define either this or `fallback`. param type matches `fn.fail` if available, otherwise `Error`. fail?: Reducer, }>; } // export interface NgrxStruct { // domains: Obj< // { // () => // state: string, // State // init: State, // reducers: Obj< // [string /*type*/, string /*Reducer*/] // >, // selectors: Obj< // string /*(Observable) => T*/, // (using R.map(R.prop) or combineLatest) // >, // effects: Obj< // ( // { // init?: T, // debounce?: number, // read?: boolean, // } & ( // ( // ( // { // fallback: U, // fn: (v: T) => { // obs: string/*Observable*/, // complete: string/*V*/, // }, // } | { // fn: (v: T) => { // obs: string/*Observable | Observable*/, // complete: string/*V*/, // fail: string/*W*/, // }, // fail: string/*Reducer*/, // } | { // fn: (v: T) => { // obs: string/*Observable | Observable*/, // complete: string/*V*/, // }, // fail: string/*Reducer*/, // } // ) & { // complete: string/*Reducer*/, // } // ) | ( // ( // { // fallback: U, // fn: (v: T) => { // obs: string/*Observable*/, // }, // } | { // fn: (v: T) => { // obs: string/*Observable | Observable*/, // fail: string/*W*/, // }, // fail: string/*Reducer*/, // } | { // fn: (v: T) => { // obs: string/*Observable | Observable*/, // }, // fail: string/*Reducer*/, // } // ), // & { // complete: string/*Reducer*/, // } // ) // ) // ), // >, // // } // > // }