mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-12-15 01:52:42 +03:00
Merge branch 'release/next-js' into ed/create-channel-icon-fix
This commit is contained in:
commit
79b0dccf3f
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f6b5e33e573818120051651c1182163527edbbe0dff0eb6591e12a55cfccb273
|
||||
size 10486101
|
||||
oid sha256:90dd5f5b2821f1a057c053b141e1143f019193c8dd7da41b39b0a3799e0fda5a
|
||||
size 10999106
|
||||
|
@ -82,6 +82,8 @@ haskell-nix.stackProject {
|
||||
|
||||
urbit-king.components.tests.urbit-king-tests.testFlags =
|
||||
[ "--brass-pill=${brass.lfs}" ];
|
||||
|
||||
lmdb.components.library.libs = lib.mkForce [ lmdb ];
|
||||
};
|
||||
}];
|
||||
}
|
||||
|
@ -169,7 +169,7 @@
|
||||
::
|
||||
%fact
|
||||
?+ p.cage.sign ~|([dap.bowl %bad-sub-mark wire p.cage.sign] !!)
|
||||
%graph-update-1
|
||||
%graph-update-2
|
||||
%- on-graph-update:tc
|
||||
!<(update:graph q.cage.sign)
|
||||
==
|
||||
@ -401,12 +401,16 @@
|
||||
:: +read-post: add envelope to state and show it to user
|
||||
::
|
||||
++ read-post
|
||||
|= [=target =index:post =post:post]
|
||||
|= [=target =index:post =maybe-post:graph]
|
||||
^- (quip card _session)
|
||||
:- (show-post:sh-out target post)
|
||||
%_ session
|
||||
history [[target index] history.session]
|
||||
count +(count.session)
|
||||
?- -.maybe-post
|
||||
%| [~ session]
|
||||
%&
|
||||
:- (show-post:sh-out target p.maybe-post)
|
||||
%_ session
|
||||
history [[target index] history.session]
|
||||
count +(count.session)
|
||||
==
|
||||
==
|
||||
::
|
||||
++ notice-remove
|
||||
@ -758,15 +762,15 @@
|
||||
::TODO move creation into lib?
|
||||
%^ act %out-message
|
||||
%graph-push-hook
|
||||
:- %graph-update-1
|
||||
:- %graph-update-2
|
||||
!> ^- update:graph
|
||||
:- now.bowl
|
||||
:+ %add-nodes audience
|
||||
%- ~(put by *(map index:post node:graph))
|
||||
:- ~[now.bowl]
|
||||
:_ *internal-graph:graph
|
||||
^- post:post
|
||||
[our-self ~[now.bowl] now.bowl [msg]~ ~ ~]
|
||||
^- maybe-post:graph
|
||||
[%& `post:post`[our-self ~[now.bowl] now.bowl [msg]~ ~ ~]]
|
||||
:: +eval: run hoon, send code and result as message
|
||||
::
|
||||
:: this double-virtualizes and clams to disable .^ for security reasons
|
||||
@ -890,10 +894,12 @@
|
||||
=/ =uid:post (snag index history)
|
||||
=/ =node:graph (got-node:libgraph uid)
|
||||
=. audience resource.uid
|
||||
?: ?=(%| -.post.node)
|
||||
[~ state]
|
||||
:_ put-ses
|
||||
^- (list card)
|
||||
:~ (print:sh-out ['?' ' ' number])
|
||||
(effect:sh-out ~(render-activate mr resource.uid post.node))
|
||||
(effect:sh-out ~(render-activate mr resource.uid p.post.node))
|
||||
prompt:sh-out
|
||||
==
|
||||
--
|
||||
|
@ -154,7 +154,7 @@
|
||||
++ poke-graph-store
|
||||
|= =update:graph-store
|
||||
^- card
|
||||
(poke-our %graph-store %graph-update-1 !>(update))
|
||||
(poke-our %graph-store %graph-update-2 !>(update))
|
||||
::
|
||||
++ nobody
|
||||
^- @p
|
||||
|
@ -1,334 +1,28 @@
|
||||
:: chat-store [landscape]:
|
||||
:: chat-store [landscape]: deprecated
|
||||
::
|
||||
:: data store that holds linear sequences of chat messages
|
||||
::
|
||||
/- *group, store=chat-store
|
||||
/+ default-agent, verb, dbug, group-store,
|
||||
graph-store, resource, *migrate, grpl=group, mdl=metadata
|
||||
~% %chat-store-top ..part ~
|
||||
/- store=chat-store
|
||||
/+ default-agent
|
||||
|%
|
||||
+$ card card:agent:gall
|
||||
+$ versioned-state
|
||||
$% state-0
|
||||
state-1
|
||||
state-2
|
||||
state-3
|
||||
state-4
|
||||
==
|
||||
::
|
||||
+$ state-0 [%0 =inbox:store]
|
||||
+$ state-1 [%1 =inbox:store]
|
||||
+$ state-2 [%2 =inbox:store]
|
||||
+$ state-3 [%3 =inbox:store]
|
||||
+$ state-4 [%4 =inbox:store]
|
||||
+$ admin-action
|
||||
$% [%trim ~]
|
||||
[%migrate-graph ~]
|
||||
==
|
||||
--
|
||||
::
|
||||
=| state-4
|
||||
=* state -
|
||||
::
|
||||
%- agent:dbug
|
||||
%+ verb |
|
||||
^- agent:gall
|
||||
=<
|
||||
~% %chat-store-agent-core ..peek-x-envelopes ~
|
||||
|_ =bowl:gall
|
||||
+* this .
|
||||
chat-core +>
|
||||
cc ~(. chat-core bowl)
|
||||
def ~(. (default-agent this %|) bowl)
|
||||
::
|
||||
++ on-init on-init:def
|
||||
++ on-save !>(state)
|
||||
++ on-load
|
||||
|= old-vase=vase
|
||||
^- (quip card _this)
|
||||
|^
|
||||
=/ old !<(versioned-state old-vase)
|
||||
=| cards=(list card)
|
||||
|-
|
||||
^- (quip card _this)
|
||||
?- -.old
|
||||
%4 [cards this(state old)]
|
||||
::
|
||||
%3
|
||||
=. cards :_(cards (poke-admin %migrate-graph ~))
|
||||
$(old [%4 inbox.old])
|
||||
::
|
||||
%2
|
||||
=/ =inbox:store
|
||||
(migrate-path-map:group-store inbox.old)
|
||||
=/ kick-paths
|
||||
%~ tap in
|
||||
%+ roll
|
||||
~(val by sup.bowl)
|
||||
|= [[=ship sub=path] subs=(set path)]
|
||||
^- (set path)
|
||||
?. ?=([@ @ *] sub)
|
||||
subs
|
||||
?. &(=(%mailbox i.sub) =('~' i.t.sub))
|
||||
subs
|
||||
(~(put in subs) sub)
|
||||
=? cards ?=(^ kick-paths)
|
||||
:_ cards
|
||||
[%give %kick kick-paths ~]
|
||||
$(old [%3 inbox])
|
||||
::
|
||||
?(%0 %1) $(old (old-to-2 inbox.old))
|
||||
::
|
||||
==
|
||||
++ poke-admin
|
||||
|= =admin-action
|
||||
^- card
|
||||
[%pass / %agent [our dap]:bowl %poke noun+!>(admin-action)]
|
||||
::
|
||||
++ old-to-2
|
||||
|= =inbox:store
|
||||
^- state-2
|
||||
:- %2
|
||||
%- ~(run by inbox)
|
||||
|= =mailbox:store
|
||||
^- mailbox:store
|
||||
[config.mailbox (flop envelopes.mailbox)]
|
||||
--
|
||||
::
|
||||
++ on-poke
|
||||
~/ %chat-store-poke
|
||||
|= [=mark =vase]
|
||||
^- (quip card _this)
|
||||
?> (team:title our.bowl src.bowl)
|
||||
=^ cards state
|
||||
?+ mark (on-poke:def mark vase)
|
||||
%noun (poke-noun:cc !<(admin-action vase))
|
||||
%import (poke-import:cc q.vase)
|
||||
==
|
||||
[cards this]
|
||||
::
|
||||
++ on-watch on-watch:def
|
||||
++ on-leave on-leave:def
|
||||
++ on-peek
|
||||
~/ %chat-store-peek
|
||||
|= =path
|
||||
^- (unit (unit cage))
|
||||
?+ path (on-peek:def path)
|
||||
[%x %all ~] ``noun+!>(inbox)
|
||||
[%x %keys ~] ``noun+!>(~(key by inbox))
|
||||
[%x %envelopes *] (peek-x-envelopes:cc t.t.path)
|
||||
[%x %mailbox *]
|
||||
?~ t.t.path
|
||||
~
|
||||
``noun+!>((~(get by inbox) t.t.path))
|
||||
::
|
||||
[%x %config *]
|
||||
?~ t.t.path
|
||||
~
|
||||
=/ mailbox (~(get by inbox) t.t.path)
|
||||
?~ mailbox
|
||||
~
|
||||
``noun+!>(config.u.mailbox)
|
||||
::
|
||||
[%x %export ~]
|
||||
``noun+!>(state)
|
||||
==
|
||||
::
|
||||
++ on-agent on-agent:def
|
||||
++ on-arvo on-arvo:def
|
||||
++ on-fail on-fail:def
|
||||
--
|
||||
|_ =bowl:gall
|
||||
+* this .
|
||||
def ~(. (default-agent this %|) bowl)
|
||||
::
|
||||
~% %chat-store-library ..card ~
|
||||
|_ bol=bowl:gall
|
||||
++ met ~(. mdl bol)
|
||||
++ grp ~(. grpl bol)
|
||||
++ on-init on-init:def
|
||||
++ on-save !>(~)
|
||||
++ on-load
|
||||
|= old-vase=vase
|
||||
^- (quip card _this)
|
||||
[~ this]
|
||||
::
|
||||
++ peek-x-envelopes
|
||||
|= pax=path
|
||||
^- (unit (unit [%noun vase]))
|
||||
?+ pax ~
|
||||
[@ @ *]
|
||||
=/ mail-path t.t.pax
|
||||
=/ mailbox (~(get by inbox) mail-path)
|
||||
?~ mailbox
|
||||
[~ ~ %noun !>(~)]
|
||||
=* envelopes envelopes.u.mailbox
|
||||
=/ sign-test=[?(%neg %pos) @]
|
||||
%- need
|
||||
%+ rush i.pax
|
||||
;~ pose
|
||||
%+ cook
|
||||
|= n=@
|
||||
[%neg n]
|
||||
;~(pfix hep dem:ag)
|
||||
::
|
||||
%+ cook
|
||||
|= n=@
|
||||
[%pos n]
|
||||
dem:ag
|
||||
==
|
||||
=* length length.config.u.mailbox
|
||||
=* start +.sign-test
|
||||
?: =(-.sign-test %neg)
|
||||
?: (gth start length)
|
||||
[~ ~ %noun !>(envelopes)]
|
||||
[~ ~ %noun !>((swag [(sub length start) start] envelopes))]
|
||||
::
|
||||
=/ end (slav %ud i.t.pax)
|
||||
?. (lte start end)
|
||||
~
|
||||
=. end ?:((lth end length) end length)
|
||||
[~ ~ %noun !>((swag [start (sub end start)] envelopes))]
|
||||
==
|
||||
::
|
||||
++ poke-noun
|
||||
|= nou=admin-action
|
||||
^- (quip card _state)
|
||||
?: ?=([%migrate-graph ~] nou)
|
||||
:_ state
|
||||
(migrate-inbox inbox)
|
||||
~& %trimming-chat-store
|
||||
:- ~
|
||||
%_ state
|
||||
inbox
|
||||
%- ~(urn by inbox)
|
||||
|= [=path mailbox:store]
|
||||
^- mailbox:store
|
||||
=/ [a=* out=(list envelope:store)]
|
||||
%+ roll envelopes
|
||||
|= $: =envelope:store
|
||||
o=[[hav=(set serial:store) curr=@] out=(list envelope:store)]
|
||||
==
|
||||
?: (~(has in hav.o) uid.envelope)
|
||||
[[hav.o curr.o] out.o]
|
||||
:-
|
||||
^- [(set serial:store) @]
|
||||
[(~(put in hav.o) uid.envelope) +(curr.o)]
|
||||
^- (list envelope:store)
|
||||
[envelope(number curr.o) out.o]
|
||||
=/ len (lent out)
|
||||
~? !=(len (lent envelopes)) [path [%old (lent envelopes)] [%new len]]
|
||||
[[len len] (flop out)]
|
||||
==
|
||||
::
|
||||
++ poke-import
|
||||
|= arc=*
|
||||
^- (quip card _state)
|
||||
=/ sty=state-4 [%4 (remake-map ;;((tree [path mailbox:store]) +.arc))]
|
||||
:_ sty
|
||||
(migrate-inbox inbox.sty)
|
||||
::
|
||||
++ update-subscribers
|
||||
|= [pax=path =update:store]
|
||||
^- (list card)
|
||||
[%give %fact ~[pax] %chat-update !>(update)]~
|
||||
::
|
||||
++ send-diff
|
||||
|= [pax=path upd=update:store]
|
||||
^- (list card)
|
||||
%- zing
|
||||
:~ (update-subscribers /all upd)
|
||||
(update-subscribers /updates upd)
|
||||
(update-subscribers [%mailbox pax] upd)
|
||||
?. |(|(=(%read -.upd) =(%message -.upd)) =(%messages -.upd))
|
||||
~
|
||||
?. |(=(%create -.upd) =(%delete -.upd))
|
||||
~
|
||||
(update-subscribers /keys upd)
|
||||
==
|
||||
::
|
||||
++ migrate-inbox
|
||||
|= =inbox:store
|
||||
^- (list card)
|
||||
%- zing
|
||||
(turn ~(tap by inbox) mailbox-to-updates)
|
||||
::
|
||||
++ add-graph
|
||||
|= [rid=resource =mailbox:store]
|
||||
%- poke-graph-store
|
||||
:- now.bol
|
||||
:+ %add-graph rid
|
||||
:- (mailbox-to-graph mailbox)
|
||||
[`%graph-validator-chat %.y]
|
||||
::
|
||||
++ archive-graph
|
||||
|= rid=resource
|
||||
%- poke-graph-store
|
||||
[now.bol %archive-graph rid]
|
||||
::
|
||||
++ nobody
|
||||
^- @p
|
||||
(bex 128)
|
||||
::
|
||||
++ path-to-resource
|
||||
|= =path
|
||||
^- resource
|
||||
?. ?=([@ @ ~] path)
|
||||
nobody^(spat path)
|
||||
=/ m-ship=(unit ship)
|
||||
(slaw %p i.path)
|
||||
?~ m-ship
|
||||
nobody^(spat path)
|
||||
[u.m-ship i.t.path]
|
||||
::
|
||||
++ mailbox-to-updates
|
||||
|= [=path =mailbox:store]
|
||||
^- (list card)
|
||||
=/ app-rid=resource
|
||||
(path-to-resource path)
|
||||
=/ group-rid=resource
|
||||
(fall (peek-group:met %graph app-rid) [nobody %bad-group])
|
||||
=/ group=(unit group)
|
||||
(scry-group:grp group-rid)
|
||||
:- (add-graph app-rid mailbox)
|
||||
?~ group (archive-graph app-rid)^~
|
||||
?. &(=(~ members.u.group) hidden.u.group) ~
|
||||
~& >>> "archiving {<app-rid>}"
|
||||
:~ (archive-graph app-rid)
|
||||
(remove-group group-rid)
|
||||
==
|
||||
::
|
||||
++ remove-group
|
||||
|= group=resource
|
||||
^- card
|
||||
=- [%pass / %agent [our.bol %group-store] %poke -]
|
||||
group-update-0+!>([%remove-group group ~])
|
||||
::
|
||||
++ poke-graph-store
|
||||
|= =update:graph-store
|
||||
^- card
|
||||
[%pass / %agent [our.bol %graph-store] %poke %graph-update-1 !>(update)]
|
||||
::
|
||||
++ letter-to-contents
|
||||
|= =letter:store
|
||||
^- (list content:graph-store)
|
||||
:_ ~
|
||||
?. ?=(%me -.letter)
|
||||
letter
|
||||
[%text narrative.letter]
|
||||
::
|
||||
++ envelope-to-node
|
||||
|= =envelope:store
|
||||
^- [atom:graph-store node:graph-store]
|
||||
=/ contents=(list content:graph-store)
|
||||
(letter-to-contents letter.envelope)
|
||||
=/ =index:graph-store
|
||||
[when.envelope ~]
|
||||
=, envelope
|
||||
:- when.envelope
|
||||
:_ [%empty ~]
|
||||
^- post:graph-store
|
||||
:* author
|
||||
index
|
||||
when
|
||||
contents
|
||||
~ ~
|
||||
==
|
||||
::
|
||||
++ mailbox-to-graph
|
||||
|= =mailbox:store
|
||||
^- graph:graph-store
|
||||
%+ gas:orm:graph-store *graph:graph-store
|
||||
(turn envelopes.mailbox envelope-to-node)
|
||||
++ on-poke on-poke:def
|
||||
++ on-watch on-watch:def
|
||||
++ on-leave on-leave:def
|
||||
++ on-peek on-peek:def
|
||||
++ on-agent on-agent:def
|
||||
++ on-arvo on-arvo:def
|
||||
++ on-fail on-fail:def
|
||||
--
|
||||
|
@ -5,7 +5,7 @@
|
||||
/- glob
|
||||
/+ default-agent, verb, dbug
|
||||
|%
|
||||
++ hash 0v3.g6u13.haedt.jt4hd.61ek5.6t30q
|
||||
++ hash 0v7.k043v.fjsi2.bpm4g.0ekbj.566c4 :: DO NOT MOVE FROM LINE 8
|
||||
+$ state-0 [%0 hash=@uv glob=(unit (each glob:glob tid=@ta))]
|
||||
+$ all-states
|
||||
$% state-0
|
||||
|
@ -9,7 +9,7 @@
|
||||
update:store
|
||||
%graph-update
|
||||
%graph-push-hook
|
||||
1 1
|
||||
2 2
|
||||
%.n
|
||||
==
|
||||
--
|
||||
@ -41,7 +41,7 @@
|
||||
%- (slog leaf+"nacked {<resource>}" tang)
|
||||
:_ this
|
||||
?. (~(has in get-keys:gra) resource) ~
|
||||
=- [%pass /pull-nack %agent [our.bowl %graph-store] %poke %graph-update-1 -]~
|
||||
=- [%pass /pull-nack %agent [our.bowl %graph-store] %poke %graph-update-2 -]~
|
||||
!> ^- update:store
|
||||
[now.bowl [%archive-graph resource]]
|
||||
::
|
||||
|
@ -12,16 +12,19 @@
|
||||
update:store
|
||||
%graph-update
|
||||
%graph-pull-hook
|
||||
1 1
|
||||
2 2
|
||||
==
|
||||
::
|
||||
+$ agent (push-hook:push-hook config)
|
||||
::
|
||||
+$ state-null ~
|
||||
+$ state-zero [%0 marks=(set mark)]
|
||||
+$ state-one [%1 ~]
|
||||
+$ versioned-state
|
||||
$@ state-null
|
||||
state-zero
|
||||
$% state-zero
|
||||
state-one
|
||||
==
|
||||
--
|
||||
::
|
||||
%- agent:dbug
|
||||
@ -30,13 +33,14 @@
|
||||
%- (agent:push-hook config)
|
||||
^- agent
|
||||
=-
|
||||
=| state-zero
|
||||
=| state-one
|
||||
=* state -
|
||||
|_ =bowl:gall
|
||||
+* this .
|
||||
def ~(. (default-agent this %|) bowl)
|
||||
grp ~(. group bowl)
|
||||
gra ~(. graph bowl)
|
||||
met ~(. mdl bowl)
|
||||
hc ~(. hook-core bowl)
|
||||
::
|
||||
++ on-init on-init:def
|
||||
@ -46,7 +50,9 @@
|
||||
=+ !<(old=versioned-state vase)
|
||||
=? old ?=(~ old)
|
||||
[%0 ~]
|
||||
?> ?=(%0 -.old)
|
||||
=? old ?=(%0 -.old)
|
||||
[%1 ~]
|
||||
?> ?=(%1 -.old)
|
||||
`this(state old)
|
||||
::
|
||||
++ on-poke on-poke:def
|
||||
@ -58,17 +64,10 @@
|
||||
|= [=wire =sign-arvo]
|
||||
^- (quip card _this)
|
||||
?+ wire (on-arvo:def wire sign-arvo)
|
||||
:: XX: no longer necessary
|
||||
::
|
||||
[%perms @ @ ~]
|
||||
?> ?=(?(%add %remove) i.t.t.wire)
|
||||
=* mark i.t.wire
|
||||
:_ this
|
||||
(build-permissions:hc mark i.t.t.wire %next)^~
|
||||
::
|
||||
[%transform-add @ ~]
|
||||
=* mark i.t.wire
|
||||
:_ this
|
||||
(build-transform-add:hc mark %next)^~
|
||||
[%perms @ @ ~] [~ this]
|
||||
[%transform-add @ ~] [~ this]
|
||||
==
|
||||
::
|
||||
++ on-fail on-fail:def
|
||||
@ -134,6 +133,8 @@
|
||||
|= $: [=index:store =node:store]
|
||||
[indices=(set index:store) lis=(list [index:store node:store])]
|
||||
==
|
||||
~| "cannot put a deleted post into %add-nodes {<post.node>}"
|
||||
?> ?=(%& -.post.node)
|
||||
=/ l (lent index)
|
||||
=/ parent-modified=?
|
||||
%- ~(rep in indices)
|
||||
@ -144,12 +145,12 @@
|
||||
%.n
|
||||
=((swag [0 k] index) i)
|
||||
=/ [ind=index:store =post:store]
|
||||
(transform index post.node now.bowl parent-modified)
|
||||
(transform index p.post.node now.bowl parent-modified)
|
||||
:- (~(put in indices) index)
|
||||
(snoc lis [ind node(post post)])
|
||||
(snoc lis [ind node(p.post post)])
|
||||
--
|
||||
::
|
||||
%remove-nodes
|
||||
%remove-posts
|
||||
?. (is-allowed-remove:hc resource.q.update indices.q.update)
|
||||
~
|
||||
`vas
|
||||
@ -173,7 +174,8 @@
|
||||
++ initial-watch
|
||||
|= [=path =resource:res]
|
||||
^- vase
|
||||
?> (is-allowed:hc resource)
|
||||
|^
|
||||
?> (is-allowed resource)
|
||||
!> ^- update:store
|
||||
?~ path
|
||||
:: new subscribe
|
||||
@ -186,22 +188,19 @@
|
||||
=/ =time (slav %da i.path)
|
||||
=/ =update-log:store (get-update-log-subset:gra resource time)
|
||||
[now.bowl [%run-updates resource update-log]]
|
||||
::
|
||||
++ is-allowed
|
||||
|= =resource:res
|
||||
=/ group-res=resource:res
|
||||
(need (peek-group:met %graph resource))
|
||||
(is-member:grp src.bowl group-res)
|
||||
--
|
||||
::
|
||||
++ take-update
|
||||
|= =vase
|
||||
^- [(list card) agent]
|
||||
=/ =update:store !<(update:store vase)
|
||||
?+ -.q.update [~ this]
|
||||
%add-graph
|
||||
?~ mark.q.update `this
|
||||
=* mark u.mark.q.update
|
||||
?: (~(has in marks) mark) `this
|
||||
:_ this(marks (~(put in marks) mark))
|
||||
:~ (build-permissions:hc mark %add %sing)
|
||||
(build-permissions:hc mark %remove %sing)
|
||||
(build-transform-add:hc mark %sing)
|
||||
==
|
||||
::
|
||||
%remove-graph
|
||||
:_ this
|
||||
[%give %kick ~[resource+(en-path:res resource.q.update)] ~]~
|
||||
@ -211,6 +210,7 @@
|
||||
[%give %kick ~[resource+(en-path:res resource.q.update)] ~]~
|
||||
==
|
||||
--
|
||||
::
|
||||
^| ^= hook-core
|
||||
|_ =bowl:gall
|
||||
+* grp ~(. group bowl)
|
||||
@ -223,28 +223,22 @@
|
||||
/[care]/(scot %p our.bowl)/[desk]/(scot %da now.bowl)
|
||||
path
|
||||
::
|
||||
++ perm-mark-name
|
||||
|= perm=@t
|
||||
^- @t
|
||||
(cat 3 'graph-permissions-' perm)
|
||||
::
|
||||
++ perm-mark
|
||||
|= [=resource:res perm=@t vip=vip-metadata:metadata =indexed-post:store]
|
||||
^- permissions:store
|
||||
|^
|
||||
=- (check vip)
|
||||
!< check=$-(vip-metadata:metadata permissions:store)
|
||||
%. !>(indexed-post)
|
||||
=/ mark (get-mark:gra resource)
|
||||
?~ mark |=(=vase !>([%no %no %no]))
|
||||
.^(tube:clay (scry %cc %home /[u.mark]/(perm-mark-name perm)))
|
||||
::
|
||||
++ add-mark
|
||||
|= [=resource:res vip=vip-metadata:metadata =indexed-post:store]
|
||||
(perm-mark resource %add vip indexed-post)
|
||||
::
|
||||
++ remove-mark
|
||||
|= [=resource:res vip=vip-metadata:metadata =indexed-post:store]
|
||||
(perm-mark resource %remove vip indexed-post)
|
||||
::
|
||||
++ perm-mark-name
|
||||
|= perm=@t
|
||||
^- @t
|
||||
(cat 3 'graph-permissions-' perm)
|
||||
--
|
||||
::
|
||||
++ get-permission
|
||||
|= [=permissions:store is-admin=? writers=(set ship)]
|
||||
@ -257,12 +251,6 @@
|
||||
writer.permissions
|
||||
reader.permissions
|
||||
::
|
||||
++ is-allowed
|
||||
|= =resource:res
|
||||
=/ group-res=resource:res
|
||||
(need (peek-group:met %graph resource))
|
||||
(is-member:grp src.bowl group-res)
|
||||
::
|
||||
++ get-roles-writers-variation
|
||||
|= =resource:res
|
||||
^- (unit [is-admin=? writers=(set ship) vip=vip-metadata:metadata])
|
||||
@ -281,22 +269,27 @@
|
||||
++ node-to-indexed-post
|
||||
|= =node:store
|
||||
^- indexed-post:store
|
||||
=* index index.post.node
|
||||
[(snag (dec (lent index)) index) post.node]
|
||||
?> ?=(%& -.post.node)
|
||||
=* index index.p.post.node
|
||||
[(snag (dec (lent index)) index) p.post.node]
|
||||
::
|
||||
++ is-allowed-add
|
||||
|= [=resource:res nodes=(map index:store node:store)]
|
||||
^- ?
|
||||
|^
|
||||
%- (bond |.(%.n))
|
||||
%+ biff (get-roles-writers-variation resource)
|
||||
|= [is-admin=? writers=(set ship) vip=vip-metadata:metadata]
|
||||
^- (unit ?)
|
||||
%- some
|
||||
%+ levy ~(tap by nodes)
|
||||
|= [=index:store =node:store]
|
||||
=/ parent-index=index:store
|
||||
(scag (dec (lent index)) index)
|
||||
?: (~(has by nodes) parent-index) %.y
|
||||
?. =(author.post.node src.bowl)
|
||||
?: ?=(%| -.post.node)
|
||||
%.n
|
||||
?. =(author.p.post.node src.bowl)
|
||||
%.n
|
||||
=/ =permissions:store
|
||||
%^ add-mark resource vip
|
||||
@ -310,20 +303,30 @@
|
||||
%self
|
||||
=/ parent-node=node:store
|
||||
(got-node:gra resource parent-index)
|
||||
=(author.post.parent-node src.bowl)
|
||||
?: ?=(%| -.post.parent-node)
|
||||
%.n
|
||||
=(author.p.post.parent-node src.bowl)
|
||||
==
|
||||
::
|
||||
++ add-mark
|
||||
|= [=resource:res vip=vip-metadata:metadata =indexed-post:store]
|
||||
(perm-mark resource %add vip indexed-post)
|
||||
--
|
||||
::
|
||||
++ is-allowed-remove
|
||||
|= [=resource:res indices=(set index:store)]
|
||||
^- ?
|
||||
|^
|
||||
%- (bond |.(%.n))
|
||||
%+ biff (get-roles-writers-variation resource)
|
||||
|= [is-admin=? writers=(set ship) vip=vip-metadata:metadata]
|
||||
%- some
|
||||
%+ levy ~(tap by indices)
|
||||
|= =index:store
|
||||
^- ?
|
||||
=/ =node:store
|
||||
(got-node:gra resource index)
|
||||
?: ?=(%| -.post.node) %.n
|
||||
=/ =permissions:store
|
||||
%^ remove-mark resource vip
|
||||
(node-to-indexed-post node)
|
||||
@ -332,23 +335,12 @@
|
||||
?- permission-level
|
||||
%yes %.y
|
||||
%no %.n
|
||||
%self =(author.post.node src.bowl)
|
||||
%self =(author.p.post.node src.bowl)
|
||||
==
|
||||
::
|
||||
++ build-permissions
|
||||
|= [=mark kind=?(%add %remove) mode=?(%sing %next)]
|
||||
^- card
|
||||
=/ =wire /perms/[mark]/[kind]
|
||||
=/ =mood:clay [%c da+now.bowl /[mark]/(perm-mark-name kind)]
|
||||
=/ =rave:clay ?:(?=(%sing mode) [mode mood] [mode mood])
|
||||
[%pass wire %arvo %c %warp our.bowl %home `rave]
|
||||
::
|
||||
++ build-transform-add
|
||||
|= [=mark mode=?(%sing %next)]
|
||||
^- card
|
||||
=/ =wire /transform-add/[mark]
|
||||
=/ =mood:clay [%c da+now.bowl /[mark]/transform-add-nodes]
|
||||
=/ =rave:clay ?:(?=(%sing mode) [mode mood] [mode mood])
|
||||
[%pass wire %arvo %c %warp our.bowl %home `rave]
|
||||
::
|
||||
++ remove-mark
|
||||
|= [=resource:res vip=vip-metadata:metadata =indexed-post:store]
|
||||
(perm-mark resource %remove vip indexed-post)
|
||||
--
|
||||
--
|
||||
|
||||
|
@ -1,29 +1,26 @@
|
||||
:: graph-store [landscape]
|
||||
::
|
||||
::
|
||||
/+ store=graph-store, sigs=signatures, res=resource, default-agent, dbug, verb,
|
||||
*migrate
|
||||
/+ store=graph-store, sigs=signatures, res=resource, default-agent, dbug, verb
|
||||
~% %graph-store-top ..part ~
|
||||
|%
|
||||
+$ card card:agent:gall
|
||||
+$ versioned-state
|
||||
$% state-0
|
||||
state-1
|
||||
state-2
|
||||
state-3
|
||||
$% [%0 network:zero:store]
|
||||
[%1 network:zero:store]
|
||||
[%2 network:zero:store]
|
||||
[%3 network:one:store]
|
||||
[%4 network:store]
|
||||
state-5
|
||||
==
|
||||
::
|
||||
+$ state-0 [%0 network:zero:store]
|
||||
+$ state-1 [%1 network:zero:store]
|
||||
+$ state-2 [%2 network:zero:store]
|
||||
+$ state-3 [%3 network:store]
|
||||
::
|
||||
+$ state-5 [%5 network:store]
|
||||
++ orm orm:store
|
||||
++ orm-log orm-log:store
|
||||
+$ debug-input [%validate-graph =resource:store]
|
||||
--
|
||||
::
|
||||
=| state-3
|
||||
=| state-5
|
||||
=* state -
|
||||
::
|
||||
%- agent:dbug
|
||||
@ -41,19 +38,18 @@
|
||||
^- (quip card _this)
|
||||
=+ !<(old=versioned-state old-vase)
|
||||
=| cards=(list card)
|
||||
|^
|
||||
|-
|
||||
?- -.old
|
||||
%0
|
||||
%0
|
||||
=* zro zero-load:upgrade:store
|
||||
%_ $
|
||||
-.old %1
|
||||
cards cards
|
||||
validators.old validators.old
|
||||
::
|
||||
graphs.old
|
||||
%- ~(run by graphs.old)
|
||||
|= [=graph:zero:store q=(unit mark)]
|
||||
^- [graph:zero:store (unit mark)]
|
||||
:- (convert-unix-timestamped-graph:zero-load graph)
|
||||
:- (convert-unix-timestamped-graph:zro graph)
|
||||
?^ q q
|
||||
`%graph-validator-link
|
||||
::
|
||||
@ -63,138 +59,57 @@
|
||||
==
|
||||
::
|
||||
%1
|
||||
=* zro zero-load:upgrade:store
|
||||
%_ $
|
||||
-.old %2
|
||||
graphs.old (~(run by graphs.old) change-revision-graph:zero-load)
|
||||
graphs.old (~(run by graphs.old) change-revision-graph:zro)
|
||||
::
|
||||
update-logs.old
|
||||
%- ~(run by update-logs.old)
|
||||
|=(a=* *update-log:zero:store)
|
||||
==
|
||||
::
|
||||
%2
|
||||
%2
|
||||
=* upg upgrade:store
|
||||
%_ $
|
||||
-.old %3
|
||||
update-logs.old (~(run by update-logs.old) update-log-to-one:store)
|
||||
graphs.old (~(run by graphs.old) marked-graph-to-one:store)
|
||||
archive.old (~(run by archive.old) marked-graph-to-one:store)
|
||||
update-logs.old (~(run by update-logs.old) update-log-to-one:upg)
|
||||
graphs.old (~(run by graphs.old) marked-graph-to-one:upg)
|
||||
archive.old (~(run by archive.old) marked-graph-to-one:upg)
|
||||
==
|
||||
::
|
||||
%3 [cards this(state old)]
|
||||
==
|
||||
%3
|
||||
=* upg upgrade:store
|
||||
%_ $
|
||||
-.old %4
|
||||
graphs.old (~(run by graphs.old) marked-graph-to-two:upg)
|
||||
archive.old (~(run by archive.old) marked-graph-to-two:upg)
|
||||
tag-queries.old *tag-queries:store
|
||||
validators.old ~
|
||||
::
|
||||
update-logs.old
|
||||
%- ~(run by update-logs.old)
|
||||
|=(a=* *update-log:store)
|
||||
==
|
||||
::
|
||||
++ zero-load
|
||||
:: =* infinitely recurses
|
||||
=, store=zero:store
|
||||
=, orm=orm:zero:store
|
||||
=, orm-log=orm-log:zero:store
|
||||
|%
|
||||
++ change-revision-graph
|
||||
|= [=graph:store q=(unit mark)]
|
||||
^- [graph:store (unit mark)]
|
||||
|^
|
||||
:_ q
|
||||
?+ q graph
|
||||
[~ %graph-validator-link] convert-links
|
||||
[~ %graph-validator-publish] convert-publish
|
||||
==
|
||||
::
|
||||
++ convert-links
|
||||
%+ gas:orm *graph:store
|
||||
%+ turn (tap:orm graph)
|
||||
|= [=atom =node:store]
|
||||
^- [^atom node:store]
|
||||
:: top-level
|
||||
::
|
||||
:+ atom post.node
|
||||
?: ?=(%empty -.children.node)
|
||||
[%empty ~]
|
||||
:- %graph
|
||||
%+ gas:orm *graph:store
|
||||
%+ turn (tap:orm p.children.node)
|
||||
|= [=^atom =node:store]
|
||||
^- [^^atom node:store]
|
||||
:: existing comments get turned into containers for revisions
|
||||
::
|
||||
:^ atom
|
||||
post.node(contents ~, hash ~)
|
||||
%graph
|
||||
%+ gas:orm *graph:store
|
||||
:_ ~ :- %0
|
||||
:_ [%empty ~]
|
||||
post.node(index (snoc index.post.node atom), hash ~)
|
||||
::
|
||||
++ convert-publish
|
||||
%+ gas:orm *graph:store
|
||||
%+ turn (tap:orm graph)
|
||||
|= [=atom =node:store]
|
||||
^- [^atom node:store]
|
||||
:: top-level
|
||||
::
|
||||
:+ atom post.node
|
||||
?: ?=(%empty -.children.node)
|
||||
[%empty ~]
|
||||
:- %graph
|
||||
%+ gas:orm *graph:store
|
||||
%+ turn (tap:orm p.children.node)
|
||||
|= [=^atom =node:store]
|
||||
^- [^^atom node:store]
|
||||
:: existing container for publish note revisions
|
||||
::
|
||||
?+ atom !!
|
||||
%1 [atom node]
|
||||
%2
|
||||
:+ atom post.node
|
||||
?: ?=(%empty -.children.node)
|
||||
[%empty ~]
|
||||
:- %graph
|
||||
%+ gas:orm *graph:store
|
||||
%+ turn (tap:orm p.children.node)
|
||||
|= [=^^atom =node:store]
|
||||
^- [^^^atom node:store]
|
||||
:+ atom post.node(contents ~, hash ~)
|
||||
:- %graph
|
||||
%+ gas:orm *graph:store
|
||||
:_ ~ :- %1
|
||||
:_ [%empty ~]
|
||||
post.node(index (snoc index.post.node atom), hash ~)
|
||||
==
|
||||
--
|
||||
::
|
||||
++ maybe-unix-to-da
|
||||
|= =atom
|
||||
^- @
|
||||
:: (bex 127) is roughly 226AD
|
||||
?. (lte atom (bex 127))
|
||||
atom
|
||||
(add ~1970.1.1 (div (mul ~s1 atom) 1.000))
|
||||
%4
|
||||
%_ $
|
||||
-.old %5
|
||||
::
|
||||
++ convert-unix-timestamped-node
|
||||
|= =node:store
|
||||
^- node:store
|
||||
=. index.post.node
|
||||
(convert-unix-timestamped-index index.post.node)
|
||||
?. ?=(%graph -.children.node)
|
||||
node
|
||||
:+ post.node
|
||||
%graph
|
||||
(convert-unix-timestamped-graph p.children.node)
|
||||
::
|
||||
++ convert-unix-timestamped-index
|
||||
|= =index:store
|
||||
(turn index maybe-unix-to-da)
|
||||
::
|
||||
++ convert-unix-timestamped-graph
|
||||
|= =graph:store
|
||||
%+ gas:orm *graph:store
|
||||
%+ turn
|
||||
(tap:orm graph)
|
||||
|= [=atom =node:store]
|
||||
^- [^atom node:store]
|
||||
:- (maybe-unix-to-da atom)
|
||||
(convert-unix-timestamped-node node)
|
||||
--
|
||||
--
|
||||
update-logs.old
|
||||
%- ~(gas by *update-logs:store)
|
||||
%+ turn ~(tap by graphs.old)
|
||||
|= [=resource:store =graph:store mar=(unit mark)]
|
||||
:- resource
|
||||
=/ log (~(got by update-logs.old) resource)
|
||||
?. =(~ log) log
|
||||
=/ =logged-update:store
|
||||
[now.bowl %add-graph resource graph mar %.y]
|
||||
(gas:orm-log ~ [now.bowl logged-update] ~)
|
||||
==
|
||||
::
|
||||
%5 [cards this(state old)]
|
||||
==
|
||||
::
|
||||
++ on-watch
|
||||
~/ %graph-store-watch
|
||||
@ -213,7 +128,7 @@
|
||||
++ give
|
||||
|= =action:store
|
||||
^- (list card)
|
||||
[%give %fact ~ [%graph-update-1 !>([now.bowl action])]]~
|
||||
[%give %fact ~ [%graph-update-2 !>([now.bowl action])]]~
|
||||
--
|
||||
::
|
||||
++ on-poke
|
||||
@ -224,7 +139,7 @@
|
||||
?> (team:title our.bowl src.bowl)
|
||||
=^ cards state
|
||||
?+ mark (on-poke:def mark vase)
|
||||
%graph-update-1 (graph-update !<(update:store vase))
|
||||
%graph-update-2 (graph-update !<(update:store vase))
|
||||
%noun (debug !<(debug-input vase))
|
||||
%import (poke-import q.vase)
|
||||
==
|
||||
@ -239,7 +154,7 @@
|
||||
%add-graph (add-graph p.update +.q.update)
|
||||
%remove-graph (remove-graph +.q.update)
|
||||
%add-nodes (add-nodes p.update +.q.update)
|
||||
%remove-nodes (remove-nodes p.update +.q.update)
|
||||
%remove-posts (remove-posts 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)
|
||||
@ -319,27 +234,27 @@
|
||||
++ check-for-duplicates
|
||||
|= [=graph:store nodes=(set index:store)]
|
||||
^- ?
|
||||
=/ node-list ~(tap in nodes)
|
||||
|-
|
||||
?~ node-list %.n
|
||||
?: (has-node graph i.node-list) %.y
|
||||
$(node-list t.node-list)
|
||||
::
|
||||
++ has-node
|
||||
|= [=graph:store =index:store]
|
||||
^- ?
|
||||
=/ node=(unit node:store) ~
|
||||
|-
|
||||
?~ index
|
||||
?=(^ node)
|
||||
?~ t.index
|
||||
?=(^ (get:orm graph i.index))
|
||||
=. node (get:orm graph i.index)
|
||||
?~ node %.n
|
||||
?- -.children.u.node
|
||||
%empty %.n
|
||||
%graph $(graph p.children.u.node, index t.index)
|
||||
==
|
||||
|^
|
||||
%+ lien ~(tap in nodes)
|
||||
|= =index:store
|
||||
(has-node graph index)
|
||||
::
|
||||
++ has-node
|
||||
|= [=graph:store =index:store]
|
||||
^- ?
|
||||
=/ node=(unit node:store) ~
|
||||
|-
|
||||
?~ index
|
||||
?=(^ node)
|
||||
?~ t.index
|
||||
?=(^ (get:orm graph i.index))
|
||||
=. node (get:orm graph i.index)
|
||||
?~ node %.n
|
||||
?- -.children.u.node
|
||||
%empty %.n
|
||||
%graph $(graph p.children.u.node, index t.index)
|
||||
==
|
||||
--
|
||||
::
|
||||
++ sort-nodes
|
||||
|= nodes=(map index:store node:store)
|
||||
@ -382,8 +297,10 @@
|
||||
:: add child
|
||||
::
|
||||
?~ t.index
|
||||
=* p post.node
|
||||
?~ hash.p node(signatures.post *signatures:store)
|
||||
~| "cannot add deleted post"
|
||||
?> ?=(%& -.post.node)
|
||||
=* p p.post.node
|
||||
?~ hash.p node(signatures.p.post *signatures:store)
|
||||
=/ =validated-portion:store
|
||||
[parent-hash author.p time-sent.p contents.p]
|
||||
=/ =hash:store `@ux`(sham validated-portion)
|
||||
@ -402,8 +319,14 @@
|
||||
^- internal-graph:store
|
||||
:- %graph
|
||||
%_ $
|
||||
index t.index
|
||||
parent-hash hash.post.parent
|
||||
index t.index
|
||||
::
|
||||
parent-hash
|
||||
?- -.post.parent
|
||||
%| `p.post.parent
|
||||
%& hash.p.post.parent
|
||||
==
|
||||
::
|
||||
graph
|
||||
?: ?=(%graph -.children.parent)
|
||||
p.children.parent
|
||||
@ -412,7 +335,7 @@
|
||||
==
|
||||
--
|
||||
::
|
||||
++ remove-nodes
|
||||
++ remove-posts
|
||||
|= [=time =resource:store indices=(set index:store)]
|
||||
^- (quip card _state)
|
||||
|^
|
||||
@ -420,82 +343,83 @@
|
||||
(~(got by graphs) resource)
|
||||
=/ =update-log:store (~(got by update-logs) resource)
|
||||
=. update-log
|
||||
(put:orm-log update-log time [time [%remove-nodes resource indices]])
|
||||
=/ [affected-indices=(set index:store) new-graph=graph:store]
|
||||
(remove-indices resource graph (sort ~(tap in indices) by-lent))
|
||||
::
|
||||
:- (give [/updates]~ [%remove-nodes resource (~(uni in indices) affected-indices)])
|
||||
(put:orm-log update-log time [time [%remove-posts resource indices]])
|
||||
:- (give [/updates]~ [%remove-posts resource indices])
|
||||
%_ state
|
||||
update-logs (~(put by update-logs) resource update-log)
|
||||
update-logs (~(put by update-logs) resource update-log)
|
||||
::
|
||||
graphs
|
||||
%+ ~(put by graphs)
|
||||
resource
|
||||
[new-graph mark]
|
||||
:_ mark
|
||||
%^ remove-indices
|
||||
resource
|
||||
graph
|
||||
(sort ~(tap in indices) by-lent)
|
||||
==
|
||||
::
|
||||
:: we always want to remove the deepest node first,
|
||||
:: so we don't remove parents before children
|
||||
++ by-lent
|
||||
|* [a=(list) b=(list)]
|
||||
^- ?
|
||||
(gth (lent a) (lent b))
|
||||
::
|
||||
++ remove-indices
|
||||
=| affected=(set index:store)
|
||||
|= [=resource:store =graph:store indices=(list index:store)]
|
||||
^- [(set index:store) graph:store]
|
||||
?~ indices [affected graph]
|
||||
=^ new-affected graph
|
||||
(remove-index graph i.indices)
|
||||
^- graph:store
|
||||
?~ indices graph
|
||||
%_ $
|
||||
indices t.indices
|
||||
affected (~(uni in affected) new-affected)
|
||||
==
|
||||
::
|
||||
++ get-descendants
|
||||
|= =graph:store
|
||||
=| indices=(list index:store)
|
||||
=/ nodes (tap:orm:store graph)
|
||||
%- ~(gas in *(set index:store))
|
||||
|- =* tap-nodes $
|
||||
^+ indices
|
||||
%- zing
|
||||
%+ turn nodes
|
||||
|= [atom =node:store]
|
||||
^- (list index:store)
|
||||
%+ welp
|
||||
index.post.node^~
|
||||
?. ?=(%graph -.children.node)
|
||||
~
|
||||
%_ tap-nodes
|
||||
nodes (tap:orm p.children.node)
|
||||
indices t.indices
|
||||
graph (remove-index graph i.indices)
|
||||
==
|
||||
::
|
||||
++ remove-index
|
||||
=| indices=(set index:store)
|
||||
=| parent-hash=(unit hash:store)
|
||||
|= [=graph:store =index:store]
|
||||
^- [(set index:store) graph:store]
|
||||
?~ index [indices graph]
|
||||
^- graph:store
|
||||
?~ index graph
|
||||
=* atom i.index
|
||||
%^ put:orm
|
||||
graph
|
||||
atom
|
||||
:: last index in list
|
||||
::
|
||||
?~ t.index
|
||||
=^ rm-node graph (del:orm graph atom)
|
||||
?~ rm-node `graph
|
||||
?. ?=(%graph -.children.u.rm-node)
|
||||
`graph
|
||||
=/ new-indices
|
||||
(get-descendants p.children.u.rm-node)
|
||||
[(~(uni in indices) new-indices) graph]
|
||||
=/ =node:store
|
||||
=/ =node:store
|
||||
~| "cannot remove index that does not exist {<index>}"
|
||||
(need (get:orm graph atom))
|
||||
%_ node
|
||||
post
|
||||
~| "cannot remove post that has already been removed"
|
||||
?> ?=(%& -.post.node)
|
||||
=* p p.post.node
|
||||
^- maybe-post:store
|
||||
:- %|
|
||||
?~ hash.p
|
||||
=/ =validated-portion:store
|
||||
[parent-hash author.p time-sent.p contents.p]
|
||||
`@ux`(sham validated-portion)
|
||||
u.hash.p
|
||||
==
|
||||
:: recurse children
|
||||
::
|
||||
=/ parent=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)
|
||||
=^ new-indices p.children.node
|
||||
$(graph p.children.node, index t.index)
|
||||
:- (~(uni in indices) new-indices)
|
||||
(put:orm graph atom node)
|
||||
?> ?=(%graph -.children.parent)
|
||||
%_ parent
|
||||
p.children
|
||||
%_ $
|
||||
index t.index
|
||||
graph p.children.parent
|
||||
::
|
||||
parent-hash
|
||||
?- -.post.parent
|
||||
%| `p.post.parent
|
||||
%& hash.p.post.parent
|
||||
==
|
||||
==
|
||||
==
|
||||
--
|
||||
::
|
||||
++ add-signatures
|
||||
@ -531,11 +455,13 @@
|
||||
graph
|
||||
atom
|
||||
?~ t.index
|
||||
~| "cannot add signatures to a deleted post"
|
||||
?> ?=(%& -.post.node)
|
||||
~| "cannot add signatures to a node missing a hash"
|
||||
?> ?=(^ hash.post.node)
|
||||
?> ?=(^ hash.p.post.node)
|
||||
~| "signatures did not match public keys!"
|
||||
?> (are-signatures-valid:sigs our.bowl signatures u.hash.post.node now.bowl)
|
||||
node(signatures.post (~(uni in signatures) signatures.post.node))
|
||||
?> (are-signatures-valid:sigs our.bowl signatures u.hash.p.post.node now.bowl)
|
||||
node(signatures.p.post (~(uni in signatures) signatures.p.post.node))
|
||||
~| "child graph does not exist to add signatures to!"
|
||||
?> ?=(%graph -.children.node)
|
||||
node(p.children $(graph p.children.node, index t.index))
|
||||
@ -576,28 +502,29 @@
|
||||
graph
|
||||
atom
|
||||
?~ t.index
|
||||
node(signatures.post (~(dif in signatures) signatures.post.node))
|
||||
~| "cannot add signatures to a deleted post"
|
||||
?> ?=(%& -.post.node)
|
||||
node(signatures.p.post (~(dif in signatures) signatures.p.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]
|
||||
|= [=term =uid:store]
|
||||
^- (quip card _state)
|
||||
?> (~(has by graphs) resource)
|
||||
:- (give [/updates /tags ~] [%add-tag term resource])
|
||||
?> (~(has by graphs) resource.uid)
|
||||
:- (give [/updates /tags ~] [%add-tag term uid])
|
||||
%_ state
|
||||
tag-queries (~(put ju tag-queries) term resource)
|
||||
tag-queries (~(put ju tag-queries) term uid)
|
||||
==
|
||||
::
|
||||
++ remove-tag
|
||||
|= [=term =resource:store]
|
||||
|= [=term =uid:store]
|
||||
^- (quip card _state)
|
||||
?> (~(has by graphs) resource)
|
||||
:- (give [/updates /tags ~] [%remove-tag term resource])
|
||||
:- (give [/updates /tags ~] [%remove-tag term uid])
|
||||
%_ state
|
||||
tag-queries (~(del ju tag-queries) term resource)
|
||||
tag-queries (~(del ju tag-queries) term uid)
|
||||
==
|
||||
::
|
||||
++ archive-graph
|
||||
@ -610,10 +537,6 @@
|
||||
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
|
||||
@ -648,7 +571,7 @@
|
||||
?- -.q.update
|
||||
%add-graph update(resource.q resource)
|
||||
%add-nodes update(resource.q resource)
|
||||
%remove-nodes update(resource.q resource)
|
||||
%remove-posts update(resource.q resource)
|
||||
%add-signatures update(resource.uid.q resource)
|
||||
%remove-signatures update(resource.uid.q resource)
|
||||
==
|
||||
@ -657,7 +580,7 @@
|
||||
++ give
|
||||
|= [paths=(list path) update=action:store]
|
||||
^- (list card)
|
||||
[%give %fact paths [%graph-update-1 !>([now.bowl update])]]~
|
||||
[%give %fact paths [%graph-update-2 !>([now.bowl update])]]~
|
||||
--
|
||||
::
|
||||
++ debug
|
||||
@ -682,7 +605,10 @@
|
||||
%+ roll (tap:orm graph)
|
||||
|= [[=atom =node:store] out=?]
|
||||
^- ?
|
||||
?& ?=(^ (vale:dais [atom post.node]))
|
||||
?& ?| ?=(%| -.post.node)
|
||||
?=(^ (vale:dais [atom p.post.node]))
|
||||
==
|
||||
::
|
||||
?- -.children.node
|
||||
%empty %.y
|
||||
%graph ^$(graph p.children.node)
|
||||
@ -691,155 +617,7 @@
|
||||
++ poke-import
|
||||
|= arc=*
|
||||
^- (quip card _state)
|
||||
|^
|
||||
=/ sty=state-3 [%3 (remake-network ;;(tree-network +.arc))]
|
||||
:_ sty
|
||||
%+ turn ~(tap by graphs.sty)
|
||||
|= [rid=resource:store =marked-graph:store]
|
||||
^- card
|
||||
?: =(our.bowl entity.rid)
|
||||
=/ =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
|
||||
$: p=time
|
||||
$= q
|
||||
$% [%add-graph =resource:store =tree-graph mark=(unit ^mark) ow=?]
|
||||
[%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
|
||||
:- p.t
|
||||
?- -.q.t
|
||||
%add-graph
|
||||
:* %add-graph
|
||||
resource.q.t
|
||||
(remake-graph tree-graph.q.t)
|
||||
mark.q.t
|
||||
ow.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=@]
|
||||
^- card
|
||||
=/ res-path (en-path:res rid)
|
||||
=/ wire [%try-rejoin (scot %ud nack-count) res-path]
|
||||
[%pass wire %agent [entity.rid %graph-push-hook] %watch resource+res-path]
|
||||
(import:store arc our.bowl)
|
||||
--
|
||||
::
|
||||
++ on-peek
|
||||
@ -858,15 +636,15 @@
|
||||
``noun+!>(q.u.result)
|
||||
::
|
||||
[%x %keys ~]
|
||||
:- ~ :- ~ :- %graph-update-1
|
||||
:- ~ :- ~ :- %graph-update-2
|
||||
!>(`update:store`[now.bowl [%keys ~(key by graphs)]])
|
||||
::
|
||||
[%x %tags ~]
|
||||
:- ~ :- ~ :- %graph-update-1
|
||||
:- ~ :- ~ :- %graph-update-2
|
||||
!>(`update:store`[now.bowl [%tags ~(key by tag-queries)]])
|
||||
::
|
||||
[%x %tag-queries ~]
|
||||
:- ~ :- ~ :- %graph-update-1
|
||||
:- ~ :- ~ :- %graph-update-2
|
||||
!>(`update:store`[now.bowl [%tag-queries tag-queries]])
|
||||
::
|
||||
[%x %graph @ @ ~]
|
||||
@ -875,7 +653,7 @@
|
||||
=/ result=(unit marked-graph:store)
|
||||
(~(get by graphs) [ship term])
|
||||
?~ result [~ ~]
|
||||
:- ~ :- ~ :- %graph-update-1
|
||||
:- ~ :- ~ :- %graph-update-2
|
||||
!> ^- update:store
|
||||
:- now.bowl
|
||||
[%add-graph [ship term] `graph:store`p.u.result q.u.result %.y]
|
||||
@ -890,7 +668,7 @@
|
||||
?~ result
|
||||
~& no-archived-graph+[ship term]
|
||||
[~ ~]
|
||||
:- ~ :- ~ :- %graph-update-1
|
||||
:- ~ :- ~ :- %graph-update-2
|
||||
!> ^- update:store
|
||||
:- now.bowl
|
||||
[%add-graph [ship term] `graph:store`p.u.result q.u.result %.y]
|
||||
@ -906,7 +684,7 @@
|
||||
=/ graph=(unit marked-graph:store)
|
||||
(~(get by graphs) [ship term])
|
||||
?~ graph [~ ~]
|
||||
:- ~ :- ~ :- %graph-update-1
|
||||
:- ~ :- ~ :- %graph-update-2
|
||||
!> ^- update:store
|
||||
:- now.bowl
|
||||
:+ %add-nodes
|
||||
@ -933,7 +711,7 @@
|
||||
(turn t.t.t.t.path (cury slav %ud))
|
||||
=/ node=(unit node:store) (get-node ship term index)
|
||||
?~ node [~ ~]
|
||||
:- ~ :- ~ :- %graph-update-1
|
||||
:- ~ :- ~ :- %graph-update-2
|
||||
!> ^- update:store
|
||||
:- now.bowl
|
||||
:+ %add-nodes
|
||||
@ -952,7 +730,7 @@
|
||||
=/ graph
|
||||
(get-node-children ship term parent)
|
||||
?~ graph [~ ~]
|
||||
:- ~ :- ~ :- %graph-update-1
|
||||
:- ~ :- ~ :- %graph-update-2
|
||||
!> ^- update:store
|
||||
:- now.bowl
|
||||
:+ %add-nodes
|
||||
@ -982,7 +760,7 @@
|
||||
=/ children
|
||||
(get-node-children ship term index)
|
||||
?~ children [~ ~]
|
||||
:- ~ :- ~ :- %graph-update-1
|
||||
:- ~ :- ~ :- %graph-update-2
|
||||
!> ^- update:store
|
||||
:- now.bowl
|
||||
:+ %add-nodes
|
||||
@ -1008,7 +786,7 @@
|
||||
?- -.children.u.node
|
||||
%empty [~ ~]
|
||||
%graph
|
||||
:- ~ :- ~ :- %graph-update-1
|
||||
:- ~ :- ~ :- %graph-update-2
|
||||
!> ^- update:store
|
||||
:- now.bowl
|
||||
:+ %add-nodes
|
||||
|
@ -24,7 +24,6 @@
|
||||
watch-on-self=_&
|
||||
==
|
||||
::
|
||||
::
|
||||
++ scry
|
||||
|* [[our=@p now=@da] =mold p=path]
|
||||
?> ?=(^ p)
|
||||
@ -37,7 +36,6 @@
|
||||
%^ scry [our now]
|
||||
tube:clay
|
||||
/cc/[desk]/[mark]/notification-kind
|
||||
::
|
||||
--
|
||||
::
|
||||
=| state-1
|
||||
@ -126,15 +124,15 @@
|
||||
::
|
||||
++ poke-noun
|
||||
|= non=*
|
||||
?> ?=(%rewatch-dms non)
|
||||
=/ graphs=(list resource)
|
||||
~(tap in get-keys:gra)
|
||||
:- ~
|
||||
%_ state
|
||||
watching
|
||||
%- ~(gas in watching)
|
||||
(murn graphs |=(rid=resource ?:((should-watch:ha rid) `[rid ~] ~)))
|
||||
==
|
||||
[~ state]
|
||||
:: ?> ?=(%rewatch-dms non)
|
||||
:: =/ graphs=(list resource)
|
||||
:: ~(tap in get-keys:gra)
|
||||
:: %_ state
|
||||
:: watching
|
||||
:: %- ~(gas in watching)
|
||||
:: (murn graphs |=(rid=resource ?:((should-watch:ha rid) `[rid ~] ~)))
|
||||
:: ==
|
||||
::
|
||||
++ hark-graph-hook-action
|
||||
|= =action:hook
|
||||
@ -182,7 +180,7 @@
|
||||
~[watch-graph:ha]
|
||||
::
|
||||
%fact
|
||||
?. ?=(%graph-update-1 p.cage.sign)
|
||||
?. ?=(%graph-update-2 p.cage.sign)
|
||||
(on-agent:def wire sign)
|
||||
=^ cards state
|
||||
(graph-update !<(update:graph-store q.cage.sign))
|
||||
@ -197,18 +195,20 @@
|
||||
::
|
||||
?(%remove-graph %archive-graph)
|
||||
(remove-graph resource.q.update)
|
||||
::
|
||||
%remove-nodes
|
||||
(remove-nodes resource.q.update indices.q.update)
|
||||
::
|
||||
::
|
||||
%remove-posts
|
||||
(remove-posts resource.q.update indices.q.update)
|
||||
::
|
||||
%add-nodes
|
||||
=* rid resource.q.update
|
||||
(check-nodes ~(val by nodes.q.update) rid)
|
||||
=/ assoc=(unit association:metadata)
|
||||
(peek-association:met %graph rid)
|
||||
(check-nodes ~(val by nodes.q.update) rid assoc)
|
||||
==
|
||||
:: this is awful, but notification kind should always switch
|
||||
:: on the index, so hopefully doesn't matter
|
||||
:: TODO: rethink this
|
||||
++ remove-nodes
|
||||
++ remove-posts
|
||||
|= [rid=resource indices=(set index:graph-store)]
|
||||
=/ to-remove
|
||||
%- ~(gas by *(set [resource index:graph-store]))
|
||||
@ -257,31 +257,30 @@
|
||||
(get-graph-mop:gra rid)
|
||||
=/ node=(unit node:graph-store)
|
||||
(bind (peek:orm:graph-store graph) |=([@ =node:graph-store] node))
|
||||
=/ assoc=(unit association:metadata)
|
||||
(peek-association:met %graph rid)
|
||||
=^ cards state
|
||||
(check-nodes (drop node) rid)
|
||||
?. (should-watch:ha rid)
|
||||
(check-nodes (drop node) rid assoc)
|
||||
?. (should-watch:ha rid assoc)
|
||||
[cards state]
|
||||
:_ state(watching (~(put in watching) [rid ~]))
|
||||
(weld cards (give:ha ~[/updates] %listen [rid ~]))
|
||||
::
|
||||
::
|
||||
++ check-nodes
|
||||
|= $: nodes=(list node:graph-store)
|
||||
rid=resource
|
||||
assoc=(unit association:metadata)
|
||||
==
|
||||
=/ group=(unit resource)
|
||||
(peek-group:met %graph rid)
|
||||
?~ group
|
||||
~& no-group+rid
|
||||
?~ assoc
|
||||
~& no-assoc+rid
|
||||
`state
|
||||
=/ metadatum=(unit metadatum:metadata)
|
||||
(peek-metadatum:met %graph rid)
|
||||
?~ metadatum `state
|
||||
=* group group.u.assoc
|
||||
=* metadatum metadatum.u.assoc
|
||||
=/ module=term
|
||||
?: ?=(%empty -.config.u.metadatum) %$
|
||||
?: ?=(%group -.config.u.metadatum) %$
|
||||
module.config.u.metadatum
|
||||
abet:check:(abed:handle-update:ha rid nodes u.group module)
|
||||
?: ?=(%empty -.config.metadatum) %$
|
||||
?: ?=(%group -.config.metadatum) %$
|
||||
module.config.metadatum
|
||||
abet:check:(abed:handle-update:ha rid nodes group module)
|
||||
--
|
||||
::
|
||||
++ on-peek on-peek:def
|
||||
@ -343,12 +342,11 @@
|
||||
$(contents t.contents)
|
||||
::
|
||||
++ should-watch
|
||||
|= rid=resource
|
||||
|= [rid=resource assoc=(unit association:metadata)]
|
||||
^- ?
|
||||
=/ group-rid=(unit resource)
|
||||
(peek-group:met %graph rid)
|
||||
?~ group-rid %.n
|
||||
?| !(is-managed:grp u.group-rid)
|
||||
?~ assoc
|
||||
%.n
|
||||
?| !(is-managed:grp group.u.assoc)
|
||||
&(watch-on-self =(our.bowl entity.rid))
|
||||
==
|
||||
::
|
||||
@ -367,7 +365,9 @@
|
||||
update-core(rid r, updates upds, group grp, module mod)
|
||||
::
|
||||
++ get-conversion
|
||||
(^get-conversion rid)
|
||||
:: LA: this tube should be cached in %hark-graph-hook state
|
||||
:: instead of just trying to keep it warm, as the scry overhead is large
|
||||
~+ (^get-conversion rid)
|
||||
::
|
||||
++ abet
|
||||
^- (quip card _state)
|
||||
@ -417,30 +417,34 @@
|
||||
|= =node:graph-store
|
||||
^+ update-core
|
||||
=. update-core (check-node-children node)
|
||||
?: ?=(%| -.post.node)
|
||||
update-core
|
||||
=* pos p.post.node
|
||||
=+ !< notif-kind=(unit notif-kind:hook)
|
||||
(get-conversion !>([0 post.node]))
|
||||
%- get-conversion
|
||||
!>(`indexed-post:graph-store`[0 pos])
|
||||
?~ notif-kind
|
||||
update-core
|
||||
=/ desc=@t
|
||||
?: (is-mention contents.post.node)
|
||||
?: (is-mention contents.pos)
|
||||
%mention
|
||||
name.u.notif-kind
|
||||
=* not-kind u.notif-kind
|
||||
=/ parent=index:post
|
||||
(scag parent.index-len.not-kind index.post.node)
|
||||
(scag parent.index-len.not-kind index.pos)
|
||||
=/ notif-index=index:store
|
||||
[%graph group rid module desc parent]
|
||||
?: =(our.bowl author.post.node)
|
||||
?: =(our.bowl author.pos)
|
||||
(self-post node notif-index not-kind)
|
||||
=. update-core
|
||||
(update-unread-count not-kind notif-index [time-sent index]:post.node)
|
||||
(update-unread-count not-kind notif-index [time-sent index]:pos)
|
||||
=? update-core
|
||||
?| =(desc %mention)
|
||||
(~(has in watching) [rid parent])
|
||||
==
|
||||
=/ =contents:store
|
||||
[%graph (limo post.node ~)]
|
||||
(add-unread notif-index [time-sent.post.node %.n contents])
|
||||
[%graph (limo pos ~)]
|
||||
(add-unread notif-index [time-sent.pos %.n contents])
|
||||
update-core
|
||||
::
|
||||
++ update-unread-count
|
||||
@ -459,19 +463,19 @@
|
||||
=notif-kind:hook
|
||||
==
|
||||
^+ update-core
|
||||
?> ?=(%& -.post.node)
|
||||
=/ =stats-index:store
|
||||
(to-stats-index:store index)
|
||||
=. update-core
|
||||
(hark %seen-index time-sent.post.node stats-index)
|
||||
(hark %seen-index time-sent.p.post.node stats-index)
|
||||
=? update-core ?=(%count mode.notif-kind)
|
||||
(hark %read-count stats-index)
|
||||
=? update-core watch-on-self
|
||||
(new-watch index.post.node [watch-for index-len]:notif-kind)
|
||||
(new-watch index.p.post.node [watch-for index-len]:notif-kind)
|
||||
update-core
|
||||
::
|
||||
++ add-unread
|
||||
|= [=index:store =notification:store]
|
||||
(hark %add-note index notification)
|
||||
::
|
||||
--
|
||||
--
|
||||
|
@ -202,7 +202,7 @@
|
||||
++ convert-graph-contents-4
|
||||
|= con=(list post:post-zero:post)
|
||||
^- (list post:post)
|
||||
(turn con post-to-one:graph-store)
|
||||
(turn con post-to-one:upgrade:graph-store)
|
||||
::
|
||||
++ convert-notifications-3
|
||||
|= old=notifications:state-two:store
|
||||
|
@ -24,6 +24,6 @@
|
||||
<div id="portal-root"></div>
|
||||
<script src="/~landscape/js/channel.js"></script>
|
||||
<script src="/~landscape/js/session.js"></script>
|
||||
<script src="/~landscape/js/bundle/index.59e682153138f604d358.js"></script>
|
||||
<script src="/~landscape/js/bundle/index.0a121973708299f6b966.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -5,6 +5,6 @@
|
||||
|= $: [now=@da eny=@uvJ =beak]
|
||||
[[=resource mark=(unit mark) overwrite=? ~] ~]
|
||||
==
|
||||
:- %graph-update-1
|
||||
:- %graph-update-2
|
||||
^- update
|
||||
[now [%add-graph resource (gas:orm ~ ~) mark overwrite]]
|
||||
|
@ -12,9 +12,9 @@
|
||||
contents.post contents
|
||||
==
|
||||
::
|
||||
:- %graph-update-1
|
||||
:- %graph-update-2
|
||||
^- update
|
||||
:- now
|
||||
:+ %add-nodes [our name]
|
||||
%- ~(gas by *(map index node))
|
||||
~[[[now]~ [post [%empty ~]]]]
|
||||
~[[[now]~ [[%& post] [%empty ~]]]]
|
||||
|
@ -5,6 +5,6 @@
|
||||
|= $: [now=@da eny=@uvJ =beak]
|
||||
[[[=resource =index] =signatures ~] ~]
|
||||
==
|
||||
:- %graph-update-1
|
||||
:- %graph-update-2
|
||||
^- update
|
||||
[now [%add-signatures [resource index] signatures]]
|
||||
|
@ -3,8 +3,8 @@
|
||||
/- *graph-store
|
||||
:- %say
|
||||
|= $: [now=@da eny=@uvJ =beak]
|
||||
[[=term =resource ~] ~]
|
||||
[[=term =uid ~] ~]
|
||||
==
|
||||
:- %graph-update-1
|
||||
:- %graph-update-2
|
||||
^- update
|
||||
[now [%add-tag term resource]]
|
||||
[now [%add-tag term uid]]
|
||||
|
@ -5,6 +5,6 @@
|
||||
|= $: [now=@da eny=@uvJ =beak]
|
||||
[[=resource ~] ~]
|
||||
==
|
||||
:- %graph-update-1
|
||||
:- %graph-update-2
|
||||
^- update
|
||||
[now [%archive-graph resource]]
|
||||
|
@ -4,7 +4,7 @@
|
||||
|= $: [now=@da eny=@uvJ bec=beak]
|
||||
[[=ship graph=term ~] ~]
|
||||
==
|
||||
:- %graph-update-1
|
||||
:- %graph-update-2
|
||||
=/ our (scot %p p.bec)
|
||||
=/ wen (scot %da now)
|
||||
=/ who (scot %p ship)
|
||||
|
@ -4,6 +4,6 @@
|
||||
|= $: [now=@da eny=@uvJ bec=beak]
|
||||
[[graph=term =path ~] ~]
|
||||
==
|
||||
:- %graph-update-1
|
||||
:- %graph-update-2
|
||||
=- ~& update=- -
|
||||
.^(=update:graph-store %cx path)
|
||||
|
@ -5,6 +5,6 @@
|
||||
|= $: [now=@da eny=@uvJ =beak]
|
||||
[[=resource ~] ~]
|
||||
==
|
||||
:- %graph-update-1
|
||||
:- %graph-update-2
|
||||
^- update
|
||||
[now [%remove-graph resource]]
|
||||
|
@ -1,10 +1,10 @@
|
||||
:: graph-store|remove-nodes: remove nodes from a graph at indices
|
||||
:: graph-store|remove-posts: remove nodes from a graph at indices
|
||||
::
|
||||
/- *graph-store
|
||||
:- %say
|
||||
|= $: [now=@da eny=@uvJ =beak]
|
||||
[[=resource indices=(set index) ~] ~]
|
||||
==
|
||||
:- %graph-update-1
|
||||
:- %graph-update-2
|
||||
^- update
|
||||
[now [%remove-nodes resource indices]]
|
||||
[now [%remove-posts resource indices]]
|
@ -6,6 +6,6 @@
|
||||
|= $: [now=@da eny=@uvJ =beak]
|
||||
[[[=resource =index] =signatures ~] ~]
|
||||
==
|
||||
:- %graph-update-1
|
||||
:- %graph-update-2
|
||||
^- update
|
||||
[now [%remove-signatures [resource index] signatures]]
|
||||
|
@ -3,8 +3,8 @@
|
||||
/- *graph-store
|
||||
:- %say
|
||||
|= $: [now=@da eny=@uvJ =beak]
|
||||
[[=term =resource ~] ~]
|
||||
[[=term =uid ~] ~]
|
||||
==
|
||||
:- %graph-update-1
|
||||
:- %graph-update-2
|
||||
^- update
|
||||
[now [%remove-tag term resource]]
|
||||
[now [%remove-tag term uid]]
|
||||
|
@ -5,6 +5,6 @@
|
||||
|= $: [now=@da eny=@uvJ =beak]
|
||||
[[=resource ~] ~]
|
||||
==
|
||||
:- %graph-update-1
|
||||
:- %graph-update-2
|
||||
^- update
|
||||
[now [%unarchive-graph resource]]
|
||||
|
@ -3,15 +3,14 @@
|
||||
:::: /hoon/code/hood/gen
|
||||
::
|
||||
/? 310
|
||||
::
|
||||
::::
|
||||
::
|
||||
:- %say
|
||||
/- *sole
|
||||
/+ *generators
|
||||
:- %ask
|
||||
|= $: [now=@da eny=@uvJ bec=beak]
|
||||
[arg=?(~ [%reset ~]) ~]
|
||||
==
|
||||
=* our p.bec
|
||||
:- %helm-code
|
||||
^- (sole-result [%helm-code ?(~ %reset)])
|
||||
?~ arg
|
||||
=/ code=tape
|
||||
%+ slag 1
|
||||
@ -20,11 +19,23 @@
|
||||
=/ step=tape
|
||||
%+ scow %ud
|
||||
.^(@ud %j /(scot %p our)/step/(scot %da now)/(scot %p our))
|
||||
%- %- slog
|
||||
:~ [%leaf code]
|
||||
[%leaf (weld "current step=" step)]
|
||||
[%leaf "use |code %reset to invalidate this and generate a new code"]
|
||||
==
|
||||
~
|
||||
::
|
||||
%+ print 'use |code %reset to invalidate this and generate a new code'
|
||||
%+ print leaf+(weld "current step=" step)
|
||||
%+ print leaf+code
|
||||
(produce [%helm-code ~])
|
||||
::
|
||||
?> =(%reset -.arg)
|
||||
%reset
|
||||
%+ print 'continue?'
|
||||
%+ print 'warning: resetting your code closes all web sessions'
|
||||
%+ prompt
|
||||
[%& %project "y/n: "]
|
||||
%+ parse
|
||||
;~ pose
|
||||
(cold %.y (mask "yY"))
|
||||
(cold %.n (mask "nN"))
|
||||
==
|
||||
|= reset=?
|
||||
?. reset
|
||||
no-product
|
||||
(produce [%helm-code %reset])
|
||||
|
@ -67,7 +67,7 @@
|
||||
=/ real=(set resource:re)
|
||||
=/ upd=update:ga
|
||||
%+ scry update:ga
|
||||
[%x %graph-store /keys/graph-update-1]
|
||||
[%x %graph-store /keys/graph-update-2]
|
||||
?> ?=(%keys -.q.upd)
|
||||
resources.q.upd
|
||||
:: count activity per channel
|
||||
@ -92,8 +92,11 @@
|
||||
:- (lent week)
|
||||
%~ wyt in
|
||||
%+ roll week
|
||||
|= [[* [author=ship *] *] a=(set ship)]
|
||||
(~(put in a) author)
|
||||
|= [[* mp=maybe-post:ga *] a=(set ship)]
|
||||
?- -.mp
|
||||
%| a
|
||||
%& (~(put in a) author.p.mp)
|
||||
==
|
||||
:: render results
|
||||
::
|
||||
:- (tac 'the date is ' (scot %da now))
|
||||
|
@ -1,105 +1,10 @@
|
||||
/- sur=graph-store, pos=post
|
||||
/+ res=resource
|
||||
/+ res=resource, migrate
|
||||
=< [sur .]
|
||||
=< [pos .]
|
||||
=, sur
|
||||
=, pos
|
||||
|%
|
||||
::
|
||||
++ update-log-to-one
|
||||
|= =update-log:zero
|
||||
^- ^update-log
|
||||
%+ gas:orm-log *^update-log
|
||||
%+ turn (tap:orm-log:zero update-log)
|
||||
|= [=time =logged-update:zero]
|
||||
:- time
|
||||
:- p.logged-update
|
||||
(logged-update-to-one q.logged-update)
|
||||
::
|
||||
++ logged-update-to-one
|
||||
|= upd=logged-update-0:zero
|
||||
?+ -.upd upd
|
||||
%add-graph upd(graph (graph-to-one graph.upd))
|
||||
%add-nodes upd(nodes (~(run by nodes.upd) node-to-one))
|
||||
==
|
||||
::
|
||||
++ node-to-one
|
||||
|= =node:zero
|
||||
(node:(upgrade ,post:zero ,post) node post-to-one)
|
||||
::
|
||||
++ graph-to-one
|
||||
|= =graph:zero
|
||||
(graph:(upgrade ,post:zero ,post) graph post-to-one)
|
||||
::
|
||||
++ marked-graph-to-one
|
||||
|= [=graph:zero m=(unit mark)]
|
||||
[(graph-to-one graph) m]
|
||||
::
|
||||
++ post-to-one
|
||||
|= p=post:zero
|
||||
^- post
|
||||
p(contents (contents-to-one contents.p))
|
||||
::
|
||||
++ contents-to-one
|
||||
|= cs=(list content:zero)
|
||||
^- (list content)
|
||||
%+ murn cs
|
||||
|= =content:zero
|
||||
^- (unit ^content)
|
||||
?: ?=(%reference -.content) ~
|
||||
`content
|
||||
::
|
||||
++ upgrade
|
||||
|* [in-pst=mold out-pst=mold]
|
||||
=>
|
||||
|%
|
||||
++ in-orm
|
||||
((ordered-map atom in-node) gth)
|
||||
+$ in-node
|
||||
[post=in-pst children=in-internal-graph]
|
||||
+$ in-graph
|
||||
((mop atom in-node) gth)
|
||||
+$ in-internal-graph
|
||||
$~ [%empty ~]
|
||||
$% [%graph p=in-graph]
|
||||
[%empty ~]
|
||||
==
|
||||
::
|
||||
++ out-orm
|
||||
((ordered-map atom out-node) gth)
|
||||
+$ out-node
|
||||
[post=out-pst children=out-internal-graph]
|
||||
+$ out-graph
|
||||
((mop atom out-node) gth)
|
||||
+$ out-internal-graph
|
||||
$~ [%empty ~]
|
||||
$% [%graph p=out-graph]
|
||||
[%empty ~]
|
||||
==
|
||||
--
|
||||
|%
|
||||
::
|
||||
++ graph
|
||||
|= $: gra=in-graph
|
||||
fn=$-(in-pst out-pst)
|
||||
==
|
||||
^- out-graph
|
||||
%+ gas:out-orm *out-graph
|
||||
^- (list [atom out-node])
|
||||
%+ turn (tap:in-orm gra)
|
||||
|= [a=atom n=in-node]
|
||||
^- [atom out-node]
|
||||
[a (node n fn)]
|
||||
::
|
||||
++ node
|
||||
|= [nod=in-node fn=$-(in-pst out-pst)]
|
||||
^- out-node
|
||||
:- (fn post.nod)
|
||||
^- out-internal-graph
|
||||
?: ?=(%empty -.children.nod)
|
||||
[%empty ~]
|
||||
[%graph (graph p.children.nod fn)]
|
||||
--
|
||||
:: NOTE: move these functions to zuse
|
||||
++ nu :: parse number as hex
|
||||
|= jon=json
|
||||
@ -212,6 +117,14 @@
|
||||
s+(enjs-path:res grp)
|
||||
--
|
||||
::
|
||||
++ maybe-post
|
||||
|= mp=^maybe-post
|
||||
^- json
|
||||
?- -.mp
|
||||
%| s+(scot %ux p.mp)
|
||||
%& (post p.mp)
|
||||
==
|
||||
::
|
||||
++ post
|
||||
|= p=^post
|
||||
^- json
|
||||
@ -252,8 +165,8 @@
|
||||
[%nodes (nodes nodes.upd)]
|
||||
==
|
||||
::
|
||||
%remove-nodes
|
||||
:- %remove-nodes
|
||||
%remove-posts
|
||||
:- %remove-posts
|
||||
%- pairs
|
||||
:~ [%resource (enjs:res resource.upd)]
|
||||
[%indices (indices indices.upd)]
|
||||
@ -277,14 +190,14 @@
|
||||
:- %add-tag
|
||||
%- pairs
|
||||
:~ [%term s+term.upd]
|
||||
[%resource (enjs:res resource.upd)]
|
||||
[%uid (uid uid.upd)]
|
||||
==
|
||||
::
|
||||
%remove-tag
|
||||
:- %remove-tag
|
||||
%- pairs
|
||||
:~ [%term s+term.upd]
|
||||
[%resource (enjs:res resource.upd)]
|
||||
[%uid (uid uid.upd)]
|
||||
==
|
||||
::
|
||||
%archive-graph
|
||||
@ -306,9 +219,9 @@
|
||||
:- %tag-queries
|
||||
%- pairs
|
||||
%+ turn ~(tap by tag-queries.upd)
|
||||
|= [=term =resources]
|
||||
|= [=term uids=(set ^uid)]
|
||||
^- [cord json]
|
||||
[term [%a (turn ~(tap in resources) enjs:res)]]
|
||||
[term [%a (turn ~(tap in uids) uid)]]
|
||||
==
|
||||
::
|
||||
++ graph
|
||||
@ -328,7 +241,7 @@
|
||||
|= n=^node
|
||||
^- json
|
||||
%- pairs
|
||||
:~ [%post (post post.n)]
|
||||
:~ [%post (maybe-post post.n)]
|
||||
:- %children
|
||||
?- -.children.n
|
||||
%empty ~
|
||||
@ -336,7 +249,6 @@
|
||||
==
|
||||
==
|
||||
::
|
||||
::
|
||||
++ nodes
|
||||
|= m=(map ^index ^node)
|
||||
^- json
|
||||
@ -370,7 +282,7 @@
|
||||
++ decode
|
||||
%- of
|
||||
:~ [%add-nodes add-nodes]
|
||||
[%remove-nodes remove-nodes]
|
||||
[%remove-posts remove-posts]
|
||||
[%add-signatures add-signatures]
|
||||
[%remove-signatures remove-signatures]
|
||||
::
|
||||
@ -422,7 +334,7 @@
|
||||
::
|
||||
++ node
|
||||
%- ot
|
||||
:~ [%post post]
|
||||
:~ [%post maybe-post]
|
||||
[%children internal-graph]
|
||||
==
|
||||
::
|
||||
@ -433,6 +345,15 @@
|
||||
[%empty ~]
|
||||
[%graph (graph jon)]
|
||||
::
|
||||
++ maybe-post
|
||||
|= jon=json
|
||||
^- ^maybe-post
|
||||
?~ jon !!
|
||||
?+ -.jon !!
|
||||
%s [%| (nu jon)]
|
||||
%o [%& (post jon)]
|
||||
==
|
||||
::
|
||||
++ post
|
||||
%- ot
|
||||
:~ [%author (su ;~(pfix sig fed:ag))]
|
||||
@ -489,9 +410,8 @@
|
||||
:~ expression+so
|
||||
output+tang
|
||||
==
|
||||
|
||||
::
|
||||
++ remove-nodes
|
||||
++ remove-posts
|
||||
%- ot
|
||||
:~ [%resource dejs:res]
|
||||
[%indices (as index)]
|
||||
@ -527,13 +447,13 @@
|
||||
++ add-tag
|
||||
%- ot
|
||||
:~ [%term so]
|
||||
[%resource dejs:res]
|
||||
[%uid uid]
|
||||
==
|
||||
::
|
||||
++ remove-tag
|
||||
%- ot
|
||||
:~ [%term so]
|
||||
[%resource dejs:res]
|
||||
[%uid uid]
|
||||
==
|
||||
::
|
||||
++ keys
|
||||
@ -568,4 +488,391 @@
|
||||
*signatures
|
||||
==
|
||||
--
|
||||
::
|
||||
++ upgrade
|
||||
|%
|
||||
::
|
||||
:: +two
|
||||
::
|
||||
++ marked-graph-to-two
|
||||
|= [=graph:one m=(unit mark)]
|
||||
[(graph-to-two graph) m]
|
||||
::
|
||||
++ graph-to-two
|
||||
|= =graph:one
|
||||
(graph:(upgrade ,post:one ,maybe-post) graph post-to-two)
|
||||
::
|
||||
++ post-to-two
|
||||
|= p=post:one
|
||||
^- maybe-post
|
||||
[%& p]
|
||||
::
|
||||
::
|
||||
:: +one
|
||||
::
|
||||
++ update-log-to-one
|
||||
|= =update-log:zero
|
||||
^- update-log:one
|
||||
%+ gas:orm-log:one *update-log:one
|
||||
%+ turn (tap:orm-log:zero update-log)
|
||||
|= [=time =logged-update:zero]
|
||||
^- [^time logged-update:one]
|
||||
:- time
|
||||
:- p.logged-update
|
||||
(logged-update-to-one q.logged-update)
|
||||
::
|
||||
++ logged-update-to-one
|
||||
|= upd=logged-update-0:zero
|
||||
^- logged-action:one
|
||||
?+ -.upd upd
|
||||
%add-graph upd(graph (graph-to-one graph.upd))
|
||||
%add-nodes upd(nodes (~(run by nodes.upd) node-to-one))
|
||||
==
|
||||
::
|
||||
++ node-to-one
|
||||
|= =node:zero
|
||||
(node:(upgrade ,post:zero ,post) node post-to-one)
|
||||
::
|
||||
++ graph-to-one
|
||||
|= =graph:zero
|
||||
(graph:(upgrade ,post:zero ,post) graph post-to-one)
|
||||
::
|
||||
++ marked-graph-to-one
|
||||
|= [=graph:zero m=(unit mark)]
|
||||
[(graph-to-one graph) m]
|
||||
::
|
||||
++ post-to-one
|
||||
|= p=post:zero
|
||||
^- post
|
||||
p(contents (contents-to-one contents.p))
|
||||
::
|
||||
++ contents-to-one
|
||||
|= cs=(list content:zero)
|
||||
^- (list content)
|
||||
%+ murn cs
|
||||
|= =content:zero
|
||||
^- (unit ^content)
|
||||
?: ?=(%reference -.content) ~
|
||||
`content
|
||||
::
|
||||
++ upgrade
|
||||
|* [in-pst=mold out-pst=mold]
|
||||
=>
|
||||
|%
|
||||
++ in-orm
|
||||
((ordered-map atom in-node) gth)
|
||||
+$ in-node
|
||||
[post=in-pst children=in-internal-graph]
|
||||
+$ in-graph
|
||||
((mop atom in-node) gth)
|
||||
+$ in-internal-graph
|
||||
$~ [%empty ~]
|
||||
$% [%graph p=in-graph]
|
||||
[%empty ~]
|
||||
==
|
||||
::
|
||||
++ out-orm
|
||||
((ordered-map atom out-node) gth)
|
||||
+$ out-node
|
||||
[post=out-pst children=out-internal-graph]
|
||||
+$ out-graph
|
||||
((mop atom out-node) gth)
|
||||
+$ out-internal-graph
|
||||
$~ [%empty ~]
|
||||
$% [%graph p=out-graph]
|
||||
[%empty ~]
|
||||
==
|
||||
--
|
||||
|%
|
||||
::
|
||||
++ graph
|
||||
|= $: gra=in-graph
|
||||
fn=$-(in-pst out-pst)
|
||||
==
|
||||
^- out-graph
|
||||
%+ gas:out-orm *out-graph
|
||||
^- (list [atom out-node])
|
||||
%+ turn (tap:in-orm gra)
|
||||
|= [a=atom n=in-node]
|
||||
^- [atom out-node]
|
||||
[a (node n fn)]
|
||||
::
|
||||
++ node
|
||||
|= [nod=in-node fn=$-(in-pst out-pst)]
|
||||
^- out-node
|
||||
:- (fn post.nod)
|
||||
^- out-internal-graph
|
||||
?: ?=(%empty -.children.nod)
|
||||
[%empty ~]
|
||||
[%graph (graph p.children.nod fn)]
|
||||
--
|
||||
::
|
||||
++ zero-load
|
||||
:: =* infinitely recurses
|
||||
=, store=zero
|
||||
=, orm=orm:zero
|
||||
=, orm-log=orm-log:zero
|
||||
|%
|
||||
++ change-revision-graph
|
||||
|= [=graph:store q=(unit mark)]
|
||||
^- [graph:store (unit mark)]
|
||||
|^
|
||||
:_ q
|
||||
?+ q graph
|
||||
[~ %graph-validator-link] convert-links
|
||||
[~ %graph-validator-publish] convert-publish
|
||||
==
|
||||
::
|
||||
++ convert-links
|
||||
%+ gas:orm *graph:store
|
||||
%+ turn (tap:orm graph)
|
||||
|= [=atom =node:store]
|
||||
^- [^atom node:store]
|
||||
:: top-level
|
||||
::
|
||||
:+ atom post.node
|
||||
?: ?=(%empty -.children.node)
|
||||
[%empty ~]
|
||||
:- %graph
|
||||
%+ gas:orm *graph:store
|
||||
%+ turn (tap:orm p.children.node)
|
||||
|= [=^atom =node:store]
|
||||
^- [^^atom node:store]
|
||||
:: existing comments get turned into containers for revisions
|
||||
::
|
||||
:^ atom
|
||||
post.node(contents ~, hash ~)
|
||||
%graph
|
||||
%+ gas:orm *graph:store
|
||||
:_ ~ :- %0
|
||||
:_ [%empty ~]
|
||||
post.node(index (snoc index.post.node atom), hash ~)
|
||||
::
|
||||
++ convert-publish
|
||||
%+ gas:orm *graph:store
|
||||
%+ turn (tap:orm graph)
|
||||
|= [=atom =node:store]
|
||||
^- [^atom node:store]
|
||||
:: top-level
|
||||
::
|
||||
:+ atom post.node
|
||||
?: ?=(%empty -.children.node)
|
||||
[%empty ~]
|
||||
:- %graph
|
||||
%+ gas:orm *graph:store
|
||||
%+ turn (tap:orm p.children.node)
|
||||
|= [=^atom =node:store]
|
||||
^- [^^atom node:store]
|
||||
:: existing container for publish note revisions
|
||||
::
|
||||
?+ atom !!
|
||||
%1 [atom node]
|
||||
%2
|
||||
:+ atom post.node
|
||||
?: ?=(%empty -.children.node)
|
||||
[%empty ~]
|
||||
:- %graph
|
||||
%+ gas:orm *graph:store
|
||||
%+ turn (tap:orm p.children.node)
|
||||
|= [=^^atom =node:store]
|
||||
^- [^^^atom node:store]
|
||||
:+ atom post.node(contents ~, hash ~)
|
||||
:- %graph
|
||||
%+ gas:orm *graph:store
|
||||
:_ ~ :- %1
|
||||
:_ [%empty ~]
|
||||
post.node(index (snoc index.post.node atom), hash ~)
|
||||
==
|
||||
--
|
||||
::
|
||||
++ maybe-unix-to-da
|
||||
|= =atom
|
||||
^- @
|
||||
:: (bex 127) is roughly 226AD
|
||||
?. (lte atom (bex 127))
|
||||
atom
|
||||
(add ~1970.1.1 (div (mul ~s1 atom) 1.000))
|
||||
::
|
||||
++ convert-unix-timestamped-node
|
||||
|= =node:store
|
||||
^- node:store
|
||||
=. index.post.node
|
||||
(convert-unix-timestamped-index index.post.node)
|
||||
?. ?=(%graph -.children.node)
|
||||
node
|
||||
:+ post.node
|
||||
%graph
|
||||
(convert-unix-timestamped-graph p.children.node)
|
||||
::
|
||||
++ convert-unix-timestamped-index
|
||||
|= =index:store
|
||||
(turn index maybe-unix-to-da)
|
||||
::
|
||||
++ convert-unix-timestamped-graph
|
||||
|= =graph:store
|
||||
%+ gas:orm *graph:store
|
||||
%+ turn
|
||||
(tap:orm graph)
|
||||
|= [=atom =node:store]
|
||||
^- [^atom node:store]
|
||||
:- (maybe-unix-to-da atom)
|
||||
(convert-unix-timestamped-node node)
|
||||
--
|
||||
--
|
||||
++ import
|
||||
|= [arc=* our=ship]
|
||||
^- (quip card:agent:gall [%5 network])
|
||||
|^
|
||||
=/ sty [%5 (remake-network ;;(tree-network +.arc))]
|
||||
:_ sty
|
||||
%+ turn ~(tap by graphs.sty)
|
||||
|= [rid=resource =marked-graph]
|
||||
^- card:agent:gall
|
||||
?: =(our entity.rid)
|
||||
=/ =cage [%push-hook-action !>([%add rid])]
|
||||
[%pass / %agent [our %graph-push-hook] %poke cage]
|
||||
(try-rejoin rid 0)
|
||||
::
|
||||
+$ tree-network
|
||||
$: graphs=tree-graphs
|
||||
tag-queries=(tree [term (tree uid)])
|
||||
update-logs=tree-update-logs
|
||||
archive=tree-graphs
|
||||
~
|
||||
==
|
||||
+$ tree-graphs (tree [resource tree-marked-graph])
|
||||
+$ tree-marked-graph [p=tree-graph q=(unit ^mark)]
|
||||
+$ tree-graph (tree [atom tree-node])
|
||||
+$ tree-node [post=tree-maybe-post children=tree-internal-graph]
|
||||
+$ tree-internal-graph
|
||||
$~ [%empty ~]
|
||||
$% [%graph p=tree-graph]
|
||||
[%empty ~]
|
||||
==
|
||||
+$ tree-update-logs (tree [resource tree-update-log])
|
||||
+$ tree-update-log (tree [time tree-logged-update])
|
||||
+$ tree-logged-update
|
||||
$: p=time
|
||||
$= q
|
||||
$% [%add-graph =resource =tree-graph mark=(unit ^mark) ow=?]
|
||||
[%add-nodes =resource nodes=(tree [index tree-node])]
|
||||
[%remove-posts =resource indices=(tree index)]
|
||||
[%add-signatures =uid signatures=tree-signatures]
|
||||
[%remove-signatures =uid signatures=tree-signatures]
|
||||
==
|
||||
==
|
||||
+$ tree-signatures (tree signature)
|
||||
+$ tree-maybe-post (each tree-post hash)
|
||||
+$ tree-post
|
||||
$: author=ship
|
||||
=index
|
||||
time-sent=time
|
||||
contents=(list content)
|
||||
hash=(unit hash)
|
||||
signatures=tree-signatures
|
||||
==
|
||||
::
|
||||
++ remake-network
|
||||
|= t=tree-network
|
||||
^- network
|
||||
:* (remake-graphs graphs.t)
|
||||
(remake-jug:migrate tag-queries.t)
|
||||
(remake-update-logs update-logs.t)
|
||||
(remake-graphs archive.t)
|
||||
~
|
||||
==
|
||||
::
|
||||
++ remake-graphs
|
||||
|= t=tree-graphs
|
||||
^- graphs
|
||||
%- remake-map:migrate
|
||||
(~(run by t) remake-marked-graph)
|
||||
::
|
||||
++ remake-marked-graph
|
||||
|= t=tree-marked-graph
|
||||
^- marked-graph
|
||||
[(remake-graph p.t) q.t]
|
||||
::
|
||||
++ remake-graph
|
||||
|= t=tree-graph
|
||||
^- graph
|
||||
%+ gas:orm *graph
|
||||
%+ turn ~(tap by t)
|
||||
|= [a=atom tn=tree-node]
|
||||
^- [atom node]
|
||||
[a (remake-node tn)]
|
||||
::
|
||||
++ remake-internal-graph
|
||||
|= t=tree-internal-graph
|
||||
^- internal-graph
|
||||
?: ?=(%empty -.t)
|
||||
[%empty ~]
|
||||
[%graph (remake-graph p.t)]
|
||||
::
|
||||
++ remake-node
|
||||
|= t=tree-node
|
||||
^- node
|
||||
:- (remake-post post.t)
|
||||
(remake-internal-graph children.t)
|
||||
::
|
||||
++ remake-update-logs
|
||||
|= t=tree-update-logs
|
||||
^- update-logs
|
||||
%- remake-map:migrate
|
||||
(~(run by t) remake-update-log)
|
||||
::
|
||||
++ remake-update-log
|
||||
|= t=tree-update-log
|
||||
^- update-log
|
||||
=/ ulm ((ordered-map time logged-update) gth)
|
||||
%+ gas:ulm *update-log
|
||||
%+ turn ~(tap by t)
|
||||
|= [=time tlu=tree-logged-update]
|
||||
^- [^time logged-update]
|
||||
[time (remake-logged-update tlu)]
|
||||
::
|
||||
++ remake-logged-update
|
||||
|= t=tree-logged-update
|
||||
^- logged-update
|
||||
:- p.t
|
||||
?- -.q.t
|
||||
%add-graph
|
||||
:* %add-graph
|
||||
resource.q.t
|
||||
(remake-graph tree-graph.q.t)
|
||||
mark.q.t
|
||||
ow.q.t
|
||||
==
|
||||
::
|
||||
%add-nodes
|
||||
:- %add-nodes
|
||||
:- resource.q.t
|
||||
%- remake-map:migrate
|
||||
(~(run by nodes.q.t) remake-node)
|
||||
::
|
||||
%remove-posts
|
||||
[%remove-posts resource.q.t (remake-set:migrate indices.q.t)]
|
||||
::
|
||||
%add-signatures
|
||||
[%add-signatures uid.q.t (remake-set:migrate signatures.q.t)]
|
||||
::
|
||||
%remove-signatures
|
||||
[%remove-signatures uid.q.t (remake-set:migrate signatures.q.t)]
|
||||
==
|
||||
::
|
||||
++ remake-post
|
||||
|= t=tree-maybe-post
|
||||
^- maybe-post
|
||||
?- -.t
|
||||
%| t
|
||||
%& t(signatures.p (remake-set:migrate signatures.p.t))
|
||||
==
|
||||
::
|
||||
++ try-rejoin
|
||||
|= [rid=resource nack-count=@]
|
||||
^- card:agent:gall
|
||||
=/ res-path (en-path:res rid)
|
||||
=/ wire [%try-rejoin (scot %ud nack-count) res-path]
|
||||
[%pass wire %agent [entity.rid %graph-push-hook] %watch resource+res-path]
|
||||
--
|
||||
--
|
||||
|
@ -19,7 +19,7 @@
|
||||
%add-graph ~[resource.q.update]
|
||||
%remove-graph ~[resource.q.update]
|
||||
%add-nodes ~[resource.q.update]
|
||||
%remove-nodes ~[resource.q.update]
|
||||
%remove-posts ~[resource.q.update]
|
||||
%add-signatures ~[resource.uid.q.update]
|
||||
%remove-signatures ~[resource.uid.q.update]
|
||||
%archive-graph ~[resource.q.update]
|
||||
@ -76,6 +76,7 @@
|
||||
++ get-graph
|
||||
|= res=resource
|
||||
^- update:store
|
||||
=- -(p *time)
|
||||
%+ scry-for update:store
|
||||
/graph/(scot %p entity.res)/[name.res]
|
||||
::
|
||||
|
@ -90,7 +90,12 @@
|
||||
$: tracking=(map resource track)
|
||||
inner-state=vase
|
||||
==
|
||||
|
||||
::
|
||||
+$ base-state-3
|
||||
$: prev-version=@ud
|
||||
prev-min-version=@ud
|
||||
base-state-2
|
||||
==
|
||||
::
|
||||
+$ state-0 [%0 base-state-0]
|
||||
::
|
||||
@ -100,12 +105,24 @@
|
||||
::
|
||||
+$ state-3 [%3 base-state-2]
|
||||
::
|
||||
+$ state-4 [%4 base-state-3]
|
||||
::
|
||||
+$ versioned-state
|
||||
$% state-0
|
||||
state-1
|
||||
state-2
|
||||
state-3
|
||||
state-4
|
||||
==
|
||||
:: +diplomatic: only renegotiate if versions changed
|
||||
::
|
||||
:: If %.n please leave note as to why renegotiation necessary
|
||||
::
|
||||
:: - Fixing incorrectly held unversioned subscriptions
|
||||
::
|
||||
++ diplomatic
|
||||
^- ?
|
||||
%.n
|
||||
::
|
||||
++ default
|
||||
|* [pull-hook=* =config]
|
||||
@ -198,7 +215,7 @@
|
||||
++ agent
|
||||
|* =config
|
||||
|= =(pull-hook config)
|
||||
=| state-3
|
||||
=| state-4
|
||||
=* state -
|
||||
^- agent:gall
|
||||
=<
|
||||
@ -224,13 +241,21 @@
|
||||
=| cards=(list card:agent:gall)
|
||||
|^
|
||||
?- -.old
|
||||
%3
|
||||
%4
|
||||
=^ og-cards pull-hook
|
||||
(on-load:og inner-state.old)
|
||||
=. state old
|
||||
=/ kick=(list card)
|
||||
?: ?& =(min-version.config prev-min-version.old)
|
||||
=(version.config prev-version.old)
|
||||
diplomatic
|
||||
==
|
||||
~
|
||||
(poke-self:pass kick+!>(%kick))^~
|
||||
:_ this
|
||||
:(weld cards og-cards (poke-self:pass kick+!>(%kick))^~)
|
||||
:(weld cards og-cards kick)
|
||||
::
|
||||
%3 $(old [%4 0 0 +.old])
|
||||
%2 $(old (state-to-3 old))
|
||||
%1 $(old [%2 +.old ~])
|
||||
%0 !! :: pre-breach
|
||||
@ -255,8 +280,10 @@
|
||||
::
|
||||
++ on-save
|
||||
^- vase
|
||||
=. inner-state
|
||||
on-save:og
|
||||
=: inner-state on-save:og
|
||||
prev-min-version min-version.config
|
||||
prev-version version.config
|
||||
==
|
||||
!>(state)
|
||||
::
|
||||
++ on-poke
|
||||
@ -422,6 +449,7 @@
|
||||
?~ tan tr-core
|
||||
?. versioned
|
||||
(tr-ap-og:tr-cleanup |.((on-pull-nack:og rid u.tan)))
|
||||
%- (slog leaf+"versioned nack for {<rid>} in {<dap.bowl>}" u.tan)
|
||||
=/ pax
|
||||
(kick-mule:virt rid |.((on-pull-kick:og rid)))
|
||||
?~ pax tr-failed-kick
|
||||
@ -446,18 +474,18 @@
|
||||
:: subscription
|
||||
tr-core
|
||||
(tr-suspend-pub-ver min-version.config)
|
||||
=/ =vase
|
||||
=/ =^cage
|
||||
(convert-to:ver cage)
|
||||
=/ =wire
|
||||
(make-wire /store)
|
||||
=+ resources=(~(gas in *(set resource)) (resource-for-update:og vase))
|
||||
=+ resources=(~(gas in *(set resource)) (resource-for-update:og q.cage))
|
||||
?> ?| no-validate.config
|
||||
?& (check-src resources)
|
||||
(~(has in resources) rid)
|
||||
== ==
|
||||
=/ =mark
|
||||
(append-version:ver version.config)
|
||||
(tr-emit (~(poke-our pass wire) store-name.config mark vase))
|
||||
(tr-emit (~(poke-our pass wire) store-name.config cage))
|
||||
--
|
||||
::
|
||||
++ tr-kick
|
||||
@ -472,6 +500,7 @@
|
||||
::
|
||||
++ tr-add
|
||||
|= [s=^ship r=resource]
|
||||
?< =(s our.bowl)
|
||||
=: ship s
|
||||
rid r
|
||||
status [%active ~]
|
||||
|
@ -57,14 +57,32 @@
|
||||
inner-state=vase
|
||||
==
|
||||
::
|
||||
+$ base-state-1
|
||||
$: prev-version=@ud
|
||||
prev-min-version=@ud
|
||||
base-state-0
|
||||
==
|
||||
::
|
||||
+$ state-0 [%0 base-state-0]
|
||||
::
|
||||
+$ state-1 [%1 base-state-0]
|
||||
+$ state-2 [%2 base-state-1]
|
||||
::
|
||||
+$ versioned-state
|
||||
$% state-0
|
||||
state-1
|
||||
state-2
|
||||
==
|
||||
:: +diplomatic: only renegotiate if versions changed
|
||||
::
|
||||
:: If %.n please leave note as to why renegotiation necessary
|
||||
::
|
||||
:: - Fixing incorrectly held unversioned subscriptions
|
||||
::
|
||||
++ diplomatic
|
||||
^- ?
|
||||
%.n
|
||||
::
|
||||
++ push-hook
|
||||
|* =config
|
||||
$_ ^|
|
||||
@ -153,7 +171,7 @@
|
||||
++ agent
|
||||
|* =config
|
||||
|= =(push-hook config)
|
||||
=| state-1
|
||||
=| state-2
|
||||
=* state -
|
||||
^- agent:gall
|
||||
=<
|
||||
@ -179,16 +197,21 @@
|
||||
=| cards=(list card:agent:gall)
|
||||
|^
|
||||
?- -.old
|
||||
%1
|
||||
%2
|
||||
=^ og-cards push-hook
|
||||
(on-load:og inner-state.old)
|
||||
=/ old-subs
|
||||
find-old-subs
|
||||
(find-old-subs [prev-version prev-min-version]:old)
|
||||
=/ version-cards
|
||||
:- (fact:io version+!>(version.config) /version ~)
|
||||
?~ old-subs ~
|
||||
(kick:io old-subs)^~
|
||||
[:(weld cards og-cards version-cards) this(state old)]
|
||||
::
|
||||
%1
|
||||
%_ $
|
||||
old [%2 0 0 +.old]
|
||||
==
|
||||
::
|
||||
::
|
||||
%0
|
||||
@ -205,6 +228,13 @@
|
||||
==
|
||||
::
|
||||
++ find-old-subs
|
||||
|= [prev-min-version=@ud prev-version=@ud]
|
||||
?: ?& =(min-version.config prev-min-version)
|
||||
=(prev-version version.config)
|
||||
diplomatic
|
||||
==
|
||||
:: bail on kick if we didn't change versions
|
||||
~
|
||||
%~ tap in
|
||||
%+ roll
|
||||
~(val by sup.bowl)
|
||||
@ -230,8 +260,10 @@
|
||||
--
|
||||
::
|
||||
++ on-save
|
||||
=. inner-state
|
||||
on-save:og
|
||||
=: prev-version version.config
|
||||
prev-min-version min-version.config
|
||||
inner-state on-save:og
|
||||
==
|
||||
!>(state)
|
||||
::
|
||||
++ on-poke
|
||||
@ -270,23 +302,21 @@
|
||||
?. (supported:ver mark)
|
||||
:_ this
|
||||
(fact-init-kick:io version+!>(min-version.config))
|
||||
=/ =vase
|
||||
(convert-to:ver mark (initial-watch:og t.t.t.t.t.t.path resource))
|
||||
:_ this
|
||||
[%give %fact ~ mark vase]~
|
||||
=- [%give %fact ~ -]~
|
||||
(convert-to:ver mark (initial-watch:og t.t.t.t.t.t.path resource))
|
||||
::
|
||||
++ unversioned
|
||||
?> ?=([%ship @ @ *] t.path)
|
||||
?. =(min-version.config 0)
|
||||
~& >>> "unversioned req from: {<src.bowl>}, nooping"
|
||||
`this
|
||||
=/ =resource
|
||||
(de-path:resource t.path)
|
||||
=/ =vase
|
||||
%+ convert-to:ver update-mark.config
|
||||
=/ =vase
|
||||
(initial-watch:og t.t.t.t.path resource)
|
||||
:_ this
|
||||
[%give %fact ~ update-mark.config vase]~
|
||||
?. =(min-version.config 0)
|
||||
~& >>> "unversioned req from: {<src.bowl>}, nooping"
|
||||
~
|
||||
[%give %fact ~ (convert-to:ver update-mark.config vase)]~
|
||||
--
|
||||
::
|
||||
++ on-agent
|
||||
@ -440,10 +470,7 @@
|
||||
|= [fact-ver=@ud paths=(set path)]
|
||||
=/ =mark
|
||||
(append-version:ver fact-ver)
|
||||
=/ =^cage
|
||||
:- mark
|
||||
(convert-from:ver mark q.cage)
|
||||
(fact:io cage ~(tap in paths))
|
||||
(fact:io (convert-from:ver mark q.cage) ~(tap in paths))
|
||||
:: TODO: deprecate
|
||||
++ unversioned
|
||||
?. =(min-version.config 0) ~
|
||||
@ -453,18 +480,15 @@
|
||||
%- ~(gas in *(set path))
|
||||
(turn (incoming-subscriptions prefix) tail)
|
||||
?: =(0 ~(wyt in unversioned)) ~
|
||||
=/ =^cage
|
||||
:- update-mark.config
|
||||
(convert-from:ver update-mark.config q.cage)
|
||||
(fact:io cage ~(tap in unversioned))^~
|
||||
(fact:io (convert-from:ver update-mark.config q.cage) ~(tap in unversioned))^~
|
||||
--
|
||||
::
|
||||
++ forward-update
|
||||
|= =cage
|
||||
^- (list card:agent:gall)
|
||||
=- lis
|
||||
=/ vas
|
||||
(convert-to:ver cage)
|
||||
=/ vas=vase
|
||||
q:(convert-to:ver cage)
|
||||
%+ roll (resource-for-update q.cage)
|
||||
|= [rid=resource [lis=(list card:agent:gall) tf-vas=(unit vase)]]
|
||||
^- [(list card:agent:gall) (unit vase)]
|
||||
|
@ -29,11 +29,12 @@
|
||||
&((gte ver min) (lte ver version))
|
||||
::
|
||||
++ convert-to
|
||||
|= =cage
|
||||
^- vase
|
||||
?: =(p.cage current-version)
|
||||
q.cage
|
||||
((tube-to p.cage) q.cage)
|
||||
|= [=mark =vase]
|
||||
^- cage
|
||||
:- current-version
|
||||
?: =(mark current-version)
|
||||
vase
|
||||
((tube-to mark) vase)
|
||||
::
|
||||
++ tube-to
|
||||
|= =mark
|
||||
@ -44,10 +45,11 @@
|
||||
.^(tube:clay %cc (scry:io %home /[current-version]/[mark]))
|
||||
::
|
||||
++ convert-from
|
||||
|= =cage
|
||||
^- vase
|
||||
?: =(p.cage current-version)
|
||||
q.cage
|
||||
((tube-from p.cage) q.cage)
|
||||
|= [=mark =vase]
|
||||
^- cage
|
||||
:- mark
|
||||
?: =(mark current-version)
|
||||
vase
|
||||
((tube-from mark) vase)
|
||||
--
|
||||
|
||||
|
@ -1,19 +1,17 @@
|
||||
/+ *graph-store
|
||||
=* as-octs as-octs:mimes:html
|
||||
::
|
||||
|_ upd=update
|
||||
|_ upd=update:one
|
||||
++ grad %noun
|
||||
++ grow
|
||||
|%
|
||||
++ noun upd
|
||||
++ json (update:enjs upd)
|
||||
++ mime [/application/x-urb-graph-update (as-octs (jam upd))]
|
||||
--
|
||||
::
|
||||
++ grab
|
||||
|%
|
||||
++ noun update
|
||||
++ json update:dejs
|
||||
++ noun update:one
|
||||
++ mime |=([* =octs] ;;(update (cue q.octs)))
|
||||
--
|
||||
--
|
||||
|
19
pkg/arvo/mar/graph/update-2.hoon
Normal file
19
pkg/arvo/mar/graph/update-2.hoon
Normal file
@ -0,0 +1,19 @@
|
||||
/+ *graph-store
|
||||
=* as-octs as-octs:mimes:html
|
||||
::
|
||||
|_ upd=update
|
||||
++ grad %noun
|
||||
++ grow
|
||||
|%
|
||||
++ noun upd
|
||||
++ json (update:enjs upd)
|
||||
++ mime [/application/x-urb-graph-update (as-octs (jam upd))]
|
||||
--
|
||||
::
|
||||
++ grab
|
||||
|%
|
||||
++ noun update
|
||||
++ json update:dejs
|
||||
++ mime |=([* =octs] ;;(update (cue q.octs)))
|
||||
--
|
||||
--
|
@ -1,5 +1,61 @@
|
||||
/- *post
|
||||
|%
|
||||
+$ graph ((mop atom node) gth)
|
||||
+$ marked-graph [p=graph q=(unit mark)]
|
||||
::
|
||||
+$ maybe-post (each post hash)
|
||||
+$ node [post=maybe-post children=internal-graph]
|
||||
+$ graphs (map resource marked-graph)
|
||||
::
|
||||
+$ tag-queries (jug term uid)
|
||||
::
|
||||
+$ 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
|
||||
~
|
||||
==
|
||||
::
|
||||
+$ update [p=time q=action]
|
||||
::
|
||||
+$ logged-update [p=time q=logged-action]
|
||||
|
||||
::
|
||||
+$ logged-action
|
||||
$% [%add-graph =resource =graph mark=(unit mark) overwrite=?]
|
||||
[%add-nodes =resource nodes=(map index node)]
|
||||
[%remove-posts =resource indices=(set index)]
|
||||
[%add-signatures =uid =signatures]
|
||||
[%remove-signatures =uid =signatures]
|
||||
==
|
||||
::
|
||||
+$ action
|
||||
$% logged-action
|
||||
[%remove-graph =resource]
|
||||
::
|
||||
[%add-tag =term =uid]
|
||||
[%remove-tag =term =uid]
|
||||
::
|
||||
[%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]
|
||||
==
|
||||
::
|
||||
+$ permissions
|
||||
[admin=permission-level writer=permission-level reader=permission-level]
|
||||
@ -13,11 +69,75 @@
|
||||
+$ permission-level
|
||||
?(%no %self %yes)
|
||||
::
|
||||
:: %graph-store types version 1
|
||||
::
|
||||
++ one
|
||||
|%
|
||||
++ orm ((ordered-map atom node) gth)
|
||||
++ orm-log ((ordered-map time logged-update) gth)
|
||||
::
|
||||
+$ 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 [p=time q=action]
|
||||
::
|
||||
+$ logged-update [p=time q=logged-action]
|
||||
::
|
||||
+$ logged-action
|
||||
$% [%add-graph =resource =graph mark=(unit mark) overwrite=?]
|
||||
[%add-nodes =resource nodes=(map index node)]
|
||||
[%remove-nodes =resource indices=(set index)]
|
||||
[%add-signatures =uid =signatures]
|
||||
[%remove-signatures =uid =signatures]
|
||||
==
|
||||
::
|
||||
+$ action
|
||||
$% logged-action
|
||||
[%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]
|
||||
==
|
||||
--
|
||||
::
|
||||
:: %graph-store types version 0
|
||||
::
|
||||
++ zero
|
||||
=< [. post-zero]
|
||||
=, post-zero
|
||||
|%
|
||||
::
|
||||
++ orm ((ordered-map atom node) gth)
|
||||
++ orm-log ((ordered-map time logged-update) gth)
|
||||
::
|
||||
@ -81,61 +201,4 @@
|
||||
[%tag-queries =tag-queries]
|
||||
==
|
||||
--
|
||||
|
||||
+$ 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 [p=time q=action]
|
||||
::
|
||||
+$ logged-update [p=time q=logged-action]
|
||||
|
||||
::
|
||||
+$ logged-action
|
||||
$% [%add-graph =resource =graph mark=(unit mark) overwrite=?]
|
||||
[%add-nodes =resource nodes=(map index node)]
|
||||
[%remove-nodes =resource indices=(set index)]
|
||||
[%add-signatures =uid =signatures]
|
||||
[%remove-signatures =uid =signatures]
|
||||
==
|
||||
::
|
||||
+$ action
|
||||
$% logged-action
|
||||
[%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]
|
||||
==
|
||||
--
|
||||
|
@ -1,27 +1,5 @@
|
||||
/- *resource
|
||||
|%
|
||||
::
|
||||
++ post-zero
|
||||
|%
|
||||
::
|
||||
+$ content
|
||||
$% [%text text=cord]
|
||||
[%mention =ship]
|
||||
[%url url=cord]
|
||||
[%code expression=cord output=(list tank)]
|
||||
[%reference =uid]
|
||||
==
|
||||
::
|
||||
+$ post
|
||||
$: author=ship
|
||||
=index
|
||||
time-sent=time
|
||||
contents=(list content)
|
||||
hash=(unit hash)
|
||||
=signatures
|
||||
==
|
||||
--
|
||||
|
||||
+$ index (list atom)
|
||||
+$ uid [=resource =index]
|
||||
::
|
||||
@ -60,4 +38,25 @@
|
||||
[%code expression=cord output=(list tank)]
|
||||
[%reference =reference]
|
||||
==
|
||||
::
|
||||
++ post-zero
|
||||
|%
|
||||
::
|
||||
+$ content
|
||||
$% [%text text=cord]
|
||||
[%mention =ship]
|
||||
[%url url=cord]
|
||||
[%code expression=cord output=(list tank)]
|
||||
[%reference =uid]
|
||||
==
|
||||
::
|
||||
+$ post
|
||||
$: author=ship
|
||||
=index
|
||||
time-sent=time
|
||||
contents=(list content)
|
||||
hash=(unit hash)
|
||||
=signatures
|
||||
==
|
||||
--
|
||||
--
|
||||
|
@ -32,7 +32,7 @@
|
||||
=/ hashes (nodes-to-pending-indices nodes.q.update)
|
||||
;< ~ bind:m
|
||||
%^ poke-our %graph-push-hook
|
||||
%graph-update-1
|
||||
%graph-update-2
|
||||
!>(update)
|
||||
(pure:m !>(`action:graph-view`[%pending-indices hashes]))
|
||||
::
|
||||
@ -75,7 +75,8 @@
|
||||
^- [index:store node:store]
|
||||
=* loop $
|
||||
:- index
|
||||
=* p post.node
|
||||
?> ?=(%& -.post.node)
|
||||
=* p p.post.node
|
||||
=/ =hash:store
|
||||
=- `@ux`(sham -)
|
||||
:^ ?^ parent-hash
|
||||
@ -85,9 +86,9 @@
|
||||
time-sent.p
|
||||
contents.p
|
||||
%_ node
|
||||
hash.post `hash
|
||||
hash.p.post `hash
|
||||
::
|
||||
signatures.post
|
||||
signatures.p.post
|
||||
%- ~(gas in *signatures:store)
|
||||
[(sign:sig our.bowl now.bowl hash)]~
|
||||
::
|
||||
@ -115,7 +116,8 @@
|
||||
?: ?=([@ ~] index)
|
||||
~
|
||||
=/ node (got-deep:gra graph (snip `(list atom)`index))
|
||||
hash.post.node
|
||||
?> ?=(%& -.post.node)
|
||||
hash.p.post.node
|
||||
::
|
||||
++ nodes-to-pending-indices
|
||||
|= nodes=(map index:store node:store)
|
||||
@ -124,6 +126,7 @@
|
||||
%+ turn ~(tap by nodes)
|
||||
|= [=index:store =node:store]
|
||||
^- [hash:store index:store]
|
||||
?> ?=(^ hash.post.node)
|
||||
[u.hash.post.node index]
|
||||
?> ?=(%& -.post.node)
|
||||
?> ?=(^ hash.p.post.node)
|
||||
[u.hash.p.post.node index]
|
||||
--
|
||||
|
@ -39,7 +39,7 @@
|
||||
==
|
||||
;< ~ bind:m
|
||||
%+ poke-our %graph-store
|
||||
:- %graph-update-1
|
||||
:- %graph-update-2
|
||||
!> ^- update:graph
|
||||
[now.bowl %add-graph feed-rid *graph:graph `%graph-validator-post %&]
|
||||
;< ~ bind:m
|
||||
|
@ -54,7 +54,7 @@
|
||||
=/ =update:graph
|
||||
[now.bowl %add-graph rid.action *graph:graph mark.action overwrite]
|
||||
;< ~ bind:m
|
||||
(poke-our %graph-store graph-update-1+!>(update))
|
||||
(poke-our %graph-store graph-update-2+!>(update))
|
||||
;< ~ bind:m
|
||||
(poke-our %graph-push-hook %push-hook-action !>([%add rid.action]))
|
||||
::
|
||||
|
@ -36,7 +36,7 @@
|
||||
^- form:m
|
||||
;< =bowl:spider bind:m get-bowl:strandio
|
||||
;< ~ bind:m
|
||||
(poke-our %graph-store %graph-update-1 !>([now.bowl %remove-graph rid]))
|
||||
(poke-our %graph-store %graph-update-2 !>([now.bowl %remove-graph rid]))
|
||||
;< ~ bind:m
|
||||
(poke-our %graph-push-hook %push-hook-action !>([%remove rid]))
|
||||
;< ~ bind:m
|
||||
|
@ -40,7 +40,7 @@
|
||||
?: ?=([~ ^] feed.config.metadatum)
|
||||
;< ~ bind:m
|
||||
%+ poke-our %graph-store
|
||||
:- %graph-update-1
|
||||
:- %graph-update-2
|
||||
!> ^- update:graph
|
||||
[now.bowl [%archive-graph resource.u.u.feed.config.metadatum]]
|
||||
(pure:m !>(~))
|
||||
|
@ -39,7 +39,7 @@
|
||||
;< ~ bind:m
|
||||
(poke-our %graph-pull-hook %pull-hook-action !>([%remove rid]))
|
||||
;< ~ bind:m
|
||||
(poke-our %graph-store %graph-update-1 !>([now [%remove-graph rid]]))
|
||||
(poke-our %graph-store %graph-update-2 !>([now [%remove-graph rid]]))
|
||||
(pure:m ~)
|
||||
--
|
||||
::
|
||||
|
@ -17,7 +17,7 @@
|
||||
;< =bowl:spider bind:m get-bowl:strandio
|
||||
:: unarchive graph and share it
|
||||
;< ~ bind:m
|
||||
(poke-our %graph-store %graph-update-1 !>([now.bowl %unarchive-graph rid]))
|
||||
(poke-our %graph-store %graph-update-2 !>([now.bowl %unarchive-graph rid]))
|
||||
;< ~ bind:m
|
||||
(poke-our %graph-push-hook %push-hook-action !>([%add rid]))
|
||||
::
|
||||
|
@ -70,7 +70,7 @@
|
||||
;< ~ bind:m
|
||||
%+ raw-poke
|
||||
[our.bowl %graph-store]
|
||||
:- %graph-update-1
|
||||
:- %graph-update-2
|
||||
!> ^- update:gra
|
||||
[now.bowl [%archive-graph app-resource]]
|
||||
;< ~ bind:m
|
||||
|
@ -12,9 +12,9 @@
|
||||
|= [our=@p wen=@da rid=resource body=cord id=@]
|
||||
=/ =index:post [id]~
|
||||
=/ =post:post [our index wen [%text body]~ ~ ~]
|
||||
=/ =node:graph-store [post %empty ~]
|
||||
=/ =node:graph-store [[%& post] %empty ~]
|
||||
=/ act=update:graph-store [wen %add-nodes rid (my [index node] ~)]
|
||||
(poke-app our %graph-push-hook %graph-update-1 act)
|
||||
(poke-app our %graph-push-hook %graph-update-2 act)
|
||||
--
|
||||
::
|
||||
^- thread:spider
|
||||
|
@ -12,9 +12,9 @@
|
||||
|= [our=@p wen=@da rid=resource body=cord id=@]
|
||||
=/ =index:post [id]~
|
||||
=/ =post:post [our index wen [%text body]~ ~ ~]
|
||||
=/ =node:graph-store [post %empty ~]
|
||||
=/ =node:graph-store [[%& post] %empty ~]
|
||||
=/ act=update:graph-store [wen %add-nodes rid (my [index node] ~)]
|
||||
(poke-app our %graph-push-hook %graph-update-1 act)
|
||||
(poke-app our %graph-push-hook %graph-update-2 act)
|
||||
--
|
||||
::
|
||||
^- thread:spider
|
||||
|
@ -25,12 +25,13 @@ The first two options result in Urbit attempting to boot either the ship named b
|
||||
In consequence, it is safe to remove the container and start a new container which mounts the same volume, e.g. to upgrade the version of the urbit binary by running a later container version. It is also possible to stop the container and then move the pier away e.g. to a location where you will run it directly with the Urbit binary.
|
||||
|
||||
### Ports
|
||||
The image includes `EXPOSE` directives for TCP port 80 and UDP port 34343. Port `80` is used for Urbit's HTTP interface for both [Landscape](https://urbit.org/docs/glossary/landscape/) and for [API calls](https://urbit.org/using/integrating-api/) to the ship. Port `34343` is used by [Ames](https://urbit.org/docs/glossary/ames/) for ship-to-ship communication.
|
||||
The image includes `EXPOSE` directives for TCP port 80 and UDP port 34343. Port `80` is used for Urbit's HTTP interface for both [Landscape](https://urbit.org/docs/glossary/landscape/) and for [API calls](https://urbit.org/using/integrating-api/) to the ship. Port `34343` is set by default to be used by [Ames](https://urbit.org/docs/glossary/ames/) for ship-to-ship communication.
|
||||
|
||||
You can either pass the `-P` flag to docker to map ports directly to the corresponding ports on the host, or map them individually with `-p` flags. For local testing the latter is often convenient, for instance to remap port 80 to an unprivileged port.
|
||||
You can either pass the `-P` flag to docker to map ports directly to the corresponding ports on the host, or map them individually with `-p` flags. For local testing the latter is often convenient, for instance to remap port 80 to an unprivileged port.
|
||||
|
||||
You should be able to use port mapping for most purposes but you can force Ames to use a custom port.
|
||||
`--port=$AMES_PORT` can be passed as an argument to the `docker start` command. Passing `--port=13436` for example, would use port 13436.
|
||||
For best performance, you must map the Ames UDP port to the *same* port on the host. If you map to a different port Ames will not be able to make direct connections and your network performance may suffer somewhat. Note that using the same port is required for direct connections but is not by itself sufficient for them. If you are behind a NAT router or the host is not on a public IP address or you are firewalled, you may not achive direct connections regardless.
|
||||
|
||||
For this purpose you can force Ames to use a custom port. `/bin/start-urbit --port=$AMES_PORT` can be passed as an argument to the `docker start` command. Passing `/bin/start-urbit --port=13436` for example, would use port 13436. You must pass the name of the start script `/bin/start-urbit` in order to also pass arguments, if this is omitted your container will not start.
|
||||
|
||||
### Examples
|
||||
Creating a volume for ~sampel=palnet:
|
||||
@ -38,23 +39,23 @@ Creating a volume for ~sampel=palnet:
|
||||
docker volume create sampel-palnet
|
||||
```
|
||||
|
||||
Copying key to sampel-palnet's volume (assumes default docker location)
|
||||
Copying key to sampel-palnet's volume (assumes default docker location):
|
||||
```
|
||||
sudo cp ~/sampel-palnet.key /var/lib/docker/volumes/sampel-palnet/_data/sampel-palnet.key
|
||||
```
|
||||
|
||||
Using that volume and launching ~sampel-palnet on host port 8080 with Ames talking on host port 27000:
|
||||
Using that volume and launching ~sampel-palnet on host port 8080 with Ames talking on the default host port 34343:
|
||||
```
|
||||
docker run -d -p 8080:80 -p 27000:34343/udp --name sampel-palnet \
|
||||
docker run -d -p 8080:80 -p 34343:34343/udp --name sampel-palnet \
|
||||
--mount type=volume,source=sampel-palnet,destination=/urbit \
|
||||
tloncorp/urbit
|
||||
```
|
||||
|
||||
Using host port 8088 with Ames talking on host port 23232 while forcing Ames to start internally on port 13436:
|
||||
Using host port 8088 with Ames talking on host port 23232:
|
||||
```
|
||||
docker run -d -p 8088:80 -p 23232:13436/udp --name sampel-palnet \
|
||||
docker run -d -p 8088:80 -p 23232:23232/udp --name sampel-palnet \
|
||||
--mount type=volume,source=sampel-palnet,destination=/urbit \
|
||||
tloncorp/urbit --port=13436
|
||||
tloncorp/urbit /bin/start-urbit --port=23232
|
||||
```
|
||||
|
||||
### Getting and resetting the Landscape +code
|
||||
|
@ -25,10 +25,10 @@ module Urbit.Arvo.Common
|
||||
import Urbit.Prelude
|
||||
|
||||
import Control.Monad.Fail (fail)
|
||||
import Data.Bits
|
||||
import Data.Serialize
|
||||
|
||||
import qualified Network.HTTP.Types.Method as H
|
||||
import qualified Network.Socket as N
|
||||
import qualified Urbit.Ob as Ob
|
||||
|
||||
|
||||
@ -159,6 +159,19 @@ deriveNoun ''JsonNode
|
||||
|
||||
-- Ames Destinations -------------------------------------------------
|
||||
|
||||
serializeToNoun :: Serialize a => a -> Noun
|
||||
serializeToNoun = A . bytesAtom . encode
|
||||
|
||||
serializeParseNoun :: Serialize a => String -> Int -> Noun -> Parser a
|
||||
serializeParseNoun desc len = named (pack desc) . \case
|
||||
A (atomBytes -> bs)
|
||||
-- Atoms lose leading 0s, but since lsb, these become trailing NULs
|
||||
| length bs <= len -> case decode $ bs <> replicate (len - length bs) 0 of
|
||||
Right aa -> pure aa
|
||||
Left msg -> fail msg
|
||||
| otherwise -> fail ("putative " <> desc <> " " <> show bs <> " too long")
|
||||
C{} -> fail ("unexpected cell in " <> desc)
|
||||
|
||||
newtype Patp a = Patp { unPatp :: a }
|
||||
deriving newtype (Eq, Ord, Enum, Real, Integral, Num, ToNoun, FromNoun)
|
||||
|
||||
@ -167,17 +180,29 @@ newtype Port = Port { unPort :: Word16 }
|
||||
deriving newtype (Eq, Ord, Show, Enum, Real, Integral, Num, ToNoun, FromNoun)
|
||||
|
||||
-- @if
|
||||
newtype Ipv4 = Ipv4 { unIpv4 :: Word32 }
|
||||
deriving newtype (Eq, Ord, Enum, Real, Integral, Num, ToNoun, FromNoun)
|
||||
newtype Ipv4 = Ipv4 { unIpv4 :: N.HostAddress }
|
||||
deriving newtype (Eq, Ord, Enum)
|
||||
|
||||
instance Serialize Ipv4 where
|
||||
get = (\a b c d -> Ipv4 $ N.tupleToHostAddress $ (d, c, b, a))
|
||||
<$> getWord8 <*> getWord8 <*> getWord8 <*> getWord8
|
||||
put (Ipv4 (N.hostAddressToTuple -> (a, b, c, d))) = for_ [d, c, b, a] putWord8
|
||||
|
||||
instance ToNoun Ipv4 where
|
||||
toNoun = serializeToNoun
|
||||
|
||||
instance FromNoun Ipv4 where
|
||||
parseNoun = serializeParseNoun "Ipv4" 4
|
||||
|
||||
instance Show Ipv4 where
|
||||
show (Ipv4 i) =
|
||||
show ((shiftR i 24) .&. 0xff) ++ "." ++
|
||||
show ((shiftR i 16) .&. 0xff) ++ "." ++
|
||||
show ((shiftR i 8) .&. 0xff) ++ "." ++
|
||||
show (i .&. 0xff)
|
||||
show (Ipv4 (N.hostAddressToTuple -> (a, b, c, d))) =
|
||||
show a ++ "." ++
|
||||
show b ++ "." ++
|
||||
show c ++ "." ++
|
||||
show d
|
||||
|
||||
-- @is
|
||||
-- should probably use hostAddress6ToTuple here, but no one uses it right now
|
||||
newtype Ipv6 = Ipv6 { unIpv6 :: Word128 }
|
||||
deriving newtype (Eq, Ord, Show, Enum, Real, Integral, Num, ToNoun, FromNoun)
|
||||
|
||||
@ -190,21 +215,14 @@ data AmesAddress = AAIpv4 Ipv4 Port
|
||||
deriving (Eq, Ord, Show)
|
||||
|
||||
instance Serialize AmesAddress where
|
||||
get = AAIpv4 <$> (Ipv4 <$> getWord32le) <*> (Port <$> getWord16le)
|
||||
put (AAIpv4 (Ipv4 ip) (Port port)) = putWord32le ip >> putWord16le port
|
||||
get = AAIpv4 <$> get <*> (Port <$> getWord16le)
|
||||
put (AAIpv4 ip (Port port)) = put ip >> putWord16le port
|
||||
|
||||
instance FromNoun AmesAddress where
|
||||
parseNoun = named "AmesAddress" . \case
|
||||
A (atomBytes -> bs)
|
||||
-- Atoms lose leading 0s, but since lsb, these become trailing NULs
|
||||
| length bs <= 6 -> case decode $ bs <> replicate (6 - length bs) 0 of
|
||||
Right aa -> pure aa
|
||||
Left msg -> fail msg
|
||||
| otherwise -> fail ("putative address " <> show bs <> " too long")
|
||||
C{} -> fail "unexpected cell in ames address"
|
||||
parseNoun = serializeParseNoun "AmesAddress" 6
|
||||
|
||||
instance ToNoun AmesAddress where
|
||||
toNoun = A . bytesAtom . encode
|
||||
toNoun = serializeToNoun
|
||||
|
||||
type AmesDest = Each Galaxy AmesAddress
|
||||
|
||||
|
@ -80,10 +80,6 @@ data ShipClass
|
||||
muk :: ByteString -> Word20
|
||||
muk bs = mugBS bs .&. (2 ^ 20 - 1)
|
||||
|
||||
-- XX check this
|
||||
getAmesAddress :: Get AmesAddress
|
||||
getAmesAddress = AAIpv4 <$> (Ipv4 <$> getWord32le) <*> (Port <$> getWord16le)
|
||||
|
||||
putAmesAddress :: Putter AmesAddress
|
||||
putAmesAddress = \case
|
||||
AAIpv4 (Ipv4 ip) (Port port) -> putWord32le ip >> putWord16le port
|
||||
@ -104,7 +100,7 @@ instance Serialize Packet where
|
||||
guard isAmes
|
||||
|
||||
pktOrigin <- if isRelayed
|
||||
then Just <$> getAmesAddress
|
||||
then Just <$> get
|
||||
else pure Nothing
|
||||
|
||||
-- body
|
||||
@ -157,9 +153,10 @@ instance Serialize Packet where
|
||||
|
||||
putWord32le head
|
||||
case pktOrigin of
|
||||
Just o -> putAmesAddress o
|
||||
Just o -> put o
|
||||
Nothing -> pure ()
|
||||
putByteString body
|
||||
|
||||
where
|
||||
putShipGetRank s@(Ship (LargeKey p q)) = case () of
|
||||
_ | s < 2 ^ 16 -> (0, putWord16le $ fromIntegral s) -- lord
|
||||
|
@ -4,8 +4,12 @@
|
||||
1. Opens a UDP socket and makes sure that it stays open.
|
||||
|
||||
- If can't open the port, wait and try again repeatedly.
|
||||
- If there is an error reading or writting from the open socket,
|
||||
close it and open another.
|
||||
- If there is an error reading to or writing from the open socket,
|
||||
close it and open another, making sure, however, to reuse the
|
||||
same port
|
||||
NOTE: It's not clear what, if anything, closing and reopening
|
||||
the socket does. We're keeping this behavior out of conservatism
|
||||
until we understand it better.
|
||||
|
||||
2. Receives packets from the socket.
|
||||
|
||||
@ -158,7 +162,7 @@ realUdpServ
|
||||
-> HostAddress
|
||||
-> AmesStat
|
||||
-> RIO e UdpServ
|
||||
realUdpServ por hos sat = do
|
||||
realUdpServ startPort hos sat = do
|
||||
logInfo $ displayShow ("AMES", "UDP", "Starting real UDP server.")
|
||||
|
||||
env <- ask
|
||||
@ -202,23 +206,30 @@ realUdpServ por hos sat = do
|
||||
did <- atomically (tryWriteTBQueue qSend (a, b))
|
||||
when (did == False) $ do
|
||||
logWarn "AMES: UDP: Dropping outbound packet because queue is full."
|
||||
let opener por = do
|
||||
logInfo $ displayShow $ ("AMES", "UDP", "Trying to open socket, port",)
|
||||
por
|
||||
sk <- forceBind por hos
|
||||
sn <- io $ getSocketName sk
|
||||
sp <- io $ socketPort sk
|
||||
logInfo $ displayShow $ ("AMES", "UDP", "Got socket", sn, sp)
|
||||
|
||||
tOpen <- async $ forever $ do
|
||||
sk <- forceBind por hos
|
||||
sn <- io $ getSocketName sk
|
||||
let waitForRelease = do
|
||||
atomically (writeTVar vSock (Just sk))
|
||||
broken <- atomically (takeTMVar vFail)
|
||||
logWarn "AMES: UDP: Closing broken socket."
|
||||
io (close broken)
|
||||
|
||||
let waitForRelease = do
|
||||
atomically (writeTVar vSock (Just sk))
|
||||
broken <- atomically (takeTMVar vFail)
|
||||
logWarn "AMES: UDP: Closing broken socket."
|
||||
io (close broken)
|
||||
case sn of
|
||||
(SockAddrInet boundPort _) ->
|
||||
-- When we're on IPv4, maybe port forward at the NAT.
|
||||
rwith (requestPortAccess $ fromIntegral boundPort) $
|
||||
\() -> waitForRelease
|
||||
_ -> waitForRelease
|
||||
|
||||
case sn of
|
||||
(SockAddrInet boundPort _) ->
|
||||
-- When we're on IPv4, maybe port forward at the NAT.
|
||||
rwith (requestPortAccess $ fromIntegral boundPort) $
|
||||
\() -> waitForRelease
|
||||
_ -> waitForRelease
|
||||
opener sp
|
||||
|
||||
tOpen <- async $ opener startPort
|
||||
|
||||
tSend <- async $ forever $ join $ atomically $ do
|
||||
(adr, byt) <- readTBQueue qSend
|
||||
|
@ -37,12 +37,12 @@ textPlain = Path [(MkKnot "text"), (MkKnot "plain")]
|
||||
|
||||
-- | Filter for dotfiles, tempfiles and backup files.
|
||||
validClaySyncPath :: FilePath -> Bool
|
||||
validClaySyncPath fp = hasPeriod && notTildeFile && notDotHash && notDoubleHash
|
||||
validClaySyncPath fp = hasPeriod && notTildeFile && notDotFile && notDoubleHash
|
||||
where
|
||||
fileName = takeFileName fp
|
||||
hasPeriod = elem '.' fileName
|
||||
notTildeFile = not $ "~" `isSuffixOf` fileName
|
||||
notDotHash = not $ ".#" `isPrefixOf` fileName
|
||||
notDotFile = not $ "." `isPrefixOf` fileName
|
||||
notDoubleHash =
|
||||
not $ ("#" `isPrefixOf` fileName) && ("#" `isSuffixOf` fileName)
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
name: urbit-king
|
||||
version: 1.3
|
||||
version: 1.5
|
||||
license: MIT
|
||||
license-file: LICENSE
|
||||
data-files:
|
||||
|
@ -1,3 +1,3 @@
|
||||
module.exports = {
|
||||
extends: "@urbit"
|
||||
};
|
||||
extends: '@urbit'
|
||||
};
|
||||
|
3652
pkg/interface/package-lock.json
generated
3652
pkg/interface/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -8,9 +8,10 @@
|
||||
"@reach/disclosure": "^0.10.5",
|
||||
"@reach/menu-button": "^0.10.5",
|
||||
"@reach/tabs": "^0.10.5",
|
||||
"@react-spring/web": "^9.1.1",
|
||||
"@tlon/indigo-dark": "^1.0.6",
|
||||
"@tlon/indigo-light": "^1.0.7",
|
||||
"@tlon/indigo-react": "^1.2.21",
|
||||
"@tlon/indigo-react": "^1.2.22",
|
||||
"@tlon/sigil-js": "^1.4.3",
|
||||
"@urbit/api": "file:../npm/api",
|
||||
"any-ascii": "^0.1.7",
|
||||
@ -23,7 +24,6 @@
|
||||
"formik": "^2.1.5",
|
||||
"immer": "^8.0.1",
|
||||
"lodash": "^4.17.20",
|
||||
"markdown-to-jsx": "^6.11.4",
|
||||
"moment": "^2.29.1",
|
||||
"mousetrap": "^1.6.5",
|
||||
"mousetrap-global-bind": "^1.1.0",
|
||||
@ -38,15 +38,18 @@
|
||||
"react-markdown": "^4.3.1",
|
||||
"react-oembed-container": "^1.0.0",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-use-gesture": "^9.1.3",
|
||||
"react-virtuoso": "^0.20.3",
|
||||
"react-visibility-sensor": "^5.1.1",
|
||||
"remark": "^12.0.0",
|
||||
"remark-breaks": "^2.0.1",
|
||||
"remark-disable-tokenizers": "^1.0.24",
|
||||
"remark-disable-tokenizers": "1.1.0",
|
||||
"stacktrace-js": "^2.0.2",
|
||||
"style-loader": "^1.3.0",
|
||||
"styled-components": "^5.1.1",
|
||||
"styled-system": "^5.1.5",
|
||||
"suncalc": "^1.8.0",
|
||||
"unist-util-visit": "^3.0.0",
|
||||
"urbit-ob": "^5.0.1",
|
||||
"workbox-core": "^6.0.2",
|
||||
"workbox-precaching": "^6.0.2",
|
||||
|
@ -1,9 +1,7 @@
|
||||
import './wdyr';
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
|
||||
import './register-sw';
|
||||
|
||||
import App from './views/App';
|
||||
import './wdyr';
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById('root'));
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Path, Patp } from '@urbit/api';
|
||||
import _ from 'lodash';
|
||||
import { Patp, Path } from '@urbit/api';
|
||||
import BaseStore from '../store/base';
|
||||
|
||||
export default class BaseApi<S extends object = {}> {
|
||||
|
@ -1,7 +1,8 @@
|
||||
import BaseApi from './base';
|
||||
import { StoreState } from '../store/type';
|
||||
import { Patp } from '@urbit/api';
|
||||
import { ContactEdit } from '@urbit/api/contacts';
|
||||
import { ContactEditField } from '@urbit/api/contacts';
|
||||
import _ from 'lodash';
|
||||
import { StoreState } from '../store/type';
|
||||
import BaseApi from './base';
|
||||
|
||||
export default class ContactsApi extends BaseApi<StoreState> {
|
||||
add(ship: Patp, contact: any) {
|
||||
@ -13,7 +14,7 @@ export default class ContactsApi extends BaseApi<StoreState> {
|
||||
return this.storeAction({ remove: { ship } });
|
||||
}
|
||||
|
||||
edit(ship: Patp, editField: ContactEdit) {
|
||||
edit(ship: Patp, editField: ContactEditField) {
|
||||
/* editField can be...
|
||||
{nickname: ''}
|
||||
{email: ''}
|
||||
@ -73,6 +74,28 @@ export default class ContactsApi extends BaseApi<StoreState> {
|
||||
);
|
||||
}
|
||||
|
||||
async disallowedShipsForOurContact(ships: string[]): Promise<string[]> {
|
||||
return _.compact(
|
||||
await Promise.all(
|
||||
ships.map(
|
||||
async (s) => {
|
||||
const ship = `~${s}`;
|
||||
if(s === window.ship) {
|
||||
return null;
|
||||
}
|
||||
const allowed = await this.fetchIsAllowed(
|
||||
`~${window.ship}`,
|
||||
'personal',
|
||||
ship,
|
||||
true
|
||||
);
|
||||
return allowed ? null : ship;
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
retrieve(ship: string) {
|
||||
const resource = { ship, name: '' };
|
||||
return this.action('contact-pull-hook', 'pull-hook-action', {
|
||||
|
@ -1,7 +1,5 @@
|
||||
import type { StoreState } from '../store/type';
|
||||
import BaseApi from './base';
|
||||
import type {StoreState} from '../store/type';
|
||||
import type {GcpToken} from '../../types/gcp-state';
|
||||
|
||||
|
||||
export default class GcpApi extends BaseApi<StoreState> {
|
||||
// Does not touch the store; use the value manually.
|
||||
@ -18,4 +16,4 @@ export default class GcpApi extends BaseApi<StoreState> {
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1,17 +1,17 @@
|
||||
import { Patp } from '@urbit/api';
|
||||
import BaseApi from './base';
|
||||
import { StoreState } from '../store/type';
|
||||
import GlobalStore from '../store/store';
|
||||
import LocalApi from './local';
|
||||
import InviteApi from './invite';
|
||||
import MetadataApi from './metadata';
|
||||
import { StoreState } from '../store/type';
|
||||
import BaseApi from './base';
|
||||
import ContactsApi from './contacts';
|
||||
import GroupsApi from './groups';
|
||||
import LaunchApi from './launch';
|
||||
import GraphApi from './graph';
|
||||
import S3Api from './s3';
|
||||
import GcpApi from './gcp';
|
||||
import GraphApi from './graph';
|
||||
import GroupsApi from './groups';
|
||||
import { HarkApi } from './hark';
|
||||
import InviteApi from './invite';
|
||||
import LaunchApi from './launch';
|
||||
import LocalApi from './local';
|
||||
import MetadataApi from './metadata';
|
||||
import S3Api from './s3';
|
||||
import SettingsApi from './settings';
|
||||
|
||||
export default class GlobalApi extends BaseApi<StoreState> {
|
||||
|
@ -1,10 +1,9 @@
|
||||
import BaseApi from './base';
|
||||
import { StoreState } from '../store/type';
|
||||
import { Patp, Path, Resource } from '@urbit/api';
|
||||
import { Content, Enc, GraphNode, GroupPolicy, Path, Patp, Post, Resource } from '@urbit/api';
|
||||
import _ from 'lodash';
|
||||
import { decToUd, deSig, resourceAsPath, unixToDa } from '~/logic/lib/util';
|
||||
import { makeResource, resourceFromPath } from '../lib/group';
|
||||
import { GroupPolicy, Enc, Post, Content } from '@urbit/api';
|
||||
import { numToUd, unixToDa, decToUd, deSig, resourceAsPath } from '~/logic/lib/util';
|
||||
import { StoreState } from '../store/type';
|
||||
import BaseApi from './base';
|
||||
|
||||
export const createBlankNodeWithChildPost = (
|
||||
parentIndex = '',
|
||||
@ -83,7 +82,7 @@ export default class GraphApi extends BaseApi<StoreState> {
|
||||
joiningGraphs = new Set<string>();
|
||||
|
||||
private storeAction(action: any): Promise<any> {
|
||||
return this.action('graph-store', 'graph-update-1', action);
|
||||
return this.action('graph-store', 'graph-update-2', action);
|
||||
}
|
||||
|
||||
private viewAction(threadName: string, action: any) {
|
||||
@ -91,7 +90,7 @@ export default class GraphApi extends BaseApi<StoreState> {
|
||||
}
|
||||
|
||||
private hookAction(ship: Patp, action: any): Promise<any> {
|
||||
return this.action('graph-push-hook', 'graph-update-1', action);
|
||||
return this.action('graph-push-hook', 'graph-update-2', action);
|
||||
}
|
||||
|
||||
createManagedGraph(
|
||||
@ -185,13 +184,12 @@ export default class GraphApi extends BaseApi<StoreState> {
|
||||
});
|
||||
}
|
||||
|
||||
eval(cord: string) {
|
||||
eval(cord: string): Promise<string[] | undefined> {
|
||||
return this.spider('graph-view-action', 'tang', 'graph-eval', {
|
||||
eval: cord
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
addGraph(ship: Patp, name: string, graph: any, mark: any) {
|
||||
return this.storeAction({
|
||||
'add-graph': {
|
||||
@ -211,7 +209,7 @@ export default class GraphApi extends BaseApi<StoreState> {
|
||||
return this.addNodes(ship, name, nodes);
|
||||
}
|
||||
|
||||
addNode(ship: Patp, name: string, node: Object) {
|
||||
addNode(ship: Patp, name: string, node: GraphNode) {
|
||||
const nodes = {};
|
||||
nodes[node.post.index] = node;
|
||||
|
||||
@ -227,7 +225,7 @@ export default class GraphApi extends BaseApi<StoreState> {
|
||||
};
|
||||
|
||||
const pendingPromise = this.spider(
|
||||
'graph-update-1',
|
||||
'graph-update-2',
|
||||
'graph-view-action',
|
||||
'graph-add-nodes',
|
||||
action
|
||||
@ -265,7 +263,7 @@ export default class GraphApi extends BaseApi<StoreState> {
|
||||
'resource',
|
||||
'graph-create-group-feed',
|
||||
{
|
||||
"create-group-feed": { resource: group, vip }
|
||||
'create-group-feed': { resource: group, vip }
|
||||
}
|
||||
);
|
||||
return resource;
|
||||
@ -277,15 +275,14 @@ export default class GraphApi extends BaseApi<StoreState> {
|
||||
'json',
|
||||
'graph-disable-group-feed',
|
||||
{
|
||||
"disable-group-feed": { resource: group }
|
||||
'disable-group-feed': { resource: group }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
removeNodes(ship: Patp, name: string, indices: string[]) {
|
||||
removePosts(ship: Patp, name: string, indices: string[]) {
|
||||
return this.hookAction(ship, {
|
||||
'remove-nodes': {
|
||||
'remove-posts': {
|
||||
resource: { ship, name },
|
||||
indices
|
||||
}
|
||||
@ -369,7 +366,7 @@ export default class GraphApi extends BaseApi<StoreState> {
|
||||
const node = data['graph-update'];
|
||||
this.store.handleEvent({
|
||||
data: {
|
||||
"graph-update-loose": node
|
||||
'graph-update-loose': node
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
import BaseApi from './base';
|
||||
import { StoreState } from '../store/type';
|
||||
import { Path, Patp, Enc } from '@urbit/api';
|
||||
import { Enc, Patp } from '@urbit/api';
|
||||
import {
|
||||
GroupAction,
|
||||
GroupPolicy,
|
||||
Resource,
|
||||
Tag,
|
||||
GroupPolicyDiff
|
||||
|
||||
GroupPolicyDiff, Resource,
|
||||
Tag
|
||||
} from '@urbit/api/groups';
|
||||
import { makeResource } from '../lib/group';
|
||||
import { StoreState } from '../store/type';
|
||||
import BaseApi from './base';
|
||||
|
||||
export default class GroupsApi extends BaseApi<StoreState> {
|
||||
remove(resource: Resource, ships: Patp[]) {
|
||||
|
@ -1,10 +1,10 @@
|
||||
import BaseApi from './base';
|
||||
import { StoreState } from '../store/type';
|
||||
import { dateToDa, decToUd } from '../lib/util';
|
||||
import { NotifIndex, IndexedNotification, Association, GraphNotifDescription } from '@urbit/api';
|
||||
import { Association, GraphNotifDescription, IndexedNotification, NotifIndex } from '@urbit/api';
|
||||
import { BigInteger } from 'big-integer';
|
||||
import { getParentIndex } from '../lib/notification';
|
||||
import { dateToDa, decToUd } from '../lib/util';
|
||||
import useHarkState from '../state/hark';
|
||||
import { StoreState } from '../store/type';
|
||||
import BaseApi from './base';
|
||||
|
||||
function getHarkSize() {
|
||||
return useHarkState.getState().notifications.size ?? 0;
|
||||
@ -75,7 +75,6 @@ export class HarkApi extends BaseApi<StoreState> {
|
||||
graph: {
|
||||
graph: association.resource,
|
||||
group: association.group,
|
||||
module: association.metadata.module,
|
||||
description,
|
||||
index: parent
|
||||
} }
|
||||
|
@ -1,6 +1,6 @@
|
||||
import BaseApi from './base';
|
||||
import { Serial } from '@urbit/api';
|
||||
import { StoreState } from '../store/type';
|
||||
import { Serial, Path } from '@urbit/api';
|
||||
import BaseApi from './base';
|
||||
|
||||
export default class InviteApi extends BaseApi<StoreState> {
|
||||
accept(app: string, uid: Serial) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import BaseApi from './base';
|
||||
import { StoreState } from '../store/type';
|
||||
import BaseApi from './base';
|
||||
|
||||
export default class LaunchApi extends BaseApi<StoreState> {
|
||||
add(name: string, tile = { basic : { title: '', linkedUrl: '', iconUrl: '' } }) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import BaseApi from './base';
|
||||
import { StoreState } from '../store/type';
|
||||
import BaseApi from './base';
|
||||
|
||||
export default class LocalApi extends BaseApi<StoreState> {
|
||||
getBaseHash() {
|
||||
@ -7,8 +7,4 @@ export default class LocalApi extends BaseApi<StoreState> {
|
||||
this.store.handleEvent({ data: { baseHash } });
|
||||
});
|
||||
}
|
||||
|
||||
dehydrate() {
|
||||
this.store.dehydrate();
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
|
||||
import BaseApi from './base';
|
||||
import { StoreState } from '../store/type';
|
||||
import { Path, Patp, Association, Metadata, MetadataUpdatePreview } from '@urbit/api';
|
||||
import { Association, Metadata, MetadataUpdatePreview, Path } from '@urbit/api';
|
||||
import { uxToHex } from '../lib/util';
|
||||
import { StoreState } from '../store/type';
|
||||
import BaseApi from './base';
|
||||
|
||||
export default class MetadataApi extends BaseApi<StoreState> {
|
||||
metadataAdd(appName: string, resource: Path, group: Path, title: string, description: string, dateCreated: string, color: string, moduleName: string) {
|
||||
|
@ -1,6 +1,5 @@
|
||||
import BaseApi from './base';
|
||||
import { StoreState } from '../store/type';
|
||||
import { S3Update } from '../../types/s3-update';
|
||||
import BaseApi from './base';
|
||||
|
||||
export default class S3Api extends BaseApi<StoreState> {
|
||||
setCurrentBucket(bucket: string) {
|
||||
|
@ -1,12 +1,13 @@
|
||||
import BaseApi from './base';
|
||||
import { StoreState } from '../store/type';
|
||||
import { Key,
|
||||
Value,
|
||||
Bucket
|
||||
import {
|
||||
Bucket, Key,
|
||||
|
||||
SettingsUpdate, Value
|
||||
} from '@urbit/api/settings';
|
||||
import { StoreState } from '../store/type';
|
||||
import BaseApi from './base';
|
||||
|
||||
export default class SettingsApi extends BaseApi<StoreState> {
|
||||
private storeAction(action: SettingsEvent): Promise<any> {
|
||||
private storeAction(action: SettingsUpdate): Promise<any> {
|
||||
return this.action('settings-store', 'settings-event', action);
|
||||
}
|
||||
|
||||
@ -47,14 +48,14 @@ export default class SettingsApi extends BaseApi<StoreState> {
|
||||
}
|
||||
|
||||
async getAll() {
|
||||
const { all } = await this.scry("settings-store", "/all");
|
||||
this.store.handleEvent({data:
|
||||
{"settings-data": { all } }
|
||||
const { all } = await this.scry('settings-store', '/all');
|
||||
this.store.handleEvent({ data:
|
||||
{ 'settings-data': { all } }
|
||||
});
|
||||
}
|
||||
|
||||
async getBucket(bucket: Key) {
|
||||
const data = await this.scry('settings-store', `/bucket/${bucket}`);
|
||||
const data: Record<string, unknown> = await this.scry('settings-store', `/bucket/${bucket}`);
|
||||
this.store.handleEvent({ data: { 'settings-data': {
|
||||
'bucket-key': bucket,
|
||||
'bucket': data.bucket
|
||||
@ -62,7 +63,7 @@ export default class SettingsApi extends BaseApi<StoreState> {
|
||||
}
|
||||
|
||||
async getEntry(bucket: Key, entry: Key) {
|
||||
const data = await this.scry('settings-store', `/entry/${bucket}/${entry}`);
|
||||
const data: Record<string, unknown> = await this.scry('settings-store', `/entry/${bucket}/${entry}`);
|
||||
this.store.handleEvent({ data: { 'settings-data': {
|
||||
'bucket-key': bucket,
|
||||
'entry-key': entry,
|
||||
|
@ -7,14 +7,12 @@
|
||||
//
|
||||
import querystring from 'querystring';
|
||||
import {
|
||||
StorageAcl,
|
||||
StorageClient,
|
||||
StorageUpload,
|
||||
UploadParams,
|
||||
UploadResult
|
||||
} from './StorageClient';
|
||||
|
||||
|
||||
const ENDPOINT = 'storage.googleapis.com';
|
||||
|
||||
class GcpUpload implements StorageUpload {
|
||||
@ -27,7 +25,7 @@ class GcpUpload implements StorageUpload {
|
||||
}
|
||||
|
||||
async promise(): Promise<UploadResult> {
|
||||
const {Bucket, Key, ContentType, Body} = this.#params;
|
||||
const { Bucket, Key, ContentType, Body } = this.#params;
|
||||
const urlParams = {
|
||||
uploadType: 'media',
|
||||
name: Key,
|
||||
@ -50,7 +48,7 @@ class GcpUpload implements StorageUpload {
|
||||
console.error('GcpClient server error', await response.json());
|
||||
throw new Error(`GcpClient: response ${response.status}`);
|
||||
}
|
||||
return {Location: `https://${ENDPOINT}/${Bucket}/${Key}`};
|
||||
return { Location: `https://${ENDPOINT}/${Bucket}/${Key}` };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,13 @@
|
||||
// Defines a StorageClient interface interoperable between S3 and GCP Storage.
|
||||
//
|
||||
|
||||
|
||||
// XX kind of gross. S3 needs 'public-read', GCP needs 'publicRead'.
|
||||
// Rather than write a wrapper around S3, we offer this field here, which
|
||||
// should always be passed, and will be replaced by 'publicRead' in the
|
||||
// GCP client.
|
||||
export enum StorageAcl {
|
||||
PublicRead = 'public-read'
|
||||
};
|
||||
}
|
||||
|
||||
export interface UploadParams {
|
||||
Bucket: string; // the bucket to upload the object to
|
||||
@ -16,17 +15,17 @@ export interface UploadParams {
|
||||
ContentType: string; // the object's mime-type
|
||||
ACL: StorageAcl; // ACL, always 'public-read'
|
||||
Body: File; // the object itself
|
||||
};
|
||||
}
|
||||
|
||||
export interface UploadResult {
|
||||
Location: string;
|
||||
};
|
||||
}
|
||||
|
||||
// Extra layer of indirection used by S3 client.
|
||||
export interface StorageUpload {
|
||||
promise(): Promise<UploadResult>;
|
||||
};
|
||||
}
|
||||
|
||||
export interface StorageClient {
|
||||
upload(params: UploadParams): StorageUpload;
|
||||
};
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import bigInt, { BigInteger } from 'big-integer';
|
||||
import { BigInteger } from 'big-integer';
|
||||
|
||||
export function max(a: BigInteger, b: BigInteger) {
|
||||
return a.gt(b) ? a : b;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React from "react";
|
||||
import React from 'react';
|
||||
|
||||
export type SubmitHandler = () => Promise<any>;
|
||||
interface IFormGroupContext {
|
||||
@ -12,7 +12,7 @@ const fallback: IFormGroupContext = {
|
||||
addSubmit: () => {},
|
||||
onDirty: () => {},
|
||||
onErrors: () => {},
|
||||
submitAll: () => Promise.resolve(),
|
||||
submitAll: () => Promise.resolve()
|
||||
};
|
||||
|
||||
export const FormGroupContext = React.createContext(fallback);
|
||||
|
@ -15,7 +15,6 @@
|
||||
import GlobalApi from '../api/global';
|
||||
import useStorageState from '../state/storage';
|
||||
|
||||
|
||||
class GcpManager {
|
||||
#api: GlobalApi | null = null;
|
||||
|
||||
@ -59,15 +58,15 @@ class GcpManager {
|
||||
this.start();
|
||||
}
|
||||
|
||||
#consecutiveFailures: number = 0;
|
||||
#configured: boolean = false;
|
||||
#consecutiveFailures = 0;
|
||||
#configured = false;
|
||||
|
||||
private refreshLoop() {
|
||||
if (!this.#configured) {
|
||||
this.#api!.gcp.isConfigured()
|
||||
.then((configured) => {
|
||||
if (configured === undefined) {
|
||||
throw new Error("can't check whether GCP is configured?");
|
||||
throw new Error('can\'t check whether GCP is configured?');
|
||||
}
|
||||
this.#configured = configured;
|
||||
if (this.#configured) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { Path, PatpNoSig } from '@urbit/api';
|
||||
import { Group, Resource, roleTags, RoleTags } from '@urbit/api/groups';
|
||||
import _ from 'lodash';
|
||||
import { roleTags, RoleTags, Group, Resource } from '@urbit/api/groups';
|
||||
import { PatpNoSig, Path } from '@urbit/api';
|
||||
import { deSig } from './util';
|
||||
|
||||
export function roleForShip(
|
||||
group: Group,
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { IndexedNotification, NotificationGraphConfig, Unreads } from '@urbit/api';
|
||||
import bigInt, { BigInteger } from 'big-integer';
|
||||
import f from 'lodash/fp';
|
||||
import { Unreads, NotificationGraphConfig } from '@urbit/api';
|
||||
|
||||
export function getLastSeen(
|
||||
unreads: Unreads,
|
||||
@ -36,11 +36,24 @@ export function getNotificationCount(
|
||||
}
|
||||
|
||||
export function isWatching(
|
||||
config: NotificationGraphConfig,
|
||||
config: NotificationGraphConfig,
|
||||
graph: string,
|
||||
index = "/"
|
||||
index = '/'
|
||||
) {
|
||||
return !!config.watching.find(
|
||||
return Boolean(config.watching.find(
|
||||
watch => watch.graph === graph && watch.index === index
|
||||
);
|
||||
));
|
||||
}
|
||||
|
||||
export function getNotificationKey(time: BigInteger, notification: IndexedNotification): string {
|
||||
const base = time.toString();
|
||||
if('graph' in notification.index) {
|
||||
const { graph, index } = notification.index.graph;
|
||||
return `${base}-${graph}-${index}`;
|
||||
} else if('group' in notification.index) {
|
||||
const { group } = notification.index.group;
|
||||
return `${base}-${group}`;
|
||||
}
|
||||
return `${base}-unknown`;
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
export function useIdlingState() {
|
||||
const [idling, setIdling] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
useEffect(() => {
|
||||
function blur() {
|
||||
setIdling(true);
|
||||
}
|
||||
@ -16,7 +16,7 @@ export function useIdlingState() {
|
||||
return () => {
|
||||
window.removeEventListener('blur', blur);
|
||||
window.removeEventListener('focus', focus);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
return idling;
|
||||
|
@ -1,15 +1,15 @@
|
||||
import useLocalState, { LocalState } from "~/logic/state/local";
|
||||
import useSettingsState from "~/logic/state/settings";
|
||||
import GlobalApi from "../api/global";
|
||||
import { BackgroundConfig, RemoteContentPolicy } from "~/types";
|
||||
import useLocalState from '~/logic/state/local';
|
||||
import useSettingsState from '~/logic/state/settings';
|
||||
import { BackgroundConfig, RemoteContentPolicy } from '~/types';
|
||||
import GlobalApi from '../api/global';
|
||||
|
||||
const getBackgroundString = (bg: BackgroundConfig) => {
|
||||
if (bg?.type === "url") {
|
||||
if (bg?.type === 'url') {
|
||||
return bg.url;
|
||||
} else if (bg?.type === "color") {
|
||||
} else if (bg?.type === 'color') {
|
||||
return bg.color;
|
||||
} else {
|
||||
return "";
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
@ -18,17 +18,17 @@ export function useMigrateSettings(api: GlobalApi) {
|
||||
const { display, remoteContentPolicy, calm } = useSettingsState();
|
||||
|
||||
return async () => {
|
||||
let promises: Promise<any>[] = [];
|
||||
const promises: Promise<any>[] = [];
|
||||
|
||||
if (local.hideAvatars !== calm.hideAvatars) {
|
||||
promises.push(
|
||||
api.settings.putEntry("calm", "hideAvatars", local.hideAvatars)
|
||||
api.settings.putEntry('calm', 'hideAvatars', local.hideAvatars)
|
||||
);
|
||||
}
|
||||
|
||||
if (local.hideNicknames !== calm.hideNicknames) {
|
||||
promises.push(
|
||||
api.settings.putEntry("calm", "hideNicknames", local.hideNicknames)
|
||||
api.settings.putEntry('calm', 'hideNicknames', local.hideNicknames)
|
||||
);
|
||||
}
|
||||
|
||||
@ -38,15 +38,15 @@ export function useMigrateSettings(api: GlobalApi) {
|
||||
) {
|
||||
promises.push(
|
||||
api.settings.putEntry(
|
||||
"display",
|
||||
"background",
|
||||
'display',
|
||||
'background',
|
||||
getBackgroundString(local.background)
|
||||
)
|
||||
);
|
||||
promises.push(
|
||||
api.settings.putEntry(
|
||||
"display",
|
||||
"backgroundType",
|
||||
'display',
|
||||
'backgroundType',
|
||||
local.background?.type
|
||||
)
|
||||
);
|
||||
@ -57,12 +57,12 @@ export function useMigrateSettings(api: GlobalApi) {
|
||||
const localVal = local.remoteContentPolicy[key];
|
||||
if (localVal !== remoteContentPolicy[key]) {
|
||||
promises.push(
|
||||
api.settings.putEntry("remoteContentPolicy", key, localVal)
|
||||
api.settings.putEntry('remoteContentPolicy', key, localVal)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
await Promise.all(promises);
|
||||
localStorage.removeItem("localReducer");
|
||||
localStorage.removeItem('localReducer');
|
||||
};
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { GraphNotifIndex, GraphNotificationContents } from '@urbit/api';
|
||||
import { GraphNotificationContents, GraphNotifIndex } from '@urbit/api';
|
||||
|
||||
export function getParentIndex(
|
||||
idx: GraphNotifIndex,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { cite } from '~/logic/lib/util';
|
||||
import { isChannelAdmin } from '~/logic/lib/group';
|
||||
import { cite } from '~/logic/lib/util';
|
||||
|
||||
const makeIndexes = () => new Map([
|
||||
['ships', []],
|
||||
@ -23,7 +23,7 @@ const result = function(title, link, app, host) {
|
||||
const shipIndex = function(contacts) {
|
||||
const ships = [];
|
||||
Object.keys(contacts).map((e) => {
|
||||
return ships.push(result(e, `/~profile/${e}`, 'profile', contacts[e]?.status || ""));
|
||||
return ships.push(result(e, `/~profile/${e}`, 'profile', contacts[e]?.status || ''));
|
||||
});
|
||||
return ships;
|
||||
};
|
||||
@ -38,11 +38,11 @@ const commandIndex = function (currentGroup, groups, associations) {
|
||||
? (association.metadata.vip === 'member-metadata' || isChannelAdmin(group, currentGroup))
|
||||
: !currentGroup; // home workspace or hasn't loaded
|
||||
const workspace = currentGroup || '/home';
|
||||
commands.push(result(`Groups: Create`, `/~landscape/new`, 'Groups', null));
|
||||
commands.push(result('Groups: Create', '/~landscape/new', 'Groups', null));
|
||||
if (canAdd) {
|
||||
commands.push(result(`Channel: Create`, `/~landscape${workspace}/new`, 'Groups', null));
|
||||
commands.push(result('Channel: Create', `/~landscape${workspace}/new`, 'Groups', null));
|
||||
}
|
||||
commands.push(result(`Groups: Join`, `/~landscape/join`, 'Groups', null));
|
||||
commands.push(result('Groups: Join', '/~landscape/join', 'Groups', null));
|
||||
|
||||
return commands;
|
||||
};
|
||||
@ -80,7 +80,7 @@ const otherIndex = function(config) {
|
||||
logout: result('Log Out', '/~/logout', 'logout', null)
|
||||
};
|
||||
other.push(result('Tutorial', '/?tutorial=true', 'tutorial', null));
|
||||
for(let cat of config.categories) {
|
||||
for(const cat of config.categories) {
|
||||
if(idx[cat]) {
|
||||
other.push(idx[cat]);
|
||||
}
|
||||
@ -102,7 +102,7 @@ export default function index(contacts, associations, apps, currentGroup, groups
|
||||
}).map((e) => {
|
||||
// iterate through each app's metadata object
|
||||
Object.keys(associations[e])
|
||||
.filter((association) => !associations?.[e]?.[association]?.metadata?.hidden)
|
||||
.filter(association => !associations?.[e]?.[association]?.metadata?.hidden)
|
||||
.map((association) => {
|
||||
const each = associations[e][association];
|
||||
let title = each.resource;
|
||||
|
@ -1,15 +1,12 @@
|
||||
|
||||
import {
|
||||
Association,
|
||||
resourceFromPath,
|
||||
Group,
|
||||
ReferenceContent,
|
||||
} from "@urbit/api";
|
||||
ReferenceContent, resourceFromPath
|
||||
} from '@urbit/api';
|
||||
|
||||
export function getPermalinkForGraph(
|
||||
group: string,
|
||||
graph: string,
|
||||
index = ""
|
||||
index = ''
|
||||
) {
|
||||
const groupLink = getPermalinkForAssociatedGroup(group);
|
||||
const { ship, name } = resourceFromPath(graph);
|
||||
@ -21,16 +18,15 @@ function getPermalinkForAssociatedGroup(group: string) {
|
||||
return `web+urbitgraph://group/${ship}/${name}`;
|
||||
}
|
||||
|
||||
|
||||
type Permalink = GraphPermalink | GroupPermalink;
|
||||
|
||||
interface GroupPermalink {
|
||||
type: "group";
|
||||
type: 'group';
|
||||
group: string;
|
||||
link: string;
|
||||
}
|
||||
interface GraphPermalink {
|
||||
type: "graph";
|
||||
export interface GraphPermalink {
|
||||
type: 'graph';
|
||||
link: string;
|
||||
graph: string;
|
||||
group: string;
|
||||
@ -43,16 +39,16 @@ function parseGraphPermalink(
|
||||
segments: string[]
|
||||
): GraphPermalink | null {
|
||||
const [kind, ship, name, ...index] = segments;
|
||||
if (kind !== "graph") {
|
||||
if (kind !== 'graph') {
|
||||
return null;
|
||||
}
|
||||
const graph = `/ship/${ship}/${name}`;
|
||||
return {
|
||||
type: "graph",
|
||||
type: 'graph',
|
||||
link: link.slice(16),
|
||||
graph,
|
||||
group,
|
||||
index: `/${index.join("/")}`,
|
||||
index: `/${index.join('/')}`
|
||||
};
|
||||
}
|
||||
|
||||
@ -64,7 +60,7 @@ export function permalinkToReference(link: Permalink): ReferenceContent {
|
||||
group: link.group,
|
||||
index: link.index
|
||||
}
|
||||
}
|
||||
};
|
||||
return { reference };
|
||||
} else {
|
||||
const reference = {
|
||||
@ -89,22 +85,22 @@ export function referenceToPermalink({ reference }: ReferenceContent): Permalink
|
||||
type: 'group',
|
||||
link,
|
||||
...reference
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function parsePermalink(url: string): Permalink | null {
|
||||
const [kind, ...rest] = url.slice(17).split("/");
|
||||
if (kind === "group") {
|
||||
const [kind, ...rest] = url.slice(17).split('/');
|
||||
if (kind === 'group') {
|
||||
const [ship, name, ...graph] = rest;
|
||||
const group = `/ship/${ship}/${name}`;
|
||||
if (graph.length > 0) {
|
||||
return parseGraphPermalink(url, group, graph);
|
||||
}
|
||||
return {
|
||||
type: "group",
|
||||
type: 'group',
|
||||
group,
|
||||
link: url.slice(11),
|
||||
link: url.slice(11)
|
||||
};
|
||||
}
|
||||
return null;
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
const ua = window.navigator.userAgent;
|
||||
|
||||
export const IS_IOS = ua.includes('iPhone');
|
||||
export const IS_IOS = ua.includes('iPhone') || ua.includes('iPad');
|
||||
|
||||
export const IS_SAFARI = ua.includes('Safari') && !ua.includes('Chrome');
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Post, GraphNode } from '@urbit/api';
|
||||
import { GraphNode, Post } from '@urbit/api';
|
||||
|
||||
export const buntPost = (): Post => ({
|
||||
author: '',
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { Post, GraphNode, TextContent } from '@urbit/api';
|
||||
import { Content, GraphNode, Post, TextContent } from '@urbit/api';
|
||||
import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap';
|
||||
import bigInt, { BigInteger } from 'big-integer';
|
||||
import { buntPost } from '~/logic/lib/post';
|
||||
import { unixToDa } from '~/logic/lib/util';
|
||||
import BigIntOrderedMap from "@urbit/api/lib/BigIntOrderedMap";
|
||||
import bigInt, { BigInteger } from 'big-integer';
|
||||
import tokenizeMessage from './tokenizeMessage';
|
||||
|
||||
export function newPost(
|
||||
title: string,
|
||||
@ -19,13 +20,15 @@ export function newPost(
|
||||
signatures: []
|
||||
};
|
||||
|
||||
const tokenisedBody = tokenizeMessage(body);
|
||||
|
||||
const revContainer: Post = { ...root, index: root.index + '/1' };
|
||||
const commentsContainer = { ...root, index: root.index + '/2' };
|
||||
|
||||
const firstRevision: Post = {
|
||||
...revContainer,
|
||||
index: revContainer.index + '/1',
|
||||
contents: [{ text: title }, { text: body }]
|
||||
contents: [{ text: title }, ...tokenisedBody]
|
||||
};
|
||||
|
||||
const nodes = {
|
||||
@ -54,11 +57,12 @@ export function newPost(
|
||||
|
||||
export function editPost(rev: number, noteId: BigInteger, title: string, body: string) {
|
||||
const now = Date.now();
|
||||
const tokenisedBody = tokenizeMessage(body);
|
||||
const newRev: Post = {
|
||||
author: `~${window.ship}`,
|
||||
index: `/${noteId.toString()}/1/${rev}`,
|
||||
'time-sent': now,
|
||||
contents: [{ text: title }, { text: body }],
|
||||
contents: [{ text: title }, ...tokenisedBody],
|
||||
hash: null,
|
||||
signatures: []
|
||||
};
|
||||
@ -73,8 +77,8 @@ export function editPost(rev: number, noteId: BigInteger, title: string, body: s
|
||||
}
|
||||
|
||||
export function getLatestRevision(node: GraphNode): [number, string, string, Post] {
|
||||
const revs = node.children?.get(bigInt(1));
|
||||
const empty = [1, '', '', buntPost()] as [number, string, string, Post];
|
||||
const revs = node.children?.get(bigInt(1));
|
||||
if(!revs) {
|
||||
return empty;
|
||||
}
|
||||
@ -85,8 +89,9 @@ export function getLatestRevision(node: GraphNode): [number, string, string, Pos
|
||||
if (!rev) {
|
||||
return empty;
|
||||
}
|
||||
const [title, body] = rev.post.contents as TextContent[];
|
||||
return [revNum.toJSNumber(), title.text, body.text, rev.post];
|
||||
const title = rev.post.contents[0];
|
||||
const body = rev.post.contents.slice(1);
|
||||
return [revNum.toJSNumber(), title.text, body, rev.post];
|
||||
}
|
||||
|
||||
export function getLatestCommentRevision(node: GraphNode): [number, Post] {
|
||||
@ -113,10 +118,12 @@ export function getComments(node: GraphNode): GraphNode {
|
||||
return comments;
|
||||
}
|
||||
|
||||
export function getSnippet(body: string) {
|
||||
const newlineIdx = body.indexOf('\n', 2);
|
||||
const end = newlineIdx > -1 ? newlineIdx : body.length;
|
||||
const start = body.substr(0, end);
|
||||
export function getSnippet(body: Content[]) {
|
||||
const firstContent = body
|
||||
.filter((c: Content): c is TextContent => 'text' in c).map(c => c.text)[0] ?? '';
|
||||
const newlineIdx = firstContent.indexOf('\n', 2);
|
||||
const end = newlineIdx > -1 ? newlineIdx : firstContent.length;
|
||||
const start = firstContent.substr(0, end);
|
||||
|
||||
return (start === body || start.startsWith('![')) ? start : `${start}...`;
|
||||
return (start === firstContent || firstContent.startsWith('![')) ? start : `${start}...`;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { memo } from 'react';
|
||||
import { sigil, reactRenderer } from '@tlon/sigil-js';
|
||||
import { Box } from '@tlon/indigo-react';
|
||||
import { reactRenderer, sigil } from '@tlon/sigil-js';
|
||||
import React, { memo } from 'react';
|
||||
|
||||
export const foregroundFromBackground = (background) => {
|
||||
const rgb = {
|
||||
|
@ -1,31 +1,43 @@
|
||||
import urbitOb from 'urbit-ob';
|
||||
import { parsePermalink, permalinkToReference } from "~/logic/lib/permalinks";
|
||||
import { parsePermalink, permalinkToReference } from '~/logic/lib/permalinks';
|
||||
|
||||
const URL_REGEX = new RegExp(String(/^(([\w\-\+]+:\/\/)[-a-zA-Z0-9:@;?&=\/%\+\.\*!'\(\),\$_\{\}\^~\[\]`#|]+\w)/.source));
|
||||
|
||||
const GROUP_REGEX = new RegExp(String(/^~[-a-z_]+\/[-a-z]+/.source));
|
||||
|
||||
const isUrl = (string) => {
|
||||
try {
|
||||
return URL_REGEX.test(string);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const isRef = (str) => {
|
||||
return isUrl(str) && str.startsWith("web+urbitgraph://");
|
||||
return isUrl(str) && str.startsWith('web+urbitgraph://');
|
||||
};
|
||||
|
||||
const isGroup = str => {
|
||||
try {
|
||||
return GROUP_REGEX.test(str);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const convertToGroupRef = (group) => `web+urbitgraph://group/${group}`;
|
||||
|
||||
const tokenizeMessage = (text) => {
|
||||
let messages = [];
|
||||
let message = [];
|
||||
// by line
|
||||
let currTextBlock = [];
|
||||
let isInCodeBlock = false;
|
||||
let endOfCodeBlock = false;
|
||||
text.split(/\r?\n/).forEach((line, index) => {
|
||||
if (index !== 0) {
|
||||
message.push('\n');
|
||||
}
|
||||
// by space
|
||||
let currTextLine = [];
|
||||
// A line of backticks enters and exits a codeblock
|
||||
if (line.startsWith('```')) {
|
||||
if (line.trim().startsWith('```')) {
|
||||
// But we need to check if we've ended a codeblock
|
||||
endOfCodeBlock = isInCodeBlock;
|
||||
isInCodeBlock = (!isInCodeBlock);
|
||||
@ -34,9 +46,13 @@ const tokenizeMessage = (text) => {
|
||||
}
|
||||
|
||||
if (isInCodeBlock || endOfCodeBlock) {
|
||||
message.push(line);
|
||||
currTextLine = [line];
|
||||
} else {
|
||||
line.split(/\s/).forEach((str) => {
|
||||
const words = line.split(/\s/);
|
||||
words.forEach((word, idx) => {
|
||||
const str = isGroup(word) ? convertToGroupRef(word) : word;
|
||||
|
||||
const last = words.length - 1 === idx;
|
||||
if (
|
||||
(str.startsWith('`') && str !== '`')
|
||||
|| (str === '`' && !isInCodeBlock)
|
||||
@ -50,9 +66,12 @@ const tokenizeMessage = (text) => {
|
||||
}
|
||||
|
||||
if(isRef(str) && !isInCodeBlock) {
|
||||
if (message.length > 0) {
|
||||
if (currTextLine.length > 0 || currTextBlock.length > 0) {
|
||||
// If we're in the middle of a message, add it to the stack and reset
|
||||
messages.push({ text: message.join(' ') });
|
||||
currTextLine.push('');
|
||||
messages.push({ text: currTextBlock.join('\n') + currTextLine.join(' ') });
|
||||
currTextBlock = last ? [''] : [];
|
||||
currTextLine = [];
|
||||
}
|
||||
const link = parsePermalink(str);
|
||||
if(!link) {
|
||||
@ -61,34 +80,39 @@ const tokenizeMessage = (text) => {
|
||||
const reference = permalinkToReference(link);
|
||||
messages.push(reference);
|
||||
}
|
||||
message = [];
|
||||
currTextLine = [];
|
||||
} else if (isUrl(str) && !isInCodeBlock) {
|
||||
if (message.length > 0) {
|
||||
if (currTextLine.length > 0 || currTextBlock.length > 0) {
|
||||
// If we're in the middle of a message, add it to the stack and reset
|
||||
messages.push({ text: message.join(' ') });
|
||||
message = [];
|
||||
currTextLine.push('');
|
||||
messages.push({ text: currTextBlock.join('\n') + currTextLine.join(' ') });
|
||||
currTextBlock = last ? [''] : [];
|
||||
currTextLine = [];
|
||||
}
|
||||
messages.push({ url: str });
|
||||
message = [];
|
||||
currTextLine = [];
|
||||
} else if(urbitOb.isValidPatp(str) && !isInCodeBlock) {
|
||||
if (message.length > 0) {
|
||||
if (currTextLine.length > 0 || currTextBlock.length > 0) {
|
||||
// If we're in the middle of a message, add it to the stack and reset
|
||||
messages.push({ text: message.join(' ') });
|
||||
message = [];
|
||||
currTextLine.push('');
|
||||
messages.push({ text: currTextBlock.join('\n') + currTextLine.join(' ') });
|
||||
currTextBlock = last ? [''] : [];
|
||||
currTextLine = [];
|
||||
}
|
||||
messages.push({ mention: str });
|
||||
message = [];
|
||||
currTextLine = [];
|
||||
|
||||
} else {
|
||||
message.push(str);
|
||||
currTextLine.push(str);
|
||||
}
|
||||
});
|
||||
}
|
||||
currTextBlock.push(currTextLine.join(' '))
|
||||
});
|
||||
|
||||
if (message.length) {
|
||||
if (currTextBlock.length) {
|
||||
// Add any remaining message
|
||||
messages.push({ text: message.join(' ') });
|
||||
messages.push({ text: currTextBlock.join('\n') });
|
||||
}
|
||||
return messages;
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Associations } from '@urbit/api';
|
||||
import { TutorialProgress } from '~/types';
|
||||
import { AlignX, AlignY } from '~/logic/lib/relativePosition';
|
||||
import { TutorialProgress } from '~/types';
|
||||
import { Direction } from '~/views/components/Triangle';
|
||||
|
||||
export const MODAL_WIDTH = 256;
|
||||
@ -92,7 +92,7 @@ export const progressDetails: Record<TutorialProgress, StepDetail> = {
|
||||
alignY: 'top',
|
||||
arrow: 'East',
|
||||
offsetX: MODAL_WIDTH + 24,
|
||||
offsetY: 80,
|
||||
offsetY: 80
|
||||
},
|
||||
channels: {
|
||||
title: 'Channels',
|
||||
@ -157,17 +157,17 @@ export const progressDetails: Record<TutorialProgress, StepDetail> = {
|
||||
alignX: 'right',
|
||||
arrow: 'South',
|
||||
offsetX: -300 + MODAL_WIDTH / 2,
|
||||
offsetY: -4,
|
||||
offsetY: -4
|
||||
},
|
||||
leap: {
|
||||
title: 'Leap',
|
||||
description:
|
||||
'Leap allows you to go to a specific channel, message, collection, profile or group simply by typing in a command or selecting a shortcut from the dropdown menu.',
|
||||
url: `/~profile/~${window.ship}`,
|
||||
alignY: "top",
|
||||
alignX: "left",
|
||||
arrow: "North",
|
||||
alignY: 'top',
|
||||
alignX: 'left',
|
||||
arrow: 'North',
|
||||
offsetX: 76,
|
||||
offsetY: -48,
|
||||
},
|
||||
offsetY: -48
|
||||
}
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { writeText } from "./util";
|
||||
import { useCallback, useState, useMemo } from "react";
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { writeText } from './util';
|
||||
|
||||
export function useCopy(copied: string, display: string) {
|
||||
export function useCopy(copied: string, display?: string) {
|
||||
const [didCopy, setDidCopy] = useState(false);
|
||||
const doCopy = useCallback(() => {
|
||||
writeText(copied);
|
||||
@ -11,9 +11,9 @@ export function useCopy(copied: string, display: string) {
|
||||
}, 2000);
|
||||
}, [copied]);
|
||||
|
||||
const copyDisplay = useMemo(() => (didCopy ? "Copied" : display), [
|
||||
const copyDisplay = useMemo(() => (didCopy ? 'Copied' : display), [
|
||||
didCopy,
|
||||
display,
|
||||
display
|
||||
]);
|
||||
|
||||
return { copyDisplay, doCopy, didCopy };
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useState, useCallback, useMemo, useEffect } from 'react';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
function validateDragEvent(e: DragEvent): FileList | File[] | true | null {
|
||||
const files: File[] = [];
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useState, useEffect, useMemo, useCallback } from 'react';
|
||||
import { useCallback, useState } from 'react';
|
||||
|
||||
export function useDropdown<C>(
|
||||
candidates: C[],
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { useEffect, RefObject, useRef, useState } from 'react';
|
||||
import _ from 'lodash';
|
||||
import { RefObject, useEffect, useState } from 'react';
|
||||
import usePreviousValue from './usePreviousValue';
|
||||
|
||||
export function distanceToBottom(el: HTMLElement) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useState, useCallback, useEffect } from 'react';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
function retrieve<T>(key: string, initial: T): T {
|
||||
const s = localStorage.getItem(key);
|
||||
|
@ -1,15 +1,13 @@
|
||||
import { Box } from '@tlon/indigo-react';
|
||||
import React, {
|
||||
useState,
|
||||
ReactNode,
|
||||
useCallback,
|
||||
useMemo,
|
||||
useRef
|
||||
useRef, useState
|
||||
} from 'react';
|
||||
|
||||
import { Box } from '@tlon/indigo-react';
|
||||
import { PropFunc } from '~/types';
|
||||
import { ModalOverlay } from '~/views/components/ModalOverlay';
|
||||
import { Portal } from '~/views/components/Portal';
|
||||
import { PropFunc } from '~/types';
|
||||
|
||||
type ModalFunc = (dismiss: () => void) => JSX.Element;
|
||||
interface UseModalProps {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useEffect, RefObject } from 'react';
|
||||
import { RefObject, useEffect } from 'react';
|
||||
|
||||
export function useOutsideClick(
|
||||
ref: RefObject<HTMLElement | null | undefined>,
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useMemo, useCallback } from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import _ from "lodash";
|
||||
import _ from 'lodash';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
function mergeQuery(search: URLSearchParams, added: Record<string, string>) {
|
||||
_.forIn(added, (v, k) => {
|
||||
@ -32,7 +32,7 @@ export function useQuery() {
|
||||
mergeQuery(q, params);
|
||||
return {
|
||||
pathname: path,
|
||||
search: q.toString(),
|
||||
search: q.toString()
|
||||
};
|
||||
},
|
||||
[search, pathname]
|
||||
@ -41,6 +41,6 @@ export function useQuery() {
|
||||
return {
|
||||
query,
|
||||
appendQuery,
|
||||
toQuery,
|
||||
toQuery
|
||||
};
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import {unstable_batchedUpdates} from "react-dom";
|
||||
import { useEffect, useState } from 'react';
|
||||
import { unstable_batchedUpdates } from 'react-dom';
|
||||
|
||||
export type IOInstance<I, P, O> = (
|
||||
input: I
|
||||
@ -29,7 +29,7 @@ export function useRunIO<I, O>(
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
reject(new Error("useRunIO: key changed"));
|
||||
reject(new Error('useRunIO: key changed'));
|
||||
setDone(false);
|
||||
setOutput(null);
|
||||
}, [key]);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { MouseEvent, useCallback, useState, useEffect } from 'react';
|
||||
import { MouseEvent, useCallback, useEffect, useState } from 'react';
|
||||
export type AsyncClickableState = 'waiting' | 'error' | 'loading' | 'success';
|
||||
|
||||
export function useStatelessAsyncClickable(
|
||||
|
@ -1,22 +1,16 @@
|
||||
import { useCallback, useMemo, useEffect, useRef, useState } from 'react';
|
||||
import {
|
||||
GcpState,
|
||||
S3State,
|
||||
StorageState
|
||||
} from '../../types';
|
||||
import S3 from 'aws-sdk/clients/s3';
|
||||
import GcpClient from './GcpClient';
|
||||
import { StorageClient, StorageAcl } from './StorageClient';
|
||||
import { dateToDa, deSig } from './util';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import useStorageState from '../state/storage';
|
||||
|
||||
import GcpClient from './GcpClient';
|
||||
import { StorageAcl, StorageClient } from './StorageClient';
|
||||
import { dateToDa, deSig } from './util';
|
||||
|
||||
export interface IuseStorage {
|
||||
canUpload: boolean;
|
||||
upload: (file: File, bucket: string) => Promise<string>;
|
||||
uploadDefault: (file: File) => Promise<string>;
|
||||
uploading: boolean;
|
||||
promptUpload: () => Promise<unknown>;
|
||||
promptUpload: () => Promise<string>;
|
||||
}
|
||||
|
||||
const useStorage = ({ accept = '*' } = { accept: '*' }): IuseStorage => {
|
||||
@ -54,7 +48,7 @@ const useStorage = ({ accept = '*' } = { accept: '*' }): IuseStorage => {
|
||||
);
|
||||
|
||||
const upload = useCallback(
|
||||
async (file: File, bucket: string) => {
|
||||
async (file: File, bucket: string): Promise<string> => {
|
||||
if (client.current === null) {
|
||||
throw new Error('Storage not ready');
|
||||
}
|
||||
@ -83,7 +77,7 @@ const useStorage = ({ accept = '*' } = { accept: '*' }): IuseStorage => {
|
||||
[client, setUploading]
|
||||
);
|
||||
|
||||
const uploadDefault = useCallback(async (file: File) => {
|
||||
const uploadDefault = useCallback(async (file: File): Promise<string> => {
|
||||
if (s3.configuration.currentBucket === '') {
|
||||
throw new Error('current bucket not set');
|
||||
}
|
||||
@ -91,7 +85,7 @@ const useStorage = ({ accept = '*' } = { accept: '*' }): IuseStorage => {
|
||||
}, [s3, upload]);
|
||||
|
||||
const promptUpload = useCallback(
|
||||
() => {
|
||||
(): Promise<string> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const fileSelector = document.createElement('input');
|
||||
fileSelector.setAttribute('type', 'file');
|
||||
@ -101,10 +95,10 @@ const useStorage = ({ accept = '*' } = { accept: '*' }): IuseStorage => {
|
||||
const files = fileSelector.files;
|
||||
if (!files || files.length <= 0) {
|
||||
reject();
|
||||
return;
|
||||
} else {
|
||||
uploadDefault(files[0]).then(resolve);
|
||||
document.body.removeChild(fileSelector);
|
||||
}
|
||||
uploadDefault(files[0]).then(resolve);
|
||||
document.body.removeChild(fileSelector);
|
||||
});
|
||||
document.body.appendChild(fileSelector);
|
||||
fileSelector.click();
|
||||
@ -113,7 +107,7 @@ const useStorage = ({ accept = '*' } = { accept: '*' }): IuseStorage => {
|
||||
[uploadDefault]
|
||||
);
|
||||
|
||||
return {canUpload, upload, uploadDefault, uploading, promptUpload};
|
||||
return { canUpload, upload, uploadDefault, uploading, promptUpload };
|
||||
};
|
||||
|
||||
export default useStorage;
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { useState, useCallback } from "react";
|
||||
import { useCallback, useState } from 'react';
|
||||
|
||||
export function useToggleState(initial: boolean) {
|
||||
const [state, setState] = useState(initial);
|
||||
|
||||
const toggle = useCallback(() => {
|
||||
setState((s) => !s);
|
||||
setState(s => !s);
|
||||
}, [setState]);
|
||||
|
||||
return [state, toggle] as const;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
export function useWaitForProps<P>(props: P, timeout = 0) {
|
||||
const [resolve, setResolve] = useState<() => void>(() => () => {});
|
||||
|
@ -1,15 +1,13 @@
|
||||
import { useEffect, useState, useCallback, useMemo } from 'react';
|
||||
import _ from 'lodash';
|
||||
import f, { compose, memoize } from 'lodash/fp';
|
||||
import bigInt, { BigInteger } from 'big-integer';
|
||||
/* eslint-disable max-lines */
|
||||
import { Association, Contact } from '@urbit/api';
|
||||
import useLocalState from '../state/local';
|
||||
import produce, { enableMapSet } from 'immer';
|
||||
import useSettingsState from '../state/settings';
|
||||
import { State, UseStore } from 'zustand';
|
||||
import { Cage } from '~/types/cage';
|
||||
import { BaseState } from '../state/base';
|
||||
import anyAscii from 'any-ascii';
|
||||
import bigInt, { BigInteger } from 'big-integer';
|
||||
import { enableMapSet } from 'immer';
|
||||
import _ from 'lodash';
|
||||
import f from 'lodash/fp';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { IconRef } from '~/types';
|
||||
import useSettingsState from '../state/settings';
|
||||
|
||||
enableMapSet();
|
||||
|
||||
@ -24,7 +22,9 @@ export const MOMENT_CALENDAR_DATE = {
|
||||
sameElse: '~YYYY.M.D'
|
||||
};
|
||||
|
||||
export const getModuleIcon = (mod: string) => {
|
||||
export type GraphModule = 'link' | 'post' | 'chat' | 'publish';
|
||||
|
||||
export const getModuleIcon = (mod: GraphModule): IconRef => {
|
||||
if (mod === 'link') {
|
||||
return 'Collection';
|
||||
}
|
||||
@ -33,7 +33,7 @@ export const getModuleIcon = (mod: string) => {
|
||||
return 'Dashboard';
|
||||
}
|
||||
|
||||
return _.capitalize(mod);
|
||||
return _.capitalize(mod) as IconRef;
|
||||
};
|
||||
|
||||
export function wait(ms: number) {
|
||||
@ -172,9 +172,9 @@ export function dateToDa(d: Date, mil = false) {
|
||||
);
|
||||
}
|
||||
|
||||
export function deSig(ship: string) {
|
||||
export function deSig(ship: string): string {
|
||||
if (!ship) {
|
||||
return null;
|
||||
return '';
|
||||
}
|
||||
return ship.replace('~', '');
|
||||
}
|
||||
@ -201,7 +201,7 @@ export const hexToUx = (hex) => {
|
||||
return `0x${ux}`;
|
||||
};
|
||||
|
||||
export function writeText(str: string) {
|
||||
export function writeText(str: string | null): Promise<void> {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
const range = document.createRange();
|
||||
range.selectNodeContents(document.body);
|
||||
@ -226,11 +226,11 @@ export function writeText(str: string) {
|
||||
}
|
||||
|
||||
// trim patps to match dojo, chat-cli
|
||||
export function cite(ship: string) {
|
||||
export function cite(ship: string): string {
|
||||
let patp = ship,
|
||||
shortened = '';
|
||||
if (patp === null || patp === '') {
|
||||
return null;
|
||||
return '';
|
||||
}
|
||||
if (patp.startsWith('~')) {
|
||||
patp = patp.substr(1);
|
||||
@ -400,7 +400,7 @@ export function pluralize(text: string, isPlural = false, vowel = false) {
|
||||
export function useShowNickname(contact: Contact | null, hide?: boolean): boolean {
|
||||
const hideState = useSettingsState(state => state.calm.hideNicknames);
|
||||
const hideNicknames = typeof hide !== 'undefined' ? hide : hideState;
|
||||
return !!(contact && contact.nickname && !hideNicknames);
|
||||
return Boolean(contact && contact.nickname && !hideNicknames);
|
||||
}
|
||||
|
||||
interface useHoveringInterface {
|
||||
@ -413,19 +413,18 @@ interface useHoveringInterface {
|
||||
|
||||
export const useHovering = (): useHoveringInterface => {
|
||||
const [hovering, setHovering] = useState(false);
|
||||
const onMouseOver = useCallback(() => setHovering(true), [])
|
||||
const onMouseLeave = useCallback(() => setHovering(false), [])
|
||||
const onMouseOver = useCallback(() => setHovering(true), []);
|
||||
const onMouseLeave = useCallback(() => setHovering(false), []);
|
||||
const bind = useMemo(() => ({
|
||||
onMouseOver,
|
||||
onMouseLeave,
|
||||
onMouseLeave
|
||||
}), [onMouseLeave, onMouseOver]);
|
||||
|
||||
|
||||
return useMemo(() => ({ hovering, bind }), [hovering, bind]);
|
||||
};
|
||||
|
||||
const DM_REGEX = /ship\/~([a-z]|-)*\/dm--/;
|
||||
export function getItemTitle(association: Association) {
|
||||
export function getItemTitle(association: Association): string {
|
||||
if (DM_REGEX.test(association.resource)) {
|
||||
const [, , ship, name] = association.resource.split('/');
|
||||
if (ship.slice(1) === window.ship) {
|
||||
@ -433,6 +432,6 @@ export function getItemTitle(association: Association) {
|
||||
}
|
||||
return cite(ship);
|
||||
}
|
||||
return association.metadata.title || association.resource;
|
||||
return association.metadata.title ?? association.resource ?? '';
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user