mirror of
				https://github.com/flynx/pWiki.git
				synced 2025-11-04 04:50:09 +00:00 
			
		
		
		
	added index cache dependencies + docs/notes...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									3e2be6b7e9
								
							
						
					
					
						commit
						2d0b965655
					
				@ -15,15 +15,14 @@ var pwpath = require('../path')
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
//---------------------------------------------------------------------
 | 
					//---------------------------------------------------------------------
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// - define (name, generate, merge)
 | 
					// - define (name, generate, merge) 	- DONE
 | 
				
			||||||
// 		inline
 | 
					// 		inline							- DONE
 | 
				
			||||||
// 		online
 | 
					// 		online							- DONE
 | 
				
			||||||
// - undefine (online)
 | 
					// - undefine (online)					- ???
 | 
				
			||||||
// - enumerate/list
 | 
					// - enumerate/list						- DONE
 | 
				
			||||||
// - group operations:
 | 
					// - group operations:
 | 
				
			||||||
// 		- update item
 | 
					// 		- reset (cache)					- DONE
 | 
				
			||||||
// 		- remove item
 | 
					// 		- custom						- DONE
 | 
				
			||||||
// 		- reset (cache)
 | 
					 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -77,20 +76,52 @@ var pwpath = require('../path')
 | 
				
			|||||||
// 	.__<name>_cache / .<name>
 | 
					// 	.__<name>_cache / .<name>
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					// Options format:
 | 
				
			||||||
 | 
					// 	{
 | 
				
			||||||
 | 
					// 		// XXX
 | 
				
			||||||
 | 
					// 		attr: false 
 | 
				
			||||||
 | 
					// 			| true 
 | 
				
			||||||
 | 
					// 			| <name>,
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 		// list of dependencies that when changed will trigger a cache 
 | 
				
			||||||
 | 
					// 		// drop on current index...
 | 
				
			||||||
 | 
					// 		// NOTE: dependency checking is done via .modified time, if value
 | 
				
			||||||
 | 
					// 		//		is changed manually and not via an action then the system
 | 
				
			||||||
 | 
					// 		//		will not catch the change.
 | 
				
			||||||
 | 
					// 		depends: [ 
 | 
				
			||||||
 | 
					// 			<index-name>, 
 | 
				
			||||||
 | 
					// 			... 
 | 
				
			||||||
 | 
					// 		],
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 		// custom action...
 | 
				
			||||||
 | 
					// 		// NOTE: this is the same as defining .__<name>_<action-name>__(..)
 | 
				
			||||||
 | 
					// 		//		method...
 | 
				
			||||||
 | 
					// 		<action-name>: <func>,
 | 
				
			||||||
 | 
					// 	}
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// XXX move this to a separate module (???)
 | 
				
			||||||
var makeIndexed = 
 | 
					var makeIndexed = 
 | 
				
			||||||
 | 
					module.makeIndexed =
 | 
				
			||||||
