filter sync bug fixed, at last...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2026-08-04 21:50:21 +03:00
parent 327693a768
commit 74b6c19753
2 changed files with 32 additions and 21 deletions

View File

@ -18,7 +18,7 @@ var pwpath = require('./path')
//--------------------------------------------------------------------- //---------------------------------------------------------------------
// Parser... // Parser/Runner...
// XXX TODO: // XXX TODO:
// callbacks on elements resolving... // callbacks on elements resolving...
@ -280,7 +280,8 @@ module.BaseParser = {
return f in (that.filters ?? {})}) return f in (that.filters ?? {})})
var handle = function(str){ var handle = function(str){
// skip non-basic data... // skip non-basic data...
if(typeof(str) == 'object' if(str == null
|| typeof(str) == 'object'
|| typeof(str) == 'function'){ || typeof(str) == 'function'){
return str } return str }
return filters return filters
@ -768,27 +769,25 @@ module.BaseParser = {
var unresolved = [] var unresolved = []
// merge resolved elements into the last item of elems... // merge resolved elements into the last item of elems...
var elems = [] var elems = []
for(var elem of ast){ for(var elem of ast){
// nesting... // nesting...
while(elem && elem.value){ while(elem && elem.value){
// exec stage II macros... // exec stage II macros...
if(typeof(elem.value) == 'function'){ if(typeof(elem.value) == 'function'){
let i = elems.length
let e = elem let e = elem
let func = e.value let func = e.value
Promise.awaitOrRun( elem = Promise.awaitOrRun(
// if not everything is resolved, delay the stage II // if not everything is resolved, delay the stage II
// callbacks till .wait is done... // callbacks till .wait is done...
// NOTE: this depends on that JS is single thread // NOTE: this depends on that JS is single thread
// and we can't have state.wait resolve in // and we can't have state.wait resolve in
// the middle of this loop. // the middle of this loop.
// NOTE: waiting promises resolving is also done in
// FIFO orderm thus maintaining order of execution
state.wait, state.wait,
function(){ function(){
return elem = e.value = return func(state) })
func(state) }) break }
break }
elem = elem.value } elem = elem.value }
if(elem == null){ if(elem == null){
continue } continue }
@ -847,12 +846,9 @@ module.BaseParser = {
// - apply stage III post handlers // - apply stage III post handlers
// //
// //
// XXX BUG: this seems to always return a promise...
// XXX RECURSION might be a good idea to limit recursion/nesting depth // XXX RECURSION might be a good idea to limit recursion/nesting depth
// of inner resolve(..)... // of inner resolve(..)...
// XXX RENAME...
finalize: function(page, ast, state={}, nested_handlers={}, wait='wait'){ finalize: function(page, ast, state={}, nested_handlers={}, wait='wait'){
//finalize: function(page, ast, state={}, nested_handlers={}, wait='waitNested'){
var that = this var that = this
var stage3 = function(ast){ var stage3 = function(ast){
@ -864,10 +860,8 @@ module.BaseParser = {
.flat() } .flat() }
var resolve = function(ast){ var resolve = function(ast){
return Promise.awaitOrRun( return Promise.awaitOrRun(
// XXX LOCAL_STATE
state.hasOwnProperty('wait') ? state.hasOwnProperty('wait') ?
state.wait state.wait
// XXX
: null, : null,
function(){ function(){
//delete state.unresolved //delete state.unresolved
@ -886,20 +880,17 @@ module.BaseParser = {
ast = this.resolve(page, ast, state, nested_handlers) ast = this.resolve(page, ast, state, nested_handlers)
return Promise.awaitOrRun( return Promise.awaitOrRun(
// XXX LOCAL_STATE Promise
// XXX do we actually need to wait here??? .iter(ast)
// ...each macro should already be waiting... .sync(),
//...[state[wait]].flat(),
(wait && state.hasOwnProperty(wait)) ? (wait && state.hasOwnProperty(wait)) ?
state[wait] state[wait]
: null, : null,
function(){ function(ast){
// NOTE: in an async world where any promised macro can // NOTE: in an async world where any promised macro can
// call .exec(..) / .execNested(..) we can't trust // call .exec(..) / .execNested(..) we can't trust
// the lack of .unresolved in state... // the lack of .unresolved in state...
return Promise.awaitOrRun( return Promise.awaitOrRun(
// XXX LOCAL_STATE if we are nested we should not wait
// for anything after the caller...
that.isResolved(ast) ? that.isResolved(ast) ?
ast ast
: resolve(ast), : resolve(ast),

View File

@ -435,6 +435,26 @@ test.Setups({
code: [ code: [
'<filter upper/>@include(/async/page)', '<filter upper/>@include(/async/page)',
'PAGE' ]} }, 'PAGE' ]} },
filter_exclude: function(assert){
return {
page: P,
code: [
'<filter upper/>filtered <filter -upper>unfiltered</filter>',
'FILTERED unfiltered' ]} },
filter_exclude_sync: function(assert){
var state = this.filter_exclude(assert)
return {
...state,
code: [
state.code[0] +' @include(/page)',
state.code[1] +' PAGE' ]} },
filter_exclude_async: function(assert){
var state = this.filter_exclude(assert)
return {
...state,
code: [
state.code[0] +' @include(/async/page)',
state.code[1] +' PAGE' ]} },
filter_mixed_isolated_sync: function(assert){ filter_mixed_isolated_sync: function(assert){
return { return {
page: P, page: P,