Skip to content

Commit 2058a91

Browse files
feat(overmind): initial implementation of revertable
1 parent b9e625e commit 2058a91

File tree

7 files changed

+70
-28
lines changed

7 files changed

+70
-28
lines changed

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,6 @@ describe('Overmind', () => {
221221
method: 'set',
222222
path: 'foo',
223223
hasChangedValue: true,
224-
revertValue: 'bar',
225224
},
226225
],
227226
executionId: 0,

packages/node_modules/overmind/src/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,15 @@ export class Overmind<ThisConfig extends IConfiguration>
479479
execution,
480480
proxyStateTree: this.proxyStateTree,
481481
effects: this.trackEffects(this.effects, execution),
482+
revertable: (cb: () => void) => {
483+
const mutations: IMutation[] = []
484+
const dispose = this.addMutationListener((mutation) => {
485+
mutations.unshift(mutation)
486+
})
487+
cb()
488+
dispose()
489+
return () => mutations.forEach((mutation) => mutation.revert())
490+
},
482491
}
483492
}
484493
private scopeValue(value: any, tree: TTree) {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ describe('Mock', () => {
3838
path: 'foo',
3939
args: ['bar2!!!'],
4040
hasChangedValue: true,
41-
revertValue: 'bar',
41+
revert: overmind.mutations[0].revert,
4242
},
4343
])
4444
})
@@ -76,7 +76,7 @@ describe('Mock', () => {
7676
path: 'foo',
7777
args: ['bar!'],
7878
hasChangedValue: true,
79-
revertValue: 'bar',
79+
revert: overmind.mutations[0].revert,
8080
},
8181
])
8282
})

packages/node_modules/overmind/src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export type IContext<ThisConfig extends IConfiguration> = {
3737
state: ResolveState<ThisConfig['state']>
3838
actions: ResolveActions<ThisConfig['actions']>
3939
effects: ThisConfig['effects']
40+
revertable: () => void
4041
}
4142

4243
export interface IReaction<ThisConfig extends IConfiguration> {

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

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,31 +21,46 @@ const arrayMutations = new Set([
2121
const getValue = (proxyOrValue) =>
2222
proxyOrValue && proxyOrValue[IS_PROXY] ? proxyOrValue[VALUE] : proxyOrValue
2323

24-
const getArrayRevertValue = (method: string, target: any[], args: any[]) => {
24+
const getArrayMutationRevert = (method: string, target: any[], args: any[]) => {
2525
switch (method) {
2626
case 'push': {
27-
return null
27+
return () => {
28+
target.splice(target.indexOf(args[0]), 1)
29+
}
2830
}
2931
case 'shift': {
30-
return target[0]
32+
const value = target[0]
33+
return () => {
34+
target.unshift(value)
35+
}
3136
}
3237
case 'pop': {
33-
return target[target.length - 1]
38+
const index = target.length - 1
39+
const value = target[index]
40+
41+
return () => {
42+
target.splice(index, 1, value)
43+
}
3444
}
3545
case 'unshift': {
36-
return null
46+
return () => {
47+
target.splice(target.indexOf(args[0]), 1)
48+
}
3749
}
3850
case 'splice': {
39-
return target.slice(args[0], args[1])
51+
const removedValues = target.slice(args[0], args[1])
52+
const addedValues = args.slice(2)
53+
return () =>
54+
target.splice(args[0], args[1] + addedValues.length, ...removedValues)
4055
}
4156
case 'reverse': {
42-
return null
57+
return () => target.reverse()
4358
}
4459
case 'sort': {
45-
return null
60+
return () => target.sort((a, b) => -1 * args[0](a, b))
4661
}
4762
case 'copyWithin': {
48-
return null
63+
return () => target
4964
}
5065
}
5166
}
@@ -174,7 +189,7 @@ export class Proxifier {
174189
path: path,
175190
args: args,
176191
hasChangedValue: true,
177-
revertValue: getArrayRevertValue(method, target, args),
192+
revert: getArrayMutationRevert(method, target, args),
178193
})
179194

180195
if (process.env.NODE_ENV === 'production') {
@@ -206,12 +221,20 @@ export class Proxifier {
206221
)
207222

208223
const mutationTree = proxifier.getMutationTree()
224+
const existingValue = target[prop]
209225

210226
mutationTree.addMutation({
211227
method: 'set',
212228
path: nestedPath,
213229
args: [value],
214230
hasChangedValue: true,
231+
revert: () => {
232+
if (existingValue === undefined) {
233+
delete target[prop]
234+
} else {
235+
target[prop] = existingValue
236+
}
237+
},
215238
})
216239

217240
return Reflect.set(target, prop, value)
@@ -300,14 +323,21 @@ export class Proxifier {
300323
}
301324

302325
const mutationTree = proxifier.getMutationTree()
326+
const existingValue = target[prop]
303327

304328
mutationTree.addMutation(
305329
{
306330
method: 'set',
307331
path: nestedPath,
308332
args: [value],
309333
hasChangedValue: value !== target[prop],
310-
revertValue: target[prop],
334+
revert: () => {
335+
if (existingValue === undefined) {
336+
delete target[prop]
337+
} else {
338+
target[prop] = existingValue
339+
}
340+
},
311341
},
312342
objectChangePath
313343
)
@@ -329,14 +359,17 @@ export class Proxifier {
329359
}
330360

331361
const mutationTree = proxifier.getMutationTree()
362+
const existingValue = target[prop]
332363

333364
mutationTree.addMutation(
334365
{
335366
method: 'unset',
336367
path: nestedPath,
337368
args: [],
338369
hasChangedValue: true,
339-
revertValue: target[prop],
370+
revert: () => {
371+
target[prop] = existingValue
372+
},
340373
},
341374
objectChangePath
342375
)

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

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ describe('TrackStateAccessTree', () => {
6060
path: 'foo',
6161
args: ['bar2'],
6262
hasChangedValue: true,
63-
revertValue: 'bar',
63+
revert: mutation.revert,
6464
})
6565
})
6666

@@ -204,7 +204,7 @@ describe('OBJECTS', () => {
204204
path: 'foo',
205205
args: ['bar'],
206206
hasChangedValue: false,
207-
revertValue: 'bar',
207+
revert: mutationTree.mutations[0].revert,
208208
},
209209
])
210210
expect(renderCount).toBe(0)
@@ -222,7 +222,7 @@ describe('OBJECTS', () => {
222222
path: 'foo',
223223
args: ['bar2'],
224224
hasChangedValue: true,
225-
revertValue: 'bar',
225+
revert: mutationTree.mutations[0].revert,
226226
},
227227
])
228228
expect(mutationTree.state.foo).toBe('bar2')
@@ -242,7 +242,7 @@ describe('OBJECTS', () => {
242242
path: 'foo',
243243
args: [],
244244
hasChangedValue: true,
245-
revertValue: 'bar',
245+
revert: mutationTree.mutations[0].revert,
246246
},
247247
])
248248
expect(mutationTree.state.foo).toBe(undefined)
@@ -424,7 +424,7 @@ describe('ARRAYS', () => {
424424
path: 'foo',
425425
args: ['bar'],
426426
hasChangedValue: true,
427-
revertValue: null,
427+
revert: mutationTree.mutations[0].revert,
428428
},
429429
])
430430

