diff --git a/pwiki/page.js b/pwiki/page.js index cc9068b..dac18c4 100755 --- a/pwiki/page.js +++ b/pwiki/page.js @@ -521,6 +521,19 @@ object.Constructor('Page', BasePage, { NOT_FOUND_TEMPLATE_ERROR: 'NotFoundTemplateError', + // XXX DEPENDS to be used for cache invalidation... + // Format: + // { + // : Set([, ...]), + // } + // + dependencies: undefined, + // NOTE: for this to populate .text must be done at least once... + get depends(){ + return (this.dependencies ?? {})[this.path] }, + set depends(value){ + ;(this.dependencies = this.dependencies ?? {})[this.path] = value }, + // The page that started the current render... // // This is set by .text and maintained by .clone(..). @@ -581,8 +594,17 @@ object.Constructor('Page', BasePage, { // // // - now: function(){ + /* XXX DEPENDS this makes the whole render uncachable -- do we need this??? + now: function(args, body, state){ + // XXX DEPENDS... + // NOTE: this makes a template uncachable... + var depends = state.depends = + state.depends + ?? new Set() + depends.add('TIME') return ''+ Date.now() }, + //*/ + // // @filter() // /> @@ -679,12 +701,19 @@ object.Constructor('Page', BasePage, { var join = args.join && await base.parse(args.join, state) + // XXX DEPENDS + var depends = state.depends = + state.depends + ?? new Set() + handler = handler ?? async function(src){ return isolated ? {data: await this.get(src) - //.parse({seen: new Set(state.seen ?? [])})} - .parse({seen: state.seen})} + .parse({ + seen: state.seen, + depends, + })} : this.get(src) .parse(state) } @@ -722,6 +751,8 @@ object.Constructor('Page', BasePage, { // load the included page... var res = await handler.call(page, full) + // XXX DEPENDS + depends.add(full) // NOTE: we only track recursion down and not sideways... seen.delete(full) @@ -774,6 +805,11 @@ object.Constructor('Page', BasePage, { await base.parse(src, state) : src + // XXX DEPENDS + var depends = state.depends = + state.depends + ?? new Set() + var pages = src ? this.get(src).asPages() : text instanceof Array ? @@ -796,6 +832,9 @@ object.Constructor('Page', BasePage, { text = typeof(page) == 'string' ? page : await page.raw + // XXX DEPENDS... + page.path + && depends.add(page.path) var filters = args.filter @@ -974,6 +1013,11 @@ object.Constructor('Page', BasePage, { && !args.nonstrict var join + // XXX DEPENDS + var depends = state.depends = + state.depends + ?? new Set() + var _getBlock = function(name){ var block = args[name] ? [{ @@ -1021,7 +1065,9 @@ object.Constructor('Page', BasePage, { if(join && !first){ yield join } first = false - yield this.__parser__.expand(page, text, state) } + yield this.__parser__.expand(page, text, state) + // XXX DEPENDS... + depends.add(page.path) } // else... if(first && (text || args['else'])){ @@ -1150,9 +1196,11 @@ object.Constructor('Page', BasePage, { return this.get(this.NOT_FOUND_TEMPLATE_ERROR).parse() } // render template in context of page... + var depends = this.depends = new Set([tpl]) + var state = {depends} var data = { render_root: this } return this.get(path, data) - .parse(this.get(tpl, data).raw) }).call(this) }, + .parse(this.get(tpl, data).raw, state) }).call(this) }, set text(value){ this.__update__({text: value}) }, //this.onTextUpdate(value) }, diff --git a/pwiki/path.js b/pwiki/path.js index 32aa21d..c77bd00 100755 --- a/pwiki/path.js +++ b/pwiki/path.js @@ -240,6 +240,13 @@ module = { // // Syntax: // /:/:/../action + // XXX or? + // ::= : + // ::= + // | : + // ::= + // + // | : // // XXX the problem here is that we could legitimately create path // items containing ":" -- it either needs to be a reserved char diff --git a/pwiki2.js b/pwiki2.js index 73298ab..ca7ec2c 100755 --- a/pwiki2.js +++ b/pwiki2.js @@ -1,11 +1,6 @@ /********************************************************************** * * -* XXX track requested paths in render state.paths... -* ...this would be useful for dependency tracking and cache -* management/invalidation... -* ...would also be useful to have a parse mode that would only -* track paths -- is this practical??? * XXX need a uniform way to track state in pwiki for things like paging * and the like with simple user/macro access... * ...the simplest that comes to mind is to store in in path @@ -38,6 +33,9 @@ * ... * - session * - stored (config) +* ...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... * ...experiment with a controllable iterator/range thing... * This would require: @@ -57,11 +55,7 @@ * XXX BUG: .move(..) behaves in an odd way... * see: System/move page action * ...deletes the original and moves an empty page -- sync error??? -* XXX does @macro(..) have to follow the same overloading rules as @slot(..)??? -* ...does it?? -* XXX ranges in pattern paths -- page-size=X page=Y | from=X to=Y / ... -* ...url syntax??? -* XXX differenced in behaviour between _abc and abc, either need to make +* XXX differences in behaviour between _abc and abc, either need to make * them the same or document the differences and the reasons behind * them... * XXX add support for tag in include/source/quote??? @@ -80,18 +74,13 @@ * XXX OPTIMIZE: /tree is really slow... * ...is the problem purely in the async/await playing ping-pong??? * XXX BUG: FF: conflict between object.run and PouchDB... -* XXX BUG: browser: .get('/*').raw hangs in the browser context... -* XXX BUG?: /_tree for some reason does not show anything on lower levels... -* ...renaming _tree -> all fixed the issue -* ...might be a problem with how rendering templates are handled in -* .text... -* ...if this is not fixable need to document that rendering templates -* are not to be recursive... * XXX add action to reset overloaded (bootstrap) pages... * - per page * - global * XXX Q: can we access fs from a pwa??? * ...looks like no :| +* XXX DEPENDS @now() makes the template uncachable, to we actually need it??? +* XXX CHECK: @macro(..) and @slot(..) must overload in the same way... * * *