Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
didierfranc authored May 10, 2018
2 parents cc65faf + eb5fcdd commit 622d576
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 28 deletions.
44 changes: 21 additions & 23 deletions dist/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,27 @@
declare module 'react-waterfall' {
import { ComponentType } from 'react';

import React from 'react'
export type Action<T> = (...args: any[]) => void
export type Actions<T> = {
[K: string]: Action<T>
}
export type Store<T, A> = {
initialState: T
actions: {
[K in keyof A]: (state: T, ...args: any[]) => T | Promise<T>
}
}

declare type State = any
declare type Self = any
declare type Action = (state: State) => any
declare type Actions = { [key: string]: Action }
declare type Subscriber = (action: Action, state: State) => void
export type Subscriber<T, A> = (action: keyof A, state: T, ...args: any[]) => void

declare type Store = {
initialState: State
actions: Actions
}
export type Middleware<T, A> = (store: Store<T, A>, self: ComponentType<any>) => (action: keyof A, ...args: any[]) => void

declare type Middleware = (store: Store, self: Self) => (action: string) => void
export type Connect<T, P = any> = (selector: (state: T) => P) => (baseComponet: ComponentType<any>) => ComponentType<any>

declare export const initStore: (
state: any,
middlewares?: Middleware[],
) => {
Provider: React.Component<any>
Consumer: React.Component<any>
connect: (state: any) => (component: React.Component<any>) => React.Component<any>
actions: Actions
getState: () => State
subscribe: Subscriber
}
export function initStore<T, A extends Actions<T>>(store: Store<T, A>, ...middlewares: Middleware<T, A>[]): {
Provider: ComponentType<any>
Consumer: ComponentType<any>
connect: Connect<T>
actions: A
getState: () => T
subscribe: (subscruber: Subscriber<T, A>) => void
}
17 changes: 17 additions & 0 deletions src/__tests__/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ describe('initStore', () => {
expect(storeContext.getState).toBeDefined()
expect(storeContext.connect).toBeDefined()
expect(storeContext.subscribe).toBeDefined()
expect(storeContext.unsubscribe).toBeDefined()
})

test('should fail an action if provider not initialized', () => {
Expand Down Expand Up @@ -92,6 +93,22 @@ describe('initStore', () => {
expect(subscriber).toHaveBeenCalledTimes(1)
})

test('should remove subscribers on unsubscribe', () => {
const { connect, Provider, actions, subscribe, unsubscribe } = initStore(mockStore)
const Count = connect(state => ({ count: state.count }))(TestCount)
const subscriber = jest.fn()
subscribe(subscriber)
const component = renderer.create(
<Provider>
<Count />
</Provider>
);
unsubscribe(subscriber)
actions.increment()
component.toJSON() // invoke render
expect(subscriber).toHaveBeenCalledTimes(0)
})

test('should allow action to return a promise', () => {
const { connect, Provider, actions, subscribe } = initStore(mockStore)
const Count = connect(state => ({ count: state.count }))(TestCount)
Expand Down
15 changes: 10 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ export const initStore: Function = (store, ...middlewares) => {
subscriptions = [...subscriptions, fn]
}

const unsubscribe = fn => {
subscriptions = subscriptions.filter(subscriber => subscriber !== fn)
}

const actions = Object.keys(store.actions).reduce(
(r, v) => ({
...r,
Expand All @@ -48,9 +52,9 @@ export const initStore: Function = (store, ...middlewares) => {
_children = () => this.props.children

prevent = ({ state, actions }) => {
const { mapStateToProps } = this.props
const { mapStateToProps, children /* exclude children from rest */, ...rest } = this.props
return (
<Prevent {...mapStateToProps(state)} actions={actions} _children={this._children} />
<Prevent {...mapStateToProps(state)} {...rest} actions={actions} _children={this._children} />
)
}

Expand All @@ -64,9 +68,9 @@ export const initStore: Function = (store, ...middlewares) => {
}

const connect = mapStateToProps => WrappedComponent => {
const ConnectComponent = (props) =>
<Consumer mapStateToProps={mapStateToProps}>
{injectedProps => <WrappedComponent {...props} {...injectedProps} />}
const ConnectComponent = props =>
<Consumer mapStateToProps={mapStateToProps} {...props}>
{injectedProps => <WrappedComponent {...injectedProps} />}
</Consumer>
ConnectComponent.displayName = `Connect(${WrappedComponent.displayName || WrappedComponent.name || 'Unknown'})`
return ConnectComponent
Expand Down Expand Up @@ -104,5 +108,6 @@ export const initStore: Function = (store, ...middlewares) => {
getState,
connect,
subscribe,
unsubscribe,
}
}

0 comments on commit 622d576

Please sign in to comment.