mirror of
				https://github.com/flynx/pWiki.git
				synced 2025-11-04 04:50:09 +00:00 
			
		
		
		
	investigating the sync issue...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									0b133aeeb8
								
							
						
					
					
						commit
						4991dd1bd0
					
				
							
								
								
									
										126
									
								
								pwiki/parser.js
									
									
									
									
									
								
							
							
						
						
									
										126
									
								
								pwiki/parser.js
									
									
									
									
									
								
							@ -446,8 +446,37 @@ module.BaseParser = {
 | 
				
			|||||||
	//			old code:
 | 
						//			old code:
 | 
				
			||||||
	//				await p.pwiki.parse('<slot moo/>!!! <slot moo>moo</slot>')
 | 
						//				await p.pwiki.parse('<slot moo/>!!! <slot moo>moo</slot>')
 | 
				
			||||||
	//					-> 'moo!!! '
 | 
						//					-> 'moo!!! '
 | 
				
			||||||
	//		...does not seem to affect named macros...
 | 
						//		...this affects @var(..) and @slot(..) and does not affect @macro(..)
 | 
				
			||||||
	_expand: function(page, ast, state={}){
 | 
						//		The problem is that .callMacro(..) is for some execution paths is
 | 
				
			||||||
 | 
						//		called sync and in some paths after the current execution frame is 
 | 
				
			||||||
 | 
						//		done, i.e. async...
 | 
				
			||||||
 | 
						//		...turns out that the problem is in the inconsistent await behavior,
 | 
				
			||||||
 | 
						//		in var macro, as an example, there are two paths: the assign and 
 | 
				
			||||||
 | 
						//		the get, the assign calls .parse(..) and awaits for the result 
 | 
				
			||||||
 | 
						//		while the get path is "sync", this results in the first exec path
 | 
				
			||||||
 | 
						//		getting pushed to the next execution frame while the second is run
 | 
				
			||||||
 | 
						//		in sync with the caller, here is a simplified demo:
 | 
				
			||||||
 | 
						//			console.log(1)
 | 
				
			||||||
 | 
						//			// note that we are NOTE await'ing for the function here...
 | 
				
			||||||
 | 
						//			(async function f(){ 
 | 
				
			||||||
 | 
						//				console.log(2)})()
 | 
				
			||||||
 | 
						//			console.log(3)
 | 
				
			||||||
 | 
						//				-> prints 1, 2, 3
 | 
				
			||||||
 | 
						//		and:
 | 
				
			||||||
 | 
						//			console.log(1)
 | 
				
			||||||
 | 
						//			(async function f(){ 
 | 
				
			||||||
 | 
						//				// note the await -- this is the only difference...
 | 
				
			||||||
 | 
						//				console.log(await 2)})()
 | 
				
			||||||
 | 
						//			console.log(3)
 | 
				
			||||||
 | 
						//				-> prints 1, 3, 2
 | 
				
			||||||
 | 
						//		this could both be a bug or a feature depending on how you look
 | 
				
			||||||
 | 
						//		at it, but it makes promise sequencing very unpredictable...
 | 
				
			||||||
 | 
						//		...another problem here is that in the var macro, simply adding
 | 
				
			||||||
 | 
						//		an await of something does not fix the issue, we need to await 
 | 
				
			||||||
 | 
						//		for something significant -- await this.parse('') works, while
 | 
				
			||||||
 | 
						//		await vars[name] does not -- to the contrary of the above example...
 | 
				
			||||||
 | 
						// XXX EXPERIMENTAL...
 | 
				
			||||||
 | 
						expand: function(page, ast, state={}){
 | 
				
			||||||
		var that = this
 | 
							var that = this
 | 
				
			||||||
		ast = ast == null ?
 | 
							ast = ast == null ?
 | 
				
			||||||
				Promise.awaitOrRun(
 | 
									Promise.awaitOrRun(
 | 
				
			||||||
@ -460,55 +489,54 @@ module.BaseParser = {
 | 
				
			|||||||
				ast
 | 
									ast
 | 
				
			||||||
			: ast.iter()
 | 
								: ast.iter()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// XXX this must execute sequentially for things that depend on 
 | 
							// NOTE this must execute sequentially for things that depend on 
 | 
				
			||||||
		// 		lexical scope not to get lost in the mess...
 | 
							// 		lexical scope not to get lost in the mess...
 | 
				
			||||||
		// 		...or it's a question of if we can maintain "slices" of 
 | 
					 | 
				
			||||||
		// 		state per macro call that is both containing all the state 
 | 
					 | 
				
			||||||
		// 		from previous macros, and is not affected by the changes 
 | 
					 | 
				
			||||||
		// 		done by next macros (unless needed)...
 | 
					 | 
				
			||||||
		return Promise.seqiter(ast, 
 | 
							return Promise.seqiter(ast, 
 | 
				
			||||||
			function(value){
 | 
									function(value){
 | 
				
			||||||
				// text block...
 | 
										// text block...
 | 
				
			||||||
				if(typeof(value) == 'string'){
 | 
										if(typeof(value) == 'string'){
 | 
				
			||||||
					return value }
 | 
											return value }
 | 
				
			||||||
				// macro...
 | 
										// macro...
 | 
				
			||||||
				var {name, args, body} = value
 | 
										var {name, args, body} = value
 | 
				
			||||||
				// nested macro -- skip...
 | 
										// nested macro -- skip...
 | 
				
			||||||
				if(typeof(page.macros[name]) != 'function'){
 | 
										if(typeof(page.macros[name]) != 'function'){
 | 
				
			||||||
					return {...value, skip: true} }
 | 
											return {...value, skip: true} }
 | 
				
			||||||
				// macro call...
 | 
										// macro call...
 | 
				
			||||||
				return Promise.awaitOrRun(
 | 
										return Promise.awaitOrRun(
 | 
				
			||||||
					that.callMacro(page, name, args, body, state),
 | 
											// XXX due to the unpredictable behavior of await we 
 | 
				
			||||||
					function(res){
 | 
											// 		need to call this only AFTER the previous call
 | 
				
			||||||
						res = res ?? ''
 | 
											// 		is done...
 | 
				
			||||||
						// result...
 | 
											that.callMacro(page, name, args, body, state),
 | 
				
			||||||
						if(res instanceof Array 
 | 
											function(res){
 | 
				
			||||||
								|| page.macros[name] instanceof types.Generator){
 | 
												res = res ?? ''
 | 
				
			||||||
							return res
 | 
												// result...
 | 
				
			||||||
						} else {
 | 
												if(res instanceof Array 
 | 
				
			||||||
							return [res] } }) },
 | 
														|| page.macros[name] instanceof types.Generator){
 | 
				
			||||||
			function(err){
 | 
													return res
 | 
				
			||||||
				console.error(err)
 | 
												} else {
 | 
				
			||||||
				return page.parse(
 | 
													return [res] } }) },
 | 
				
			||||||
					// XXX add line number and page path...
 | 
									function(err){
 | 
				
			||||||
					'@include("./ParseError'
 | 
										console.error(err)
 | 
				
			||||||
						+':path='
 | 
										return page.parse(
 | 
				
			||||||
							// XXX use pwpath.encodeElem(..) ???
 | 
											// XXX add line number and page path...
 | 
				
			||||||
							+ page.path 
 | 
											'@include("./ParseError'
 | 
				
			||||||
						+':msg='
 | 
												+':path='
 | 
				
			||||||
							+ err.message 
 | 
													// XXX use pwpath.encodeElem(..) ???
 | 
				
			||||||
								// quote html stuff...
 | 
													+ page.path 
 | 
				
			||||||
								.replace(/&/g, '&')
 | 
												+':msg='
 | 
				
			||||||
								.replace(/</g, '<')
 | 
													+ err.message 
 | 
				
			||||||
								.replace(/>/g, '>')
 | 
														// quote html stuff...
 | 
				
			||||||
								// quote argument syntax...
 | 
														.replace(/&/g, '&')
 | 
				
			||||||
								.replace(/["']/g, function(c){
 | 
														.replace(/</g, '<')
 | 
				
			||||||
									return '%'+ c.charCodeAt().toString(16) })
 | 
														.replace(/>/g, '>')
 | 
				
			||||||
								.replace(/:/g, ':')
 | 
														// quote argument syntax...
 | 
				
			||||||
								.replace(/=/g, '=')
 | 
														.replace(/["']/g, function(c){
 | 
				
			||||||
						+'")') })
 | 
															return '%'+ c.charCodeAt().toString(16) })
 | 
				
			||||||
			.sync() },
 | 
														.replace(/:/g, ':')
 | 
				
			||||||
	//*/
 | 
														.replace(/=/g, '=')
 | 
				
			||||||
 | 
												+'")') })
 | 
				
			||||||
 | 
									.sync() },
 | 
				
			||||||
 | 
						/*/
 | 
				
			||||||
	expand: async function*(page, ast, state={}){
 | 
						expand: async function*(page, ast, state={}){
 | 
				
			||||||
		try{
 | 
							try{
 | 
				
			||||||
			ast = ast == null ?
 | 
								ast = ast == null ?
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user