Skip to content

Commit 473802c

Browse files
gaspardchristianalfoni
authored andcommitted
fix(overmind): extract modules into its own function
this greatly simplifies the types BREAKING CHANGE: modules are now supported by the "modules" function
1 parent ca15456 commit 473802c

File tree

3 files changed

+164
-188
lines changed

3 files changed

+164
-188
lines changed

packages/node_modules/overmind/src/index.test.ts

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import App, { TAction, TConfig, DynamicAction, dynamicModule } from './'
1+
import App, {
2+
DynamicAction,
3+
TAction,
4+
TConfig,
5+
dynamicModule,
6+
modules,
7+
} from './'
28

39
describe('Overmind', () => {
410
test('should instantiate app with state', () => {
@@ -14,8 +20,8 @@ describe('Overmind', () => {
1420

1521
expect(app.state.foo).toEqual('bar')
1622
})
17-
test('should instantiate app with namespaces', () => {
18-
const fooAction: Action<string> = ({ run }) => run(() => {})
23+
test('should instantiate app with modules', () => {
24+
const fooAction: TAction<string> = ({ run }) => run(() => {})
1925

2026
const foo = {
2127
state: {
@@ -36,21 +42,16 @@ describe('Overmind', () => {
3642
bar: fooAction,
3743
},
3844
}
39-
type Config = TConfig<{
40-
modules: {
41-
foo: typeof foo
42-
bar: typeof bar
43-
}
44-
}>
4545

46-
type Action<Input = void, Output = any> = TAction<Input, Output, Config>
47-
48-
const config = {
46+
const config = modules({
4947
modules: {
5048
foo,
5149
bar,
5250
},
53-
}
51+
})
52+
53+
type Config = TConfig<typeof config>
54+
type Action<Input = void, Output = any> = TAction<Input, Output, Config>
5455

5556
const app = new App(config)
5657

@@ -74,11 +75,11 @@ describe('Overmind', () => {
7475
}
7576
})
7677

77-
const config = {
78+
const config = modules({
7879
modules: {
7980
foo,
8081
},
81-
}
82+
})
8283

8384
const app = new App(config)
8485

packages/node_modules/overmind/src/index.ts

Lines changed: 16 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import {
1919
} from './internalTypes'
2020
import Reaction from './reaction'
2121

22+
export { modules } from './modules'
23+
2224
export { IValueAction, Compose, EventType }
2325

2426
export const log = (...objects: any[]) =>
@@ -37,15 +39,6 @@ export type Configuration = {
3739
effects?: any
3840
actions?: any
3941
reactions?: any
40-
modules?: {
41-
[namespace: string]: {
42-
onInitialize?: any
43-
state?: any
44-
effects?: any
45-
actions?: any
46-
reactions?: any
47-
}
48-
}
4942
}
5043

5144
/*
@@ -67,43 +60,9 @@ type StateNode<State extends object> = {
6760
: State[P] extends object ? StateNode<State[P]> : State[P]
6861
}
6962

70-
export type TState<Config extends Configuration> = [Config['state']] extends [
71-
undefined
72-
]
73-
? {
74-
[P in keyof SubType<Config['modules'], { state: {} }>]: SubType<
75-
Config['modules'],
76-
{ state: {} }
77-
>[P]['state']
78-
}
79-
: [Config['modules']] extends [undefined]
80-
? Config['state']
81-
: Config['state'] &
82-
{
83-
[P in keyof SubType<Config['modules'], { state: {} }>]: SubType<
84-
Config['modules'],
85-
{ state: {} }
86-
>[P]['state']
87-
}
63+
export type TState<Config extends Configuration> = Config['state']
8864

89-
export type TEffects<Config extends Configuration> = [
90-
Config['effects']
91-
] extends [undefined]
92-
? {
93-
[P in keyof SubType<Config['modules'], { effects: object }>]: SubType<
94-
Config['modules'],
95-
{ effects: object }
96-
>[P]['effects']
97-
}
98-
: [Config['modules']] extends [undefined]
99-
? Config['effects']
100-
: Config['effects'] &
101-
{
102-
[P in keyof SubType<Config['modules'], { effects: object }>]: SubType<
103-
Config['modules'],
104-
{ effects: object }
105-
>[P]['effects']
106-
}
65+
export type TEffects<Config extends Configuration> = Config['effects']
10766

10867
export type Mutate<Value = any> = (state: IApp['state'], value: Value) => void
10968

@@ -131,8 +90,8 @@ export type Action<InitialValue = void, ReturnValue = any> = Compose<
13190

13291
export type TAction<
13392
InitialValue,
134-
ReturnValue,
135-
App extends { state: any; effects: any }
93+
ReturnValue = InitialValue,
94+
App extends { state: any; effects: any } = { state: any; effects: any }
13695
> = Compose<
13796
App['state'],
13897
App['effects'] & { state: App['state'] },
@@ -172,56 +131,10 @@ export type Compute<Input, Output> = (
172131
) => (state: IApp['state']) => Output
173132

174133
export type TConfig<Config extends Configuration> = {
175-
state: [Config['state']] extends [undefined]
176-
? {
177-
[P in keyof SubType<Config['modules'], { state: {} }>]: SubType<
178-
Config['modules'],
179-
{ state: {} }
180-
>[P]['state']
181-
}
182-
: [Config['modules']] extends [undefined]
183-
? Config['state']
184-
: Config['state'] &
185-
{
186-
[P in keyof SubType<Config['modules'], { state: {} }>]: SubType<
187-
Config['modules'],
188-
{ state: {} }
189-
>[P]['state']
190-
}
191-
effects: [Config['effects']] extends [undefined]
192-
? {
193-
[P in keyof SubType<Config['modules'], { effects: object }>]: SubType<
194-
Config['modules'],
195-
{ effects: object }
196-
>[P]['effects']
197-
}
198-
: [Config['modules']] extends [undefined]
199-
? Config['effects']
200-
: Config['effects'] &
201-
{
202-
[P in keyof SubType<
203-
Config['modules'],
204-
{ effects: object }
205-
>]: SubType<Config['modules'], { effects: object }>[P]['effects']
206-
}
207-
actions: [Config['actions']] extends [undefined]
208-
? {
209-
[P in keyof SubType<Config['modules'], { actions: object }>]: SubType<
210-
Config['modules'],
211-
{ actions: object }
212-
>[P]['actions']
213-
}
214-
: [Config['modules']] extends [undefined]
215-
? Config['actions']
216-
: Config['actions'] &
217-
{
218-
[P in keyof SubType<
219-
Config['modules'],
220-
{ actions: object }
221-
>]: SubType<Config['modules'], { actions: object }>[P]['actions']
222-
}
134+
state: Config['state'] & {}
135+
effects: Config['effects'] & {}
136+
actions: Config['actions'] & {}
223137
reactions: any
224-
namespaces: any
225138
}
226139

227140
export type TActionCreator<App> = {
@@ -268,10 +181,6 @@ export default class App<
268181
}
269182
}
270183

271-
/*
272-
Mutate module functions into module objects
273-
*/
274-
this.mutateModuleFunctionsIntoModules(configuration)
275184
/*
276185
Set up an eventHub to trigger information from derived, computed and reactions
277186
*/
@@ -352,36 +261,11 @@ export default class App<
352261
this.proxyStateTree = proxyStateTree
353262
this.eventHub = eventHub
354263

355-
const initializers = this.getInitializers(configuration)
356-
357-
if (!initializers.length) {
358-
return
359-
}
360-
361-
const rootInitializer =
362-
initializers[0].name === 'onInitialize' ? initializers.shift() : null
363-
364-
let onInitialize
365-
366-
if (initializers.length) {
367-
onInitialize = operators.parallel(initializers)
368-
}
369-
370-
if (rootInitializer) {
371-
onInitialize = operators.compose(rootInitializer)
372-
}
373-
374-
// @ts-ignore
375-
onInitialize.displayName = 'onInitialize'
376-
onInitialize(undefined)
377-
}
378-
private mutateModuleFunctionsIntoModules(config: Configuration) {
379-
if (config.modules) {
380-
Object.keys(config.modules).forEach((key) => {
381-
if (typeof config.modules[key] === 'function') {
382-
config.modules[key] = (config.modules[key] as any)(key)
383-
}
384-
})
264+
if (configuration.onInitialize) {
265+
const onInitialize = operators.compose(configuration.onInitialize)
266+
// @ts-ignore
267+
onInitialize.displayName = 'onInitialize'
268+
onInitialize(undefined)
385269
}
386270
}
387271
private initializeDevtools(host, actionChain, eventHub, proxyStateTree) {
@@ -492,44 +376,14 @@ export default class App<
492376
reaction.create(reactions[name][0], reactions[name][1])
493377
})
494378
}
495-
private getState(configuration) {
379+
private getState(configuration: Configuration) {
496380
let state = {}
497381
if (configuration.state) {
498382
state = this.processState(configuration.state)
499383
}
500-
if (configuration.modules) {
501-
Object.keys(configuration.modules).reduce((aggr, key) => {
502-
if (configuration.modules[key].state) {
503-
return Object.assign(aggr, {
504-
[key]: this.processState(configuration.modules[key].state),
505-
})
506-
}
507-
508-
return aggr
509-
}, state)
510-
}
511384

512385
return state
513386
}
514-
private getInitializers(configuration) {
515-
let initializers = []
516-
if (configuration.onInitialize) {
517-
initializers.push(configuration.onInitialize)
518-
}
519-
if (configuration.modules) {
520-
initializers = Object.keys(configuration.modules).reduce((aggr, key) => {
521-
if (configuration.modules[key].onInitialize) {
522-
configuration.modules[key].onInitialize.displayName =
523-
key + '.onInitialize'
524-
return aggr.concat(configuration.modules[key].onInitialize)
525-
}
526-
527-
return aggr
528-
}, initializers)
529-
}
530-
531-
return initializers
532-
}
533387
private processState(state: {}) {
534388
return Object.keys(state).reduce((aggr, key) => {
535389
const value = state[key]
@@ -544,22 +398,11 @@ export default class App<
544398
return aggr
545399
}, {})
546400
}
547-
private getActions(configuration, operators) {
401+
private getActions(configuration: Configuration, operators) {
548402
let actions = {}
549403
if (configuration.actions) {
550404
actions = configuration.actions
551405
}
552-
if (configuration.modules) {
553-
Object.keys(configuration.modules).reduce((aggr, key) => {
554-
if (configuration.modules[key].actions) {
555-
return Object.assign(aggr, {
556-
[key]: configuration.modules[key].actions,
557-
})
558-
}
559-
560-
return aggr
561-
}, actions)
562-
}
563406

564407
const evaluatedActions = Object.keys(actions).reduce((aggr, name) => {
565408
if (typeof actions[name] === 'function') {

0 commit comments

Comments
 (0)