Merge pull request #3479 from urbit/lf/graph-be

graph-view backend
This commit is contained in:
L 2020-09-15 15:48:44 -05:00 committed by GitHub
commit bbeaa0690e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 751 additions and 28 deletions

View File

@ -100,9 +100,7 @@
?~ path
:: new subscribe
::
=/ [=graph:store mark=(unit mark:store)]
(get-graph:gra resource)
[%0 now.bowl [%add-graph resource graph mark]]
(get-graph:gra resource)
:: resubscribe
::
=/ =time (slav %da i.path)

View File

@ -1,5 +1,5 @@
/- spider
/+ libstrand=strand, default-agent, verb
/+ libstrand=strand, default-agent, verb, server
=, strand=strand:libstrand
|%
+$ card card:agent:gall
@ -17,15 +17,25 @@
$: starting=(map yarn [=trying =vase])
running=trie
tid=(map tid yarn)
serving=(map tid [@ta =mark])
==
::
+$ clean-slate-any
$^ clean-slate-ket
$% clean-slate-sig
clean-slate-1
clean-slate
==
::
+$ clean-slate
$: %2
starting=(map yarn [=trying =vase])
running=(list yarn)
tid=(map tid yarn)
serving=(map tid [@ta =mark])
==
::
+$ clean-slate-1
$: %1
starting=(map yarn [=trying =vase])
running=(list yarn)
@ -133,7 +143,10 @@
sc ~(. spider-core bowl)
def ~(. (default-agent this %|) bowl)
::
++ on-init on-init:def
++ on-init
^- (quip card _this)
:_ this
~[bind-eyre:sc]
++ on-save clean-state:sc
++ on-load
|^
@ -141,7 +154,9 @@
=+ !<(any=clean-slate-any old-state)
=? any ?=(^ -.any) (old-to-1 any)
=? any ?=(~ -.any) (old-to-1 any)
?> ?=(%1 -.any)
=^ upgrade-cards any
(old-to-2 any)
?> ?=(%2 -.any)
::
=. tid.state tid.any
=/ yarns=(list yarn)
@ -154,12 +169,26 @@
(handle-stop-thread:sc (yarn-to-tid i.yarns) |)
=^ cards-2 this
$(yarns t.yarns)
[(weld cards-1 cards-2) this]
[:(weld upgrade-cards cards-1 cards-2) this]
::
++ old-to-1
|= old=clean-slate-ket
^- clean-slate
^- clean-slate-1
1+old(starting (~(run by starting.old) |=([* v=vase] none+v)))
::
++ old-to-2
|= old=clean-slate-any
^- (quip card clean-slate)
?> ?=(?(%1 %2) -.old)
?: ?=(%2 -.old)
`old
:- ~[bind-eyre:sc]
:* %2
starting.old
running.old
tid.old
~
==
--
::
++ on-poke
@ -172,6 +201,9 @@
%spider-input (on-poke-input:sc !<(input vase))
%spider-start (handle-start-thread:sc !<(start-args vase))
%spider-stop (handle-stop-thread:sc !<([tid ?] vase))
::
%handle-http-request
(handle-http-request:sc !<([@ta =inbound-request:eyre] vase))
==
[cards this]
::
@ -182,6 +214,7 @@
?+ path (on-watch:def path)
[%thread @ *] (on-watch:sc t.path)
[%thread-result @ ~] (on-watch-result:sc i.t.path)
[%http-response *] `state
==
[cards this]
::
@ -216,6 +249,7 @@
?+ wire (on-arvo:def wire sign-arvo)
[%thread @ *] (handle-sign:sc i.t.wire t.t.wire sign-arvo)
[%build @ ~] (handle-build:sc i.t.wire sign-arvo)
[%bind ~] `state
==
[cards this]
:: On unexpected failure, kill all outstanding strands
@ -228,6 +262,41 @@
--
::
|_ =bowl:gall
::
++ bind-eyre
^- card
[%pass /bind %arvo %e %connect [~ /spider] %spider]
::
++ handle-http-request
|= [eyre-id=@ta =inbound-request:eyre]
^- (quip card _state)
?> authenticated.inbound-request
=/ url
(parse-request-line:server url.request.inbound-request)
?> ?=([%spider @t @t @t ~] site.url)
=* input-mark i.t.site.url
=* thread i.t.t.site.url
=* output-mark i.t.t.t.site.url
=/ =tid
(scot %uv (sham eny.bowl))
=. serving.state
(~(put by serving.state) tid [eyre-id output-mark])
=+ .^
=tube:clay
%cc
/(scot %p our.bowl)/[q.byk.bowl]/(scot %da now.bowl)/json/[input-mark]
==
?> ?=(^ body.request.inbound-request)
=/ body=json
(need (de-json:html q.u.body.request.inbound-request))
=/ input=vase
(tube !>(body))
=/ =start-args
[~ `tid thread input]
=^ cards state
(handle-start-thread start-args)
[cards state]
::
++ on-poke-input
|= input
=/ yarn (~(got by tid.state) tid)
@ -394,6 +463,25 @@
:~ [%give %fact ~[/thread-result/[tid]] %thread-fail !>([term tang])]
[%give %kick ~[/thread-result/[tid]] ~]
==
++ thread-http-fail
|= [=tid =term =tang]
^- (quip card ^state)
=- (fall - `state)
%+ bind
(~(get by serving.state) tid)
|= [eyre-id=@ta output=mark]
:_ state(serving (~(del by serving.state) tid))
%+ give-simple-payload:app:server eyre-id
^- simple-payload:http
:_ ~ :_ ~
?. ?=(http-error:spider term)
((slog tang) 500)
?- term
%bad-request 400
%forbidden 403
%nonexistent 404
%offline 504
==
::
++ thread-fail
|= [=yarn =term =tang]
@ -402,7 +490,24 @@
=/ =tid (yarn-to-tid yarn)
=/ fail-cards (thread-say-fail tid term tang)
=^ cards state (thread-clean yarn)
[(weld fail-cards cards) state]
=^ http-cards state (thread-http-fail tid term tang)
[:(weld fail-cards cards http-cards) state]
::
++ thread-http-response
|= [=tid =vase]
^- (quip card ^state)
=- (fall - `state)
%+ bind
(~(get by serving.state) tid)
|= [eyre-id=@ta output=mark]
=+ .^
=tube:clay
%cc
/(scot %p our.bowl)/[q.byk.bowl]/(scot %da now.bowl)/[output]/json
==
:_ state(serving (~(del by serving.state) tid))
%+ give-simple-payload:app:server eyre-id
(json-response:gen:server !<(json (tube vase)))
::
++ thread-done
|= [=yarn =vase]
@ -413,8 +518,10 @@
:~ [%give %fact ~[/thread-result/[tid]] %thread-done vase]
[%give %kick ~[/thread-result/[tid]] ~]
==
=^ http-cards state
(thread-http-response tid vase)
=^ cards state (thread-clean yarn)
[(weld done-cards cards) state]
[:(weld done-cards cards http-cards) state]
::
++ thread-clean
|= =yarn
@ -474,5 +581,5 @@
::
++ clean-state
!> ^- clean-slate
1+state(running (turn (tap-yarn running.state) head))
2+state(running (turn (tap-yarn running.state) head))
--