@@ -444,7 +444,7 @@ describe('ARRAYS', () => {
444444
path: 'foo',
445445
args: [],
446446
hasChangedValue: true,
447-
revertValue: 'foo',
447+
revert: mutationTree.mutations[0].revert,
448448
},
449449
])
450450

@@ -465,7 +465,7 @@ describe('ARRAYS', () => {
465465
path: 'foo',
466466
args: [],
467467
hasChangedValue: true,
468-
revertValue: 'foo',
468+
revert: mutationTree.mutations[0].revert,
469469
},
470470
])
471471

@@ -485,7 +485,7 @@ describe('ARRAYS', () => {
485485
path: 'foo',
486486
args: ['foo'],
487487
hasChangedValue: true,
488-
revertValue: null,
488+
revert: mutationTree.mutations[0].revert,
489489
},
490490
])
491491

@@ -505,7 +505,7 @@ describe('ARRAYS', () => {
505505
path: 'foo',
506506
args: [0, 1, 'bar'],
507507
hasChangedValue: true,
508-
revertValue: ['foo'],
508+
revert: mutationTree.mutations[0].revert,
509509
},
510510
])
511511

@@ -648,7 +648,7 @@ describe('REACTIONS', () => {
648648
path: 'foo',
649649
args: ['bar2'],
650650
hasChangedValue: true,
651-
revertValue: 'bar',
651+
revert: mutation.revert,
652652
})
653653
})
654654

@@ -755,14 +755,14 @@ describe('REACTIONS', () => {
755755
method: 'set',
756756
args: ['bar2'],
757757
hasChangedValue: true,
758-
revertValue: 'bar',
758+
revert: flushResult.mutations[0].revert,
759759
},
760760
{
761761
path: 'foo',
762762
method: 'set',
763763
args: ['bar3'],
764764
hasChangedValue: true,
765-
revertValue: 'bar2',
765+
revert: flushResult.mutations[1].revert,
766766
},
767767
],
768768
})

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export interface IMutation {
88
path: string
99
args: any[]
1010
hasChangedValue: boolean
11-
revertValue?: any
11+
revert: () => void
1212
}
1313

1414
export interface IMutationCallback {

0 commit comments

Comments
 (0)