| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | /********************************************************************** | 
					
						
							|  |  |  | *  | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | **********************************************************************/ | 
					
						
							|  |  |  | ((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define) | 
					
						
							|  |  |  | (function(require){ var module={} // make module AMD/node compatible...
 | 
					
						
							|  |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var actions = require('lib/actions') | 
					
						
							|  |  |  | var features = require('lib/features') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var core = require('features/core') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*********************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-02-15 06:41:54 +03:00
										 |  |  | // XXX TODO:
 | 
					
						
							| 
									
										
										
										
											2018-03-15 10:26:35 +03:00
										 |  |  | // 		- path variables syntax
 | 
					
						
							| 
									
										
										
										
											2018-02-15 06:41:54 +03:00
										 |  |  | // 			$VAR or ${VAR}
 | 
					
						
							| 
									
										
										
										
											2018-03-15 10:26:35 +03:00
										 |  |  | // 		- general path variables:
 | 
					
						
							|  |  |  | // 			${INSTANCE}		(DONE)
 | 
					
						
							|  |  |  | // 			...
 | 
					
						
							|  |  |  | // 		- specific path variables
 | 
					
						
							| 
									
										
										
										
											2018-03-17 03:40:44 +03:00
										 |  |  | // 			fs -> system env variables
 | 
					
						
							| 
									
										
										
										
											2018-03-15 10:26:35 +03:00
										 |  |  | // 			... 
 | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | // XXX should we unify this with the save/load API
 | 
					
						
							|  |  |  | var StoreActions = actions.Actions({ | 
					
						
							|  |  |  | 	config: { | 
					
						
							|  |  |  | 		// Storage mode...
 | 
					
						
							|  |  |  | 		//
 | 
					
						
							|  |  |  | 		// This can be:
 | 
					
						
							|  |  |  | 		// 	'read-only'
 | 
					
						
							|  |  |  | 		// 	'read-write'
 | 
					
						
							|  |  |  | 		// 	null			- ignore store
 | 
					
						
							|  |  |  | 		//
 | 
					
						
							|  |  |  | 		// NOTE: this only affects start/stop/timer event handling, manual
 | 
					
						
							|  |  |  | 		// 		call to .loadData(..) / .saveData(..) are not affected...
 | 
					
						
							|  |  |  | 		'store-mode': 'read-write', | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Store handler dict...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// Format:
 | 
					
						
							|  |  |  | 	// 	{
 | 
					
						
							|  |  |  | 	// 		<store-tag>: <handler-action>,
 | 
					
						
							|  |  |  | 	// 		...
 | 
					
						
							|  |  |  | 	// 	}
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// XXX this is almost the same as .collection_handlers...
 | 
					
						
							| 
									
										
										
										
											2018-02-25 03:28:42 +03:00
										 |  |  | 	// XXX might be a good idea to shift this from meaning "store handlers" 
 | 
					
						
							|  |  |  | 	// 		to "store APIs", i.e. mark all specific store actions with 
 | 
					
						
							|  |  |  | 	// 		store tag and collect/group them for reference...
 | 
					
						
							|  |  |  | 	// 			new format:
 | 
					
						
							|  |  |  | 	// 				{
 | 
					
						
							|  |  |  | 	// 					<store-tag>: [
 | 
					
						
							|  |  |  | 	// 						<action-name>,
 | 
					
						
							|  |  |  | 	// 						...
 | 
					
						
							|  |  |  | 	// 					],
 | 
					
						
							|  |  |  | 	// 					...
 | 
					
						
							|  |  |  | 	// 				}
 | 
					
						
							| 
									
										
										
										
											2018-02-26 04:24:37 +03:00
										 |  |  | 	// 		...might also be a good idea to split this to:
 | 
					
						
							|  |  |  | 	// 			.stores				- list of store tags (i.e. Object.keys(this.stores_actions))
 | 
					
						
							|  |  |  | 	// 			.stores_actions		- dict of store-specific actions
 | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 	get stores(){ | 
					
						
							|  |  |  | 		return this.cache('stores', function(d){ | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 			var res = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			this.actions.forEach(function(action){  | 
					
						
							|  |  |  | 				var store = this.getActionAttr(action, 'handle_data_store') | 
					
						
							|  |  |  | 				res[store] | 
					
						
							|  |  |  | 					&& console.warn('Multiple handlers for store:', store) | 
					
						
							|  |  |  | 				if(store){ | 
					
						
							|  |  |  | 					res[store] = action | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			}.bind(this)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return res | 
					
						
							|  |  |  | 		}) }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// events...
 | 
					
						
							| 
									
										
										
										
											2018-02-21 06:54:11 +03:00
										 |  |  | 	// XXX update signature -- see doc for: .loadStore(..)
 | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 	storeDataLoaded: ['- Store/', | 
					
						
							|  |  |  | 		core.doc`Store data loaded event...
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		This is tirggered as soon per store as soon as data is loaded,  | 
					
						
							|  |  |  | 		this is sync for sync stores. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		NOTE: only one store data set is included per call.`,
 | 
					
						
							| 
									
										
										
										
											2018-02-21 06:54:11 +03:00
										 |  |  | 		core.Event(function(store, data){ | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 			// Store data loaded event...
 | 
					
						
							|  |  |  | 			//
 | 
					
						
							|  |  |  | 			// Not intended for direct use, use .declareReady() to initiate.
 | 
					
						
							|  |  |  | 			return data | 
					
						
							|  |  |  | 		})], | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-18 15:02:45 +03:00
										 |  |  | 	// base API...
 | 
					
						
							| 
									
										
										
										
											2018-02-25 03:28:42 +03:00
										 |  |  | 	// XXX .stores: see .stores notes above for new semantics...
 | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 	parseStoreQuery: ['- Store/', | 
					
						
							|  |  |  | 		core.doc`
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 06:54:11 +03:00
										 |  |  | 			Get default query... | 
					
						
							|  |  |  | 			.parseStoreQuery() | 
					
						
							|  |  |  | 				-> defaults | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Get unexpanded default query... | 
					
						
							|  |  |  | 			.parseStoreQuery(true) | 
					
						
							|  |  |  | 				-> defaults | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Parse query... | 
					
						
							|  |  |  | 			.parseStoreQuery(query) | 
					
						
							|  |  |  | 				-> query | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Parse query without expanding... | 
					
						
							|  |  |  | 			.parseStoreQuery(query, true) | 
					
						
							|  |  |  | 				-> query | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 		Query syntax: | 
					
						
							|  |  |  | 			<event>:<store>:<key> | 
					
						
							|  |  |  | 			<store>:<key> | 
					
						
							|  |  |  | 			<store> | 
					
						
							|  |  |  | 			<key> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Format: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				query: <input-query>, | 
					
						
							|  |  |  | 				date: <timestamp>, | 
					
						
							|  |  |  | 				event: 'manual' | <event>, | 
					
						
							|  |  |  | 				store: '*' | <store> | [<store>, ...] | 
					
						
							|  |  |  | 				key: '*' | <key> | [<key>, ...] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		`,
 | 
					
						
							| 
									
										
										
										
											2018-02-21 06:54:11 +03:00
										 |  |  | 		function(query, no_expand){ | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 			var defaults = { | 
					
						
							| 
									
										
										
										
											2018-02-21 06:54:11 +03:00
										 |  |  | 				date: Date.timeStamp(), | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 				event: 'manual', | 
					
						
							|  |  |  | 				store: '*', | 
					
						
							|  |  |  | 				key: '*', | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-02-21 06:54:11 +03:00
										 |  |  | 			if(query === true || query === false){ | 
					
						
							|  |  |  | 				no_expand = query | 
					
						
							|  |  |  | 				query = null | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// parse string...
 | 
					
						
							|  |  |  | 			if(typeof(query) == typeof('str')){ | 
					
						
							|  |  |  | 				var res = {} | 
					
						
							|  |  |  | 				res.query = query | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				query = query.split(/:/g) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				res.event = query.length > 2 ?  | 
					
						
							|  |  |  | 					query.shift() | 
					
						
							|  |  |  | 					: defaults.event | 
					
						
							|  |  |  | 				res.store = (this.stores[query[0]] || query.length > 1) ?  | 
					
						
							|  |  |  | 					query.shift().split(/\|/g)  | 
					
						
							|  |  |  | 					: defaults.store | 
					
						
							| 
									
										
										
										
											2018-02-19 00:08:31 +03:00
										 |  |  | 					//: Object.keys(this.stores)
 | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 				res.key = query.length > 0 ?  | 
					
						
							|  |  |  | 					query.pop().split(/\|/g) | 
					
						
							|  |  |  | 					: defaults.key | 
					
						
							| 
									
										
										
										
											2018-02-21 06:54:11 +03:00
										 |  |  | 				res.date = defaults.date | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 06:54:11 +03:00
										 |  |  | 				query = res | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// get the defaults...
 | 
					
						
							|  |  |  | 			} else if(query == null){ | 
					
						
							| 
									
										
										
										
											2018-02-21 06:54:11 +03:00
										 |  |  | 				query = defaults | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// pass on the input...
 | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-02-20 01:00:41 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 06:54:11 +03:00
										 |  |  | 			if(!no_expand){ | 
					
						
							|  |  |  | 				// XXX 
 | 
					
						
							|  |  |  | 				var handlers = this.stores | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 06:54:11 +03:00
										 |  |  | 				// expand store '*'...
 | 
					
						
							|  |  |  | 				query.store = (query.store.length == 1 && query.store[0] == '*') ?  | 
					
						
							|  |  |  | 					Object.keys(handlers)  | 
					
						
							|  |  |  | 					: query.store | 
					
						
							|  |  |  | 				// expand key '*'...
 | 
					
						
							|  |  |  | 				query.key = query.key.length == 1 && query.key[0] == '*' ?  | 
					
						
							|  |  |  | 					'*'  | 
					
						
							|  |  |  | 					: query.key | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 06:54:11 +03:00
										 |  |  | 			return query | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 		}], | 
					
						
							| 
									
										
										
										
											2018-02-20 01:00:41 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-02 04:03:43 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// HL API...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2018-02-23 04:47:38 +03:00
										 |  |  | 	// XXX sync or async or both???
 | 
					
						
							| 
									
										
										
										
											2018-03-01 03:17:48 +03:00
										 |  |  | 	// 		...should we add an .onStore(query, handler) event/promise???
 | 
					
						
							| 
									
										
										
										
											2018-03-02 04:03:43 +03:00
										 |  |  | 	// 		one way to do this is to place promises into res where async...
 | 
					
						
							| 
									
										
										
										
											2018-02-19 00:08:31 +03:00
										 |  |  | 	store: ['- Store/', | 
					
						
							|  |  |  | 		core.doc`
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Get stored key(s)... | 
					
						
							|  |  |  | 			.store(query) | 
					
						
							|  |  |  | 				-> value{s} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Write value to key(s)... | 
					
						
							|  |  |  | 			.store(query, value) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Remove key(s)... | 
					
						
							|  |  |  | 			.store(query, null) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-02 04:03:43 +03:00
										 |  |  | 		Returns: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				<store>: { | 
					
						
							|  |  |  | 					<key>: <value>, | 
					
						
							|  |  |  | 					... | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				... | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-19 00:08:31 +03:00
										 |  |  | 		NOTE: for query syntax see .parseStoreQuery(..) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-02 00:35:36 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		Store API: | 
					
						
							|  |  |  | 			- High-level API... | 
					
						
							|  |  |  | 				.store(..) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			- Application-level API... | 
					
						
							|  |  |  | 				.prepareStoreToLoad(..) | 
					
						
							|  |  |  | 				.prepareStoreToSave(..) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			- Storage-level general API... | 
					
						
							|  |  |  | 				.loadStore(..) | 
					
						
							|  |  |  | 				.saveStore(..) | 
					
						
							|  |  |  | 				.clearStore(..) | 
					
						
							| 
									
										
										
										
											2018-03-02 04:03:43 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			NOTE: .prepareStoreToSave(..) is triggered only when no data | 
					
						
							|  |  |  | 				is passed to .saveStore(..)... | 
					
						
							|  |  |  | 			NOTE: .prepareStoreToLoad(..) is called every time .loadStore(..) | 
					
						
							|  |  |  | 				is called... | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-19 00:08:31 +03:00
										 |  |  | 		`,
 | 
					
						
							|  |  |  | 		function(query, value){ | 
					
						
							|  |  |  | 			query = this.parseStoreQuery(query) | 
					
						
							| 
									
										
										
										
											2018-03-02 00:35:36 +03:00
										 |  |  | 			return ( | 
					
						
							|  |  |  | 				// get...
 | 
					
						
							|  |  |  | 				arguments.length == 1 ? | 
					
						
							| 
									
										
										
										
											2018-03-02 04:03:43 +03:00
										 |  |  | 					this.loadStore(query) | 
					
						
							| 
									
										
										
										
											2018-03-02 00:35:36 +03:00
										 |  |  | 				// delete...
 | 
					
						
							|  |  |  | 				: (value === undefined && arguments.length == 2) ? | 
					
						
							|  |  |  | 					this.clearStore(query) | 
					
						
							|  |  |  | 				// set...
 | 
					
						
							| 
									
										
										
										
											2018-03-02 04:03:43 +03:00
										 |  |  | 				: (this.saveStore(query, value) && undefined) ) }], | 
					
						
							| 
									
										
										
										
											2018-02-21 06:54:11 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-02 04:03:43 +03:00
										 |  |  | 	// Application API...
 | 
					
						
							| 
									
										
										
										
											2018-02-21 06:54:11 +03:00
										 |  |  | 	prepareStoreToSave: ['- Store/', | 
					
						
							|  |  |  | 		core.doc`
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Format: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				// metadata...
 | 
					
						
							|  |  |  | 				mode: <mode>, | 
					
						
							|  |  |  | 				data: <timestamp>, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// the actual data...
 | 
					
						
							|  |  |  | 				data: { | 
					
						
							|  |  |  | 					<data-type>: { | 
					
						
							|  |  |  | 						<data-key>: <data>, | 
					
						
							|  |  |  | 						... | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 					... | 
					
						
							|  |  |  | 				}, | 
					
						
							| 
									
										
										
										
											2018-02-19 00:08:31 +03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-02-21 06:54:11 +03:00
										 |  |  | 		`,
 | 
					
						
							|  |  |  | 		function(query, data){  | 
					
						
							|  |  |  | 			var defaults = this.parseStoreQuery() | 
					
						
							|  |  |  | 			query = this.parseStoreQuery(query) | 
					
						
							|  |  |  | 			var stores = query.store || defaults.store | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			data = data || {} | 
					
						
							|  |  |  | 			query.store.forEach(function(s){ data[s] = {} }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return { | 
					
						
							|  |  |  | 				date: query.date || Date.timeStamp(), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				event: query.event || defaults.event, | 
					
						
							|  |  |  | 				key: query.key || defaults.key, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				data: data || {}, | 
					
						
							|  |  |  | 			}  | 
					
						
							| 
									
										
										
										
											2018-02-19 00:08:31 +03:00
										 |  |  | 		}], | 
					
						
							| 
									
										
										
										
											2018-02-21 06:54:11 +03:00
										 |  |  | 	prepareStoreToLoad: ['- Store/', | 
					
						
							|  |  |  | 		core.doc`
 | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		NOTE: this can be called multiple times, once per each store. | 
					
						
							|  |  |  | 		NOTE: only one store data set is included per call.`,
 | 
					
						
							|  |  |  | 		function(query, data){  | 
					
						
							|  |  |  | 			return data || {} }], | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-02 04:03:43 +03:00
										 |  |  | 	// Store API...
 | 
					
						
							|  |  |  | 	saveStore: ['- Store/', | 
					
						
							|  |  |  | 		core.doc`
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Build and store all/query data... | 
					
						
							|  |  |  | 			.saveStore() | 
					
						
							|  |  |  | 			.saveStore(query) | 
					
						
							|  |  |  | 				-> data | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Store query data... | 
					
						
							|  |  |  | 			.saveStore(query, data) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		NOTE: this only calls .prepareStoreToSave(..) if no data is given... | 
					
						
							|  |  |  | 		NOTE: the returned data is the same format as returned by .store(..) | 
					
						
							|  |  |  | 		`,
 | 
					
						
							|  |  |  | 		core.notUserCallable(function(query, data){ | 
					
						
							|  |  |  | 			// Extending action must:
 | 
					
						
							|  |  |  | 			// 	- save query/data to it's store...
 | 
					
						
							|  |  |  | 			return data == null ?  | 
					
						
							|  |  |  | 				this.prepareStoreToSave(this.parseStoreQuery(query), {}).data | 
					
						
							|  |  |  | 				: undefined | 
					
						
							|  |  |  | 		})], | 
					
						
							|  |  |  | 	loadStore: ['- Store/', | 
					
						
							|  |  |  | 		core.doc`
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			.loadStore(query) | 
					
						
							|  |  |  | 				-> data | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		NOTE: async stores will write promises to .data | 
					
						
							|  |  |  | 		`,
 | 
					
						
							|  |  |  | 		core.notUserCallable(function(query){ | 
					
						
							|  |  |  | 			// Extending action must:
 | 
					
						
							|  |  |  | 			// 	- populate query from it's store...
 | 
					
						
							|  |  |  | 			// 	- trigger .storeDataLoaded(store) event when done...
 | 
					
						
							|  |  |  | 			//
 | 
					
						
							|  |  |  | 			// NOTE: if query.store is a single value then the root object
 | 
					
						
							|  |  |  | 			// 		must be populated, otherwise the appropriate section 
 | 
					
						
							|  |  |  | 			// 		should be used...
 | 
					
						
							|  |  |  | 			// 		e.g.
 | 
					
						
							|  |  |  | 			// 			if(query.store.length == 1){
 | 
					
						
							|  |  |  | 			//				res = data
 | 
					
						
							|  |  |  | 			// 			} else {
 | 
					
						
							|  |  |  | 			// 				res['store-key'] = data
 | 
					
						
							|  |  |  | 			// 			}
 | 
					
						
							|  |  |  | 			var res = {} | 
					
						
							|  |  |  | 			var q = this.parseStoreQuery(query) | 
					
						
							|  |  |  | 			query | 
					
						
							|  |  |  | 				&& q.store.length >= 1 | 
					
						
							|  |  |  | 				&& q.store.forEach(function(s){ res[s] = {} }) | 
					
						
							|  |  |  | 			return this.prepareStoreToLoad(q, res) | 
					
						
							|  |  |  | 		})], | 
					
						
							|  |  |  | 	clearStore: ['- Store/', | 
					
						
							|  |  |  | 		core.doc`
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			.clearStore(query) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		`,
 | 
					
						
							|  |  |  | 		core.notUserCallable(function(query){ | 
					
						
							|  |  |  | 			// Extending action:
 | 
					
						
							|  |  |  | 			// 	- must clear query from it's store...
 | 
					
						
							|  |  |  | 		})], | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 06:54:11 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-02 04:03:43 +03:00
										 |  |  | 	// XXX LEGACY STUFF... (???)
 | 
					
						
							| 
									
										
										
										
											2018-03-11 00:37:17 +03:00
										 |  |  | 	// 		...this is currently used to store config -- migrate to new API...
 | 
					
						
							| 
									
										
										
										
											2018-02-21 06:54:11 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-19 00:08:31 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 	// XXX this is different from .prepareIndexForWrite(..) in that there
 | 
					
						
							|  |  |  | 	// 		is no default data set...
 | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 	// XXX async???
 | 
					
						
							|  |  |  | 	saveData: ['- Store/', | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 		// XXX signature not final...
 | 
					
						
							|  |  |  | 		function(query, data){ | 
					
						
							| 
									
										
										
										
											2018-02-21 06:54:11 +03:00
										 |  |  | 			var defaults = this.parseStoreQuery() | 
					
						
							|  |  |  | 			query = this.parseStoreQuery(query) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 			var handlers = this.stores | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// save the given data...
 | 
					
						
							|  |  |  | 			// NOTE: we are not calling .prepareStoreToSave(..) here, thus
 | 
					
						
							|  |  |  | 			// 		we need not care about .key, .date, and other stuff...
 | 
					
						
							|  |  |  | 			if(data){ | 
					
						
							|  |  |  | 				if(query.store == defaults.store || query.key == defaults.key){ | 
					
						
							|  |  |  | 					console.error('saveData: at least "store" and "key" ' | 
					
						
							|  |  |  | 						+'must be explicitly set in query...') | 
					
						
							|  |  |  | 					return | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				var d = { | 
					
						
							|  |  |  | 					data: {} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				var stores = query.store == '*' ? handlers : query.store | 
					
						
							|  |  |  | 				stores = stores instanceof Array ? stores : [stores] | 
					
						
							|  |  |  | 				stores.forEach(function(s){  | 
					
						
							|  |  |  | 					d.data[s] = { | 
					
						
							|  |  |  | 						[query.key]: data, | 
					
						
							|  |  |  | 					} }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				data = d | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// build the data...
 | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				data = this.prepareStoreToSave(query) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// iterate and handle stores...
 | 
					
						
							|  |  |  | 			Object.keys(data.data).forEach(function(store){ | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 				var handler = handlers[store] | 
					
						
							|  |  |  | 				handler  | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 					&& this[handler].call(this, data.data[store]) | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 			}.bind(this)) | 
					
						
							|  |  |  | 		}], | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 	// XXX add query support... (???)
 | 
					
						
							|  |  |  | 	// 		...we can't support keys other than '*' until we register 
 | 
					
						
							|  |  |  | 	// 		store keys...
 | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 	loadData: ['- Store/', | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 		function(query){ | 
					
						
							|  |  |  | 			var handlers = this.stores | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var defaults = this.parseStoreQuery() | 
					
						
							|  |  |  | 			query = this.parseStoreQuery(query) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// XXX need to filter loading by query.key...
 | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 			var data = {} | 
					
						
							|  |  |  | 			return Promise | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 				.all(query.store | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 					.map(function(s){ | 
					
						
							|  |  |  | 						var res = this[handlers[s]]() | 
					
						
							|  |  |  | 						return res instanceof Promise ? | 
					
						
							|  |  |  | 							// async store...
 | 
					
						
							|  |  |  | 							res.then(function(d){ d  | 
					
						
							|  |  |  | 								&& (data[s] = d) | 
					
						
							| 
									
										
										
										
											2018-02-21 06:54:11 +03:00
										 |  |  | 								&& this.storeDataLoaded(s, | 
					
						
							|  |  |  | 									this.prepareStoreToLoad(query, {[s]: d})) }.bind(this)) | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 							// sync store...
 | 
					
						
							|  |  |  | 							: (res  | 
					
						
							|  |  |  | 								&& (data[s] = res) | 
					
						
							| 
									
										
										
										
											2018-02-21 06:54:11 +03:00
										 |  |  | 								&& this.storeDataLoaded(s, | 
					
						
							|  |  |  | 									this.prepareStoreToLoad(query, {[s]: res}))) | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 					}.bind(this)))  | 
					
						
							|  |  |  | 				.then(function(){ return data })}], | 
					
						
							|  |  |  | 	// XXX do we need to do a partial clear???
 | 
					
						
							|  |  |  | 	clearData: ['- Store/', | 
					
						
							|  |  |  | 		function(target){ | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 			var handlers = this.stores | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			Object.keys(handlers).forEach(function(store){ | 
					
						
							|  |  |  | 				var handler = handlers[store] | 
					
						
							|  |  |  | 				handler | 
					
						
							|  |  |  | 					&& this[handler].call(this, null) | 
					
						
							|  |  |  | 			}.bind(this)) | 
					
						
							|  |  |  | 		}], | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var Store =  | 
					
						
							|  |  |  | module.Store = core.ImageGridFeatures.Feature({ | 
					
						
							|  |  |  | 	title: '', | 
					
						
							|  |  |  | 	doc: '', | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tag: 'store', | 
					
						
							|  |  |  | 	depends: [ | 
					
						
							|  |  |  | 		'cache', | 
					
						
							|  |  |  | 	], | 
					
						
							|  |  |  | 	suggested: [ | 
					
						
							|  |  |  | 		'store-localstorage', | 
					
						
							| 
									
										
										
										
											2018-02-19 00:08:31 +03:00
										 |  |  | 		'store-fs', | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 	], | 
					
						
							|  |  |  | 	isApplicable: function(){ return typeof(localStorage) != 'undefined' }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	actions: StoreActions, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	handlers: [ | 
					
						
							|  |  |  | 		['start.pre',  | 
					
						
							|  |  |  | 			function(){  | 
					
						
							|  |  |  | 				if(this.config['store-mode'] != null){ | 
					
						
							|  |  |  | 					this.requestReadyAnnounce() | 
					
						
							|  |  |  | 					this | 
					
						
							|  |  |  | 						.loadData()  | 
					
						
							|  |  |  | 						.then(function(){ | 
					
						
							|  |  |  | 							this.declareReady() }.bind(this))  | 
					
						
							|  |  |  | 				} }], | 
					
						
							|  |  |  | 		['stop',  | 
					
						
							|  |  |  | 			function(){  | 
					
						
							|  |  |  | 				this.config['store-mode'] == 'read-write' && this.saveData() }], | 
					
						
							|  |  |  | 		// XXX timer???
 | 
					
						
							|  |  |  | 		// XXX
 | 
					
						
							|  |  |  | 	], | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-15 06:41:54 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | //---------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | // NOTE: the doc is reused for both localStorage and sessionStorage with 
 | 
					
						
							|  |  |  | // 		appropriate automated changes...
 | 
					
						
							|  |  |  | var __storageHandler_doc =  | 
					
						
							|  |  |  | 	core.doc`Handle localStorage store data...
 | 
					
						
							| 
									
										
										
										
											2018-02-18 15:02:45 +03:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		Write data to key... | 
					
						
							|  |  |  | 		.localStorageDataHandler(key, data) | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		Get data from key... | 
					
						
							|  |  |  | 		.localStorageDataHandler(key) | 
					
						
							|  |  |  | 			-> value | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		Remove key... | 
					
						
							|  |  |  | 		.localStorageDataHandler(key, null) | 
					
						
							|  |  |  | 		.localStorageDataHandler([key, ..], null) | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-18 15:02:45 +03:00
										 |  |  | 		Get stored keys... | 
					
						
							|  |  |  | 		.localStorageDataHandler('?') | 
					
						
							|  |  |  | 			-> keys | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 		.localStorageDataHandler() | 
					
						
							| 
									
										
										
										
											2018-02-19 00:08:31 +03:00
										 |  |  | 		.localStorageDataHandler('*') | 
					
						
							| 
									
										
										
										
											2018-02-18 15:02:45 +03:00
										 |  |  | 		.localStorageDataHandler('??') | 
					
						
							|  |  |  | 			-> data | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		.localStorageDataHandler([key, ..], '??') | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 			-> data | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-18 15:02:45 +03:00
										 |  |  | 		Expand data to store... | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 		.localStorageDataHandler(data) | 
					
						
							| 
									
										
										
										
											2018-02-18 15:02:45 +03:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		Remove all data... | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 		.localStorageDataHandler(null) | 
					
						
							| 
									
										
										
										
											2018-02-18 15:02:45 +03:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	NOTE: when handling key expansion the unexpanded key should be used  | 
					
						
							|  |  |  | 		to access data, e.g. if writing '\${INSTANCE}/xyz' the same string | 
					
						
							|  |  |  | 		is returned via .localStorageDataHandler('??') and should be used  | 
					
						
							|  |  |  | 		to get the value, i.e.  | 
					
						
							|  |  |  | 			.localStorageDataHandler('\${INSTANCE}/xyz') | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 	`
 | 
					
						
							| 
									
										
										
										
											2018-02-18 15:02:45 +03:00
										 |  |  | function makeStorageHandler(storage){ | 
					
						
							|  |  |  | 	var func = function(a, b){ | 
					
						
							| 
									
										
										
										
											2018-02-19 00:08:31 +03:00
										 |  |  | 		// normalize a...
 | 
					
						
							|  |  |  | 		a = a == '??' ? '*' : a  | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-15 06:41:54 +03:00
										 |  |  | 		storage = typeof(storage) == typeof('str') ? window[storage] : storage | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-18 15:02:45 +03:00
										 |  |  | 		var instance = this.config['store-instance-key']  | 
					
						
							| 
									
										
										
										
											2018-02-15 06:41:54 +03:00
										 |  |  | 		var resolvePath = function(p){ | 
					
						
							|  |  |  | 			return p | 
					
						
							| 
									
										
										
										
											2018-02-19 00:08:31 +03:00
										 |  |  | 				.replace('${INSTANCE}', instance) } | 
					
						
							| 
									
										
										
										
											2018-02-15 06:41:54 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-18 15:02:45 +03:00
										 |  |  | 		var keys = Object.keys(storage) | 
					
						
							| 
									
										
										
										
											2018-02-17 04:41:07 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-18 15:02:45 +03:00
										 |  |  | 		var dict_key = '${INSTANCE}/__dict__' | 
					
						
							|  |  |  | 		var k = resolvePath(dict_key) | 
					
						
							|  |  |  | 		var dict = JSON.parse(storage[k] || '{}') | 
					
						
							|  |  |  | 		dict[k] = dict_key | 
					
						
							| 
									
										
										
										
											2018-02-15 06:41:54 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-18 15:02:45 +03:00
										 |  |  | 		// get list of keys...
 | 
					
						
							|  |  |  | 		if(a == '?'){ | 
					
						
							|  |  |  | 			return keys | 
					
						
							|  |  |  | 				.map(function(key){ return dict[key] || key }) | 
					
						
							| 
									
										
										
										
											2018-02-15 06:41:54 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-18 15:02:45 +03:00
										 |  |  | 		// get store contents...
 | 
					
						
							| 
									
										
										
										
											2018-02-19 00:08:31 +03:00
										 |  |  | 		} else if(a == '*'  | 
					
						
							| 
									
										
										
										
											2018-02-18 15:02:45 +03:00
										 |  |  | 				|| arguments.length == 0  | 
					
						
							|  |  |  | 				|| (a instanceof Array && (b == '??' || arguments.length == 1))){ | 
					
						
							|  |  |  | 			var res = {} | 
					
						
							| 
									
										
										
										
											2018-03-03 01:31:08 +03:00
										 |  |  | 			keys = a instanceof Array ? a : keys | 
					
						
							| 
									
										
										
										
											2018-02-19 00:08:31 +03:00
										 |  |  | 			keys | 
					
						
							| 
									
										
										
										
											2018-03-03 01:31:08 +03:00
										 |  |  | 				// add parsed candidates...
 | 
					
						
							| 
									
										
										
										
											2018-03-05 00:39:13 +03:00
										 |  |  | 				.map(function(k){ return resolvePath(k) }) | 
					
						
							| 
									
										
										
										
											2018-02-19 00:08:31 +03:00
										 |  |  | 				// clear keys not in store...
 | 
					
						
							|  |  |  | 				.filter(function(k){  | 
					
						
							|  |  |  | 					return dict[k] in storage || k in storage }) | 
					
						
							|  |  |  | 				.forEach(function(k){ | 
					
						
							|  |  |  | 					res[dict[k] || k] = JSON.parse(storage[k]) }) | 
					
						
							| 
									
										
										
										
											2018-02-18 15:02:45 +03:00
										 |  |  | 			return res | 
					
						
							| 
									
										
										
										
											2018-02-15 06:41:54 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-18 15:02:45 +03:00
										 |  |  | 		// remove all keys...
 | 
					
						
							|  |  |  | 		} else if(a === null || (a instanceof Array && b === null)){ | 
					
						
							|  |  |  | 			;(a || keys) | 
					
						
							|  |  |  | 				.forEach(function(key){ | 
					
						
							|  |  |  | 					delete storage[key] }) | 
					
						
							|  |  |  | 			dict = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// expand data to store...
 | 
					
						
							|  |  |  | 		} else if(typeof(a) != typeof('str')){ | 
					
						
							|  |  |  | 			Object.keys(a).forEach(function(key){ | 
					
						
							|  |  |  | 				var k = resolvePath(key) | 
					
						
							|  |  |  | 				k != key | 
					
						
							|  |  |  | 					&& (dict[k] = key) | 
					
						
							|  |  |  | 				storage[k] = JSON.stringify(a[key]) }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// remove key...
 | 
					
						
							| 
									
										
										
										
											2018-02-19 00:08:31 +03:00
										 |  |  | 		// XXX revise, should this be null or undefined???
 | 
					
						
							| 
									
										
										
										
											2018-02-18 15:02:45 +03:00
										 |  |  | 		} else if(b === null){ | 
					
						
							|  |  |  | 			var k = resolvePath(a) | 
					
						
							|  |  |  | 			delete dict[k] | 
					
						
							|  |  |  | 			delete storage[k] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-19 00:08:31 +03:00
										 |  |  | 		// get keys...
 | 
					
						
							|  |  |  | 		// XXX revise, should this be null or undefined???
 | 
					
						
							| 
									
										
										
										
											2018-02-18 15:02:45 +03:00
										 |  |  | 		} else if(b === undefined){ | 
					
						
							|  |  |  | 			var k = resolvePath(a) | 
					
						
							|  |  |  | 			return k in storage ?  | 
					
						
							|  |  |  | 				JSON.parse(storage[k])  | 
					
						
							|  |  |  | 				: actions.UNDEFINED | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// write key...
 | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			var k = resolvePath(a) | 
					
						
							|  |  |  | 			k != a | 
					
						
							|  |  |  | 				&& (dict[k] = a) | 
					
						
							|  |  |  | 			storage[k] = JSON.stringify(b) | 
					
						
							| 
									
										
										
										
											2018-02-15 06:41:54 +03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-02-18 15:02:45 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		storage[resolvePath('${INSTANCE}/__dict__')] = JSON.stringify(dict) | 
					
						
							| 
									
										
										
										
											2018-02-15 06:41:54 +03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(typeof(storage) == typeof('str')){ | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 		func.long_doc = __storageHandler_doc.replace(/localStorage/g, storage) | 
					
						
							| 
									
										
										
										
											2018-02-15 06:41:54 +03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return func | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | // XXX we should have a separate store config with settings of how to 
 | 
					
						
							|  |  |  | // 		load the store... (???)
 | 
					
						
							|  |  |  | var StoreLocalStorageActions = actions.Actions({ | 
					
						
							|  |  |  | 	config: { | 
					
						
							| 
									
										
										
										
											2018-02-18 15:02:45 +03:00
										 |  |  | 		'store-instance-key': 'ImageGrid.Viewer.main', | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-18 00:57:28 +03:00
										 |  |  | 	// NOTE: for docs see __storageHandler_doc...
 | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 	localStorageDataHandler: ['- Store/', | 
					
						
							| 
									
										
										
										
											2018-02-18 03:24:07 +03:00
										 |  |  | 		{handle_data_store: 'storage',}, | 
					
						
							| 
									
										
										
										
											2018-02-18 15:02:45 +03:00
										 |  |  | 		makeStorageHandler('localStorage')], | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 	sessionStorageDataHandler: ['- Store/', | 
					
						
							| 
									
										
										
										
											2018-02-18 03:24:07 +03:00
										 |  |  | 		{handle_data_store: 'session',}, | 
					
						
							| 
									
										
										
										
											2018-02-18 15:02:45 +03:00
										 |  |  | 		makeStorageHandler('sessionStorage')], | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var StoreLocalStorage =  | 
					
						
							|  |  |  | module.StoreLocalStorage = core.ImageGridFeatures.Feature({ | 
					
						
							|  |  |  | 	title: '', | 
					
						
							|  |  |  | 	doc: '', | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tag: 'store-localstorage', | 
					
						
							|  |  |  | 	depends: [ | 
					
						
							|  |  |  | 		'store', | 
					
						
							|  |  |  | 	], | 
					
						
							|  |  |  | 	isApplicable: function(){  | 
					
						
							|  |  |  | 		return typeof(localStorage) != 'undefined'  | 
					
						
							|  |  |  | 			&& typeof(sessionStorage) != 'undefined' }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	actions: StoreLocalStorageActions, | 
					
						
							| 
									
										
										
										
											2018-03-02 00:35:36 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	handlers: [ | 
					
						
							|  |  |  | 		// localStorage...
 | 
					
						
							|  |  |  | 		// XXX should we use .localStorageDataHandler(..) here???
 | 
					
						
							|  |  |  | 		// XXX the following two sections are almost identical...
 | 
					
						
							|  |  |  | 		['saveStore',  | 
					
						
							| 
									
										
										
										
											2018-03-02 04:03:43 +03:00
										 |  |  | 			function(res, query, value){ | 
					
						
							|  |  |  | 				var q = this.parseStoreQuery(query) | 
					
						
							| 
									
										
										
										
											2018-03-02 00:35:36 +03:00
										 |  |  | 				query  | 
					
						
							| 
									
										
										
										
											2018-03-02 04:03:43 +03:00
										 |  |  | 					&& q.key instanceof Array | 
					
						
							|  |  |  | 					&& q.store.indexOf('storage') >= 0 | 
					
						
							|  |  |  | 					&& q.key.forEach(function(k){ | 
					
						
							|  |  |  | 						this.localStorageDataHandler( | 
					
						
							|  |  |  | 							k,  | 
					
						
							|  |  |  | 							res !== this ? res.data : value) }.bind(this)) }], | 
					
						
							| 
									
										
										
										
											2018-03-02 00:35:36 +03:00
										 |  |  | 		['loadStore',  | 
					
						
							|  |  |  | 			function(res, query){ | 
					
						
							| 
									
										
										
										
											2018-03-02 04:03:43 +03:00
										 |  |  | 				query = this.parseStoreQuery(query) | 
					
						
							| 
									
										
										
										
											2018-03-02 00:35:36 +03:00
										 |  |  | 				res.storage | 
					
						
							|  |  |  | 					&& Object.assign(res.storage, this.localStorageDataHandler(query.key)) }], | 
					
						
							|  |  |  | 		['clearStore',  | 
					
						
							|  |  |  | 			function(_, query){ | 
					
						
							| 
									
										
										
										
											2018-03-02 04:03:43 +03:00
										 |  |  | 				var q = this.parseStoreQuery(query) | 
					
						
							| 
									
										
										
										
											2018-03-02 00:35:36 +03:00
										 |  |  | 				query  | 
					
						
							| 
									
										
										
										
											2018-03-02 04:03:43 +03:00
										 |  |  | 					&& q.store.indexOf('storage') >= 0 | 
					
						
							|  |  |  | 					&& this.localStorageDataHandler(q.key, null) }], | 
					
						
							| 
									
										
										
										
											2018-03-02 00:35:36 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// sessionStorage...
 | 
					
						
							|  |  |  | 		['saveStore',  | 
					
						
							| 
									
										
										
										
											2018-03-02 04:03:43 +03:00
										 |  |  | 			function(res, query, value){ | 
					
						
							|  |  |  | 				var q = this.parseStoreQuery(query) | 
					
						
							| 
									
										
										
										
											2018-03-02 00:35:36 +03:00
										 |  |  | 				query  | 
					
						
							| 
									
										
										
										
											2018-03-02 04:03:43 +03:00
										 |  |  | 					&& q.key instanceof Array | 
					
						
							|  |  |  | 					&& q.store.indexOf('session') >= 0 | 
					
						
							|  |  |  | 					&& q.key.forEach(function(k){ | 
					
						
							|  |  |  | 						this.sessionStorageDataHandler( | 
					
						
							|  |  |  | 							k,  | 
					
						
							|  |  |  | 							res !== this ? res.data : value) }.bind(this)) }], | 
					
						
							| 
									
										
										
										
											2018-03-02 00:35:36 +03:00
										 |  |  | 		['loadStore',  | 
					
						
							|  |  |  | 			function(res, query){ | 
					
						
							| 
									
										
										
										
											2018-03-02 04:03:43 +03:00
										 |  |  | 				query = this.parseStoreQuery(query) | 
					
						
							| 
									
										
										
										
											2018-03-02 00:35:36 +03:00
										 |  |  | 				res.session | 
					
						
							| 
									
										
										
										
											2018-03-03 01:31:08 +03:00
										 |  |  | 					&& Object.assign(res.session, this.sessionStorageDataHandler(query.key)) }], | 
					
						
							| 
									
										
										
										
											2018-03-02 00:35:36 +03:00
										 |  |  | 		['clearStore',  | 
					
						
							|  |  |  | 			function(_, query){ | 
					
						
							| 
									
										
										
										
											2018-03-02 04:03:43 +03:00
										 |  |  | 				var q = this.parseStoreQuery(query) | 
					
						
							| 
									
										
										
										
											2018-03-02 00:35:36 +03:00
										 |  |  | 				query  | 
					
						
							| 
									
										
										
										
											2018-03-02 04:03:43 +03:00
										 |  |  | 					&& q.store.indexOf('session') >= 0 | 
					
						
							|  |  |  | 					&& this.sessionStorageDataHandler(q.key, null) }], | 
					
						
							| 
									
										
										
										
											2018-03-02 00:35:36 +03:00
										 |  |  | 	], | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-15 06:41:54 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | //---------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // XXX StoreFSJSONSync
 | 
					
						
							|  |  |  | // 		Lookup order:
 | 
					
						
							|  |  |  | // 			- app dir
 | 
					
						
							|  |  |  | // 			- $HOME
 | 
					
						
							| 
									
										
										
										
											2018-02-19 00:08:31 +03:00
										 |  |  | var StoreFSJSONActions = actions.Actions({ | 
					
						
							|  |  |  | 	config: { | 
					
						
							|  |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-19 00:08:31 +03:00
										 |  |  | 	// XXX
 | 
					
						
							|  |  |  | 	localStorageFSJSONSyncHandler: ['- Store/', | 
					
						
							|  |  |  | 		{handle_data_store: 'fileSync',}, | 
					
						
							|  |  |  | 		function(a, b){ | 
					
						
							|  |  |  | 			// XXX
 | 
					
						
							|  |  |  | 		}], | 
					
						
							|  |  |  | 	// XXX
 | 
					
						
							|  |  |  | 	localStorageFSJSONHandler: ['- Store/', | 
					
						
							|  |  |  | 		{handle_data_store: 'file',}, | 
					
						
							|  |  |  | 		function(a, b){ | 
					
						
							|  |  |  | 			// XXX
 | 
					
						
							|  |  |  | 			return new Promise(function(resolve, reject){ | 
					
						
							|  |  |  | 				// XXX
 | 
					
						
							|  |  |  | 				resolve() | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		}], | 
					
						
							|  |  |  | }) | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-19 00:08:31 +03:00
										 |  |  | var StoreFSJSON =  | 
					
						
							|  |  |  | module.StoreFSJSONSync = core.ImageGridFeatures.Feature({ | 
					
						
							|  |  |  | 	title: '', | 
					
						
							|  |  |  | 	doc: '', | 
					
						
							| 
									
										
										
										
											2018-02-15 06:41:54 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-19 00:08:31 +03:00
										 |  |  | 	tag: 'store-fs', | 
					
						
							|  |  |  | 	depends: [ | 
					
						
							|  |  |  | 		'fs', | 
					
						
							|  |  |  | 		'store', | 
					
						
							|  |  |  | 	], | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-19 00:08:31 +03:00
										 |  |  | 	actions: StoreFSJSONActions, | 
					
						
							|  |  |  | }) | 
					
						
							| 
									
										
										
										
											2018-02-14 16:49:44 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /********************************************************************** | 
					
						
							|  |  |  | * vim:set ts=4 sw=4 :                               */ return module }) |