View File

@ -0,0 +1,61 @@
/- sur=graph-view
/+ resource, group-store
^?
=< [sur .]
=, sur
|%
++ dejs
=, dejs:format
|%
++ action
|^
^- $-(json ^action)
%- of
:~ create+create
delete+delete
join+join
leave+leave
groupify+groupify
::invite+invite
==
::
++ create
%- ou
:~ resource+(un dejs:resource)
title+(un so)
description+(un so)
mark+(uf ~ (mu so))
associated+(un associated)
==
::
++ leave
%- ot
:~ resource+dejs:resource
==
::
++ delete
%- ot
:~ resource+dejs:resource
==
::
++ join
%- ot
:~ resource+dejs:resource
ship+(su ;~(pfix sig fed:ag))
==
::
++ groupify
%- ou
:~ resource+(un dejs:resource)
to+(uf ~ (mu dejs:resource))
==
++ invite !!
::
++ associated
%- of
:~ group+dejs:resource
policy+policy:dejs:group-store
==
--
--
--

View File

@ -13,10 +13,16 @@
::
++ get-graph
|= res=resource
^- marked-graph:store
%+ scry-for marked-graph:store
^- update:store
%+ scry-for update:store
/graph/(scot %p entity.res)/[name.res]
::
++ get-update-log
|= rid=resource
^- update-log:store
%+ scry-for update-log:store
/update-log/(scot %p entity.rid)/[name.rid]
::
++ peek-update-log
|= res=resource
^- (unit time)

