Skip to content
This repository has been archived by the owner on Jan 15, 2023. It is now read-only.

Commit

Permalink
refactored EffectsModule; renamed useSelector to useSelect; small cha…
Browse files Browse the repository at this point in the history
…nges in core lib and StoreModule
  • Loading branch information
markostanimirovic committed Aug 23, 2020
1 parent 27b5bbe commit 40c0e50
Show file tree
Hide file tree
Showing 18 changed files with 45 additions and 70 deletions.
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -444,13 +444,13 @@ It's similar for the effects. Instead of `registerEffects` function, there is `E
imports: [
...
StoreModule.forRoot(initialAppState, !environment.production),
EffectsModule.forRoot([TodosEffects]),
EffectsModule.register([TodosEffects]),
],
})
export class AppModule {}
```

`forRoot` method from `EffectsModule` accepts an array of classes with effects. By creating effects within the class, you can use all the benefits
`register` method from `EffectsModule` accepts an array of classes with effects. By creating effects within the class, you can use all the benefits
of dependency injection.

```typescript
Expand Down Expand Up @@ -484,13 +484,11 @@ ReactDOM.render(
);
```

This plugin provides `useSelector` hook that accepts the selector function and `useDispatch` hook that returns the dispatch function.
This plugin provides `useSelect` hook that accepts a selector function or feature key and `useDispatch` hook that returns the dispatch function.

```typescript
const selectTodosState = (state: AppState) => state[fromTodos.featureKey];

