diff --git a/pkg/arvo/app/chat-hook.hoon b/pkg/arvo/app/chat-hook.hoon index a0f7a4ee99..15e374624c 100644 --- a/pkg/arvo/app/chat-hook.hoon +++ b/pkg/arvo/app/chat-hook.hoon @@ -8,7 +8,7 @@ view=chat-view, *group /+ default-agent, verb, dbug, store=chat-store, group-store, grpl=group, - resource + resource, *migrate ~% %chat-hook-top ..is ~ |% +$ card card:agent:gall @@ -704,7 +704,12 @@ ++ poke-import |= arc=* ^- (quip card _state) - =/ sty=state-10 ;;(state-10 arc) + =/ sty=state-10 + :* %10 + (remake-map ;;((tree [path ship]) +<.arc)) + ;;(? +>-.arc) + (remake-map ;;((tree [path ?]) +>+.arc)) + == :_ sty %+ turn ~(tap by synced.sty) |= [=path =ship] diff --git a/pkg/arvo/app/chat-store.hoon b/pkg/arvo/app/chat-store.hoon index e1fab3631c..6726c12e00 100644 --- a/pkg/arvo/app/chat-store.hoon +++ b/pkg/arvo/app/chat-store.hoon @@ -2,7 +2,7 @@ :: :: data store that holds linear sequences of chat messages :: -/+ store=chat-store, default-agent, verb, dbug, group-store +/+ store=chat-store, default-agent, verb, dbug, group-store, *migrate ~% %chat-store-top ..is ~ |% +$ card card:agent:gall @@ -242,7 +242,7 @@ ++ poke-import |= arc=* ^- (quip card _state) - =/ sty=state-3 ;;(state-3 arc) + =/ sty=state-3 [%3 (remake-map ;;((tree [path mailbox:store]) +.arc))] [~ sty] :: ++ handle-create diff --git a/pkg/arvo/app/contact-hook.hoon b/pkg/arvo/app/contact-hook.hoon index 379b8fdc10..87767faac2 100644 --- a/pkg/arvo/app/contact-hook.hoon +++ b/pkg/arvo/app/contact-hook.hoon @@ -8,7 +8,14 @@ *metadata-hook, *metadata-store, *group -/+ *contact-json, default-agent, dbug, group-store, verb, resource, grpl=group +/+ *contact-json, + default-agent, + dbug, + group-store, + verb, + resource, + grpl=group, + *migrate ~% %contact-hook-top ..is ~ |% +$ card card:agent:gall @@ -286,7 +293,8 @@ ++ poke-import |= arc=* ^- (quip card _state) - =/ sty=state-three ;;(state-three arc) + =/ sty=state-three + [%3 (remake-map ;;((tree [path ship]) +<.arc)) ;;(? +>.arc)] :_ sty %+ turn ~(tap by synced.sty) |= [=path =ship] diff --git a/pkg/arvo/app/contact-store.hoon b/pkg/arvo/app/contact-store.hoon index 8ed19228a0..7f4323a640 100644 --- a/pkg/arvo/app/contact-store.hoon +++ b/pkg/arvo/app/contact-store.hoon @@ -2,7 +2,7 @@ :: :: data store that holds group-based contact data :: -/+ *contact-json, default-agent, dbug +/+ *contact-json, default-agent, dbug, *migrate |% +$ card card:agent:gall +$ versioned-state @@ -207,7 +207,10 @@ ++ poke-import |= arc=* ^- (quip card _state) - =/ sty=state-three ;;(state-three arc) + =/ sty=state-three + :- %3 + %- remake-map-of-map + ;;((tree [path (tree [ship contact])]) +.arc) [~ sty] :: ++ handle-create diff --git a/pkg/arvo/app/contact-view.hoon b/pkg/arvo/app/contact-view.hoon index 2abbbb0f67..4350e9d439 100644 --- a/pkg/arvo/app/contact-view.hoon +++ b/pkg/arvo/app/contact-view.hoon @@ -181,22 +181,7 @@ ~[(add-pending rid ship.act)] :: %delete - =/ rid=resource - (de-path:resource path.act) - =/ group-pokes=(list card) - ?: =(our.bol entity.rid) - ~[(group-push-poke %remove rid)] - :~ (group-proxy-poke %remove-members rid (sy our.bol ~)) - (group-pull-poke %remove rid) - == - ;: weld - group-pokes - :~ (contact-hook-poke [%remove path.act]) - (group-poke [%remove-group rid ~]) - (contact-poke [%delete path.act]) - == - (delete-metadata path.act) - == + ~ :: %remove =/ rid=resource @@ -357,13 +342,6 @@ (metadata-hook-poke [%add-owned path]) == :: -++ delete-metadata - |= =path - ^- (list card) - :~ (metadata-poke [%remove path [%contacts path]]) - (metadata-hook-poke [%remove path]) - == -:: ++ all-scry ^- rolodex .^(rolodex %gx /(scot %p our.bol)/contact-store/(scot %da now.bol)/all/noun) diff --git a/pkg/arvo/app/graph-store.hoon b/pkg/arvo/app/graph-store.hoon index 1104fb4129..4af84305a0 100644 --- a/pkg/arvo/app/graph-store.hoon +++ b/pkg/arvo/app/graph-store.hoon @@ -1,7 +1,8 @@ :: graph-store [landscape] :: :: -/+ store=graph-store, sigs=signatures, res=resource, default-agent, dbug +/+ store=graph-store, sigs=signatures, res=resource, default-agent, dbug, + *migrate ~% %graph-store-top ..is ~ |% +$ card card:agent:gall @@ -617,7 +618,8 @@ ++ poke-import |= arc=* ^- (quip card _state) - =/ sty ;;(state-2 arc) + |^ + =/ sty=state-2 [%2 (remake-network ;;(tree-network +.arc))] :_ sty %+ turn ~(tap by graphs.sty) |= [rid=resource:store =marked-graph:store] @@ -626,6 +628,130 @@ =/ =cage [%push-hook-action !>([%add rid])] [%pass / %agent [our.bowl %graph-push-hook] %poke cage] (try-rejoin rid 0) + :: + +$ tree-network + $: graphs=tree-graphs + tag-queries=(tree [term (tree resource:store)]) + update-logs=tree-update-logs + archive=tree-graphs + validators=(tree ^mark) + == + +$ tree-graphs (tree [resource:store tree-marked-graph]) + +$ tree-marked-graph [p=tree-graph q=(unit ^mark)] + +$ tree-graph (tree [atom tree-node]) + +$ tree-node [post=tree-post children=tree-internal-graph] + +$ tree-internal-graph + $~ [%empty ~] + $% [%graph p=tree-graph] + [%empty ~] + == + +$ tree-update-logs (tree [resource:store tree-update-log]) + +$ tree-update-log (tree [time tree-logged-update]) + +$ tree-logged-update + $: %0 + p=time + $= q + $% [%add-nodes =resource:store nodes=(tree [index:store tree-node])] + [%remove-nodes =resource:store indices=(tree index:store)] + [%add-signatures =uid:store signatures=tree-signatures] + [%remove-signatures =uid:store signatures=tree-signatures] + == + == + +$ tree-signatures (tree signature:store) + +$ tree-post + $: author=ship + =index:store + time-sent=time + contents=(list content:store) + hash=(unit hash:store) + signatures=tree-signatures + == + :: + ++ remake-network + |= t=tree-network + ^- network:store + :* (remake-graphs graphs.t) + (remake-jug tag-queries.t) + (remake-update-logs update-logs.t) + (remake-graphs archive.t) + (remake-set validators.t) + == + :: + ++ remake-graphs + |= t=tree-graphs + ^- graphs:store + %- remake-map + (~(run by t) remake-marked-graph) + :: + ++ remake-marked-graph + |= t=tree-marked-graph + ^- marked-graph:store + [(remake-graph p.t) q.t] + :: + ++ remake-graph + |= t=tree-graph + ^- graph:store + %+ gas:orm *graph:store + %+ turn ~(tap by t) + |= [a=atom tn=tree-node] + ^- [atom node:store] + [a (remake-node tn)] + :: + ++ remake-internal-graph + |= t=tree-internal-graph + ^- internal-graph:store + ?: ?=(%empty -.t) + [%empty ~] + [%graph (remake-graph p.t)] + :: + ++ remake-node + |= t=tree-node + ^- node:store + :- (remake-post post.t) + (remake-internal-graph children.t) + :: + ++ remake-update-logs + |= t=tree-update-logs + ^- update-logs:store + %- remake-map + (~(run by t) remake-update-log) + :: + ++ remake-update-log + |= t=tree-update-log + ^- update-log:store + =/ ulm ((ordered-map time logged-update:store) gth) + %+ gas:ulm *update-log:store + %+ turn ~(tap by t) + |= [=time tlu=tree-logged-update] + ^- [^time logged-update:store] + [time (remake-logged-update tlu)] + :: + ++ remake-logged-update + |= t=tree-logged-update + ^- logged-update:store + :+ %0 p.t + ?- -.q.t + %add-nodes + :- %add-nodes + :- resource.q.t + %- remake-map + (~(run by nodes.q.t) remake-node) + :: + %remove-nodes + [%remove-nodes resource.q.t (remake-set indices.q.t)] + :: + %add-signatures + [%add-signatures uid.q.t (remake-set signatures.q.t)] + :: + %remove-signatures + [%remove-signatures uid.q.t (remake-set signatures.q.t)] + == + :: + ++ remake-post + |= t=tree-post + ^- post:store + t(signatures (remake-set signatures.t)) + -- :: ++ try-rejoin |= [rid=resource:store nack-count=@] @@ -837,10 +963,11 @@ [~ this] =/ rid=resource:store (de-path:res t.t.wire) ?~ p.sign - :: leave and poke our graph-pull-hook =/ =cage [%pull-hook-action !>([%add entity.rid rid])] :_ this - [%pass / %agent [our.bowl %graph-pull-hook] %poke cage]~ + :~ [%pass / %agent [our.bowl %graph-pull-hook] %poke cage] + [%pass wire %agent [entity.rid %graph-push-hook] %leave ~] + == =/ nack-count=@ud (slav %ud i.t.wire) =/ wakeup=@da (add now.bowl (mul ~s1 (bex (min 19 nack-count)))) diff --git a/pkg/arvo/app/group-store.hoon b/pkg/arvo/app/group-store.hoon index f61d145699..0a838195e1 100644 --- a/pkg/arvo/app/group-store.hoon +++ b/pkg/arvo/app/group-store.hoon @@ -30,7 +30,7 @@ :: :: /- *group, permission-store, *contact-view -/+ store=group-store, default-agent, verb, dbug, resource +/+ store=group-store, default-agent, verb, dbug, resource, *migrate |% +$ card card:agent:gall :: @@ -285,23 +285,61 @@ ++ poke-import |= arc=* ^- (quip card _state) - =/ sty=state-one ;;(state-one arc) + |^ + =/ sty=state-one + [%1 (remake-groups ;;((tree [resource tree-group]) +.arc))] :_ sty %+ roll ~(tap by groups.sty) - |= [[=resource =group] out=(list card)] - ?: =(entity.resource our.bol) + |= [[rid=resource grp=group] out=(list card)] + ?: =(entity.rid our.bol) %+ weld out - %+ roll ~(tap in members.group) + %+ roll ~(tap in members.grp) |= [recipient=@p out=(list card)] ?: =(recipient our.bol) out :_ out %- poke-contact - :* %invite resource recipient - (crip "Rejoin disconnected group {}/{}") + :* %invite rid recipient + (crip "Rejoin disconnected group {}/{}") == :_ out - (try-rejoin resource 0) + (try-rejoin rid 0) + :: + ++ remake-groups + |= grps=(tree [resource tree-group]) + ^- ^groups + %- remake-map + (~(run by grps) remake-group) + :: + ++ remake-group + |= grp=tree-group + ^- group + %= grp + members (remake-set members.grp) + tags (remake-jug tags.grp) + policy (remake-policy policy.grp) + == + :: + +$ tree-group + $: members=(tree ship) + tags=(tree [tag (tree ship)]) + policy=tree-policy + hidden=? + == + :: + +$ tree-policy + $% [%invite pending=(tree ship)] + [%open ban-ranks=(tree rank:title) banned=(tree ship)] + == + :: + ++ remake-policy + |= pl=tree-policy + ^- policy + ?- -.pl + %invite [%invite (remake-set pending.pl)] + %open [%open (remake-set ban-ranks.pl) (remake-set banned.pl)] + == + -- :: ++ try-rejoin |= [rid=resource nack-count=@ud] diff --git a/pkg/arvo/app/invite-store.hoon b/pkg/arvo/app/invite-store.hoon index 5e504be746..ae74a4e5f0 100644 --- a/pkg/arvo/app/invite-store.hoon +++ b/pkg/arvo/app/invite-store.hoon @@ -1,6 +1,6 @@ :: invite-store [landscape] /- store=invite-store -/+ res=resource, default-agent, dbug +/+ res=resource, default-agent, dbug, *migrate |% +$ card card:agent:gall +$ versioned-state @@ -109,7 +109,10 @@ ++ poke-import |= arc=* ^- (quip card _state) - =/ sty=state-1 ;;(state-1 arc) + =/ sty=state-1 + :- %1 + %- remake-map-of-map + ;;((tree [term (tree [serial:store invite:store])]) +.arc) [~ sty] :: ++ poke-invite-action diff --git a/pkg/arvo/app/metadata-hook.hoon b/pkg/arvo/app/metadata-hook.hoon index 1d3e6dbcef..2558a44816 100644 --- a/pkg/arvo/app/metadata-hook.hoon +++ b/pkg/arvo/app/metadata-hook.hoon @@ -6,7 +6,7 @@ :: /group/%group-path all updates related to this group :: /- *metadata-store, *metadata-hook -/+ default-agent, dbug, verb, grpl=group +/+ default-agent, dbug, verb, grpl=group, *migrate ~% %metadata-hook-top ..is ~ |% +$ card card:agent:gall @@ -196,7 +196,8 @@ ++ poke-import |= arc=* ^- (quip card _state) - =/ sty=state-one ;;(state-one arc) + =/ sty=state-one + [%1 (remake-map ;;((tree [group-path ship]) +.arc))] :_ sty %+ murn ~(tap by synced.sty) |= [=group-path =ship] diff --git a/pkg/arvo/app/metadata-store.hoon b/pkg/arvo/app/metadata-store.hoon index 402e39501d..10ca142d0d 100644 --- a/pkg/arvo/app/metadata-store.hoon +++ b/pkg/arvo/app/metadata-store.hoon @@ -24,7 +24,7 @@ :: /group/%group-path associations for group :: /- *metadata-store, *metadata-hook -/+ *metadata-json, default-agent, verb, dbug, resource +/+ *metadata-json, default-agent, verb, dbug, resource, *migrate |% +$ card card:agent:gall +$ base-state-0 @@ -378,8 +378,27 @@ ++ poke-import |= arc=* ^- (quip card _state) - =/ sty=state-6 ;;(state-6 arc) + |^ + =/ sty=state-6 + [%6 (remake-metadata ;;(tree-metadata +.arc))] [~ sty] + :: + +$ tree-metadata + $: associations=(tree [[group-path md-resource] metadata]) + group-indices=(tree [group-path (tree md-resource)]) + app-indices=(tree [app-name (tree [group-path app-path])]) + resource-indices=(tree [md-resource (tree group-path)]) + == + :: + ++ remake-metadata + |= tm=tree-metadata + ^- base-state-1 + :* (remake-map associations.tm) + (remake-jug group-indices.tm) + (remake-jug app-indices.tm) + (remake-jug resource-indices.tm) + == + -- :: ++ handle-add |= [=group-path =md-resource =metadata] diff --git a/pkg/arvo/app/observe-hook.hoon b/pkg/arvo/app/observe-hook.hoon index 174b90b13c..9f93de49a1 100644 --- a/pkg/arvo/app/observe-hook.hoon +++ b/pkg/arvo/app/observe-hook.hoon @@ -10,10 +10,13 @@ +$ card card:agent:gall +$ versioned-state $% state-0 + state-1 == :: +$ serial @uv +$ state-0 [%0 observers=(map serial observer:sur)] ++$ state-1 [%1 observers=(map serial observer:sur)] +:: ++ got-by-val |= [a=(map serial observer:sur) b=observer:sur] ^- serial @@ -24,7 +27,7 @@ -- :: %- agent:dbug -=| state-0 +=| state-1 =* state - :: ^- agent:gall @@ -35,8 +38,14 @@ ++ on-init |^ ^- (quip card _this) :_ this - :_ ~ - (act /inv-gra [%watch %invite-store /invitatory/graph %invite-accepted-graph]) + :~ %+ act + /inv-gra + [%watch %invite-store /invitatory/graph %invite-accepted-graph] + :: + %+ act + /grp-gra + [%watch %group-store /groups %group-on-leave] + == :: ++ act |= [=wire =action:sur] @@ -56,7 +65,17 @@ ++ on-load |= old-vase=vase ^- (quip card _this) - `this(state !<(state-0 old-vase)) + =/ old-state !<(versioned-state old-vase) + ?- -.old-state + %1 `this(state old-state) + :: + %0 + =. state [%1 observers.old-state] + %+ on-poke + %observe-action + !> ^- action:sur + [%watch %group-store /groups %group-on-leave] + == :: ++ on-poke |= [=mark =vase] diff --git a/pkg/arvo/lib/group-store.hoon b/pkg/arvo/lib/group-store.hoon index 56e663301f..e2a14576b7 100644 --- a/pkg/arvo/lib/group-store.hoon +++ b/pkg/arvo/lib/group-store.hoon @@ -417,6 +417,7 @@ :: ++ remove-group |= =json + ^- [resource ~] ?> ?=(%o -.json) =/ rid=resource (dejs:resource (~(got by p.json) 'resource')) diff --git a/pkg/arvo/lib/migrate.hoon b/pkg/arvo/lib/migrate.hoon new file mode 100644 index 0000000000..2f1d3b0152 --- /dev/null +++ b/pkg/arvo/lib/migrate.hoon @@ -0,0 +1,19 @@ +|% +++ remake-set + |* s=(tree) + (sy ~(tap in s)) +:: +++ remake-map + |* m=(tree) + (my ~(tap by m)) +:: +++ remake-jug + |* j=(tree [* (tree)]) + %- remake-map + (~(run by j) remake-set) +:: +++ remake-map-of-map + |* mm=(tree [* (tree)]) + %- remake-map + (~(run by mm) remake-map) +-- diff --git a/pkg/arvo/lib/strandio.hoon b/pkg/arvo/lib/strandio.hoon index bc17a28359..7fa9da0fa3 100644 --- a/pkg/arvo/lib/strandio.hoon +++ b/pkg/arvo/lib/strandio.hoon @@ -219,6 +219,25 @@ ;< ~ bind:m (send-raw-card card) (take-poke-ack /poke) :: +++ raw-poke + |= [=dock =cage] + =/ m (strand ,~) + ^- form:m + =/ =card:agent:gall [%pass /poke %agent dock %poke cage] + ;< ~ bind:m (send-raw-card card) + =/ m (strand ,~) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ + `[%wait ~] + :: + [~ %agent * %poke-ack *] + ?. =(/poke wire.u.in.tin) + `[%skip ~] + `[%done ~] + == +:: ++ poke-our |= [=term =cage] =/ m (strand ,~) diff --git a/pkg/arvo/ted/group/on-leave.hoon b/pkg/arvo/ted/group/on-leave.hoon new file mode 100644 index 0000000000..aa3fcad4e2 --- /dev/null +++ b/pkg/arvo/ted/group/on-leave.hoon @@ -0,0 +1,94 @@ +/- spider, grp=group-store, gra=graph-store, met=metadata-store, con=contact-store +/+ strandio, res=resource +:: +=* strand strand:spider +=* raw-poke raw-poke:strandio +=* scry scry:strandio +:: +^- thread:spider +|= arg=vase +=/ m (strand ,vase) +^- form:m +=+ !<([=update:grp ~] arg) +?. ?=(%remove-group -.update) + (pure:m !>(~)) +;< =bowl:spider bind:m get-bowl:strandio +:: tell group host to remove us as member +:: +;< ~ bind:m + %+ raw-poke + [entity.resource.update %group-push-hook] + :- %group-update + !> ^- update:grp + [%remove-members resource.update (silt [our.bowl ~])] +:: stop serving or syncing group updates +:: +;< ~ bind:m + %+ raw-poke + [our.bowl %group-push-hook] + :- %push-hook-action + !>([%remove resource.update]) +;< ~ bind:m + %+ raw-poke + [our.bowl %group-pull-hook] + :- %pull-hook-action + !>([%remove resource.update]) +:: stop serving or syncing contacts associated with group +:: +;< ~ bind:m + %+ raw-poke + [our.bowl %contact-hook] + :- %contact-hook-action + !>([%remove (en-path:res resource.update)]) +:: remove contact data associated with group +:: +;< ~ bind:m + %+ raw-poke + [our.bowl %contact-store] + :- %contact-action + !> ^- contact-action:con + [%delete (en-path:res resource.update)] +:: stop serving or syncing metadata associated with group +:: +;< ~ bind:m + %+ raw-poke + [our.bowl %metadata-hook] + :- %metadata-hook-action + !>([%remove (en-path:res resource.update)]) +:: get metadata associated with group +:: +;< =associations:met bind:m + %+ scry associations:met + ;: weld + /gx/metadata-store/group + (en-path:res resource.update) + /noun + == +=/ entries=(list [g=group-path:met m=md-resource:met]) + ~(tap in ~(key by associations)) +|- ^- form:m +=* loop $ +?~ entries + (pure:m !>(~)) +:: remove metadata associated with group +:: +;< ~ bind:m + %+ raw-poke + [our.bowl %metadata-store] + :- %metadata-action + !> ^- metadata-action:met + [%remove g.i.entries m.i.entries] +:: archive graph associated with group +:: +;< ~ bind:m + %+ raw-poke + [our.bowl %graph-store] + :- %graph-update + !> ^- update:gra + [%0 now.bowl [%archive-graph (de-path:res app-path.m.i.entries)]] +;< ~ bind:m + %+ raw-poke + [our.bowl %graph-pull-hook] + :- %pull-hook-action + !>([%remove (de-path:res app-path.m.i.entries)]) +loop(entries t.entries) diff --git a/pkg/interface/src/logic/api/contacts.ts b/pkg/interface/src/logic/api/contacts.ts index 27f8faf25c..3049442f5a 100644 --- a/pkg/interface/src/logic/api/contacts.ts +++ b/pkg/interface/src/logic/api/contacts.ts @@ -32,10 +32,6 @@ export default class ContactsApi extends BaseApi { }); } - delete(path: Path) { - return this.viewAction({ delete: { path } }); - } - remove(path: Path, ship: Patp) { return this.viewAction({ remove: { path, ship } }); } diff --git a/pkg/interface/src/logic/api/groups.ts b/pkg/interface/src/logic/api/groups.ts index cdd1514ecc..3901149fd2 100644 --- a/pkg/interface/src/logic/api/groups.ts +++ b/pkg/interface/src/logic/api/groups.ts @@ -26,6 +26,10 @@ export default class GroupsApi extends BaseApi { return this.proxyAction({ addMembers: { resource, ships } }); } + removeGroup(resource: Resource) { + return this.storeAction({ removeGroup: { resource } }); + } + changePolicy(resource: Resource, diff: Enc) { return this.proxyAction({ changePolicy: { resource, diff } }); } @@ -35,6 +39,7 @@ export default class GroupsApi extends BaseApi { } private storeAction(action: GroupAction) { - return this.action('group-store', 'group-action', action); + console.log(action); + return this.action('group-store', 'group-update', action); } } diff --git a/pkg/interface/src/views/landscape/components/GroupSettings/Personal.tsx b/pkg/interface/src/views/landscape/components/GroupSettings/Personal.tsx index 7d4838d2ab..240a8f12a5 100644 --- a/pkg/interface/src/views/landscape/components/GroupSettings/Personal.tsx +++ b/pkg/interface/src/views/landscape/components/GroupSettings/Personal.tsx @@ -38,7 +38,8 @@ function DeleteGroup(props: { const shouldDelete = (prompt(`To confirm deleting this group, type ${name}`) === name); if (!shouldDelete) return; } - await props.api.contacts.delete(props.association["group-path"]); + const resource = resourceFromPath(props.association["group-path"]) + await props.api.groups.removeGroup(resource); history.push("/"); };