simplified store

This commit is contained in:
Anton Dyudin 2015-08-05 19:13:41 -07:00
parent 9b7efc3a3f
commit f6d5005e60
7 changed files with 124 additions and 287 deletions

View File

@ -10,18 +10,19 @@
:: ::
++ grow :: convert to ++ grow :: convert to
|% |%
++ tape (pojo react-snip-json) ++ mime [/application/json (tact tape)]
++ tape (pojo react-snips-json)
++ elem ;div:(h1:"*{hed}" div:"*{tal}") ++ elem ;div:(h1:"*{hed}" div:"*{tal}")
++ react-snip-js (crip (react-to-tape elem)) ++ react-snip-js (crip (react-to-tape elem))
++ react-snips-json ++ react-snips-json
::?> ?=([[%div ~] [[%h1 ~] *] [[%div ~] *] ~]] own) :: xx mystery fish-loop ::?> ?=([[%div ~] [[%h1 ~] *] [[%div ~] *] ~]] own) :: xx mystery fish-loop
%^ jobe %^ jobe
head/(react-to-json ;h1:"*{hed}") head/react-head-json
body/(react-to-json ;div:"*{tal}") body/react-snip-json
~ ~
++ react-head-json [%a (turn hed react-to-json)] ::
++ react-snip-json [%a (turn tal react-to-json)] ++ react-head-json (react-to-json ;h1:"*{hed}")
++ mime [/application/json (tact tape)] ++ react-snip-json (react-to-json ;div:"*{tal}")
-- --
++ grab |% :: convert from ++ grab |% :: convert from
++ noun manx :: clam from %noun ++ noun manx :: clam from %noun

View File

