mirror of
				https://github.com/flynx/pWiki.git
				synced 2025-11-04 04:50:09 +00:00 
			
		
		
		
	render caching now working...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									c353621589
								
							
						
					
					
						commit
						7236429eed
					
				
							
								
								
									
										131
									
								
								pwiki/page.js
									
									
									
									
									
								
							
							
						
						
									
										131
									
								
								pwiki/page.js
									
									
									
									
									
								
							@ -541,7 +541,10 @@ object.Constructor('Page', BasePage, {
 | 
				
			|||||||
	get depends(){
 | 
						get depends(){
 | 
				
			||||||
		return (this.dependencies ?? {})[this.path] },
 | 
							return (this.dependencies ?? {})[this.path] },
 | 
				
			||||||
	set depends(value){
 | 
						set depends(value){
 | 
				
			||||||
		;(this.dependencies = this.dependencies ?? {})[this.path] = value },
 | 
							if(value == null){
 | 
				
			||||||
 | 
								delete (this.dependencies ?? {})[this.path]
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								;(this.dependencies = this.dependencies ?? {})[this.path] = value } },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// The page that started the current render...
 | 
						// The page that started the current render...
 | 
				
			||||||
	//
 | 
						//
 | 
				
			||||||
@ -1077,15 +1080,20 @@ object.Constructor('Page', BasePage, {
 | 
				
			|||||||
					join = join
 | 
										join = join
 | 
				
			||||||
						&& await base.parse(join, state)
 | 
											&& await base.parse(join, state)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										// XXX DEPENDS...
 | 
				
			||||||
 | 
										// NOTE: thie does not introduce a dependency on each 
 | 
				
			||||||
 | 
										// 		of the iterated pages, that is handled by the 
 | 
				
			||||||
 | 
										// 		respective include/source/.. macros, this however
 | 
				
			||||||
 | 
										// 		only depends on page count...
 | 
				
			||||||
 | 
										depends.add(src)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					// expand matches...
 | 
										// expand matches...
 | 
				
			||||||
					var first = true
 | 
										var first = true
 | 
				
			||||||
					for await(var page of this.get(src).asPages(strict)){
 | 
										for await(var page of this.get(src).asPages(strict)){
 | 
				
			||||||
						if(join && !first){
 | 
											if(join && !first){
 | 
				
			||||||
							yield join }
 | 
												yield join }
 | 
				
			||||||
						first = false 
 | 
											first = false 
 | 
				
			||||||
						yield this.__parser__.expand(page, text, state) 
 | 
											yield this.__parser__.expand(page, text, state) }
 | 
				
			||||||
						// XXX DEPENDS...
 | 
					 | 
				
			||||||
						depends.add(page.path) }
 | 
					 | 
				
			||||||
					// else...
 | 
										// else...
 | 
				
			||||||
					if(first
 | 
										if(first
 | 
				
			||||||
							&& (text || args['else'])){
 | 
												&& (text || args['else'])){
 | 
				
			||||||
@ -1258,13 +1266,108 @@ object.Constructor('Page', BasePage, {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//---------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// XXX this is good enough on the front-side to think about making the 
 | 
				
			||||||
 | 
					// 		cache persistent with a very large timeout (if set at all), but
 | 
				
			||||||
 | 
					// 		we are not tracking changes on the store-side...
 | 
				
			||||||
 | 
					var CachedPage =
 | 
				
			||||||
 | 
					module.CachedPage =
 | 
				
			||||||
 | 
					object.Constructor('CachedPage', Page, {
 | 
				
			||||||
 | 
						// XXX should this always refer to .render_root.cachestore
 | 
				
			||||||
 | 
						cachestore: undefined,
 | 
				
			||||||
 | 
						/*/
 | 
				
			||||||
 | 
						get cachestore(){
 | 
				
			||||||
 | 
							return (this.render_root ?? this).__cachestore },
 | 
				
			||||||
 | 
						set cachestore(value){
 | 
				
			||||||
 | 
							;(this.render_root ?? this).__cachestore = value },
 | 
				
			||||||
 | 
						//*/
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						// NOTE: set this to null/undefined/0 to disable...
 | 
				
			||||||
 | 
						cache_timeout: '20m',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						get cache(){
 | 
				
			||||||
 | 
							this.chechCache(this.path)
 | 
				
			||||||
 | 
							return ((this.cachestore ?? {})[this.path] ?? {}).value },
 | 
				
			||||||
 | 
						set cache(value){
 | 
				
			||||||
 | 
							if(this.cachestore === false 
 | 
				
			||||||
 | 
									|| this.cache == value){
 | 
				
			||||||
 | 
								return }
 | 
				
			||||||
 | 
							var path = this.path
 | 
				
			||||||
 | 
							if(value == null){
 | 
				
			||||||
 | 
								delete (this.cachestore ?? {})[path]
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								;(this.cachestore = this.cachestore ?? {})[path] = {
 | 
				
			||||||
 | 
									created: Date.now(),
 | 
				
			||||||
 | 
									// XXX
 | 
				
			||||||
 | 
									valid: undefined,
 | 
				
			||||||
 | 
									value,
 | 
				
			||||||
 | 
								} } 
 | 
				
			||||||
 | 
							// clear depended pages from cache...
 | 
				
			||||||
 | 
							for(var [key, deps] of Object.entries(this.dependencies)){
 | 
				
			||||||
 | 
								if(key != path && deps.has(path)){
 | 
				
			||||||
 | 
									//console.log('CACHE: DROP:', key)
 | 
				
			||||||
 | 
									delete this.cachestore[key] } } },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// XXX should this return something useful???
 | 
				
			||||||
 | 
						chechCache: function(...paths){
 | 
				
			||||||
 | 
							if(!this.cache_timeout || !this.cachestore){
 | 
				
			||||||
 | 
								return this }
 | 
				
			||||||
 | 
							paths = paths.length == 0 ?
 | 
				
			||||||
 | 
								Object.keys(this.cachestore)
 | 
				
			||||||
 | 
								: paths
 | 
				
			||||||
 | 
							for(var path of paths){
 | 
				
			||||||
 | 
								var {created, valid, value} = this.cachestore[path] ?? {}
 | 
				
			||||||
 | 
								if(value){
 | 
				
			||||||
 | 
									var now = Date.now()
 | 
				
			||||||
 | 
									valid = valid 
 | 
				
			||||||
 | 
										?? Date.str2ms(this.cache_timeout)
 | 
				
			||||||
 | 
									// drop cache...
 | 
				
			||||||
 | 
									if(now > created + valid){
 | 
				
			||||||
 | 
										//console.log('CACHE: DROP:', this.path)
 | 
				
			||||||
 | 
										delete this.cachestore[path] } } }
 | 
				
			||||||
 | 
							return this },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						__update__: function(){
 | 
				
			||||||
 | 
							this.cache = null
 | 
				
			||||||
 | 
							return object.parentCall(CachedPage.prototype.__update__, this, ...arguments) },
 | 
				
			||||||
 | 
						__delete__: function(){
 | 
				
			||||||
 | 
							this.cache = null
 | 
				
			||||||
 | 
							return object.parentCall(CachedPage.prototype.__delete__, this, ...arguments) },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						get text(){
 | 
				
			||||||
 | 
							var that = this
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* XXX
 | 
				
			||||||
 | 
							console.log(
 | 
				
			||||||
 | 
								this.cache ? 
 | 
				
			||||||
 | 
									'CACHED:' 
 | 
				
			||||||
 | 
									: 'RENDER:', 
 | 
				
			||||||
 | 
								this.path)
 | 
				
			||||||
 | 
							//*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							var text = this.cache 
 | 
				
			||||||
 | 
								?? object.parentProperty(CachedPage.prototype, 'text').get.call(this)
 | 
				
			||||||
 | 
							text instanceof Promise
 | 
				
			||||||
 | 
								&& text.then(function(text){
 | 
				
			||||||
 | 
									that.cache = text })
 | 
				
			||||||
 | 
							return text },
 | 
				
			||||||
 | 
						set text(value){
 | 
				
			||||||
 | 
							object.parentProperty(CachedPage.prototype, 'text').set.call(this, value) },
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//---------------------------------------------------------------------
 | 
					//---------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var wikiword = require('./dom/wikiword')
 | 
					var wikiword = require('./dom/wikiword')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var pWikiPageElement =
 | 
					var pWikiPageElement =
 | 
				
			||||||
module.pWikiPageElement = 
 | 
					module.pWikiPageElement = 
 | 
				
			||||||
 | 
					/* XXX CACHE...
 | 
				
			||||||
object.Constructor('pWikiPageElement', Page, {
 | 
					object.Constructor('pWikiPageElement', Page, {
 | 
				
			||||||
 | 
					/*/
 | 
				
			||||||
 | 
					object.Constructor('pWikiPageElement', CachedPage, {
 | 
				
			||||||
 | 
					//*/
 | 
				
			||||||
	dom: undefined,
 | 
						dom: undefined,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1273,7 +1376,8 @@ object.Constructor('pWikiPageElement', Page, {
 | 
				
			|||||||
		wikiword: wikiword.wikiWordText,
 | 
							wikiword: wikiword.wikiWordText,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	__clone_constructor__: Page,
 | 
						//__clone_constructor__: Page,
 | 
				
			||||||
 | 
						__clone_constructor__: CachedPage,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	__clone_proto: undefined,
 | 
						__clone_proto: undefined,
 | 
				
			||||||
	get __clone_proto__(){
 | 
						get __clone_proto__(){
 | 
				
			||||||
@ -1320,7 +1424,16 @@ object.Constructor('pWikiPageElement', Page, {
 | 
				
			|||||||
	onLoad: types.event.Event('onLoad', function(){
 | 
						onLoad: types.event.Event('onLoad', function(){
 | 
				
			||||||
		this.dom.dispatchEvent(this.__pWikiLoadedDOMEvent) }),
 | 
							this.dom.dispatchEvent(this.__pWikiLoadedDOMEvent) }),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	refresh: async function(){
 | 
						// XXX CACHE...
 | 
				
			||||||
 | 
						__last_refresh_path: undefined,
 | 
				
			||||||
 | 
						refresh: async function(full=false){
 | 
				
			||||||
 | 
							// drop cache if re-refreshing or when full refresh requested...
 | 
				
			||||||
 | 
							// XXX CACHE...
 | 
				
			||||||
 | 
							;(full
 | 
				
			||||||
 | 
									|| this.__last_refresh_path == this.path)	
 | 
				
			||||||
 | 
								&& this.cache 
 | 
				
			||||||
 | 
								&& (this.cache = null)
 | 
				
			||||||
 | 
							this.__last_refresh_path = this.path
 | 
				
			||||||
		var dom = this.dom
 | 
							var dom = this.dom
 | 
				
			||||||
		dom.innerHTML = await this.text 
 | 
							dom.innerHTML = await this.text 
 | 
				
			||||||
		for(var filter of Object.values(this.domFilters)){
 | 
							for(var filter of Object.values(this.domFilters)){
 | 
				
			||||||
@ -1372,7 +1485,11 @@ module.System = {
 | 
				
			|||||||
		text: '@include(. isolated join="@source(file-separator)")' },
 | 
							text: '@include(. isolated join="@source(file-separator)")' },
 | 
				
			||||||
	_view: {
 | 
						_view: {
 | 
				
			||||||
		text: object.doc`
 | 
							text: object.doc`
 | 
				
			||||||
			<slot name="header">/list @source(./path)/_edit</slot>
 | 
								<slot name="header">
 | 
				
			||||||
 | 
									<a href="#/list">☰</a>
 | 
				
			||||||
 | 
									@source(./path) 
 | 
				
			||||||
 | 
									<a href="#@source(./path)/_edit">(edit)</a>
 | 
				
			||||||
 | 
								</slot>
 | 
				
			||||||
			<hr>
 | 
								<hr>
 | 
				
			||||||
			<slot name="content"></slot>
 | 
								<slot name="content"></slot>
 | 
				
			||||||
			<hr>
 | 
								<hr>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										12
									
								
								pwiki2.js
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								pwiki2.js
									
									
									
									
									
								
							@ -1,6 +1,7 @@
 | 
				
			|||||||
/**********************************************************************
 | 
					/**********************************************************************
 | 
				
			||||||
* 
 | 
					* 
 | 
				
			||||||
*
 | 
					*
 | 
				
			||||||
 | 
					* XXX CACHE track store changes...
 | 
				
			||||||
* XXX need a uniform way to track some state in links in pwiki for things 
 | 
					* XXX need a uniform way to track some state in links in pwiki for things 
 | 
				
			||||||
* 		like paging and the like with simple user/macro access (???)...
 | 
					* 		like paging and the like with simple user/macro access (???)...
 | 
				
			||||||
* 		...the simplest that comes to mind is to store in in path 
 | 
					* 		...the simplest that comes to mind is to store in in path 
 | 
				
			||||||
@ -34,8 +35,6 @@
 | 
				
			|||||||
* 				- session
 | 
					* 				- session
 | 
				
			||||||
* 				- stored (config)
 | 
					* 				- stored (config)
 | 
				
			||||||
* 		...css selector as path....
 | 
					* 		...css selector as path....
 | 
				
			||||||
* XXX CACHE cache rendered pages and invalidate cache based to changes 
 | 
					 | 
				
			||||||
* 		to page dependencies...
 | 
					 | 
				
			||||||
* XXX GENERATOR make pattern path parsing a generator...
 | 
					* XXX GENERATOR make pattern path parsing a generator...
 | 
				
			||||||
* 		...experiment with a controllable iterator/range thing...
 | 
					* 		...experiment with a controllable iterator/range thing...
 | 
				
			||||||
* 		This would require:
 | 
					* 		This would require:
 | 
				
			||||||
@ -52,6 +51,13 @@
 | 
				
			|||||||
* 							...might be a good idea to make filters local only...
 | 
					* 							...might be a good idea to make filters local only...
 | 
				
			||||||
* 						XXX slots/macros might also pose a problem...
 | 
					* 						XXX slots/macros might also pose a problem...
 | 
				
			||||||
* 			2) all the macros that can source pages to produce generators (DONE)
 | 
					* 			2) all the macros that can source pages to produce generators (DONE)
 | 
				
			||||||
 | 
					* XXX the parser should handle all action return values, including:
 | 
				
			||||||
 | 
					* 			- lists			-- DONE
 | 
				
			||||||
 | 
					* 			- iterators		-- DONE
 | 
				
			||||||
 | 
					* 			- strings		-- DONE
 | 
				
			||||||
 | 
					* 			- numbers		-- DONE
 | 
				
			||||||
 | 
					* 			- misc:
 | 
				
			||||||
 | 
					* 				dates		-- ???
 | 
				
			||||||
* XXX BUG: .move(..) behaves in an odd way...
 | 
					* XXX BUG: .move(..) behaves in an odd way...
 | 
				
			||||||
* 		see: System/move page action
 | 
					* 		see: System/move page action
 | 
				
			||||||
* 		...deletes the original and moves an empty page -- sync error???
 | 
					* 		...deletes the original and moves an empty page -- sync error???
 | 
				
			||||||
@ -81,6 +87,8 @@
 | 
				
			|||||||
* 		...looks like no :|
 | 
					* 		...looks like no :|
 | 
				
			||||||
* XXX DEPENDS @now() makes the template uncachable, to we actually need it???
 | 
					* XXX DEPENDS @now() makes the template uncachable, to we actually need it???
 | 
				
			||||||
* XXX CHECK: @macro(..) and @slot(..) must overload in the same way...
 | 
					* XXX CHECK: @macro(..) and @slot(..) must overload in the same way...
 | 
				
			||||||
 | 
					* XXX DEPENDS/CACHE @macro(..) introduces a dependency on count (pattern)
 | 
				
			||||||
 | 
					* 		...not sure how we track these...
 | 
				
			||||||
*
 | 
					*
 | 
				
			||||||
*
 | 
					*
 | 
				
			||||||
*
 | 
					*
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user