function(name, generate, options={}){
 | 
					function(name, generate, options={}){
 | 
				
			||||||
	// XXX revise default...
 | 
						// attr names...
 | 
				
			||||||
	var cache = !!options.attr ?
 | 
						var cache = 
 | 
				
			||||||
		name
 | 
							typeof(options.attr) == 'string' ?
 | 
				
			||||||
 | 
								options.attr
 | 
				
			||||||
 | 
							// XXX revise default...
 | 
				
			||||||
 | 
							: !!options.attr ?
 | 
				
			||||||
 | 
								name
 | 
				
			||||||
		: `__${name}_cache`
 | 
							: `__${name}_cache`
 | 
				
			||||||
	var merge = `__${name}_merge__`
 | 
						var merge = `__${name}_merge__`
 | 
				
			||||||
	var special = `__${name}__`
 | 
						var special = `__${name}__`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// make local cache...
 | 
						// make local cache...
 | 
				
			||||||
	var _make = function(){
 | 
						var _make = function(){
 | 
				
			||||||
		return this[special] != null ?
 | 
							var res = this[special] != null ?
 | 
				
			||||||
			this[special]()
 | 
								this[special]()
 | 
				
			||||||
			: generate.call(this) }
 | 
								: generate.call(this) 
 | 
				
			||||||
 | 
							meth.modified = Date.now()
 | 
				
			||||||
 | 
							return res }
 | 
				
			||||||
	// unwrap a promised value into cache...
 | 
						// unwrap a promised value into cache...
 | 
				
			||||||
	var _await = function(obj, val){
 | 
						var _await = function(obj, val){
 | 
				
			||||||
		if(val instanceof Promise){
 | 
							if(val instanceof Promise){
 | 
				
			||||||
@ -98,18 +129,27 @@ function(name, generate, options={}){
 | 
				
			|||||||
				obj[cache] = value }) }
 | 
									obj[cache] = value }) }
 | 
				
			||||||
		return val }
 | 
							return val }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// build the method...
 | 
				
			||||||
	var meth
 | 
						var meth
 | 
				
			||||||
	return (meth = Object.assign(
 | 
						return (meth = Object.assign(
 | 
				
			||||||
		function(action='get', ...args){
 | 
							function(action='get', ...args){
 | 
				
			||||||
			var that = this
 | 
								var that = this
 | 
				
			||||||
			// clear/reset...
 | 
								// action: clear/reset...
 | 
				
			||||||
			if(action == 'clear' 
 | 
								if(action == 'clear' 
 | 
				
			||||||
					|| action == 'reset'){
 | 
										|| action == 'reset'){
 | 
				
			||||||
				delete this[cache] }
 | 
									delete this[cache] }
 | 
				
			||||||
			// clear...
 | 
								// action: clear...
 | 
				
			||||||
			if(action == 'clear'){
 | 
								if(action == 'clear'){
 | 
				
			||||||
				return }
 | 
									return }
 | 
				
			||||||
			// other actions...
 | 
								// check dependencies (timestamps)...
 | 
				
			||||||
 | 
								if(cache in this 
 | 
				
			||||||
 | 
										&& meth.options.depends){
 | 
				
			||||||
 | 
									var cur = meth.modified
 | 
				
			||||||
 | 
									for(var dep of meth.options.depends){
 | 
				
			||||||
 | 
										if(this[dep].modified > cur){
 | 
				
			||||||
 | 
											delete this[cache]
 | 
				
			||||||
 | 
											break } } }
 | 
				
			||||||
 | 
								// action: other...
 | 
				
			||||||
			if(action != 'get' 
 | 
								if(action != 'get' 
 | 
				
			||||||
					&& action != 'reset'){
 | 
										&& action != 'reset'){
 | 
				
			||||||
				var action_meth = `__${name}_${action}__`
 | 
									var action_meth = `__${name}_${action}__`
 | 
				
			||||||
@ -117,15 +157,18 @@ function(name, generate, options={}){
 | 
				
			|||||||
				var cur = cache in this ?
 | 
									var cur = cache in this ?
 | 
				
			||||||
					this[cache]
 | 
										this[cache]
 | 
				
			||||||
					: meth.call(this, 'reset')
 | 
										: meth.call(this, 'reset')
 | 
				
			||||||
				return _await(this, this[cache] = 
 | 
									var res = _await(this, this[cache] = 
 | 
				
			||||||
					// NOTE: this[action_meth] will fully shadow options[action]...
 | 
										// NOTE: this[action_meth] will fully shadow options[action]...
 | 
				
			||||||
					action_meth in this ?
 | 
										action_meth in this ?
 | 
				
			||||||
						this[action_meth](cur, ...args)
 | 
											this[action_meth](cur, ...args)
 | 
				
			||||||
					: (action in options 
 | 
										: (action in options 
 | 
				
			||||||
							&& typeof(options[action]) == 'function') ?
 | 
												&& typeof(options[action]) == 'function') ?
 | 
				
			||||||
						options[action].call(this, cur, ...args)
 | 
											options[action].call(this, cur, ...args)
 | 
				
			||||||
					: cur) }
 | 
										: cur) 
 | 
				
			||||||
			// get...
 | 
									res !== cur
 | 
				
			||||||
 | 
										&& (meth.modified = Date.now())
 | 
				
			||||||
 | 
									return res }
 | 
				
			||||||
 | 
								// action: get/local...
 | 
				
			||||||
			return _await(this,
 | 
								return _await(this,
 | 
				
			||||||
				// NOTE: this is intentionally not cached...
 | 
									// NOTE: this is intentionally not cached...
 | 
				
			||||||
				action == 'local' ?
 | 
									action == 'local' ?
 | 
				
			||||||
@ -146,30 +189,64 @@ function(name, generate, options={}){
 | 
				
			|||||||
			options,
 | 
								options,
 | 
				
			||||||
		})) }
 | 
							})) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// XXX make this a mixin...
 | 
				
			||||||
var indexTest = 
 | 
					var IndexManagerMixin = 
 | 
				
			||||||
module.indexTest =
 | 
					module.IndexManagerMixin =
 | 
				
			||||||
{
 | 
					object.Mixin('IndexManagerMixin', {
 | 
				
			||||||
 | 
						// List of index handler attribute names...
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
	// XXX rename???
 | 
						// XXX rename???
 | 
				
			||||||
	get indexi(){
 | 
						get index_attrs(){
 | 
				
			||||||
		var that = this
 | 
							var that = this
 | 
				
			||||||
		return object.deepKeys(this)
 | 
							return object.deepKeys(this)
 | 
				
			||||||
			.filter(function(key){
 | 
								.filter(function(key){
 | 
				
			||||||
				var d = object.values(that, key, true).next().value.value
 | 
									var d = object.values(that, key, true).next().value.value
 | 
				
			||||||
				return typeof(d) == 'function' 
 | 
									return typeof(d) == 'function' 
 | 
				
			||||||
						&& d.indexed }) },
 | 
											&& d.indexed }) },
 | 
				
			||||||
	
 | 
						//
 | 
				
			||||||
 | 
						// 	.index()
 | 
				
			||||||
 | 
						// 	.index('get')
 | 
				
			||||||
 | 
						// 		-> <indexi>
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						// 	.index('clear')
 | 
				
			||||||
 | 
						// 		-> <indexi>
 | 
				
			||||||
 | 
						// 	.index('reset')
 | 
				
			||||||
 | 
						// 		-> <indexi>
 | 
				
			||||||
 | 
						// 	.index('local')
 | 
				
			||||||
 | 
						// 		-> <indexi>
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						// 	.index(<action>, ...)
 | 
				
			||||||
 | 
						// 		-> <indexi>
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
	index: async function(action='get', ...args){
 | 
						index: async function(action='get', ...args){
 | 
				
			||||||
 | 
							// create a new index...
 | 
				
			||||||
 | 
							if(action == 'new'){
 | 
				
			||||||
 | 
								var res = makeIndexed(...args)
 | 
				
			||||||
 | 
								var [name, _, options={}] = args
 | 
				
			||||||
 | 
								var attr = name
 | 
				
			||||||
 | 
								if(options.attr){
 | 
				
			||||||
 | 
									var attr = `__${name}`
 | 
				
			||||||
 | 
									Object.defineProperty(this, name, {
 | 
				
			||||||
 | 
										get: function(){ 
 | 
				
			||||||
 | 
											return this[attr] }, }) }
 | 
				
			||||||
 | 
								return (this[attr] = res) }
 | 
				
			||||||
 | 
							// propagate action...
 | 
				
			||||||
		var that = this
 | 
							var that = this
 | 
				
			||||||
		return Object.fromEntries(
 | 
							return Object.fromEntries(
 | 
				
			||||||
			await Promise.all(
 | 
								await Promise.all(
 | 
				
			||||||
				this.indexi
 | 
									this.index_attrs
 | 
				
			||||||
					.map(async function(name){
 | 
										.map(async function(name){
 | 
				
			||||||
						return [
 | 
											return [
 | 
				
			||||||
							that[name].attr, 
 | 
												that[name].attr, 
 | 
				
			||||||
							await that[name](action, ...args),
 | 
												await that[name](action, ...args),
 | 
				
			||||||
						] }))) },
 | 
											] }))) },
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var indexTest = 
 | 
				
			||||||
 | 
					module.indexTest =
 | 
				
			||||||
 | 
					IndexManagerMixin({
 | 
				
			||||||
	// tests...
 | 
						// tests...
 | 
				
			||||||
	//
 | 
						//
 | 
				
			||||||
	moo: makeIndexed('moo', () => 123),
 | 
						moo: makeIndexed('moo', () => 123),
 | 
				
			||||||
@ -188,13 +265,23 @@ module.indexTest =
 | 
				
			|||||||
		return await cur + val },
 | 
							return await cur + val },
 | 
				
			||||||
	__soo: makeIndexed('soo', async () => 123),
 | 
						__soo: makeIndexed('soo', async () => 123),
 | 
				
			||||||
	get soo(){
 | 
						get soo(){
 | 
				
			||||||
		return this.__soo() }
 | 
							return this.__soo() },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// XXX need a way to link indexes...
 | 
						__sum: makeIndexed('sum', 
 | 
				
			||||||
	// 		Ex:
 | 
							async function(){
 | 
				
			||||||
	// 			sum -> soo + boo + foo + moo
 | 
								return await this.moo() 
 | 
				
			||||||
	// 			...changing any of the summed values should drop cache of sum
 | 
									+ await this.foo_index()
 | 
				
			||||||
}
 | 
									+ await this.boo() 
 | 
				
			||||||
 | 
									+ await this.soo },
 | 
				
			||||||
 | 
							{ depends: [
 | 
				
			||||||
 | 
								'moo', 
 | 
				
			||||||
 | 
								'foo_index', 
 | 
				
			||||||
 | 
								'boo', 
 | 
				
			||||||
 | 
								'__soo',
 | 
				
			||||||
 | 
							], }),
 | 
				
			||||||
 | 
						get sum(){
 | 
				
			||||||
 | 
							return this.__sum() },
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user