View File

@ -241,6 +241,16 @@
;< our=@p bind:m get-our
(watch wire [our term] path)
::
++ scry
|* [=mold =path]
=/ m (strand ,mold)
^- form:m
?> ?=(^ path)
?> ?=(^ t.path)
;< =bowl:spider bind:m get-bowl
%- pure:m
.^(mold i.path (scot %p our.bowl) i.t.path (scot %da now.bowl) t.t.path)
::
++ leave
|= [=wire =dock]
=/ m (strand ,~)
@ -285,6 +295,20 @@
[%pass /wait/(scot %da until) %arvo %b %wait until]
(send-raw-card card)
::
++ map-err
|* computation-result=mold
=/ m (strand ,computation-result)
|= [f=$-([term tang] [term tang]) computation=form:m]
^- form:m
|= tin=strand-input:strand
=* loop $
=/ c-res (computation tin)
?: ?=(%cont -.next.c-res)
c-res(self.next ..loop(computation self.next.c-res))
?. ?=(%fail -.next.c-res)
c-res
c-res(err.next (f err.next.c-res))
::
++ set-timeout
|* computation-result=mold
=/ m (strand ,computation-result)
@ -478,6 +502,17 @@
`[%skip ~]
`[%done +>.sign-arvo.u.in.tin]
==
:: +check-online: require that peer respond before timeout
::
++ check-online
|= [who=ship lag=@dr]
=/ m (strand ,~)
^- form:m
%+ (map-err ,~) |=(* [%offline *tang])
%+ (set-timeout ,~) lag
;< ~ bind:m
(poke [who %hood] %helm-hi !>(~))
(pure:m ~)
::
:: Queue on skip, try next on fail %ignore
::

View File

@ -1,7 +1,9 @@
/+ *graph-store
|_ upd=update
++ grad %noun
++ grow
|%
++ noun upd
++ json (update:enjs upd)
--
::

View File

@ -0,0 +1,13 @@
/+ *graph-view
|_ act=action
++ grad %noun
++ grow
|%
++ noun act
--
++ grab
|%
++ noun action
++ json action:dejs
--
--

View File

@ -0,0 +1,44 @@
/- *group
/+ resource
^?
|%
:: $associated: A group to associate, or a policy if it is unmanaged
::
+$ associated
$% [%group rid=resource]
[%policy =policy]
==
::
:: $error: An error from a graph-view poke
::
:: %offline: Ship is offline
:: %bad-perms: Not permitted
:: %unknown: Anything not described above
::
+$ error
?(%offline %bad-perms %unknown)
:: $action: A semantic action on graphs
::
:: %create: Create a graph and associated metadata
:: %delete: Delete a graph
:: %join: Join a graph
:: %invite: Invite users to a graph
:: %groupify: Make graph into managed group
::
+$ action
$%
$: %create
rid=resource
title=@t
description=@t
mark=(unit mark)
=associated
==
[%delete rid=resource]
[%leave rid=resource]
[%join rid=resource =ship]
::[%invite rid=resource ships=(set ship)]
[%groupify rid=resource to=(unit resource)]
==
--

View File

@ -5,4 +5,10 @@
+$ input [=tid =cage]
+$ tid tid:strand
+$ bowl bowl:strand
+$ http-error
$? %bad-request :: 400
%forbidden :: 403
%nonexistent :: 404
%offline :: 504
==
--

View File

