Comparing version 2.1.1 to 2.1.2
# Changelog | ||
## v2.2.0 (provisional) | ||
* Cursors are now ES6 iterables ([@kirjs](https://github.com/kirjs)). | ||
## v2.1.2 | ||
* Storing hashed paths using `λ` as delimiter instead of `/` to enable some edge cases ([@nivekmai](https://github.com/nivekmai)). | ||
* Fixing an issue with cursors where a stopped history wouldn't restart correctly ([@nikvm](https://github.com/nikvm)). | ||
* Fixing monkeys' laziness. | ||
* Fixing an edge case when one watches over paths beneath monkeys. | ||
## v2.1.1 | ||
@@ -4,0 +15,0 @@ |
@@ -59,3 +59,2 @@ /** | ||
var deepMerge = helpers.deepMerge; | ||
var pathObject = helpers.pathObject; | ||
var shallowClone = helpers.shallowClone; | ||
@@ -103,5 +102,7 @@ var shallowMerge = helpers.shallowMerge; | ||
function hashPath(path) { | ||
return '/' + path.map(function (step) { | ||
if (_type2['default']['function'](step) || _type2['default'].object(step)) return '#' + uniqid() + '#';else return step; | ||
}).join('/'); | ||
return 'λ' + path.map(function (step) { | ||
if (_type2['default']['function'](step) || _type2['default'].object(step)) return '#' + uniqid() + '#'; | ||
return step; | ||
}).join('λ'); | ||
} | ||
@@ -161,3 +162,3 @@ | ||
// Properties | ||
this.root = new _cursor2['default'](this, [], '/'); | ||
this.root = new _cursor2['default'](this, [], 'λ'); | ||
delete this.root.release; | ||
@@ -472,3 +473,3 @@ | ||
var affectedPaths = Object.keys(this._affectedPathsIndex).map(function (h) { | ||
return h !== '/' ? h.split('/').slice(1) : []; | ||
return h !== 'λ' ? h.split('λ').slice(1) : []; | ||
}); | ||
@@ -573,3 +574,5 @@ | ||
if (args.length === 1) return new _monkey.MonkeyDefinition(args[0]);else return new _monkey.MonkeyDefinition(args); | ||
if (args.length === 1) return new _monkey.MonkeyDefinition(args[0]); | ||
return new _monkey.MonkeyDefinition(args); | ||
}; | ||
@@ -591,3 +594,3 @@ Baobab.dynamicNode = Baobab.monkey; | ||
Object.defineProperty(Baobab, 'version', { | ||
value: '2.1.1' | ||
value: '2.1.2' | ||
}); | ||
@@ -594,0 +597,0 @@ |
@@ -306,3 +306,5 @@ /** | ||
value: function up() { | ||
if (!this.isRoot()) return this.tree.select(this.path.slice(0, -1));else return null; | ||
if (!this.isRoot()) return this.tree.select(this.path.slice(0, -1)); | ||
return null; | ||
} | ||
@@ -424,2 +426,35 @@ | ||
/** | ||
* Method used to allow iterating over cursors containing list-type data. | ||
* | ||
* e.g. for(let i of cursor) { ... } | ||
* | ||
* @returns {object} - Each item sequentially. | ||
// */ | ||
// [Symbol.iterator]() { | ||
// const array = this._get().data; | ||
// if (!type.array(array)) | ||
// throw Error('baobab.Cursor.@@iterate: cannot iterate a non-list type.'); | ||
// let i = 0; | ||
// const cursor = this, | ||
// length = array.length; | ||
// return { | ||
// next: function() { | ||
// if (i < length) { | ||
// return { | ||
// value: cursor.select(i++) | ||
// }; | ||
// } | ||
// return { | ||
// done: true | ||
// }; | ||
// } | ||
// }; | ||
// } | ||
/** | ||
* Getter Methods | ||
@@ -595,2 +630,4 @@ * --------------- | ||
this.state.recording = true; | ||
if (this.archive) return this; | ||
@@ -602,3 +639,2 @@ | ||
this.archive = new _helpers.Archive(maxRecords); | ||
this.state.recording = true; | ||
return this; | ||
@@ -605,0 +641,0 @@ } |
@@ -0,1 +1,3 @@ | ||
/* eslint eqeqeq: 0 */ | ||
/** | ||
@@ -20,3 +22,2 @@ * Baobab Helpers | ||
exports.makeError = makeError; | ||
exports.pathObject = pathObject; | ||
exports.solveRelativePath = solveRelativePath; | ||
@@ -42,2 +43,36 @@ exports.solveUpdate = solveUpdate; | ||
/** | ||
* Function returning the index of the first element of a list matching the | ||
* given predicate. | ||
* | ||
* @param {array} a - The target array. | ||
* @param {function} fn - The predicate function. | ||
* @return {mixed} - The index of the first matching item or -1. | ||
*/ | ||
function index(a, fn) { | ||
var i = undefined, | ||
l = undefined; | ||
for (i = 0, l = a.length; i < l; i++) { | ||
if (fn(a[i])) return i; | ||
} | ||
return -1; | ||
} | ||
/** | ||
* Efficient slice function used to clone arrays or parts of them. | ||
* | ||
* @param {array} array - The array to slice. | ||
* @return {array} - The sliced array. | ||
*/ | ||
function slice(array) { | ||
var newArray = new Array(array.length); | ||
var i = undefined, | ||
l = undefined; | ||
for (i = 0, l = array.length; i < l; i++) newArray[i] = array[i]; | ||
return newArray; | ||
} | ||
/** | ||
* Archive abstraction | ||
@@ -155,5 +190,6 @@ * | ||
function cloneRegexp(re) { | ||
var pattern = re.source, | ||
flags = ''; | ||
var pattern = re.source; | ||
var flags = ''; | ||
if (re.global) flags += 'g'; | ||
@@ -183,10 +219,12 @@ if (re.multiline) flags += 'm'; | ||
if (deep) { | ||
var a = []; | ||
var i = undefined, | ||
l = undefined, | ||
a = []; | ||
l = undefined; | ||
for (i = 0, l = item.length; i < l; i++) a.push(cloner(true, item[i])); | ||
return a; | ||
} else { | ||
return slice(item); | ||
} | ||
return slice(item); | ||
} | ||
@@ -202,7 +240,18 @@ | ||
if (_type2['default'].object(item)) { | ||
var k = undefined, | ||
o = {}; | ||
var o = {}; | ||
var k = undefined; | ||
// NOTE: could be possible to erase computed properties through `null`. | ||
for (k in item) if (item.hasOwnProperty(k)) o[k] = deep ? cloner(true, item[k]) : item[k]; | ||
for (k in item) { | ||
if (_type2['default'].lazyGetter(item, k)) { | ||
Object.defineProperty(o, k, { | ||
get: Object.getOwnPropertyDescriptor(item, k).get, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
} else if (item.hasOwnProperty(k)) { | ||
o[k] = deep ? cloner(true, item[k]) : item[k]; | ||
} | ||
} | ||
return o; | ||
@@ -333,4 +382,5 @@ } | ||
var solvedPath = [], | ||
exists = true, | ||
var solvedPath = []; | ||
var exists = true, | ||
c = object, | ||
@@ -373,19 +423,2 @@ idx = undefined, | ||
/** | ||
* Function returning the index of the first element of a list matching the | ||
* given predicate. | ||
* | ||
* @param {array} a - The target array. | ||
* @param {function} fn - The predicate function. | ||
* @return {mixed} - The index of the first matching item or -1. | ||
*/ | ||
function index(a, fn) { | ||
var i = undefined, | ||
l = undefined; | ||
for (i = 0, l = a.length; i < l; i++) { | ||
if (fn(a[i])) return i; | ||
} | ||
return -1; | ||
} | ||
/** | ||
* Little helper returning a JavaScript error carrying some data with it. | ||
@@ -421,4 +454,5 @@ * | ||
var o = objects[0], | ||
t = undefined, | ||
var o = objects[0]; | ||
var t = undefined, | ||
i = undefined, | ||
@@ -453,43 +487,2 @@ l = undefined, | ||
/** | ||
* Function returning a nested object according to the given path and the | ||
* given leaf. | ||
* | ||
* @param {array} path - The path to follow. | ||
* @param {mixed} leaf - The leaf to append at the end of the path. | ||
* @return {object} - The nested object. | ||
*/ | ||
function pathObject(path, leaf) { | ||
var l = path.length, | ||
o = {}, | ||
c = o, | ||
i = undefined; | ||
if (!l) o = leaf; | ||
for (i = 0; i < l; i++) { | ||
c[path[i]] = i + 1 === l ? leaf : {}; | ||
c = c[path[i]]; | ||
} | ||
return o; | ||
} | ||
/** | ||
* Efficient slice function used to clone arrays or parts of them. | ||
* | ||
* @param {array} array - The array to slice. | ||
* @return {array} - The sliced array. | ||
*/ | ||
function slice(array) { | ||
var newArray = new Array(array.length), | ||
i = undefined, | ||
l = undefined; | ||
for (i = 0, l = array.length; i < l; i++) newArray[i] = array[i]; | ||
return newArray; | ||
} | ||
/** | ||
* Solving a potentially relative path. | ||
@@ -604,2 +597,3 @@ * | ||
var i = 0; | ||
return function () { | ||
@@ -606,0 +600,0 @@ return i++; |
@@ -31,3 +31,3 @@ /** | ||
* Monkey Definition class | ||
* Note: The only reason why this is a class is to be able to spot it whithin | ||
* Note: The only reason why this is a class is to be able to spot it within | ||
* otherwise ordinary data. | ||
@@ -176,3 +176,5 @@ * | ||
if (!this.isRecursive) return paths;else return paths.reduce(function (accumulatedPaths, path) { | ||
if (!this.isRecursive) return paths; | ||
return paths.reduce(function (accumulatedPaths, path) { | ||
var monkeyPath = _type2['default'].monkeyPath(_this4.tree._monkeys, path); | ||
@@ -179,0 +181,0 @@ |
@@ -162,4 +162,5 @@ /** | ||
type.monkeyPath = function (data, path) { | ||
var subpath = [], | ||
c = data, | ||
var subpath = []; | ||
var c = data, | ||
i = undefined, | ||
@@ -205,7 +206,11 @@ l = undefined; | ||
return type.path(definition.cursors[k]); | ||
}))) return null;else return 'object'; | ||
}))) return null; | ||
return 'object'; | ||
} else if (type.array(definition)) { | ||
if (!type['function'](definition[definition.length - 1]) || !definition.slice(0, -1).every(function (p) { | ||
return type.path(p); | ||
})) return null;else return 'array'; | ||
})) return null; | ||
return 'array'; | ||
} | ||
@@ -212,0 +217,0 @@ |
@@ -22,4 +22,2 @@ /** | ||
var _monkey = require('./monkey'); | ||
var _helpers = require('./helpers'); | ||
@@ -49,7 +47,7 @@ | ||
var dummy = { root: data }, | ||
dummyPath = ['root'].concat(_toConsumableArray(path)); | ||
dummyPath = ['root'].concat(_toConsumableArray(path)), | ||
currentPath = []; | ||
// Walking the path | ||
var p = dummy, | ||
currentPath = [], | ||
i = undefined, | ||
@@ -80,5 +78,3 @@ l = undefined, | ||
if (opts.persistent) { | ||
p[s] = (0, _helpers.shallowClone)(value); | ||
} else if (value instanceof _monkey.MonkeyDefinition) { | ||
if (_type2['default'].lazyGetter(p, s)) { | ||
Object.defineProperty(p, s, { | ||
@@ -89,2 +85,4 @@ value: value, | ||
}); | ||
} else if (opts.persistent) { | ||
p[s] = (0, _helpers.shallowClone)(value); | ||
} else { | ||
@@ -113,5 +111,15 @@ p[s] = value; | ||
// Purity check | ||
if (opts.pure && result === value) return { node: p[s] }; | ||
if (opts.pure && p[s] === result) return { node: p[s] }; | ||
p[s] = opts.persistent ? (0, _helpers.shallowClone)(result) : result; | ||
if (_type2['default'].lazyGetter(p, s)) { | ||
Object.defineProperty(p, s, { | ||
value: result, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
} else if (opts.persistent) { | ||
p[s] = (0, _helpers.shallowClone)(result); | ||
} else { | ||
p[s] = result; | ||
} | ||
} | ||
@@ -118,0 +126,0 @@ |
@@ -94,3 +94,5 @@ /** | ||
// Watcher mappings can accept a cursor | ||
if (v instanceof _cursor2['default']) return v.solvedPath;else return _this2.mapping[k]; | ||
if (v instanceof _cursor2['default']) return v.solvedPath; | ||
return _this2.mapping[k]; | ||
}); | ||
@@ -108,3 +110,3 @@ | ||
if (monkeyPath) return cp.concat((0, _helpers.getIn)(_this2.tree._monkeys, p).data.relatedPaths()); | ||
if (monkeyPath) return cp.concat((0, _helpers.getIn)(_this2.tree._monkeys, monkeyPath).data.relatedPaths()); | ||
@@ -111,0 +113,0 @@ return cp.concat([p]); |
{ | ||
"name": "baobab", | ||
"version": "2.1.1", | ||
"version": "2.1.2", | ||
"description": "JavaScript persistent data tree with cursors.", | ||
@@ -17,2 +17,3 @@ "main": "./dist/baobab.js", | ||
"eslint": "^1.1.0", | ||
"eslint-config-airbnb": "^1.0.0", | ||
"gulp": "^3.8.10", | ||
@@ -31,3 +32,3 @@ "gulp-header": "^1.2.2", | ||
"build": "gulp build && babel ./src --out-dir dist", | ||
"lint": "eslint ./*.js && eslint ./src", | ||
"lint": "eslint ./src ./test", | ||
"prepublish": "npm run build", | ||
@@ -34,0 +35,0 @@ "test": "mocha -R spec --compilers js:babel/register ./test/endpoint.js" |
@@ -80,3 +80,3 @@ [![Build Status](https://travis-ci.org/Yomguithereal/baobab.svg)](https://travis-ci.org/Yomguithereal/baobab) | ||
The library (as a standalone) currently weights ~8ko gzipped. | ||
The library (as a standalone) currently weighs ~8kb gzipped. | ||
@@ -976,21 +976,5 @@ ## Usage | ||
Contributions are obviously welcome. This project is nothing but experimental and I would cherish some feedback and advice about the library. | ||
See [CONTRIBUTING.md](CONTRIBUTING.md). | ||
Be sure to add unit tests if relevant and pass them all before submitting your pull request. | ||
```bash | ||
# Installing the dev environment | ||
git clone git@github.com:Yomguithereal/baobab.git | ||
cd baobab | ||
npm install | ||
# Running the tests | ||
npm test | ||
# Linting, building | ||
npm run lint | ||
npm run build | ||
``` | ||
## License | ||
MIT |
@@ -22,3 +22,2 @@ /** | ||
deepMerge, | ||
pathObject, | ||
shallowClone, | ||
@@ -67,8 +66,8 @@ shallowMerge, | ||
function hashPath(path) { | ||
return '/' + path.map(step => { | ||
return 'λ' + path.map(step => { | ||
if (type.function(step) || type.object(step)) | ||
return `#${uniqid()}#`; | ||
else | ||
return step; | ||
}).join('/'); | ||
return step; | ||
}).join('λ'); | ||
} | ||
@@ -123,3 +122,3 @@ | ||
// Properties | ||
this.root = new Cursor(this, [], '/'); | ||
this.root = new Cursor(this, [], 'λ'); | ||
delete this.root.release; | ||
@@ -178,15 +177,10 @@ | ||
const clean = (data, p=[]) => { | ||
const clean = (data, p = []) => { | ||
if (data instanceof Monkey) { | ||
data.release(); | ||
update( | ||
this._monkeys, | ||
p, | ||
{type: 'unset'}, | ||
{ | ||
immutable: false, | ||
persistent: false, | ||
pure: false | ||
} | ||
); | ||
update(this._monkeys, p, {type: 'unset'}, { | ||
immutable: false, | ||
persistent: false, | ||
pure: false | ||
}); | ||
@@ -197,3 +191,3 @@ return; | ||
if (type.object(data)) { | ||
for (let k in data) | ||
for (const k in data) | ||
clean(data[k], p.concat(k)); | ||
@@ -205,3 +199,3 @@ } | ||
const walk = (data, p=[]) => { | ||
const walk = (data, p = []) => { | ||
@@ -219,12 +213,7 @@ // Should we sit a monkey in the tree? | ||
update( | ||
this._monkeys, | ||
p, | ||
{type: 'set', value: monkey}, | ||
{ | ||
immutable: false, | ||
persistent: false, | ||
pure: false | ||
} | ||
); | ||
update(this._monkeys, p, {type: 'set', value: monkey}, { | ||
immutable: false, | ||
persistent: false, | ||
pure: false | ||
}); | ||
@@ -236,3 +225,3 @@ return; | ||
if (type.object(data)) { | ||
for (let k in data) | ||
for (const k in data) | ||
walk(data[k], p.concat(k)); | ||
@@ -423,3 +412,3 @@ } | ||
// If the operation is push, the affected path is slightly different | ||
let affectedPath = solvedPath.concat( | ||
const affectedPath = solvedPath.concat( | ||
operation.type === 'push' ? node.length - 1 : [] | ||
@@ -471,4 +460,4 @@ ); | ||
const affectedPaths = Object.keys(this._affectedPathsIndex).map(h => { | ||
return h !== '/' ? | ||
h.split('/').slice(1) : | ||
return h !== 'λ' ? | ||
h.split('λ').slice(1) : | ||
[]; | ||
@@ -567,4 +556,4 @@ }); | ||
return new MonkeyDefinition(args[0]); | ||
else | ||
return new MonkeyDefinition(args); | ||
return new MonkeyDefinition(args); | ||
}; | ||
@@ -586,3 +575,3 @@ Baobab.dynamicNode = Baobab.monkey; | ||
Object.defineProperty(Baobab, 'version', { | ||
value: '2.1.1' | ||
value: '2.1.2' | ||
}); | ||
@@ -589,0 +578,0 @@ |
@@ -267,4 +267,4 @@ /** | ||
return this.tree.select(this.path.slice(0, -1)); | ||
else | ||
return null; | ||
return null; | ||
} | ||
@@ -373,4 +373,4 @@ | ||
let array = this._get().data, | ||
l = arguments.length; | ||
const array = this._get().data, | ||
l = arguments.length; | ||
@@ -391,2 +391,35 @@ if (!type.array(array)) | ||
/** | ||
* Method used to allow iterating over cursors containing list-type data. | ||
* | ||
* e.g. for(let i of cursor) { ... } | ||
* | ||
* @returns {object} - Each item sequentially. | ||
// */ | ||
// [Symbol.iterator]() { | ||
// const array = this._get().data; | ||
// if (!type.array(array)) | ||
// throw Error('baobab.Cursor.@@iterate: cannot iterate a non-list type.'); | ||
// let i = 0; | ||
// const cursor = this, | ||
// length = array.length; | ||
// return { | ||
// next: function() { | ||
// if (i < length) { | ||
// return { | ||
// value: cursor.select(i++) | ||
// }; | ||
// } | ||
// return { | ||
// done: true | ||
// }; | ||
// } | ||
// }; | ||
// } | ||
/** | ||
* Getter Methods | ||
@@ -406,3 +439,3 @@ * --------------- | ||
*/ | ||
_get(path=[]) { | ||
_get(path = []) { | ||
@@ -502,3 +535,3 @@ if (!type.path(path)) | ||
for (let k in m) { | ||
for (const k in m) { | ||
if (m[k] instanceof Monkey) | ||
@@ -525,3 +558,3 @@ delete d[k]; | ||
for (let k in projection) | ||
for (const k in projection) | ||
data[k] = this.get(projection[k]); | ||
@@ -565,2 +598,4 @@ | ||
this.state.recording = true; | ||
if (this.archive) | ||
@@ -573,3 +608,2 @@ return this; | ||
this.archive = new Archive(maxRecords); | ||
this.state.recording = true; | ||
return this; | ||
@@ -594,3 +628,3 @@ } | ||
*/ | ||
undo(steps=1) { | ||
undo(steps = 1) { | ||
if (!this.state.recording) | ||
@@ -597,0 +631,0 @@ throw new Error('Baobab.Cursor.undo: cursor is not recording.'); |
@@ -0,1 +1,3 @@ | ||
/* eslint eqeqeq: 0 */ | ||
/** | ||
@@ -16,2 +18,37 @@ * Baobab Helpers | ||
/** | ||
* Function returning the index of the first element of a list matching the | ||
* given predicate. | ||
* | ||
* @param {array} a - The target array. | ||
* @param {function} fn - The predicate function. | ||
* @return {mixed} - The index of the first matching item or -1. | ||
*/ | ||
function index(a, fn) { | ||
let i, l; | ||
for (i = 0, l = a.length; i < l; i++) { | ||
if (fn(a[i])) | ||
return i; | ||
} | ||
return -1; | ||
} | ||
/** | ||
* Efficient slice function used to clone arrays or parts of them. | ||
* | ||
* @param {array} array - The array to slice. | ||
* @return {array} - The sliced array. | ||
*/ | ||
function slice(array) { | ||
const newArray = new Array(array.length); | ||
let i, | ||
l; | ||
for (i = 0, l = array.length; i < l; i++) | ||
newArray[i] = array[i]; | ||
return newArray; | ||
} | ||
/** | ||
* Archive abstraction | ||
@@ -112,5 +149,6 @@ * | ||
function cloneRegexp(re) { | ||
let pattern = re.source, | ||
flags = ''; | ||
const pattern = re.source; | ||
let flags = ''; | ||
if (re.global) flags += 'g'; | ||
@@ -145,3 +183,7 @@ if (re.multiline) flags += 'm'; | ||
if (deep) { | ||
let i, l, a = []; | ||
const a = []; | ||
let i, | ||
l; | ||
for (i = 0, l = item.length; i < l; i++) | ||
@@ -151,5 +193,4 @@ a.push(cloner(true, item[i])); | ||
} | ||
else { | ||
return slice(item); | ||
} | ||
return slice(item); | ||
} | ||
@@ -167,8 +208,19 @@ | ||
if (type.object(item)) { | ||
let k, o = {}; | ||
const o = {}; | ||
let k; | ||
// NOTE: could be possible to erase computed properties through `null`. | ||
for (k in item) | ||
if (item.hasOwnProperty(k)) | ||
for (k in item) { | ||
if (type.lazyGetter(item, k)) { | ||
Object.defineProperty(o, k, { | ||
get: Object.getOwnPropertyDescriptor(item, k).get, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
} | ||
else if (item.hasOwnProperty(k)) { | ||
o[k] = deep ? cloner(true, item[k]) : item[k]; | ||
} | ||
} | ||
return o; | ||
@@ -313,4 +365,5 @@ } | ||
let solvedPath = [], | ||
exists = true, | ||
const solvedPath = []; | ||
let exists = true, | ||
c = object, | ||
@@ -358,19 +411,2 @@ idx, | ||
/** | ||
* Function returning the index of the first element of a list matching the | ||
* given predicate. | ||
* | ||
* @param {array} a - The target array. | ||
* @param {function} fn - The predicate function. | ||
* @return {mixed} - The index of the first matching item or -1. | ||
*/ | ||
function index(a, fn) { | ||
let i, l; | ||
for (i = 0, l = a.length; i < l; i++) { | ||
if (fn(a[i])) | ||
return i; | ||
} | ||
return -1; | ||
} | ||
/** | ||
* Little helper returning a JavaScript error carrying some data with it. | ||
@@ -385,3 +421,3 @@ * | ||
for (let k in data) | ||
for (const k in data) | ||
err[k] = data[k]; | ||
@@ -403,4 +439,5 @@ | ||
function merger(deep, ...objects) { | ||
let o = objects[0], | ||
t, | ||
const o = objects[0]; | ||
let t, | ||
i, | ||
@@ -437,44 +474,2 @@ l, | ||
/** | ||
* Function returning a nested object according to the given path and the | ||
* given leaf. | ||
* | ||
* @param {array} path - The path to follow. | ||
* @param {mixed} leaf - The leaf to append at the end of the path. | ||
* @return {object} - The nested object. | ||
*/ | ||
export function pathObject(path, leaf) { | ||
let l = path.length, | ||
o = {}, | ||
c = o, | ||
i; | ||
if (!l) | ||
o = leaf; | ||
for (i = 0; i < l; i++) { | ||
c[path[i]] = (i + 1 === l) ? leaf : {}; | ||
c = c[path[i]]; | ||
} | ||
return o; | ||
} | ||
/** | ||
* Efficient slice function used to clone arrays or parts of them. | ||
* | ||
* @param {array} array - The array to slice. | ||
* @return {array} - The sliced array. | ||
*/ | ||
function slice(array) { | ||
let newArray = new Array(array.length), | ||
i, | ||
l; | ||
for (i = 0, l = array.length; i < l; i++) | ||
newArray[i] = array[i]; | ||
return newArray; | ||
} | ||
/** | ||
* Solving a potentially relative path. | ||
@@ -490,3 +485,3 @@ * | ||
for (let i = 0, l = to.length; i < l; i++) { | ||
let step = to[i]; | ||
const step = to[i]; | ||
@@ -584,3 +579,4 @@ if (step === '.') { | ||
const uniqid = (function() { | ||
var i = 0; | ||
let i = 0; | ||
return function() { | ||
@@ -587,0 +583,0 @@ return i++; |
@@ -10,3 +10,2 @@ /** | ||
import { | ||
arrayFrom, | ||
deepFreeze, | ||
@@ -21,3 +20,3 @@ getIn, | ||
* Monkey Definition class | ||
* Note: The only reason why this is a class is to be able to spot it whithin | ||
* Note: The only reason why this is a class is to be able to spot it within | ||
* otherwise ordinary data. | ||
@@ -156,14 +155,14 @@ * | ||
return paths; | ||
else | ||
return paths.reduce((accumulatedPaths, path) => { | ||
const monkeyPath = type.monkeyPath(this.tree._monkeys, path); | ||
if (!monkeyPath) | ||
return accumulatedPaths.concat([path]); | ||
return paths.reduce((accumulatedPaths, path) => { | ||
const monkeyPath = type.monkeyPath(this.tree._monkeys, path); | ||
// Solving recursive path | ||
const relatedMonkey = getIn(this.tree._monkeys, monkeyPath).data; | ||
if (!monkeyPath) | ||
return accumulatedPaths.concat([path]); | ||
return accumulatedPaths.concat(relatedMonkey.relatedPaths()); | ||
}, []); | ||
// Solving recursive path | ||
const relatedMonkey = getIn(this.tree._monkeys, monkeyPath).data; | ||
return accumulatedPaths.concat(relatedMonkey.relatedPaths()); | ||
}, []); | ||
} | ||
@@ -226,3 +225,2 @@ | ||
this.tree._data = result.data; | ||
} | ||
@@ -229,0 +227,0 @@ |
@@ -57,3 +57,3 @@ /** | ||
!(target instanceof Date) && | ||
!(target instanceof RegExp) && | ||
!(target instanceof RegExp) && | ||
!(typeof Map === 'function' && target instanceof Map) && | ||
@@ -160,4 +160,5 @@ !(typeof Set === 'function' && target instanceof Set); | ||
type.monkeyPath = function(data, path) { | ||
let subpath = [], | ||
c = data, | ||
const subpath = []; | ||
let c = data, | ||
i, | ||
@@ -210,4 +211,4 @@ l; | ||
return null; | ||
else | ||
return 'object'; | ||
return 'object'; | ||
} | ||
@@ -218,4 +219,4 @@ else if (type.array(definition)) { | ||
return null; | ||
else | ||
return 'array'; | ||
return 'array'; | ||
} | ||
@@ -222,0 +223,0 @@ |
@@ -8,3 +8,2 @@ /** | ||
import type from './type'; | ||
import {MonkeyDefinition} from './monkey'; | ||
import { | ||
@@ -38,3 +37,3 @@ freeze, | ||
*/ | ||
export default function update(data, path, operation, opts={}) { | ||
export default function update(data, path, operation, opts = {}) { | ||
const {type: operationType, value} = operation; | ||
@@ -44,7 +43,7 @@ | ||
const dummy = {root: data}, | ||
dummyPath = ['root', ...path]; | ||
dummyPath = ['root', ...path], | ||
currentPath = []; | ||
// Walking the path | ||
let p = dummy, | ||
currentPath = [], | ||
i, | ||
@@ -77,8 +76,5 @@ l, | ||
if (opts.persistent) { | ||
p[s] = shallowClone(value); | ||
} | ||
else if (value instanceof MonkeyDefinition) { | ||
if (type.lazyGetter(p, s)) { | ||
Object.defineProperty(p, s, { | ||
value: value, | ||
value, | ||
enumerable: true, | ||
@@ -88,2 +84,5 @@ configurable: true | ||
} | ||
else if (opts.persistent) { | ||
p[s] = shallowClone(value); | ||
} | ||
else { | ||
@@ -112,6 +111,18 @@ p[s] = value; | ||
// Purity check | ||
if (opts.pure && result === value) | ||
return {node: p[s]}; | ||
if (opts.pure && p[s] === result) | ||
return {node: p[s]}; | ||
p[s] = opts.persistent ? shallowClone(result) : result; | ||
if (type.lazyGetter(p, s)) { | ||
Object.defineProperty(p, s, { | ||
value: result, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
} | ||
else if (opts.persistent) { | ||
p[s] = shallowClone(result); | ||
} | ||
else { | ||
p[s] = result; | ||
} | ||
} | ||
@@ -118,0 +129,0 @@ |
@@ -66,4 +66,4 @@ /** | ||
return v.solvedPath; | ||
else | ||
return this.mapping[k]; | ||
return this.mapping[k]; | ||
}); | ||
@@ -85,3 +85,3 @@ | ||
return cp.concat( | ||
getIn(this.tree._monkeys, p).data.relatedPaths() | ||
getIn(this.tree._monkeys, monkeyPath).data.relatedPaths() | ||
); | ||
@@ -127,5 +127,5 @@ | ||
// Creating the get method | ||
let projection = {}; | ||
const projection = {}; | ||
for (let k in mapping) | ||
for (const k in mapping) | ||
projection[k] = mapping[k] instanceof Cursor ? | ||
@@ -132,0 +132,0 @@ mapping[k].path : |
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
188683
20
4707
17
979