diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2019-10-11 10:15:58 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2019-10-11 10:15:58 +0000 |
| commit | e2a4257fc05d37822df2b7bbe0f587645375edf2 (patch) | |
| tree | b170a7323f4c080207dd681f66f70ee43fbc01ae | |
| parent | add table to mmm/dom convert (diff) | |
| download | mmm-e2a4257fc05d37822df2b7bbe0f587645375edf2.tar.gz mmm-e2a4257fc05d37822df2b7bbe0f587645375edf2.zip | |
fileders load via get_index rather than list_facets/list_fileders
| -rw-r--r-- | build/server.moon | 8 | ||||
| -rw-r--r-- | mmm/init.client.moon | 6 | ||||
| -rw-r--r-- | mmm/init.server.moon | 6 | ||||
| -rw-r--r-- | mmm/mmmfs/fileder.moon | 34 | ||||
| -rw-r--r-- | mmm/mmmfs/stores/fs.moon | 20 | ||||
| -rw-r--r-- | mmm/mmmfs/stores/init.moon | 32 | ||||
| -rw-r--r-- | mmm/mmmfs/stores/sql.moon | 21 | ||||
| -rw-r--r-- | mmm/mmmfs/stores/web.moon | 46 | ||||
| -rw-r--r-- | spec/stores_spec.moon | 70 |
9 files changed, 170 insertions, 73 deletions
diff --git a/build/server.moon b/build/server.moon index 706e4e0..89cf1a6 100644 --- a/build/server.moon +++ b/build/server.moon @@ -60,7 +60,10 @@ class Server local browser = require 'mmm.mmmfs.browser' local fileder = require 'mmm.mmmfs.fileder' local web = require 'mmm.mmmfs.stores.web' - local root = fileder.Fileder(web.WebStore({ verbose = true }), path) + + local store = web.WebStore({ verbose = true }) + local index = store:get_index(path, -1) + local root = fileder.Fileder(store, index) BROWSER = browser.Browser(root, path, true) end) @@ -70,7 +73,8 @@ class Server -- serve fileder index -- '?index': one level deep -- '?tree': recursively - index = fileder\get_index facet.name == '?tree' + depth = if facet.name == '?tree' then -1 else 1 + index = @store\get_index path, depth convert 'table', facet.type, index, fileder, facet.name else -- fileder and facet given diff --git a/mmm/init.client.moon b/mmm/init.client.moon index c29a675..e32f25d 100644 --- a/mmm/init.client.moon +++ b/mmm/init.client.moon @@ -40,7 +40,11 @@ relative = do base = base\match '^(.*)%.%w+$' (name, x) -> - name = base .. name if '.' == name\sub 1, 1 + if name == '.' + name = base + else if '.' == name\sub 1, 1 + name = base .. name + _require name if on_load diff --git a/mmm/init.server.moon b/mmm/init.server.moon index 8fc6a0e..0fe36d5 100644 --- a/mmm/init.server.moon +++ b/mmm/init.server.moon @@ -35,5 +35,9 @@ relative = do base = base\match '^(.*)%.%w+$' (name, x) -> - name = base .. name if '.' == name\sub 1, 1 + if name == '.' + name = base + else if '.' == name\sub 1, 1 + name = base .. name + _require name diff --git a/mmm/mmmfs/fileder.moon b/mmm/mmmfs/fileder.moon index b7876a3..0d484b5 100644 --- a/mmm/mmmfs/fileder.moon +++ b/mmm/mmmfs/fileder.moon @@ -134,14 +134,26 @@ class Fileder @facet_keys[k] = v } - load: => + -- this fails with JS objects from JSON.parse + if 'table' == type @path + index = @path + @path = index.path + @load index + + assert ('string' == type @path), "invalid path: '#{@path}'" + + load: (index) => + assert not @loaded, "already loaded!" @loaded = true - for path in @store\list_fileders_in @path - table.insert @children, Fileder @store, path + if not index + index = @store\get_index @path + + for path_or_index in *index.children + table.insert @children, Fileder @store, path_or_index - for name, type in @store\list_facets @path - key = Key name, type + for key in *index.facets + key = Key key @facet_keys[key] = key _, name = dir_base @path @@ -195,18 +207,6 @@ class Fileder [name for name in pairs names] - -- get an index table, listing path, facets and children - -- optionally get recursive index - get_index: (recursive=false) => - { - path: @path - facets: [key for str, key in pairs @facet_keys] - children: if recursive - [child\get_index true for child in *@children] - else - [{ :path } for { :path } in *@children] - } - -- check whether a facet is directly available has: (...) => want = Key ... diff --git a/mmm/mmmfs/stores/fs.moon b/mmm/mmmfs/stores/fs.moon index ac20232..5167668 100644 --- a/mmm/mmmfs/stores/fs.moon +++ b/mmm/mmmfs/stores/fs.moon @@ -1,4 +1,6 @@ +require = relative ..., 1 lfs = require 'lfs' +import Store from require '.' -- split filename into dirname + basename dir_base = (path) -> @@ -8,21 +10,16 @@ dir_base = (path) -> dir, base -class FSStore +class FSStore extends Store new: (opts = {}) => - opts.root or= 'root' - opts.verbose or= false + super opts - if not opts.verbose - @log = -> + opts.root or= 'root' -- ensure path doesnt end with a slash @root = opts.root\match '^(.-)/?$' @log "opening '#{opts.root}'..." - log: (...) => - print "[DB]", ... - -- fileders list_fileders_in: (path='') => coroutine.wrap -> @@ -32,13 +29,6 @@ class FSStore if 'directory' == lfs.attributes entry_path, 'mode' coroutine.yield "#{path}/#{entry_name}" - list_all_fileders: (path='') => - coroutine.wrap -> - for path in @list_fileders_in path - coroutine.yield path - for p in @list_all_fileders path - coroutine.yield p - create_fileder: (parent, name) => @log "creating fileder #{path}" path = "#{parent}/#{name}" diff --git a/mmm/mmmfs/stores/init.moon b/mmm/mmmfs/stores/init.moon index 64fc44d..bbca33f 100644 --- a/mmm/mmmfs/stores/init.moon +++ b/mmm/mmmfs/stores/init.moon @@ -1,5 +1,36 @@ require = relative ..., 0 +class Store + new: (opts) => + opts.verbose or= false + + if not opts.verbose + @log = -> + + list_fileders_in: => error "not implemented" + + list_all_fileders: (path='') => + coroutine.wrap -> + for path in @list_fileders_in path + coroutine.yield path + for p in @list_all_fileders path + coroutine.yield p + + get_index: (path='', depth=1) => + if depth == 0 + return path + + { + :path + facets: [{:name, :type} for name, type in @list_facets path] + children: [@get_index child, depth - 1 for child in @list_fileders_in path] + } + + close: => + + log: (...) => + print "[#{@@__name}]", ... + -- instantiate a store from a CLI arg -- e.g.: sql, fs:/path/to/root, sql:MEMORY, sql:db.sqlite3 get_store = (args='sql', opts={verbose: true}) -> @@ -29,5 +60,6 @@ get_store = (args='sql', opts={verbose: true}) -> os.exit 1 { + :Store :get_store } diff --git a/mmm/mmmfs/stores/sql.moon b/mmm/mmmfs/stores/sql.moon index 490eade..1d50877 100644 --- a/mmm/mmmfs/stores/sql.moon +++ b/mmm/mmmfs/stores/sql.moon @@ -1,15 +1,14 @@ +require = relative ..., 1 sqlite = require 'sqlite3' -root = os.tmpname! +import Store from require '.' -class SQLStore +class SQLStore extends Store new: (opts = {}) => + super opts + opts.file or= 'db.sqlite3' - opts.verbose or= false opts.memory or= false - if not opts.verbose - @log = -> - if opts.memory @log "opening in-memory DB..." @db = sqlite.open_memory! @@ -43,9 +42,6 @@ class SQLStore CREATE INDEX IF NOT EXISTS facet_name ON facet(name); ]] - log: (...) => - print "[DB]", ... - close: => @db\close! @@ -71,13 +67,6 @@ class SQLStore FROM fileder WHERE parent IS ?', path coroutine.yield path - list_all_fileders: (path='') => - coroutine.wrap -> - for path in @list_fileders_in path - coroutine.yield path - for p in @list_all_fileders path - coroutine.yield p - create_fileder: (parent, name) => path = "#{parent}/#{name}" diff --git a/mmm/mmmfs/stores/web.moon b/mmm/mmmfs/stores/web.moon index adf3ee4..082fea8 100644 --- a/mmm/mmmfs/stores/web.moon +++ b/mmm/mmmfs/stores/web.moon @@ -1,3 +1,7 @@ +require = relative ..., 1 +import Store from require '.' +{ :location, :XMLHttpRequest, :JSON, :Object, :Array } = js.global + -- split filename into dirname + basename dir_base = (path) -> dir, base = path\match '(.-)([^/]-)$' @@ -6,7 +10,6 @@ dir_base = (path) -> dir, base -{ :location, :XMLHttpRequest, :JSON } = js.global fetch = (url) -> request = js.new XMLHttpRequest request\open 'GET', url, false @@ -15,38 +18,46 @@ fetch = (url) -> assert request.status == 200, "unexpected status code: #{request.status}" request.responseText -class WebStore +parse_json = do + fix = (val) -> + switch type val + when 'userdata' + if Array\isArray val + [fix x for x in js.of val] + else + {(fix e[0]), (fix e[1]) for e in js.of Object\entries(val)} + else + val + + (string) -> + print fix JSON\parse string + fix JSON\parse string + +class WebStore extends Store new: (opts = {}) => + super opts + if MODE == 'CLIENT' origin = location.origin opts.host or= origin - opts.verbose or= false - - if not opts.verbose - @log = -> -- ensure host ends without a slash @host = opts.host\match '^(.-)/?$' @log "connecting to '#{@host}'..." - log: (...) => - print "[DB]", ... + get_index: (path='', depth=1) => + pseudo = if depth > 1 or depth < 0 '?tree' else '?index' + json = fetch "#{@host .. path}/#{pseudo}: application/json" + parse_json json -- fileders list_fileders_in: (path='') => coroutine.wrap -> json = fetch "#{@host .. path}/?index: application/json" - index = JSON\parse json + index = parse_json json for child in js.of index.children coroutine.yield child.path - list_all_fileders: (path='') => - coroutine.wrap -> - for path in @list_fileders_in path - coroutine.yield path - for p in @list_all_fileders path - coroutine.yield p - create_fileder: (parent, name) => @log "creating fileder #{path}" error "not implemented" @@ -70,9 +81,6 @@ class WebStore index = JSON\parse json for facet in js.of index.facets coroutine.yield facet.name, facet.type - -- @TODO: this doesn't belong here! - if facet.type\match 'text/moonscript' - coroutine.yield facet.name, facet.type\gsub 'text/moonscript', 'text/lua' load_facet: (path, name, type) => fetch "#{@host .. path}/#{name}: #{type}" diff --git a/spec/stores_spec.moon b/spec/stores_spec.moon index 3997ded..742d8c8 100644 --- a/spec/stores_spec.moon +++ b/spec/stores_spec.moon @@ -1,3 +1,21 @@ +-- relative imports +_G.relative = do + _require = require + + (base, sub) -> + sub = sub or 0 + + for i=1, sub + base = base\match '^(.*)%.%w+$' + + (name, x) -> + if name == '.' + name = base + else if '.' == name\sub 1, 1 + name = base .. name + + _require name + sort2 = (a, b) -> {ax, ay}, {bx, by} = a, b "#{ax}//#{ay}" < "#{bx}//#{by}" @@ -57,6 +75,51 @@ test_store = (ts) -> assert.are.same {{'', 'text/markdown'}, {'name', 'alpha'}}, toseq2 ts\list_facets '/hello/world' + describe "can get indexes", -> + hello_index = { + path: '/hello' + children: { + '/hello/world' + } + facets: { + { name: 'name', type: 'alpha' } + } + } + + it "for a single level", -> + assert.are.same hello_index, ts\get_index '/hello' + + + root_index = { + path: '' + children: { + hello_index + } + facets: {} + } + it "for a limited number of levels", -> + assert.are.same root_index, ts\get_index '', 2 + + it "recursively", -> + hello_index.children[1] = { + path: '/hello/world' + children: { + { + path: '/hello/world/again' + children: {} + facets: {} + } + } + facets: { + { name: '', type: 'text/markdown' } + { name: 'name', type: 'alpha' } + } + } + + assert.are.same root_index, ts\get_index '', -1 + + it "can get indexes recursively", -> + it "can load facets", -> assert.are.equal 'hello', ts\load_facet '/hello', 'name', 'alpha' assert.are.equal 'world', ts\load_facet '/hello/world', 'name', 'alpha' @@ -89,7 +152,10 @@ test_store = (ts) -> ts\remove_fileder '/hello' assert.are.same {}, toseq ts\list_all_fileders! -describe "SQL spec", -> + it "can be closed", -> + ts\close! + +describe "SQL store", -> import SQLStore from require 'mmm.mmmfs.stores.sql' test_store SQLStore memory: true @@ -105,7 +171,7 @@ describe "FS store", -> assert os.remove root assert lfs.mkdir root - test_store LFSStore :root + test_store FSStore :root teardown -> assert lfs.rmdir root |
