Skip to content

Commit e220a6b

Browse files
fix(overmind): use json for class serialization support
1 parent 839cd15 commit e220a6b

File tree

8 files changed

+44
-46
lines changed

8 files changed

+44
-46
lines changed

packages/node_modules/overmind/src/Devtools.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { stringify } from 'proxy-state-tree'
1+
import { IS_JSON } from './utils'
22

33
export type Message = {
44
type: string
@@ -71,15 +71,25 @@ export class Devtools {
7171
send(message: Message) {
7272
const safeClassNames = this.safeClassNames
7373
const unsafeClassNames = this.unsafeClassNames
74-
const stringifiedMessage = stringify(
74+
const stringifiedMessage = JSON.stringify(
7575
message,
7676
function (_, value) {
7777
if (typeof value === 'function') {
7878
return '[Function]'
7979
}
80+
8081
if (this.__CLASS__) {
8182
return value
8283
}
84+
85+
if (value && value[IS_JSON] && value.constructor.name !== 'Object') {
86+
return {
87+
__CLASS__: true,
88+
name: value.constructor.name,
89+
value
90+
}
91+
}
92+
8393
if (
8494
typeof value === 'object' &&
8595
value !== null &&
@@ -89,7 +99,6 @@ export class Devtools {
8999
) {
90100
if (!safeClassNames.has(value.constructor.name) && !unsafeClassNames.has(value.constructor.name)) {
91101
try {
92-
JSON.stringify(value)
93102
safeClassNames.add(value.constructor.name)
94103
} catch {
95104
unsafeClassNames.add(value.constructor.name)
@@ -109,14 +118,7 @@ export class Devtools {
109118

110119
return value
111120
},
112-
0,
113-
function (value) {
114-
return {
115-
__CLASS__: true,
116-
name: this.constructor.name,
117-
value
118-
}
119-
}
121+
0
120122
)
121123
this.buffer.push(stringifiedMessage)
122124
this.sendBuffer()

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ function createDefaultOvermind() {
2525
item: {
2626
isAwesome: true,
2727
},
28-
value: [] as StateValue[]
28+
value: null as unknown as StateValue
2929
}
3030
const changeFoo: Action<void, string> = (context) => {
3131
context.state.foo = 'bar2'
@@ -392,15 +392,15 @@ describe('Overmind', () => {
392392
item: {
393393
isAwesome: false
394394
},
395-
value: [{
395+
value: {
396396
value: 'bar'
397-
}]
397+
}
398398
})
399399
expect(app.state.foo).toEqual('bar2')
400400
expect(app.state.item).toEqual({
401401
isAwesome: false
402402
})
403-
expect(app.state.value[0].toJSON()).toEqual({
403+
expect(app.state.value.toJSON()).toEqual({
404404
value: 'bar'
405405
})
406406
})

packages/node_modules/overmind/src/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,7 @@ export interface OnInitialize extends IOnInitialize<Config> {}
9191

9292
export interface Reaction extends IReaction<Config> {}
9393

94-
export const json = (obj: any) =>
95-
deepCopy(obj && obj[IS_PROXY] ? obj[VALUE] : obj)
94+
export { json } from './utils'
9695

9796
export const rehydrate = <T extends IState>(state: T, source: IMutation[] | IState, classes: RehydrateClasses<T> = {} as RehydrateClasses<T>) => {
9897
if (Array.isArray(source)) {

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1+
import { IMutation } from 'proxy-state-tree'
2+
13
import {
2-
createOvermindSSR,
3-
Overmind,
4-
IOnInitialize,
54
IConfig,
6-
rehydrate,
5+
IOnInitialize,
6+
Overmind,
7+
createOvermindSSR,
78
json,
9+
rehydrate,
810
} from './'
9-
import { IMutation } from 'proxy-state-tree'
11+
import { IS_JSON } from './utils'
1012

1113
describe('Mock', () => {
1214
test('should allow changing the state', () => {
@@ -81,6 +83,7 @@ describe('Mock', () => {
8183

8284
expect(json(overmind.state)).toEqual({
8385
foo: 'bar2',
86+
[IS_JSON]: overmind.state
8487
})
8588
})
8689
})

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ describe('deepCopy', () => {
1111
copy.value = 15
1212
expect(copy.valuePlusTwo).toBe(17)
1313
})
14-
})
14+
})

packages/node_modules/overmind/src/utils.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import isPlainObject from 'is-plain-obj'
2+
import { IS_PROXY, VALUE } from 'proxy-state-tree'
23

34
import { Derived } from './derived'
45
import { RehydrateClasses } from './internalTypes'
@@ -12,6 +13,7 @@ export const EXECUTION = Symbol('execution')
1213
export const MODE_DEFAULT = Symbol('MODE_DEFAULT')
1314
export const MODE_TEST = Symbol('MODE_TEST')
1415
export const MODE_SSR = Symbol('MODE_SSR')
16+
export const IS_JSON = Symbol('IS_JSON')
1517

1618
export class MockedEventEmitter {
1719
emit() {}
@@ -21,6 +23,13 @@ export class MockedEventEmitter {
2123
addListener() {}
2224
}
2325

26+
export const json = (obj: any) => {
27+
const result = deepCopy(obj && obj[IS_PROXY] ? obj[VALUE] : obj)
28+
result[IS_JSON] = obj
29+
return result
30+
}
31+
32+
2433
export function isPromise(maybePromise: any) {
2534
return (
2635
maybePromise instanceof Promise ||
@@ -164,15 +173,16 @@ export function rehydrateState<T extends IState>(target: T, source: IState, clas
164173
Object.keys(source).forEach((key) => {
165174
const value = source[key]
166175
const classInstance = classes[key]
167-
if (typeof value === 'object' && !Array.isArray(value) && value !== null) {
168-
if (!target[key]) target[key] = {}
169-
rehydrateState(target[key] as IState, source[key] as IState, classes[key])
170-
} else if (classInstance && Array.isArray(source[key])) {
176+
177+
if (typeof classInstance === 'function' && Array.isArray(source[key])) {
171178
target[key] = (source[key] as any[]).map(value => classInstance(value))
172-
} else if (classInstance) {
179+
} else if (typeof classInstance === 'function') {
173180
target[key] = classInstance(source[key])
181+
} else if (typeof value === 'object' && !Array.isArray(value) && value !== null) {
182+
if (!target[key]) target[key] = {}
183+
rehydrateState(target[key] as IState, source[key] as IState, classes[key])
174184
} else {
175185
target[key] = source[key]
176186
}
177187
})
178-
}
188+
}

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

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,6 @@ export const PATH = Symbol('PATH')
77
export const VALUE = Symbol('VALUE')
88
export const PROXY_TREE = Symbol('PROXY_TREE')
99

10-
let JSONReplacer = null
11-
12-
export const stringify = (
13-
value: any,
14-
replacer?: (this: any, key: string, value: any) => any,
15-
space?: string | number,
16-
toJSONReplacer?: (value: any) => any
17-
) => {
18-
JSONReplacer = toJSONReplacer
19-
const result = JSON.stringify(value, replacer, space)
20-
JSONReplacer = null
21-
return result
22-
}
23-
2410
const arrayMutations = new Set([
2511
'push',
2612
'shift',
@@ -312,7 +298,7 @@ export class Proxifier {
312298
const currentTree = trackingTree || proxifier.tree
313299

314300
if (typeof targetValue === 'function' && isClass(target)) {
315-
return (...args) => prop === 'toJSON' && JSONReplacer ? JSONReplacer.call(proxy, targetValue.call(proxy, ...args)) : targetValue.call(proxy, ...args)
301+
return (...args) => targetValue.call(proxy, ...args)
316302
} else if (typeof targetValue === 'function') {
317303
return proxifier.tree.master.options.dynamicWrapper
318304
? proxifier.tree.master.options.dynamicWrapper(

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ export {
2929
MutationTree,
3030
}
3131

32-
export { stringify } from './Proxyfier'
33-
3432
export * from './types'
3533

3634
export class ProxyStateTree<T extends object> implements IProxyStateTree<T> {

0 commit comments

Comments
 (0)