function Todos() {
const todosState = useSelector(selectTodosState);
const todosState = useSelect<AppState, fromTodos.State>(fromTodos.featureKey);
const dispatch = useDispatch();

return (
Expand Down
4 changes: 2 additions & 2 deletions projects/juliette-ng/package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"name": "juliette-ng",
"version": "0.10.0",
"version": "0.11.0",
"peerDependencies": {
"juliette": "0.10.0",
"juliette": "0.11.0",
"@angular/core": "^10.0.5",
"rxjs": "^6.5.5"
},
Expand Down
32 changes: 6 additions & 26 deletions projects/juliette-ng/src/lib/effects.module.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,25 @@
import { Inject, ModuleWithProviders, NgModule, Type } from '@angular/core';
import { CLASSES_WITH_FEATURE_EFFECTS, CLASSES_WITH_ROOT_EFFECTS } from './tokens';
import { OBJECTS_WITH_EFFECTS } from './tokens';
import {
fromClassesWithEffectsToClassProviders,
fromObjectsWithEffectsToEffects,
} from './effects.mapper';
import { registerEffects, Store } from 'juliette';

@NgModule()
export class EffectsRootModule {
constructor(store: Store<any>, @Inject(CLASSES_WITH_ROOT_EFFECTS) objectsWithEffects: any[]) {
const effects = fromObjectsWithEffectsToEffects(objectsWithEffects);
registerEffects(store, effects);
}
}

@NgModule()
export class EffectsFeatureModule {
constructor(store: Store<any>, @Inject(CLASSES_WITH_FEATURE_EFFECTS) objectsWithEffects: any[]) {
export class EffectsModule {
constructor(store: Store<any>, @Inject(OBJECTS_WITH_EFFECTS) objectsWithEffects: any[]) {
const effects = fromObjectsWithEffectsToEffects(
objectsWithEffects.splice(0, objectsWithEffects.length),
);
registerEffects(store, effects);
}
}

@NgModule()
export class EffectsModule {
static forRoot(classesWithEffects: Type<any>[] = []): ModuleWithProviders<EffectsRootModule> {
return {
ngModule: EffectsRootModule,
providers: [
...fromClassesWithEffectsToClassProviders(CLASSES_WITH_ROOT_EFFECTS, classesWithEffects),
],
};
}

static forFeature(classesWithEffects: Type<any>[] = []): ModuleWithProviders<any> {
static register(classesWithEffects: Type<any>[]): ModuleWithProviders<EffectsModule> {
return {
ngModule: EffectsFeatureModule,
ngModule: EffectsModule,
providers: [
...fromClassesWithEffectsToClassProviders(CLASSES_WITH_FEATURE_EFFECTS, classesWithEffects),
...fromClassesWithEffectsToClassProviders(OBJECTS_WITH_EFFECTS, classesWithEffects),
],
};
}
Expand Down
14 changes: 7 additions & 7 deletions projects/juliette-ng/src/lib/store.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Inject, ModuleWithProviders, NgModule } from '@angular/core';
import { createStore, Store } from 'juliette';
import { DEV_MODE, FEATURE_KEYS, FEATURE_STATES, INITIAL_STATE } from './tokens';
import { DEV_MODE, FEATURE_KEYS, INITIAL_FEATURE_STATES, INITIAL_ROOT_STATE } from './tokens';

export function createStoreFactory<T>(initialState: T, devMode: boolean): Store<T> {
return createStore(initialState, devMode);
Expand All @@ -14,9 +14,9 @@ export class StoreFeatureModule {
constructor(
store: Store<any>,
@Inject(FEATURE_KEYS) featureKeys: any[],
@Inject(FEATURE_STATES) featureStates: any[],
@Inject(INITIAL_FEATURE_STATES) initialStates: any[],
) {
store.addFeatureState(featureKeys.pop(), featureStates.pop());
store.addFeatureState(featureKeys.pop(), initialStates.pop());
}
}

Expand All @@ -26,26 +26,26 @@ export class StoreModule {
return {
ngModule: StoreRootModule,
providers: [
{ provide: INITIAL_STATE, useValue: initialState },
{ provide: INITIAL_ROOT_STATE, useValue: initialState },
{ provide: DEV_MODE, useValue: devMode },
{
provide: Store,
useFactory: createStoreFactory,
deps: [INITIAL_STATE, DEV_MODE],
deps: [INITIAL_ROOT_STATE, DEV_MODE],
},
],
};
}

static forFeature<T>(
featureKey: keyof T,
featureState: T[keyof T],
initialState: T[keyof T],
): ModuleWithProviders<StoreFeatureModule> {
return {
ngModule: StoreFeatureModule,
providers: [
{ provide: FEATURE_KEYS, multi: true, useValue: featureKey },
{ provide: FEATURE_STATES, multi: true, useValue: featureState },
{ provide: INITIAL_FEATURE_STATES, multi: true, useValue: initialState },
],
};
}
Expand Down
13 changes: 5 additions & 8 deletions projects/juliette-ng/src/lib/tokens.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { InjectionToken } from '@angular/core';

export const INITIAL_STATE = new InjectionToken('__julietteNgInternal/initialState__');
export const INITIAL_ROOT_STATE = new InjectionToken('__julietteNgInternal/initialRootState__');
export const FEATURE_KEYS = new InjectionToken('__julietteNgInternal/featureKeys__');
export const FEATURE_STATES = new InjectionToken('__julietteNgInternal/featureStates__');
export const DEV_MODE = new InjectionToken('__julietteNgInternal/devMode__');
export const CLASSES_WITH_ROOT_EFFECTS = new InjectionToken(
'__julietteNgInternal/classesWithRootEffects__',
);
export const CLASSES_WITH_FEATURE_EFFECTS = new InjectionToken(
'__julietteNgInternal/classesWithFeatureEffects__',
export const INITIAL_FEATURE_STATES = new InjectionToken(
'__julietteNgInternal/initialFeatureStates__',
);
export const DEV_MODE = new InjectionToken('__julietteNgInternal/devMode__');
export const OBJECTS_WITH_EFFECTS = new InjectionToken('__julietteNgInternal/objectsWithEffects__');
4 changes: 2 additions & 2 deletions projects/juliette-react/package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "juliette-react",
"version": "0.10.0",
"version": "0.11.0",
"main": "public-api.js",
"types": "public-api.d.ts",
"peerDependencies": {
"juliette": "0.10.0",
"juliette": "0.11.0",
"react": "^16.13.1"
}
}
6 changes: 3 additions & 3 deletions projects/juliette-react/src/lib/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ export function useDispatch(): Dispatch {
return useCallback(store.dispatch.bind(store), [store]);
}

export function useSelector<T, R extends T[keyof T]>(featureKey: keyof T): R;
export function useSelect<T, R extends T[keyof T]>(featureKey: keyof T): R;

export function useSelector<T, R>(selector: Selector<T, R>): R;
export function useSelect<T, R>(selector: Selector<T, R>): R;

export function useSelector<T, K extends keyof T, R>(keyOrSelector: K | Selector<T, R>): T[K] | R {
export function useSelect<T, K extends keyof T, R>(keyOrSelector: K | Selector<T, R>): T[K] | R {
const store = useStore<T>();
const [state$, initialState] = useMemo(() => {
let initialState: T[K] | R = null as any;
Expand Down
2 changes: 1 addition & 1 deletion projects/juliette/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "juliette",
"version": "0.10.0",
"version": "0.11.0",
"main": "public-api.js",
"types": "public-api.d.ts",
"peerDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions projects/juliette/src/lib/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ export class Store<T> {
return this.state$.pipe(map<T, T[K] | R>(mapFn), distinctUntilChanged());
}

addFeatureState(featureKey: keyof T, featureState: T[keyof T]): void {
this.state.next({ ...this.state.value, [featureKey]: featureState });
addFeatureState(featureKey: keyof T, initialState: T[keyof T]): void {
this.state.next({ ...this.state.value, [featureKey]: initialState });
}
}

Expand Down
2 changes: 1 addition & 1 deletion projects/playground-ng/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { UsersComponent } from './containers/users.component';
imports: [
BrowserModule,
StoreModule.forRoot(initialAppState, !environment.production),
EffectsModule.forRoot([UsersEffects]),
EffectsModule.register([UsersEffects]),
AppRoutingModule,
],
bootstrap: [AppComponent],
Expand Down
4 changes: 2 additions & 2 deletions projects/playground-ng/src/app/feature1/feature1.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Store } from 'juliette';
import { Feature1State, fromFeature1 } from './store';
import { Feature1AppState, fromFeature1 } from './store';
import { FormControl } from '@angular/forms';
import { takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
Expand All @@ -20,7 +20,7 @@ export class Feature1Component implements OnInit, OnDestroy {
fooControl = new FormControl();
state$ = this.store.select(fromFeature1.featureKey);

constructor(private store: Store<Feature1State>) {}
constructor(private store: Store<Feature1AppState>) {}

ngOnInit(): void {
this.fooControl.valueChanges
Expand Down
2 changes: 1 addition & 1 deletion projects/playground-ng/src/app/feature1/feature1.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { Feature1Effects } from './store/feature1.effects';
ReactiveFormsModule,
Feature1RoutingModule,
StoreModule.forFeature(fromFeature1.featureKey, fromFeature1.initialState),
EffectsModule.forFeature([Feature1Effects]),
EffectsModule.register([Feature1Effects]),
],
})
export class Feature1Module {}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { Store, ofType, toPayload } from 'juliette';
import { Feature1State, fromFeature1 } from './index';
import { Feature1AppState, fromFeature1 } from './index';
import { tap } from 'rxjs/operators';

@Injectable()
Expand All @@ -11,5 +11,5 @@ export class Feature1Effects {
tap(({ foo }) => console.log('fooUpdated', foo)),
);

constructor(private store: Store<Feature1State>) {}
constructor(private store: Store<Feature1AppState>) {}
}
2 changes: 1 addition & 1 deletion projects/playground-ng/src/app/feature1/store/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as fromFeature1 from './feature1.handlers';

export interface Feature1State {
export interface Feature1AppState {
[fromFeature1.featureKey]: fromFeature1.State;
}

Expand Down
4 changes: 2 additions & 2 deletions projects/playground-ng/src/app/feature2/feature2.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Store } from 'juliette';
import { Feature2State, fromFeature2 } from './store';
import { Feature2AppState, fromFeature2 } from './store';
import { FormControl } from '@angular/forms';
import { takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
Expand All @@ -20,7 +20,7 @@ export class Feature2Component implements OnInit, OnDestroy {
barControl = new FormControl();
state$ = this.store.select(fromFeature2.featureKey);

constructor(private store: Store<Feature2State>) {}
constructor(private store: Store<Feature2AppState>) {}

ngOnInit(): void {
this.barControl.valueChanges
Expand Down
2 changes: 1 addition & 1 deletion projects/playground-ng/src/app/feature2/feature2.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { Feature2Effects } from './store/feature2.effects';
ReactiveFormsModule,
Feature2RoutingModule,
StoreModule.forFeature(fromFeature2.featureKey, fromFeature2.initialState),
EffectsModule.forFeature([Feature2Effects]),
EffectsModule.register([Feature2Effects]),
],
})
export class Feature2Module {}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { Store, ofType, toPayload } from 'juliette';
import { Feature2State, fromFeature2 } from './index';
import { Feature2AppState, fromFeature2 } from './index';
import { tap } from 'rxjs/operators';

@Injectable()
Expand All @@ -11,5 +11,5 @@ export class Feature2Effects {
tap(({ bar }) => console.log('barUpdated', bar)),
);

constructor(private store: Store<Feature2State>) {}
constructor(private store: Store<Feature2AppState>) {}
}
2 changes: 1 addition & 1 deletion projects/playground-ng/src/app/feature2/store/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as fromFeature2 from './feature2.handlers';

export interface Feature2State {
export interface Feature2AppState {
[fromFeature2.featureKey]: fromFeature2.State;
}

Expand Down

0 comments on commit 40c0e50

Please sign in to comment.