Skip to content

Commit 7fbe394

Browse files
committed
fix: assure only one clone ever exists in memory
Clones are now handled in the same way that instances are. If you call clone twice on the same object, the return value is always the same clone. This assures that only one clone ever exists in memory, creating a very consistent API. (Of course, more clones can always be stored anywhere in an app by manual use of a cloning utility like fast-copy)
1 parent 73bd282 commit 7fbe394

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

src/service-module/make-model.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export default function makeModel(options: FeathersVuexOptions) {
4646
// Think of these as abstract static properties
4747
public static servicePath: string
4848
public static namespace: string
49+
public static keepCopiesInStore = options.keepCopiesInStore
4950
// eslint-disable-next-line
5051
public static instanceDefaults(data, { models, store }) {
5152
return data
@@ -79,20 +80,30 @@ export default function makeModel(options: FeathersVuexOptions) {
7980
public constructor(data, options: BaseModelInstanceOptions) {
8081
// You have to pass at least an empty object to get a tempId.
8182
const originalData = data
83+
data = data || {}
8284
options = Object.assign({}, defaultOptions, options)
85+
8386
const {
8487
store,
88+
keepCopiesInStore,
89+
copiesById: copiesByIdOnModel,
8590
models,
8691
instanceDefaults,
8792
idField,
93+
tempIdField,
8894
setupInstance,
8995
getFromStore,
96+
namespace,
9097
_commit
9198
} = this.constructor as typeof BaseModel
9299
const id = getId(data, idField)
93100
const hasValidId = id !== null && id !== undefined
101+
const tempId = data && data.hasOwnProperty(tempIdField) && data[tempIdField]
102+
const hasValidTempId = tempId !== null && tempId !== undefined
103+
const copiesById = keepCopiesInStore
104+
? store.state[namespace].copiesById
105+
: copiesByIdOnModel
94106

95-
data = data || {}
96107

97108
const existingItem = hasValidId && !options.clone
98109
? getFromStore.call(this.constructor, id)
@@ -105,6 +116,16 @@ export default function makeModel(options: FeathersVuexOptions) {
105116
return existingItem
106117
}
107118

119+
// If cloning and a clone already exists, update and return the original clone. Only one clone is allowed.
120+
const existingClone = (hasValidId || hasValidTempId) && options.clone
121+
? copiesById[id] || copiesById[tempId]
122+
: null
123+
if (existingClone) {
124+
// This must be done in a mutation to avoid Vuex errors.
125+
_commit.call(this.constructor, 'merge', { dest: existingClone, source: data })
126+
return existingClone
127+
}
128+
108129
// Mark as a clone
109130
if (options.clone) {
110131
Object.defineProperty(this, '__isClone', {

src/service-module/service-module.mutations.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,13 @@ export default function makeServiceMutations() {
113113
}
114114
}
115115

116+
function merge(state, { dest, source }) {
117+
mergeWithAccessors(dest, source)
118+
}
119+
116120
return {
117121
mergeInstance,
122+
merge,
118123
addItem(state, item) {
119124
addItems(state, [item])
120125
},

0 commit comments

Comments
 (0)