refactoring store...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2022-05-03 16:15:16 +03:00
parent 988abb3cbf
commit 0debd6505b

View File

@ -134,6 +134,8 @@ module.path = {
split: function(path){ split: function(path){
return this.normalize(path, 'array') }, return this.normalize(path, 'array') },
join: function(path){
return this.normalize(path, 'string') },
} }
@ -153,20 +155,24 @@ module.path = {
// XXX should we support page symlinking??? // XXX should we support page symlinking???
var BaseStore = var BaseStore =
module.BaseStore = { module.BaseStore = {
data: undefined,
exists: function(path){ exists: function(path){
path = module.path.normalize(path, 'string') path = module.path.normalize(path, 'string')
return path in this var data = this.data
return path in data
|| (path[0] == '/' ? || (path[0] == '/' ?
path.slice(1) in this path.slice(1) in data
: ('/'+ path) in this) }, : ('/'+ path) in data) },
paths: function(){ paths: function(){
return Object.keys(this) }, return Object.keys(this.data) },
pages: function(){ pages: function(){
var that = this var that = this
return this.paths() return this.paths()
.map(function(p){ .map(function(p){
return [p, that[p]] }) }, return [p, that.data[p]] }) },
// //
// Resolve page for path // Resolve page for path
@ -187,6 +193,7 @@ module.BaseStore = {
// match all sub-paths. // match all sub-paths.
// //
match: function(path, strict=false){ match: function(path, strict=false){
var data = this.data
// pattern match * / ** // pattern match * / **
if(path.includes('*') if(path.includes('*')
|| path.includes('**')){ || path.includes('**')){
@ -208,17 +215,17 @@ module.BaseStore = {
return res }, new Set())] } return res }, new Set())] }
// search... // search...
for(var p of module.path.paths(path)){ for(var p of module.path.paths(path)){
if(p in this){ if(p in data){
return p } return p }
// NOTE: all paths at this point and in store are absolute, // NOTE: all paths at this point and in store are absolute,
// so we check both with the leading '/' and without // so we check both with the leading '/' and without
// it to make things a bit more relaxed and return the // it to make things a bit more relaxed and return the
// actual matching path... // actual matching path...
if(p[0] == '/' if(p[0] == '/'
&& p.slice(1) in this){ && p.slice(1) in data){
return p.slice(1) } return p.slice(1) }
if(p[0] != '/' if(p[0] != '/'
&& ('/'+p) in this){ && ('/'+p) in data){
return '/'+p } } }, return '/'+p } } },
// //
// Resolve page // Resolve page
@ -241,6 +248,7 @@ module.BaseStore = {
// XXX should this return a map for pattern matches??? // XXX should this return a map for pattern matches???
get: function(path, strict=false){ get: function(path, strict=false){
var that = this var that = this
var data = this.data
path = this.match(path, strict) path = this.match(path, strict)
return path instanceof Array ? return path instanceof Array ?
// XXX should we return matched paths??? // XXX should we return matched paths???
@ -248,9 +256,9 @@ module.BaseStore = {
// NOTE: p can match a non existing page at this point, // NOTE: p can match a non existing page at this point,
// this can be the result of matching a/* in a a/b/c // this can be the result of matching a/* in a a/b/c
// and returning a a/b which can be undefined... // and returning a a/b which can be undefined...
return that[p] return data[p]
?? that[that.match(p)] }) ?? data[that.match(p)] })
: this[path] }, : data[path] },
// NOTE: deleting and updating only applies to explicit matching // NOTE: deleting and updating only applies to explicit matching
// paths -- no page acquisition is performed... // paths -- no page acquisition is performed...
@ -260,26 +268,34 @@ module.BaseStore = {
// XXX BUG: for path '/' this adds an entry at '', but when getting // XXX BUG: for path '/' this adds an entry at '', but when getting
// '/', the later is not found... // '/', the later is not found...
update: function(path, data, mode='update'){ update: function(path, data, mode='update'){
var d = this.data
path = module.path.normalize('/'+ path, 'string') path = module.path.normalize('/'+ path, 'string')
path = path[path.length-1] == '/' ? path = path[path.length-1] == '/' ?
path.slice(0, -1) path.slice(0, -1)
: path : path
this[path] = d[path] =
mode == 'update' ? mode == 'update' ?
Object.assign( Object.assign(
this[path] ?? {}, d[path] ?? {},
data) data)
: data : data
return this }, return this },
// XXX revise... // XXX revise...
delete: function(path){ delete: function(path){
var data = this.data
path = module.path.normalize(path, 'string') path = module.path.normalize(path, 'string')
path = path[path.length-1] == '/' ? path = path[path.length-1] == '/' ?
path.slice(0, -1) path.slice(0, -1)
: path : path
// XXX revise... // XXX revise...
delete this[path] delete data[path]
delete this['/'+ path] delete data['/'+ path]
return this },
// XXX do we need this???
load: function(...data){
Object.assign(this.data, ...data)
return this }, return this },
} }
@ -290,32 +306,44 @@ var store =
module.store = { module.store = {
__proto__: BaseStore, __proto__: BaseStore,
// XXX need a way to integrate these better...
// ...i.e. need a way to layer stores...
data: {
// metadata... // metadata...
// //
'System/path': function(page){ 'System/path': function(){
return this.get('..').path }, return this.get('..').path },
'System/location': function(page){ 'System/location': function(){
return this.get('..').path }, return this.get('..').path },
'System/resolved': function(page){ 'System/resolved': function(){
return this.get('..').match() }, return this.get('..').match() },
'System/dir': function(page){ 'System/dir': function(){
return this.get('..').dir }, return this.get('..').dir },
'System/name': function(page){ 'System/name': function(){
return this.get('..').name }, return this.get('..').name },
'System/title': function(page){ 'System/title': function(){
var p = this.get('..') var p = this.get('..')
return p.title return p.title
?? p.name }, ?? p.name },
// actions...
// utils...
// //
// XXX System/subpaths // XXX System/subpaths
// XXX System/sort
// XXX System/reverse
// XXX System/delete // actions...
//
'System/delete': function(){
this.location = '..'
this.delete()
return this.text },
// XXX System/back // XXX System/back
// XXX System/forward // XXX System/forward
// XXX System/sort
// XXX System/reverse
},
} }
@ -435,7 +463,9 @@ object.Constructor('BasePage', {
// relative proxies to store... // relative proxies to store...
exists: relProxy('exists'), exists: relProxy('exists'),
match: relProxy('match'), match: relProxy('match'),
delete: relProxy('delete'), delete: function(path='.'){
this.store.delete(module.path.relative(this.location, path))
return this },
// XXX how should this handle functions as values??? // XXX how should this handle functions as values???
get: function(path, referrer){ get: function(path, referrer){
@ -1407,15 +1437,14 @@ var WIKIWORD_PATTERN =
//--------------------------------------------------------------------- //---------------------------------------------------------------------
// XXX experiments and testing... // XXX experiments and testing...
store.load(require('./bootstrap'))
// NOTE: in general the root wiki api is simply a page instance. // NOTE: in general the root wiki api is simply a page instance.
// XXX not yet sure how to organize the actual alient -- UI, hooks, .. etc // XXX not yet sure how to organize the actual alient -- UI, hooks, .. etc
var pwiki = var pwiki =
module.pwiki = module.pwiki =
Page('/', '/', Page('/', '/', store)
Object.assign(
Object.create(store),
require('./bootstrap')))
// XXX TEST... // XXX TEST...
@ -1463,6 +1492,7 @@ pwiki
+'\n' +'\n'
+'@filter(test)', +'@filter(test)',
}) })
//*/