diff --git a/pkg/arvo/app/graph-store.hoon b/pkg/arvo/app/graph-store.hoon new file mode 100644 index 0000000000..ab9a6b9710 --- /dev/null +++ b/pkg/arvo/app/graph-store.hoon @@ -0,0 +1,572 @@ +/+ store=graph-store, sigs=signatures, res=resource, default-agent, dbug +~% %graph-store-top ..is ~ +|% ++$ card card:agent:gall ++$ versioned-state + $% state-0 + == +:: ++$ state-0 [%0 network:store] +++ orm orm:store +++ orm-log orm-log:store +-- +:: +=| state-0 +=* state - +:: +%- agent:dbug +^- agent:gall +~% %graph-store-agent ..card ~ +|_ =bowl:gall ++* this . + def ~(. (default-agent this %|) bowl) +:: +++ on-init [~ this] +++ on-save !>(state) +++ on-load + |= old=vase + ^- (quip card _this) + [~ this(state !<(state-0 old))] +:: +++ on-watch + ~/ %graph-store-watch + |= =path + ^- (quip card _this) + |^ + ?> (team:title our.bowl src.bowl) + =/ cards=(list card) + ?+ path (on-watch:def path) + [%updates ~] ~ + [%keys ~] (give [%keys ~(key by graphs)]) + [%tags ~] (give [%tags ~(key by tag-queries)]) + == + [cards this] + :: + ++ give + |= =update-0:store + ^- (list card) + [%give %fact ~ [%graph-update !>([%0 now.bowl update-0])]]~ + -- +:: +++ on-poke + ~/ %graph-store-poke + |= [=mark =vase] + ^- (quip card _this) + |^ + ?> (team:title our.bowl src.bowl) + =^ cards state + ?+ mark (on-poke:def mark vase) + %graph-update (graph-update !<(update:store vase)) + == + [cards this] + :: + ++ graph-update + |= =update:store + ^- (quip card _state) + |^ + ?> ?=(%0 -.update) + ?- -.q.update + %add-graph (add-graph +.q.update) + %remove-graph (remove-graph +.q.update) + %add-nodes (add-nodes p.update +.q.update) + %remove-nodes (remove-nodes p.update +.q.update) + %add-signatures (add-signatures p.update +.q.update) + %remove-signatures (remove-signatures p.update +.q.update) + %add-tag (add-tag +.q.update) + %remove-tag (remove-tag +.q.update) + %archive-graph (archive-graph +.q.update) + %unarchive-graph (unarchive-graph +.q.update) + %run-updates (run-updates +.q.update) + %keys ~|('cannot send %keys as poke' !!) + %tags ~|('cannot send %tags as poke' !!) + %tag-queries ~|('cannot send %tag-queries as poke' !!) + == + :: + ++ add-graph + |= [=resource:store =graph:store mark=(unit mark:store)] + ^- (quip card _state) + ?< (~(has by archive) resource) + ?< (~(has by graphs) resource) + ?> (validate-graph graph mark) + :_ %_ state + graphs (~(put by graphs) resource [graph mark]) + update-logs (~(put by update-logs) resource (gas:orm-log ~ ~)) + validators + ?~ mark validators + (~(put in validators) u.mark) + == + %- zing + :~ (give [/updates /keys ~] [%add-graph resource graph mark]) + ?~ mark ~ + ?: (~(has in validators) u.mark) ~ + =/ wire (weld /graph (en-path:res resource)) + =/ =rave:clay [%sing %b [%da now.bowl] /[u.mark]] + [%pass wire %arvo %c %warp our.bowl [%home `rave]]~ + == + :: + ++ remove-graph + |= =resource:store + ^- (quip card _state) + ?< (~(has by archive) resource) + ?> (~(has by graphs) resource) + :- (give [/updates /keys ~] [%remove-graph resource]) + %_ state + graphs (~(del by graphs) resource) + update-logs (~(del by update-logs) resource) + == + :: + ++ add-nodes + |= $: =time + =resource:store + nodes=(map index:store node:store) + == + ^- (quip card _state) + |^ + =/ [=graph:store mark=(unit mark:store)] + (~(got by graphs) resource) + =/ =update-log:store (~(got by update-logs) resource) + =. update-log + (put:orm-log update-log time [%0 time [%add-nodes resource nodes]]) + :: + :- (give [/updates]~ [%add-nodes resource nodes]) + %_ state + update-logs (~(put by update-logs) resource update-log) + graphs + %+ ~(put by graphs) + resource + :_ mark + (add-node-list resource graph mark (sort-nodes nodes)) + == + :: + ++ sort-nodes + |= nodes=(map index:store node:store) + ^- (list [index:store node:store]) + %+ sort ~(tap by nodes) + |= [p=[=index:store *] q=[=index:store *]] + ^- ? + (lth (lent index.p) (lent index.q)) + :: + ++ add-node-list + |= $: =resource:store + =graph:store + mark=(unit mark:store) + node-list=(list [index:store node:store]) + == + ^- graph:store + ?~ node-list graph + =* index -.i.node-list + =* node +.i.node-list + %_ $ + node-list t.node-list + graph (add-node-at-index graph index node mark) + == + :: + ++ add-node-at-index + =| parent-hash=(unit hash:store) + |= $: =graph:store + =index:store + =node:store + mark=(unit mark:store) + == + ^- graph:store + ?< ?=(~ index) + ~| "validation of node failed using mark {}" + ?> (validate-graph (gas:orm ~ [i.index node]~) mark) + =* atom i.index + %^ put:orm + graph + atom + :: add child + :: + ?~ t.index + =* p post.node + =/ =validated-portion:store + [parent-hash author.p time-sent.p contents.p] + =/ =hash:store `@ux`(sham validated-portion) + ?~ hash.p node(signatures.post *signatures:store) + ~| "signatures do not match the calculated hash" + ?> (are-signatures-valid:sigs signatures.p hash now.bowl) + ~| "hash of post does not match calculated hash" + ?> =(hash u.hash.p) + node + :: recurse children + :: + =/ parent=node:store + ~| "index does not exist to add a node to!" + (need (get:orm graph atom)) + %_ parent + children + ^- internal-graph:store + :- %graph + %_ $ + index t.index + parent-hash hash.post.parent + graph + ?: ?=(%graph -.children.parent) + p.children.parent + (gas:orm ~ ~) + == + == + -- + :: + ++ remove-nodes + |= [=time =resource:store indices=(set index:store)] + ^- (quip card _state) + |^ + =/ [=graph:store mark=(unit mark:store)] + (~(got by graphs) resource) + =/ =update-log:store (~(got by update-logs) resource) + =. update-log + (put:orm-log update-log time [%0 time [%remove-nodes resource indices]]) + :: + :- (give [/updates]~ [%remove-nodes resource indices]) + %_ state + update-logs (~(put by update-logs) resource update-log) + graphs + %+ ~(put by graphs) + resource + [(remove-indices resource graph ~(tap in indices)) mark] + == + :: + ++ remove-indices + |= [=resource:store =graph:store indices=(list index:store)] + ^- graph:store + ?~ indices graph + %_ $ + indices t.indices + graph (remove-index graph i.indices) + == + :: + ++ remove-index + |= [=graph:store =index:store] + ^- graph:store + ?~ index graph + =* atom i.index + :: last index in list + :: + ?~ t.index + +:`[* graph:store]`(del:orm graph atom) + =/ =node:store + ~| "parent index does not exist to remove a node from!" + (need (get:orm graph atom)) + ~| "child index does not exist to remove a node from!" + ?> ?=(%graph -.children.node) + %^ put:orm + graph + atom + node(p.children $(graph p.children.node, index t.index)) + -- + :: + ++ add-signatures + |= [=time =uid:store =signatures:store] + ^- (quip card _state) + |^ + =* resource resource.uid + =/ [=graph:store mark=(unit mark:store)] + (~(got by graphs) resource) + =/ =update-log:store (~(got by update-logs) resource) + =. update-log + (put:orm-log update-log time [%0 time [%add-signatures uid signatures]]) + :: + :- (give [/updates]~ [%add-signatures uid signatures]) + %_ state + update-logs (~(put by update-logs) resource update-log) + graphs + %+ ~(put by graphs) resource + [(add-at-index graph index.uid signatures) mark] + == + :: + ++ add-at-index + |= [=graph:store =index:store =signatures:store] + ^- graph:store + ?~ index graph + =* atom i.index + =/ =node:store + ~| "node does not exist to add signatures to!" + (need (get:orm graph atom)) + :: last index in list + :: + %^ put:orm + graph + atom + ?~ t.index + ~| "cannot add signatures to a node missing a hash" + ?> ?=(^ hash.post.node) + ~| "signatures did not match public keys!" + ?> (are-signatures-valid:sigs signatures u.hash.post.node now.bowl) + node(signatures.post (~(uni in signatures) signatures.post.node)) + ~| "child graph does not exist to add signatures to!" + ?> ?=(%graph -.children.node) + node(p.children $(graph p.children.node, index t.index)) + -- + :: + ++ remove-signatures + |= [=time =uid:store =signatures:store] + ^- (quip card _state) + |^ + =* resource resource.uid + =/ [=graph:store mark=(unit mark:store)] + (~(got by graphs) resource) + =/ =update-log:store (~(got by update-logs) resource) + =. update-log + %^ put:orm-log update-log + time + [%0 time [%remove-signatures uid signatures]] + :: + :- (give [/updates]~ [%remove-signatures uid signatures]) + %_ state + update-logs (~(put by update-logs) resource update-log) + graphs + %+ ~(put by graphs) resource + [(remove-at-index graph index.uid signatures) mark] + == + :: + ++ remove-at-index + |= [=graph:store =index:store =signatures:store] + ^- graph:store + ?~ index graph + =* atom i.index + =/ =node:store + ~| "node does not exist to add signatures to!" + (need (get:orm graph atom)) + :: last index in list + :: + %^ put:orm + graph + atom + ?~ t.index + node(signatures.post (~(dif in signatures) signatures.post.node)) + ~| "child graph does not exist to add signatures to!" + ?> ?=(%graph -.children.node) + node(p.children $(graph p.children.node, index t.index)) + -- + :: + ++ add-tag + |= [=term =resource:store] + ^- (quip card _state) + ?> (~(has by graphs) resource) + :- (give [/updates /tags ~] [%add-tag term resource]) + %_ state + tag-queries (~(put ju tag-queries) term resource) + == + :: + ++ remove-tag + |= [=term =resource:store] + ^- (quip card _state) + ?> (~(has by graphs) resource) + :- (give [/updates /tags ~] [%remove-tag term resource]) + %_ state + tag-queries (~(del ju tag-queries) term resource) + == + :: + ++ archive-graph + |= =resource:store + ^- (quip card _state) + ?< (~(has by archive) resource) + ?> (~(has by graphs) resource) + :- (give [/updates /keys /tags ~] [%archive-graph resource]) + %_ state + archive (~(put by archive) resource (~(got by graphs) resource)) + graphs (~(del by graphs) resource) + update-logs (~(del by update-logs) resource) + tag-queries + %- ~(run by tag-queries) + |= =resources:store + (~(del in resources) resource) + == + :: + ++ unarchive-graph + |= =resource:store + ^- (quip card _state) + ?> (~(has by archive) resource) + ?< (~(has by graphs) resource) + :- (give [/updates /keys ~] [%unarchive-graph resource]) + %_ state + archive (~(del by archive) resource) + graphs (~(put by graphs) resource (~(got by archive) resource)) + update-logs (~(put by update-logs) resource (gas:orm-log ~ ~)) + == + :: + ++ run-updates + |= [=resource:store =update-log:store] + ^- (quip card _state) + ?< (~(has by archive) resource) + ?> (~(has by graphs) resource) + :_ state + %+ turn (tap:orm-log update-log) + |= [=time update=logged-update:store] + ^- card + ?> ?=(%0 -.update) + :* %pass + /run-updates/(scot %da time) + %agent + [our.bowl %graph-store] + %poke + :- %graph-update + !> + ^- update:store + ?- -.q.update + %add-nodes update(resource.q resource) + %remove-nodes update(resource.q resource) + %add-signatures update(resource.uid.q resource) + %remove-signatures update(resource.uid.q resource) + == + == + :: + ++ validate-graph + |= [=graph:store mark=(unit mark:store)] + ^- ? + ?~ mark %.y + ?~ graph %.y + =/ =dais:clay + .^ =dais:clay + %cb + /(scot %p our.bowl)/[q.byk.bowl]/(scot %da now.bowl)/[u.mark] + == + %+ roll (tap:orm graph) + |= [[=atom =node:store] out=?] + ?& out + =(%& -:(mule |.((vale:dais [atom post.node])))) + ?- -.children.node + %empty %.y + %graph ^$(graph p.children.node) + == + == + :: + ++ give + |= [paths=(list path) update=update-0:store] + ^- (list card) + [%give %fact paths [%graph-update !>([%0 now.bowl update])]]~ + -- + -- +:: +++ on-peek + ~/ %graph-store-peek + |= =path + ^- (unit (unit cage)) + |^ + ?> (team:title our.bowl src.bowl) + ?+ path (on-peek:def path) + [%x %keys ~] ``noun+!>(~(key by graphs)) + [%x %tags ~] ``noun+!>(~(key by tag-queries)) + [%x %tag-queries ~] ``noun+!>(tag-queries) + [%x %graph @ @ ~] + =/ =ship (slav %p i.t.t.path) + =/ =term i.t.t.t.path + =/ result=(unit marked-graph:store) + (~(get by graphs) [ship term]) + ?~ result [~ ~] + ``noun+!>(u.result) + :: + [%x %graph-subset @ @ @ @ ~] + =/ =ship (slav %p i.t.t.path) + =/ =term i.t.t.t.path + =/ start=(unit atom) (rush i.t.t.t.t.path dem:ag) + =/ end=(unit atom) (rush i.t.t.t.t.t.path dem:ag) + =/ graph=(unit marked-graph:store) + (~(get by graphs) [ship term]) + ?~ graph [~ ~] + ``noun+!>(`graph:store`(subset:orm p.u.graph start end)) + :: + [%x %node @ @ @ *] + =/ =ship (slav %p i.t.t.path) + =/ =term i.t.t.t.path + =/ =index:store + (turn t.t.t.t.path |=(=cord (slav %ud cord))) + =/ node=(unit node:store) (get-node ship term index) + ?~ node [~ ~] + ``noun+!>(u.node) + :: + [%x %post @ @ @ *] + =/ =ship (slav %p i.t.t.path) + =/ =term i.t.t.t.path + =/ =index:store + (turn t.t.t.t.path |=(=cord (slav %ud cord))) + =/ node=(unit node:store) (get-node ship term index) + ?~ node [~ ~] + ``noun+!>(post.u.node) + :: + [%x %node-children @ @ @ *] + =/ =ship (slav %p i.t.t.path) + =/ =term i.t.t.t.path + =/ =index:store + (turn t.t.t.t.path |=(=cord (slav %ud cord))) + =/ node=(unit node:store) (get-node ship term index) + ?~ node [~ ~] + ?- -.children.u.node + %empty [~ ~] + %graph ``noun+!>(p.children.u.node) + == + :: + [%x %node-children-subset @ @ @ @ @ *] + =/ =ship (slav %p i.t.t.path) + =/ =term i.t.t.t.path + =/ start=(unit atom) (rush i.t.t.t.t.path dem:ag) + =/ end=(unit atom) (rush i.t.t.t.t.t.path dem:ag) + =/ =index:store + (turn t.t.t.t.t.t.path |=(=cord (slav %ud cord))) + =/ node=(unit node:store) (get-node ship term index) + ?~ node [~ ~] + ?- -.children.u.node + %empty [~ ~] + %graph ``noun+!>(`graph:store`(subset:orm p.children.u.node start end)) + == + :: + [%x %update-log @ @ ~] + =/ =ship (slav %p i.t.t.path) + =/ =term i.t.t.t.path + =/ update-log=(unit update-log:store) (~(get by update-logs) [ship term]) + ?~ update-log [~ ~] + ``noun+!>(u.update-log) + :: + [%x %peek-update-log @ @ ~] + =/ =ship (slav %p i.t.t.path) + =/ =term i.t.t.t.path + =/ update-log=(unit update-log:store) (~(get by update-logs) [ship term]) + ?~ update-log [~ ~] + =/ result=(unit [time update:store]) + (peek:orm-log:store u.update-log) + ?~ result [~ ~] + ``noun+!>([~ -.u.result]) + == + :: + ++ get-node + |= [=ship =term =index:store] + ^- (unit node:store) + =/ parent-graph=(unit marked-graph:store) + (~(get by graphs) [ship term]) + ?~ parent-graph ~ + =/ node=(unit node:store) ~ + =/ =graph:store p.u.parent-graph + |- + ?~ index + node + ?~ t.index + (get:orm graph i.index) + =. node (get:orm graph i.index) + ?~ node ~ + ?- -.children.u.node + %empty ~ + %graph $(graph p.children.u.node, index t.index) + == + -- +:: +++ on-arvo + |= [=wire =sign-arvo] + ^- (quip card _this) + ?+ -.sign-arvo (on-arvo:def wire sign-arvo) + %c + :_ this + ?> ?=([%graph @ *] wire) + =/ =resource:store (de-path:res t.wire) + =/ gra=(unit marked-graph:store) (~(get by graphs) resource) + ?~ gra ~ + ?~ q.u.gra ~ + =/ =rave:clay [%next %b [%da now.bowl] /[u.q.u.gra]] + [%pass wire %arvo %c %warp our.bowl [%home `rave]]~ + == +:: +++ on-agent on-agent:def +++ on-leave on-leave:def +++ on-fail on-fail:def +-- diff --git a/pkg/arvo/app/hood.hoon b/pkg/arvo/app/hood.hoon index e83b30b151..1bc70ed80d 100644 --- a/pkg/arvo/app/hood.hoon +++ b/pkg/arvo/app/hood.hoon @@ -2,22 +2,16 @@ /+ drum=hood-drum, helm=hood-helm, kiln=hood-kiln |% +$ state - $: %8 - drum=state:drum - helm=state:helm - kiln=state:kiln - == -+$ state-7 - $: %7 + $: %9 drum=state:drum helm=state:helm kiln=state:kiln == +$ any-state $% state - state-7 [ver=?(%1 %2 %3 %4 %5 %6) lac=(map @tas fin-any-state)] [%7 drum=state:drum helm=state:helm kiln=state:kiln] + [%8 drum=state:drum helm=state:helm kiln=state:kiln] == +$ any-state-tuple $: drum=any-state:drum diff --git a/pkg/arvo/gen/graph-store/add-graph.hoon b/pkg/arvo/gen/graph-store/add-graph.hoon new file mode 100644 index 0000000000..a95468928b --- /dev/null +++ b/pkg/arvo/gen/graph-store/add-graph.hoon @@ -0,0 +1,10 @@ +:: graph-store|add-graph: add new graph +:: +/+ *graph-store +:- %say +|= $: [now=@da eny=@uvJ =beak] + [[=resource mark=(unit mark) ~] ~] + == +:- %graph-update +^- update +[%0 now [%add-graph resource (gas:orm ~ ~) mark]] diff --git a/pkg/arvo/gen/graph-store/add-post.hoon b/pkg/arvo/gen/graph-store/add-post.hoon new file mode 100644 index 0000000000..643e073c03 --- /dev/null +++ b/pkg/arvo/gen/graph-store/add-post.hoon @@ -0,0 +1,20 @@ +:: graph-store|add-post: add post to a graph +:: +/- *graph-store +:- %say +|= $: [now=@da eny=@uvJ =beak] + [[[our=ship name=term] contents=(list content) ~] ~] + == +=/ =post *post +=: author.post our + index.post [now]~ + time-sent.post now + contents.post contents +== +:: +:- %graph-update +^- update +:+ %0 now +:+ %add-nodes [our name] +%- ~(gas by *(map index node)) +~[[[now]~ [post [%empty ~]]]] diff --git a/pkg/arvo/gen/graph-store/add-signatures.hoon b/pkg/arvo/gen/graph-store/add-signatures.hoon new file mode 100644 index 0000000000..9a536d6d52 --- /dev/null +++ b/pkg/arvo/gen/graph-store/add-signatures.hoon @@ -0,0 +1,10 @@ +:: graph-store|add-signatures: add signatures to a node at a particular uid +:: +/- *graph-store +:- %say +|= $: [now=@da eny=@uvJ =beak] + [[[=resource =index] =signatures ~] ~] + == +:- %graph-update +^- update +[%0 now [%add-signatures [resource index] signatures]] diff --git a/pkg/arvo/gen/graph-store/add-tag.hoon b/pkg/arvo/gen/graph-store/add-tag.hoon new file mode 100644 index 0000000000..8c83f1c4eb --- /dev/null +++ b/pkg/arvo/gen/graph-store/add-tag.hoon @@ -0,0 +1,10 @@ +:: graph-store|add-tag: tag a particular graph +:: +/- *graph-store +:- %say +|= $: [now=@da eny=@uvJ =beak] + [[=term =resource ~] ~] + == +:- %graph-update +^- update +[%0 now [%add-tag term resource]] diff --git a/pkg/arvo/gen/graph-store/archive-graph.hoon b/pkg/arvo/gen/graph-store/archive-graph.hoon new file mode 100644 index 0000000000..a40a7a5336 --- /dev/null +++ b/pkg/arvo/gen/graph-store/archive-graph.hoon @@ -0,0 +1,10 @@ +:: graph-store|archive-graph: archive graph +:: +/- *graph-store +:- %say +|= $: [now=@da eny=@uvJ =beak] + [[=resource ~] ~] + == +:- %graph-update +^- update +[%0 now [%archive-graph resource]] diff --git a/pkg/arvo/gen/graph-store/remove-graph.hoon b/pkg/arvo/gen/graph-store/remove-graph.hoon new file mode 100644 index 0000000000..e06305981e --- /dev/null +++ b/pkg/arvo/gen/graph-store/remove-graph.hoon @@ -0,0 +1,10 @@ +:: graph-store|remove-graph: remove graph +:: +/- *graph-store +:- %say +|= $: [now=@da eny=@uvJ =beak] + [[=resource ~] ~] + == +:- %graph-update +^- update +[%0 now [%remove-graph resource]] diff --git a/pkg/arvo/gen/graph-store/remove-nodes.hoon b/pkg/arvo/gen/graph-store/remove-nodes.hoon new file mode 100644 index 0000000000..8c5e13603b --- /dev/null +++ b/pkg/arvo/gen/graph-store/remove-nodes.hoon @@ -0,0 +1,10 @@ +:: graph-store|remove-nodes: remove nodes from a graph at indices +:: +/- *graph-store +:- %say +|= $: [now=@da eny=@uvJ =beak] + [[=resource indices=(set index) ~] ~] + == +:- %graph-update +^- update +[%0 now [%remove-nodes resource indices]] diff --git a/pkg/arvo/gen/graph-store/remove-signatures.hoon b/pkg/arvo/gen/graph-store/remove-signatures.hoon new file mode 100644 index 0000000000..b9bd658fa7 --- /dev/null +++ b/pkg/arvo/gen/graph-store/remove-signatures.hoon @@ -0,0 +1,11 @@ +:: graph-store|remove-signatures: remove signatures from a node at a +:: particular uid +:: +/- *graph-store +:- %say +|= $: [now=@da eny=@uvJ =beak] + [[[=resource =index] =signatures ~] ~] + == +:- %graph-update +^- update +[%0 now [%remove-signatures [resource index] signatures]] diff --git a/pkg/arvo/gen/graph-store/remove-tag.hoon b/pkg/arvo/gen/graph-store/remove-tag.hoon new file mode 100644 index 0000000000..722d4af5c7 --- /dev/null +++ b/pkg/arvo/gen/graph-store/remove-tag.hoon @@ -0,0 +1,10 @@ +:: graph-store|remove-tag: remove a tag from a particular graph +:: +/- *graph-store +:- %say +|= $: [now=@da eny=@uvJ =beak] + [[=term =resource ~] ~] + == +:- %graph-update +^- update +[%0 now [%remove-tag term resource]] diff --git a/pkg/arvo/gen/graph-store/unarchive-graph.hoon b/pkg/arvo/gen/graph-store/unarchive-graph.hoon new file mode 100644 index 0000000000..1d684de6a1 --- /dev/null +++ b/pkg/arvo/gen/graph-store/unarchive-graph.hoon @@ -0,0 +1,10 @@ +:: graph-store|unarchive-graph: unarchive graph +:: +/- *graph-store +:- %say +|= $: [now=@da eny=@uvJ =beak] + [[=resource ~] ~] + == +:- %graph-update +^- update +[%0 now [%unarchive-graph resource]] diff --git a/pkg/arvo/lib/graph-store.hoon b/pkg/arvo/lib/graph-store.hoon new file mode 100644 index 0000000000..bf099c89f6 --- /dev/null +++ b/pkg/arvo/lib/graph-store.hoon @@ -0,0 +1,411 @@ +/- sur=graph-store, pos=post +/+ res=resource +=< [sur .] +=< [pos .] +=, sur +=, pos +|% +:: NOTE: move these functions to zuse +++ nu :: parse number as hex + |= jon/json + ?> ?=({$s *} jon) + (rash p.jon hex) +:: +++ re :: recursive reparsers + |* {gar/* sef/_|.(fist:dejs-soft:format)} + |= jon/json + ^- (unit _gar) + =- ~! gar ~! (need -) - + ((sef) jon) +:: +++ dank :: tank + ^- $-(json (unit tank)) + =, ^? dejs-soft:format + %+ re *tank |. ~+ + %- of :~ + leaf+sa + palm+(ot style+(ot mid+sa cap+sa open+sa close+sa ~) lines+(ar dank) ~) + rose+(ot style+(ot mid+sa open+sa close+sa ~) lines+(ar dank) ~) + == +:: +++ orm ((ordered-map atom node) gth) +++ orm-log ((ordered-map time logged-update) gth) +:: +++ enjs + =, enjs:format + |% + ++ update + |= upd=^update + ^- json + ?> ?=(%0 -.upd) + |^ (frond %graph-update (pairs ~[(encode q.upd)])) + :: + ++ encode + |= upd=update-0 + ^- [cord json] + ?- -.upd + %add-graph + :- %add-graph + %- pairs + :~ [%resource (enjs:res resource.upd)] + [%graph (graph graph.upd)] + [%mark ?~(mark.upd ~ s+u.mark.upd)] + == + :: + %remove-graph + [%remove-graph (enjs:res resource.upd)] + :: + %add-nodes + :- %add-nodes + %- pairs + :~ [%resource (enjs:res resource.upd)] + [%nodes (nodes nodes.upd)] + == + :: + %remove-nodes + :- %remove-nodes + %- pairs + :~ [%resource (enjs:res resource.upd)] + [%indices (indices indices.upd)] + == + :: + %add-signatures + :- %add-signatures + %- pairs + :~ [%uid (uid uid.upd)] + [%signatures (signatures signatures.upd)] + == + :: + %remove-signatures + :- %remove-signatures + %- pairs + :~ [%uid (uid uid.upd)] + [%signatures (signatures signatures.upd)] + == + :: + %add-tag + :- %add-tag + %- pairs + :~ [%term s+term.upd] + [%resource (enjs:res resource.upd)] + == + :: + %remove-tag + :- %remove-tag + %- pairs + :~ [%term s+term.upd] + [%resource (enjs:res resource.upd)] + == + :: + %archive-graph + [%archive-graph (enjs:res resource.upd)] + :: + %unarchive-graph + [%unarchive-graph (enjs:res resource.upd)] + :: + %keys + [%keys [%a (turn ~(tap in resources.upd) enjs:res)]] + :: + %tags + [%tags [%a (turn ~(tap in tags.upd) |=(=term s+term))]] + :: + %run-updates + [%run-updates ~] + :: + %tag-queries + :- %tag-queries + %- pairs + %+ turn ~(tap by tag-queries.upd) + |= [=term =resources] + ^- [cord json] + [term [%a (turn ~(tap in resources) enjs:res)]] + == + :: + ++ graph + |= g=^graph + ^- json + :- %a + %+ turn (tap:orm g) + |= [a=atom n=^node] + ^- json + :- %a + :~ (index [a]~) + (node n) + == + :: + ++ index + |= i=^index + ^- json + =/ j=^tape "" + |- + ?~ i [%s (crip j)] + =/ k=json (numb i.i) + ?> ?=(%n -.k) + %_ $ + i t.i + j (weld j (weld "/" (trip +.k))) + == + :: + ++ node + |= n=^node + ^- json + %- pairs + :~ [%post (post post.n)] + :- %children + ?- -.children.n + %empty ~ + %graph (graph +.children.n) + == + == + :: + ++ post + |= p=^post + ^- json + %- pairs + :~ [%author (ship author.p)] + [%index (index index.p)] + [%time-sent (time time-sent.p)] + [%contents [%a (turn contents.p content)]] + [%hash ?~(hash.p ~ s+(scot %ux u.hash.p))] + [%signatures (signatures signatures.p)] + == + :: + ++ content + |= c=^content + ^- json + ?- -.c + %text (frond %text s+text.c) + %url (frond %url s+url.c) + %reference (frond %reference (uid uid.c)) + %code + %+ frond %code + %- pairs + :- [%expression s+expression.c] + :_ ~ + :- %output + :: virtualize output rendering, +tank:enjs:format might crash + :: + =/ result=(each (list json) tang) + (mule |.((turn output.c tank))) + ?- -.result + %& a+p.result + %| a+[a+[%s '[[output rendering error]]']~]~ + == + == + :: + ++ nodes + |= m=(map ^index ^node) + ^- json + :- %a + %+ turn ~(tap by m) + |= [n=^index o=^node] + ^- json + :- %a + :~ (index n) + (node o) + == + :: + ++ indices + |= i=(set ^index) + ^- json + [%a (turn ~(tap in i) index)] + :: + ++ uid + |= u=^uid + ^- json + %- pairs + :~ [%resource (enjs:res resource.u)] + [%index (index index.u)] + == + :: + ++ signatures + |= s=^signatures + ^- json + [%a (turn ~(tap in s) signature)] + :: + ++ signature + |= s=^signature + ^- json + %- pairs + :~ [%signature s+(scot %ux p.s)] + [%ship (ship q.s)] + [%life (numb r.s)] + == + -- + -- +:: +++ dejs + =, dejs:format + |% + ++ update + |= jon=json + ^- ^update + :- %0 + :- *time + ^- update-0 + =< (decode jon) + |% + ++ decode + %- of + :~ [%add-graph add-graph] + [%remove-graph remove-graph] + [%add-nodes add-nodes] + [%remove-nodes remove-nodes] + [%add-signatures add-signatures] + [%remove-signatures remove-signatures] + [%add-tag add-tag] + [%remove-tag remove-tag] + [%archive-graph archive-graph] + [%unarchive-graph unarchive-graph] + [%keys keys] + [%tags tags] + [%tag-queries tag-queries] + [%run-updates run-updates] + == + :: + ++ add-graph + %- ot + :~ [%resource dejs:res] + [%graph graph] + [%mark (mu so)] + == + :: + ++ graph + |= a=json + ^- ^graph + =/ or-mp ((ordered-map atom ^node) gth) + %+ gas:or-mp ~ + %+ turn ~(tap by ((om node) a)) + |* [b=cord c=*] + ^- [atom ^node] + => .(+< [b c]=+<) + [(rash b dem) c] + :: + ++ remove-graph (ot [%resource dejs:res]~) + ++ archive-graph (ot [%resource dejs:res]~) + ++ unarchive-graph (ot [%resource dejs:res]~) + :: + ++ add-nodes + %- ot + :~ [%resource dejs:res] + [%nodes nodes] + == + :: + ++ nodes (op ;~(pfix net (more net dem)) node) + :: + ++ node + %- ot + :~ [%post post] + :: TODO: support adding nodes with children by supporting the + :: graph key + [%children (of [%empty ul]~)] + == + :: + ++ post + %- ot + :~ [%author (su ;~(pfix sig fed:ag))] + [%index index] + [%time-sent di] + [%contents (ar content)] + [%hash (mu nu)] + [%signatures (as signature)] + == + :: + ++ content + %- of + :~ [%text so] + [%url so] + [%reference uid] + [%code eval] + == + :: + ++ eval + |= a=^json + ^- [cord (list tank)] + =, ^? dejs-soft:format + =+ exp=((ot expression+so ~) a) + %- need + ?~ exp [~ '' ~] + :+ ~ u.exp + :: NOTE: when sending, if output is an empty list, + :: graph-store will evaluate + (fall ((ot output+(ar dank) ~) a) ~) + :: + ++ remove-nodes + %- ot + :~ [%resource dejs:res] + [%indices (as index)] + == + :: + ++ add-signatures + %- ot + :~ [%uid uid] + [%signatures (as signature)] + == + :: + ++ remove-signatures + %- ot + :~ [%uid uid] + [%signatures (as signature)] + == + :: + ++ signature + %- ot + :~ [%hash nu] + [%ship (su ;~(pfix sig fed:ag))] + [%life ni] + == + :: + ++ uid + %- ot + :~ [%resource dejs:res] + [%index index] + == + :: + ++ index (su ;~(pfix net (more net dem))) + :: + ++ add-tag + %- ot + :~ [%term so] + [%resource dejs:res] + == + :: + ++ remove-tag + %- ot + :~ [%term so] + [%resource dejs:res] + == + :: + ++ keys + |= =json + *resources + :: + ++ tags + |= =json + *(set term) + :: + ++ tag-queries + |= =json + *^tag-queries + :: + ++ run-updates + |= a=json + ^- [resource update-log] + [*resource *update-log] + -- + -- +:: +++ create + |_ [our=ship now=time] + ++ post + |= [=index contents=(list content)] + ^- ^post + :* our + index + now + contents + ~ + *signatures + == + -- +-- diff --git a/pkg/arvo/lib/graph.hoon b/pkg/arvo/lib/graph.hoon new file mode 100644 index 0000000000..395c0554fa --- /dev/null +++ b/pkg/arvo/lib/graph.hoon @@ -0,0 +1,24 @@ +/- *resource +/+ store=graph-store +|_ =bowl:gall +++ scry-for + |* [=mold =path] + .^ mold + %gx + (scot %p our.bowl) + %graph-store + (scot %da now.bowl) + (snoc `^path`path %noun) + == +:: +++ get-graph + |= res=resource + ^- marked-graph:store + %+ scry-for marked-graph:store + /graph/(scot %p entity.res)/[name.res] +:: +++ peek-log + |= res=resource + ^- (unit time) + (scry-for (unit time) /peek-update-log/(scot %p entity.res)/[name.res]) +-- diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index 0afec46ceb..e7b91cfbe2 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -104,6 +104,7 @@ %s3-store %file-server %glob + %graph-store == :: ++ deft-fish :: default connects @@ -206,7 +207,7 @@ == :: ++ on-load - |= [hood-version=?(%1 %2 %3 %4 %5 %6 %7 %8) old=any-state] + |= [hood-version=?(%1 %2 %3 %4 %5 %6 %7 %8 %9) old=any-state] =< se-abet =< se-view =. sat old =. dev (~(gut by bin) ost *source) @@ -233,6 +234,8 @@ =? ..on-load (lte hood-version %8) => (se-born | %home %group-push-hook) (se-born | %home %group-pull-hook) + =? ..on-load (lte hood-version %9) + (se-born | %home %graph-store) ..on-load :: ++ reap-phat :: ack connect diff --git a/pkg/arvo/lib/push-hook.hoon b/pkg/arvo/lib/push-hook.hoon index 4958085a2a..776aa0f597 100644 --- a/pkg/arvo/lib/push-hook.hoon +++ b/pkg/arvo/lib/push-hook.hoon @@ -59,7 +59,6 @@ |~ [term tang] *[(list card) _^|(..on-init)] :: +resource-for-update: get affected resource from an update - ++ resource-for-update |~ vase *(unit resource) diff --git a/pkg/arvo/lib/signatures.hoon b/pkg/arvo/lib/signatures.hoon new file mode 100644 index 0000000000..12b58a644d --- /dev/null +++ b/pkg/arvo/lib/signatures.hoon @@ -0,0 +1,43 @@ +/- post +^? +=< [post .] +=, post +|% +++ sign + |= [our=ship now=time =hash] + ^- signature + =/ =life .^(life %j /=life/(scot %da now)/(scot %p our)) + =/ =ring .^(ring %j /=vein/(scot %da now)/(scot %ud life)) + :+ `@ux`(sign:as:(nol:nu:crub:crypto ring) hash) + our + life +:: +++ is-signature-valid + |= [=signature =hash now=time] + ^- ? + =/ deed=(unit [a=life b=pass c=(unit @ux)]) + .^ (unit [life pass (unit @ux)]) + %j + /=deed/(scot %da now)/(scot %p q.signature)/(scot %ud p.signature) + == + :: we do not have a public key from ship + :: + ?~ deed %.y + :: we do not have a public key from ship at this life + :: + ?. =(a.u.deed r.signature) %.y + :: verify signature from ship at life + :: + =(`hash (tear:as:crub:crypto b.u.deed p.signature)) +:: +++ are-signatures-valid + |= [=signatures =hash now=time] + ^- ? + =/ signature-list ~(tap in signatures) + |- + ?~ signature-list + %.y + ?: (is-signature-valid i.signature-list hash now) + $(signature-list t.signature-list) + %.n +-- diff --git a/pkg/arvo/mar/graph/update.hoon b/pkg/arvo/mar/graph/update.hoon new file mode 100644 index 0000000000..d5f0f4abec --- /dev/null +++ b/pkg/arvo/mar/graph/update.hoon @@ -0,0 +1,13 @@ +/+ *graph-store +|_ upd=update +++ grow + |% + ++ json (update:enjs upd) + -- +:: +++ grab + |% + ++ noun update + ++ json update:dejs + -- +-- diff --git a/pkg/arvo/mar/graph/validator/chat.hoon b/pkg/arvo/mar/graph/validator/chat.hoon new file mode 100644 index 0000000000..c493735145 --- /dev/null +++ b/pkg/arvo/mar/graph/validator/chat.hoon @@ -0,0 +1,17 @@ +/- *post +|_ i=indexed-post +++ grow + |% + ++ noun i + -- +++ grab + |% + ++ noun + |= p=* + =/ ip ;;(indexed-post p) + ?> ?=([@ ~] index.p.ip) + ip + -- +:: +++ grad %noun +-- diff --git a/pkg/arvo/sur/graph-store.hoon b/pkg/arvo/sur/graph-store.hoon new file mode 100644 index 0000000000..edcfb41359 --- /dev/null +++ b/pkg/arvo/sur/graph-store.hoon @@ -0,0 +1,61 @@ +/- *post +|% ++$ graph ((mop atom node) gth) ++$ marked-graph [p=graph q=(unit mark)] +:: ++$ node [=post children=internal-graph] ++$ graphs (map resource marked-graph) +:: ++$ tag-queries (jug term resource) +:: ++$ update-log ((mop time logged-update) gth) ++$ update-logs (map resource update-log) +:: ++$ internal-graph + $~ [%empty ~] + $% [%graph p=graph] + [%empty ~] + == +:: ++$ network + $: =graphs + =tag-queries + =update-logs + archive=graphs + validators=(set mark) + == +:: ++$ update + $% [%0 p=time q=update-0] + == +:: ++$ logged-update + $% [%0 p=time q=logged-update-0] + == +:: ++$ logged-update-0 + $% [%add-nodes =resource nodes=(map index node)] + [%remove-nodes =resource indices=(set index)] + [%add-signatures =uid =signatures] + [%remove-signatures =uid =signatures] + == +:: ++$ update-0 + $% logged-update-0 + [%add-graph =resource =graph mark=(unit mark)] + [%remove-graph =resource] + :: + [%add-tag =term =resource] + [%remove-tag =term =resource] + :: + [%archive-graph =resource] + [%unarchive-graph =resource] + [%run-updates =resource =update-log] + :: + :: NOTE: cannot be sent as pokes + :: + [%keys =resources] + [%tags tags=(set term)] + [%tag-queries =tag-queries] + == +-- diff --git a/pkg/arvo/sur/post.hoon b/pkg/arvo/sur/post.hoon new file mode 100644 index 0000000000..c5c354615c --- /dev/null +++ b/pkg/arvo/sur/post.hoon @@ -0,0 +1,37 @@ +/- *resource +|% ++$ index (list atom) ++$ uid [=resource =index] +:: +:: +sham (half sha-256) hash of +validated-portion ++$ hash @ux +:: ++$ signature [p=@ux q=ship r=life] ++$ signatures (set signature) ++$ post + $: author=ship + =index + time-sent=time + contents=(list content) + hash=(unit hash) + =signatures + == +:: ++$ indexed-post [a=atom p=post] +:: ++$ validated-portion + $: parent-hash=(unit hash) + author=ship + time-sent=time + contents=(list content) + == +:: ++$ content + $% [%text text=cord] + [%url url=cord] + [%code expression=cord output=(list tank)] + [%reference =uid] + :: TODO: maybe use a cask? + ::[%cage =cage] + == +-- diff --git a/pkg/arvo/sur/pull-hook.hoon b/pkg/arvo/sur/pull-hook.hoon index 81655a1818..1c66648c1d 100644 --- a/pkg/arvo/sur/pull-hook.hoon +++ b/pkg/arvo/sur/pull-hook.hoon @@ -8,5 +8,4 @@ +$ update $% [%tracking tracking=(map resource ship)] == -:: -- diff --git a/pkg/interface/src/apps/chat/components/lib/chat-input.js b/pkg/interface/src/apps/chat/components/lib/chat-input.js index 685ce25d68..b507d11142 100644 --- a/pkg/interface/src/apps/chat/components/lib/chat-input.js +++ b/pkg/interface/src/apps/chat/components/lib/chat-input.js @@ -57,24 +57,6 @@ export class ChatInput extends Component { this.editor = null; - // perf testing: - /* let closure = () => { - let x = 0; - for (var i = 0; i < 30; i++) { - x++; - props.api.chat.message( - props.station, - `~${window.ship}`, - Date.now(), - { - text: `${x}` - } - ); - } - setTimeout(closure, 1000); - }; - this.closure = closure.bind(this);*/ - moment.updateLocale('en', { relativeTime : { past: function(input) { @@ -284,8 +266,24 @@ export class ChatInput extends Component { message = []; } - // perf: - // setTimeout(this.closure, 2000); + // perf testing: + /*let closure = () => { + let x = 0; + for (var i = 0; i < 30; i++) { + x++; + props.api.chat.message( + props.station, + `~${window.ship}`, + Date.now(), + { + text: `${x}` + } + ); + } + setTimeout(closure, 1000); + }; + this.closure = closure.bind(this); + setTimeout(this.closure, 2000);*/ this.editor.setValue(''); } diff --git a/pkg/interface/src/apps/publish/components/lib/new-post.js b/pkg/interface/src/apps/publish/components/lib/new-post.js index 3700ba3597..8dd9d1cbef 100644 --- a/pkg/interface/src/apps/publish/components/lib/new-post.js +++ b/pkg/interface/src/apps/publish/components/lib/new-post.js @@ -25,6 +25,29 @@ export class NewPost extends Component { postSubmit() { const { state } = this; + + // perf testing: + /*let closure = () => { + let x = 0; + for (var i = 0; i < 5; i++) { + x++; + let rand = Math.floor(Math.random() * 1000); + const newNote = { + 'new-note': { + who: this.props.ship.slice(1), + book: this.props.book, + note: stringToSymbol(this.state.title + '-' + Date.now() + '-' + rand), + title: 'asdf-' + rand + '-' + Date.now(), + body: 'asdf-' + Date.now() + } + }; + + this.props.api.publishAction(newNote); + } + setTimeout(closure, 3000); + }; + setTimeout(closure, 2000);*/ + if (state.submit && !state.disabled) { const newNote = { 'new-note': { diff --git a/pkg/interface/src/reducers/invite-update.ts b/pkg/interface/src/reducers/invite-update.ts index d4b0f670c6..cea77f1638 100644 --- a/pkg/interface/src/reducers/invite-update.ts +++ b/pkg/interface/src/reducers/invite-update.ts @@ -50,7 +50,6 @@ export default class InviteReducer { accepted(json: InviteUpdate, state: S) { const data = _.get(json, 'accepted', false); if (data) { - console.log(data); delete state.invites[data.path][data.uid]; } } diff --git a/pkg/interface/src/reducers/metadata-update.ts b/pkg/interface/src/reducers/metadata-update.ts index 43d8b0492e..24d26b7bd3 100644 --- a/pkg/interface/src/reducers/metadata-update.ts +++ b/pkg/interface/src/reducers/metadata-update.ts @@ -11,12 +11,10 @@ export default class MetadataReducer { reduce(json: Cage, state: S) { let data = json['metadata-update'] if (data) { - console.log('data: ', data); this.associations(data, state); this.add(data, state); this.update(data, state); this.remove(data, state); - console.log('state: ', state); } } diff --git a/pkg/interface/src/store/publish.js b/pkg/interface/src/store/publish.js index fc70cbdded..32cfaef74a 100644 --- a/pkg/interface/src/store/publish.js +++ b/pkg/interface/src/store/publish.js @@ -48,4 +48,3 @@ export default class PublishStore extends BaseStore { this.responseReducer.reduce(data, this.state); } } -