Comparing version 0.1.1 to 0.1.2
133
index.js
@@ -23,5 +23,6 @@ 'use strict'; | ||
} | ||
var analyze = new Analyze(structure); | ||
var def = this._defined[key] = { | ||
deep: createFunc(analyze(structure)), | ||
shallow: createFunc(analyze(structure, 1)) | ||
deep: createFunc(analyze.deep()), | ||
shallow: createFunc(analyze.shallow()) | ||
}; | ||
@@ -52,2 +53,52 @@ return def.deep; | ||
function Analyze(structure) { | ||
this._structure = structure; | ||
this._object = []; | ||
this._keys = []; | ||
} | ||
Analyze.prototype._analyze = function(structure, keys, depth, current) { | ||
if (structure === null) { | ||
return 'null'; | ||
} | ||
var type = typeof structure; | ||
if (type === 'function') { | ||
return structure; | ||
} | ||
var index = this._object.indexOf(structure); | ||
if (index >= 0) { | ||
return resolveKey(clone(this._keys[index])).key; | ||
} | ||
current = current || 0; | ||
if (current === depth || type !== 'object') { | ||
return type; | ||
} | ||
current++; | ||
var self = this; | ||
self._object.push(structure); | ||
self._keys.push(keys); | ||
structure = map(structure, function(value, key) { | ||
return self._analyze(value, keys.concat(key), depth, current); | ||
}); | ||
if (current === 1) { | ||
this._object = []; | ||
this._keys = []; | ||
} | ||
return structure; | ||
}; | ||
Analyze.prototype.deep = function() { | ||
return this._analyze(this._structure, ['c']); | ||
}; | ||
Analyze.prototype.shallow = function() { | ||
return this._analyze(this._structure, ['c'], 1); | ||
}; | ||
function clone(obj) { | ||
return map(obj, function(value) { | ||
return value; | ||
}); | ||
} | ||
function map(obj, iter) { | ||
@@ -74,20 +125,2 @@ var index = -1; | ||
function analyze(structure, depth, current) { | ||
if (structure === null) { | ||
return 'null'; | ||
} | ||
var type = typeof structure; | ||
if (type === 'function') { | ||
return structure; | ||
} | ||
current = current || 0; | ||
if (current === depth || type !== 'object') { | ||
return type; | ||
} | ||
current++; | ||
return map(structure, function(value) { | ||
return analyze(value, depth, current); | ||
}); | ||
} | ||
function replace(str, value, exp) { | ||
@@ -113,3 +146,6 @@ exp = exp || /%s/; | ||
if (!l) { | ||
return replace(str, k); | ||
return { | ||
str: replace(str, k), | ||
key: k | ||
}; | ||
} | ||
@@ -131,4 +167,5 @@ str = replace(str, ['%s&&%s', k]); | ||
function resolveValue(keys, value) { | ||
var str = '%k!==u?%k:%s'; | ||
str = replace(str, resolveKey(keys), /%k/); | ||
var str = '%s!==u?%s:%s'; | ||
var info = resolveKey(keys); | ||
str = replace(str, info); | ||
switch (value) { | ||
@@ -139,2 +176,4 @@ case 'string': | ||
return replace(str, 0); | ||
case 'undefined': | ||
return replace(str, undefined); | ||
case 'boolean': | ||
@@ -147,31 +186,53 @@ return replace(str, false); | ||
default: | ||
return replace(str, value); | ||
if (typeof value === 'function') { | ||
return replace(str, value.toString()); | ||
} | ||
// circular structure | ||
return replace(replace('%c<%s|%s>', info.key), value); | ||
} | ||
} | ||
function createFuncStr(obj, keys, parentStr) { | ||
function createFuncStr(obj, keys, str) { | ||
var type = typeof obj; | ||
if (type !== 'object') { | ||
if (!parentStr) { | ||
if (!str) { | ||
return resolveValue(keys, obj); | ||
} | ||
return replace(parentStr, resolveValue(keys, obj)); | ||
return replace(str, resolveValue(keys, obj)); | ||
} | ||
var isArray = Array.isArray(obj); | ||
var str = isArray ? '[%s],%s' : '{%s},%s'; | ||
map(obj, function(cObj, cKey) { | ||
str = isArray ? replace(str, '%s,%s') : replace(str, cKey + ':%s,%s'); | ||
str = createFuncStr(cObj, keys.concat(cKey), str); | ||
var s = isArray ? '[%s],%s' : '{%s},%s'; | ||
map(obj, function(o, k) { | ||
s = isArray ? replace(s, '%s,%s') : replace(s, k + ':%s,%s'); | ||
s = createFuncStr(o, keys.concat(k), s); | ||
}); | ||
str = replace(str, '', /(%s|,%s)/g); | ||
return replace(parentStr, str) || str; | ||
s = replace(s, '', /(%s|,%s)/g); | ||
return replace(str, s) || s; | ||
} | ||
function resolveCircular(str) { | ||
var exp = /%c<(.*?)>/; | ||
var bar = str.match(exp); | ||
if (!bar) { | ||
return str; | ||
} | ||
str = replace(str, 'u', exp); | ||
var param = bar[1].split(/\|/); | ||
var key = replace(param[0], 'c', /o/); | ||
var val = param[1]; | ||
var s = '%s=%s;'; | ||
s = replace(s, [key, val]); | ||
str = replace(str, ['%s%s', s]); | ||
return resolveCircular(str); | ||
} | ||
function createFunc(structure) { | ||
var base = '{var u=undefined;return %s;}'; | ||
var base = '{var u,c=%s;%sreturn c;}'; | ||
var str = createFuncStr(structure, ['o'], ''); | ||
var result = replace(base, str); | ||
return new Function('o', result); | ||
str = replace(base, str); | ||
str = resolveCircular(str); | ||
str = replace(str, ''); | ||
return new Function('o', str); | ||
} | ||
module.exports = new DeepCopy(); |
{ | ||
"name": "dcp", | ||
"version": "0.1.1", | ||
"version": "0.1.2", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -45,5 +45,5 @@ # Deep CoPy | ||
* { a: 10, | ||
* b: 'default', | ||
* b: '', | ||
* c: [1, 2], | ||
* d: { d1: true } } | ||
* d: { d1: false } } | ||
*/ | ||
@@ -50,0 +50,0 @@ |
/* global beforeEach, describe, it */ | ||
'use strict'; | ||
@@ -157,2 +156,41 @@ | ||
it('should not cause an error even if an object has circular structure', function() { | ||
var obj = { | ||
a: 1 | ||
}; | ||
var obj2 = { | ||
a: 2, | ||
b: obj | ||
}; | ||
obj.b = obj2; | ||
var clone = dcp.define('test', obj); | ||
var newObj = clone(obj); | ||
assert.deepEqual(newObj, obj); | ||
assert.notStrictEqual(newObj.b, obj.b); | ||
assert.notStrictEqual(newObj.b.b, obj.b.b); | ||
}); | ||
it('should copy multi circular structure', function() { | ||
var obj1 = { | ||
a: 1 | ||
}; | ||
var obj2 = { | ||
a: 2, | ||
b: obj1 | ||
}; | ||
var obj3 = { | ||
a: 3, | ||
b: obj2 | ||
}; | ||
obj1.b = obj2; | ||
obj1.c = obj3; | ||
obj2.c = obj3; | ||
obj3.c = obj1; | ||
var clone = dcp.define('test', obj1); | ||
var newObj = clone(obj1); | ||
assert.deepEqual(newObj, obj1); | ||
assert.notStrictEqual(newObj.b, obj1.b); | ||
assert.notStrictEqual(newObj.b.b, obj1.b.b); | ||
}); | ||
}); | ||
@@ -159,0 +197,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
13475
404