forked from mobxjs/mst-gql
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Revert "feat: improve merge strategy for better performance (mobxjs#346…
…)" This reverts commit b906feb.
- Loading branch information
1 parent
989c564
commit c704d87
Showing
1 changed file
with
26 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,89 +1,44 @@ | ||
import { isNumber, isObject } from "lodash" | ||
import { resolveIdentifier, getSnapshot } from "mobx-state-tree" | ||
import { resolveIdentifier } from "mobx-state-tree" | ||
import { typenameToCollectionName } from "./utils" | ||
|
||
// use a proxy for array-type structures, saves huge amounts of memory, and improves performance | ||
const proxyHandler = (store: any) => ({ | ||
get(target: any, prop: any, receiver: any) { | ||
const instance = Reflect.get(target, prop, receiver) as any | ||
|
||
if (isNumber(prop)) return instance | ||
|
||
const { __typename, id } = instance | ||
const typeDef = store.getTypeDef(__typename) | ||
|
||
return id !== undefined ? resolveIdentifier(typeDef, store, id) : instance | ||
} | ||
}) | ||
|
||
// prepare reactive results with proxies and for any depth | ||
function buildResponse(data: any, store: any) { | ||
if (!data || typeof data !== "object") return data | ||
if (Array.isArray(data)) | ||
return new Proxy( | ||
Object.isFrozen(data) ? Array.from(data) : data, | ||
proxyHandler(store) | ||
) | ||
|
||
const { __typename, id } = data | ||
|
||
if (__typename && id) { | ||
const typeDef = store.getTypeDef(__typename) | ||
|
||
return resolveIdentifier(typeDef, store, id) | ||
} | ||
|
||
const reactiveResult: any = {} | ||
|
||
for (const key in data) { | ||
if (Object.prototype.hasOwnProperty.call(data, key)) { | ||
reactiveResult[key] = buildResponse(data[key], store) | ||
} | ||
} | ||
|
||
return reactiveResult | ||
} | ||
|
||
// logic to wrap and update mst-tree | ||
export function mergeHelper(store: any, initialData: any): any { | ||
export function mergeHelper(store: any, data: any) { | ||
function merge(data: any): any { | ||
if (!data || typeof data !== "object") return data | ||
if (Array.isArray(data)) return data.map(merge) | ||
|
||
const { __typename, id } = data | ||
const snapshot: any = {} | ||
|
||
// convert values deeply first to MST objects as much as possible | ||
const snapshot: any = {} | ||
for (const key in data) { | ||
if (isObject(data[key]) || Array.isArray(data[key])) { | ||
snapshot[key] = merge(data[key]) | ||
} else { | ||
snapshot[key] = data[key] | ||
} | ||
snapshot[key] = merge(data[key]) | ||
} | ||
|
||
// GQL object | ||
if (__typename && store.isKnownType(__typename)) { | ||
// process with root types | ||
if (store.isRootType(__typename)) { | ||
const rootMap = store[store.getCollectionName(__typename)] | ||
const instance = rootMap.get(id) | ||
const newInstance = { | ||
...(instance ? getSnapshot<Object>(instance) : {}), | ||
...snapshot | ||
} | ||
rootMap.set(id, newInstance) | ||
// another ones | ||
// GQL object with known type, instantiate or recycle MST object | ||
const typeDef = store.getTypeDef(__typename) | ||
// Try to reuse instance, even if it is not a root type | ||
let instance = id !== undefined && resolveIdentifier(typeDef, store, id) | ||
if (instance) { | ||
// update existing object | ||
Object.assign(instance, snapshot) | ||
} else { | ||
const typeDef = store.getTypeDef(__typename) | ||
const instance = typeDef.create(snapshot) | ||
// create a new one | ||
instance = typeDef.create(snapshot) | ||
if (store.isRootType(__typename)) { | ||
// register in the store if a root | ||
//store[typenameToCollectionName(__typename)].set(id, instance) | ||
store[store.getCollectionName(__typename)].set(id, instance) | ||
} | ||
instance.__setStore(store) | ||
|
||
return instance | ||
} | ||
return instance | ||
} else { | ||
// GQL object with unknown type, return verbatim | ||
return snapshot | ||
} | ||
|
||
return __typename && store.isRootType(__typename) ? id : snapshot | ||
} | ||
|
||
merge(initialData) | ||
|
||
return buildResponse(initialData, store) | ||
return merge(data) | ||
} |