diff --git a/packages/nx/spec/data-persistence.spec.ts b/packages/nx/spec/data-persistence.spec.ts index 68ae7a825f..774ee51004 100644 --- a/packages/nx/spec/data-persistence.spec.ts +++ b/packages/nx/spec/data-persistence.spec.ts @@ -92,7 +92,7 @@ describe('DataPersistence', () => { class TodoEffects { @Effect() loadTodo = this.s.navigation(TodoComponent, { - run: (a: ActivatedRouteSnapshot, state: TodosState) => { + run: (a, state) => { return { type: 'TODO_LOADED', payload: { id: a.params['id'], user: state.user } @@ -100,7 +100,7 @@ describe('DataPersistence', () => { }, onError: () => null }); - constructor(private s: DataPersistence) {} + constructor(private s: DataPersistence) {} } beforeEach(() => { @@ -131,7 +131,7 @@ describe('DataPersistence', () => { class TodoEffects { @Effect() loadTodo = this.s.navigation(TodoComponent, { - run: (a: ActivatedRouteSnapshot, state: TodosState) => { + run: (a, state) => { if (a.params['id'] === '123') { throw new Error('boom'); } else { @@ -143,7 +143,7 @@ describe('DataPersistence', () => { }, onError: (a, e) => ({ type: 'ERROR', payload: { error: e } }) }); - constructor(private s: DataPersistence) {} + constructor(private s: DataPersistence) {} } beforeEach(() => { @@ -183,7 +183,7 @@ describe('DataPersistence', () => { class TodoEffects { @Effect() loadTodo = this.s.navigation(TodoComponent, { - run: (a: ActivatedRouteSnapshot, state: TodosState) => { + run: (a, state) => { if (a.params['id'] === '123') { return _throw('boom'); } else { @@ -195,7 +195,7 @@ describe('DataPersistence', () => { }, onError: (a, e) => ({ type: 'ERROR', payload: { error: e } }) }); - constructor(private s: DataPersistence) {} + constructor(private s: DataPersistence) {} } beforeEach(() => { @@ -236,11 +236,15 @@ describe('DataPersistence', () => { }); describe('no id', () => { + type GetTodos = { + type: 'GET_TODOS'; + }; + @Injectable() class TodoEffects { @Effect() - loadTodos = this.s.fetch('GET_TODOS', { - run: (a: any, state: TodosState) => { + loadTodos = this.s.fetch('GET_TODOS', { + run: (a, state) => { // we need to introduce the delay to "enable" switchMap return of({ type: 'TODOS', @@ -248,10 +252,10 @@ describe('DataPersistence', () => { }).delay(1); }, - onError: (a: UpdateTodo, e: any) => null + onError: (a, e: any) => null }); - constructor(private s: DataPersistence) {} + constructor(private s: DataPersistence) {} } function userReducer() { @@ -281,16 +285,21 @@ describe('DataPersistence', () => { }); describe('id', () => { + type GetTodo = { + type: 'GET_TODO'; + payload: { id: string }; + }; + @Injectable() class TodoEffects { @Effect() - loadTodo = this.s.fetch('GET_TODO', { - id: (a: any, state: TodosState) => a.payload.id, - run: (a: any, state: TodosState) => of({ type: 'TODO', payload: a.payload }).delay(1), - onError: (a: UpdateTodo, e: any) => null + loadTodo = this.s.fetch('GET_TODO', { + id: (a, state) => a.payload.id, + run: (a, state) => of({ type: 'TODO', payload: a.payload }).delay(1), + onError: (a, e: any) => null }); - constructor(private s: DataPersistence) {} + constructor(private s: DataPersistence) {} } function userReducer() { @@ -333,15 +342,15 @@ describe('DataPersistence', () => { @Injectable() class TodoEffects { @Effect() - loadTodo = this.s.pessimisticUpdate('UPDATE_TODO', { - run: (a: UpdateTodo, state: TodosState) => ({ + loadTodo = this.s.pessimisticUpdate('UPDATE_TODO', { + run: (a, state) => ({ type: 'TODO_UPDATED', payload: { user: state.user, newTitle: a.payload.newTitle } }), - onError: (a: UpdateTodo, e: any) => null + onError: (a, e: any) => null }); - constructor(private s: DataPersistence) {} + constructor(private s: DataPersistence) {} } function userReducer() { @@ -379,18 +388,18 @@ describe('DataPersistence', () => { @Injectable() class TodoEffects { @Effect() - loadTodo = this.s.pessimisticUpdate('UPDATE_TODO', { - run: (a: UpdateTodo, state: TodosState) => { + loadTodo = this.s.pessimisticUpdate('UPDATE_TODO', { + run: (a, state) => { throw new Error('boom'); }, - onError: (a: UpdateTodo, e: any) => ({ + onError: (a, e: any) => ({ type: 'ERROR', payload: { error: e } }) }); - constructor(private s: DataPersistence) {} + constructor(private s: DataPersistence) {} } function userReducer() { @@ -426,18 +435,18 @@ describe('DataPersistence', () => { @Injectable() class TodoEffects { @Effect() - loadTodo = this.s.pessimisticUpdate('UPDATE_TODO', { - run: (a: UpdateTodo, state: TodosState) => { + loadTodo = this.s.pessimisticUpdate('UPDATE_TODO', { + run: (a, state) => { return _throw('boom'); }, - onError: (a: UpdateTodo, e: any) => ({ + onError: (a, e: any) => ({ type: 'ERROR', payload: { error: e } }) }); - constructor(private s: DataPersistence) {} + constructor(private s: DataPersistence) {} } function userReducer() { @@ -479,18 +488,18 @@ describe('DataPersistence', () => { @Injectable() class TodoEffects { @Effect() - loadTodo = this.s.optimisticUpdate('UPDATE_TODO', { - run: (a: UpdateTodo, state: TodosState) => { + loadTodo = this.s.optimisticUpdate('UPDATE_TODO', { + run: (a, state) => { throw new Error('boom'); }, - undoAction: (a: UpdateTodo, e: any) => ({ + undoAction: (a, e: any) => ({ type: 'UNDO_UPDATE_TODO', payload: a.payload }) }); - constructor(private s: DataPersistence) {} + constructor(private s: DataPersistence) {} } function userReducer() { diff --git a/packages/nx/src/data-persistence.ts b/packages/nx/src/data-persistence.ts index cf38a16380..728b77b0a5 100644 --- a/packages/nx/src/data-persistence.ts +++ b/packages/nx/src/data-persistence.ts @@ -17,32 +17,32 @@ import { withLatestFrom } from 'rxjs/operator/withLatestFrom'; /** * See {@link DataPersistence.pessimisticUpdate} for more information. */ -export interface PessimisticUpdateOpts { - run(a: Action, state?: any): Observable | Action | void; - onError(a: Action, e: any): Observable | any; +export interface PessimisticUpdateOpts { + run(a: A, state?: T): Observable | Action | void; + onError(a: A, e: any): Observable | any; } /** * See {@link DataPersistence.pessimisticUpdate} for more information. */ -export interface OptimisticUpdateOpts { - run(a: Action, state?: any): Observable | any; - undoAction(a: Action, e: any): Observable | Action; +export interface OptimisticUpdateOpts { + run(a: A, state?: T): Observable | Action | void; + undoAction(a: A, e: any): Observable | Action; } /** * See {@link DataPersistence.navigation} for more information. */ -export interface FetchOpts { - id?(a: Action, state?: any): any; - run(a: Action, state?: any): Observable | Action | void; - onError?(a: Action, e: any): Observable | any; +export interface FetchOpts { + id?(a: A, state?: T): any; + run(a: A, state?: T): Observable | Action | void; + onError?(a: A, e: any): Observable | any; } /** * See {@link DataPersistence.navigation} for more information. */ -export interface HandleNavigationOpts { - run(a: ActivatedRouteSnapshot, state?: any): Observable | Action | void; +export interface HandleNavigationOpts { + run(a: ActivatedRouteSnapshot, state?: T): Observable | Action | void; onError?(a: ActivatedRouteSnapshot, e: any): Observable | any; } @@ -69,9 +69,9 @@ export class DataPersistence { * ```typescript * @Injectable() * class TodoEffects { - * @Effect() updateTodo = this.s.pessimisticUpdate('UPDATE_TODO', { + * @Effect() updateTodo = this.s.pessimisticUpdate('UPDATE_TODO', { * // provides an action and the current state of the store - * run(a: UpdateTodo, state: TodosState) { + * run(a, state) { * // update the backend first, and then dispatch an action that will * // update the client side * return this.backend(state.user, a.payload).map(updated => ({ @@ -80,7 +80,7 @@ export class DataPersistence { * })); * }, * - * onError(a: UpdateTodo, e: any) { + * onError(a, e: any) { * // we don't need to undo the changes on the client side. * // we can dispatch an error, or simply log the error here and return `null` * return null; @@ -91,7 +91,7 @@ export class DataPersistence { * } * ``` */ - pessimisticUpdate(actionType: string, opts: PessimisticUpdateOpts): Observable { + pessimisticUpdate(actionType: string, opts: PessimisticUpdateOpts): Observable { const nav = this.actions.ofType(actionType); const pairs = withLatestFrom.call(nav, this.store); return concatMap.call(pairs, this.runWithErrorHandling(opts.run, opts.onError)); @@ -114,13 +114,13 @@ export class DataPersistence { * ```typescript * @Injectable() * class TodoEffects { - * @Effect() updateTodo = this.s.optimisticUpdate('UPDATE_TODO', { + * @Effect() updateTodo = this.s.optimisticUpdate('UPDATE_TODO', { * // provides an action and the current state of the store - * run: (a: UpdateTodo, state: TodosState) => { + * run: (a, state) => { * return this.backend(state.user, a.payload); * }, * - * undoAction: (a: UpdateTodo, e: any) => { + * undoAction: (a, e: any) => { * // dispatch an undo action to undo the changes in the client state * return ({ * type: 'UNDO_UPDATE_TODO', @@ -133,7 +133,7 @@ export class DataPersistence { * } * ``` */ - optimisticUpdate(actionType: string, opts: OptimisticUpdateOpts): Observable { + optimisticUpdate(actionType: string, opts: OptimisticUpdateOpts): Observable { const nav = this.actions.ofType(actionType); const pairs = withLatestFrom.call(nav, this.store); return concatMap.call(pairs, this.runWithErrorHandling(opts.run, opts.undoAction)); @@ -153,16 +153,16 @@ export class DataPersistence { * ```typescript * @Injectable() * class TodoEffects { - * @Effect() loadTodos = this.s.fetch('GET_TODOS', { + * @Effect() loadTodos = this.s.fetch('GET_TODOS', { * // provides an action and the current state of the store - * run: (a: GetTodos, state: TodosState) => { + * run: (a, state) => { * return this.backend(state.user, a.payload).map(r => ({ * type: 'TODOS', * payload: r * }); * }, * - * onError: (a: GetTodos, e: any) => { + * onError: (a, e: any) => { * // dispatch an undo action to undo the changes in the client state * } * }); @@ -178,20 +178,20 @@ export class DataPersistence { * ```typescript * @Injectable() * class TodoEffects { - * @Effect() loadTodo = this.s.fetch('GET_TODO', { - * id: (a: GetTodo, state: TodosState) => { + * @Effect() loadTodo = this.s.fetch('GET_TODO', { + * id: (a, state) => { * return a.payload.id; * } * * // provides an action and the current state of the store - * run: (a: GetTodo, state: TodosState) => { + * run: (a, state) => { * return this.backend(state.user, a.payload).map(r => ({ * type: 'TODO', * payload: r * }); * }, * - * onError: (a: GetTodo, e: any) => { + * onError: (a, e: any) => { * // dispatch an undo action to undo the changes in the client state * return null; * } @@ -206,7 +206,7 @@ export class DataPersistence { * In addition, if DataPersistence notices that there are multiple requests for Todo 1 scheduled, * it will only run the last one. */ - fetch(actionType: string, opts: FetchOpts): Observable { + fetch(actionType: string, opts: FetchOpts): Observable { const nav = this.actions.ofType(actionType); const allPairs = withLatestFrom.call(nav, this.store); @@ -237,13 +237,13 @@ export class DataPersistence { * @Injectable() * class TodoEffects { * @Effect() loadTodo = this.s.navigation(TodoComponent, { - * run: (a: ActivatedRouteSnapshot, state: TodosState) => { + * run: (a, state) => { * return this.backend.fetchTodo(a.params['id']).map(todo => ({ * type: 'TODO_LOADED', * payload: todo * })); * }, - * onError: (a: ActivatedRouteSnapshot, e: any) => { + * onError: (a, e: any) => { * // we can log and error here and return null * // we can also navigate back * return null; @@ -254,7 +254,7 @@ export class DataPersistence { * ``` * */ - navigation(component: Type, opts: HandleNavigationOpts): Observable { + navigation(component: Type, opts: HandleNavigationOpts): Observable { const nav = filter.call( map.call(this.actions.ofType(ROUTER_NAVIGATION), (a: RouterNavigationAction) => findSnapshot(component, a.payload.routerState.root)