@ -25,7 +25,7 @@ which is normalized and type-checked(request types are `%t` text, `%r` html-deri
- `[%name %t]`, the node name - `[%name %t]`, the node name
- `[%path %t]`, the current path - `[%path %t]`, the current path
- `[%snip %r]`, a snippet, extracted via `react-snip-json` - `[%snip %r]`, a snippet, extracted via `react-snip-json`
- `[%head %r]`, the first header, extracted via `react-head-json` - `[%head %r]`, the first `<h1/>`, extracted via `react-head-json`
- `[%body %r]`, the `react-json` body - `[%body %r]`, the `react-json` body
- `[%meta %j]`, json frontmatter per the `mdy` mark definition - `[%meta %j]`, json frontmatter per the `mdy` mark definition

View File

@ -2,34 +2,13 @@ TreeDispatcher = require '../dispatcher/Dispatcher.coffee'
TreePersistence = require '../persistence/TreePersistence.coffee' TreePersistence = require '../persistence/TreePersistence.coffee'
module.exports = module.exports =
loadPath: (path,body,kids) -> loadPath: (path,data) ->
TreeDispatcher.handleServerAction TreeDispatcher.handleServerAction {path,data,type:"path-load"}
type:"path-load"
path:path
body:body
kids:kids
loadKids: (path,kids) ->
TreeDispatcher.handleServerAction
type:"kids-load"
path:path
kids:kids
loadSnip: (path,kids) ->
TreeDispatcher.handleServerAction
type:"snip-load"
path:path
kids:kids
sendQuery: (path,query) -> sendQuery: (path,query) ->
return unless query? return unless query?
if path.slice(-1) is "/" then path = path.slice(0,-1) if path.slice(-1) is "/" then path = path.slice(0,-1)
TreePersistence.get path,query,(err,res) => @loadPath path,res
TreePersistence.get path,query,(err,res) =>
switch
when query.kids?.body then @loadKids path,res.kids
when query.kids?.head then @loadSnip path,res.kids
else @loadPath path,res.body,res.kids
setCurr: (path) -> setCurr: (path) ->
TreeDispatcher.handleViewAction TreeDispatcher.handleViewAction

View File

@ -5,7 +5,7 @@ recl = React.createClass
module.exports = recl module.exports = recl
hash:null hash:null
displayName: "TableofContents" displayName: "TableOfContents"
_onChangeStore: -> @setState tocs: @compute() _onChangeStore: -> @setState tocs: @compute()
_click: (e) -> _click: (e) ->
@ -35,8 +35,6 @@ module.exports = recl
getInitialState: -> tocs: @compute() getInitialState: -> tocs: @compute()
gotPath: -> TreeStore.gotSnip(@state.path)
compute: -> compute: ->
$headers = $('#toc h1, #toc h2, #toc h3, #toc h4') $headers = $('#toc h1, #toc h2, #toc h3, #toc h4')
for h in $headers for h in $headers
@ -45,6 +43,6 @@ module.exports = recl
render: -> render: ->
onClick = @_click onClick = @_click
(div {className:'toc'}, @state.tocs.map ({h,t}) -> (div {className:'toc'}, @state.tocs.map ({h,t},key) ->
(React.DOM[h] {onClick}, t) (React.DOM[h] {onClick,key}, t)
) )

View File

@ -6,26 +6,11 @@ TreeDispatcher = require('../dispatcher/Dispatcher.coffee');
TreePersistence = require('../persistence/TreePersistence.coffee'); TreePersistence = require('../persistence/TreePersistence.coffee');
module.exports = { module.exports = {
loadPath: function(path, body, kids) { loadPath: function(path, data) {
return TreeDispatcher.handleServerAction({ return TreeDispatcher.handleServerAction({
type: "path-load",
path: path, path: path,
body: body, data: data,
kids: kids type: "path-load"
});
},
loadKids: function(path, kids) {
return TreeDispatcher.handleServerAction({
type: "kids-load",
path: path,
kids: kids
});
},
loadSnip: function(path, kids) {
return TreeDispatcher.handleServerAction({
type: "snip-load",
path: path,
kids: kids
}); });
}, },
sendQuery: function(path, query) { sendQuery: function(path, query) {
@ -37,15 +22,7 @@ module.exports = {
} }
return TreePersistence.get(path, query, (function(_this) { return TreePersistence.get(path, query, (function(_this) {
return function(err, res) { return function(err, res) {
var ref, ref1; return _this.loadPath(path, res);
switch (false) {
case !((ref = query.kids) != null ? ref.body : void 0):
return _this.loadKids(path, res.kids);
case !((ref1 = query.kids) != null ? ref1.head : void 0):
return _this.loadSnip(path, res.kids);
default:
return _this.loadPath(path, res.body, res.kids);
}
}; };
})(this)); })(this));
}, },
@ -662,7 +639,7 @@ div = React.DOM.div;
module.exports = recl({ module.exports = recl({
hash: null, hash: null,
displayName: "TableofContents", displayName: "TableOfContents",
_onChangeStore: function() { _onChangeStore: function() {
return this.setState({ return this.setState({
tocs: this.compute() tocs: this.compute()
@ -710,9 +687,6 @@ module.exports = recl({
tocs: this.compute() tocs: this.compute()
}; };
}, },
gotPath: function() {
return TreeStore.gotSnip(this.state.path);
},
compute: function() { compute: function() {
var $h, $headers, h, i, len, results; var $h, $headers, h, i, len, results;
$headers = $('#toc h1, #toc h2, #toc h3, #toc h4'); $headers = $('#toc h1, #toc h2, #toc h3, #toc h4');
@ -733,11 +707,12 @@ module.exports = recl({
onClick = this._click; onClick = this._click;
return div({ return div({
className: 'toc' className: 'toc'
}, this.state.tocs.map(function(arg) { }, this.state.tocs.map(function(arg, key) {
var h, t; var h, t;
h = arg.h, t = arg.t; h = arg.h, t = arg.t;
return React.DOM[h]({ return React.DOM[h]({
onClick: onClick onClick: onClick,
key: key
}, t); }, t);
})); }));
} }
@ -1336,7 +1311,7 @@ module.exports = {
},{}],18:[function(require,module,exports){ },{}],18:[function(require,module,exports){
var EventEmitter, MessageDispatcher, TreeStore, _cont, _curr, _got_snip, _snip, _tree, clog; var EventEmitter, MessageDispatcher, TreeStore, _curr, _data, _tree, clog;
EventEmitter = require('events').EventEmitter; EventEmitter = require('events').EventEmitter;
@ -1346,11 +1321,7 @@ clog = console.log.bind(console);
_tree = {}; _tree = {};
_cont = {}; _data = {};
_snip = {};
_got_snip = {};
_curr = ""; _curr = "";
@ -1368,26 +1339,23 @@ TreeStore = _.extend(EventEmitter.prototype, {
return _path.split("/"); return _path.split("/");
}, },
fulfill: function(path, query) { fulfill: function(path, query) {
var data, i, k, len, ref, ref1, ref2, ref3; return this.fulfillAt(this.getTree(path.split('/')), path, query);
},
fulfillAt: function(tree, path, query) {
var data, i, k, len, ref, ref1, sub;
data = this.fulfillLocal(path, query); data = this.fulfillLocal(path, query);
if (query.body) { ref = ["body", "head", "snip", "meta"];
data.body = _cont[path]; for (i = 0, len = ref.length; i < len; i++) {
} k = ref[i];
if (query.head) { if (query[k]) {
data.head = (ref = _snip[path]) != null ? ref.head : void 0; data[k] = (ref1 = _data[path]) != null ? ref1[k] : void 0;
} }
if (query.snip) {
data.snip = (ref1 = _snip[path]) != null ? ref1.body : void 0;
}
if (query.meta) {
data.meta = (ref2 = _snip[path]) != null ? ref2.meta : void 0;
} }
if (query.kids) { if (query.kids) {
data.kids = {}; data.kids = {};
ref3 = this.getKids(path); for (k in tree) {
for (i = 0, len = ref3.length; i < len; i++) { sub = tree[k];
k = ref3[i]; data.kids[k] = this.fulfillAt(sub, path + "/" + k, query.kids);
data.kids[k] = this.fulfill(path + "/" + k, query.kids);
} }
} }
if (!_.isEmpty(data)) { if (!_.isEmpty(data)) {
@ -1404,81 +1372,45 @@ TreeStore = _.extend(EventEmitter.prototype, {
data.name = path.split("/").pop(); data.name = path.split("/").pop();
} }
if (query.sein) { if (query.sein) {
data.sein = TreeStore.getPare(path); data.sein = this.getPare(path);
}
if (query.sibs) {
data.sibs = TreeStore.getSiblings(path);
} }
if (query.next) { if (query.next) {
data.next = TreeStore.getNext(path); data.next = this.getNext(path);
} }
if (query.prev) { if (query.prev) {
data.prev = TreeStore.getPrev(path); data.prev = this.getPrev(path);
} }
return data; return data;
}, },
getTree: function(_path) {
var i, len, sub, tree;
tree = _tree;
for (i = 0, len = _path.length; i < len; i++) {
sub = _path[i];
tree = tree[sub];
if (tree == null) {
return null;
}
}
return tree;
},
setCurr: function(path) { setCurr: function(path) {
return _curr = path; return _curr = path;
}, },
getCurr: function() { getCurr: function() {
return _curr; return _curr;
}, },
getCont: function() { loadPath: function(path, data) {
return _cont; return this.loadValues(this.getTree(path.split('/'), true), path, data);
}, },
mergePathToTree: function(path, kids) { loadValues: function(tree, path, data) {
var i, j, len, len1, ref, ref1, ref2, sub, tree, x; var i, k, len, old, ref, ref1, ref2, v;
tree = _tree; old = (ref = _data[path]) != null ? ref : {};
ref = this.pathToArr(path); ref1 = ["body", "head", "snip", "meta"];
for (i = 0, len = ref.length; i < len; i++) { for (i = 0, len = ref1.length; i < len; i++) {
sub = ref[i]; k = ref1[i];
tree[sub] = (ref1 = tree[sub]) != null ? ref1 : {}; if (data[k] !== void 0) {
tree = tree[sub]; old[k] = data[k];
}
for (j = 0, len1 = kids.length; j < len1; j++) {
x = kids[j];
tree[x] = (ref2 = tree[x]) != null ? ref2 : {};
}
return tree;
},
getSnip: function() {
return _snip;
},
gotSnip: function(path) {
return !!_got_snip[path];
},
loadSnip: function(path, kids) {
var i, len, v;
this.mergePathToTree(path, _.pluck(kids, "name"));
if ((kids != null ? kids.length : void 0) !== 0) {
for (i = 0, len = kids.length; i < len; i++) {
v = kids[i];
_snip[path + "/" + v.name] = {
head: {
gn: 'h1',
c: v.head
},
body: {
gn: 'div',
c: v.snip
},
meta: v.meta
};
} }
} else { }
_cont[path] = { ref2 = data.kids;
for (k in ref2) {
v = ref2[k];
if (tree[k] == null) {
tree[k] = {};
}
this.loadValues(tree[k], path + "/" + k, v);
}
if (data.kids && _.isEmpty(data.kids)) {
old.body = {
gn: 'div', gn: 'div',
c: [ c: [
{ {
@ -1502,27 +1434,7 @@ TreeStore = _.extend(EventEmitter.prototype, {
] ]
}; };
} }
return _got_snip[path] = true; return _data[path] = old;
},
loadKids: function(path, kids) {
var k, results, v;
this.mergePathToTree(path, _.pluck(kids, "name"));
results = [];
for (k in kids) {
v = kids[k];
results.push(_cont[path + "/" + v.name] = v.body);
}
return results;
},
loadPath: function(path, body, kids) {
this.mergePathToTree(path, _.pluck(kids, "name"));
return _cont[path] = body;
},
getKids: function(path) {
if (path == null) {
path = _curr;
}
return _.keys(this.getTree(path.split("/")));
}, },
getSiblings: function(path) { getSiblings: function(path) {
var curr; var curr;
@ -1537,6 +1449,24 @@ TreeStore = _.extend(EventEmitter.prototype, {
return {}; return {};
} }
}, },
getTree: function(_path, make) {
var i, len, sub, tree;
if (make == null) {
make = false;
}
tree = _tree;
for (i = 0, len = _path.length; i < len; i++) {
sub = _path[i];
if (tree[sub] == null) {
if (!make) {
return null;
}
tree[sub] = {};
}
tree = tree[sub];
}
return tree;
},
getPrev: function(path) { getPrev: function(path) {
var ind, key, par, sibs, win; var ind, key, par, sibs, win;
if (path == null) { if (path == null) {
@ -1546,7 +1476,7 @@ TreeStore = _.extend(EventEmitter.prototype, {
if (sibs.length < 2) { if (sibs.length < 2) {
return null; return null;
} else { } else {
par = _curr.split("/"); par = path.split("/");
key = par.pop(); key = par.pop();
ind = sibs.indexOf(key); ind = sibs.indexOf(key);
win = ind - 1 >= 0 ? sibs[ind - 1] : sibs[sibs.length - 1]; win = ind - 1 >= 0 ? sibs[ind - 1] : sibs[sibs.length - 1];
@ -1563,7 +1493,7 @@ TreeStore = _.extend(EventEmitter.prototype, {
if (sibs.length < 2) { if (sibs.length < 2) {
return null; return null;
} else { } else {
par = _curr.split("/"); par = path.split("/");
key = par.pop(); key = par.pop();
ind = sibs.indexOf(key); ind = sibs.indexOf(key);
win = ind + 1 < sibs.length ? sibs[ind + 1] : sibs[0]; win = ind + 1 < sibs.length ? sibs[ind + 1] : sibs[0];
@ -1587,31 +1517,6 @@ TreeStore = _.extend(EventEmitter.prototype, {
} else { } else {
return null; return null;
} }
},
getCrumbs: function(path) {
var _path, crum, crums, k, v;
if (path == null) {
path = _curr;
}
_path = this.pathToArr(path);
crum = "";
crums = [];
for (k in _path) {
v = _path[k];
crum += "/" + v;
crums.push({
name: v,
path: crum
});
}
return crums;
},
getBody: function() {
if (_cont[_curr]) {
return _cont[_curr];
} else {
return null;
}
} }
}); });
@ -1620,13 +1525,7 @@ TreeStore.dispatchToken = MessageDispatcher.register(function(payload) {
action = payload.action; action = payload.action;
switch (action.type) { switch (action.type) {
case 'path-load': case 'path-load':
TreeStore.loadPath(action.path, action.body, action.kids, action.snip); TreeStore.loadPath(action.path, action.data);
return TreeStore.emitChange();
case 'snip-load':
TreeStore.loadSnip(action.path, action.kids);
return TreeStore.emitChange();
case 'kids-load':
TreeStore.loadKids(action.path, action.kids);
return TreeStore.emitChange(); return TreeStore.emitChange();
case 'set-curr': case 'set-curr':
TreeStore.setCurr(action.path); TreeStore.setCurr(action.path);

View File

@ -4,8 +4,7 @@ MessageDispatcher = require '../dispatcher/Dispatcher.coffee'
clog = console.log.bind(console) clog = console.log.bind(console)
_tree = {} _tree = {}
_cont = {} _data = {}
_snip = {}; _got_snip = {}
_curr = "" _curr = ""
TreeStore = _.extend EventEmitter.prototype, { TreeStore = _.extend EventEmitter.prototype, {
@ -17,63 +16,42 @@ TreeStore = _.extend EventEmitter.prototype, {
pathToArr: (_path) -> _path.split "/" pathToArr: (_path) -> _path.split "/"
fulfill: (path,query)-> fulfill: (path,query) -> @fulfillAt (@getTree path.split '/'),path,query
fulfillAt: (tree,path,query)->
data = @fulfillLocal path, query data = @fulfillLocal path, query
if query.body then data.body = _cont[path] for k in ["body", "head" ,"snip" ,"meta"]
if query.head then data.head = _snip[path]?.head data[k] = _data[path]?[k] if query[k]
if query.snip then data.snip = _snip[path]?.body
if query.meta then data.meta = _snip[path]?.meta
if query.kids if query.kids
data.kids = {} data.kids = {}
for k in @getKids path for k,sub of tree
data.kids[k] = @fulfill path+"/"+k, query.kids data.kids[k] = @fulfillAt sub, path+"/"+k, query.kids
data unless _.isEmpty data data unless _.isEmpty data
fulfillLocal: (path, query)-> fulfillLocal: (path, query)->
data = {} data = {}
if query.path then data.path = path if query.path then data.path = path
if query.name then data.name = path.split("/").pop() if query.name then data.name = path.split("/").pop()
if query.sein then data.sein = TreeStore.getPare path if query.sein then data.sein = @getPare path
if query.sibs then data.sibs = TreeStore.getSiblings path if query.next then data.next = @getNext path
if query.next then data.next = TreeStore.getNext path if query.prev then data.prev = @getPrev path
if query.prev then data.prev = TreeStore.getPrev path
data data
getTree: (_path) ->
tree = _tree
for sub in _path
tree = tree[sub]
return null unless tree?
tree
setCurr: (path) -> _curr = path setCurr: (path) -> _curr = path
getCurr: -> _curr getCurr: -> _curr
getCont: -> _cont loadPath: (path,data) ->
@loadValues (@getTree (path.split '/'),true), path, data
mergePathToTree: (path,kids) -> loadValues: (tree,path,data) ->
tree = _tree old = _data[path] ? {}
for sub in @pathToArr path for k in ["body", "head" ,"snip" ,"meta"]
tree[sub] = tree[sub] ? {} old[k] = data[k] if data[k] isnt undefined
tree = tree[sub]
for x in kids for k,v of data.kids
tree[x] = tree[x] ? {} tree[k] ?= {}
tree @loadValues tree[k], path+"/"+k, v
getSnip: -> _snip if data.kids && _.isEmpty data.kids
gotSnip: (path)-> !!_got_snip[path] old.body =
loadSnip: (path,kids) ->
@mergePathToTree path,_.pluck(kids,"name")
if kids?.length isnt 0
for v in kids
_snip[path+"/"+v.name] =
head: {gn:'h1',c:v.head}
body: {gn:'div',c:v.snip}
meta: v.meta
else
_cont[path] =
gn: 'div' gn: 'div'
c: [ {gn:'h1', ga:{className:'error'}, c:['Error: Empty path']} c: [ {gn:'h1', ga:{className:'error'}, c:['Error: Empty path']}
{gn:'div', c:[ {gn:'div', c:[
@ -81,18 +59,8 @@ TreeStore = _.extend EventEmitter.prototype, {
{gn:'span', c:['is either empty or does not exist.']} {gn:'span', c:['is either empty or does not exist.']}
# {gn:'list'} XX handle empty snip # {gn:'list'} XX handle empty snip
] }] ] }]
_got_snip[path] = true
_data[path] = old
loadKids: (path,kids) ->
@mergePathToTree path,_.pluck(kids,"name")
for k,v of kids
_cont[path+"/"+v.name] = v.body
loadPath: (path,body,kids) ->
@mergePathToTree path,_.pluck(kids,"name")
_cont[path] = body
getKids: (path=_curr)-> _.keys @getTree path.split("/")
getSiblings: (path=_curr)-> getSiblings: (path=_curr)->
curr = path.split("/") curr = path.split("/")
@ -101,13 +69,22 @@ TreeStore = _.extend EventEmitter.prototype, {
@getTree curr @getTree curr
else else
{} {}
getTree: (_path,make=false) ->
tree = _tree
for sub in _path
if not tree[sub]?
if not make then return null
tree[sub] = {}
tree = tree[sub]
tree
getPrev: (path=_curr)-> getPrev: (path=_curr)->
sibs = _.keys(@getSiblings path).sort() sibs = _.keys(@getSiblings path).sort()
if sibs.length < 2 if sibs.length < 2
null null
else else
par = _curr.split "/" par = path.split "/"
key = par.pop() key = par.pop()
ind = sibs.indexOf key ind = sibs.indexOf key
win = if ind-1 >= 0 then sibs[ind-1] else sibs[sibs.length-1] win = if ind-1 >= 0 then sibs[ind-1] else sibs[sibs.length-1]
@ -119,7 +96,7 @@ TreeStore = _.extend EventEmitter.prototype, {
if sibs.length < 2 if sibs.length < 2
null null
else else
par = _curr.split "/" par = path.split "/"
key = par.pop() key = par.pop()
ind = sibs.indexOf key ind = sibs.indexOf key
win = if ind+1 < sibs.length then sibs[ind+1] else sibs[0] win = if ind+1 < sibs.length then sibs[ind+1] else sibs[0]
@ -135,17 +112,6 @@ TreeStore = _.extend EventEmitter.prototype, {
_path _path
else else
null null
getCrumbs: (path=_curr)->
_path = @pathToArr path
crum = ""
crums = []
for k,v of _path
crum += "/"+v
crums.push {name:v,path:crum}
crums
getBody: -> if _cont[_curr] then _cont[_curr] else null
} }
TreeStore.dispatchToken = MessageDispatcher.register (payload) -> TreeStore.dispatchToken = MessageDispatcher.register (payload) ->
@ -153,13 +119,7 @@ TreeStore.dispatchToken = MessageDispatcher.register (payload) ->
switch action.type switch action.type
when 'path-load' when 'path-load'
TreeStore.loadPath action.path,action.body,action.kids,action.snip TreeStore.loadPath action.path,action.data
TreeStore.emitChange()
when 'snip-load'
TreeStore.loadSnip action.path,action.kids
TreeStore.emitChange()
when 'kids-load'
TreeStore.loadKids action.path,action.kids
TreeStore.emitChange() TreeStore.emitChange()
when 'set-curr' when 'set-curr'
TreeStore.setCurr action.path TreeStore.setCurr action.path

View File

@ -56,10 +56,10 @@
%meta (from-type +.a meta.dat) %meta (from-type +.a meta.dat)
%body (from-type +.a body.dat) %body (from-type +.a body.dat)
%kids ?< (~(has by (mo p.a)) %kids) :: XX recursion? %kids ?< (~(has by (mo p.a)) %kids) :: XX recursion?
=< a/(turn (~(tap by kid)) .) =< o/(~(urn by kid) .)
|= [dir=span dak=tree-include] |= [dir=span dak=tree-include]
^^$(quy [name/%t p.a], s.bem [dir s.bem], dat dak, kid ~) ^^$(quy p.a, s.bem [dir s.bem], dat dak, kid ~)
== :: XX array ==
-- --
!: !:
:::: ::::