reworking recursion detection, still not happy with it...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2022-08-27 16:17:25 +03:00
parent 3d1598052a
commit ac267b8c9f
3 changed files with 25 additions and 26 deletions

View File

@ -26,7 +26,7 @@ var pouchdbstore = require('./pwiki/store/pouchdb')
var store = var store =
module.store = { module.store = {
// XXX base localstorage... /* XXX base localstorage...
__proto__: localstoragestore.localStorageStore, __proto__: localstoragestore.localStorageStore,
__prefix__: '--pwiki-root:', __prefix__: '--pwiki-root:',
data: localStorage, data: localStorage,

View File

@ -505,7 +505,7 @@ module.Page =
object.Constructor('Page', BasePage, { object.Constructor('Page', BasePage, {
__parser__: parser.parser, __parser__: parser.parser,
NESTING_RECURSION_THRESHOLD: 10, NESTING_RECURSION_TEST_THRESHOLD: 50,
// Filter that will isolate the page/include/.. from parent filters... // Filter that will isolate the page/include/.. from parent filters...
ISOLATED_FILTERS: 'isolated', ISOLATED_FILTERS: 'isolated',
@ -523,11 +523,8 @@ object.Constructor('Page', BasePage, {
// not present or broken. // not present or broken.
// NOTE: to force the system to fail set this to undefined. // NOTE: to force the system to fail set this to undefined.
NOT_FOUND_ERROR: 'NotFoundError', NOT_FOUND_ERROR: 'NotFoundError',
RECURSION_ERROR: 'RecursionError', RECURSION_ERROR: 'RecursionError',
NOT_FOUND_TEMPLATE_ERROR: 'NotFoundTemplateError', NOT_FOUND_TEMPLATE_ERROR: 'NotFoundTemplateError',
QUOTE_ACTION_PAGE: 'QuoteActionPage', QUOTE_ACTION_PAGE: 'QuoteActionPage',
// Format: // Format:
@ -709,7 +706,7 @@ object.Constructor('Page', BasePage, {
?? new Set() ?? new Set()
handler = handler handler = handler
?? async function(src){ ?? async function(src, state){
return isolated ? return isolated ?
{data: await this.get(src) {data: await this.get(src)
.parse({ .parse({
@ -734,17 +731,18 @@ object.Constructor('Page', BasePage, {
// recursion detected... // recursion detected...
if(seen.has(full) if(seen.has(full)
// nesting path recursion... // nesting path recursion...
// XXX a more general way to check would be to see if the || (full.length % (this.NESTING_RECURSION_TEST_THRESHOLD || 50) == 0
// path resolves to the same source (done below) and && pwpath.split(full).length > 3
// check if the context has changed -- i.e. if the paths && await page.find() == await page.get('..').find()
// actually contain anything... && await page.find() == await page.get('../..').find())){
|| (seen.size % (this.NESTING_RECURSION_THRESHOLD || 10) == 0
&& new Set([...seen]
.map(function(p){
return page.get(p).match()[0] }))
.size < seen.size)){
if(recursive == null){ if(recursive == null){
yield page.get(page.RECURSION_ERROR).parse(state) console.warn(
`@${key}(..): ${
seen.has(full) ?
'direct'
: 'depth-limit'
} recursion detected:`, seen)
yield page.get(page.RECURSION_ERROR).parse()
continue } continue }
// have the 'recursive' arg... // have the 'recursive' arg...
yield base.parse(recursive, state) yield base.parse(recursive, state)
@ -752,7 +750,7 @@ object.Constructor('Page', BasePage, {
seen.add(full) seen.add(full)
// load the included page... // load the included page...
var res = await handler.call(page, full) var res = await handler.call(page, full, state)
depends.add(full) depends.add(full)
// NOTE: we only track recursion down and not sideways... // NOTE: we only track recursion down and not sideways...
@ -771,7 +769,7 @@ object.Constructor('Page', BasePage, {
yield* this.macros.include.call(this, yield* this.macros.include.call(this,
'source', 'source',
args, body, state, 'sources', args, body, state, 'sources',
async function(src){ async function(src, state){
return this.parse(this.get(src).raw, state) }) }), return this.parse(this.get(src).raw, state) }) }),
// //
// @quote(<src>) // @quote(<src>)
@ -1657,11 +1655,11 @@ module.System = {
// NOTE: these are last resort pages, preferably overloaded in /Templates. // NOTE: these are last resort pages, preferably overloaded in /Templates.
// //
RecursionError: { RecursionError: {
text: 'RECURSION ERROR: @quote(../path)' }, text: 'RECURSION ERROR: @source(../path)' },
NotFoundError: { NotFoundError: {
text: 'NOT FOUND ERROR: @quote(./path)' }, text: 'NOT FOUND ERROR: @source(./path)' },
NotFoundTemplateError: { NotFoundTemplateError: {
text: 'NOT FOUND TEMPLATE ERROR: @quote(../path)' }, text: 'NOT FOUND TEMPLATE ERROR: @source(../path)' },
DeletingPage: { DeletingPage: {
text: 'Deleting: @source(../path)' }, text: 'Deleting: @source(../path)' },

View File

@ -4,11 +4,12 @@
* XXX BUG with non-BaseStore root, the paths under /Test/.. report * XXX BUG with non-BaseStore root, the paths under /Test/.. report
* recursion errors when rendered by /tree... * recursion errors when rendered by /tree...
* /Test/tree -- works fine * /Test/tree -- works fine
* XXX BUG service pages (NotFoundError, RecursionError, ...) now print * this is affected by page.NESTING_RECURSION_THRESHOLD
* "[ native code ]" instead of the path and replacing @quote(..) * XXX the problem is that we are still tracking state sideways...
* with @source(..) breaks things... * ...likely via state transfer through @macro(..)
* ...this seems to happen only if the root store is not * XXX not sure how it's connected to store type...
* MetaStore/BaseStore... * ...this turned out to trivial, local storage store simply
* has more stuff...
* XXX BUG: .get(..) does not seem to resolve to <store>.next... * XXX BUG: .get(..) does not seem to resolve to <store>.next...
* XXX page search: make things invariant via .names * XXX page search: make things invariant via .names
* - if a page is in a system path and there are no alternatives * - if a page is in a system path and there are no alternatives