Deep-clone model settings in lib/builtin-models
Fix the code loading builtin models to always clone the JSON object used as model settings/definition. This is needed to allow applications to modify model settings while not affecting settings of new models created in the local registry of another app.
This commit is contained in:
parent
c45954cdaa
commit
f0c9700e1d
|
@ -4,6 +4,9 @@
|
||||||
// License text available at https://opensource.org/licenses/MIT
|
// License text available at https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
module.exports = function(registry) {
|
module.exports = function(registry) {
|
||||||
// NOTE(bajtos) we must use static require() due to browserify limitations
|
// NOTE(bajtos) we must use static require() due to browserify limitations
|
||||||
|
|
||||||
|
@ -52,8 +55,33 @@ module.exports = function(registry) {
|
||||||
require('../common/models/checkpoint.js'));
|
require('../common/models/checkpoint.js'));
|
||||||
|
|
||||||
function createModel(definitionJson, customizeFn) {
|
function createModel(definitionJson, customizeFn) {
|
||||||
|
// Clone the JSON definition to allow applications
|
||||||
|
// to modify model settings while not affecting
|
||||||
|
// settings of new models created in the local registry
|
||||||
|
// of another app.
|
||||||
|
// This is needed because require() always returns the same
|
||||||
|
// object instance it loaded during the first call.
|
||||||
|
definitionJson = cloneDeepJson(definitionJson);
|
||||||
|
|
||||||
var Model = registry.createModel(definitionJson);
|
var Model = registry.createModel(definitionJson);
|
||||||
customizeFn(Model);
|
customizeFn(Model);
|
||||||
return Model;
|
return Model;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Because we are cloning objects created by JSON.parse,
|
||||||
|
// the cloning algorithm can stay much simpler than a general-purpose
|
||||||
|
// "cloneDeep" e.g. from lodash.
|
||||||
|
function cloneDeepJson(obj) {
|
||||||
|
const result = Array.isArray(obj) ? [] : {};
|
||||||
|
assert.equal(Object.getPrototypeOf(result), Object.getPrototypeOf(obj));
|
||||||
|
for (const key in obj) {
|
||||||
|
const value = obj[key];
|
||||||
|
if (typeof value === 'object') {
|
||||||
|
result[key] = cloneDeepJson(value);
|
||||||
|
} else {
|
||||||
|
result[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue