Skip to content

Commit 40a03b0

Browse files
fix(overmind): allow passed in proxy values to be mutated
1 parent a8a52ef commit 40a03b0

File tree

7 files changed

+44
-16
lines changed

7 files changed

+44
-16
lines changed

packages/demos/react-typescript-todomvc/src/app/actions.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as React from 'react'
22
import { Action } from 'overmind'
3+
import { Todo } from './state'
34

45
type ChangeEvent = React.ChangeEvent<HTMLInputElement>
56

@@ -21,7 +22,6 @@ export const addTodo: Action = ({ state }) => {
2122
state.newTodoTitle = ''
2223
}
2324

24-
export const toggleCompleted: Action<string> = ({ value: todoId, state }) => {
25-
const todo = state.todos.find((todo) => todo.id === todoId)
25+
export const toggleCompleted: Action<Todo> = ({ value: todo }) => {
2626
todo.completed = !todo.completed
2727
}

packages/demos/react-typescript-todomvc/src/components/Todo/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ type Props = {
88
} & Connect
99

1010
const Todo: React.SFC<Props> = ({ todo, app }) => (
11-
<Item onClick={() => app.actions.toggleCompleted(todo.id)}>
11+
<Item onClick={() => app.actions.toggleCompleted(todo)}>
1212
<Completed completed={todo.completed}></Completed> {todo.title}
1313
</Item>
1414
)

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

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ function toJSON(obj) {
88
function createDefaultApp() {
99
const state = {
1010
foo: 'bar',
11+
item: {
12+
isAwesome: true,
13+
},
1114
}
1215
const changeFoo: Action = (context) => {
1316
context.state.foo = 'bar2'
@@ -24,11 +27,15 @@ function createDefaultApp() {
2427
await Promise.resolve()
2528
context.state.foo = 'bar2'
2629
}
30+
const changeValue: Action<{ isAwesome: boolean }> = (context) => {
31+
context.value.isAwesome = !context.value.isAwesome
32+
}
2733
const actions = {
2834
changeFoo,
2935
changeFooWithEffect,
3036
waitAndChangeFoo,
3137
asyncChangeFoo,
38+
changeValue,
3239
}
3340
const effects = {
3441
hello() {
@@ -49,11 +56,7 @@ function createDefaultApp() {
4956
actions: typeof actions
5057
effects: typeof effects
5158
}>
52-
type Action<Value = void, ReturnValue = Value> = TAction<
53-
App,
54-
Value,
55-
ReturnValue
56-
>
59+
type Action<Value = void> = TAction<App, Value>
5760

5861
return new Overmind(config)
5962
}
@@ -296,4 +299,10 @@ describe('Overmind', () => {
296299
expect(result).toEqual(['foo', 'bar'])
297300
})
298301
})
302+
test('should allow mutations on passed values', () => {
303+
expect.assertions(2)
304+
const app = createDefaultApp()
305+
expect(() => app.actions.changeValue(app.state.item)).not.toThrow()
306+
expect(app.state.item.isAwesome).toBe(false)
307+
})
299308
})

packages/node_modules/overmind/src/index.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,7 @@ export interface IApp {}
3131

3232
type App = BaseApp & IApp
3333

34-
export type Action<Value = void, ReturnValue = any> = TAction<
35-
App,
36-
Value,
37-
ReturnValue
38-
>
34+
export type Action<Value = void> = TAction<App, Value>
3935

4036
export type Context<Value> = TContext<App, Value>
4137

@@ -215,7 +211,11 @@ export class Overmind<Config extends Configuration> implements BaseApp {
215211
const scopedTree = this.proxyStateTree.getScopedTree()
216212
scopedTree.startMutationTracking()
217213
const result = action(
218-
this.createContext(value, execution, scopedTree.get())
214+
this.createContext(
215+
scopedTree.scope(value),
216+
execution,
217+
scopedTree.get()
218+
)
219219
)
220220
this.eventHub.emit(EventType.OPERATOR_END, {
221221
...execution,

packages/node_modules/overmind/src/types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ export type TContext<App extends BaseApp, Value> = TBaseContext<App> & {
3131
value: Value
3232
}
3333

34-
export type TAction<App extends BaseApp, Value, ReturnValue = Value> = (
34+
export type TAction<App extends BaseApp, Value> = (
3535
context: TContext<App, Value>
36-
) => ReturnValue
36+
) => any
3737

3838
export type TOperator<C, RC> = (
3939
err: Error,

packages/node_modules/proxy-state-tree/src/index.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -951,4 +951,18 @@ describe('SCOPED', () => {
951951
expect(tree.get().foo).toBe('bar2')
952952
expect(scoped.get().foo).toBe('bar2')
953953
})
954+
it('should be able to change scope of state', () => {
955+
const tree = new ProxyStateTree({
956+
foo: 'bar',
957+
})
958+
959+
const scoped = tree.getScopedTree()
960+
const changeScope = scoped.scope(tree.get())
961+
962+
scoped.startMutationTracking()
963+
changeScope.foo = 'bar2'
964+
scoped.clearMutationTracking()
965+
expect(tree.get().foo).toBe('bar2')
966+
expect(scoped.get().foo).toBe('bar2')
967+
})
954968
})

packages/node_modules/proxy-state-tree/src/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ export class ProxyStateTree {
7474

7575
return instance
7676
}
77+
scope(value) {
78+
return value && value[IS_PROXY]
79+
? proxify(this, value[VALUE], value[PATH])
80+
: value
81+
}
7782
addTrackingPath(path) {
7883
if (this.status.has(STATUS.TRACKING_PATHS)) {
7984
this.paths[this.paths.length - 1].add(path)

0 commit comments

Comments
 (0)