diff --git a/pwiki/store/base.js b/pwiki/store/base.js index b64a6b0..5270f26 100755 --- a/pwiki/store/base.js +++ b/pwiki/store/base.js @@ -13,6 +13,137 @@ var types = require('ig-types') var pwpath = require('../path') +//--------------------------------------------------------------------- +// +// - define (name, generate, merge) +// inline +// online +// - undefine (online) +// - enumerate/list +// - group operations: +// - update item +// - remove item +// - reset (cache) +// +// + + +// XXX need support for: +// 'update', , +// 'remove', +// +var makeIndexed = +function(name, generate, options={}){ + var cache = !!options.attr ? + name + : `__${name}_cache` + var merge = `__${name}_merge__` + var special = `__${name}__` + + // make local cache... + var _make = function(){ + return this[special] != null ? + this[special]() + : generate.call(this) } + // unwrap a promised value into cache... + var _await = function(obj, val){ + if(val instanceof Promise){ + val.then(function(value){ + obj[cache] = value }) } + return val } + + var meth + return (meth = Object.assign( + function(action='get', ...args){ + var that = this + // clear/reset... + if(action == 'clear' + || action == 'reset'){ + delete this[cache] } + // clear... + if(action == 'clear'){ + return } + // other actions... + if(action != 'get' + && action != 'reset'){ + var action_meth = `__${name}_${action}__` + // generate cache if not available... + var cur = cache in this ? + this[cache] + : meth.call(this, 'reset') + return _await(this, this[cache] = + (action in options + && typeof(options[action]) == 'function') ? + options[action].call(this, cur, ...args) + : action_meth in this ? + this[action_meth](cur, ...args) + : cur) } + // get... + return _await(this, + // NOTE: this is intentionally not cached... + action == 'local' ? + _make.call(this) + // get... + : (this[cache] = + // cached... + this[cache] != null ? + this[cache] + // generate + merge... + : this[merge] != null ? + this[merge](_make.call(this)) + // generate... + : _make.call(this)) ) }, + { + attr: name, + indexed: true, + options, + })) } + + +var indexTest = +module.indexTest = +{ + get indexi(){ + var that = this + return object.deepKeys(this) + .filter(function(key){ + var d = object.values(that, key, true).next().value.value + return typeof(d) == 'function' + && d.indexed }) }, + + index: async function(action='get', ...args){ + var that = this + return Object.fromEntries( + await Promise.all( + this.indexi + .map(async function(name){ + return [ + that[name].attr, + await that[name](action, ...args), + ] }))) }, + + // tests... + // + moo: makeIndexed('moo', () => 123), + + _foo_index: makeIndexed('foo', () => 123, { + attr: true, + add: function(cur, val){ + return cur + val }, + }), + + __boo_add__: function(cur, val){ + return cur + val }, + boo: makeIndexed('boo', () => 123), + + __amoo_add__: async function(cur, val){ + return await cur + val }, + amoo: makeIndexed('amoo', async () => 123), +} + + + + //--------------------------------------------------------------------- @@ -739,10 +870,12 @@ module.MetaStore = { // trim path... path.slice(path.indexOf(p)+p.length), ...[...arguments].slice(1)) + this.__cache_add(path) return this } // add local... return object.parentCall(MetaStore.update, this, ...arguments) }, // XXX Q: how do we delete a substore??? + // XXX need to call .__cache_remove(..) here if we did not super-call... delete: metaProxy('delete'), } diff --git a/pwiki2.js b/pwiki2.js index 8b20509..147c19c 100755 --- a/pwiki2.js +++ b/pwiki2.js @@ -17,6 +17,24 @@ * - CLI * * +* XXX INDEX / CACHE: +* - centralized +* - nestable +* - updates propagate down to substore +* - updates propagate up to root +* - extensible +* name, generate, get (extensible), update, delete +* - event-based??? +* - sync??? +* API???: +* // create +* .index(, {generate, update, ... }) +* delete .index. +* . - index data (prop) +* .____() - index getter +* .index.(..) - update +* .index.clear() +* .index.refresh() * XXX BUG: when editing the root page of a substore the page's .cache is * not reset for some reason... * ...the problem is in that .names() cache is not reset when a new