@ -0,0 +1,60 @@
/- spider, graph=graph-store, *metadata-store, *group, group-store
/+ strandio, resource, graph-view
=>
|%
++ strand strand:spider
++ poke poke:strandio
++ poke-our poke-our:strandio
::
++ handle-group
|= [rid=resource =associated:graph-view]
=/ m (strand ,resource)
?: ?=(%group -.associated)
(pure:m rid.associated)
=/ =action:group-store
[%add-group rid policy.associated %&]
;< ~ bind:m (poke-our %group-store %group-action !>(action))
;< ~ bind:m
(poke-our %group-push-hook %push-hook-action !>([%add rid]))
(pure:m rid)
--
::
=, strand=strand:spider
^- thread:spider
|= arg=vase
=/ m (strand ,vase)
^- form:m
=+ !<(=action:graph-view arg)
?> ?=(%create -.action)
;< =bowl:spider bind:m get-bowl:strandio
:: Add graph to graph-store
::
?. =(our.bowl entity.rid.action)
(strand-fail:strandio %bad-request ~)
=/ =update:graph
[%0 now.bowl %add-graph rid.action *graph:graph mark.action]
;< ~ bind:m
(poke-our %graph-store graph-update+!>(update))
;< ~ bind:m
(poke-our %graph-push-hook %push-hook-action !>([%add rid.action]))
:: Add group, if graph is unmanaged
::
;< group=resource bind:m
(handle-group rid.action associated.action)
=/ group-path=path
(en-path:resource group)
:: Setup metadata
::
=/ =metadata
%* . *metadata
title title.action
description description.action
date-created now.bowl
creator our.bowl
==
=/ act=metadata-action
[%add group-path graph+(en-path:resource rid.action) metadata]
;< ~ bind:m (poke-our %metadata-hook %metadata-action !>(act))
;< ~ bind:m
(poke-our %metadata-hook %metadata-hook-action !>([%add-owned group-path]))
(pure:m !>(~))

View File

