Skip to content

Commit 0a16bec

Browse files
Merge pull request cerebral#143 from cerebral/renameToConfig
feat(overmind): rename modules to config and add merge. allow for new…
2 parents 93077f9 + cd13b71 commit 0a16bec

File tree

10 files changed

+346
-87
lines changed

10 files changed

+346
-87
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"name": "overmind/config",
3+
"private": true,
4+
"main": "../lib/config",
5+
"module": "../es/config",
6+
"jsnext:main": "../es/config",
7+
"typings": "../lib/config.d.ts"
8+
}

packages/node_modules/overmind/modules/package.json

Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { merge, namespaced } from './config'
2+
3+
describe('Config', () => {
4+
test('should merge configs', () => {
5+
const configA = {
6+
state: {
7+
foo: 'bar',
8+
},
9+
}
10+
const configB = {
11+
state: {
12+
bar: 'baz',
13+
},
14+
}
15+
const merged = merge(configA, configB)
16+
17+
expect(merged.state.foo).toEqual('bar')
18+
expect(merged.state.bar).toEqual('baz')
19+
})
20+
test('should namespace', () => {
21+
const configA = {
22+
state: {
23+
foo: 'bar',
24+
},
25+
}
26+
const configB = {
27+
state: {
28+
bar: 'baz',
29+
},
30+
}
31+
const merged = namespaced({ configA, configB })
32+
33+
expect(merged.state.configA.foo).toEqual('bar')
34+
expect(merged.state.configB.bar).toEqual('baz')
35+
})
36+
test('should merge normal and namespaced', () => {
37+
const configA = {
38+
state: {
39+
foo: 'bar',
40+
},
41+
}
42+
const configB = {
43+
state: {
44+
bar: 'baz',
45+
},
46+
}
47+
const merged = merge(configA, namespaced({ configB }))
48+
49+
expect(merged.state.foo).toEqual('bar')
50+
expect(merged.state.configB.bar).toEqual('baz')
51+
})
52+
})
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
import { Configuration } from './'
2+
3+
/*
4+
MERGE
5+
*/
6+
7+
export function merge<A extends Configuration, B extends Configuration>(
8+
configA: A,
9+
configB: B
10+
): A & B
11+
export function merge<
12+
A extends Configuration,
13+
B extends Configuration,
14+
C extends Configuration
15+
>(configA: A, configB: B, configC: C): A & B & C
16+
export function merge<
17+
A extends Configuration,
18+
B extends Configuration,
19+
C extends Configuration,
20+
D extends Configuration
21+
>(configA: A, configB: B, configC: C, configD: D): A & B & C & D
22+
export function merge<
23+
A extends Configuration,
24+
B extends Configuration,
25+
C extends Configuration,
26+
D extends Configuration,
27+
E extends Configuration
28+
>(configA: A, configB: B, configC: C, configD: D, configE: E): A & B & C & D & E
29+
export function merge<
30+
A extends Configuration,
31+
B extends Configuration,
32+
C extends Configuration,
33+
D extends Configuration,
34+
E extends Configuration,
35+
F extends Configuration
36+
>(
37+
configA: A,
38+
configB: B,
39+
configC: C,
40+
configD: D,
41+
configE: E,
42+
configF: F
43+
): A & B & C & D & E & F
44+
export function merge<
45+
A extends Configuration,
46+
B extends Configuration,
47+
C extends Configuration,
48+
D extends Configuration,
49+
E extends Configuration,
50+
F extends Configuration,
51+
G extends Configuration
52+
>(
53+
configA: A,
54+
configB: B,
55+
configC: C,
56+
configD: D,
57+
configE: E,
58+
configF: F,
59+
configG: G
60+
): A & B & C & D & E & F & G
61+
export function merge<
62+
A extends Configuration,
63+
B extends Configuration,
64+
C extends Configuration,
65+
D extends Configuration,
66+
E extends Configuration,
67+
F extends Configuration,
68+
G extends Configuration,
69+
H extends Configuration
70+
>(
71+
configA: A,
72+
configB: B,
73+
configC: C,
74+
configD: D,
75+
configE: E,
76+
configF: F,
77+
configG: G,
78+
configH: H
79+
): A & B & C & D & E & F & G & H
80+
export function merge<
81+
A extends Configuration,
82+
B extends Configuration,
83+
C extends Configuration,
84+
D extends Configuration,
85+
E extends Configuration,
86+
F extends Configuration,
87+
G extends Configuration,
88+
H extends Configuration,
89+
I extends Configuration
90+
>(
91+
configA: A,
92+
configB: B,
93+
configC: C,
94+
configD: D,
95+
configE: E,
96+
configF: F,
97+
configG: G,
98+
configH: H,
99+
configI: I
100+
): A & B & C & D & E & F & G & H & I
101+
export function merge(...configurations: Configuration[]): Configuration {
102+
const initializers = configurations.reduce(
103+
(aggr, config) =>
104+
config.onInitialize ? aggr.concat(config.onInitialize) : aggr,
105+
[] as any[]
106+
)
107+
108+
return configurations.reduce(
109+
(aggr, config) => {
110+
return {
111+
onInitialize: aggr.onInitialize,
112+
state: {
113+
...aggr.state,
114+
...config.state,
115+
},
116+
effects: {
117+
...aggr.effects,
118+
...config.effects,
119+
},
120+
actions: {
121+
...aggr.actions,
122+
...config.actions,
123+
},
124+
reactions: {
125+
...aggr.reactions,
126+
...config.reactions,
127+
},
128+
}
129+
},
130+
{
131+
onInitialize: initializers.length
132+
? (context) => Promise.all(initializers.map((cb) => cb(context)))
133+
: undefined,
134+
state: {},
135+
effects: {},
136+
actions: {},
137+
reactions: {},
138+
}
139+
)
140+
}
141+
142+
/*
143+
NAMESPACED
144+
*/
145+
interface NamespacedConfiguration {
146+
[namespace: string]: {
147+
onInitialize?: any
148+
state?: {}
149+
effects?: {}
150+
actions?: {}
151+
reactions?: {}
152+
}
153+
}
154+
155+
function parseNamespacedConfig(
156+
result: { actions: any; effects: any; state: any; initializers: any[] },
157+
name: string,
158+
config: Configuration
159+
) {
160+
const { actions, effects, onInitialize, state }: Configuration = config
161+
162+
if (actions) {
163+
result.actions[name] = actions
164+
}
165+
if (effects) {
166+
result.effects[name] = effects
167+
}
168+
if (state) {
169+
result.state[name] = state
170+
}
171+
if (onInitialize) {
172+
result.initializers.push(onInitialize)
173+
}
174+
}
175+
176+
export function namespaced<T extends NamespacedConfiguration>(
177+
namespaces: T
178+
): {
179+
onInitialize?: any
180+
state: { [P in keyof T]: T[P]['state'] }
181+
effects: { [P in keyof T]: T[P]['effects'] }
182+
actions: { [P in keyof T]: T[P]['actions'] }
183+
} {
184+
const result: any = {
185+
initializers: [],
186+
actions: {},
187+
effects: {},
188+
state: {},
189+
}
190+
191+
Object.keys(namespaces).forEach((name) => {
192+
parseNamespacedConfig(result, name, namespaces[name])
193+
})
194+
195+
return Object.assign(
196+
{
197+
actions: result.actions,
198+
effects: result.effects,
199+
state: result.state,
200+
},
201+
result.initializers.length
202+
? {
203+
onInitialize: (context) =>
204+
Promise.all(result.initializers.map((cb) => cb(context))),
205+
}
206+
: {}
207+
)
208+
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { EventType, Overmind, TAction, TApp } from './'
2-
import { modules } from './modules'
2+
import { namespaced } from './config'
33

44
function toJSON(obj) {
55
return JSON.parse(JSON.stringify(obj))
@@ -273,7 +273,7 @@ describe('Overmind', () => {
273273

274274
const config = Object.assign(
275275
{},
276-
modules({
276+
namespaced({
277277
foo,
278278
bar,
279279
})
@@ -289,7 +289,7 @@ describe('Overmind', () => {
289289
test('should instantiate modules with onInitialize', () => {
290290
const result: string[] = []
291291
const app = new Overmind(
292-
modules({
292+
namespaced({
293293
foo: {
294294
onInitialize: () => {
295295
result.push('foo')

packages/node_modules/overmind/src/modules.ts

Lines changed: 0 additions & 62 deletions
This file was deleted.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Config
2+
3+
The base configuration of your application is:
4+
5+
`{ state, actions, effects, reactions }`
6+
7+
When your application grows it will be necessary to split up your configuration. Overmind provides some helpers allowing you to structure and scale up your configuration.
8+
9+
## merge
10+
Allows you to merge configurations together.
11+
12+
```marksy
13+
h(Example, { name: "api/config_merge" })
14+
```
15+
16+
Note that merge can be useful to combine a root configuration with namespaced configuration.
17+
18+
## namespaced
19+
Allows you to namespace configurations by a key.
20+
21+
```marksy
22+
h(Example, { name: "api/config_namespaced" })
23+
```

0 commit comments

Comments
 (0)