Comparing version 0.9.0 to 0.10.0
166
index.js
@@ -1,75 +0,9 @@ | ||
/* hugov@runbox.com | https://github.com/hville/attostore.git | license:MIT */ | ||
'use strict'; | ||
var getKey = require('./src/get-key'), | ||
isEqual = require('./src/is-eq'), | ||
pathKeys = require('./src/path-keys'), | ||
isObj = require('./src/is-obj') | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
module.exports = Store | ||
/** | ||
* @function | ||
* @param {*} v - object to test | ||
* @return {*} null|undefined|Constructor | ||
*/ | ||
function cType(v) { | ||
//null, String, Boolean, Number, Object, Array | ||
return v == null ? v : v.constructor || Object | ||
} | ||
function isObj(v) { | ||
return v && typeof v === 'object' | ||
} | ||
function missingKeys(reference, value) { | ||
var keys = isObj(reference) ? Object.keys(reference) : []; | ||
return isObj(value) ? keys.filter(filterVoid, value) : keys | ||
} | ||
function changedKeys(reference, value) { | ||
var keys = isObj(reference) ? Object.keys(reference) : [], | ||
diff = []; | ||
if (isObj(value)) for (var i=0; i<keys.length; ++i) { | ||
var key = keys[i], | ||
val = value[key]; | ||
if (val !== reference[key] && val !== undefined) diff.push(key); | ||
} | ||
return diff | ||
} | ||
function filterVoid(k) { | ||
return this[k] === undefined | ||
} | ||
function getKey(obj, key) { | ||
if (isObj(obj)) return obj[key] | ||
} | ||
/** | ||
* deep Equal check on JSON-like objects | ||
* @function | ||
* @param {*} obj - object to check | ||
* @param {*} ref - the reference | ||
* @return {boolean|void} true if equal | ||
*/ | ||
function isEqual(obj, ref) { | ||
var cO = cType(obj), | ||
cR = cType(ref); | ||
if (cO !== cR) return false | ||
if (cO === Array) { | ||
if (obj.length !== ref.length) return false | ||
for (var i=0; i<obj.length; ++i) if (!isEqual(obj[i], ref[i])) return false | ||
return true | ||
} | ||
if (cO === Object) { | ||
var ko = Object.keys(obj); //TODO type annotation obj: Object | ||
if (ko.length !== Object.keys(ref).length) return false //TODO type annotation typeof ref: Object | ||
for (i=0; i<ko.length; ++i) if (!isEqual(obj[ko[i]], ref[ko[i]])) return false | ||
return true | ||
} | ||
else return obj === ref | ||
} | ||
function pathKeys(path) { | ||
var ct = cType(path); | ||
return ct === Array ? path : ct === Number ? [path] : !path ? [] : path.split('/') | ||
} | ||
/** | ||
* @constructor | ||
@@ -79,5 +13,5 @@ * @param {*} initValue | ||
function Store(initValue) { | ||
this._ks = new Map; | ||
this._fs = []; | ||
this.data = initValue; | ||
this._ks = new Map | ||
this._fs = [] | ||
this.data = initValue | ||
} | ||
@@ -94,6 +28,6 @@ | ||
var leaf = setLeaf(this, pathKeys(key)), | ||
list = leaf._fs; | ||
if (indexOf(list, fcn, ctx) === -1) list.push({f: fcn, c:ctx}); | ||
list = leaf._fs | ||
if (indexOf(list, fcn, ctx) === -1) list.push({f: fcn, c:ctx}) | ||
return this | ||
}; | ||
} | ||
@@ -111,9 +45,9 @@ | ||
arr = itm && itm._fs, | ||
idx = indexOf(arr, fcn, ctx); | ||
idx = indexOf(arr, fcn, ctx) | ||
if (idx !== -1) { | ||
arr.splice(idx, 1); | ||
if (!arr.length && !itm._ks.size) delLeaf(this, keys, 0); | ||
arr.splice(idx, 1) | ||
if (!arr.length && !itm._ks.size) delLeaf(this, keys, 0) | ||
} | ||
return this | ||
}; | ||
} | ||
@@ -128,19 +62,19 @@ | ||
Store.prototype.once = function(key, fcn, ctx) { | ||
var store = this; | ||
var store = this | ||
function wrap(v,k,o) { | ||
store.off(key, wrap, ctx); | ||
fcn.call(this, v,k,o); | ||
fcn.call(this, v,k,o) | ||
} | ||
return this.on(key, wrap, ctx) | ||
}; | ||
} | ||
Store.prototype.get = function(path) { | ||
var keys = pathKeys(path); | ||
var keys = pathKeys(path) | ||
for (var i=0, itm = this.data; i<keys.length; ++i) { | ||
if (isObj(itm)) itm = itm[keys[i]]; | ||
if (isObj(itm)) itm = itm[keys[i]] | ||
else return | ||
} | ||
return itm | ||
}; | ||
} | ||
@@ -153,6 +87,6 @@ /** | ||
Store.prototype.set = function(path, data) { | ||
var res = setKeys(this.data, pathKeys(path), data, 0); | ||
var res = setKeys(this.data, pathKeys(path), data, 0) | ||
if (res instanceof Error) return res | ||
update(this, res, null); | ||
}; | ||
update(this, res, null) | ||
} | ||
@@ -165,9 +99,9 @@ | ||
Store.prototype.run = function(ops) { | ||
var res = this.data; | ||
var res = this.data | ||
for (var i=0; i<ops.length; ++i) { | ||
res = setKeys(res, pathKeys(ops[i].path), ops[i].data, 0); | ||
res = setKeys(res, pathKeys(ops[i].path), ops[i].data, 0) | ||
if (res instanceof Error) return res | ||
} | ||
update(this, res, null); | ||
}; | ||
update(this, res, null) | ||
} | ||
@@ -182,3 +116,3 @@ | ||
for (var i=0, itm = root; i<keys.length; ++i) { | ||
if (itm !== undefined) itm = itm._ks.get(''+keys[i]); | ||
if (itm !== undefined) itm = itm._ks.get(''+keys[i]) | ||
} | ||
@@ -196,5 +130,5 @@ return itm | ||
for (var i=0, itm = root; i<keys.length; ++i) { | ||
var key = ''+keys[i]; | ||
if (!itm._ks.has(key)) itm._ks.set(key, new Store(getKey(itm.data, key))); | ||
itm = itm._ks.get(key); | ||
var key = ''+keys[i] | ||
if (!itm._ks.has(key)) itm._ks.set(key, new Store(getKey(itm.data, key))) | ||
itm = itm._ks.get(key) | ||
} | ||
@@ -213,6 +147,6 @@ return itm | ||
var key = keys[idx++], | ||
kid = trie._ks.get(key); | ||
kid = trie._ks.get(key) | ||
if (kid instanceof Store) { | ||
if (idx !== keys.length) delLeaf(kid, keys, idx); | ||
if (!kid._ks.size && !kid._fs.length) trie._ks.delete(key); | ||
if (idx !== keys.length) delLeaf(kid, keys, idx) | ||
if (!kid._ks.size && !kid._fs.length) trie._ks.delete(key) | ||
} | ||
@@ -241,10 +175,10 @@ } | ||
function update(trie, val, key) { | ||
if (val !== trie.data) { | ||
var old = trie.data; | ||
trie.data = val; | ||
var old = trie.data | ||
if (val !== old) { | ||
trie.data = val | ||
// fire kids first... | ||
trie._ks.forEach(updateKid, val); | ||
trie._ks.forEach(updateKid, val) | ||
// ...then self | ||
for (var i=0, fs=trie._fs; i<fs.length; ++i) { | ||
fs[i].f.call(fs[i].c, val, key, old); | ||
fs[i].f.call(fs[i].c, val, key, old) | ||
} | ||
@@ -254,3 +188,3 @@ } | ||
function updateKid(kid, k) { | ||
update(kid, getKey(this, k), k); | ||
update(kid, getKey(this, k), k) | ||
} | ||
@@ -274,3 +208,3 @@ | ||
o = obj[k], | ||
v = setKeys(o, keys, val, idx+1); | ||
v = setKeys(o, keys, val, idx+1) | ||
return v instanceof Error ? v : v === o ? obj : Array.isArray(obj) ? aSet(obj, +k, v) : oSet(obj, k, v) | ||
@@ -287,10 +221,10 @@ } | ||
function aSet(arr, key, val) { | ||
var tgt = arr.slice(); | ||
var tgt = arr.slice() | ||
if (val === undefined) { | ||
if (key !== arr.length-1) return Error('only the last array item can be deleted') | ||
tgt.length = key; | ||
tgt.length = key | ||
return tgt | ||
} | ||
if (key <= arr.length) { | ||
tgt[key] = val; | ||
tgt[key] = val | ||
return tgt | ||
@@ -309,11 +243,5 @@ } | ||
function oSet(obj, key, val) { | ||
for (var i=0, ks=Object.keys(obj), res={}; i<ks.length; ++i) if (ks[i] !== key) res[ks[i]] = obj[ks[i]]; | ||
if (val !== undefined) res[key] = val; | ||
for (var i=0, ks=Object.keys(obj), res={}; i<ks.length; ++i) if (ks[i] !== key) res[ks[i]] = obj[ks[i]] | ||
if (val !== undefined) res[key] = val | ||
return res | ||
} | ||
// @ts-check | ||
exports.changedKeys = changedKeys; | ||
exports.missingKeys = missingKeys; | ||
exports.Store = Store; |
{ | ||
"name": "attostore", | ||
"version": "0.9.0", | ||
"version": "0.10.0", | ||
"description": "json data store", | ||
@@ -16,15 +16,8 @@ "keywords": [ | ||
"devDependencies": { | ||
"@types/node": "^8.0.12", | ||
"cotest": "^2.1.0", | ||
"node-dynamic-import": "0.0.1" | ||
"@types/node": "^8.5.9", | ||
"cotest": "^3.0.0" | ||
}, | ||
"scripts": { | ||
"test": "npm run build:main & cotest ./tst", | ||
"build:main": "rollup -o ./index.js -f cjs --banner \"/* hugov@runbox.com | https://github.com/hville/attostore.git | license:MIT */\" ./module.js", | ||
"build:browser": "rollup -o ./browser.js -f iife -n attostore --banner \"/* hugov@runbox.com | https://github.com/hville/attostore.git | license:MIT */\" ./module.js", | ||
"build": "npm run build:main & npm run build:browser", | ||
"prepublishOnly": "npm test & npm run build:browser", | ||
"gzip": "node -e \"fs.writeFileSync(process.argv[2], zlib.gzipSync(fs.readFileSync(process.argv[1])))\"", | ||
"build:min": "google-closure-compiler-js --compilationLevel ADVANCED --languageIn ES5 --languageOut ES5 --useTypesForOptimization true ./browser.js > ./bld/browser.min.js", | ||
"build:gzip": "npm run gzip -- ./bld/browser.min.js ./bld/browser.gz" | ||
"test": "cotest ./tst", | ||
"prepublishOnly": "npm test" | ||
}, | ||
@@ -31,0 +24,0 @@ "repository": { |
@@ -1,2 +0,2 @@ | ||
# attodom | ||
# attostore | ||
@@ -10,4 +10,3 @@ *small json in-memory store with path events, ~3kb min, ~1kb gz* | ||
```javascript | ||
import {Store} from 'attostore' | ||
var Store = require('attostore') | ||
var store = new Store({}) | ||
@@ -19,14 +18,8 @@ | ||
store.run([{path:'a/b', data:'hello'}]) | ||
store.set(['a', 'b'], data:'world') | ||
store.run([{path:'a/b', data:'hello'}]) //runs a series of patches | ||
store.set(['a', 'b'], 'world') //directly sets a value | ||
``` | ||
supports different environments | ||
* CJS: `var create = require('attostore').createStore` | ||
* ES modules: `import {createStore} from 'attostore'` | ||
### Features, Limitations, Gotcha | ||
* available in CommonJS and ES6 modules | ||
* only the last item of an Array can be deleted to avoid shifting of keys | ||
@@ -62,3 +55,3 @@ * No Array splicing to keep the keys unchanged. additions and removals from the end only (eg. push pop) | ||
* `0`, `"0"`, `[0]`, `["0"]` are equivalent | ||
* `''`, `null`, `undefined` are equivalent | ||
* `''`, `null`, `undefined`, `[]` all point to the root | ||
* `a/b`, `["a", "b"]` are equivalent | ||
@@ -65,0 +58,0 @@ |
@@ -1,5 +0,5 @@ | ||
import {isObj} from './type' | ||
var isObj = require('./is-obj') | ||
export function getKey(obj, key) { | ||
module.exports = function getKey(obj, key) { | ||
if (isObj(obj)) return obj[key] | ||
} |
@@ -1,3 +0,5 @@ | ||
import {cType} from './type' | ||
var cType = require('./c-type') | ||
module.exports = isEqual | ||
/** | ||
@@ -10,3 +12,3 @@ * deep Equal check on JSON-like objects | ||
*/ | ||
export function isEqual(obj, ref) { | ||
function isEqual(obj, ref) { | ||
var cO = cType(obj), | ||
@@ -13,0 +15,0 @@ cR = cType(ref) |
@@ -1,6 +0,25 @@ | ||
import {cType} from './type' | ||
var cType = require('./c-type') | ||
export function pathKeys(path) { | ||
var ct = cType(path) | ||
return ct === Array ? path : ct === Number ? [path] : !path ? [] : path.split('/') | ||
/** | ||
* @param {*} path | ||
* @return {Array<string>} | ||
*/ | ||
module.exports = function(path) { | ||
switch (cType(path)) { | ||
case Number: return ['' + path] | ||
case Array: return path.map(keyString) | ||
case undefined: case null: return [] | ||
case String: | ||
if (!path) return [] | ||
if (path[0] !== '/') return path.split('/') | ||
} | ||
throw Error('invalid key of type ' + typeof path) | ||
} | ||
function keyString(k) { | ||
switch (cType(k)) { | ||
case String: return k | ||
case Number: return '' + k | ||
} | ||
throw Error('invalid key of type ' + typeof k) | ||
} |
@@ -1,8 +0,6 @@ | ||
var S = require( '../index' ), | ||
var changed = require('../changed-keys'), | ||
missing = require('../missing-keys'), | ||
t = require('cotest') | ||
var changed = S.changedKeys, | ||
missing = S.missingKeys | ||
t('compare - changed', function() { | ||
@@ -9,0 +7,0 @@ t('{==}', changed([0,1,2], [0,1,9]), [2]) |
@@ -1,8 +0,6 @@ | ||
var S = require( '../index' ), | ||
var Store = require( '../index' ), | ||
changed = require('../changed-keys'), | ||
missing = require('../missing-keys'), | ||
t = require('cotest') | ||
var Store = S.Store, | ||
changed = S.changedKeys, | ||
missing = S.missingKeys | ||
function compare(v,k,o) { | ||
@@ -85,5 +83,5 @@ t('!==', v, o, 'child event only if value changed: ') | ||
t('===', store.set('a/b', 9) instanceof Error, true) | ||
t('===', store.set('a/b') instanceof Error, true) | ||
t('===', store.set('a/b', undefined) instanceof Error, true) | ||
var res = store.run([{path:'a/b', data:9}]) | ||
t('===', res instanceof Error && res.message, 'invalid path: a/b') | ||
}) |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
2
14217
14
413
59
1