Comparing version 0.1.4 to 0.1.5
@@ -33,3 +33,3 @@ 'use strict'; | ||
var _invalidate2 = require('./invalidate'); | ||
var _invalidate = require('./invalidate'); | ||
@@ -45,32 +45,21 @@ var Avenger = (function () { | ||
this.emit = function (meta, value) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
_types.EmitMeta(meta); | ||
} | ||
var id = meta.id; | ||
var _meta$cache = meta.cache; | ||
meta = _types.EmitMeta(meta); | ||
value = _tcomb2['default'].Any(value); | ||
var _meta = meta; | ||
var id = _meta.id; | ||
var _meta$loading = _meta.loading; | ||
var loading = _meta$loading === undefined ? false : _meta$loading; | ||
var _meta$cache = _meta.cache; | ||
var cache = _meta$cache === undefined ? false : _meta$cache; | ||
var _meta$error = meta.error; | ||
var _meta$error = _meta.error; | ||
var error = _meta$error === undefined ? false : _meta$error; | ||
var _meta$multi = meta.multi; | ||
var _meta$multi = _meta.multi; | ||
var multi = _meta$multi === undefined ? false : _meta$multi; | ||
var _meta$multiAll = meta.multiAll; | ||
var _meta$multiAll = _meta.multiAll; | ||
var multiAll = _meta$multiAll === undefined ? false : _meta$multiAll; | ||
var _meta$loading = meta.loading; | ||
var loading = _meta$loading === undefined ? false : _meta$loading; | ||
var now = new Date().getTime(); | ||
var _ref = _this.result.__meta[id] || {}; | ||
var currentCache = _ref.cache; | ||
if (error) { | ||
// TODO(gio): should also update __meta | ||
// and emit a `change` | ||
_this.emitter.emit('error', value); | ||
return; | ||
} | ||
if (multi && !multiAll) { | ||
// swallow up! | ||
// not sure about this, | ||
@@ -82,5 +71,9 @@ // but seems easier to just emit once | ||
// TODO(gio): we should make sure not to | ||
// throw away valid refs here... | ||
if (value) { | ||
// TODO(gio): should value be the last valid value even if | ||
// last fetch caused an error? | ||
// error meta is anyway updated accordingly below | ||
if (!error) { | ||
// TODO(gio): we should make sure not to throw away | ||
// valid refs here... but as long as potentially reusable | ||
// values are from cache (memory), we should be safe | ||
_this.result[id] = value; | ||
@@ -93,11 +86,13 @@ } | ||
loading: loading, | ||
error: false | ||
error: !!error | ||
}; | ||
if (error) { | ||
_this.emitter.emit('error', value); | ||
} | ||
_this.emitter.emit('change', _extends({}, _this.result)); | ||
}; | ||
if (process.env.NODE_ENV !== 'production') { | ||
_tcomb2['default'].assert(_types.AvengerInput.is(allQueries), 'Invalid allQueries'); | ||
} | ||
allQueries = _types.AvengerInput(allQueries); | ||
@@ -112,2 +107,7 @@ this.allQueries = allQueries; | ||
}; | ||
if (process.env.NODE_ENV === 'development') { | ||
if (typeof window !== 'undefined') { | ||
window.$av = this; | ||
} | ||
} | ||
} | ||
@@ -128,53 +128,66 @@ | ||
Avenger.prototype.run = function run(input, state) { | ||
var _this2 = this; | ||
input = _types.AvengerInput(input); | ||
state = _types.State(state); | ||
// TODO(gio): not handling remote version for now | ||
var ret = function (input, state) { | ||
var _this2 = this; | ||
var built = _build2['default'](input, this.allQueries); | ||
// TODO(gio): not handling remote version for now | ||
var built = _build2['default'](input, this.allQueries); | ||
// cleanup current result.. | ||
this.result = Object.keys(built || {}).map(function (k) { | ||
return built[k]; | ||
}).reduce(function (ac, _ref2) { | ||
var _extends2, _extends3; | ||
// cleanup current result.. | ||
this.result = Object.keys(built || {}).map(function (k) { | ||
return built[k]; | ||
}).reduce(function (ac, _ref) { | ||
var _extends2, _extends3; | ||
var id = _ref2.query.id; | ||
return _extends({}, ac, (_extends3 = {}, _extends3[id] = _this2.result[id], _extends3.__meta = _extends({}, ac.__meta, (_extends2 = {}, _extends2[id] = _this2.result.__meta[id], _extends2)), _extends3)); | ||
}, {}); | ||
var id = _ref.query.id; | ||
return _extends({}, ac, (_extends3 = {}, _extends3[id] = _this2.result[id], _extends3.__meta = _extends({}, ac.__meta, (_extends2 = {}, _extends2[id] = _this2.result.__meta[id], _extends2)), _extends3)); | ||
}, {}); | ||
return _run.runLocal({ | ||
input: built, | ||
oldInput: this.currentInput, | ||
state: state, | ||
oldState: this.currentState, | ||
cache: this.cache, | ||
emit: this.emit | ||
}).then(function (res) { | ||
_this2.currentInput = built; | ||
_this2.currentState = state; | ||
return res; | ||
}, function (err) { | ||
throw err; | ||
}); | ||
return _run.runLocal({ | ||
input: built, | ||
oldInput: this.currentInput, | ||
state: state, | ||
oldState: this.currentState, | ||
cache: this.cache, | ||
emit: this.emit | ||
}).then(function (res) { | ||
_this2.currentInput = built; | ||
_this2.currentState = state; | ||
return res; | ||
}, function (err) { | ||
throw err; | ||
}); | ||
}.call(this, input, state); | ||
return _types.PromiseType(ret); | ||
}; | ||
Avenger.prototype.invalidate = function invalidate(state, _invalidate) { | ||
// TODO(gio): not handling remote version for now | ||
Avenger.prototype.invalidate = function invalidate(state, _inv) { | ||
state = _types.State(state); | ||
_inv = _types.AvengerInput(_inv); | ||
var _result = this.result; | ||
var __meta = _result.__meta; | ||
var ret = function (state, _inv) { | ||
// TODO(gio): not handling remote version for now | ||
var result = _objectWithoutProperties(_result, ['__meta']); | ||
var _result = this.result; | ||
var __meta = _result.__meta; | ||
return _invalidate2.invalidateLocal({ | ||
invalidate: _invalidate, | ||
input: this.currentInput, | ||
result: result, | ||
state: state, | ||
cache: this.cache, | ||
emit: this.emit | ||
}); | ||
var result = _objectWithoutProperties(_result, ['__meta']); | ||
return _invalidate.invalidateLocal({ | ||
invalidate: _inv, | ||
input: this.currentInput, | ||
result: result, | ||
state: state, | ||
cache: this.cache, | ||
emit: this.emit | ||
}); | ||
}.call(this, state, _inv); | ||
return _types.PromiseType(ret); | ||
}; | ||
// there should also be a way to track subsequent invalidation | ||
// TODO(gio): there should also be a way to track subsequent invalidation | ||
// e.g. `runCommandAndThenWaitForSubsequentInvalidation` | ||
@@ -184,16 +197,19 @@ // or this could be built on top of emit if we add a `stable` event | ||
Avenger.prototype.runCommand = function runCommand(state, command) { | ||
var _this3 = this; | ||
state = _types.State(state); | ||
command = _types.Command(command); | ||
// TODO(gio): not handling remote version for now | ||
var ret = function (state, command) { | ||
var _this3 = this; | ||
if (process.env.NODE_ENV !== 'production') { | ||
_types.Command(command); | ||
} | ||
// TODO(gio): not handling remote version for now | ||
return command.run(state).then(function (res) { | ||
_this3.invalidate(state, command.invalidates); | ||
return res; | ||
}, function (err) { | ||
throw err; | ||
}); | ||
return command.run(state).then(function (res) { | ||
_this3.invalidate(state, command.invalidates); | ||
return res; | ||
}, function (err) { | ||
throw err; | ||
}); | ||
}.call(this, state, command); | ||
return _types.PromiseType(ret); | ||
}; | ||
@@ -200,0 +216,0 @@ |
@@ -27,13 +27,16 @@ // a cache implementation able to produce an ActualizedCache | ||
function hashedParams(params) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
_types.State(params); | ||
} | ||
var keys = Object.keys(params); | ||
keys.sort(function (a, b) { | ||
return a < b ? -1 : a > b ? 1 : 0; | ||
}); | ||
var hashed = keys.map(function (k1) { | ||
return k1 + ':' + params[k1]; | ||
}).join('-'); | ||
return hashed ? hashed : '∅'; | ||
params = _types.State(params); | ||
var ret = function (params) { | ||
var keys = Object.keys(params); | ||
keys.sort(function (a, b) { | ||
return a < b ? -1 : a > b ? 1 : 0; | ||
}); | ||
var hashed = keys.map(function (k1) { | ||
return k1 + ':' + params[k1]; | ||
}).join('-'); | ||
return hashed ? hashed : '∅'; | ||
}.call(this, params); | ||
return _tcomb2['default'].Str(ret); | ||
} | ||
@@ -50,4 +53,6 @@ | ||
this.set = function (id, params) { | ||
id = _tcomb2['default'].String(id); | ||
params = _types.State(params); | ||
return function (value) { | ||
_this.checkParams(params); | ||
value = _tcomb2['default'].Any(value); | ||
@@ -67,3 +72,4 @@ var hp = hashedParams(params); | ||
this.invalidate = function (id, params) { | ||
_this.checkParams(params); | ||
id = _tcomb2['default'].String(id); | ||
params = _types.State(params); | ||
@@ -80,29 +86,37 @@ if (_this.state[id]) { | ||
AvengerCache.prototype.toJSON = function toJSON() { | ||
return this.state; | ||
}; | ||
var ret = function () { | ||
return this.state; | ||
}.call(this); | ||
AvengerCache.prototype.checkParams = function checkParams(params) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
_tcomb2['default'].assert(_types.State.is(params), 'Invalid params provided to cache: ' + JSON.stringify(params)); | ||
} | ||
return _types.CacheState(ret); | ||
}; | ||
AvengerCache.prototype.has = function has(id, params) { | ||
this.checkParams(params); | ||
id = _tcomb2['default'].String(id); | ||
params = _types.State(params); | ||
if (!this.state[id]) { | ||
return false; | ||
} | ||
var ret = function (id, params) { | ||
if (!this.state[id]) { | ||
return false; | ||
} | ||
return typeof this.state[id][hashedParams(params)] !== 'undefined'; | ||
return typeof this.state[id][hashedParams(params)] !== 'undefined'; | ||
}.call(this, id, params); | ||
return _tcomb2['default'].Boolean(ret); | ||
}; | ||
AvengerCache.prototype.get = function get(id, params) { | ||
this.checkParams(params); | ||
id = _tcomb2['default'].String(id); | ||
params = _types.State(params); | ||
if (!this.state[id]) { | ||
return null; | ||
} | ||
var ret = function (id, params) { | ||
if (!this.state[id]) { | ||
return null; | ||
} | ||
return this.state[id][hashedParams(params)] || null; | ||
return this.state[id][hashedParams(params)] || null; | ||
}.call(this, id, params); | ||
return _tcomb2['default'].Any(ret); | ||
}; | ||
@@ -109,0 +123,0 @@ |
108
lib/build.js
@@ -33,68 +33,68 @@ 'use strict'; | ||
// (AvengerInput, AvengerInput) -> QueryNodes | ||
function build(input, all) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
_tcomb2['default'].assert(_types.AvengerInput.is(input), 'invalid input provided to build'); | ||
_tcomb2['default'].assert(_types.AvengerInput.is(all), 'invalid all provided to build'); | ||
} | ||
input = _types.AvengerInput(input); | ||
all = _types.AvengerInput(all); | ||
var _upset = _upset3['default'](input); | ||
var ret = function (input, all) { | ||
var _upset = _upset3['default'](input); | ||
var builtUp = Object.keys(_upset).reduce(function (_ref) { | ||
var _extends3; | ||
var builtUp = Object.keys(_upset).reduce(function (_ref) { | ||
var _extends3; | ||
var from = _ref.from; | ||
var to = _ref.to; | ||
var from = _ref.from; | ||
var to = _ref.to; | ||
var fromList = Object.keys(from).map(function (k) { | ||
return from[k]; | ||
}); | ||
var firstFree = _lodashCollectionFind2['default'](fromList, function (_ref2) { | ||
var deps = _ref2.dependencies; | ||
return _lodashCollectionEvery2['default'](Object.keys(deps || {}).map(function (k) { | ||
return deps[k].query.id; | ||
}), function (id) { | ||
return !!to[id]; | ||
var fromList = Object.keys(from).map(function (k) { | ||
return from[k]; | ||
}); | ||
var firstFree = _lodashCollectionFind2['default'](fromList, function (_ref2) { | ||
var deps = _ref2.dependencies; | ||
return _lodashCollectionEvery2['default'](Object.keys(deps || {}).map(function (k) { | ||
return deps[k].query.id; | ||
}), function (id) { | ||
return !!to[id]; | ||
}); | ||
}); | ||
return { | ||
from: _extends({}, _lodashObjectOmit2['default'](from, firstFree.id)), | ||
to: _extends({}, to, (_extends3 = {}, _extends3[firstFree.id] = { | ||
query: firstFree, | ||
parents: Object.keys(firstFree.dependencies || {}).map(function (k) { | ||
return firstFree.dependencies[k].query.id; | ||
}).reduce(function (parents, id) { | ||
var _extends2; | ||
return _extends({}, parents, (_extends2 = {}, _extends2[id] = to[id], _extends2)); | ||
}, {}), | ||
children: {} | ||
}, _extends3)) | ||
}; | ||
}, { | ||
from: _extends({}, _upset), | ||
to: {} | ||
}).to; | ||
var builtUpList = Object.keys(builtUp).map(function (qId) { | ||
return builtUp[qId]; | ||
}); | ||
return { | ||
from: _extends({}, _lodashObjectOmit2['default'](from, firstFree.id)), | ||
to: _extends({}, to, (_extends3 = {}, _extends3[firstFree.id] = { | ||
query: firstFree, | ||
parents: Object.keys(firstFree.dependencies || {}).map(function (k) { | ||
return firstFree.dependencies[k].query.id; | ||
}).reduce(function (parents, id) { | ||
var _extends2; | ||
return builtUpList.reduce(function (ac, qn) { | ||
var _extends5; | ||
return _extends({}, parents, (_extends2 = {}, _extends2[id] = to[id], _extends2)); | ||
}, {}), | ||
children: {} | ||
}, _extends3)) | ||
}; | ||
}, { | ||
from: _extends({}, _upset), | ||
to: {} | ||
}).to; | ||
return _extends({}, ac, (_extends5 = {}, _extends5[qn.query.id] = (function () { | ||
qn.children = builtUpList.filter(function (_ref3) { | ||
var parents = _ref3.parents; | ||
return !!parents[qn.query.id]; | ||
}).reduce(function (nc, n) { | ||
var _extends4; | ||
var builtUpList = Object.keys(builtUp).map(function (qId) { | ||
return builtUp[qId]; | ||
}); | ||
return builtUpList.reduce(function (ac, qn) { | ||
var _extends5; | ||
return _extends({}, nc, (_extends4 = {}, _extends4[n.query.id] = n, _extends4)); | ||
}, {}); | ||
return qn; | ||
})(), _extends5)); | ||
}, {}); | ||
}.call(this, input, all); | ||
return _extends({}, ac, (_extends5 = {}, _extends5[qn.query.id] = (function () { | ||
qn.children = builtUpList.filter(function (_ref3) { | ||
var parents = _ref3.parents; | ||
return !!parents[qn.query.id]; | ||
}).reduce(function (nc, n) { | ||
var _extends4; | ||
return _extends({}, nc, (_extends4 = {}, _extends4[n.query.id] = n, _extends4)); | ||
}, {}); | ||
return qn; | ||
})(), _extends5)); | ||
}, {}); | ||
return _types.QueryNodes(ret); | ||
} | ||
module.exports = exports['default']; |
@@ -80,3 +80,3 @@ 'use strict'; | ||
var multiParams = args.depsParams[multiDep.key]; | ||
_tcomb2['default'].assert(_tcomb2['default'].Arr.is(multiParams), 'Invalid (non-Array) result for dependency param ' + multiDep.key + ' (among ' + args.id + ' params)'); | ||
_tcomb2['default'].assert(_tcomb2['default'].Array.is(multiParams), 'Invalid (non-Array) result for dependency param ' + multiDep.key + ' (among ' + args.id + ' params)'); | ||
@@ -83,0 +83,0 @@ var emit = function emit(index) { |
@@ -1,2 +0,2 @@ | ||
"use strict"; | ||
'use strict'; | ||
@@ -7,12 +7,20 @@ exports.__esModule = true; | ||
exports["default"] = downset; | ||
exports['default'] = downset; | ||
var _types = require('./types'); | ||
function downset(nodes) { | ||
return Object.keys(nodes).reduce(function (down, qId) { | ||
var _extends2; | ||
nodes = _types.QueryNodes(nodes); | ||
return _extends({}, down, (_extends2 = {}, _extends2[qId] = nodes[qId], _extends2), downset(nodes[qId].children)); | ||
}, {}); | ||
var ret = function (nodes) { | ||
return Object.keys(nodes).reduce(function (down, qId) { | ||
var _extends2; | ||
return _extends({}, down, (_extends2 = {}, _extends2[qId] = nodes[qId], _extends2), downset(nodes[qId].children)); | ||
}, {}); | ||
}.call(this, nodes); | ||
return _types.QueryNodes(ret); | ||
} | ||
module.exports = exports["default"]; | ||
module.exports = exports['default']; |
@@ -25,79 +25,81 @@ 'use strict'; | ||
state: _types.State, | ||
result: _tcomb2['default'].Obj, | ||
result: _tcomb2['default'].Object, | ||
cache: _tcomb2['default'].Any, | ||
emit: _tcomb2['default'].Func | ||
emit: _tcomb2['default'].Function | ||
}, 'InvalidateLocalParams'); | ||
function invalidateLocal(params) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
InvalidateLocalParams(params); | ||
} | ||
params = InvalidateLocalParams(params); | ||
var | ||
// queries to be invalidated | ||
invalidate = params.invalidate; | ||
var | ||
// current QS queries | ||
input = params.input; | ||
var | ||
// current result | ||
result = params.result; | ||
var state = params.state; | ||
var cache = params.cache; | ||
var emit = params.emit; | ||
var ret = function (params) { | ||
var | ||
// queries to be invalidated | ||
invalidate = params.invalidate; | ||
var | ||
// current QS queries | ||
input = params.input; | ||
var | ||
// current result | ||
result = params.result; | ||
var state = params.state; | ||
var cache = params.cache; | ||
var emit = params.emit; | ||
var oldInput = _extends({}, input); | ||
var oldInput = _extends({}, input); | ||
var _invalidate = function _invalidate(_ref) { | ||
var _ref$query = _ref.query; | ||
var id = _ref$query.id; | ||
var cacheParams = _ref$query.cacheParams; | ||
var dependencies = _ref$query.dependencies; | ||
var children = _ref.children; | ||
var _invalidate = function _invalidate(_ref) { | ||
var _ref$query = _ref.query; | ||
var id = _ref$query.id; | ||
var cacheParams = _ref$query.cacheParams; | ||
var dependencies = _ref$query.dependencies; | ||
var children = _ref.children; | ||
var depsParams = Object.keys(dependencies || {}).map(function (k) { | ||
return { | ||
k: k, val: dependencies[k].map(result[dependencies[k].query.id]) | ||
}; | ||
}).reduce(function (ac, _ref2) { | ||
var _extends2; | ||
var depsParams = Object.keys(dependencies || {}).map(function (k) { | ||
return { | ||
k: k, val: dependencies[k].map(result[dependencies[k].query.id]) | ||
}; | ||
}).reduce(function (ac, _ref2) { | ||
var _extends2; | ||
var k = _ref2.k; | ||
var val = _ref2.val; | ||
return _extends({}, ac, (_extends2 = {}, _extends2[k] = val, _extends2)); | ||
}, {}); | ||
var allParams = _extends({}, state, depsParams); | ||
var allKeys = Object.keys(allParams); | ||
var filteredKeys = allKeys.filter(function (k) { | ||
return (cacheParams ? Object.keys(cacheParams) : allKeys).indexOf(k) !== -1; | ||
}); | ||
var filteredCacheParams = filteredKeys.reduce.apply(filteredKeys, _util.collect(allParams)); | ||
var k = _ref2.k; | ||
var val = _ref2.val; | ||
return _extends({}, ac, (_extends2 = {}, _extends2[k] = val, _extends2)); | ||
}, {}); | ||
var allParams = _extends({}, state, depsParams); | ||
var allKeys = Object.keys(allParams); | ||
var filteredKeys = allKeys.filter(function (k) { | ||
return (cacheParams ? Object.keys(cacheParams) : allKeys).indexOf(k) !== -1; | ||
}); | ||
var filteredCacheParams = filteredKeys.reduce.apply(filteredKeys, _util.collect(allParams)); | ||
// invalidate cache for this query | ||
cache.invalidate(id, filteredCacheParams); | ||
// keep track of non-stale (invaldiated) queries | ||
// in oldInput in order to trick `run` | ||
delete oldInput[id]; | ||
// invalidate cache for this query | ||
cache.invalidate(id, filteredCacheParams); | ||
// keep track of non-stale (invaldiated) queries | ||
// in oldInput in order to trick `run` | ||
delete oldInput[id]; | ||
Object.keys(children).map(function (k) { | ||
return children[k]; | ||
Object.keys(children).map(function (k) { | ||
return children[k]; | ||
}).forEach(_invalidate); | ||
}; | ||
Object.keys(invalidate).map(function (k) { | ||
return input[k]; | ||
}).forEach(_invalidate); | ||
}; | ||
Object.keys(invalidate).map(function (k) { | ||
return input[k]; | ||
}).forEach(_invalidate); | ||
return _run.runLocal({ | ||
state: state, oldState: state, | ||
input: input, oldInput: oldInput, | ||
cache: cache, | ||
emit: emit | ||
}).then(function (fresh) { | ||
return _extends({}, result, fresh); | ||
}, function (err) { | ||
throw err; | ||
}); | ||
}.call(this, params); | ||
return _run.runLocal({ | ||
state: state, oldState: state, | ||
input: input, oldInput: oldInput, | ||
cache: cache, | ||
emit: emit | ||
}).then(function (fresh) { | ||
return _extends({}, result, fresh); | ||
}, function (err) { | ||
throw err; | ||
}); | ||
return _types.PromiseType(ret); | ||
} | ||
// export function invalidateRemote() {} |
@@ -24,26 +24,30 @@ 'use strict'; | ||
var PositiveDiffOutput = _tcomb2['default'].dict(_tcomb2['default'].String, _tcomb2['default'].Boolean, 'PositiveDiffOutput'); | ||
function positiveDiff(params) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
PositiveDiffParams(params); | ||
} | ||
params = PositiveDiffParams(params); | ||
var a = params.a; | ||
var b = params.b; | ||
var aState = params.aState; | ||
var bState = params.bState; | ||
var ret = function (params) { | ||
var a = params.a; | ||
var b = params.b; | ||
var aState = params.aState; | ||
var bState = params.bState; | ||
var stateDiff = function stateDiff(a, b, query) { | ||
var relevantKeys = query.cacheParams ? Object.keys(query.cacheParams) : Object.keys(a); | ||
return relevantKeys.reduce(function (ac, k) { | ||
return ac || a[k] !== b[k]; | ||
}, false); | ||
}; | ||
var stateDiff = function stateDiff(a, b, query) { | ||
var relevantKeys = query.cacheParams ? Object.keys(query.cacheParams) : Object.keys(a); | ||
return relevantKeys.reduce(function (ac, k) { | ||
return ac || a[k] !== b[k]; | ||
}, false); | ||
}; | ||
return Object.keys(a).reduce(function (ac, nk) { | ||
var _extends2; | ||
return Object.keys(a).reduce(function (ac, nk) { | ||
var _extends2; | ||
return _extends({}, ac, (_extends2 = {}, _extends2[nk] = !(b || {})[nk] || stateDiff(aState || {}, bState || {}, a[nk].query), _extends2)); | ||
}, {}); | ||
return _extends({}, ac, (_extends2 = {}, _extends2[nk] = !(b || {})[nk] || stateDiff(aState || {}, bState || {}, a[nk].query), _extends2)); | ||
}, {}); | ||
}.call(this, params); | ||
return PositiveDiffOutput(ret); | ||
} | ||
module.exports = exports['default']; |
145
lib/run.js
@@ -14,3 +14,3 @@ 'use strict'; | ||
var _types = require( /*, MinimizedCache*/'./types'); | ||
var _types = require('./types'); | ||
@@ -41,89 +41,91 @@ var _util = require('./util'); | ||
cache: _tcomb2['default'].Any, | ||
emit: _tcomb2['default'].Func | ||
emit: _tcomb2['default'].Function | ||
}, 'RunLocalParams'); | ||
function runLocal(params) { | ||
var _Object$keys$filter, _Object$keys2; | ||
params = RunLocalParams(params); | ||
if (process.env.NODE_ENV !== 'production') { | ||
RunLocalParams(params); | ||
} | ||
var ret = function (params) { | ||
var _Object$keys$filter, _Object$keys2; | ||
var input = params.input; | ||
var oldInput = params.oldInput; | ||
var state = params.state; | ||
var oldState = params.oldState; | ||
var cache = params.cache; | ||
var emit = params.emit; | ||
var input = params.input; | ||
var oldInput = params.oldInput; | ||
var state = params.state; | ||
var oldState = params.oldState; | ||
var cache = params.cache; | ||
var emit = params.emit; | ||
// typecheck state params | ||
if (process.env.NODE_ENV !== 'production') { | ||
Object.keys(input).forEach(function (k) { | ||
var _input$k$query = input[k].query; | ||
var cacheParams = _input$k$query.cacheParams; | ||
var dependencies = _input$k$query.dependencies; | ||
// typecheck state params | ||
if (process.env.NODE_ENV !== 'production') { | ||
Object.keys(input).forEach(function (k) { | ||
var _input$k$query = input[k].query; | ||
var cacheParams = _input$k$query.cacheParams; | ||
var dependencies = _input$k$query.dependencies; | ||
Object.keys(cacheParams || {}).filter(function (k) { | ||
return Object.keys(dependencies || {}).indexOf(k) === -1; | ||
}).forEach(function (k) { | ||
cacheParams[k](state[k]); | ||
Object.keys(cacheParams || {}).filter(function (k) { | ||
return Object.keys(dependencies || {}).indexOf(k) === -1; | ||
}).forEach(function (k) { | ||
cacheParams[k](state[k]); | ||
}); | ||
}); | ||
} | ||
var diff = _positiveDiff2['default']({ | ||
a: input, b: oldInput, aState: state, bState: oldState | ||
}); | ||
} | ||
var toRun = _downset2['default']((_Object$keys$filter = Object.keys(input).filter(function (k) { | ||
return diff[k]; | ||
})).reduce.apply(_Object$keys$filter, _util.collect(input))); | ||
var runState = {}; | ||
var diff = _positiveDiff2['default']({ | ||
a: input, b: oldInput, aState: state, bState: oldState | ||
}); | ||
var toRun = _downset2['default']((_Object$keys$filter = Object.keys(input).filter(function (k) { | ||
return diff[k]; | ||
})).reduce.apply(_Object$keys$filter, _util.collect(input))); | ||
var runState = {}; | ||
var _run = function _run(node) { | ||
var _Object$keys; | ||
var _run = function _run(node) { | ||
var _Object$keys; | ||
var _node$query = node.query; | ||
var id = _node$query.id; | ||
var dependencies = _node$query.dependencies; | ||
var fetch = _node$query.fetch; | ||
var cacheMode = _node$query.cache; | ||
var cacheParams = _node$query.cacheParams; | ||
var parents = node.parents; | ||
var _node$query = node.query; | ||
var id = _node$query.id; | ||
var dependencies = _node$query.dependencies; | ||
var fetch = _node$query.fetch; | ||
var cacheMode = _node$query.cache; | ||
var cacheParams = _node$query.cacheParams; | ||
var parents = node.parents; | ||
var more = _objectWithoutProperties(node, ['query', 'parents']); | ||
var more = _objectWithoutProperties(node, ['query', 'parents']); | ||
if (runState[id]) { | ||
return runState[id]; | ||
} | ||
if (runState[id]) { | ||
return runState[id]; | ||
} | ||
var depsPrsObj = (_Object$keys = Object.keys(parents)).reduce.apply(_Object$keys, _util.collect(parents, _run)); | ||
var depsPrs = _util.allValues(depsPrsObj); | ||
var depsPrsObj = (_Object$keys = Object.keys(parents)).reduce.apply(_Object$keys, _util.collect(parents, _run)); | ||
var depsPrs = _util.allValues(depsPrsObj); | ||
runState[id] = new Promise(function (resolve, reject) { | ||
depsPrs.then(function (depsResults) { | ||
return _createFetcher2['default']({ | ||
id: id, fetch: fetch, state: state, cache: cache, cacheMode: cacheMode, cacheParams: cacheParams, emit: emit, reject: reject, | ||
depsParams: _minDepsParams2['default'](dependencies || {}, depsResults), | ||
multiDep: (function () { | ||
var multiKey = Object.keys(dependencies || {}).filter(function (k) { | ||
return !!dependencies[k].multi; | ||
})[0]; | ||
return multiKey && { | ||
key: multiKey, | ||
map: _tcomb2['default'].Function.is(dependencies[multiKey]) ? dependencies[multiKey] : function (v) { | ||
return v; | ||
} | ||
}; | ||
})() | ||
}).then(function (res) { | ||
resolve(res); | ||
return res; | ||
}, _util.error(emit, id, reject)); | ||
}, _util.error(emit, id, reject))['catch'](_util.error(emit, id, reject)); | ||
}); | ||
runState[id] = new Promise(function (resolve, reject) { | ||
depsPrs.then(function (depsResults) { | ||
return _createFetcher2['default']({ | ||
id: id, fetch: fetch, state: state, cache: cache, cacheMode: cacheMode, cacheParams: cacheParams, emit: emit, reject: reject, | ||
depsParams: _minDepsParams2['default'](dependencies || {}, depsResults), | ||
multiDep: (function () { | ||
var multiKey = Object.keys(dependencies || {}).filter(function (k) { | ||
return !!dependencies[k].multi; | ||
})[0]; | ||
return multiKey && { | ||
key: multiKey, | ||
map: _tcomb2['default'].Func.is(dependencies[multiKey]) ? dependencies[multiKey] : function (v) { | ||
return v; | ||
} | ||
}; | ||
})() | ||
}).then(function (res) { | ||
resolve(res); | ||
return res; | ||
}, _util.error(emit, id, reject)); | ||
}, _util.error(emit, id, reject))['catch'](_util.error(emit, id, reject)); | ||
}); | ||
return runState[id]; | ||
}; | ||
return runState[id]; | ||
}; | ||
return _util.allValues((_Object$keys2 = Object.keys(toRun)).reduce.apply(_Object$keys2, _util.collect(toRun, _run))); | ||
}.call(this, params); | ||
return _util.allValues((_Object$keys2 = Object.keys(toRun)).reduce.apply(_Object$keys2, _util.collect(toRun, _run))); | ||
return _types.PromiseType(ret); | ||
} | ||
@@ -141,2 +143,3 @@ | ||
// } | ||
// } | ||
/*, MinimizedCache*/ |
@@ -11,4 +11,9 @@ 'use strict'; | ||
var PromiseType = _tcomb2['default'].irreducible('Promise', function (v) { | ||
return v instanceof Promise; | ||
}); | ||
exports.PromiseType = PromiseType; | ||
// unique string id for the query | ||
var QueryId = _tcomb2['default'].Str; | ||
var QueryId = _tcomb2['default'].String; | ||
@@ -21,7 +26,7 @@ var Dependency = _tcomb2['default'].struct({ | ||
// (this should minimize size of dep. results): | ||
map: _tcomb2['default'].Func, | ||
map: _tcomb2['default'].Function, | ||
// TODO(gio): unused. use Query.cacheParams instead | ||
// override cache params from this dep | ||
// cacheParams: t.maybe(t.list(t.Str)), | ||
// cacheParams: t.maybe(t.list(t.String)), | ||
@@ -33,6 +38,6 @@ // run dependent query (this query) once for | ||
// defaults to an array, same size as input array | ||
multi: _tcomb2['default'].maybe(_tcomb2['default'].union([_tcomb2['default'].Bool, _tcomb2['default'].Func])) | ||
multi: _tcomb2['default'].maybe(_tcomb2['default'].union([_tcomb2['default'].Boolean, _tcomb2['default'].Function])) | ||
}, 'Dependency'); | ||
var Dependencies = _tcomb2['default'].maybe(_tcomb2['default'].subtype(_tcomb2['default'].dict(QueryId, Dependency), | ||
var Dependencies = _tcomb2['default'].maybe(_tcomb2['default'].refinement(_tcomb2['default'].dict(QueryId, Dependency), | ||
// TODO(gio): looks like a dumb/arbitrary limitation? | ||
@@ -61,5 +66,5 @@ // only a single `multi` dependency is allowed | ||
var TcombType = _tcomb2['default'].subtype(_tcomb2['default'].Any, _tcomb.isType, 'TcombType'); | ||
var TcombType = _tcomb2['default'].irreducible('TcombType', _tcomb.isType); | ||
var CacheParams = _tcomb2['default'].dict(_tcomb2['default'].Str, TcombType, 'CacheParams'); | ||
var CacheParams = _tcomb2['default'].dict(_tcomb2['default'].String, TcombType, 'CacheParams'); | ||
@@ -82,4 +87,4 @@ var Query = _tcomb2['default'].struct({ | ||
// state: t.Obj -> depFetchParams: t.Obj -> Promise[t.Obj] | ||
fetch: _tcomb2['default'].Func | ||
// state: t.Object -> depFetchParams: t.Object -> Promise[t.Object] | ||
fetch: _tcomb2['default'].Function | ||
}, 'Query'); | ||
@@ -99,7 +104,7 @@ | ||
// actual command | ||
run: _tcomb2['default'].Func // state: t.Obj -> Promise[Any] | ||
run: _tcomb2['default'].Function // state: t.Object -> Promise[t.Any] | ||
}, 'Command'); | ||
exports.Command = Command; | ||
var QueryNodeEdges = _tcomb2['default'].dict(_tcomb2['default'].Str, _tcomb2['default'].Any, 'QueryNodeEdges'); // circular, fixed below | ||
var QueryNodeEdges = _tcomb2['default'].dict(_tcomb2['default'].String, _tcomb2['default'].Any, 'QueryNodeEdges'); // circular, fixed below | ||
@@ -119,17 +124,21 @@ // a single DAG node | ||
exports.QueryNodes = QueryNodes; | ||
var StateKey = _tcomb2['default'].subtype(_tcomb2['default'].Any, function (v) { | ||
return _tcomb2['default'].Str.is(v) || _tcomb2['default'].Num.is(v) || _tcomb2['default'].Bool.is(v) || _tcomb2['default'].Dat.is(v); | ||
}, 'StateKey'); | ||
var StateKey = _tcomb2['default'].irreducible('StateKey', function (v) { | ||
return _tcomb2['default'].String.is(v) || _tcomb2['default'].Number.is(v) || _tcomb2['default'].Boolean.is(v) || _tcomb2['default'].Date.is(v); | ||
}); | ||
exports.StateKey = StateKey; | ||
var State = _tcomb2['default'].dict(_tcomb2['default'].Str, StateKey, 'State'); | ||
var State = _tcomb2['default'].dict(_tcomb2['default'].String, StateKey, 'State'); | ||
exports.State = State; | ||
// cache internal state representation | ||
var CacheState = _tcomb2['default'].dict(_tcomb2['default'].String, _tcomb2['default'].dict(_tcomb2['default'].String, _tcomb2['default'].Any)); | ||
exports.CacheState = CacheState; | ||
var EmitMeta = _tcomb2['default'].struct({ | ||
id: QueryId, | ||
error: _tcomb2['default'].maybe(_tcomb2['default'].Bool), | ||
cache: _tcomb2['default'].maybe(_tcomb2['default'].Bool), | ||
loading: _tcomb2['default'].maybe(_tcomb2['default'].Bool), | ||
multi: _tcomb2['default'].maybe(_tcomb2['default'].Bool), | ||
multiIndex: _tcomb2['default'].maybe(_tcomb2['default'].Num), | ||
multiAll: _tcomb2['default'].maybe(_tcomb2['default'].Bool) | ||
error: _tcomb2['default'].maybe(_tcomb2['default'].Boolean), | ||
cache: _tcomb2['default'].maybe(_tcomb2['default'].Boolean), | ||
loading: _tcomb2['default'].maybe(_tcomb2['default'].Boolean), | ||
multi: _tcomb2['default'].maybe(_tcomb2['default'].Boolean), | ||
multiIndex: _tcomb2['default'].maybe(_tcomb2['default'].Number), | ||
multiAll: _tcomb2['default'].maybe(_tcomb2['default'].Boolean) | ||
}, 'EmitMeta'); | ||
@@ -140,6 +149,6 @@ | ||
// // dependant qId | ||
// t.Str, | ||
// t.String, | ||
// t.dict( | ||
// // dependency qId | ||
// t.Str, | ||
// t.String, | ||
// // mapped (minimized) value | ||
@@ -154,6 +163,6 @@ // t.Any | ||
// meta: t.struct({ | ||
// cached: t.Bool, | ||
// error: t.Bool, | ||
// loading: t.Bool | ||
// cached: t.Boolean, | ||
// error: t.Boolean, | ||
// loading: t.Boolean | ||
// }) | ||
// }, 'Value'); |
@@ -1,2 +0,2 @@ | ||
"use strict"; | ||
'use strict'; | ||
@@ -7,3 +7,6 @@ exports.__esModule = true; | ||
exports["default"] = upset; | ||
exports['default'] = upset; | ||
var _types = require('./types'); | ||
var _upset = function _upset(query) { | ||
@@ -20,7 +23,13 @@ var _extends2; | ||
function upset(input) { | ||
return Object.keys(input).reduce(function (up, qId) { | ||
return _extends({}, up, _upset(input[qId])); | ||
}, {}); | ||
input = _types.QueryNodes(input); | ||
var ret = function (input) { | ||
return Object.keys(input).reduce(function (up, qId) { | ||
return _extends({}, up, _upset(input[qId])); | ||
}, {}); | ||
}.call(this, input); | ||
return _types.QueryNodes(ret); | ||
} | ||
module.exports = exports["default"]; | ||
module.exports = exports['default']; |
@@ -9,2 +9,8 @@ 'use strict'; | ||
var _types = require('./types'); | ||
var _tcomb = require('tcomb'); | ||
var _tcomb2 = _interopRequireDefault(_tcomb); | ||
var _lodashArrayZipObject = require('lodash/array/zipObject'); | ||
@@ -14,14 +20,22 @@ | ||
var DictOfPromises = _tcomb2['default'].dict(_tcomb2['default'].String, _types.PromiseType, 'DictOfPromises'); | ||
var allValues = function allValues(prs) { | ||
var keys = Object.keys(prs); | ||
var promises = keys.map(function (k) { | ||
return prs[k]; | ||
}); | ||
return Promise.all(promises).then(function (values) { | ||
return _lodashArrayZipObject2['default'](keys, values); | ||
}, function (err) { | ||
throw err; | ||
})['catch'](function (err) { | ||
throw err; | ||
}); | ||
prs = DictOfPromises(prs); | ||
var ret = function (prs) { | ||
var keys = Object.keys(prs); | ||
var promises = keys.map(function (k) { | ||
return prs[k]; | ||
}); | ||
return Promise.all(promises).then(function (values) { | ||
return _lodashArrayZipObject2['default'](keys, values); | ||
}, function (err) { | ||
throw err; | ||
})['catch'](function (err) { | ||
throw err; | ||
}); | ||
}.call(this, prs); | ||
return _types.PromiseType(ret); | ||
}; | ||
@@ -34,2 +48,3 @@ | ||
} : arguments[1]; | ||
o = _tcomb2['default'].Object(o); | ||
return [function (ac, k) { | ||
@@ -44,3 +59,8 @@ var _extends2; | ||
var error = function error(emit, id, reject) { | ||
emit = _tcomb2['default'].Function(emit); | ||
id = _tcomb2['default'].String(id); | ||
reject = _tcomb2['default'].Function(reject); | ||
return function (err) { | ||
err = _tcomb2['default'].Any(err); | ||
reject(err); | ||
@@ -47,0 +67,0 @@ emit({ id: id, error: true }, err); |
{ | ||
"name": "avenger", | ||
"version": "0.1.4", | ||
"version": "0.1.5", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "mocha", | ||
"build": "rm -rf lib && mkdir lib && babel --loose --stage 0 --out-dir lib src", | ||
"build": "rm -rf lib && mkdir lib && babel --out-dir lib src", | ||
"lint": "eslint src test", | ||
@@ -30,2 +30,3 @@ "preversion": "npm run lint && npm run test", | ||
"babel-eslint": "^4.1.3", | ||
"babel-plugin-tcomb": "gcanti/babel-plugin-tcomb#e11396625e8d1e63d3cbfc21eaa46a388b93f47e", | ||
"better-assert": "^1.0.2", | ||
@@ -32,0 +33,0 @@ "eslint": "^1.6.0", |
import t from 'tcomb'; | ||
import EventEmitter3 from 'eventemitter3'; | ||
import { AvengerInput, Command, EmitMeta } from './types'; | ||
import { AvengerInput, State, CacheState, Command, EmitMeta, PromiseType } from './types'; | ||
import AvengerCache from './AvengerCache'; | ||
@@ -10,7 +10,3 @@ import build from './build'; | ||
export default class Avenger { | ||
constructor(allQueries, initialCacheState = {}) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
t.assert(AvengerInput.is(allQueries), `Invalid allQueries`); | ||
} | ||
constructor(allQueries: AvengerInput, initialCacheState: CacheState = {}) { | ||
this.allQueries = allQueries; | ||
@@ -24,2 +20,7 @@ this.currentInput = null; | ||
}; | ||
if (process.env.NODE_ENV === 'development') { | ||
if (typeof window !== 'undefined') { | ||
window.$av = this; | ||
} | ||
} | ||
} | ||
@@ -35,26 +36,14 @@ | ||
emit = (meta, value) => { | ||
if (process.env.NODE_ENV !== 'production') { | ||
EmitMeta(meta); | ||
} | ||
emit = (meta: EmitMeta, value: t.Any) => { | ||
const { | ||
id, | ||
loading = false, | ||
cache = false, | ||
error = false, | ||
multi = false, | ||
multiAll = false, | ||
loading = false | ||
multiAll = false | ||
} = meta; | ||
const now = new Date().getTime(); | ||
const { cache: currentCache } = this.result.__meta[id] || {}; | ||
if (error) { | ||
// TODO(gio): should also update __meta | ||
// and emit a `change` | ||
this.emitter.emit('error', value); | ||
return; | ||
} | ||
if (multi && !multiAll) { | ||
if (multi && !multiAll) { // swallow up! | ||
// not sure about this, | ||
@@ -66,5 +55,9 @@ // but seems easier to just emit once | ||
// TODO(gio): we should make sure not to | ||
// throw away valid refs here... | ||
if (value) { | ||
// TODO(gio): should value be the last valid value even if | ||
// last fetch caused an error? | ||
// error meta is anyway updated accordingly below | ||
if (!error) { | ||
// TODO(gio): we should make sure not to throw away | ||
// valid refs here... but as long as potentially reusable | ||
// values are from cache (memory), we should be safe | ||
this.result[id] = value; | ||
@@ -77,5 +70,9 @@ } | ||
loading, | ||
error: false | ||
error: !!error | ||
}; | ||
if (error) { | ||
this.emitter.emit('error', value); | ||
} | ||
this.emitter.emit('change', { | ||
@@ -86,5 +83,4 @@ ...this.result | ||
run(input, state) { | ||
run(input: AvengerInput, state: State): PromiseType { | ||
// TODO(gio): not handling remote version for now | ||
const built = build(input, this.allQueries); | ||
@@ -120,3 +116,3 @@ | ||
invalidate(state, invalidate) { | ||
invalidate(state: State, _inv: AvengerInput): PromiseType { | ||
// TODO(gio): not handling remote version for now | ||
@@ -127,3 +123,3 @@ | ||
return invalidateLocal({ | ||
invalidate, | ||
invalidate: _inv, | ||
input: this.currentInput, | ||
@@ -137,12 +133,8 @@ result, | ||
// there should also be a way to track subsequent invalidation | ||
// TODO(gio): there should also be a way to track subsequent invalidation | ||
// e.g. `runCommandAndThenWaitForSubsequentInvalidation` | ||
// or this could be built on top of emit if we add a `stable` event | ||
runCommand(state, command) { | ||
runCommand(state: State, command: Command): PromiseType { | ||
// TODO(gio): not handling remote version for now | ||
if (process.env.NODE_ENV !== 'production') { | ||
Command(command); | ||
} | ||
return command.run(state).then(res => { | ||
@@ -149,0 +141,0 @@ this.invalidate( |
@@ -7,10 +7,7 @@ // a cache implementation able to produce an ActualizedCache | ||
import t from 'tcomb'; | ||
import { State } from './types'; | ||
import { State, CacheState } from './types'; | ||
const log = debug('AvengerCache'); | ||
export function hashedParams(params) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
State(params); | ||
} | ||
export function hashedParams(params: State): t.Str { | ||
const keys = Object.keys(params); | ||
@@ -24,19 +21,11 @@ keys.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); | ||
constructor(initialState = {}) { | ||
constructor(initialState: CacheState = {}) { | ||
this.state = initialState; | ||
} | ||
toJSON() { | ||
toJSON(): CacheState { | ||
return this.state; | ||
} | ||
checkParams(params) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
t.assert(State.is(params), `Invalid params provided to cache: ${JSON.stringify(params)}`); | ||
} | ||
} | ||
has(id, params) { | ||
this.checkParams(params); | ||
has(id: t.String, params: State): t.Boolean { | ||
if (!this.state[id]) { | ||
@@ -49,5 +38,3 @@ return false; | ||
get(id, params) { | ||
this.checkParams(params); | ||
get(id: t.String, params: State): t.Any { | ||
if (!this.state[id]) { | ||
@@ -60,5 +47,3 @@ return null; | ||
set = (id, params) => value => { | ||
this.checkParams(params); | ||
set = (id: t.String, params: State) => (value: t.Any) => { | ||
const hp = hashedParams(params); | ||
@@ -75,5 +60,3 @@ log(`set ${id} ${hp} = %o`, params, value); | ||
invalidate = (id, params) => { | ||
this.checkParams(params); | ||
invalidate = (id: t.String, params: State) => { | ||
if (this.state[id]) { | ||
@@ -80,0 +63,0 @@ const hp = hashedParams(params); |
import t from 'tcomb'; | ||
import { AvengerInput } from './types'; | ||
import { AvengerInput, QueryNodes } from './types'; | ||
import upset from './upset'; | ||
@@ -8,9 +8,6 @@ import find from 'lodash/collection/find'; | ||
// (AvengerInput, AvengerInput) -> QueryNodes | ||
export default function build(input, all) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
t.assert(AvengerInput.is(input), `invalid input provided to build`); | ||
t.assert(AvengerInput.is(all), `invalid all provided to build`); | ||
} | ||
export default function build( | ||
input: AvengerInput, | ||
all: AvengerInput | ||
): QueryNodes { | ||
const _upset = upset(input); | ||
@@ -17,0 +14,0 @@ |
@@ -5,4 +5,8 @@ import union from 'lodash/array/union'; | ||
export default function createFetcher({ multiDep, ...args }) { | ||
function createFetcherInner({ id, fetch, cacheMode, cacheParams, depsParams, state, cache, emit, reject }) { | ||
export default function createFetcher({ | ||
multiDep, ...args | ||
}) { | ||
function createFetcherInner({ | ||
id, fetch, cacheMode, cacheParams, depsParams, state, cache, emit, reject | ||
}) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
@@ -46,3 +50,3 @@ // check for duplicate keys in state and depsParams | ||
const multiParams = args.depsParams[multiDep.key]; | ||
t.assert(t.Arr.is(multiParams), `Invalid (non-Array) result for dependency param ${multiDep.key} (among ${args.id} params)`); | ||
t.assert(t.Array.is(multiParams), `Invalid (non-Array) result for dependency param ${multiDep.key} (among ${args.id} params)`); | ||
@@ -49,0 +53,0 @@ const emit = index => (meta, value) => { |
@@ -1,2 +0,4 @@ | ||
export default function downset(nodes) { | ||
import { QueryNodes } from './types'; | ||
export default function downset(nodes: QueryNodes): QueryNodes { | ||
return Object.keys(nodes).reduce((down, qId) => ({ | ||
@@ -3,0 +5,0 @@ ...down, |
import t from 'tcomb'; | ||
import { AvengerInput, QueryNodes, State } from './types'; | ||
import { AvengerInput, QueryNodes, State, PromiseType } from './types'; | ||
import { runLocal } from './run'; | ||
@@ -10,12 +10,8 @@ import { collect } from './util'; | ||
state: State, | ||
result: t.Obj, | ||
result: t.Object, | ||
cache: t.Any, | ||
emit: t.Func | ||
emit: t.Function | ||
}, 'InvalidateLocalParams'); | ||
export function invalidateLocal(params) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
InvalidateLocalParams(params); | ||
} | ||
export function invalidateLocal(params: InvalidateLocalParams): PromiseType { | ||
const { | ||
@@ -22,0 +18,0 @@ // queries to be invalidated |
@@ -11,7 +11,5 @@ import t from 'tcomb'; | ||
export default function positiveDiff(params) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
PositiveDiffParams(params); | ||
} | ||
const PositiveDiffOutput = t.dict(t.String, t.Boolean, 'PositiveDiffOutput'); | ||
export default function positiveDiff(params: PositiveDiffParams): PositiveDiffOutput { | ||
const { | ||
@@ -18,0 +16,0 @@ a, b, aState, bState |
import t from 'tcomb'; | ||
import { QueryNodes, State/*, MinimizedCache*/ } from './types'; | ||
import { QueryNodes, State/*, MinimizedCache*/, PromiseType } from './types'; | ||
import { allValues, collect, error } from './util'; | ||
@@ -15,10 +15,6 @@ import positiveDiff from './positiveDiff'; | ||
cache: t.Any, | ||
emit: t.Func | ||
emit: t.Function | ||
}, 'RunLocalParams'); | ||
export function runLocal(params) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
RunLocalParams(params); | ||
} | ||
export function runLocal(params: RunLocalParams): PromiseType { | ||
const { | ||
@@ -73,3 +69,3 @@ input, oldInput, | ||
key: multiKey, | ||
map: t.Func.is(dependencies[multiKey]) ? dependencies[multiKey] : v => v | ||
map: t.Function.is(dependencies[multiKey]) ? dependencies[multiKey] : v => v | ||
}; | ||
@@ -76,0 +72,0 @@ }()) |
import t, { isType } from 'tcomb'; | ||
export const PromiseType = t.irreducible('Promise', v => v instanceof Promise); | ||
// unique string id for the query | ||
const QueryId = t.Str; | ||
const QueryId = t.String; | ||
@@ -12,7 +14,7 @@ const Dependency = t.struct({ | ||
// (this should minimize size of dep. results): | ||
map: t.Func, | ||
map: t.Function, | ||
// TODO(gio): unused. use Query.cacheParams instead | ||
// override cache params from this dep | ||
// cacheParams: t.maybe(t.list(t.Str)), | ||
// cacheParams: t.maybe(t.list(t.String)), | ||
@@ -24,6 +26,6 @@ // run dependent query (this query) once for | ||
// defaults to an array, same size as input array | ||
multi: t.maybe(t.union([t.Bool, t.Func])) | ||
multi: t.maybe(t.union([t.Boolean, t.Function])) | ||
}, 'Dependency'); | ||
const Dependencies = t.maybe(t.subtype( | ||
const Dependencies = t.maybe(t.refinement( | ||
t.dict(QueryId, Dependency), | ||
@@ -49,5 +51,5 @@ // TODO(gio): looks like a dumb/arbitrary limitation? | ||
const TcombType = t.subtype(t.Any, isType, 'TcombType'); | ||
const TcombType = t.irreducible('TcombType', isType); | ||
const CacheParams = t.dict(t.Str, TcombType, 'CacheParams'); | ||
const CacheParams = t.dict(t.String, TcombType, 'CacheParams'); | ||
@@ -70,4 +72,4 @@ export const Query = t.struct({ | ||
// state: t.Obj -> depFetchParams: t.Obj -> Promise[t.Obj] | ||
fetch: t.Func | ||
// state: t.Object -> depFetchParams: t.Object -> Promise[t.Object] | ||
fetch: t.Function | ||
}, 'Query'); | ||
@@ -85,6 +87,6 @@ | ||
// actual command | ||
run: t.Func // state: t.Obj -> Promise[Any] | ||
run: t.Function // state: t.Object -> Promise[t.Any] | ||
}, 'Command'); | ||
const QueryNodeEdges = t.dict(t.Str, t.Any, 'QueryNodeEdges'); // circular, fixed below | ||
const QueryNodeEdges = t.dict(t.String, t.Any, 'QueryNodeEdges'); // circular, fixed below | ||
@@ -102,17 +104,19 @@ // a single DAG node | ||
export const StateKey = t.subtype( | ||
t.Any, | ||
v => t.Str.is(v) || t.Num.is(v) || t.Bool.is(v) || t.Dat.is(v), | ||
'StateKey' | ||
export const StateKey = t.irreducible( | ||
'StateKey', | ||
v => t.String.is(v) || t.Number.is(v) || t.Boolean.is(v) || t.Date.is(v), | ||
); | ||
export const State = t.dict(t.Str, StateKey, 'State'); | ||
export const State = t.dict(t.String, StateKey, 'State'); | ||
// cache internal state representation | ||
export const CacheState = t.dict(t.String, t.dict(t.String, t.Any)); | ||
export const EmitMeta = t.struct({ | ||
id: QueryId, | ||
error: t.maybe(t.Bool), | ||
cache: t.maybe(t.Bool), | ||
loading: t.maybe(t.Bool), | ||
multi: t.maybe(t.Bool), | ||
multiIndex: t.maybe(t.Num), | ||
multiAll: t.maybe(t.Bool) | ||
error: t.maybe(t.Boolean), | ||
cache: t.maybe(t.Boolean), | ||
loading: t.maybe(t.Boolean), | ||
multi: t.maybe(t.Boolean), | ||
multiIndex: t.maybe(t.Number), | ||
multiAll: t.maybe(t.Boolean) | ||
}, 'EmitMeta'); | ||
@@ -122,6 +126,6 @@ | ||
// // dependant qId | ||
// t.Str, | ||
// t.String, | ||
// t.dict( | ||
// // dependency qId | ||
// t.Str, | ||
// t.String, | ||
// // mapped (minimized) value | ||
@@ -136,6 +140,6 @@ // t.Any | ||
// meta: t.struct({ | ||
// cached: t.Bool, | ||
// error: t.Bool, | ||
// loading: t.Bool | ||
// cached: t.Boolean, | ||
// error: t.Boolean, | ||
// loading: t.Boolean | ||
// }) | ||
// }, 'Value'); |
@@ -0,1 +1,3 @@ | ||
import { QueryNodes } from './types'; | ||
const _upset = query => { | ||
@@ -14,3 +16,3 @@ const deps = Object.keys(query.dependencies || {}) | ||
export default function upset(input) { | ||
export default function upset(input: QueryNodes): QueryNodes { | ||
return Object.keys(input).reduce((up, qId) => ({ | ||
@@ -17,0 +19,0 @@ ...up, |
@@ -0,4 +1,8 @@ | ||
import { PromiseType } from './types'; | ||
import t from 'tcomb'; | ||
import zipObject from 'lodash/array/zipObject'; | ||
export const allValues = prs => { | ||
const DictOfPromises = t.dict(t.String, PromiseType, 'DictOfPromises'); | ||
export const allValues = (prs: DictOfPromises): PromiseType => { | ||
const keys = Object.keys(prs); | ||
@@ -16,3 +20,3 @@ const promises = keys.map((k) => prs[k]); | ||
export const collect = (o, map = v => v) => [ | ||
export const collect = (o: t.Object, map = v => v) => [ | ||
(ac, k) => ({ | ||
@@ -25,5 +29,7 @@ ...(ac || {}), | ||
export const error = (emit, id, reject) => err => { | ||
export const error = ( | ||
emit: t.Function, id: t.String, reject: t.Function | ||
) => (err: t.Any) => { | ||
reject(err); | ||
emit({ id, error: true }, err); | ||
}; |
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
320251
1519
6
12