aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2019-10-11 10:15:58 +0000
committers-ol <s-ol@users.noreply.github.com>2019-10-11 10:15:58 +0000
commite2a4257fc05d37822df2b7bbe0f587645375edf2 (patch)
treeb170a7323f4c080207dd681f66f70ee43fbc01ae
parentadd table to mmm/dom convert (diff)
downloadmmm-e2a4257fc05d37822df2b7bbe0f587645375edf2.tar.gz
mmm-e2a4257fc05d37822df2b7bbe0f587645375edf2.zip
fileders load via get_index rather than list_facets/list_fileders
-rw-r--r--build/server.moon8
-rw-r--r--mmm/init.client.moon6
-rw-r--r--mmm/init.server.moon6
-rw-r--r--mmm/mmmfs/fileder.moon34
-rw-r--r--mmm/mmmfs/stores/fs.moon20
-rw-r--r--mmm/mmmfs/stores/init.moon32
-rw-r--r--mmm/mmmfs/stores/sql.moon21
-rw-r--r--mmm/mmmfs/stores/web.moon46
-rw-r--r--spec/stores_spec.moon70
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