mirror of
https://github.com/flynx/pWiki.git
synced 2026-01-07 02:21:08 +00:00
refactoring...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
6e62ef782f
commit
c2ee30502b
@ -1237,7 +1237,9 @@ object.Constructor('Page', BasePage, {
|
|||||||
var state = {depends}
|
var state = {depends}
|
||||||
var data = { render_root: this }
|
var data = { render_root: this }
|
||||||
return this.get(path, data)
|
return this.get(path, data)
|
||||||
.parse(this.get(tpl, data).raw, state) }).call(this) },
|
.parse(
|
||||||
|
this.get('/'+tpl, data).raw,
|
||||||
|
state) }).call(this) },
|
||||||
set text(value){
|
set text(value){
|
||||||
this.__update__({text: value}) },
|
this.__update__({text: value}) },
|
||||||
//this.onTextUpdate(value) },
|
//this.onTextUpdate(value) },
|
||||||
@ -1368,10 +1370,10 @@ var wikiword = require('./dom/wikiword')
|
|||||||
|
|
||||||
var pWikiPageElement =
|
var pWikiPageElement =
|
||||||
module.pWikiPageElement =
|
module.pWikiPageElement =
|
||||||
/* XXX CACHE...
|
// XXX CACHE...
|
||||||
object.Constructor('pWikiPageElement', Page, {
|
|
||||||
/*/
|
|
||||||
object.Constructor('pWikiPageElement', CachedPage, {
|
object.Constructor('pWikiPageElement', CachedPage, {
|
||||||
|
/*/
|
||||||
|
object.Constructor('pWikiPageElement', Page, {
|
||||||
//*/
|
//*/
|
||||||
dom: undefined,
|
dom: undefined,
|
||||||
|
|
||||||
@ -1381,8 +1383,11 @@ object.Constructor('pWikiPageElement', CachedPage, {
|
|||||||
wikiword: wikiword.wikiWordText,
|
wikiword: wikiword.wikiWordText,
|
||||||
},
|
},
|
||||||
|
|
||||||
//__clone_constructor__: Page,
|
// XXX CACHE
|
||||||
__clone_constructor__: CachedPage,
|
__clone_constructor__: CachedPage,
|
||||||
|
/*/
|
||||||
|
__clone_constructor__: Page,
|
||||||
|
//*/
|
||||||
|
|
||||||
__clone_proto: undefined,
|
__clone_proto: undefined,
|
||||||
get __clone_proto__(){
|
get __clone_proto__(){
|
||||||
|
|||||||
@ -41,6 +41,23 @@ module = {
|
|||||||
'/System',
|
'/System',
|
||||||
],
|
],
|
||||||
|
|
||||||
|
/*/ XXX NORMCACHE...
|
||||||
|
__normalized_cache_threshold: 100,
|
||||||
|
__normalized_cache_size: 4096,
|
||||||
|
__normalized_cache: undefined,
|
||||||
|
get _normalized_cache(){
|
||||||
|
var norm = this.__normalized =
|
||||||
|
this.__normalized
|
||||||
|
?? new Set()
|
||||||
|
// trim to size...
|
||||||
|
var l = norm.size
|
||||||
|
var lim = this.__normalized_cache_size ?? 1000
|
||||||
|
var t = this.__normalized_cache_threshold ?? 100
|
||||||
|
if(l > lim){
|
||||||
|
norm = this.__normalized = new Set([...norm].slice(Math.max(l - lim - t, t))) }
|
||||||
|
return norm },
|
||||||
|
//*/
|
||||||
|
|
||||||
// Path utils...
|
// Path utils...
|
||||||
//
|
//
|
||||||
// Path can be in one of two formats:
|
// Path can be in one of two formats:
|
||||||
@ -50,9 +67,10 @@ module = {
|
|||||||
// NOTE: trailing/leading '/' are represented by '' at end/start of
|
// NOTE: trailing/leading '/' are represented by '' at end/start of
|
||||||
// path list...
|
// path list...
|
||||||
normalize: function(path='.', format='auto'){
|
normalize: function(path='.', format='auto'){
|
||||||
/*/ XXX RENORMALIZE...
|
/*/ XXX NORMCACHE...
|
||||||
// do not re-normalize...
|
if(typeof(path) == 'string'
|
||||||
if(path.normalized && format != 'array'){
|
&& format != 'array'
|
||||||
|
&& this._normalized_cache.has(path)){
|
||||||
return path }
|
return path }
|
||||||
//*/
|
//*/
|
||||||
format = format == 'auto' ?
|
format = format == 'auto' ?
|
||||||
@ -86,24 +104,28 @@ module = {
|
|||||||
// NOTE: the last '>>' will be retained...
|
// NOTE: the last '>>' will be retained...
|
||||||
: res.push(e)
|
: res.push(e)
|
||||||
return res }, [])
|
return res }, [])
|
||||||
return format == 'string' ?
|
/*/ XXX NORMCACHE...
|
||||||
|
var res = format == 'string' ?
|
||||||
|
// special case: root -> keep '/'
|
||||||
|
((root
|
||||||
|
&& path.length == 1
|
||||||
|
&& path[0] == '') ?
|
||||||
|
('/'+ path.join('/'))
|
||||||
|
: path.join('/'))
|
||||||
|
: path
|
||||||
|
typeof(res) == 'string'
|
||||||
|
&& this._normalized_cache.add(res)
|
||||||
|
return res },
|
||||||
|
/*/
|
||||||
|
return format == 'string' ?
|
||||||
// special case: root -> keep '/'
|
// special case: root -> keep '/'
|
||||||
/*/ XXX RENORMALIZE...
|
|
||||||
Object.assign(
|
|
||||||
new String((root
|
|
||||||
&& path.length == 1
|
|
||||||
&& path[0] == '') ?
|
|
||||||
('/'+ path.join('/'))
|
|
||||||
: path.join('/')),
|
|
||||||
{normalized: true})
|
|
||||||
/*/
|
|
||||||
((root
|
((root
|
||||||
&& path.length == 1
|
&& path.length == 1
|
||||||
&& path[0] == '') ?
|
&& path[0] == '') ?
|
||||||
('/'+ path.join('/'))
|
('/'+ path.join('/'))
|
||||||
: path.join('/'))
|
: path.join('/'))
|
||||||
//*/
|
|
||||||
: path },
|
: path },
|
||||||
|
//*/
|
||||||
split: function(path){
|
split: function(path){
|
||||||
return this.normalize(path, 'array') },
|
return this.normalize(path, 'array') },
|
||||||
join: function(...parts){
|
join: function(...parts){
|
||||||
@ -237,6 +259,15 @@ module = {
|
|||||||
for(var page of [...this.ALTERNATIVE_PAGES]){
|
for(var page of [...this.ALTERNATIVE_PAGES]){
|
||||||
yield* this.paths(path.concat(page), seen) }} },
|
yield* this.paths(path.concat(page), seen) }} },
|
||||||
|
|
||||||
|
names: function(path='/'){
|
||||||
|
path = this.normalize(path, 'string')
|
||||||
|
var name = path == '/' ?
|
||||||
|
this.ROOT_PAGE
|
||||||
|
: this.basename(path)
|
||||||
|
return name == '' ?
|
||||||
|
this.ALTERNATIVE_PAGES.slice()
|
||||||
|
: [name, ...this.ALTERNATIVE_PAGES] },
|
||||||
|
|
||||||
|
|
||||||
// XXX EXPERIMENTAL...
|
// XXX EXPERIMENTAL...
|
||||||
//
|
//
|
||||||
|
|||||||
@ -13,6 +13,44 @@ var types = require('ig-types')
|
|||||||
var pwpath = require('../path')
|
var pwpath = require('../path')
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// cached(<name>, <update>[, ...<args>])
|
||||||
|
// cached(<name>, <get>, <update>[, ...<args>])
|
||||||
|
// -> <func>
|
||||||
|
//
|
||||||
|
// NOTE: in the first case (no <get>) the first <args> item can not be
|
||||||
|
// a function...
|
||||||
|
//
|
||||||
|
// XXX better introspection???
|
||||||
|
var cached =
|
||||||
|
module.cached =
|
||||||
|
function(name, get, update, ...args){
|
||||||
|
name = `__${name}_cache`
|
||||||
|
if(typeof(update) != 'function'){
|
||||||
|
args.unshift(update)
|
||||||
|
update = get
|
||||||
|
get = null }
|
||||||
|
return update instanceof types.AsyncFunction ?
|
||||||
|
async function(){
|
||||||
|
var cache = this[name] =
|
||||||
|
this[name]
|
||||||
|
?? await update.call(this)
|
||||||
|
return get ?
|
||||||
|
get.call(this, cache, ...arguments)
|
||||||
|
: cache }
|
||||||
|
: function(){
|
||||||
|
var cache = this[name] =
|
||||||
|
this[name]
|
||||||
|
?? update.call(this)
|
||||||
|
return get ?
|
||||||
|
get.call(this, cache, ...arguments)
|
||||||
|
: cache } }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
// Store...
|
// Store...
|
||||||
|
|
||||||
@ -68,33 +106,70 @@ module.BaseStore = {
|
|||||||
// XXX might be a good idea to cache this...
|
// XXX might be a good idea to cache this...
|
||||||
__paths__: async function(){
|
__paths__: async function(){
|
||||||
return Object.keys(this.data) },
|
return Object.keys(this.data) },
|
||||||
//* XXX uncached...
|
|
||||||
|
// local paths...
|
||||||
|
__paths: cached('paths', async function(){
|
||||||
|
return this.__paths__() }),
|
||||||
|
// XXX should this also be cached???
|
||||||
paths: async function(local=false){
|
paths: async function(local=false){
|
||||||
return this.__paths__()
|
return this.__paths()
|
||||||
.iter()
|
.iter()
|
||||||
// XXX NEXT
|
|
||||||
.concat((!local && (this.next || {}).paths) ?
|
.concat((!local && (this.next || {}).paths) ?
|
||||||
this.next.paths()
|
this.next.paths()
|
||||||
: []) },
|
: []) },
|
||||||
/*/
|
|
||||||
__paths_cache_timeout: 1000,
|
// local names...
|
||||||
__paths_cache_timer: undefined,
|
__names: cached('names', async function(){
|
||||||
__paths_cache: undefined,
|
return this.__paths()
|
||||||
paths: async function(local=false){
|
.iter()
|
||||||
this.__paths_cache_timer =
|
.reduce(function(res, path){
|
||||||
this.__paths_cache_timer
|
var n = pwpath.basename(path)
|
||||||
?? setTimeout(function(){
|
if(!n.includes('*')){
|
||||||
delete this.__paths_cache_timer
|
(res[n] = res[n] ?? []).push(path) }
|
||||||
delete this.__paths_cache
|
return res }, {}) }),
|
||||||
}.bind(this), this.__paths_cache_timeout ?? 1000)
|
// XXX should this also be cached???
|
||||||
return this.__paths_cache
|
names: async function(local=false){
|
||||||
|| this.__paths__()
|
return {
|
||||||
.iter()
|
...(!local && (this.next || {}).names ?
|
||||||
// XXX NEXT
|
await this.next.names()
|
||||||
.concat((!local && (this.next || {}).paths) ?
|
: {}),
|
||||||
this.next.paths()
|
...await this.__names(),
|
||||||
: []) },
|
} },
|
||||||
//*/
|
|
||||||
|
__cache_add: function(path){
|
||||||
|
if(this.__paths_cache){
|
||||||
|
this.__paths_cache.includes(path)
|
||||||
|
|| this.__paths_cache.push(path) }
|
||||||
|
if(this.__names_cache){
|
||||||
|
var name = pwpath.basename(path)
|
||||||
|
var names = (this.__names_cache[name] =
|
||||||
|
this.__names_cache[name]
|
||||||
|
?? [])
|
||||||
|
names.includes(path)
|
||||||
|
|| names.push(path) }
|
||||||
|
return this },
|
||||||
|
__cache_remove: function(path){
|
||||||
|
if(this.__paths_cache){
|
||||||
|
var paths = this.__paths_cache
|
||||||
|
paths.splice(
|
||||||
|
paths.indexOf(
|
||||||
|
paths.includes(path) ?
|
||||||
|
path
|
||||||
|
: path[0] == '/' ?
|
||||||
|
path.slice(1)
|
||||||
|
: '/'+path),
|
||||||
|
1) }
|
||||||
|
if(this.__names_cache){
|
||||||
|
var name = pwpath.basename(path)
|
||||||
|
var names = (this.__names_cache[name] =
|
||||||
|
this.__names_cache[name]
|
||||||
|
?? [])
|
||||||
|
var i = names.indexOf(path)
|
||||||
|
i >= 0
|
||||||
|
&& names.splice(i, 1)
|
||||||
|
if(names.length == 0){
|
||||||
|
delete this.__names_cache[name] } }
|
||||||
|
return this },
|
||||||
|
|
||||||
//
|
//
|
||||||
// .exists(<path>)
|
// .exists(<path>)
|
||||||
@ -107,7 +182,7 @@ module.BaseStore = {
|
|||||||
&& path },
|
&& path },
|
||||||
exists: async function(path){
|
exists: async function(path){
|
||||||
path = pwpath.normalize(path, 'string')
|
path = pwpath.normalize(path, 'string')
|
||||||
return (await this.__exists__(path, 'string'))
|
return (await this.__exists__(path))
|
||||||
// NOTE: all paths at this point and in store are
|
// NOTE: all paths at this point and in store are
|
||||||
// absolute, so we check both with the leading
|
// absolute, so we check both with the leading
|
||||||
// '/' and without it to make things a bit more
|
// '/' and without it to make things a bit more
|
||||||
@ -127,10 +202,30 @@ module.BaseStore = {
|
|||||||
// normalize the output...
|
// normalize the output...
|
||||||
|| false },
|
|| false },
|
||||||
// find the closest existing alternative path...
|
// find the closest existing alternative path...
|
||||||
|
// XXX CACHED....
|
||||||
|
find: async function(path, strict=false){
|
||||||
|
// build list of existing page candidates...
|
||||||
|
var names = await this.names()
|
||||||
|
var pages = new Set(
|
||||||
|
pwpath.names(path)
|
||||||
|
.map(function(name){
|
||||||
|
return names[name] ?? [] })
|
||||||
|
.flat())
|
||||||
|
// select accessible candidate...
|
||||||
|
for(var p of pwpath.paths(path, !!strict)){
|
||||||
|
if(pages.has(p)){
|
||||||
|
return p }
|
||||||
|
p = p[0] == '/' ?
|
||||||
|
p.slice(1)
|
||||||
|
: '/'+p
|
||||||
|
if(pages.has(p)){
|
||||||
|
return p } } },
|
||||||
|
/*/
|
||||||
find: async function(path, strict=false){
|
find: async function(path, strict=false){
|
||||||
for(var p of pwpath.paths(path, !!strict)){
|
for(var p of pwpath.paths(path, !!strict)){
|
||||||
if(p = await this.exists(p)){
|
if(p = await this.exists(p)){
|
||||||
return p } } },
|
return p } } },
|
||||||
|
//*/
|
||||||
//
|
//
|
||||||
// Resolve page for path
|
// Resolve page for path
|
||||||
// .match(<path>)
|
// .match(<path>)
|
||||||
@ -167,7 +262,14 @@ module.BaseStore = {
|
|||||||
.replace(/\*\*/g, '.*')
|
.replace(/\*\*/g, '.*')
|
||||||
.replace(/(?<=^|[\\\/]+|[^.])\*/g, '[^\\/]*')
|
.replace(/(?<=^|[\\\/]+|[^.])\*/g, '[^\\/]*')
|
||||||
}(?=[\\\\\/]|$)`)
|
}(?=[\\\\\/]|$)`)
|
||||||
|
/*/ XXX CACHED....
|
||||||
|
var name = pwpath.basename(path)
|
||||||
|
return [...(name.includes('*') ?
|
||||||
|
await this.paths()
|
||||||
|
: await (this.names())[name])
|
||||||
|
/*/
|
||||||
return [...(await this.paths())
|
return [...(await this.paths())
|
||||||
|
//*/
|
||||||
// NOTE: we are not using .filter(..) here as wee
|
// NOTE: we are not using .filter(..) here as wee
|
||||||
// need to keep parts of the path only and not
|
// need to keep parts of the path only and not
|
||||||
// return the whole thing...
|
// return the whole thing...
|
||||||
@ -194,7 +296,11 @@ module.BaseStore = {
|
|||||||
//
|
//
|
||||||
// This is like .match(..) for non-pattern paths and paths ending
|
// This is like .match(..) for non-pattern paths and paths ending
|
||||||
// with '/'; When patterns end with a non-pattern then match the
|
// with '/'; When patterns end with a non-pattern then match the
|
||||||
// basedir and add the basename to each resulting path...
|
// basedir and add the basename to each resulting path, e.g.:
|
||||||
|
// .match('/*/tree')
|
||||||
|
// -> ['System/tree']
|
||||||
|
// .resolve('/*/tree')
|
||||||
|
// -> ['System/tree', 'Dir/tree', ...]
|
||||||
//
|
//
|
||||||
// XXX should this be used by .get(..) instead of .match(..)???
|
// XXX should this be used by .get(..) instead of .match(..)???
|
||||||
// XXX EXPERIMENTAL
|
// XXX EXPERIMENTAL
|
||||||
@ -307,11 +413,13 @@ module.BaseStore = {
|
|||||||
ctime: Date.now(),
|
ctime: Date.now(),
|
||||||
},
|
},
|
||||||
(mode == 'update' && exists) ?
|
(mode == 'update' && exists) ?
|
||||||
await this.get(path)
|
await this.__get__(path)
|
||||||
: {},
|
: {},
|
||||||
data,
|
data,
|
||||||
{mtime: Date.now()})
|
{mtime: Date.now()})
|
||||||
await this.__update__(path, data, mode)
|
await this.__update__(path, data, mode)
|
||||||
|
// XXX CACHED
|
||||||
|
this.__cache_add(path)
|
||||||
return this },
|
return this },
|
||||||
__delete__: async function(path){
|
__delete__: async function(path){
|
||||||
delete this.data[path] },
|
delete this.data[path] },
|
||||||
@ -320,8 +428,10 @@ module.BaseStore = {
|
|||||||
if(this.__delete__ == null){
|
if(this.__delete__ == null){
|
||||||
return this }
|
return this }
|
||||||
path = await this.exists(path)
|
path = await this.exists(path)
|
||||||
path
|
if(path){
|
||||||
&& await this.__delete__(path)
|
await this.__delete__(path)
|
||||||
|
// XXX CACHED
|
||||||
|
this.__cache_remove(path) }
|
||||||
return this },
|
return this },
|
||||||
|
|
||||||
// XXX NEXT might be a good idea to have an API to move pages from
|
// XXX NEXT might be a good idea to have an API to move pages from
|
||||||
@ -398,13 +508,6 @@ module.BaseStore = {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
//
|
|
||||||
// XXX stores to experiment with:
|
|
||||||
// - cache
|
|
||||||
// - fs
|
|
||||||
// - PouchDB
|
|
||||||
//
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
// Meta-Store
|
// Meta-Store
|
||||||
//
|
//
|
||||||
@ -412,58 +515,49 @@ module.BaseStore = {
|
|||||||
// be handled by nested stores.
|
// be handled by nested stores.
|
||||||
//
|
//
|
||||||
|
|
||||||
// XXX might be a good idea to normalize args...
|
|
||||||
var metaProxy =
|
var metaProxy =
|
||||||
function(meth, drop_cache=false, post){
|
function(name, pre, post){
|
||||||
var target = meth.replace(/__/g, '')
|
|
||||||
if(typeof(drop_cache) == 'function'){
|
|
||||||
post = drop_cache
|
|
||||||
drop_cache = false }
|
|
||||||
var func = async function(path, ...args){
|
var func = async function(path, ...args){
|
||||||
var store = this.substore(path)
|
path = pre ?
|
||||||
|
await pre.call(this, path, ...args)
|
||||||
|
: path
|
||||||
|
|
||||||
var res =
|
var p = this.substore(path)
|
||||||
store == null ?
|
if(p){
|
||||||
object.parentCall(MetaStore[meth], this, path, ...args)
|
var res = this.substores[p][name](
|
||||||
: this.data[store][target](
|
path.slice(path.indexOf(p)+p.length),
|
||||||
// NOTE: we are normalizing for root/non-root paths...
|
...args)
|
||||||
path.slice(path.indexOf(store)+store.length),
|
} else {
|
||||||
...args)
|
var res = object.parentCall(MetaStore[name], this, ...arguments) }
|
||||||
|
|
||||||
if(drop_cache){
|
return post ?
|
||||||
delete this.__substores }
|
post.call(this, await res, path, ...args)
|
||||||
post
|
: res }
|
||||||
&& (res = post.call(this, await res, store, path, ...args))
|
Object.defineProperty(func, 'name', {value: name})
|
||||||
return res}
|
|
||||||
Object.defineProperty(func, 'name', {value: meth})
|
|
||||||
return func }
|
return func }
|
||||||
|
|
||||||
|
|
||||||
// XXX this gets stuff from .data, can we avoid this???
|
|
||||||
// ...this can restrict this to being in-memory...
|
|
||||||
// XXX not sure about the name...
|
// XXX not sure about the name...
|
||||||
// XXX should this be a mixin???
|
// XXX should this be a mixin???
|
||||||
var MetaStore =
|
var MetaStore =
|
||||||
module.MetaStore = {
|
module.MetaStore = {
|
||||||
__proto__: BaseStore,
|
__proto__: BaseStore,
|
||||||
|
|
||||||
//data: undefined,
|
//
|
||||||
|
// Format:
|
||||||
|
// {
|
||||||
|
// <path>: <store>,
|
||||||
|
// ...
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
substores: undefined,
|
||||||
|
|
||||||
__substores: undefined,
|
|
||||||
get substores(){
|
|
||||||
return this.__substores
|
|
||||||
?? (this.__substores = Object.entries(this.data)
|
|
||||||
.filter(function([path, value]){
|
|
||||||
return object.childOf(value, BaseStore) })
|
|
||||||
.map(function([path, _]){
|
|
||||||
return path })) },
|
|
||||||
// XXX do we need to account for trailing '/' here???
|
// XXX do we need to account for trailing '/' here???
|
||||||
substore: function(path){
|
substore: function(path){
|
||||||
path = pwpath.normalize(path, 'string')
|
path = pwpath.normalize(path, 'string')
|
||||||
if(this.substores.includes(path)){
|
if(path in (this.substores ?? {})){
|
||||||
return path }
|
return path }
|
||||||
var root = path[0] == '/'
|
var root = path[0] == '/'
|
||||||
var store = this.substores
|
var store = Object.keys(this.substores ?? {})
|
||||||
// normalize store paths to the given path...
|
// normalize store paths to the given path...
|
||||||
.filter(function(p){
|
.filter(function(p){
|
||||||
return path.startsWith(
|
return path.startsWith(
|
||||||
@ -478,45 +572,87 @@ module.MetaStore = {
|
|||||||
undefined
|
undefined
|
||||||
: store },
|
: store },
|
||||||
getstore: function(path){
|
getstore: function(path){
|
||||||
return this.data[this.substore(path)] },
|
return (this.substores ?? {})[this.substore(path)] },
|
||||||
// XXX do we need to account for trailing '/' here???
|
// XXX do we need to account for trailing '/' here???
|
||||||
isStore: function(path){
|
isStore: function(path){
|
||||||
|
if(!this.substores){
|
||||||
|
return false }
|
||||||
path = pwpath.normalize(path, 'string')
|
path = pwpath.normalize(path, 'string')
|
||||||
path = path[0] == '/' ?
|
path = path[0] == '/' ?
|
||||||
path.slice(1)
|
path.slice(1)
|
||||||
: path
|
: path
|
||||||
return this.substores.includes(path)
|
return !!this.substores[path]
|
||||||
|| this.substores.includes('/'+ path) },
|
|| !!this.substores['/'+ path] },
|
||||||
|
|
||||||
// XXX this depends on .data having keys...
|
// NOTE: we are using level2 API here to enable mixing this with
|
||||||
__paths__: async function(){
|
// store adapters that can overload the level1 API to implement
|
||||||
|
// their own stuff...
|
||||||
|
|
||||||
|
paths: async function(){
|
||||||
var that = this
|
var that = this
|
||||||
var data = this.data
|
var stores = await Promise.iter(
|
||||||
//return Object.keys(data)
|
Object.entries(this.substores ?? {})
|
||||||
return Promise.iter(Object.keys(data)
|
.map(function([path, store]){
|
||||||
.map(function(path){
|
return store.paths()
|
||||||
return object.childOf(data[path], BaseStore) ?
|
.iter()
|
||||||
data[path].paths()
|
.map(function(s){
|
||||||
.iter()
|
return pwpath.join(path, s) }) }))
|
||||||
.map(function(s){
|
.flat()
|
||||||
return pwpath.join(path, s) })
|
return object.parentCall(MetaStore.paths, this, ...arguments)
|
||||||
: path }))
|
.iter()
|
||||||
.flat() },
|
.concat(stores) },
|
||||||
// XXX revise...
|
names: async function(){
|
||||||
__exists__: metaProxy('__exists__',
|
var that = this
|
||||||
// normalize path...
|
var res = await object.parentCall(MetaStore.names, this, ...arguments)
|
||||||
function(res, store, path){
|
await Promise.all(Object.entries(this.substores ?? {})
|
||||||
return (store && res) ?
|
.map(async function([path, store]){
|
||||||
path
|
return Object.entries(await store.names())
|
||||||
: res }),
|
.map(function([name, paths]){
|
||||||
__get__: metaProxy('__get__'),
|
res[name] = (res[name] ?? [])
|
||||||
__delete__: metaProxy('__delete__', true),
|
.concat(paths
|
||||||
// XXX BUG: this does not create stuff in sub-store...
|
.map(function(s){
|
||||||
__update__: metaProxy('__update__', true),
|
return pwpath.join(path, s) })) }) }))
|
||||||
|
return res },
|
||||||
|
|
||||||
|
exists: metaProxy('exists',
|
||||||
|
//async function(path){
|
||||||
|
// return this.resolve(path) },
|
||||||
|
null,
|
||||||
|
function(res, path){
|
||||||
|
var s = this.substore(path)
|
||||||
|
return res == false ?
|
||||||
|
res
|
||||||
|
: s ?
|
||||||
|
pwpath.join(s, res)
|
||||||
|
: res }),
|
||||||
|
get: metaProxy('get',
|
||||||
|
async function(path){
|
||||||
|
return this.resolve(path) }),
|
||||||
|
metadata: metaProxy('metadata'),
|
||||||
|
update: async function(path, data, mode='update'){
|
||||||
|
data = data instanceof Promise ?
|
||||||
|
await data
|
||||||
|
: data
|
||||||
|
// add substore...
|
||||||
|
if(object.childOf(data, BaseStore)){
|
||||||
|
;(this.substores = this.substores ?? {})[path] = data
|
||||||
|
return this }
|
||||||
|
// add to substore...
|
||||||
|
var p = this.substore(path)
|
||||||
|
if(p){
|
||||||
|
this.substores[p].update(
|
||||||
|
// trim path...
|
||||||
|
path.slice(path.indexOf(p)+p.length),
|
||||||
|
...[...arguments].slice(1))
|
||||||
|
return this }
|
||||||
|
// add local...
|
||||||
|
return object.parentCall(MetaStore.update, this, ...arguments) },
|
||||||
|
// XXX Q: how do we delete a substore???
|
||||||
|
delete: metaProxy('delete'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
// XXX might be a fun idea to actually use this as a backend for BaseStore...
|
// XXX might be a fun idea to actually use this as a backend for BaseStore...
|
||||||
|
|||||||
10
pwiki2.js
10
pwiki2.js
@ -1,6 +1,16 @@
|
|||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
* XXX BUG:
|
||||||
|
* await pwiki.get('/* /path').text -> '' (wrong)
|
||||||
|
* XXX NORMCACHE .normalize(..) cache normalized strings...
|
||||||
|
* ...seems to have little impact...
|
||||||
|
* XXX MATCH limit candidates to actual page name matches -- this will
|
||||||
|
* limit the number of requests to actual number of pages with that
|
||||||
|
* name...
|
||||||
|
* e.g. when searching for xxx/tree the only "tree" available is
|
||||||
|
* System/tree, and if it is overloaded it's now a question of
|
||||||
|
* picking one out of two and not out of tens generated by .paths()
|
||||||
* XXX CACHE match pattern paths -- to catch page creation...
|
* XXX CACHE match pattern paths -- to catch page creation...
|
||||||
* 1) explicit subpath matching -- same as .match(..)
|
* 1) explicit subpath matching -- same as .match(..)
|
||||||
* 2) identify recursive patterns -- same as **
|
* 2) identify recursive patterns -- same as **
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user