@ -0,0 +1,70 @@
/- spider, graph-view, graph=graph-store, *metadata-store, *group
/+ strandio, resource
=>
|%
++ strand strand:spider
++ poke poke:strandio
++ poke-our poke-our:strandio
::
++ scry-metadata
|= rid=resource
=/ m (strand ,(unit resource))
;< paxs=(unit (set path)) bind:m
%+ scry:strandio ,(unit (set path))
;: weld
/gx/metadata-store/resource/publish
(en-path:resource rid)
/noun
==
?~ paxs (pure:m ~)
?~ u.paxs (pure:m ~)
(pure:m `(de-path:resource n.u.paxs))
::
++ scry-group
|= rid=resource
=/ m (strand ,group)
;< ugroup=(unit group) bind:m
%+ scry:strandio ,(unit group)
;: weld
/gx/group-store/groups
(en-path:resource rid)
/noun
==
(pure:m (need ugroup))
::
++ delete-graph
|= rid=resource
=/ m (strand ,~)
^- form:m
;< ~ bind:m
(poke-our %graph-push-hook %push-hook-action !>([%remove rid]))
;< =bowl:spider bind:m get-bowl:strandio
;< ~ bind:m
(poke-our %graph-store %graph-update !>([%0 now.bowl %archive-graph rid]))
(pure:m ~)
--
::
^- thread:spider
|= arg=vase
=/ m (strand ,vase)
^- form:m
=+ !<(=action:graph-view arg)
?> ?=(%delete -.action)
;< =bowl:spider bind:m get-bowl:strandio
?. =(our.bowl entity.rid.action)
(strand-fail:strandio %bad-request ~)
;< ugroup-rid=(unit resource) bind:m
(scry-metadata rid.action)
?~ ugroup-rid !!
;< =group bind:m
(scry-group u.ugroup-rid)
?. hidden.group
;< ~ bind:m
(delete-graph rid.action)
(pure:m !>(~))
;< ~ bind:m
(poke-our %group-push-hook %push-hook-action !>([%remove rid.action]))
;< ~ bind:m
(poke-our %group-store %group-action !>([%remove-group rid.action]))
;< ~ bind:m (delete-graph rid.action)
(pure:m !>(~))

View File

@ -0,0 +1,74 @@
/- spider, graph-view, graph=graph-store, *metadata-store, *group, *metadata-store
/+ strandio, resource
=>
|%
++ strand strand:spider
++ poke poke:strandio
++ poke-our poke-our:strandio
::
++ check-live
|= who=ship
=/ m (strand ,~)
^- form:m
%+ (set-timeout:strandio ,~) ~s20
;< ~ bind:m
(poke [who %hood] %helm-hi !>(~))
(pure:m ~)
::
++ scry-group
|= rid=resource
=/ m (strand ,group)
^- form:m
;< ugroup=(unit group) bind:m
%+ scry:strandio (unit group)
%+ weld /gx/group-store/groups
(snoc (en-path:resource rid) %noun)
?> ?=(^ ugroup)
(pure:m u.ugroup)
::
++ scry-metadatum
|= rid=resource
=/ m (strand ,metadata)
^- form:m
=/ enc-path=@t
(scot %t (spat (en-path:resource rid)))
;< umeta=(unit metadata) bind:m
%+ scry:strandio (unit metadata)
%+ weld /gx/metadata-store/metadata
/[enc-path]/graph/[enc-path]/noun
?> ?=(^ umeta)
(pure:m u.umeta)
--
::
^- thread:spider
|= arg=vase
=/ m (strand ,vase)
^- form:m
=+ !<(=action:graph-view arg)
?> ?=(%groupify -.action)
;< =group bind:m (scry-group rid.action)
?. hidden.group
(strand-fail:strandio %bad-request ~)
;< =metadata bind:m
(scry-metadatum rid.action)
?~ to.action
;< ~ bind:m
%+ poke-our %contact-view
contact-view-action+!>([%groupify rid.action title.metadata description.metadata])
(pure:m !>(~))
;< new=^group bind:m (scry-group u.to.action)
?< hidden.new
=/ new-path
(en-path:resource u.to.action)
=/ app-path
(en-path:resource rid.action)
=/ add-md=metadata-action
[%add new-path graph+app-path metadata]
;< ~ bind:m
(poke-our %metadata-store metadata-action+!>(add-md))
;< ~ bind:m
%+ poke-our %metadata-store
metadata-action+!>([%remove app-path graph+app-path])
;< ~ bind:m
(poke-our %group-store %group-update !>([%remove-group rid.action]))
(pure:m !>(~))

View File

@ -0,0 +1,61 @@
/- spider, graph-view, graph=graph-store, *metadata-store, *group
/+ strandio, resource
=>
|%
++ strand strand:spider
++ fail strand-fail:strand
++ poke poke:strandio
++ poke-our poke-our:strandio
::
++ scry-metadata
|= rid=resource
=/ m (strand ,(unit resource))
^- form:m
;< pax=(unit (set path)) bind:m
%+ scry:strandio ,(unit (set path))
;: weld
/gx/metadata-store/resource/graph
(en-path:resource rid)
/noun
==
%- pure:m
?~ pax ~
?~ u.pax ~
`(de-path:resource n.u.pax)
--
::
^- thread:spider
|= arg=vase
=/ m (strand ,vase)
^- form:m
=+ !<(=action:graph-view arg)
?> ?=(%join -.action)
;< =bowl:spider bind:m get-bowl:strandio
?: =(our.bowl entity.rid.action)
(fail %bad-request ~)
;< group=(unit resource) bind:m (scry-metadata rid.action)
?^ group
:: We have group, graph is managed
;< ~ bind:m
%+ poke-our %graph-pull-hook
pull-hook-action+!>([%add ship.action rid.action])
(pure:m !>(~))
:: Else, add group then join
;< ~ bind:m
%+ (map-err:strandio ,~) |=(* [%forbidden ~])
%+ poke
[ship.action %group-push-hook]
group-update+!>([%add-members rid.action (sy our.bowl ~)])
::
;< ~ bind:m
%+ poke-our %group-pull-hook
pull-hook-action+!>([%add ship.action rid.action])
::
;< ~ bind:m
%+ poke-our %metadata-hook
metadata-hook-action+!>([%add-synced ship.action rid.action])
::
;< ~ bind:m
%+ poke-our %graph-pull-hook
pull-hook-action+!>([%add ship.action rid.action])
(pure:m !>(~))

View File

@ -0,0 +1,67 @@
/- spider, graph-view, graph=graph-store, *metadata-store, *group
/+ strandio, resource
=>
|%
++ strand strand:spider
++ poke poke:strandio
++ poke-our poke-our:strandio
::
++ scry-metadata
|= rid=resource
=/ m (strand ,resource)
^- form:m
;< pax=(unit (set path)) bind:m
%+ scry:strandio ,(unit (set path))
;: weld
/gx/metadata-store/resource/graph
(en-path:resource rid)
/noun
==
?> ?=(^ pax)
?> ?=(^ u.pax)
(pure:m (de-path:resource n.u.pax))
::
++ scry-group
|= rid=resource
=/ m (strand ,group)
^- form:m
;< ugroup=(unit group) bind:m
%+ scry:strandio ,(unit group)
;: weld
/gx/group-store/resource/graph
(en-path:resource rid)
/noun
==
(pure:m (need ugroup))
::
++ delete-graph
|= rid=resource
=/ m (strand ,~)
^- form:m
;< ~ bind:m
(poke-our %graph-pull-hook %pull-hook-action !>([%remove rid]))
;< ~ bind:m
(poke-our %graph-store %graph-update !>([%archive-graph rid]))
(pure:m ~)
--
::
^- thread:spider
|= arg=vase
=/ m (strand ,vase)
^- form:m
=+ !<([=action:graph-view ~] arg)
?> ?=(%leave -.action)
;< =bowl:spider bind:m get-bowl:strandio
?: =(our.bowl entity.rid.action)
(strand-fail:strandio %bad-request ~)
;< group-rid=resource bind:m (scry-metadata rid.action)
;< g=group bind:m (scry-group group-rid)
?. hidden.g
;< ~ bind:m (delete-graph rid.action)
(pure:m !>(~))
;< ~ bind:m
(poke-our %group-push-hook %pull-hook-action !>([%remove rid.action]))
;< ~ bind:m
(poke-our %group-store %group-action !>([%remove-group rid.action]))
;< ~ bind:m (delete-graph rid.action)
(pure:m !>(~))

View File

@ -57,4 +57,16 @@ export default class BaseApi<S extends object = {}> {
scry<T>(app: string, path: Path): Promise<T> {
return fetch(`/~/scry/${app}${path}.json`).then(r => r.json() as Promise<T>);
}
async spider<T>(inputMark: string, outputMark: string, threadName: string, body: any): Promise<T> {
const res = await fetch(`/spider/${inputMark}/${threadName}/${outputMark}.json`, {
method: 'POST',
body: JSON.stringify(body)
});
return res.json();
}
}

View File

@ -1,7 +1,9 @@
import BaseApi from './base';
import { StoreState } from '../store/type';
import { Patp, Path, PatpNoSig } from '~/types/noun';
import _ from 'lodash';
import {makeResource, resourceFromPath} from '../lib/group';
import {GroupPolicy, Enc, Post} from '~/types';
export const createPost = (contents: Object[], parentIndex: string = '') => {
return {
@ -20,6 +22,68 @@ export default class GraphApi extends BaseApi<StoreState> {
return this.action('graph-store', 'graph-update', action)
}
private viewAction(threadName: string, action: any) {
return this.spider('graph-view-action', 'json', threadName, action);
}
createManagedGraph(name: string, title: string, description: string, group: Path) {
const associated = { group: resourceFromPath(group) };
const resource = makeResource(`~${window.ship}`, name);
return this.viewAction('graph-create', {
"create": {
resource,
title,
description,
associated
}
});
}
createUnmanagedGraph(name: string, title: string, description: string, policy: Enc<GroupPolicy>) {
const resource = makeResource(`~${window.ship}`, name);
return this.viewAction('graph-create', {
"create": {
resource,
title,
description,
associated: { policy }
}
});
}
joinGraph(ship: Patp, name: string) {
const resource = makeResource(ship, name);
return this.viewAction('graph-join', {
join: {
resource,
ship,
}
});
}
deleteGraph(name: string) {
const resource = makeResource(`~${window.ship}`, name);
return this.viewAction('graph-delete', {
"delete": {
resource
}
});
}
groupifyGraph(ship: Patp, name: string, toPath?: string) {
const resource = makeResource(ship, name);
const to = toPath && resourceFromPath(toPath);
return this.viewAction('graph-groupify', {
groupify: {
resource,
to
}
});
}
addGraph(ship: Patp, name: string, graph: any, mark: any) {
this.storeAction({
'add-graph': {
@ -38,16 +102,17 @@ export default class GraphApi extends BaseApi<StoreState> {
});
}
addPost(ship: Patp, name: string, post: Object) {
addPost(ship: Patp, name: string, post: Post) {
let nodes = {};
const resource = { ship, name };
nodes[post.index] = {
post,
children: { empty: null }
};
this.storeAction({
return this.storeAction({
'add-nodes': {
resource: { ship, name },
resource,
nodes
}
});
@ -63,7 +128,7 @@ export default class GraphApi extends BaseApi<StoreState> {
}
removeNodes(ship: Patp, name: string, indices: string[]) {
this.storeAction({
return this.storeAction({
'remove-nodes': {
resource: { ship, name },
indices
@ -107,7 +172,7 @@ export default class GraphApi extends BaseApi<StoreState> {
});
}
getGraphSubset(ship: string, resource: string, start: string, end: start) {
getGraphSubset(ship: string, resource: string, start: string, end: string) {
this.scry<any>(
'graph-store',
`/graph-subset/${ship}/${resource}/${end}/${start}`

View File

@ -13,3 +13,8 @@ export function resourceFromPath(path: Path): Resource {
const [, , ship, name] = path.split('/');
return { ship, name }
}
export function makeResource(ship: string, name:string) {
return { ship, name };
}

View File

@ -140,10 +140,21 @@ const addNodes = (json, state) => {
};
const removeNodes = (json, state) => {
const _remove = (graph, index) => {
if (index.length === 1) {
graph.delete(index[0]);
} else {
const child = graph.get(index[0]);
_remove(child.children, index.slice(1));
graph.set(index[0], child);
}
};
const data = _.get(json, 'remove-nodes', false);
if (data) {
console.log(data);
if (!(data.resource in state.graphs)) { return; }
const { ship, name } = data.resource;
const res = `${ship}/${name}`;
if (!(res in state.graphs)) { return; }
data.indices.forEach((index) => {
console.log(index);
@ -151,13 +162,7 @@ const removeNodes = (json, state) => {
let indexArr = index.split('/').slice(1).map((ind) => {
return parseInt(ind, 10);
});
if (indexArr.length === 1) {
state.graphs[data.resource].delete(indexArr[0]);
} else {
// TODO: recursive
}
_remove(state.graphs[res], indexArr);
});
}
};

View File

@ -12,6 +12,7 @@ import { LaunchState, WeatherState } from '~/types/launch-update';
import { LinkComments, LinkCollections, LinkSeen } from '~/types/link-update';
import { ConnectionStatus } from '~/types/connection';
import { BackgroundConfig, LocalUpdateRemoteContentPolicy } from '~/types/local-update';
import {Graphs} from '~/types/graph-update';
export interface StoreState {
// local state
@ -36,7 +37,7 @@ export interface StoreState {
groupKeys: Set<Path>;
permissions: Permissions;
s3: S3State;
graphs: Object;
graphs: Graphs;
graphKeys: Set<String>;

View File

@ -0,0 +1,30 @@
import {Patp} from "./noun";
export interface TextContent { text: string; };
export interface UrlContent { url: string; }
export interface CodeContent { expresssion: string; output: string; };
export interface ReferenceContent { uid: string; }
export type Content = TextContent | UrlContent | CodeContent | ReferenceContent;
export interface Post {
author: Patp;
contents: Content[];
hash?: string;
index: string;
pending?: boolean;
signatures: string[];
'time-sent': number;
}
export interface GraphNode {
children: Graph;
post: Post;
}
export type Graph = Map<number, GraphNode>;
export type Graphs = { [rid: string]: Graph };

View File

@ -5,6 +5,7 @@ export * from './connection';
export * from './contact-update';
export * from './global';
export * from './group-update';
export * from './graph-update';
export * from './invite-update';
export * from './launch-update';
export * from './link-listen-update';