aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2018-11-01 10:17:55 +0000
committers-ol <s-ol@users.noreply.github.com>2018-11-01 10:17:55 +0000
commit30fb0dc40d595b9e0b7747ad8e5c4e8cf7e3023b (patch)
treedc56f20ec4d78115e15761c402589b5aec94ef55
parentdefer all scripts (diff)
downloadmmm-30fb0dc40d595b9e0b7747ad8e5c4e8cf7e3023b.tar.gz
mmm-30fb0dc40d595b9e0b7747ad8e5c4e8cf7e3023b.zip
move mmm code from lib to mmm etc
-rw-r--r--Tupfile10
-rw-r--r--app/init.moon158
-rw-r--r--app/test_component.moon212
-rw-r--r--app/todo.moon35
-rw-r--r--lib/duct_tape.server.moon130
-rw-r--r--mmm/canvasapp.client.moon (renamed from lib/canvasapp.client.moon)2
-rw-r--r--mmm/color.moon (renamed from lib/color.moon)0
-rw-r--r--mmm/component/init.client.moon (renamed from lib/component.client.moon)6
-rw-r--r--mmm/component/init.server.moon (renamed from lib/component.server.moon)9
-rw-r--r--mmm/dom/init.client.moon (renamed from lib/dom.client.moon)0
-rw-r--r--mmm/dom/init.server.moon (renamed from lib/dom.server.moon)2
-rw-r--r--mmm/init.client.moon (renamed from lib/init.client.moon)0
-rw-r--r--mmm/init.server.moon (renamed from lib/init.server.moon)14
-rw-r--r--mmm/mmmfs/browser.moon (renamed from lib/mmmfs/browser.moon)2
-rw-r--r--mmm/mmmfs/conversion.moon (renamed from lib/mmmfs/conversion.moon)4
-rw-r--r--mmm/mmmfs/fileder.moon (renamed from lib/mmmfs/fileder.moon)0
-rw-r--r--mmm/mmmfs/init.moon (renamed from lib/mmmfs/init.moon)26
-rw-r--r--mmm/ordered.moon (renamed from lib/ordered.moon)0
-rw-r--r--render.moon21
-rw-r--r--root/animations/init.moon4
-rw-r--r--root/animations/koch.moon6
-rw-r--r--root/animations/twisted.moon6
-rw-r--r--root/articles/init.moon4
-rw-r--r--root/articles/mmmfs/gallery.moon6
-rw-r--r--root/articles/mmmfs/init.moon8
-rw-r--r--root/articles/realities.moon4
-rw-r--r--root/experiments/center_of_mass.moon8
-rw-r--r--root/experiments/init.moon4
-rw-r--r--root/experiments/tags/init.moon6
-rw-r--r--root/init.moon7
-rw-r--r--root/meta/init.moon27
-rw-r--r--root/meta/test_component.moon224
-rw-r--r--root/meta/todo.moon42
-rw-r--r--tup.moon13
34 files changed, 373 insertions, 627 deletions
diff --git a/Tupfile b/Tupfile
index 7490dcf..370dfd9 100644
--- a/Tupfile
+++ b/Tupfile
@@ -11,14 +11,20 @@
# render stylesheet
: scss/main.scss |> !sassc |> dist/main.css
-preload lib
-preload lib/mmmfs
+# preload full mmmfs tree
preload root
preload root/animations
preload root/articles
preload root/articles/mmmfs
preload root/experiments
preload root/experiments/tags
+preload root/meta
+
+# preload all of mmm
+preload mmm
+preload mmm/dom
+preload mmm/mmmfs
+preload mmm/component
# render static content and compile sources
run moon tup.moon
diff --git a/app/init.moon b/app/init.moon
deleted file mode 100644
index 8bc95e3..0000000
--- a/app/init.moon
+++ /dev/null
@@ -1,158 +0,0 @@
-require = relative ...
-
-union = (...) -> with res = {}
- c = 1
- for i = 1, select '#', ...
- tbl = select i, ...
- for val in *tbl
- res[c] = val
- c += 1
-
-map = (f, list) -> [f val for val in *list]
-
-patch_redirs = ->
- redirs =
- 'center-of-mass': 'center_of_mass',
- 'test-component': 'test_component',
- 'play-tags': 'tags',
-
- { :location } = window
- if (not location.search\find '=') and #location.search > 1
- name = location.search\sub 2
- location.href = redirs[name] or name
-
-client_goto = ->
- { :location } = window
- if module = location.search\match 'client=([%w_]+)'
- document.body.innerHTML = ''
- require "app.#{module}"
-
-articles = {
- {
- name: 'realities'
- desc: 'exploring the nesting relationships of virtual and other realities'
- },
- {
- name: 'mmmfs'
- desc: 'a file and operating system to live in (wip)'
- },
-}
-
-animations = {
- {
- name: 'twisted'
- desc: 'pseudo 3d animation'
- },
- {
- name: 'koch'
- desc: "lil' fractal thing"
- },
-}
-
-experiments = {
- {
- name: 'center_of_mass'
- desc: 'aligning characters by their centers of mass'
- },
- {
- name: 'tags'
- desc: 'organizing files with Functional Tags'
- },
-}
-
-meta = {
- {
- name: 'todo'
- desc: 'Todo MVC with the mmm UI framework'
- },
- {
- name: 'test_component'
- desc: 'test suite for the mmm reactive UI framework'
- },
-}
-
-content = {
- { 'articles', articles }
- { 'animations', animations }
- { 'experiments', experiments }
- { 'meta', meta }
-}
-
-index = {
- name: 'index'
- route: ''
- dest: 'index.html'
- render: =>
- import h1, h3, div, b, p, a, br, ul, tt, li, img from require 'lib.dom'
- import opairs from require 'lib.ordered'
-
- moon = '\xe2\x98\xbd'
-
- -- redirects for old-style URIs
- on_client patch_redirs
-
- iconlink = (href, src, alt, style) -> a {
- class: 'iconlink',
- :href,
- target: '_blank',
- img :src, :alt, :style
- }
-
- -- menu
- append h1 {
- style: {
- position: 'relative',
- 'border-bottom': '1px solid #000'
- },
- 'mmm',
- div {
- class: 'icons',
- iconlink 'https://github.com/s-ol/mmm', 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/github.svg',
- iconlink 'https://twitter.com/S0lll0s', 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/twitter.svg',
- iconlink 'https://webring.xxiivv.com/#random', 'https://webring.xxiivv.com/icon.black.svg', 'webring',
- { height: '0.9em', 'margin-left': '.04em' }
- }
- }
-
- append p {
- tt 'mmm'
- ' is not the '
- tt 'www'
- ', because it runs on '
- a { 'MoonScript', href: 'https://moonscript.org' }
- '.'
- br!
- 'You can find the source code of everything '
- a { 'here', href: 'https://github.com/s-ol/mmm' }
- '.'
- }
-
- for { category, routes } in *content
- append h3 category, style: { 'margin-bottom': '-.5em' }
- append ul for { :name, :desc, :route } in *routes
- li (a name, href: route), ': ', desc
-
- append p {
- "made with #{moon} by "
- a { 's-ol', href: 'https://twitter.com/S0lll0s' }
- }
-
- on_client client_goto
-}
-
-load = (module) -> require "app.#{module}"
-
-destify = (route) -> with route
- .route or= .name
- .dest or= "#{.route}/index.html"
-
- if .render == 'client'
- .render = -> on_client load, .name
- .render or= -> require '.' .. .name
-
-routes = map destify, union articles, animations, experiments, meta, { index }
-{
- :routes,
- indexed: { r.name, r for r in *routes }
- render: (name) -> require ".#{name}"
-}
diff --git a/app/test_component.moon b/app/test_component.moon
deleted file mode 100644
index d3f1489..0000000
--- a/app/test_component.moon
+++ /dev/null
@@ -1,212 +0,0 @@
-on_client ->
- import div, h1, ul, li, pre from require 'lib.dom'
-
- last = nil
- test_group = (name) ->
- if last
- append div (h1 name), ul last
-
- last = {}
- (name, test) ->
- ok, err = pcall test
- table.insert last, li if ok
- "passed '#{name}'"
- else
- "failed '#{name}'", pre err
-
- expect = (expected, note, ...) ->
- ok, msg = pcall ...
- print ok, msg\find expected
- if ok or not msg\find expected
- error note
-
- run_test = test_group 'component.moon'
-
- local ReactiveVar, ReactiveElement
- run_test "exports ReactiveVar, ReactiveElement", ->
- import ReactiveVar, ReactiveElement from require 'lib.component'
- assert ReactiveVar, "ReactiveVar not exported"
- assert ReactiveElement, "ReactiveElement not exported"
-
- run_test "exports tohtml helper", ->
- import tohtml from require 'lib.component'
- assert 'function' == (type tohtml), "tohtml not exported"
-
- run_test "exports append helper", ->
- import append from require 'lib.component'
- assert 'function' == (type append), "append not exported"
-
- run_test "exports text helper", ->
- import text from require 'lib.component'
- assert 'function' == (type text), "text not exported"
-
- node = text 'a test string'
- assert (js.instanceof node, js.global.Node), "expected text to generate a Node"
- assert node.data == 'a test string', "expected text to store the string"
-
- run_test "text joins multiple arguments", ->
- import text from require 'lib.component'
-
- node = text 'a', 'test', 'string'
- assert node.data == 'a test string', "expected text to join arguments with spaces"
-
- run_test "exports elements table", ->
- import elements from require 'lib.component'
-
- assert (type elements.div!) == 'table', "expected to build element with elements.div!"
- assert (type elements.madeup!) == 'table', "expected to build element with elements.madeup!"
-
- run_test = test_group 'ReactiveVar'
-
- run_test "stores a value", ->
- reactive = ReactiveVar 'test'
- assert 'test' == reactive\get!, "expected x to be 'test'"
-
- run_test "propagates updates", ->
- local done
-
- reactive = ReactiveVar 'test'
- reactive\subscribe coroutine.wrap (next) ->
- assert next == 'toast', "expected next to be 'toast'"
- assert coroutine.yield! == 'cheese', "expected next to be 'cheese'"
- done = true
-
- reactive\set 'toast'
- assert 'toast' == reactive\get!, "expected #get to return 'toast'"
- reactive\set 'cheese'
- assert done, "expected to reach the end"
-
- run_test "passed old value as well", ->
- local done
-
- reactive = ReactiveVar 1
- reactive\subscribe coroutine.wrap (next, last) ->
- assert last == 1, "expected last:1 to be 1"
- next, last = coroutine.yield!
- assert last == 2, "expected last:2 to be 2"
- done = true
-
- reactive\set 2
- reactive\set 3
- assert done, "expected to reach the end"
-
- run_test "provides transform shorthand", ->
- local done
-
- reactive = ReactiveVar 1
- reactive\subscribe coroutine.wrap (next, last) ->
- assert last == 1, "expected last:1 to be 1"
- next, last = coroutine.yield!
- assert last == 2, "expected last:2 to be 2"
- done = true
-
- add_one = (a) -> a + 1
- reactive\transform add_one
- reactive\transform add_one
- assert done, "expected to reach the end"
-
- run_test "#subscribe returns function to unsubscribe", ->
- calls = 0
-
- reactive = ReactiveVar 1
- unsub = reactive\subscribe coroutine.wrap () ->
- calls += 1
- coroutine.yield!
- calls += 1
- coroutine.yield!
- calls += 1
-
- assert 'function' == (type unsub), "expected to receive a function"
-
- reactive\set 2
- reactive\set 3
- assert calls == 2, "wat"
-
- unsub!
- reactive\set 4
- assert calls == 2, "expected to stop receiving updates"
-
- run_test "tracks multiple subscriptions at once", ->
- reactive = ReactiveVar 'test'
- unsub = reactive\subscribe coroutine.wrap (next) ->
- assert next == 'toast', "expected next to be toast"
- next = coroutine.yield!
- assert next == 'cheese', "expected next to be cheese"
- coroutine.yield!
- error "expected not to get here"
-
- reactive\set 'toast'
-
- local done
- reactive\subscribe coroutine.wrap (next) ->
- assert next == 'cheese', "expected next to be cheese"
- next = coroutine.yield!
- assert next == 'test', "expected next to be test"
- done = true
-
- reactive\set 'cheese'
- unsub!
- reactive\set 'test'
- assert done, "expected to reach the end"
-
- run_test = test_group 'ReactiveElement'
-
- run_test "creates a HTML element", ->
- elem = ReactiveElement 'span'
- assert elem.node and elem.node.localName == 'span', "expected Node to be a <span>"
-
- run_test "sets attributes from a table arg", ->
- elem = ReactiveElement 'span', class: 'never'
- assert elem.node.class == 'never', "expected class to be 'never'"
-
- run_test "appends Nodes from arguments", ->
- e_div, e_pre = div!, pre!
- elem = ReactiveElement 'span', e_div, e_pre
- assert elem.node.firstElementChild == e_div, "expected div to be the first child of elem"
- assert elem.node.lastElementChild == e_pre, "expected pre to be the last child of elem"
-
- run_test "can append ReactiveElements and text", ->
- e_div = ReactiveElement 'div'
- elem = ReactiveElement 'div', e_div, 'testtext'
- assert elem.node.firstElementChild == e_div.node, "expected div to be the first child of elem"
- assert elem.node.lastChild.data == 'testtext', "expected last child of elem to be 'testtext'"
-
- run_test "accepts attributes after children", ->
- e_div = div!
- elem = ReactiveElement 'div', e_div, class: 'test'
- assert elem.node.firstElementChild == e_div, "expected div to be the first child of elem"
- assert elem.node.class == 'test', "expected class to be 'test'"
-
- run_test "allows mixing attributes and children in a single table", ->
- e_div, e_pre = div!, pre!
- elem = ReactiveElement 'div', { class: 'test', e_div, e_pre }
- assert elem.node.firstElementChild == e_div, "expected div to be the first child of elem"
- assert elem.node.lastElementChild == e_pre, "expected pre to be the last child of elem"
- assert elem.node.class == 'test', "expected class to be 'test'"
-
- run_test "can unwrap and track attributes from ReactiveVars", ->
- klass = ReactiveVar 'test'
- elem = ReactiveElement 'div', class: klass
- assert elem.node.class == 'test', "expected class to be 'test'"
- klass\set 'toast'
- assert elem.node.class == 'toast', "expected class to be 'toast'"
-
- run_test "can unwrap and track children from ReactiveVars", ->
- child = ReactiveVar h1 'test'
- elem = ReactiveElement 'div', child, pre 'fixed'
- assert elem.node.firstElementChild.localName == 'h1', "expected first child to be h1"
- assert elem.node.childElementCount == 2, "expected node to have two children"
- child\set div 'toast'
- assert elem.node.firstElementChild.localName == 'div', "expected first child to be div"
- assert elem.node.childElementCount == 2, "expected node to have two children"
-
- run_test "warns when appending a string from a ReactiveVar", ->
- import text from require 'lib.component'
-
- str = ReactiveVar 'test'
- elem = ReactiveElement 'div', str
- expect 'cannot replace string node', 'expected error', str\set, 'string too'
- elem\destroy!
-
- elem = ReactiveElement 'div', str\map text
- str\set 'this is text'
diff --git a/app/todo.moon b/app/todo.moon
deleted file mode 100644
index f2baa50..0000000
--- a/app/todo.moon
+++ /dev/null
@@ -1,35 +0,0 @@
-on_client ->
- import ReactiveVar, append, text, elements from require 'lib.component'
- import div, form, span, h3, a, input, textarea, button from elements
-
- parent = div!
- todoItem = (desc, done) ->
- -- convert into reactive data sources
- desc, done = (ReactiveVar desc), ReactiveVar done
- with me = div style:
- margin: '8px'
- padding: '8px'
- background: '#eeeeee'
- \append h3 (desc\map text), style: 'margin: 0;'
- \append span done\map (done) -> text if done then 'done' else 'not done yet'
- \append input type: 'checkbox', checked: done, onchange: (e) => done\set e.target.checked
- \append a (text 'delete'), href: '#', onclick: (e) => parent\remove me
-
- parent\append todoItem 'write a Component System'
- parent\append todoItem 'eat Lasagna', true
-
- desc = ReactiveVar 'start'
- form = with form {
- action: ''
- style:
- margin: '2px'
- onsubmit: (e) =>
- e\preventDefault!
- parent\append todoItem desc\get!
- desc\set ''
- }
- \append input type: 'text', value: desc, onchange: (e) => desc\set e.target.value
- \append input type: 'submit', value: 'add'
-
- append parent
- append form
diff --git a/lib/duct_tape.server.moon b/lib/duct_tape.server.moon
deleted file mode 100644
index b019ac8..0000000
--- a/lib/duct_tape.server.moon
+++ /dev/null
@@ -1,130 +0,0 @@
-package.noompath = './?.moon;./?/init.moon'
-
-export __FNDEF_NOOM_CACHE
-__FNDEF_NOOM_CACHE = setmetatable {}, __mode: 'k'
-
-assert MODE == 'SERVER', "duct_tape only works on the server"
-
-compile = require 'moonscript.compile'
-parse = require 'moonscript.parse'
-
-import smart_node, build from require 'moonscript.types'
-import dirsep from require 'moonscript.base'
-import get_options, unpack from require 'moonscript.util'
-
-line_tables = require 'moonscript.line_tables'
-lua = :loadstring, :load
-
-local *
-
-escape_str = (str) -> (str\gsub('\\', '\\\\')\gsub '"', '\\"'), nil
-
-deep_clone = (value) ->
- if 'table' == type value
- { deep_clone(k), deep_clone(v) for k,v in pairs value }
- else -- number, string, boolean, etc
- value
-
-transform_fndef = (fndef, parent, i) ->
- -- compile the function to Lua separately
- code, ltable, pos = compile.tree { deep_clone fndef }
- if not code
- return compile.format_error(ltable, pos, text)
-
- code = "(function() #{code} end)()"
-
- -- assign the lua code to __FNDEF_NOOM_CACHE[function] so it can be retrieved by `compile`
- fn = -> { 'ref', 'fn' }
- cache = build.chain {
- base: '__FNDEF_NOOM_CACHE',
- { 'index', fn! }
- }
-
- parent[i] = build.do {
- { 'declare_with_shadows', { 'fn' } }
- build.assign_one fn!, fndef
- build.assign_one cache, { 'string', '"', escape_str code }
- -- build.assign_one cache, { 'string', '[[', code }
- fn!
- }
-
- nil
-
-find_fndefs = (node, p, i) ->
- if node[1] == "fndef"
- transform_fndef node, p, i
- else
- for i = 1,#node
- v = node[i]
- find_fndefs v, node, i if 'table' == type v
-
-to_lua = (text, options={}) ->
- if "string" != type text
- t = type text
- return nil, "expecting string (got ".. t ..")"
-
- tree, err = parse.string text
- if not tree
- return nil, err
-
- find_fndefs tree
-
- code, ltable, pos = compile.tree tree, options
- if not code
- return nil, compile.format_error(ltable, pos, text)
-
- code, ltable
-
-noom_loader = (name, ...) ->
- name_path = name\gsub "%.", dirsep
-
- local file, file_path
- for path in package.noompath\gmatch "[^;]+"
- file_path = path\gsub "?", name_path
- file = io.open file_path
- break if file
-
- if file
- text = file\read "*a"
- file\close!
- res, err = loadstring text, "@#{file_path}"
- if not res
- error file_path .. ": " .. err
-
- return res
-
- return nil, "Could not find noom file"
-
-loadstring = (...) ->
- options, str, chunk_name, mode, env = get_options ...
- chunk_name or= "=(noom.loadstring)"
-
- code, ltable_or_err = to_lua str, options
- unless code
- return nil, ltable_or_err
-
- line_tables[chunk_name] = ltable_or_err if chunk_name
-
- -- the unpack prevents us from passing nil
- (lua.loadstring or lua.load) code, chunk_name, unpack { mode, env }
-
-do
- local compile
- insert_loader = (pos=2) ->
- -- if not package.moonpath
- -- package.moonpath = create_moonpath package.path
-
- loaders = package.loaders or package.searchers
- for loader in *loaders
- return false if loader == noom_loader
-
- table.insert loaders, pos, noom_loader
- true
-
- compile = (fn) -> with code = __FNDEF_NOOM_CACHE[fn]
- assert code, 'cannot compile function not loaded from noomscript source.'
-
- {
- :insert_loader
- :compile
- }
diff --git a/lib/canvasapp.client.moon b/mmm/canvasapp.client.moon
index 71ffa59..40f2423 100644
--- a/lib/canvasapp.client.moon
+++ b/mmm/canvasapp.client.moon
@@ -1,7 +1,7 @@
window = js.global
js = require 'js'
-import a, canvas, div, button, script from require 'lib.dom'
+import a, canvas, div, button, script from require 'mmm.dom'
class CanvasApp
width: 500
diff --git a/lib/color.moon b/mmm/color.moon
index 6233b47..6233b47 100644
--- a/lib/color.moon
+++ b/mmm/color.moon
diff --git a/lib/component.client.moon b/mmm/component/init.client.moon
index ffeb084..193fd94 100644
--- a/lib/component.client.moon
+++ b/mmm/component/init.client.moon
@@ -16,11 +16,6 @@ tohtml = (val) ->
else
error "not a Node: #{val}, #{type val}"
--- overloaded append
--- see tohtml for acceptable values
-g_append = append
-append = (value) -> g_append tohtml value
-
-- shorthand to form a text node from strings
text = (...) -> document\createTextNode table.concat { ... }, ' '
@@ -152,7 +147,6 @@ elements = setmetatable {}, __index: (name) =>
:get_or_create,
-- :join,
:tohtml,
- :append,
:text,
:elements,
}
diff --git a/lib/component.server.moon b/mmm/component/init.server.moon
index 0026d32..b84b8d5 100644
--- a/lib/component.server.moon
+++ b/mmm/component/init.server.moon
@@ -1,4 +1,4 @@
-import opairs from require 'lib.ordered'
+import opairs from require 'mmm.ordered'
void_tags = { 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr' }
void_tags = { t,t for t in *void_tags }
@@ -16,11 +16,6 @@ tohtml = (val) ->
else
error "not a Node: #{val}, #{type val}"
--- overloaded append
--- see tohtml for acceptable values
-g_append = append
-append = (value) -> g_append tohtml value
-
-- shorthand to form a text node from strings
text = (...) -> table.concat { ... }, ' '
@@ -123,8 +118,6 @@ get_or_create = (elem, id, ...) ->
:ReactiveElement,
:get_or_create,
:tohtml,
- :flush,
- :append,
:text,
:elements,
}
diff --git a/lib/dom.client.moon b/mmm/dom/init.client.moon
index acdbfa4..acdbfa4 100644
--- a/lib/dom.client.moon
+++ b/mmm/dom/init.client.moon
diff --git a/lib/dom.server.moon b/mmm/dom/init.server.moon
index fe6b60c..b0a8c85 100644
--- a/lib/dom.server.moon
+++ b/mmm/dom/init.server.moon
@@ -1,4 +1,4 @@
-import opairs from require 'lib.ordered'
+import opairs from require 'mmm.ordered'
void_tags = { 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr' }
void_tags = { t,t for t in *void_tags }
diff --git a/lib/init.client.moon b/mmm/init.client.moon
index 144543b..144543b 100644
--- a/lib/init.client.moon
+++ b/mmm/init.client.moon
diff --git a/lib/init.server.moon b/mmm/init.server.moon
index cc3851d..f87596e 100644
--- a/lib/init.server.moon
+++ b/mmm/init.server.moon
@@ -38,20 +38,6 @@ relative = do
name = base .. name if '.' == name\sub 1, 1
_require name
-import compile, insert_loader from require 'lib.duct_tape'
-insert_loader!
-
-on_client = (fn, ...) ->
- args = {...}
- -- warn code
- "<script type=\"application/lua\">
- local fn = #{compile fn}
- on_load = on_load or {}
- table.insert(on_load, function()
- fn(#{table.concat [string.format '%q', v for v in *args ], ', '})
- end)
- </script>"
-
{
-- access / flush the appended data
flush: ->
diff --git a/lib/mmmfs/browser.moon b/mmm/mmmfs/browser.moon
index ce7709f..b057573 100644
--- a/lib/mmmfs/browser.moon
+++ b/mmm/mmmfs/browser.moon
@@ -1,7 +1,7 @@
require = relative ..., 1
import Key from require '.fileder'
import get_conversions from require '.conversion'
-import ReactiveVar, get_or_create, text, elements from require 'lib.component'
+import ReactiveVar, get_or_create, text, elements from require 'mmm.component'
import div, span, a, select, option from elements
class Browser
diff --git a/lib/mmmfs/conversion.moon b/mmm/mmmfs/conversion.moon
index 7f86aa4..5fdb4c2 100644
--- a/lib/mmmfs/conversion.moon
+++ b/mmm/mmmfs/conversion.moon
@@ -1,5 +1,5 @@
-import text, code from require 'lib.dom'
-import tohtml from require 'lib.component'
+import text, code from require 'mmm.dom'
+import tohtml from require 'mmm.component'
-- limit function to one argument
single = (func) -> (val) -> func val
diff --git a/lib/mmmfs/fileder.moon b/mmm/mmmfs/fileder.moon
index c3e40f7..c3e40f7 100644
--- a/lib/mmmfs/fileder.moon
+++ b/mmm/mmmfs/fileder.moon
diff --git a/lib/mmmfs/init.moon b/mmm/mmmfs/init.moon
index d0de45b..52d5da8 100644
--- a/lib/mmmfs/init.moon
+++ b/mmm/mmmfs/init.moon
@@ -1,7 +1,7 @@
require = relative ...
import Key, Fileder from require '.fileder'
import Browser from require '.browser'
-import tohtml from require 'lib.component'
+import tohtml from require 'mmm.component'
define_fileders = (...) ->
source_module = ...
@@ -10,24 +10,30 @@ define_fileders = (...) ->
with fileder = Fileder ...
.source_module = source_module
-rehydrate = (path) ->
- import Browser from require 'lib.mmmfs.browser'
- root = require 'root'
- root\mount!
-
- export BROWSER
- BROWSER = Browser root, path, true
-
render = (root, path) ->
export BROWSER
BROWSER = Browser root, path
content = tohtml BROWSER
- content, on_client rehydrate, path
+
+ rehydrate = "
+<script type=\"application/lua\">
+ on_load = on_load or {}
+ table.insert(on_load, function()
+ local path = #{string.format '%q', path}
+ local browser = require 'mmm.mmmfs.browser'
+ local root = require 'root'
+ root:mount()
+
+ BROWSER = browser.Browser(root, path, true)
+ end)
+</script>"
+ content, rehydrate
{
:Key
:Fileder
+ :Browser
:render
:define_fileders
:module_roots
diff --git a/lib/ordered.moon b/mmm/ordered.moon
index 59c07bf..59c07bf 100644
--- a/lib/ordered.moon
+++ b/mmm/ordered.moon
diff --git a/render.moon b/render.moon
index 1246999..8098ba7 100644
--- a/render.moon
+++ b/render.moon
@@ -1,13 +1,11 @@
-package.moonpath = './?.server.moon;' .. package.moonpath
-import flush from require 'lib.init'
-import render from require 'lib.mmmfs'
+package.moonpath = './?.server.moon;./?/init.server.moon;' .. package.moonpath
+import flush from require 'mmm.init'
+import render from require 'mmm.mmmfs'
-- usage:
-- moon render.moon <output> <fileder_path> [<prefix module> <prefix path>]
-
{ output_name, path, prefix_mod, prefix_path } = arg
--- output_name = assert arg[1], "please specify the output filename as an argument"
--- path = assert arg[2], "please specify the path name to build as an argument"
+
assert output_name, "please specify the output filename as an argument"
assert path, "please specify the path name to build as an argument"
@@ -32,10 +30,11 @@ with io.open output_name, 'w'
<title>MMM: lunar low-gravity scripting playground</title>
<link rel=\"stylesheet\" type=\"text/css\" href=\"/main.css\" />
<!--
- <link rel=\"preload\" as=\"fetch\" href=\"/lib/dom.lua\" />
- <link rel=\"preload\" as=\"fetch\" href=\"/lib/mmmfs/init.lua\" />
- <link rel=\"preload\" as=\"fetch\" href=\"/lib/mmmfs/fileder.lua\" />
- <link rel=\"preload\" as=\"fetch\" href=\"/lib/mmmfs/browser.lua\" />
+ <link rel=\"preload\" as=\"fetch\" href=\"/mmm/dom/init.lua\" />
+ <link rel=\"preload\" as=\"fetch\" href=\"/mmm/component/init.lua\" />
+ <link rel=\"preload\" as=\"fetch\" href=\"/mmm/mmmfs/init.lua\" />
+ <link rel=\"preload\" as=\"fetch\" href=\"/mmm/mmmfs/fileder.lua\" />
+ <link rel=\"preload\" as=\"fetch\" href=\"/mmm/mmmfs/browser.lua\" />
-->
</head>
<body>
@@ -45,7 +44,7 @@ with io.open output_name, 'w'
<script defer src=\"/highlight.pack.js\"></script>
<script defer src=\"//cdnjs.cloudflare.com/ajax/libs/marked/0.5.1/marked.min.js\"></script>
<script defer src=\"//cdnjs.cloudflare.com/ajax/libs/svg.js/2.6.6/svg.min.js\"></script>
- <script defer type=\"application/lua\" src=\"/lib/init.lua\"></script>
+ <script defer type=\"application/lua\" src=\"/mmm/init.lua\"></script>
#{rehydrate}
</body>
diff --git a/root/animations/init.moon b/root/animations/init.moon
index ba8cb91..c968cfd 100644
--- a/root/animations/init.moon
+++ b/root/animations/init.moon
@@ -1,5 +1,5 @@
-import div, h3, ul, li, a from require 'lib.dom'
-import define_fileders from require 'lib.mmmfs'
+import div, h3, ul, li, a from require 'mmm.dom'
+import define_fileders from require 'mmm.mmmfs'
Fileder = define_fileders ...
require = relative ...
diff --git a/root/animations/koch.moon b/root/animations/koch.moon
index 9b8217d..4d16b8a 100644
--- a/root/animations/koch.moon
+++ b/root/animations/koch.moon
@@ -1,4 +1,4 @@
-import define_fileders from require 'lib.mmmfs'
+import define_fileders from require 'mmm.mmmfs'
Fileder = define_fileders ...
with Fileder {
@@ -9,8 +9,8 @@ with Fileder {
if MODE == 'CLIENT'
Math = window.Math
- import CanvasApp from require 'lib.canvasapp'
- import hsl from require 'lib.color'
+ import CanvasApp from require 'mmm.canvasapp'
+ import hsl from require 'mmm.color'
class KochDemo extends CanvasApp
width: 600
diff --git a/root/animations/twisted.moon b/root/animations/twisted.moon
index 9e97738..68bdac6 100644
--- a/root/animations/twisted.moon
+++ b/root/animations/twisted.moon
@@ -1,4 +1,4 @@
-import define_fileders from require 'lib.mmmfs'
+import define_fileders from require 'mmm.mmmfs'
Fileder = define_fileders ...
with Fileder {
@@ -7,8 +7,8 @@ with Fileder {
}
if MODE == 'CLIENT'
- import CanvasApp from require 'lib.canvasapp'
- import hsl from require 'lib.color'
+ import CanvasApp from require 'mmm.canvasapp'
+ import hsl from require 'mmm.color'
Math = window.Math
diff --git a/root/articles/init.moon b/root/articles/init.moon
index b706f7c..483aa32 100644
--- a/root/articles/init.moon
+++ b/root/articles/init.moon
@@ -1,5 +1,5 @@
-import div, h3, ul, li, a from require 'lib.dom'
-import define_fileders from require 'lib.mmmfs'
+import div, h3, ul, li, a from require 'mmm.dom'
+import define_fileders from require 'mmm.mmmfs'
Fileder = define_fileders ...
require = relative ...
diff --git a/root/articles/mmmfs/gallery.moon b/root/articles/mmmfs/gallery.moon
index e132f42..3abad43 100644
--- a/root/articles/mmmfs/gallery.moon
+++ b/root/articles/mmmfs/gallery.moon
@@ -1,5 +1,5 @@
-import define_fileders from require 'lib.mmmfs'
-import div, h1, a, img, br from require 'lib.dom'
+import define_fileders from require 'mmm.mmmfs'
+import div, h1, a, img, br from require 'mmm.dom'
Fileder = define_fileders ...
@@ -23,7 +23,7 @@ with Fileder {
div content
'slideshow: moon -> mmm/dom': =>
- import ReactiveVar, text, elements from require 'lib.component'
+ import ReactiveVar, text, elements from require 'mmm.component'
index = ReactiveVar 1
diff --git a/root/articles/mmmfs/init.moon b/root/articles/mmmfs/init.moon
index 2b3ef5e..8b1ce01 100644
--- a/root/articles/mmmfs/init.moon
+++ b/root/articles/mmmfs/init.moon
@@ -1,4 +1,4 @@
-import define_fileders from require 'lib.mmmfs'
+import define_fileders from require 'mmm.mmmfs'
Fileder = define_fileders ...
require = relative ...
@@ -11,7 +11,7 @@ Fileder {
-- uses the 'moon ->' conversion to execute the lua/pre moon function on get
-- resolves to a value of type mmm/dom
'moon -> mmm/dom': () =>
- html = require 'lib.dom'
+ html = require 'mmm.dom'
import article, h1, h2, h3, p, div, a, sup, ol, li, span, code, pre, br from html
moon = if MODE == 'SERVER'
@@ -235,7 +235,7 @@ Fileder {
'title: text/plain': "Hey I'm like a link to picture or smth",
'URL -> image/png': 'https://picsum.photos/200?random',
'preview: moon -> mmm/dom': =>
- import img from require 'lib.dom'
+ import img from require 'mmm.dom'
img src: @gett 'URL -> image/png' -- look for main content with 'URL to png' type
}
]]
@@ -264,7 +264,7 @@ If you are reading this in the source, then c'mon, just scroll past and give me
-- preview is a lua/pre moon function that neturns an mmm/dom value
'preview: moon -> mmm/dom': =>
- import img from require 'lib.dom'
+ import img from require 'mmm.dom'
img src: @gett 'URL -> image/png' -- look for main content with 'URL to png' type
}
diff --git a/root/articles/realities.moon b/root/articles/realities.moon
index 05c0c03..78d7bae 100644
--- a/root/articles/realities.moon
+++ b/root/articles/realities.moon
@@ -1,11 +1,11 @@
-import define_fileders from require 'lib.mmmfs'
+import define_fileders from require 'mmm.mmmfs'
Fileder = define_fileders ...
Fileder {
'name: alpha': 'realities'
'description: text/plain': 'exploring the nesting relationships of virtual and other realities'
'moon -> mmm/component': =>
- import elements from require 'lib.component'
+ import elements from require 'mmm.component'
import h1, h2, p, a, i, div, ol, li, br, hr, span, button, section, article from elements
_content = div!
diff --git a/root/experiments/center_of_mass.moon b/root/experiments/center_of_mass.moon
index 641fc5a..3d0e924 100644
--- a/root/experiments/center_of_mass.moon
+++ b/root/experiments/center_of_mass.moon
@@ -1,4 +1,4 @@
-import define_fileders from require 'lib.mmmfs'
+import define_fileders from require 'mmm.mmmfs'
Fileder = define_fileders ...
with Fileder {
@@ -7,9 +7,9 @@ with Fileder {
}
if MODE == 'CLIENT'
- import CanvasApp from require 'lib.canvasapp'
- import rgb from require 'lib.color'
- import article, h1, p, div, span, input, button from require 'lib.dom'
+ import CanvasApp from require 'mmm.canvasapp'
+ import rgb from require 'mmm.color'
+ import article, h1, p, div, span, input, button from require 'mmm.dom'
fast = true
center = true
diff --git a/root/experiments/init.moon b/root/experiments/init.moon
index d9f4938..65f3852 100644
--- a/root/experiments/init.moon
+++ b/root/experiments/init.moon
@@ -1,5 +1,5 @@
-import div, h3, ul, li, a from require 'lib.dom'
-import define_fileders from require 'lib.mmmfs'
+import div, h3, ul, li, a from require 'mmm.dom'
+import define_fileders from require 'mmm.mmmfs'
Fileder = define_fileders ...
require = relative ...
diff --git a/root/experiments/tags/init.moon b/root/experiments/tags/init.moon
index f113e74..611d722 100644
--- a/root/experiments/tags/init.moon
+++ b/root/experiments/tags/init.moon
@@ -1,5 +1,5 @@
-import div, h3, ul, li, a from require 'lib.dom'
-import define_fileders from require 'lib.mmmfs'
+import div, h3, ul, li, a from require 'mmm.dom'
+import define_fileders from require 'mmm.mmmfs'
Fileder = define_fileders ...
require = relative ...
@@ -8,7 +8,7 @@ Fileder {
'description: text/plain': 'defining toggles, categories etc. with only tags and functional hooks',
'moon -> mmm/component': if MODE == 'CLIENT' then =>
import add_tag, rmv_tag, Node, Hierarchy, Toggle, NamespacedToggle from require '.tags'
- import ReactiveVar, tohtml, text, elements from require 'lib.component'
+ import ReactiveVar, tohtml, text, elements from require 'mmm.component'
import article, div, form, span, h3, a, input, textarea, button from elements
clone = (set) ->
diff --git a/root/init.moon b/root/init.moon
index a2eab3b..8639f50 100644
--- a/root/init.moon
+++ b/root/init.moon
@@ -1,12 +1,12 @@
-import define_fileders from require 'lib.mmmfs'
+import define_fileders from require 'mmm.mmmfs'
Fileder = define_fileders ...
require = relative ...
Fileder {
'name: alpha': '',
'moon -> mmm/dom': =>
- import article, h1, h3, div, b, p, a, br, ul, tt, li, img from require 'lib.dom'
- import opairs from require 'lib.ordered'
+ import article, h1, h3, div, b, p, a, br, ul, tt, li, img from require 'mmm.dom'
+ import opairs from require 'mmm.ordered'
append, finish = do
content = {}
@@ -65,4 +65,5 @@ Fileder {
require '.articles'
require '.animations'
require '.experiments'
+ require '.meta'
}
diff --git a/root/meta/init.moon b/root/meta/init.moon
new file mode 100644
index 0000000..cd2baed
--- /dev/null
+++ b/root/meta/init.moon
@@ -0,0 +1,27 @@
+import div, h3, ul, li, a from require 'mmm.dom'
+import define_fileders from require 'mmm.mmmfs'
+Fileder = define_fileders ...
+require = relative ...
+
+Fileder {
+ 'name: alpha': 'meta',
+ 'title: text/plain': 'about mmm',
+ 'moon -> mmm/dom': (path) => div {
+ h3 @gett 'title: text/plain', style: { 'margin-bottom': '-.5em' },
+ ul for child in *@children
+ name = child\gett 'name: alpha'
+ desc = child\gett 'description: text/plain'
+ li {
+ a name, {
+ href: child.path,
+ onclick: (e) =>
+ e\preventDefault!
+ BROWSER\navigate child.path
+ },
+ ': ', desc
+ }
+ }
+
+ require '.todo'
+ require '.test_component'
+}
diff --git a/root/meta/test_component.moon b/root/meta/test_component.moon
new file mode 100644
index 0000000..c1c766e
--- /dev/null
+++ b/root/meta/test_component.moon
@@ -0,0 +1,224 @@
+import define_fileders from require 'mmm.mmmfs'
+Fileder = define_fileders ...
+
+Fileder {
+ 'name: alpha': 'mmm.component_test'
+ 'description: text/plain': 'Tests for mmm.component'
+ 'moon -> mmm/dom': =>
+ import article, div, h1, ul, li, pre from require 'mmm.dom'
+
+ _content = {}
+ append = (stuff) -> table.insert _content, stuff
+
+ last = nil
+ test_group = (name) ->
+ if last
+ append div (h1 name), ul last
+
+ last = {}
+ (name, test) ->
+ ok, err = pcall test
+ table.insert last, li if ok
+ "passed '#{name}'"
+ else
+ "failed '#{name}'", pre err
+
+ expect = (expected, note, ...) ->
+ ok, msg = pcall ...
+ print ok, msg\find expected
+ if ok or not msg\find expected
+ error note
+
+ run_test = test_group 'component.moon'
+
+ local ReactiveVar, ReactiveElement
+ run_test "exports ReactiveVar, ReactiveElement", ->
+ import ReactiveVar, ReactiveElement from require 'mmm.component'
+ assert ReactiveVar, "ReactiveVar not exported"
+ assert ReactiveElement, "ReactiveElement not exported"
+
+ run_test "exports tohtml helper", ->
+ import tohtml from require 'mmm.component'
+ assert 'function' == (type tohtml), "tohtml not exported"
+
+ -- @TODO: get_or_create
+
+ run_test "exports text helper", ->
+ import text from require 'mmm.component'
+ assert 'function' == (type text), "text not exported"
+
+ node = text 'a test string'
+ assert (js.instanceof node, js.global.Node), "expected text to generate a Node"
+ assert node.data == 'a test string', "expected text to store the string"
+
+ run_test "text joins multiple arguments", ->
+ import text from require 'mmm.component'
+
+ node = text 'a', 'test', 'string'
+ assert node.data == 'a test string', "expected text to join arguments with spaces"
+
+ run_test "exports elements table", ->
+ import elements from require 'mmm.component'
+
+ assert (type elements.div!) == 'table', "expected to build element with elements.div!"
+ assert (type elements.madeup!) == 'table', "expected to build element with elements.madeup!"
+
+ run_test = test_group 'ReactiveVar'
+
+ run_test "stores a value", ->
+ reactive = ReactiveVar 'test'
+ assert 'test' == reactive\get!, "expected x to be 'test'"
+
+ run_test "propagates updates", ->
+ local done
+
+ reactive = ReactiveVar 'test'
+ reactive\subscribe coroutine.wrap (next) ->
+ assert next == 'toast', "expected next to be 'toast'"
+ assert coroutine.yield! == 'cheese', "expected next to be 'cheese'"
+ done = true
+
+ reactive\set 'toast'
+ assert 'toast' == reactive\get!, "expected #get to return 'toast'"
+ reactive\set 'cheese'
+ assert done, "expected to reach the end"
+
+ run_test "passed old value as well", ->
+ local done
+
+ reactive = ReactiveVar 1
+ reactive\subscribe coroutine.wrap (next, last) ->
+ assert last == 1, "expected last:1 to be 1"
+ next, last = coroutine.yield!
+ assert last == 2, "expected last:2 to be 2"
+ done = true
+
+ reactive\set 2
+ reactive\set 3
+ assert done, "expected to reach the end"
+
+ run_test "provides transform shorthand", ->
+ local done
+
+ reactive = ReactiveVar 1
+ reactive\subscribe coroutine.wrap (next, last) ->
+ assert last == 1, "expected last:1 to be 1"
+ next, last = coroutine.yield!
+ assert last == 2, "expected last:2 to be 2"
+ done = true
+
+ add_one = (a) -> a + 1
+ reactive\transform add_one
+ reactive\transform add_one
+ assert done, "expected to reach the end"
+
+ run_test "#subscribe returns function to unsubscribe", ->
+ calls = 0
+
+ reactive = ReactiveVar 1
+ unsub = reactive\subscribe coroutine.wrap () ->
+ calls += 1
+ coroutine.yield!
+ calls += 1
+ coroutine.yield!
+ calls += 1
+
+ assert 'function' == (type unsub), "expected to receive a function"
+
+ reactive\set 2
+ reactive\set 3
+ assert calls == 2, "wat"
+
+ unsub!
+ reactive\set 4
+ assert calls == 2, "expected to stop receiving updates"
+
+ run_test "tracks multiple subscriptions at once", ->
+ reactive = ReactiveVar 'test'
+ unsub = reactive\subscribe coroutine.wrap (next) ->
+ assert next == 'toast', "expected next to be toast"
+ next = coroutine.yield!
+ assert next == 'cheese', "expected next to be cheese"
+ coroutine.yield!
+ error "expected not to get here"
+
+ reactive\set 'toast'
+
+ local done
+ reactive\subscribe coroutine.wrap (next) ->
+ assert next == 'cheese', "expected next to be cheese"
+ next = coroutine.yield!
+ assert next == 'test', "expected next to be test"
+ done = true
+
+ reactive\set 'cheese'
+ unsub!
+ reactive\set 'test'
+ assert done, "expected to reach the end"
+
+ run_test = test_group 'ReactiveElement'
+
+ run_test "creates a HTML element", ->
+ elem = ReactiveElement 'span'
+ assert elem.node and elem.node.localName == 'span', "expected Node to be a <span>"
+
+ -- @TODO: can take over a DOM Node
+
+ run_test "sets attributes from a table arg", ->
+ elem = ReactiveElement 'span', class: 'never'
+ assert elem.node.class == 'never', "expected class to be 'never'"
+
+ run_test "appends Nodes from arguments", ->
+ e_div, e_pre = div!, pre!
+ elem = ReactiveElement 'span', e_div, e_pre
+ assert elem.node.firstElementChild == e_div, "expected div to be the first child of elem"
+ assert elem.node.lastElementChild == e_pre, "expected pre to be the last child of elem"
+
+ run_test "can append ReactiveElements and text", ->
+ e_div = ReactiveElement 'div'
+ elem = ReactiveElement 'div', e_div, 'testtext'
+ assert elem.node.firstElementChild == e_div.node, "expected div to be the first child of elem"
+ assert elem.node.lastChild.data == 'testtext', "expected last child of elem to be 'testtext'"
+
+ run_test "accepts attributes after children", ->
+ e_div = div!
+ elem = ReactiveElement 'div', e_div, class: 'test'
+ assert elem.node.firstElementChild == e_div, "expected div to be the first child of elem"
+ assert elem.node.class == 'test', "expected class to be 'test'"
+
+ run_test "allows mixing attributes and children in a single table", ->
+ e_div, e_pre = div!, pre!
+ elem = ReactiveElement 'div', { class: 'test', e_div, e_pre }
+ assert elem.node.firstElementChild == e_div, "expected div to be the first child of elem"
+ assert elem.node.lastElementChild == e_pre, "expected pre to be the last child of elem"
+ assert elem.node.class == 'test', "expected class to be 'test'"
+
+ run_test "can unwrap and track attributes from ReactiveVars", ->
+ klass = ReactiveVar 'test'
+ elem = ReactiveElement 'div', class: klass
+ assert elem.node.class == 'test', "expected class to be 'test'"
+ klass\set 'toast'
+ assert elem.node.class == 'toast', "expected class to be 'toast'"
+
+ run_test "can unwrap and track children from ReactiveVars", ->
+ child = ReactiveVar h1 'test'
+ elem = ReactiveElement 'div', child, pre 'fixed'
+ assert elem.node.firstElementChild.localName == 'h1', "expected first child to be h1"
+ assert elem.node.childElementCount == 2, "expected node to have two children"
+ child\set div 'toast'
+ assert elem.node.firstElementChild.localName == 'div', "expected first child to be div"
+ assert elem.node.childElementCount == 2, "expected node to have two children"
+
+ run_test "warns when appending a string from a ReactiveVar", ->
+ import text from require 'mmm.component'
+
+ str = ReactiveVar 'test'
+ elem = ReactiveElement 'div', str
+ expect 'cannot replace string node', 'expected error', str\set, 'string too'
+ elem\destroy!
+
+ elem = ReactiveElement 'div', str\map text
+ str\set 'this is text'
+
+ article _content
+}
diff --git a/root/meta/todo.moon b/root/meta/todo.moon
new file mode 100644
index 0000000..eb6fc0d
--- /dev/null
+++ b/root/meta/todo.moon
@@ -0,0 +1,42 @@
+import define_fileders from require 'mmm.mmmfs'
+Fileder = define_fileders ...
+
+Fileder {
+ 'name: alpha': 'todo'
+ 'description: text/plain': 'TodoMVC using mmm.component'
+ 'moon -> mmm/component': =>
+ import ReactiveVar, text, elements from require 'mmm.component'
+ import article, div, form, span, h3, a, input, textarea, button from elements
+
+ parent = div!
+ todoItem = (desc, done) ->
+ -- convert into reactive data sources
+ desc, done = (ReactiveVar desc), ReactiveVar done
+ with me = div style:
+ margin: '8px'
+ padding: '8px'
+ background: '#eeeeee'
+ \append h3 (desc\map text), style: 'margin: 0;'
+ \append span done\map (done) -> text if done then 'done' else 'not done yet'
+ \append input type: 'checkbox', checked: done, onchange: (e) => done\set e.target.checked
+ \append a (text 'delete'), href: '#', onclick: (e) => parent\remove me
+
+ parent\append todoItem 'write a Component System', true
+ parent\append todoItem 'eat Lasagna', true
+ parent\append todoItem 'do other things'
+
+ desc = ReactiveVar 'start'
+ form = with form {
+ action: ''
+ style:
+ margin: '2px'
+ onsubmit: (e) =>
+ e\preventDefault!
+ parent\append todoItem desc\get!
+ desc\set ''
+ }
+ \append input type: 'text', value: desc, onchange: (e) => desc\set e.target.value
+ \append input type: 'submit', value: 'add'
+
+ article parent, form
+}
diff --git a/tup.moon b/tup.moon
index 033e0f6..cdee2d4 100644
--- a/tup.moon
+++ b/tup.moon
@@ -1,6 +1,6 @@
-package.moonpath = './?.server.moon;' .. package.moonpath
+package.moonpath = './?.server.moon;./?/init.server.moon;' .. package.moonpath
require 'lfs'
-require 'lib.init'
+require 'mmm.init'
-- enumerate moonscript source files
enum_dir = do
@@ -19,18 +19,21 @@ enum_dir = do
coroutine.wrap -> yieldtree dir
+-- COMPILE MOONSCRIPT
+-- mmmfs tree
for file in enum_dir 'root'
basename = assert file\match '(.*)%.moon$'
print ": #{file} |> ^ MOON %b > %o^ moonc -o %o %f |> dist/#{basename}.lua"
-for file in enum_dir 'lib'
+-- mmm
+for file in enum_dir 'mmm'
continue if file\match '%.server%.moon$'
basename = assert file\match '(.*)%.moon$'
basename = (file\match '(.*)%.client') or basename
print ": #{file} |> ^ MOON %b > %o^ moonc -o %o %f |> dist/#{basename}.lua"
--- add rules for each fileder
-import module_roots from require 'lib.mmmfs'
+-- PRE-RENDER MMMFS
+import module_roots from require 'mmm.mmmfs'
root = require 'root'
root\mount!