moved recursion testing up one level...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2026-07-05 15:30:50 +03:00
parent 67db497eab
commit b98e4ca5c0
2 changed files with 32 additions and 31 deletions

View File

@ -1313,48 +1313,47 @@ module.parser = {
// content handler... // content handler...
handler ??= handler ??=
function(page, body, path, text, state){ function(page, body, path, text, state){
// check for recursion... return args.isolated ?
var include_stack = state.include_stack ??= [] this.resolve(
page,
text,
args.isolated == 'partial' ?
serialize.partialDeepCopy(state)
: {})
: this.expand(page, text, state) }
var pageHandler =
function([path, text]){
// recursion...
// XXX for some reason this does not work for async...
// ...and works quite differently in tests and
// in console -- returns [object Object] in the
// former and hangs in the later...
var include_stack = state.include_stack ??= []
if(include_stack.includes(path)){ if(include_stack.includes(path)){
if(!recursive){ if(!recursive){
throw new Error('Recursive macro: '+include_stack) } throw new Error('Recursive macro: '+include_stack) }
return that.expand(page, recursive, state) } return that.expand(page, recursive, state) }
include_stack.push(path) include_stack.push(path)
// XXX check cache??? // XXX cache???
var res = args.isolated ? // call the handler...
this.resolve(
page,
text,
Object.assign(
args.isolated == 'partial' ?
serialize.partialDeepCopy(state)
: {},
{include_stack}))
: this.expand(page, text, state)
// handle recursion...
return Promise.awaitOrRun(
res,
function(){
state.include_stack.at(-1) == src
&& state.include_stack.pop()
// cleanup...
if(state.include_stack.length == 0){
delete state.include_stack
delete state.recursive }
return res }) }
var pageHandler =
function([path, text]){
// handle nested promises...
return Promise.awaitOrRun( return Promise.awaitOrRun(
text, text,
function(text){ function(text){
return handler.call(that, page, body, path, text, state) }) } return Promise.awaitOrRun(
handler.call(that, page, body, path, text, state),
function(res){
// recursion
state.include_stack.at(-1) == src
&& state.include_stack.pop()
// cleanup...
if(state.include_stack.length == 0){
delete state.include_stack
delete state.recursive }
return res }) }) }
// get and run things... // get and run things...
return Promise.awaitOrRun( return Promise.awaitOrRun(

View File

@ -301,6 +301,7 @@ test.Setups({
page: P, page: P,
code:[ code:[
'@include(/recursive/Self recursive="recursion found")', '@include(/recursive/Self recursive="recursion found")',
// XXX this hangs...
'@include(/async/recursive/Self recursive="recursion found")', '@include(/async/recursive/Self recursive="recursion found")',
'<< recursion found >>', ], } }, '<< recursion found >>', ], } },
include_recursive_b: function(assert){ include_recursive_b: function(assert){
@ -308,6 +309,7 @@ test.Setups({
page: P, page: P,
code:[ code:[
'@include(/recursive/SelfOther recursive="recursion found")', '@include(/recursive/SelfOther recursive="recursion found")',
// XXX this hangs...
'@include(/async/recursive/SelfOther recursive="recursion found")', '@include(/async/recursive/SelfOther recursive="recursion found")',
'<< << recursion found >> >>', ], } }, '<< << recursion found >> >>', ], } },