mirror of
https://github.com/urbit/shrub.git
synced 2024-12-22 10:21:31 +03:00
Merge branch 'lf/init-upd-log' (#4840)
* origin/lf/init-upd-log: (257 commits) graph: bunt time to ensure deduplication graph-store: initialise update logs glob: update to 0v7.dmf2h.884m6.b2p1b.l1and.uv1lv VirtualScroller: fix pendings and scroll after jump hark: fix notification archival interface: include iPad in UA check graph-store: fix %add/remove-tag generators chat: refocus and reset state on submit, allow enter linebreaks on mobile glob: update to 0v3.m4922.94fro.soub7.2cod3.0rfhh hooks: address L review VirtualScroller: do not crash if ref is unset interface: graph-reducer, put empty string when hash is null ChatPane: invert showOurContact conditional ChatResource: refactor to use ChatPane ChatPane: add component ShareProfile: refactor to remove dead props ChatWindow: remove association prop ChatInput: lift callbacks, refactor ChatMessage: refactor to remove association prop withStorage: fix typings ... Signed-off-by: Matilde Park <matilde.park@gmail.com>
This commit is contained in:
commit
991502ada7
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:abc163491b53cc9d48a70ea378dde8bb455648e3f6e7f57a0c7a8e164d4ca105
|
||||
size 10226599
|
||||
oid sha256:e1656cbfd472430c463db4e968c1dd4c8894a5219a27cd301a70ad262f5999f1
|
||||
size 10610939
|
||||
|
@ -1,10 +1,24 @@
|
||||
{ urbit, libcap, coreutils, bashInteractive, dockerTools, writeScriptBin, amesPort ? 34343 }:
|
||||
{ urbit, curl, libcap, coreutils, bashInteractive, dockerTools, writeScriptBin, amesPort ? 34343 }:
|
||||
let
|
||||
startUrbit = writeScriptBin "start-urbit" ''
|
||||
#!${bashInteractive}/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
# set defaults
|
||||
amesPort=${toString amesPort}
|
||||
|
||||
# check args
|
||||
for i in "$@"
|
||||
do
|
||||
case $i in
|
||||
-p=*|--port=*)
|
||||
amesPort="''${i#*=}"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# If the container is not started with the `-i` flag
|
||||
# then STDIN will be closed and we need to start
|
||||
# Urbit/vere with the `-t` flag.
|
||||
@ -23,7 +37,7 @@ let
|
||||
mv $keyname /tmp
|
||||
|
||||
# Boot urbit with the key, exit when done booting
|
||||
urbit $ttyflag -w $(basename $keyname .key) -k /tmp/$keyname -c $(basename $keyname .key) -p ${toString amesPort} -x
|
||||
urbit $ttyflag -w $(basename $keyname .key) -k /tmp/$keyname -c $(basename $keyname .key) -p $amesPort -x
|
||||
|
||||
# Remove the keyfile for security
|
||||
rm /tmp/$keyname
|
||||
@ -34,7 +48,7 @@ let
|
||||
cometname=''${comets[0]}
|
||||
rm *.comet
|
||||
|
||||
urbit $ttyflag -c $(basename $cometname .comet) -p ${toString amesPort} -x
|
||||
urbit $ttyflag -c $(basename $cometname .comet) -p $amesPort -x
|
||||
fi
|
||||
|
||||
# Find the first directory and start urbit with the ship therein
|
||||
@ -42,14 +56,44 @@ let
|
||||
dirs=( $dirnames )
|
||||
dirname=''${dirnames[0]}
|
||||
|
||||
urbit $ttyflag -p ${toString amesPort} $dirname
|
||||
exec urbit $ttyflag -p $amesPort $dirname
|
||||
'';
|
||||
|
||||
getUrbitCode = writeScriptBin "get-urbit-code" ''
|
||||
#!${bashInteractive}/bin/bash
|
||||
|
||||
raw=$(curl -s -X POST -H "Content-Type: application/json" \
|
||||
-d '{ "source": { "dojo": "+code" }, "sink": { "stdout": null } }' \
|
||||
http://127.0.0.1:12321)
|
||||
|
||||
# trim \n" from the end
|
||||
trim="''${raw%\\n\"}"
|
||||
|
||||
# trim " from the start
|
||||
code="''${trim#\"}"
|
||||
|
||||
echo "$code"
|
||||
'';
|
||||
|
||||
resetUrbitCode = writeScriptBin "reset-urbit-code" ''
|
||||
#!${bashInteractive}/bin/bash
|
||||
|
||||
curl=$(curl -s -X POST -H "Content-Type: application/json" \
|
||||
-d '{ "source": { "dojo": "+hood/code %reset" }, "sink": { "app": "hood" } }' \
|
||||
http://127.0.0.1:12321)
|
||||
|
||||
if [[ $? -eq 0 ]]
|
||||
then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Curl error: $?"
|
||||
fi
|
||||
'';
|
||||
|
||||
|
||||
in dockerTools.buildImage {
|
||||
name = "urbit";
|
||||
tag = "v${urbit.version}";
|
||||
contents = [ bashInteractive urbit startUrbit coreutils ];
|
||||
contents = [ bashInteractive urbit curl startUrbit getUrbitCode resetUrbitCode coreutils ];
|
||||
runAsRoot = ''
|
||||
#!${bashInteractive}
|
||||
mkdir -p /urbit
|
||||
|
@ -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
|
||||
--
|
||||
|
@ -126,6 +126,14 @@
|
||||
!=(contact(last-updated *@da) u.old(last-updated *@da))
|
||||
==
|
||||
[~ state]
|
||||
~| "cannot add a data url to cover!"
|
||||
?> ?| ?=(~ cover.contact)
|
||||
!=('data:' (cut 3 [0 5] u.cover.contact))
|
||||
==
|
||||
~| "cannot add a data url to avatar!"
|
||||
?> ?| ?=(~ avatar.contact)
|
||||
!=('data:' (cut 3 [0 5] u.avatar.contact))
|
||||
==
|
||||
:- (send-diff [%add ship contact] =(ship our.bowl))
|
||||
state(rolodex (~(put by rolodex) ship contact))
|
||||
::
|
||||
@ -149,6 +157,14 @@
|
||||
=/ contact (edit-contact old edit-field)
|
||||
?: =(old contact)
|
||||
[~ state]
|
||||
~| "cannot add a data url to cover!"
|
||||
?> ?| ?=(~ cover.contact)
|
||||
!=('data:' (cut 3 [0 5] u.cover.contact))
|
||||
==
|
||||
~| "cannot add a data url to avatar!"
|
||||
?> ?| ?=(~ avatar.contact)
|
||||
!=('data:' (cut 3 [0 5] u.avatar.contact))
|
||||
==
|
||||
=. last-updated.contact timestamp
|
||||
:- (send-diff [%edit ship edit-field timestamp] =(ship our.bowl))
|
||||
state(rolodex (~(put by rolodex) ship contact))
|
||||
|
@ -243,7 +243,7 @@
|
||||
=/ headers
|
||||
:~ content-type+mime-type
|
||||
max-1-da:gen
|
||||
'Service-Worker-Allowed'^'/'
|
||||
'service-worker-allowed'^'/'
|
||||
==
|
||||
[[200 headers] `q.u.data]
|
||||
==
|
||||
|
@ -5,7 +5,7 @@
|
||||
/- glob
|
||||
/+ default-agent, verb, dbug
|
||||
|%
|
||||
++ hash 0v2i7ds.j99ka.5dpja.pef1e.b04e0
|
||||
++ hash 0v7.dmf2h.884m6.b2p1b.l1and.uv1lv
|
||||
+$ 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,30 +38,18 @@
|
||||
^- (quip card _this)
|
||||
=+ !<(old=versioned-state old-vase)
|
||||
=| cards=(list card)
|
||||
|^
|
||||
|-
|
||||
?- -.old
|
||||
%0
|
||||
%0
|
||||
=* zro zero-load:upgrade:store
|
||||
%_ $
|
||||
-.old %1
|
||||
::
|
||||
validators.old
|
||||
(~(put in validators.old) %graph-validator-link)
|
||||
::
|
||||
cards
|
||||
%+ weld cards
|
||||
%+ turn
|
||||
~(tap in (~(put in validators.old) %graph-validator-link))
|
||||
|= validator=@t
|
||||
^- card
|
||||
=/ =wire /validator/[validator]
|
||||
=/ =rave:clay [%sing %b [%da now.bowl] /[validator]]
|
||||
[%pass wire %arvo %c %warp our.bowl [%home `rave]]
|
||||
::
|
||||
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
|
||||
::
|
||||
@ -74,138 +59,55 @@
|
||||
==
|
||||
::
|
||||
%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))
|
||||
::
|
||||
++ 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)
|
||||
--
|
||||
--
|
||||
%4
|
||||
%_ $
|
||||
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
|
||||
@ -224,7 +126,7 @@
|
||||
++ give
|
||||
|= =action:store
|
||||
^- (list card)
|
||||
[%give %fact ~ [%graph-update-1 !>([now.bowl action])]]~
|
||||
[%give %fact ~ [%graph-update-2 !>([now.bowl action])]]~
|
||||
--
|
||||
::
|
||||
++ on-poke
|
||||
@ -235,7 +137,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)
|
||||
==
|
||||
@ -250,7 +152,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)
|
||||
@ -285,19 +187,10 @@
|
||||
graphs (~(put by graphs) resource [graph mark])
|
||||
update-logs (~(put by update-logs) resource update-log)
|
||||
archive (~(del by archive) resource)
|
||||
::
|
||||
validators
|
||||
?~ mark validators
|
||||
(~(put in validators) u.mark)
|
||||
==
|
||||
%- zing
|
||||
:~ (give [/keys ~] %keys (~(put in ~(key by graphs)) resource))
|
||||
(give [/updates ~] %add-graph resource *graph:store mark overwrite)
|
||||
?~ mark ~
|
||||
?: (~(has in validators) u.mark) ~
|
||||
=/ wire /validator/[u.mark]
|
||||
=/ =rave:clay [%sing %b [%da now.bowl] /[u.mark]]
|
||||
[%pass wire %arvo %c %warp our.bowl [%home `rave]]~
|
||||
==
|
||||
::
|
||||
++ remove-graph
|
||||
@ -339,27 +232,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)
|
||||
@ -402,8 +295,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)
|
||||
@ -422,8 +317,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
|
||||
@ -432,7 +333,7 @@
|
||||
==
|
||||
--
|
||||
::
|
||||
++ remove-nodes
|
||||
++ remove-posts
|
||||
|= [=time =resource:store indices=(set index:store)]
|
||||
^- (quip card _state)
|
||||
|^
|
||||
@ -440,82 +341,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
|
||||
@ -551,11 +453,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))
|
||||
@ -596,28 +500,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
|
||||
@ -630,10 +535,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
|
||||
@ -668,7 +569,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)
|
||||
==
|
||||
@ -677,7 +578,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
|
||||
@ -702,7 +603,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)
|
||||
@ -711,155 +615,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
|
||||
@ -878,15 +634,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 @ @ ~]
|
||||
@ -895,7 +651,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]
|
||||
@ -910,7 +666,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]
|
||||
@ -926,7 +682,7 @@
|
||||
=/ graph=(unit marked-graph:store)
|
||||
(~(get by graphs) [ship term])
|
||||
?~ graph [~ ~]
|
||||
:- ~ :- ~ :- %graph-update-1
|
||||
:- ~ :- ~ :- %graph-update-2
|
||||
!> ^- update:store
|
||||
:- now.bowl
|
||||
:+ %add-nodes
|
||||
@ -953,7 +709,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
|
||||
@ -972,7 +728,7 @@
|
||||
=/ graph
|
||||
(get-node-children ship term parent)
|
||||
?~ graph [~ ~]
|
||||
:- ~ :- ~ :- %graph-update-1
|
||||
:- ~ :- ~ :- %graph-update-2
|
||||
!> ^- update:store
|
||||
:- now.bowl
|
||||
:+ %add-nodes
|
||||
@ -1002,7 +758,7 @@
|
||||
=/ children
|
||||
(get-node-children ship term index)
|
||||
?~ children [~ ~]
|
||||
:- ~ :- ~ :- %graph-update-1
|
||||
:- ~ :- ~ :- %graph-update-2
|
||||
!> ^- update:store
|
||||
:- now.bowl
|
||||
:+ %add-nodes
|
||||
@ -1028,7 +784,7 @@
|
||||
?- -.children.u.node
|
||||
%empty [~ ~]
|
||||
%graph
|
||||
:- ~ :- ~ :- %graph-update-1
|
||||
:- ~ :- ~ :- %graph-update-2
|
||||
!> ^- update:store
|
||||
:- now.bowl
|
||||
:+ %add-nodes
|
||||
@ -1119,13 +875,8 @@
|
||||
?+ wire (on-arvo:def wire sign-arvo)
|
||||
::
|
||||
:: old wire, do nothing
|
||||
[%graph *] [~ this]
|
||||
::
|
||||
[%validator @ ~]
|
||||
:_ this
|
||||
=* validator i.t.wire
|
||||
=/ =rave:clay [%next %b [%da now.bowl] /[validator]]
|
||||
[%pass wire %arvo %c %warp our.bowl [%home `rave]]~
|
||||
[%graph *] [~ this]
|
||||
[%validator @ ~] [~ this]
|
||||
::
|
||||
[%try-rejoin @ *]
|
||||
=/ rid=resource:store (de-path:res t.t.wire)
|
||||
|
@ -37,79 +37,13 @@
|
||||
++ on-init on-init:def
|
||||
++ on-save !>(~)
|
||||
++ on-load on-load:def
|
||||
++ on-poke
|
||||
|= [=mark =vase]
|
||||
^- (quip card _this)
|
||||
|^
|
||||
?. =(mark %sane)
|
||||
(on-poke:def mark vase)
|
||||
[(sane !<(?(%check %fix) vase)) this]
|
||||
::
|
||||
++ scry-sharing
|
||||
.^ (set resource)
|
||||
%gx
|
||||
(scot %p our.bowl)
|
||||
%group-push-hook
|
||||
(scot %da now.bowl)
|
||||
/sharing/noun
|
||||
==
|
||||
::
|
||||
++ sane
|
||||
|= input=?(%check %fix)
|
||||
^- (list card)
|
||||
=; cards=(list card)
|
||||
?: =(%check input)
|
||||
~&(cards ~)
|
||||
cards
|
||||
%+ murn
|
||||
~(tap in scry-sharing)
|
||||
|= rid=resource
|
||||
^- (unit card)
|
||||
=/ u-g=(unit group)
|
||||
(scry-group:grp rid)
|
||||
?~ u-g
|
||||
`(poke-us %remove rid)
|
||||
=* group u.u-g
|
||||
=/ subs=(set ship)
|
||||
(get-subscribers-for-group rid)
|
||||
=/ to-remove=(set ship)
|
||||
(~(dif in members.group) (~(gas in subs) our.bowl ~))
|
||||
?~ to-remove ~
|
||||
`(poke-store %remove-members rid to-remove)
|
||||
::
|
||||
++ poke-us
|
||||
|= =action:push-hook
|
||||
^- card
|
||||
=- [%pass / %agent [our.bowl %group-push-hook] %poke -]
|
||||
push-hook-action+!>(action)
|
||||
::
|
||||
++ poke-store
|
||||
|= =update:store
|
||||
^- card
|
||||
=+ group-update-0+!>(update)
|
||||
[%pass /sane %agent [our.bowl %group-store] %poke -]
|
||||
::
|
||||
++ get-subscribers-for-group
|
||||
|= rid=resource
|
||||
^- (set ship)
|
||||
=/ target=path
|
||||
(en-path:resource rid)
|
||||
%- ~(gas in *(set ship))
|
||||
%+ murn
|
||||
~(val by sup.bowl)
|
||||
|= [her=ship =path]
|
||||
^- (unit ship)
|
||||
?. =(path resource+target)
|
||||
~
|
||||
`her
|
||||
--
|
||||
|
||||
++ on-agent on-agent:def
|
||||
++ on-watch on-watch:def
|
||||
++ on-leave on-leave:def
|
||||
++ on-peek on-peek:def
|
||||
++ on-arvo on-arvo:def
|
||||
++ on-fail on-fail:def
|
||||
++ on-poke on-poke:def
|
||||
++ on-agent on-agent:def
|
||||
++ on-watch on-watch:def
|
||||
++ on-leave on-leave:def
|
||||
++ on-peek on-peek:def
|
||||
++ on-arvo on-arvo:def
|
||||
++ on-fail on-fail:def
|
||||
::
|
||||
++ transform-proxy-update
|
||||
|= vas=vase
|
||||
|
@ -414,11 +414,8 @@
|
||||
?> ?& ?=(~ (~(dif in ships) members))
|
||||
(~(has by tags) tag)
|
||||
==
|
||||
%= +<
|
||||
::
|
||||
tags
|
||||
%+ ~(jab by tags) tag
|
||||
|=((set ship) (~(dif in +<) ships))
|
||||
%= +<
|
||||
tags (dif-ju tags tag ships)
|
||||
==
|
||||
:_ state
|
||||
(send-diff %remove-tag rid tag ships)
|
||||
@ -543,7 +540,15 @@
|
||||
(send-diff %remove-group rid ~)
|
||||
::
|
||||
--
|
||||
|
||||
:: TODO: move to +zuse
|
||||
++ dif-ju
|
||||
|= [=tags =tag remove=(set ship)]
|
||||
=/ ships ~(tap in remove)
|
||||
|-
|
||||
?~ ships
|
||||
tags
|
||||
$(tags (~(del ju tags) tag i.ships), ships t.ships)
|
||||
::
|
||||
++ merge-tags
|
||||
|= [=tags ships=(set ship) new-tags=(set tag)]
|
||||
^+ tags
|
||||
|
@ -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
|
||||
@ -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))
|
||||
@ -198,8 +196,8 @@
|
||||
?(%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
|
||||
@ -208,7 +206,7 @@
|
||||
:: 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]))
|
||||
@ -264,7 +262,6 @@
|
||||
:_ state(watching (~(put in watching) [rid ~]))
|
||||
(weld cards (give:ha ~[/updates] %listen [rid ~]))
|
||||
::
|
||||
::
|
||||
++ check-nodes
|
||||
|= $: nodes=(list node:graph-store)
|
||||
rid=resource
|
||||
@ -417,30 +414,33 @@
|
||||
|= =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 !>([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 +459,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.3a0ba646997cd338b513.js"></script>
|
||||
<script src="/~landscape/js/bundle/index.eb051d816171fb1d0caf.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -23,7 +23,7 @@
|
||||
:: /app-name/%app-name associations for app
|
||||
:: /group/%path associations for group
|
||||
::
|
||||
/- store=metadata-store
|
||||
/- store=metadata-store, pull-hook
|
||||
/+ default-agent, verb, dbug, resource, *migrate
|
||||
|%
|
||||
+$ card card:agent:gall
|
||||
@ -95,15 +95,17 @@
|
||||
~
|
||||
==
|
||||
::
|
||||
+$ state-0 [%0 base-state-0]
|
||||
+$ state-1 [%1 base-state-0]
|
||||
+$ state-2 [%2 base-state-0]
|
||||
+$ state-3 [%3 base-state-1]
|
||||
+$ state-4 [%4 base-state-1]
|
||||
+$ state-5 [%5 base-state-1]
|
||||
+$ state-6 [%6 base-state-1]
|
||||
+$ state-7 [%7 base-state-2]
|
||||
+$ state-8 [%8 base-state-3]
|
||||
+$ state-0 [%0 base-state-0]
|
||||
+$ state-1 [%1 base-state-0]
|
||||
+$ state-2 [%2 base-state-0]
|
||||
+$ state-3 [%3 base-state-1]
|
||||
+$ state-4 [%4 base-state-1]
|
||||
+$ state-5 [%5 base-state-1]
|
||||
+$ state-6 [%6 base-state-1]
|
||||
+$ state-7 [%7 base-state-2]
|
||||
+$ state-8 [%8 base-state-3]
|
||||
+$ state-9 [%9 base-state-3]
|
||||
+$ state-10 [%10 base-state-3]
|
||||
+$ versioned-state
|
||||
$% state-0
|
||||
state-1
|
||||
@ -114,10 +116,12 @@
|
||||
state-6
|
||||
state-7
|
||||
state-8
|
||||
state-9
|
||||
state-10
|
||||
==
|
||||
::
|
||||
+$ inflated-state
|
||||
$: state-8
|
||||
$: state-10
|
||||
cached-indices
|
||||
==
|
||||
--
|
||||
@ -230,7 +234,7 @@
|
||||
=| cards=(list card)
|
||||
|^
|
||||
=* loop $
|
||||
?: ?=(%8 -.old)
|
||||
?: ?=(%10 -.old)
|
||||
:- cards
|
||||
%_ state
|
||||
associations associations.old
|
||||
@ -238,6 +242,29 @@
|
||||
group-indices (rebuild-group-indices associations.old)
|
||||
app-indices (rebuild-app-indices associations.old)
|
||||
==
|
||||
?: ?=(%9 -.old)
|
||||
=/ groups
|
||||
(fall (~(get by (rebuild-app-indices associations.old)) %groups) ~)
|
||||
=/ pokes=(list card)
|
||||
%+ murn ~(tap in ~(key by groups))
|
||||
|= group=resource
|
||||
^- (unit card)
|
||||
=/ =association:store (~(got by associations.old) [%groups group])
|
||||
=* met metadatum.association
|
||||
?. ?=([%group [~ [~ [@ [@ @]]]]] config.met)
|
||||
~
|
||||
=* res resource.u.u.feed.config.met
|
||||
?: =(our.bowl entity.res) ~
|
||||
=- `[%pass /fix-feed %agent [our.bowl %graph-pull-hook] %poke -]
|
||||
:- %pull-hook-action
|
||||
!> ^- action:pull-hook
|
||||
[%add entity.res res]
|
||||
%_ $
|
||||
cards (weld cards pokes)
|
||||
-.old %10
|
||||
==
|
||||
?: ?=(%8 -.old)
|
||||
$(-.old %9)
|
||||
?: ?=(%7 -.old)
|
||||
$(old [%8 (associations-2-to-3 associations.old) ~])
|
||||
?: ?=(%6 -.old)
|
||||
@ -369,7 +396,7 @@
|
||||
^- (quip card _state)
|
||||
|^
|
||||
=^ cards state
|
||||
(on-load !>([%8 (remake-metadata ;;(tree-metadata +.arc))]))
|
||||
(on-load !>([%9 (remake-metadata ;;(tree-metadata +.arc))]))
|
||||
:_ state
|
||||
%+ weld cards
|
||||
%+ turn ~(tap in ~(key by group-indices))
|
||||
|
@ -14,6 +14,7 @@
|
||||
[%2 observers=(map serial observer:sur)]
|
||||
[%3 observers=(map serial observer:sur)]
|
||||
[%4 observers=(map serial observer:sur)]
|
||||
[%5 observers=(map serial observer:sur) warm-cache=_|]
|
||||
==
|
||||
::
|
||||
+$ serial @uv
|
||||
@ -27,7 +28,7 @@
|
||||
--
|
||||
::
|
||||
%- agent:dbug
|
||||
=| [%4 observers=(map serial observer:sur)]
|
||||
=| [%5 observers=(map serial observer:sur) warm-cache=_|]
|
||||
=* state -
|
||||
::
|
||||
^- agent:gall
|
||||
@ -42,6 +43,7 @@
|
||||
(act [%watch %group-store /groups %group-on-leave])
|
||||
(act [%watch %group-store /groups %group-on-remove-member])
|
||||
(act [%watch %metadata-store /updates %md-on-add-group-feed])
|
||||
(act [%warm-cache-all ~])
|
||||
==
|
||||
::
|
||||
++ act
|
||||
@ -66,8 +68,13 @@
|
||||
=| cards=(list card)
|
||||
|-
|
||||
?- -.old-state
|
||||
%4
|
||||
%5
|
||||
[cards this(state old-state)]
|
||||
%4
|
||||
=. cards
|
||||
:_ cards
|
||||
(act [%warm-cache-all ~])
|
||||
$(old-state [%5 observers.old-state %.n])
|
||||
::
|
||||
%3
|
||||
=. cards
|
||||
@ -110,11 +117,19 @@
|
||||
?> (team:title our.bowl src.bowl)
|
||||
?. ?=(%observe-action mark)
|
||||
(on-poke:def mark vase)
|
||||
|^
|
||||
=/ =action:sur !<(action:sur vase)
|
||||
=* observer observer.action
|
||||
=/ vals (silt ~(val by observers))
|
||||
?- -.action
|
||||
%watch
|
||||
%watch (watch observer vals)
|
||||
%ignore (ignore observer vals)
|
||||
%warm-cache-all warm-cache-all
|
||||
%cool-cache-all cool-cache-all
|
||||
==
|
||||
::
|
||||
++ watch
|
||||
|= [=observer:sur vals=(set observer:sur)]
|
||||
?: ?|(=(app.observer %spider) =(app.observer %observe-hook))
|
||||
~|('we avoid infinite loops' !!)
|
||||
?: (~(has in vals) observer)
|
||||
@ -129,7 +144,8 @@
|
||||
path.observer
|
||||
==
|
||||
::
|
||||
%ignore
|
||||
++ ignore
|
||||
|= [=observer:sur vals=(set observer:sur)]
|
||||
?. (~(has in vals) observer)
|
||||
~|('cannot remove nonexistent observer' !!)
|
||||
=/ key (got-by-val observers observer)
|
||||
@ -142,7 +158,19 @@
|
||||
%leave
|
||||
~
|
||||
==
|
||||
==
|
||||
::
|
||||
++ warm-cache-all
|
||||
?: warm-cache
|
||||
~|('cannot warm up cache that is already warm' !!)
|
||||
:_ this(warm-cache %.y)
|
||||
=/ =rave:clay [%sing [%t da+now.bowl /mar]]
|
||||
[%pass /warm-cache %arvo %c %warp our.bowl %home `rave]~
|
||||
::
|
||||
++ cool-cache-all
|
||||
?. warm-cache
|
||||
~|('cannot cool down cache that is already cool' !!)
|
||||
[~ this(warm-cache %.n)]
|
||||
--
|
||||
::
|
||||
++ on-agent
|
||||
|= [=wire =sign:agent:gall]
|
||||
@ -260,9 +288,48 @@
|
||||
== ==
|
||||
--
|
||||
::
|
||||
++ on-arvo
|
||||
|= [=wire =sign-arvo]
|
||||
^- (quip card _this)
|
||||
:_ this
|
||||
?+ wire (on-arvo:def wire sign-arvo)
|
||||
[%warm-cache ~]
|
||||
?. warm-cache
|
||||
~
|
||||
?> ?=([%clay %writ *] sign-arvo)
|
||||
=* riot p.sign-arvo
|
||||
?~ riot
|
||||
=/ =rave:clay [%next [%t da+now.bowl /mar]]
|
||||
[%pass /warm-cache %arvo %c %warp our.bowl %home `rave]~
|
||||
:- =/ =rave:clay [%next [%t q.p.u.riot /mar]]
|
||||
[%pass /warm-cache %arvo %c %warp our.bowl %home `rave]
|
||||
%+ turn !<((list path) q.r.u.riot)
|
||||
|= pax=path
|
||||
^- card
|
||||
=. pax (snip (slag 1 pax))
|
||||
=/ mark=@ta
|
||||
%+ roll pax
|
||||
|= [=term mark=term]
|
||||
?: ?=(%$ mark)
|
||||
term
|
||||
:((cury cat 3) mark '-' term)
|
||||
=/ =rave:clay [%sing %b da+now.bowl /[mark]]
|
||||
[%pass [%mar mark ~] %arvo %c %warp our.bowl %home `rave]
|
||||
::
|
||||
[%mar ^]
|
||||
?. warm-cache
|
||||
~
|
||||
?> ?=([%clay %writ *] sign-arvo)
|
||||
=* riot p.sign-arvo
|
||||
=* mark t.wire
|
||||
?~ riot
|
||||
~
|
||||
=/ =rave:clay [%next %b q.p.u.riot mark]
|
||||
[%pass wire %arvo %c %warp our.bowl %home `rave]~
|
||||
==
|
||||
::
|
||||
++ on-watch on-watch:def
|
||||
++ on-leave on-leave:def
|
||||
++ on-peek on-peek:def
|
||||
++ on-arvo on-arvo:def
|
||||
++ on-fail on-fail:def
|
||||
--
|
||||
|
@ -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]]
|
||||
|
@ -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,11 +105,14 @@
|
||||
::
|
||||
+$ state-3 [%3 base-state-2]
|
||||
::
|
||||
+$ state-4 [%4 base-state-3]
|
||||
::
|
||||
+$ versioned-state
|
||||
$% state-0
|
||||
state-1
|
||||
state-2
|
||||
state-3
|
||||
state-4
|
||||
==
|
||||
::
|
||||
++ default
|
||||
@ -198,7 +206,7 @@
|
||||
++ agent
|
||||
|* =config
|
||||
|= =(pull-hook config)
|
||||
=| state-3
|
||||
=| state-4
|
||||
=* state -
|
||||
^- agent:gall
|
||||
=<
|
||||
@ -224,13 +232,20 @@
|
||||
=| 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)
|
||||
==
|
||||
~
|
||||
(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 +270,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
|
||||
@ -440,6 +457,11 @@
|
||||
=/ fact-ver=@ud
|
||||
(read-version:ver p.cage)
|
||||
?. (gte fact-ver min-version.config)
|
||||
?. versioned
|
||||
:: don't process unversioned, unsupported facts
|
||||
:: just wait for publisher to upgrade and kick the
|
||||
:: subscription
|
||||
tr-core
|
||||
(tr-suspend-pub-ver min-version.config)
|
||||
=/ =vase
|
||||
(convert-to:ver cage)
|
||||
@ -467,6 +489,7 @@
|
||||
::
|
||||
++ tr-add
|
||||
|= [s=^ship r=resource]
|
||||
?< =(s our.bowl)
|
||||
=: ship s
|
||||
rid r
|
||||
status [%active ~]
|
||||
|
@ -57,13 +57,21 @@
|
||||
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
|
||||
==
|
||||
++ push-hook
|
||||
|* =config
|
||||
@ -153,7 +161,7 @@
|
||||
++ agent
|
||||
|* =config
|
||||
|= =(push-hook config)
|
||||
=| state-1
|
||||
=| state-2
|
||||
=* state -
|
||||
^- agent:gall
|
||||
=<
|
||||
@ -179,16 +187,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 +218,12 @@
|
||||
==
|
||||
::
|
||||
++ find-old-subs
|
||||
|= [prev-min-version=@ud prev-version=@ud]
|
||||
?: ?& =(min-version.config prev-min-version)
|
||||
=(prev-version version.config)
|
||||
==
|
||||
:: bail on kick if we didn't change versions
|
||||
~
|
||||
%~ tap in
|
||||
%+ roll
|
||||
~(val by sup.bowl)
|
||||
@ -230,8 +249,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
|
||||
|
@ -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)))
|
||||
--
|
||||
--
|
@ -22,8 +22,9 @@
|
||||
++ notification-kind
|
||||
^- (unit notif-kind:hark)
|
||||
=/ len (lent index.p.i)
|
||||
?: =(1 len) ~
|
||||
`[%post [(dec len) len] %none %children]
|
||||
=/ =mode:hark
|
||||
?:(=(1 len) %count %none)
|
||||
`[%post [(dec len) len] mode %children]
|
||||
::
|
||||
++ transform-add-nodes
|
||||
|= [=index =post =atom was-parent-modified=?]
|
||||
|
@ -1,5 +1,5 @@
|
||||
/+ store=metadata-store
|
||||
|_ =update:store
|
||||
|_ =update:zero:store
|
||||
++ grad %noun
|
||||
++ grow
|
||||
|%
|
||||
@ -9,7 +9,6 @@
|
||||
::
|
||||
++ grab
|
||||
|%
|
||||
++ noun update:store
|
||||
++ json action:dejs:store
|
||||
++ noun update:zero:store
|
||||
--
|
||||
--
|
||||
|
@ -1,17 +1,14 @@
|
||||
/+ store=metadata-store
|
||||
|_ =update:store
|
||||
|_ =update:zero:store
|
||||
++ grad %noun
|
||||
++ grow
|
||||
|%
|
||||
++ noun update
|
||||
++ metadata-update-0 update
|
||||
++ metadata-update-1 update
|
||||
++ json (update:enjs:store update)
|
||||
--
|
||||
::
|
||||
++ grab
|
||||
|%
|
||||
++ noun update:store
|
||||
++ json action:dejs:store
|
||||
++ noun update:zero:store
|
||||
--
|
||||
--
|
||||
|
@ -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]
|
||||
==
|
||||
--
|
||||
|
@ -78,4 +78,38 @@
|
||||
=metadatum
|
||||
==
|
||||
==
|
||||
:: historical
|
||||
++ zero
|
||||
|%
|
||||
::
|
||||
+$ association [group=resource =metadatum]
|
||||
::
|
||||
+$ associations (map md-resource association)
|
||||
::
|
||||
+$ metadatum
|
||||
$: title=cord
|
||||
description=cord
|
||||
=color
|
||||
date-created=time
|
||||
creator=ship
|
||||
module=term
|
||||
picture=url
|
||||
preview=?
|
||||
vip=vip-metadata
|
||||
==
|
||||
::
|
||||
+$ update
|
||||
$% [%add group=resource resource=md-resource =metadatum]
|
||||
[%remove group=resource resource=md-resource]
|
||||
[%initial-group group=resource =associations]
|
||||
[%associations =associations]
|
||||
$: %updated-metadata
|
||||
group=resource
|
||||
resource=md-resource
|
||||
before=metadatum
|
||||
=metadatum
|
||||
==
|
||||
==
|
||||
::
|
||||
--
|
||||
--
|
||||
|
@ -1,7 +1,14 @@
|
||||
|%
|
||||
+$ observer [app=term =path thread=term]
|
||||
+$ action
|
||||
$% [%watch =observer]
|
||||
$% :: %gall actions
|
||||
::
|
||||
[%watch =observer]
|
||||
[%ignore =observer]
|
||||
::
|
||||
:: %clay actions
|
||||
::
|
||||
[%warm-cache-all ~]
|
||||
[%cool-cache-all ~]
|
||||
==
|
||||
--
|
||||
|
@ -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
|
||||
==
|
||||
--
|
||||
--
|
||||
|
@ -249,6 +249,7 @@
|
||||
font-family: "Source Code Pro";
|
||||
src: url("https://storage.googleapis.com/media.urbit.org/fonts/scp-regular.woff");
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
}
|
||||
:root {
|
||||
--red05: rgba(255,65,54,0.05);
|
||||
|
@ -6,7 +6,6 @@
|
||||
/- gcp, spider, settings
|
||||
/+ strandio
|
||||
=, strand=strand:spider
|
||||
=, enjs:format
|
||||
^- thread:spider
|
||||
|^
|
||||
|= *
|
||||
@ -22,7 +21,7 @@
|
||||
==
|
||||
%- pure:m
|
||||
!>
|
||||
%+ frond %gcp-configured
|
||||
^- json
|
||||
b+has
|
||||
::
|
||||
++ has-settings
|
||||
|
@ -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
|
||||
|
@ -7,9 +7,7 @@
|
||||
::
|
||||
++ supported-apps
|
||||
^- (list term)
|
||||
:~ %group-push-hook
|
||||
%group-store
|
||||
==
|
||||
~[%group-store]
|
||||
::
|
||||
++ poke-all-sane
|
||||
|= =input
|
||||
|
@ -25,9 +25,55 @@ 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.
|
||||
|
||||
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:
|
||||
```
|
||||
docker volume create sampel-palnet
|
||||
```
|
||||
|
||||
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 the default host port 34343:
|
||||
```
|
||||
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:
|
||||
```
|
||||
docker run -d -p 8088:80 -p 23232:23232/udp --name sampel-palnet \
|
||||
--mount type=volume,source=sampel-palnet,destination=/urbit \
|
||||
tloncorp/urbit /bin/start-urbit --port=23232
|
||||
```
|
||||
|
||||
### Getting and resetting the Landscape +code
|
||||
This docker image includes tools for retrieving and resetting the Landscape login code belonging to the planet, for programmatic use so the container does not need a tty. These scripts can be called using `docker container exec`.
|
||||
|
||||
Getting the code:
|
||||
```
|
||||
$ docker container exec sampel-palnet /bin/get-urbit-code
|
||||
sampel-sampel-sampel-sampel
|
||||
```
|
||||
|
||||
Resetting the code:
|
||||
```
|
||||
$ docker container exec sampel-palnet /bin/reset-urbit-code
|
||||
OK
|
||||
```
|
||||
|
||||
Once the code has been reset the new code can be obtained from `/bin/get-urbit-code`.
|
||||
|
||||
## Extending
|
||||
|
||||
|
@ -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:
|
||||
|
@ -32,7 +32,7 @@ same (if [developing on a local development ship][local]). Then, from
|
||||
'pkg/interface':
|
||||
|
||||
```
|
||||
npm install
|
||||
npm ci
|
||||
npm run start
|
||||
```
|
||||
|
||||
@ -59,7 +59,7 @@ module.exports = {
|
||||
```
|
||||
|
||||
The dev environment will attempt to match the subdomain against the keys of this
|
||||
object, and if matched will proxy to the corresponding URL. For example, the
|
||||
object, and if matched will proxy to the corresponding URL. For example, the
|
||||
above config will proxy `zod.localhost:9000` to `http://localhost:8080`,
|
||||
`bus.localhost:9000` to `http://localhost:8081` and so on and so forth. If no
|
||||
match is found, then it will fallback to the `URL` property.
|
||||
@ -71,7 +71,7 @@ linter and for usage through the command, do the following:
|
||||
|
||||
```bash
|
||||
$ cd ./pkg/interface
|
||||
$ npm install
|
||||
$ npm ci
|
||||
$ npm run lint
|
||||
```
|
||||
|
||||
|
@ -111,7 +111,7 @@ module.exports = {
|
||||
]
|
||||
}
|
||||
},
|
||||
exclude: /node_modules\/(?!(@tlon\/indigo-dark|@tlon\/indigo-light)\/).*/
|
||||
exclude: /node_modules\/(?!(@tlon\/indigo-dark|@tlon\/indigo-light|@tlon\/indigo-react)\/).*/
|
||||
},
|
||||
{
|
||||
test: /\.css$/i,
|
||||
|
@ -30,7 +30,7 @@ module.exports = {
|
||||
]
|
||||
}
|
||||
},
|
||||
exclude: /node_modules\/(?!(@tlon\/indigo-dark|@tlon\/indigo-light)\/).*/
|
||||
exclude: /node_modules\/(?!(@tlon\/indigo-dark|@tlon\/indigo-light|@tlon\/indigo-react)\/).*/
|
||||
},
|
||||
{
|
||||
test: /\.css$/i,
|
||||
|
3890
pkg/interface/package-lock.json
generated
3890
pkg/interface/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -9,8 +9,8 @@
|
||||
"@reach/menu-button": "^0.10.5",
|
||||
"@reach/tabs": "^0.10.5",
|
||||
"@tlon/indigo-dark": "^1.0.6",
|
||||
"@tlon/indigo-light": "^1.0.6",
|
||||
"@tlon/indigo-react": "^1.2.19",
|
||||
"@tlon/indigo-light": "^1.0.7",
|
||||
"@tlon/indigo-react": "^1.2.21",
|
||||
"@tlon/sigil-js": "^1.4.3",
|
||||
"@urbit/api": "file:../npm/api",
|
||||
"any-ascii": "^0.1.7",
|
||||
@ -88,7 +88,7 @@
|
||||
"react-hot-loader": "^4.13.0",
|
||||
"sass": "^1.32.5",
|
||||
"sass-loader": "^8.0.2",
|
||||
"typescript": "^3.9.7",
|
||||
"typescript": "^4.2.4",
|
||||
"webpack": "^4.46.0",
|
||||
"webpack-cli": "^3.3.12",
|
||||
"webpack-dev-server": "^3.11.2"
|
||||
@ -100,7 +100,7 @@
|
||||
"tsc:watch": "tsc --watch",
|
||||
"preinstall": "./preinstall.sh",
|
||||
"build:dev": "cross-env NODE_ENV=development webpack --config config/webpack.dev.js",
|
||||
"build:prod": "cross-env NODE_ENV=production webpack --config config/webpack.prod.js",
|
||||
"build:prod": "cd ../npm/api && npm ci && cd ../../interface && cross-env NODE_ENV=production webpack --config config/webpack.prod.js",
|
||||
"start": "webpack-dev-server --config config/webpack.dev.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
|
@ -6,7 +6,7 @@ for i in $(find . -type d -maxdepth 1) ; do
|
||||
if [ -f "${packageJson}" ]; then
|
||||
echo "installing ${i}..."
|
||||
cd ./${i}
|
||||
npm install
|
||||
npm ci
|
||||
cd ..
|
||||
fi
|
||||
done
|
@ -2,6 +2,7 @@ import BaseApi from './base';
|
||||
import { StoreState } from '../store/type';
|
||||
import { Patp } from '@urbit/api';
|
||||
import { ContactEdit } from '@urbit/api/contacts';
|
||||
import _ from 'lodash';
|
||||
|
||||
export default class ContactsApi extends BaseApi<StoreState> {
|
||||
add(ship: Patp, contact: any) {
|
||||
@ -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,19 +1,16 @@
|
||||
import BaseApi from './base';
|
||||
import {StoreState} from '../store/type';
|
||||
import {GcpToken} from '../types/gcp-state';
|
||||
import type {StoreState} from '../store/type';
|
||||
import type {GcpToken} from '../../types/gcp-state';
|
||||
|
||||
|
||||
export default class GcpApi extends BaseApi<StoreState> {
|
||||
isConfigured() {
|
||||
return this.spider('noun', 'json', 'gcp-is-configured', {})
|
||||
.then((data) => {
|
||||
this.store.handleEvent({
|
||||
data
|
||||
});
|
||||
});
|
||||
// Does not touch the store; use the value manually.
|
||||
async isConfigured(): Promise<boolean> {
|
||||
return this.spider('noun', 'json', 'gcp-is-configured', {});
|
||||
}
|
||||
|
||||
getToken() {
|
||||
// Does not return the token; read it out of the store.
|
||||
async getToken(): Promise<void> {
|
||||
return this.spider('noun', 'gcp-token', 'gcp-get-token', {})
|
||||
.then((token) => {
|
||||
this.store.handleEvent({
|
||||
|
@ -83,7 +83,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 +91,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(
|
||||
@ -227,7 +227,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
|
||||
@ -283,9 +283,9 @@ export default class GraphApi extends BaseApi<StoreState> {
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
|
@ -4,6 +4,11 @@ import { dateToDa, decToUd } from '../lib/util';
|
||||
import { NotifIndex, IndexedNotification, Association, GraphNotifDescription } from '@urbit/api';
|
||||
import { BigInteger } from 'big-integer';
|
||||
import { getParentIndex } from '../lib/notification';
|
||||
import useHarkState from '../state/hark';
|
||||
|
||||
function getHarkSize() {
|
||||
return useHarkState.getState().notifications.size ?? 0;
|
||||
}
|
||||
|
||||
export class HarkApi extends BaseApi<StoreState> {
|
||||
private harkAction(action: any): Promise<any> {
|
||||
@ -172,10 +177,10 @@ export class HarkApi extends BaseApi<StoreState> {
|
||||
}
|
||||
|
||||
async getMore(): Promise<boolean> {
|
||||
const offset = this.store.state['notifications']?.size || 0;
|
||||
const offset = getHarkSize();
|
||||
const count = 3;
|
||||
await this.getSubset(offset, count, false);
|
||||
return offset === (this.store.state.notifications?.size || 0);
|
||||
return offset === getHarkSize();
|
||||
}
|
||||
|
||||
async getSubset(offset:number, count:number, isArchive: boolean) {
|
||||
|
@ -1,232 +0,0 @@
|
||||
import bigInt, { BigInteger } from 'big-integer';
|
||||
|
||||
interface NonemptyNode<V> {
|
||||
n: [BigInteger, V];
|
||||
l: MapNode<V>;
|
||||
r: MapNode<V>;
|
||||
}
|
||||
|
||||
type MapNode<V> = NonemptyNode<V> | null;
|
||||
|
||||
/**
|
||||
* An implementation of ordered maps for JS
|
||||
* Plagiarised wholesale from sys/zuse
|
||||
*/
|
||||
export class BigIntOrderedMap<V> implements Iterable<[BigInteger, V]> {
|
||||
private root: MapNode<V> = null;
|
||||
size = 0;
|
||||
|
||||
constructor(initial: [BigInteger, V][] = []) {
|
||||
initial.forEach(([key, val]) => {
|
||||
this.set(key, val);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an value for a key
|
||||
*/
|
||||
get(key: BigInteger): V | null {
|
||||
const inner = (node: MapNode<V>) => {
|
||||
if (!node) {
|
||||
return node;
|
||||
}
|
||||
const [k, v] = node.n;
|
||||
if (key.eq(k)) {
|
||||
return v;
|
||||
}
|
||||
if (key.gt(k)) {
|
||||
return inner(node.l);
|
||||
} else {
|
||||
return inner(node.r);
|
||||
}
|
||||
};
|
||||
|
||||
return inner(this.root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put an item by a key
|
||||
*/
|
||||
set(key: BigInteger, value: V): void {
|
||||
const inner = (node: MapNode<V>) => {
|
||||
if (!node) {
|
||||
return {
|
||||
n: [key, value],
|
||||
l: null,
|
||||
r: null
|
||||
};
|
||||
}
|
||||
const [k] = node.n;
|
||||
if (key.eq(k)) {
|
||||
this.size--;
|
||||
return {
|
||||
...node,
|
||||
n: [k, value]
|
||||
};
|
||||
}
|
||||
if (key.gt(k)) {
|
||||
const l = inner(node.l);
|
||||
if (!l) {
|
||||
throw new Error('invariant violation');
|
||||
}
|
||||
return {
|
||||
...node,
|
||||
l
|
||||
};
|
||||
}
|
||||
const r = inner(node.r);
|
||||
if (!r) {
|
||||
throw new Error('invariant violation');
|
||||
}
|
||||
|
||||
return { ...node, r };
|
||||
};
|
||||
this.size++;
|
||||
this.root = inner(this.root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all entries
|
||||
*/
|
||||
clear() {
|
||||
this.root = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Predicate testing if map contains key
|
||||
*/
|
||||
has(key: BigInteger): boolean {
|
||||
const inner = (node: MapNode<V>) => {
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
const [k] = node.n;
|
||||
|
||||
if (k.eq(key)) {
|
||||
return true;
|
||||
}
|
||||
if (key.gt(k)) {
|
||||
return inner(node.l);
|
||||
}
|
||||
return inner(node.r);
|
||||
};
|
||||
return inner(this.root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove value associated with key, returning whether that key
|
||||
* existed in the first place
|
||||
*/
|
||||
delete(key: BigInteger) {
|
||||
const inner = (node: MapNode<V>): [boolean, MapNode<V>] => {
|
||||
if (!node) {
|
||||
return [false, null];
|
||||
}
|
||||
const [k] = node.n;
|
||||
if (k.eq(key)) {
|
||||
return [true, this.nip(node)];
|
||||
}
|
||||
if (key.gt(k)) {
|
||||
const [bool, l] = inner(node.l);
|
||||
return [
|
||||
bool,
|
||||
{
|
||||
...node,
|
||||
l
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
const [bool, r] = inner(node.r);
|
||||
return [
|
||||
bool,
|
||||
{
|
||||
...node,
|
||||
r
|
||||
}
|
||||
];
|
||||
};
|
||||
const [ret, newRoot] = inner(this.root);
|
||||
if(ret) {
|
||||
this.size--;
|
||||
}
|
||||
this.root = newRoot;
|
||||
return ret;
|
||||
}
|
||||
|
||||
private nip(nod: NonemptyNode<V>): MapNode<V> {
|
||||
const inner = (node: NonemptyNode<V>) => {
|
||||
if (!node.l) {
|
||||
return node.r;
|
||||
}
|
||||
if (!node.r) {
|
||||
return node.l;
|
||||
}
|
||||
return {
|
||||
...node.l,
|
||||
r: inner(node.r)
|
||||
};
|
||||
};
|
||||
return inner(nod);
|
||||
}
|
||||
|
||||
peekLargest(): [BigInteger, V] | undefined {
|
||||
const inner = (node: MapNode<V>) => {
|
||||
if(!node) {
|
||||
return undefined;
|
||||
}
|
||||
if(node.l) {
|
||||
return inner(node.l);
|
||||
}
|
||||
return node.n;
|
||||
};
|
||||
return inner(this.root);
|
||||
}
|
||||
|
||||
peekSmallest(): [BigInteger, V] | undefined {
|
||||
const inner = (node: MapNode<V>) => {
|
||||
if(!node) {
|
||||
return undefined;
|
||||
}
|
||||
if(node.r) {
|
||||
return inner(node.r);
|
||||
}
|
||||
return node.n;
|
||||
};
|
||||
return inner(this.root);
|
||||
}
|
||||
|
||||
keys(): BigInteger[] {
|
||||
const list = Array.from(this);
|
||||
return list.map(([key]) => key);
|
||||
}
|
||||
|
||||
forEach(f: (value: V, key: BigInteger) => void) {
|
||||
const list = Array.from(this);
|
||||
return list.forEach(([k,v]) => f(v,k));
|
||||
}
|
||||
|
||||
[Symbol.iterator](): IterableIterator<[BigInteger, V]> {
|
||||
const result: [BigInteger, V][] = [];
|
||||
const inner = (node: MapNode<V>) => {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
inner(node.l);
|
||||
result.push(node.n);
|
||||
inner(node.r);
|
||||
};
|
||||
inner(this.root);
|
||||
|
||||
let idx = 0;
|
||||
return {
|
||||
[Symbol.iterator]: this[Symbol.iterator],
|
||||
next: (): IteratorResult<[BigInteger, V]> => {
|
||||
if (idx < result.length) {
|
||||
return { value: result[idx++], done: false };
|
||||
}
|
||||
return { done: true, value: null };
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -26,7 +26,7 @@ class GcpUpload implements StorageUpload {
|
||||
this.#accessKey = accessKey;
|
||||
}
|
||||
|
||||
async promise(): UploadResult {
|
||||
async promise(): Promise<UploadResult> {
|
||||
const {Bucket, Key, ContentType, Body} = this.#params;
|
||||
const urlParams = {
|
||||
uploadType: 'media',
|
||||
|
18
pkg/interface/src/logic/lib/formGroup.ts
Normal file
18
pkg/interface/src/logic/lib/formGroup.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import React from "react";
|
||||
|
||||
export type SubmitHandler = () => Promise<any>;
|
||||
interface IFormGroupContext {
|
||||
addSubmit: (id: string, submit: SubmitHandler) => void;
|
||||
onDirty: (id: string, touched: boolean) => void;
|
||||
onErrors: (id: string, errors: boolean) => void;
|
||||
submitAll: () => Promise<any>;
|
||||
}
|
||||
|
||||
const fallback: IFormGroupContext = {
|
||||
addSubmit: () => {},
|
||||
onDirty: () => {},
|
||||
onErrors: () => {},
|
||||
submitAll: () => Promise.resolve(),
|
||||
};
|
||||
|
||||
export const FormGroupContext = React.createContext(fallback);
|
@ -5,10 +5,9 @@
|
||||
// 1. call configure with a GlobalApi and GlobalStore.
|
||||
// 2. call start() to start the token refresh loop.
|
||||
//
|
||||
// If the ship does not have GCP storage configured, we don't try to get
|
||||
// a token, but we keep checking at regular intervals to see if it gets
|
||||
// configured. If GCP storage is configured, we try to invoke the GCP
|
||||
// get-token thread on the ship until it gives us an access token. Once
|
||||
// If the ship does not have GCP storage configured, we don't try to
|
||||
// get a token. If GCP storage is configured, we try to invoke the GCP
|
||||
// get-token thread on the ship until it gives us an access token. Once
|
||||
// we have a token, we refresh it every hour or so according to its
|
||||
// intrinsic expiry.
|
||||
//
|
||||
@ -25,7 +24,7 @@ class GcpManager {
|
||||
}
|
||||
|
||||
#running = false;
|
||||
#timeoutId: number | null = null;
|
||||
#timeoutId: ReturnType<typeof setTimeout> | null = null;
|
||||
|
||||
start() {
|
||||
if (this.#running) {
|
||||
@ -61,19 +60,17 @@ class GcpManager {
|
||||
}
|
||||
|
||||
#consecutiveFailures: number = 0;
|
||||
|
||||
private isConfigured() {
|
||||
return useStorageState.getState().gcp.configured;
|
||||
}
|
||||
#configured: boolean = false;
|
||||
|
||||
private refreshLoop() {
|
||||
if (!this.isConfigured()) {
|
||||
this.#api.gcp.isConfigured()
|
||||
.then(() => {
|
||||
if (this.isConfigured() === undefined) {
|
||||
if (!this.#configured) {
|
||||
this.#api!.gcp.isConfigured()
|
||||
.then((configured) => {
|
||||
if (configured === undefined) {
|
||||
throw new Error("can't check whether GCP is configured?");
|
||||
}
|
||||
if (this.isConfigured()) {
|
||||
this.#configured = configured;
|
||||
if (this.#configured) {
|
||||
this.refreshLoop();
|
||||
} else {
|
||||
console.log('GcpManager: GCP storage not configured; stopping.');
|
||||
@ -86,7 +83,7 @@ class GcpManager {
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.#api.gcp.getToken()
|
||||
this.#api!.gcp.getToken()
|
||||
.then(() => {
|
||||
const token = useStorageState.getState().gcp.token;
|
||||
if (token) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import bigInt, { BigInteger } from 'big-integer';
|
||||
import f from 'lodash/fp';
|
||||
import { Unreads } from '@urbit/api';
|
||||
import { Unreads, NotificationGraphConfig } from '@urbit/api';
|
||||
|
||||
export function getLastSeen(
|
||||
unreads: Unreads,
|
||||
@ -31,6 +31,16 @@ export function getNotificationCount(
|
||||
): number {
|
||||
const unread = unreads.graph?.[path] || {};
|
||||
return Object.keys(unread)
|
||||
.map(index => unread[index]?.notifications || 0)
|
||||
.map(index => unread[index]?.notifications?.length || 0)
|
||||
.reduce(f.add, 0);
|
||||
}
|
||||
|
||||
export function isWatching(
|
||||
config: NotificationGraphConfig,
|
||||
graph: string,
|
||||
index = "/"
|
||||
) {
|
||||
return !!config.watching.find(
|
||||
watch => watch.graph === graph && watch.index === index
|
||||
);
|
||||
}
|
||||
|
@ -99,9 +99,11 @@ export default function index(contacts, associations, apps, currentGroup, groups
|
||||
Object.keys(associations).filter((e) => {
|
||||
// skip apps with no metadata
|
||||
return Object.keys(associations[e]).length > 0;
|
||||
}).map((e) => {
|
||||
// iterate through each app's metadata object
|
||||
Object.keys(associations[e]).map((association) => {
|
||||
}).map((e) => {
|
||||
// iterate through each app's metadata object
|
||||
Object.keys(associations[e])
|
||||
.filter((association) => !associations?.[e]?.[association]?.metadata?.hidden)
|
||||
.map((association) => {
|
||||
const each = associations[e][association];
|
||||
let title = each.resource;
|
||||
if (each.metadata.title !== '') {
|
||||
|
@ -1,6 +1,10 @@
|
||||
|
||||
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');
|
||||
|
||||
export const IS_ANDROID = ua.includes('Android');
|
||||
|
||||
export const IS_MOBILE = IS_IOS || IS_ANDROID;
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { Post, GraphNode, TextContent, Graph, NodeMap } from '@urbit/api';
|
||||
import { Post, GraphNode, TextContent } from '@urbit/api';
|
||||
import { buntPost } from '~/logic/lib/post';
|
||||
import { unixToDa } from '~/logic/lib/util';
|
||||
import { BigIntOrderedMap } from './BigIntOrderedMap';
|
||||
import BigIntOrderedMap from "@urbit/api/lib/BigIntOrderedMap";
|
||||
import bigInt, { BigInteger } from 'big-integer';
|
||||
|
||||
export function newPost(
|
||||
title: string,
|
||||
body: string
|
||||
): [BigInteger, NodeMap] {
|
||||
): [BigInteger, any] {
|
||||
const now = Date.now();
|
||||
const nowDa = unixToDa(now);
|
||||
const root: Post = {
|
||||
@ -73,13 +73,16 @@ 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;
|
||||
}
|
||||
const [revNum, rev] = [...revs.children][0];
|
||||
if(!rev) {
|
||||
let revNum, rev;
|
||||
if (revs?.children !== null) {
|
||||
[revNum, rev] = [...revs.children][0];
|
||||
}
|
||||
if (!rev) {
|
||||
return empty;
|
||||
}
|
||||
const [title, body] = rev.post.contents as TextContent[];
|
||||
@ -88,18 +91,22 @@ export function getLatestRevision(node: GraphNode): [number, string, string, Pos
|
||||
|
||||
export function getLatestCommentRevision(node: GraphNode): [number, Post] {
|
||||
const empty = [1, buntPost()] as [number, Post];
|
||||
if (node.children.size <= 0) {
|
||||
const childSize = node?.children?.size ?? 0;
|
||||
if (childSize <= 0) {
|
||||
return empty;
|
||||
}
|
||||
const [revNum, rev] = [...node.children][0];
|
||||
if(!rev) {
|
||||
let revNum, rev;
|
||||
if (node?.children !== null) {
|
||||
[revNum, rev] = [...node.children][0];
|
||||
}
|
||||
if (!rev) {
|
||||
return empty;
|
||||
}
|
||||
return [revNum.toJSNumber(), rev.post];
|
||||
}
|
||||
|
||||
export function getComments(node: GraphNode): GraphNode {
|
||||
const comments = node.children.get(bigInt(2));
|
||||
const comments = node.children?.get(bigInt(2));
|
||||
if(!comments) {
|
||||
return { post: buntPost(), children: new BigIntOrderedMap() };
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { TutorialProgress, Associations } from '@urbit/api';
|
||||
import { Associations } from '@urbit/api';
|
||||
import { TutorialProgress } from '~/types';
|
||||
import { AlignX, AlignY } from '~/logic/lib/relativePosition';
|
||||
import { Direction } from '~/views/components/Triangle';
|
||||
|
||||
@ -22,7 +23,7 @@ interface StepDetail {
|
||||
alignY: AlignY | AlignY[];
|
||||
offsetX: number;
|
||||
offsetY: number;
|
||||
arrow: Direction;
|
||||
arrow?: Direction;
|
||||
}
|
||||
|
||||
export function hasTutorialGroup(props: { associations: Associations }) {
|
||||
|
@ -16,5 +16,5 @@ export function useCopy(copied: string, display: string) {
|
||||
display,
|
||||
]);
|
||||
|
||||
return { copyDisplay, doCopy };
|
||||
return { copyDisplay, doCopy, didCopy };
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ export function distanceToBottom(el: HTMLElement) {
|
||||
|
||||
export function useLazyScroll(
|
||||
ref: RefObject<HTMLElement>,
|
||||
ready: boolean,
|
||||
margin: number,
|
||||
count: number,
|
||||
loadMore: () => Promise<boolean>
|
||||
@ -41,7 +42,13 @@ export function useLazyScroll(
|
||||
}, [count]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!ref.current || isDone) {
|
||||
if(!ready) {
|
||||
setIsDone(false);
|
||||
}
|
||||
}, [ready]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!ref.current || isDone || !ready) {
|
||||
return;
|
||||
}
|
||||
const scroll = ref.current;
|
||||
@ -57,7 +64,7 @@ export function useLazyScroll(
|
||||
return () => {
|
||||
ref.current?.removeEventListener('scroll', onScroll);
|
||||
};
|
||||
}, [ref?.current, count]);
|
||||
}, [ref?.current, ready, isDone]);
|
||||
|
||||
return { isDone, isLoading };
|
||||
}
|
||||
|
@ -15,7 +15,8 @@ function retrieve<T>(key: string, initial: T): T {
|
||||
interface SetStateFunc<T> {
|
||||
(t: T): T;
|
||||
}
|
||||
type SetState<T> = T | SetStateFunc<T>;
|
||||
// See microsoft/typescript#37663 for filed bug
|
||||
type SetState<T> = T extends any ? SetStateFunc<T> : never;
|
||||
export function useLocalStorageState<T>(key: string, initial: T) {
|
||||
const [state, _setState] = useState(() => retrieve(key, initial));
|
||||
|
||||
|
@ -2,18 +2,14 @@ import React, {
|
||||
useState,
|
||||
ReactNode,
|
||||
useCallback,
|
||||
SyntheticEvent,
|
||||
useMemo,
|
||||
useEffect,
|
||||
useRef
|
||||
} from 'react';
|
||||
|
||||
import { Box } from '@tlon/indigo-react';
|
||||
import { useOutsideClick } from './useOutsideClick';
|
||||
import { ModalOverlay } from '~/views/components/ModalOverlay';
|
||||
import { Portal } from '~/views/components/Portal';
|
||||
import { ModalPortal } from '~/views/components/ModalPortal';
|
||||
import { PropFunc } from '@urbit/api';
|
||||
import { PropFunc } from '~/types';
|
||||
|
||||
type ModalFunc = (dismiss: () => void) => JSX.Element;
|
||||
interface UseModalProps {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { useRef } from 'react';
|
||||
import { Primitive } from '@urbit/api';
|
||||
import { Primitive } from '~/types';
|
||||
|
||||
export default function usePreviousValue<T extends Primitive>(value: T): T {
|
||||
const prev = useRef<T | null>(null);
|
||||
|
51
pkg/interface/src/logic/lib/useRunIO.ts
Normal file
51
pkg/interface/src/logic/lib/useRunIO.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import {unstable_batchedUpdates} from "react-dom";
|
||||
|
||||
export type IOInstance<I, P, O> = (
|
||||
input: I
|
||||
) => (props: P) => Promise<[(p: P) => boolean, O]>;
|
||||
|
||||
export function useRunIO<I, O>(
|
||||
io: (i: I) => Promise<O>,
|
||||
after: (o: O) => void,
|
||||
key: string
|
||||
): (i: I) => Promise<unknown> {
|
||||
const [resolve, setResolve] = useState<() => void>(() => () => {});
|
||||
const [reject, setReject] = useState<(e: any) => void>(() => () => {});
|
||||
const [output, setOutput] = useState<O | null>(null);
|
||||
const [done, setDone] = useState(false);
|
||||
const run = (i: I) =>
|
||||
new Promise((res, rej) => {
|
||||
setResolve(() => res);
|
||||
setReject(() => rej);
|
||||
io(i)
|
||||
.then((o) => {
|
||||
unstable_batchedUpdates(() => {
|
||||
setOutput(o);
|
||||
setDone(true);
|
||||
});
|
||||
})
|
||||
.catch(rej);
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
reject(new Error("useRunIO: key changed"));
|
||||
setDone(false);
|
||||
setOutput(null);
|
||||
}, [key]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!done) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
after(output!);
|
||||
resolve();
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
}, [done]);
|
||||
|
||||
return run;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ export function useStatelessAsyncClickable(
|
||||
onClick: (e: MouseEvent) => Promise<void>,
|
||||
name: string
|
||||
) {
|
||||
const [state, setState] = useState<ButtonState>('waiting');
|
||||
const [state, setState] = useState<AsyncClickableState>('waiting');
|
||||
const handleClick = useCallback(
|
||||
async (e: MouseEvent) => {
|
||||
try {
|
||||
|
@ -16,7 +16,7 @@ export interface IuseStorage {
|
||||
upload: (file: File, bucket: string) => Promise<string>;
|
||||
uploadDefault: (file: File) => Promise<string>;
|
||||
uploading: boolean;
|
||||
promptUpload: () => Promise<string | undefined>;
|
||||
promptUpload: () => Promise<unknown>;
|
||||
}
|
||||
|
||||
const useStorage = ({ accept = '*' } = { accept: '*' }): IuseStorage => {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useEffect, useState, useCallback, useMemo } from 'react';
|
||||
import _ from 'lodash';
|
||||
import f, { compose, memoize } from 'lodash/fp';
|
||||
import bigInt, { BigInteger } from 'big-integer';
|
||||
@ -30,7 +30,7 @@ export const getModuleIcon = (mod: string) => {
|
||||
}
|
||||
|
||||
if (mod === 'post') {
|
||||
return 'Spaces';
|
||||
return 'Dashboard';
|
||||
}
|
||||
|
||||
return _.capitalize(mod);
|
||||
@ -63,6 +63,16 @@ export function unixToDa(unix: number) {
|
||||
return DA_UNIX_EPOCH.add(timeSinceEpoch);
|
||||
}
|
||||
|
||||
export function dmCounterparty(resource: string) {
|
||||
const [,,ship,name] = resource.split('/');
|
||||
return ship === `~${window.ship}` ? `~${name.slice(4)}` : ship;
|
||||
}
|
||||
|
||||
export function isDm(resource: string) {
|
||||
const [,,,name] = resource.split('/');
|
||||
return name.startsWith('dm--');
|
||||
}
|
||||
|
||||
export function makePatDa(patda: string) {
|
||||
return bigInt(udToDec(patda));
|
||||
}
|
||||
@ -182,7 +192,10 @@ export function uxToHex(ux: string) {
|
||||
export const hexToUx = (hex) => {
|
||||
const ux = f.flow(
|
||||
f.chunk(4),
|
||||
f.map(x => _.dropWhile(x, y => y === 0).join('')),
|
||||
// eslint-disable-next-line prefer-arrow-callback
|
||||
f.map(x => _.dropWhile(x, function(y: unknown) {
|
||||
return y === 0;
|
||||
}).join('')),
|
||||
f.join('.')
|
||||
)(hex.split(''));
|
||||
return `0x${ux}`;
|
||||
@ -400,11 +413,15 @@ interface useHoveringInterface {
|
||||
|
||||
export const useHovering = (): useHoveringInterface => {
|
||||
const [hovering, setHovering] = useState(false);
|
||||
const bind = {
|
||||
onMouseOver: () => setHovering(true),
|
||||
onMouseLeave: () => setHovering(false)
|
||||
};
|
||||
return { hovering, bind };
|
||||
const onMouseOver = useCallback(() => setHovering(true), [])
|
||||
const onMouseLeave = useCallback(() => setHovering(false), [])
|
||||
const bind = useMemo(() => ({
|
||||
onMouseOver,
|
||||
onMouseLeave,
|
||||
}), [onMouseLeave, onMouseOver]);
|
||||
|
||||
|
||||
return useMemo(() => ({ hovering, bind }), [hovering, bind]);
|
||||
};
|
||||
|
||||
const DM_REGEX = /ship\/~([a-z]|-)*\/dm--/;
|
||||
|
@ -7,6 +7,7 @@ import React, {
|
||||
useEffect,
|
||||
} from "react";
|
||||
import usePreviousValue from "./usePreviousValue";
|
||||
import {Primitive} from "~/types";
|
||||
|
||||
export interface VirtualContextProps {
|
||||
save: () => void;
|
||||
@ -42,14 +43,14 @@ export function useVirtualResizeState(s: boolean) {
|
||||
[_setState, save]
|
||||
);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
restore();
|
||||
useEffect(() => {
|
||||
requestAnimationFrame(restore);
|
||||
}, [state]);
|
||||
|
||||
return [state, setState] as const;
|
||||
}
|
||||
|
||||
export function useVirtualResizeProp<T>(prop: T) {
|
||||
export function useVirtualResizeProp(prop: Primitive) {
|
||||
const { save, restore } = useVirtual();
|
||||
const oldProp = usePreviousValue(prop)
|
||||
|
||||
@ -57,8 +58,8 @@ export function useVirtualResizeProp<T>(prop: T) {
|
||||
save();
|
||||
}
|
||||
|
||||
useLayoutEffect(() => {
|
||||
restore();
|
||||
useEffect(() => {
|
||||
requestAnimationFrame(restore);
|
||||
}, [prop]);
|
||||
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Associations, Workspace } from '@urbit/api';
|
||||
import { Associations } from '@urbit/api';
|
||||
import { Workspace } from '~/types';
|
||||
|
||||
export function getTitleFromWorkspace(
|
||||
associations: Associations,
|
||||
|
@ -1,5 +1,4 @@
|
||||
import _ from 'lodash';
|
||||
import { StoreState } from '../../store/type';
|
||||
import { StoreState } from '../store/type';
|
||||
import { Cage } from '~/types/cage';
|
||||
|
||||
type LocalState = Pick<StoreState, 'connection'>;
|
||||
|
@ -1,31 +1,21 @@
|
||||
import _ from 'lodash';
|
||||
import {StoreState} from '../store/type';
|
||||
import {GcpToken} from '../../types/gcp-state';
|
||||
import { Cage } from '~/types/cage';
|
||||
import type {GcpToken} from '../../types/gcp-state';
|
||||
import type {Cage} from '~/types/cage';
|
||||
import useStorageState, { StorageState } from '../state/storage';
|
||||
import { reduceState } from '../state/base';
|
||||
|
||||
export default class GcpReducer {
|
||||
reduce(json: Cage) {
|
||||
reduceState<StorageState, any>(useStorageState, json, [
|
||||
reduceConfigured,
|
||||
reduceToken
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
const reduceConfigured = (json, state: StorageState): StorageState => {
|
||||
let data = json['gcp-configured'];
|
||||
if (data !== undefined) {
|
||||
state.gcp.configured = data;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
const reduceToken = (json: Cage, state: StorageState): StorageState => {
|
||||
let data = json['gcp-token'];
|
||||
if (data) {
|
||||
state = setToken(data, state);
|
||||
setToken(data, state);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
@ -37,7 +27,7 @@ const setToken = (data: any, state: StorageState): StorageState => {
|
||||
return state;
|
||||
}
|
||||
|
||||
const isToken = (token: any): boolean => {
|
||||
const isToken = (token: any): token is GcpToken => {
|
||||
return (typeof(token.accessKey) === 'string' &&
|
||||
typeof(token.expiresIn) === 'number');
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import _ from 'lodash';
|
||||
import { BigIntOrderedMap } from "~/logic/lib/BigIntOrderedMap";
|
||||
import BigIntOrderedMap from "@urbit/api/lib/BigIntOrderedMap";
|
||||
import produce from 'immer';
|
||||
import bigInt, { BigInteger } from "big-integer";
|
||||
import useGraphState, { GraphState } from '../state/graph';
|
||||
import { reduceState } from '../state/base';
|
||||
@ -13,7 +14,7 @@ export const GraphReducer = (json) => {
|
||||
addGraph,
|
||||
removeGraph,
|
||||
addNodes,
|
||||
removeNodes
|
||||
removePosts
|
||||
]);
|
||||
}
|
||||
const loose = _.get(json, 'graph-update-loose', false);
|
||||
@ -51,23 +52,18 @@ const keys = (json, state: GraphState): GraphState => {
|
||||
const processNode = (node) => {
|
||||
// is empty
|
||||
if (!node.children) {
|
||||
node.children = new BigIntOrderedMap();
|
||||
return node;
|
||||
return produce(node, draft => {
|
||||
draft.children = new BigIntOrderedMap();
|
||||
});
|
||||
}
|
||||
|
||||
// is graph
|
||||
let converted = new BigIntOrderedMap();
|
||||
for (let idx in node.children) {
|
||||
let item = node.children[idx];
|
||||
let index = bigInt(idx);
|
||||
|
||||
converted.set(
|
||||
index,
|
||||
processNode(item)
|
||||
);
|
||||
}
|
||||
node.children = converted;
|
||||
return node;
|
||||
return produce(node, draft => {
|
||||
draft.children = new BigIntOrderedMap()
|
||||
.gas(_.map(draft.children, (item, idx) =>
|
||||
[bigInt(idx), processNode(item)] as [BigInteger, any]
|
||||
));
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@ -85,17 +81,10 @@ const addGraph = (json, state: GraphState): GraphState => {
|
||||
state.graphTimesentMap[resource] = {};
|
||||
|
||||
|
||||
for (let idx in data.graph) {
|
||||
let item = data.graph[idx];
|
||||
let index = bigInt(idx);
|
||||
|
||||
let node = processNode(item);
|
||||
state.graphs[resource] = state.graphs[resource].gas(Object.keys(data.graph).map(idx => {
|
||||
return [bigInt(idx), processNode(data.graph[idx])];
|
||||
}));
|
||||
|
||||
state.graphs[resource].set(
|
||||
index,
|
||||
node
|
||||
);
|
||||
}
|
||||
state.graphKeys.add(resource);
|
||||
}
|
||||
return state;
|
||||
@ -116,7 +105,7 @@ const removeGraph = (json, state: GraphState): GraphState => {
|
||||
};
|
||||
|
||||
const mapifyChildren = (children) => {
|
||||
return new BigIntOrderedMap(
|
||||
return new BigIntOrderedMap().gas(
|
||||
_.map(children, (node, idx) => {
|
||||
idx = idx && idx.startsWith('/') ? idx.slice(1) : idx;
|
||||
const nd = {...node, children: mapifyChildren(node.children || {}) };
|
||||
@ -128,8 +117,7 @@ const addNodes = (json, state) => {
|
||||
const _addNode = (graph, index, node) => {
|
||||
// set child of graph
|
||||
if (index.length === 1) {
|
||||
graph.set(index[0], node);
|
||||
return graph;
|
||||
return graph.set(index[0], node);
|
||||
}
|
||||
|
||||
// set parent of graph
|
||||
@ -138,19 +126,20 @@ const addNodes = (json, state) => {
|
||||
console.error('parent node does not exist, cannot add child');
|
||||
return graph;
|
||||
}
|
||||
parNode.children = _addNode(parNode.children, index.slice(1), node);
|
||||
graph.set(index[0], parNode);
|
||||
return graph;
|
||||
return graph.set(index[0], produce(parNode, draft => {
|
||||
draft.children = _addNode(draft.children, index.slice(1), node);
|
||||
}));
|
||||
};
|
||||
|
||||
const _remove = (graph, index) => {
|
||||
if (index.length === 1) {
|
||||
graph.delete(index[0]);
|
||||
return graph.delete(index[0]);
|
||||
} else {
|
||||
const child = graph.get(index[0]);
|
||||
if (child) {
|
||||
child.children = _remove(child.children, index.slice(1));
|
||||
graph.set(index[0], child);
|
||||
return graph.set(index[0], produce(child, draft => {
|
||||
draft.children = _remove(draft.children, index.slice(1));
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,10 +155,9 @@ const addNodes = (json, state) => {
|
||||
return bigInt(ind);
|
||||
});
|
||||
|
||||
graph = _remove(graph, indexArr);
|
||||
delete state.graphTimesentMap[resource][timestamp];
|
||||
return _remove(graph, indexArr);
|
||||
}
|
||||
|
||||
return graph;
|
||||
};
|
||||
|
||||
@ -181,7 +169,6 @@ const addNodes = (json, state) => {
|
||||
graph = _killByFuzzyTimestamp(graph, resource, post['time-sent']);
|
||||
graph = _killByFuzzyTimestamp(graph, resource, post['time-sent'] - 1);
|
||||
graph = _killByFuzzyTimestamp(graph, resource, post['time-sent'] + 1);
|
||||
|
||||
return graph;
|
||||
};
|
||||
|
||||
@ -208,11 +195,12 @@ const addNodes = (json, state) => {
|
||||
return aArr.length - bArr.length;
|
||||
});
|
||||
|
||||
let graph = state.graphs[resource];
|
||||
|
||||
indices.forEach((index) => {
|
||||
let node = data.nodes[index];
|
||||
graph = _removePending(graph, node.post, resource);
|
||||
const old = state.graphs[resource].size;
|
||||
state.graphs[resource] = _removePending(state.graphs[resource], node.post, resource);
|
||||
const newSize = state.graphs[resource].size;
|
||||
|
||||
|
||||
if (index.split('/').length === 0) { return; }
|
||||
let indexArr = index.split('/').slice(1).map((ind) => {
|
||||
@ -225,35 +213,52 @@ const addNodes = (json, state) => {
|
||||
state.graphTimesentMap[resource][node.post['time-sent']] = index;
|
||||
}
|
||||
|
||||
node.children = mapifyChildren(node?.children || {});
|
||||
|
||||
|
||||
graph = _addNode(
|
||||
graph,
|
||||
state.graphs[resource] = _addNode(
|
||||
state.graphs[resource],
|
||||
indexArr,
|
||||
node
|
||||
produce(node, draft => {
|
||||
draft.children = mapifyChildren(draft?.children || {});
|
||||
})
|
||||
);
|
||||
if(newSize !== old) {
|
||||
console.log(`${resource}, (${old}, ${newSize}, ${state.graphs[resource].size})`);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
state.graphs[resource] = graph;
|
||||
}
|
||||
return state;
|
||||
};
|
||||
|
||||
const removeNodes = (json, state: GraphState): GraphState => {
|
||||
const removePosts = (json, state: GraphState): GraphState => {
|
||||
const _remove = (graph, index) => {
|
||||
const child = graph.get(index[0]);
|
||||
if (index.length === 1) {
|
||||
graph.delete(index[0]);
|
||||
if (child) {
|
||||
return graph.set(index[0], {
|
||||
post: child.post.hash || '',
|
||||
children: child.children
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (child) {
|
||||
_remove(child.children, index.slice(1));
|
||||
return graph.set(index[0], child);
|
||||
} else {
|
||||
const child = graph.get(index[0]);
|
||||
if (child) {
|
||||
_remove(child.children, index.slice(1));
|
||||
graph.set(index[0], child);
|
||||
return graph.set(index[0], produce(draft => {
|
||||
draft.children = _remove(draft.children, index.slice(1))
|
||||
}));
|
||||
}
|
||||
return graph;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const data = _.get(json, 'remove-nodes', false);
|
||||
const data = _.get(json, 'remove-posts', false);
|
||||
if (data) {
|
||||
const { ship, name } = data.resource;
|
||||
const res = `${ship}/${name}`;
|
||||
@ -264,7 +269,7 @@ const removeNodes = (json, state: GraphState): GraphState => {
|
||||
let indexArr = index.split('/').slice(1).map((ind) => {
|
||||
return bigInt(ind);
|
||||
});
|
||||
_remove(state.graphs[res], indexArr);
|
||||
state.graphs[res] = _remove(state.graphs[res], indexArr);
|
||||
});
|
||||
}
|
||||
return state;
|
||||
|
@ -5,16 +5,14 @@ import {
|
||||
Group,
|
||||
Tags,
|
||||
GroupPolicy,
|
||||
GroupPolicyDiff,
|
||||
OpenPolicyDiff,
|
||||
OpenPolicy,
|
||||
InvitePolicyDiff,
|
||||
InvitePolicy
|
||||
} from '@urbit/api/groups';
|
||||
import { Enc, PatpNoSig } from '@urbit/api';
|
||||
import { Enc } from '@urbit/api';
|
||||
import { resourceAsPath } from '../lib/util';
|
||||
import useGroupState, { GroupState } from '../state/group';
|
||||
import { compose } from 'lodash/fp';
|
||||
import { reduceState } from '../state/base';
|
||||
|
||||
function decodeGroup(group: Enc<Group>): Group {
|
||||
@ -125,9 +123,9 @@ const addMembers = (json: GroupUpdate, state: GroupState): GroupState => {
|
||||
state.groups[resourcePath].members.add(member);
|
||||
if (
|
||||
'invite' in state.groups[resourcePath].policy &&
|
||||
state.groups[resourcePath].policy.invite.pending.has(member)
|
||||
state.groups[resourcePath].policy['invite'].pending.has(member)
|
||||
) {
|
||||
state.groups[resourcePath].policy.invite.pending.delete(member)
|
||||
state.groups[resourcePath].policy['invite'].pending.delete(member);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -159,7 +157,7 @@ const addTag = (json: GroupUpdate, state: GroupState): GroupState => {
|
||||
_.set(tags, tagAccessors, tagged);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
const removeTag = (json: GroupUpdate, state: GroupState): GroupState => {
|
||||
if ('removeTag' in json) {
|
||||
|
@ -1,23 +1,19 @@
|
||||
import {
|
||||
Notifications,
|
||||
NotifIndex,
|
||||
NotificationGraphConfig,
|
||||
GroupNotificationsConfig,
|
||||
UnreadStats,
|
||||
Timebox
|
||||
} from '@urbit/api';
|
||||
import { makePatDa } from '~/logic/lib/util';
|
||||
import _ from 'lodash';
|
||||
import { BigIntOrderedMap } from '../lib/BigIntOrderedMap';
|
||||
import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap';
|
||||
import useHarkState, { HarkState } from '../state/hark';
|
||||
import { compose } from 'lodash/fp';
|
||||
import { reduceState } from '../state/base';
|
||||
import bigInt, {BigInteger} from 'big-integer';
|
||||
import {BigInteger} from 'big-integer';
|
||||
|
||||
export const HarkReducer = (json: any) => {
|
||||
const data = _.get(json, 'harkUpdate', false);
|
||||
if (data) {
|
||||
reduce(data);
|
||||
reduceState(useHarkState, data, [reduce]);
|
||||
}
|
||||
const graphHookData = _.get(json, 'hark-graph-hook-update', false);
|
||||
if (graphHookData) {
|
||||
@ -39,8 +35,9 @@ export const HarkReducer = (json: any) => {
|
||||
}
|
||||
};
|
||||
|
||||
function reduce(data) {
|
||||
reduceState<HarkState, any>(useHarkState, data, [
|
||||
function reduce(data, state) {
|
||||
const reducers = [
|
||||
calculateCount,
|
||||
unread,
|
||||
read,
|
||||
archive,
|
||||
@ -56,8 +53,11 @@ function reduce(data) {
|
||||
seenIndex,
|
||||
removeGraph,
|
||||
readAll,
|
||||
calculateCount
|
||||
]);
|
||||
];
|
||||
const reducer = compose(reducers.map(r => s => {
|
||||
return r(data, s);
|
||||
}));
|
||||
return reducer(state);
|
||||
}
|
||||
|
||||
function calculateCount(json: any, state: HarkState) {
|
||||
@ -147,8 +147,8 @@ function graphWatchSelf(json: any, state: HarkState): HarkState {
|
||||
|
||||
function readAll(json: any, state: HarkState): HarkState {
|
||||
const data = _.get(json, 'read-all');
|
||||
if(data) {
|
||||
state = clearState(state);
|
||||
if(data) {
|
||||
clearState(state);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
@ -164,7 +164,7 @@ function removeGraph(json: any, state: HarkState): HarkState {
|
||||
function seenIndex(json: any, state: HarkState): HarkState {
|
||||
const data = _.get(json, 'seen-index');
|
||||
if(data) {
|
||||
state = updateNotificationStats(state, data.index, 'last', () => data.time);
|
||||
updateNotificationStats(state, data.index, 'last', () => data.time);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
@ -172,7 +172,7 @@ function seenIndex(json: any, state: HarkState): HarkState {
|
||||
function readEach(json: any, state: HarkState): HarkState {
|
||||
const data = _.get(json, 'read-each');
|
||||
if (data) {
|
||||
state = updateUnreads(state, data.index, u => u.delete(data.target));
|
||||
updateUnreads(state, data.index, u => u.delete(data.target));
|
||||
}
|
||||
return state;
|
||||
}
|
||||
@ -180,7 +180,7 @@ function readEach(json: any, state: HarkState): HarkState {
|
||||
function readSince(json: any, state: HarkState): HarkState {
|
||||
const data = _.get(json, 'read-count');
|
||||
if(data) {
|
||||
state = updateUnreadCount(state, data, () => 0);
|
||||
updateUnreadCount(state, data, () => 0);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
@ -188,7 +188,7 @@ function readSince(json: any, state: HarkState): HarkState {
|
||||
function unreadSince(json: any, state: HarkState): HarkState {
|
||||
const data = _.get(json, 'unread-count');
|
||||
if(data) {
|
||||
state = updateUnreadCount(state, data.index, u => u + 1);
|
||||
updateUnreadCount(state, data.index, u => u + 1);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
@ -196,7 +196,7 @@ function unreadSince(json: any, state: HarkState): HarkState {
|
||||
function unreadEach(json: any, state: HarkState): HarkState {
|
||||
const data = _.get(json, 'unread-each');
|
||||
if(data) {
|
||||
state = updateUnreads(state, data.index, us => us.add(data.target));
|
||||
updateUnreads(state, data.index, us => us.add(data.target));
|
||||
}
|
||||
return state;
|
||||
}
|
||||
@ -204,7 +204,7 @@ function unreadEach(json: any, state: HarkState): HarkState {
|
||||
function unreads(json: any, state: HarkState): HarkState {
|
||||
const data = _.get(json, 'unreads');
|
||||
if(data) {
|
||||
state = clearState(state);
|
||||
clearState(state);
|
||||
data.forEach(({ index, stats }) => {
|
||||
const { unreads, notifications, last } = stats;
|
||||
updateNotificationStats(state, index, 'last', () => last);
|
||||
@ -212,11 +212,11 @@ function unreads(json: any, state: HarkState): HarkState {
|
||||
addNotificationToUnread(state, index, makePatDa(time));
|
||||
});
|
||||
if('count' in unreads) {
|
||||
state = updateUnreadCount(state, index, (u = 0) => u + unreads.count);
|
||||
updateUnreadCount(state, index, (u = 0) => u + unreads.count);
|
||||
} else {
|
||||
state = updateUnreads(state, index, s => new Set());
|
||||
updateUnreads(state, index, s => new Set());
|
||||
unreads.each.forEach((u: string) => {
|
||||
state = updateUnreads(state, index, s => s.add(u));
|
||||
updateUnreads(state, index, s => s.add(u));
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -240,10 +240,8 @@ function clearState(state: HarkState): HarkState {
|
||||
},
|
||||
notificationsCount: 0
|
||||
};
|
||||
Object.assign(state, initialState);
|
||||
|
||||
Object.keys(initialState).forEach((key) => {
|
||||
state[key] = initialState[key];
|
||||
});
|
||||
return state;
|
||||
}
|
||||
|
||||
@ -262,7 +260,7 @@ function updateUnreads(state: HarkState, index: NotifIndex, f: (us: Set<string>)
|
||||
if(!('graph' in index)) {
|
||||
return state;
|
||||
}
|
||||
let unreads = _.get(state.unreads.graph, [index.graph.graph, index.graph.index, 'unreads'], new Set<string>());
|
||||
let unreads: any = _.get(state.unreads.graph, [index.graph.graph, index.graph.index, 'unreads'], new Set<string>());
|
||||
f(unreads);
|
||||
|
||||
_.set(state.unreads.graph, [index.graph.graph, index.graph.index, 'unreads'], unreads);
|
||||
@ -276,7 +274,7 @@ function addNotificationToUnread(state: HarkState, index: NotifIndex, time: BigI
|
||||
_.set(state.unreads.graph, path,
|
||||
[
|
||||
...curr.filter(c => !(c.time.eq(time) && notifIdxEqual(c.index, index))),
|
||||
{ time, index}
|
||||
{ time, index }
|
||||
]
|
||||
);
|
||||
} else if ('group' in index) {
|
||||
@ -285,7 +283,7 @@ function addNotificationToUnread(state: HarkState, index: NotifIndex, time: BigI
|
||||
_.set(state.unreads.group, path,
|
||||
[
|
||||
...curr.filter(c => !(c.time.eq(time) && notifIdxEqual(c.index, index))),
|
||||
{ time, index}
|
||||
{ time, index }
|
||||
]
|
||||
);
|
||||
}
|
||||
@ -310,10 +308,10 @@ function removeNotificationFromUnread(state: HarkState, index: NotifIndex, time:
|
||||
function updateNotificationStats(state: HarkState, index: NotifIndex, statField: 'unreads' | 'last', f: (x: number) => number) {
|
||||
|
||||
if('graph' in index) {
|
||||
const curr = _.get(state.unreads.graph, [index.graph.graph, index.graph.index, statField], 0);
|
||||
const curr: any = _.get(state.unreads.graph, [index.graph.graph, index.graph.index, statField], 0);
|
||||
_.set(state.unreads.graph, [index.graph.graph, index.graph.index, statField], f(curr));
|
||||
} else if('group' in index) {
|
||||
const curr = _.get(state.unreads.group, [index.group.group, statField], 0);
|
||||
const curr: any = _.get(state.unreads.group, [index.group.group, statField], 0);
|
||||
_.set(state.unreads.group, [index.group.group, statField], f(curr));
|
||||
}
|
||||
}
|
||||
@ -331,9 +329,9 @@ function added(json: any, state: HarkState): HarkState {
|
||||
);
|
||||
if (arrIdx !== -1) {
|
||||
timebox[arrIdx] = { index, notification };
|
||||
state.notifications.set(time, timebox);
|
||||
state.notifications = state.notifications.set(time, timebox);
|
||||
} else {
|
||||
state.notifications.set(time, [...timebox, { index, notification }]);
|
||||
state.notifications = state.notifications.set(time, [...timebox, { index, notification }]);
|
||||
}
|
||||
}
|
||||
return state;
|
||||
@ -352,7 +350,7 @@ const timebox = (json: any, state: HarkState): HarkState => {
|
||||
if (data) {
|
||||
const time = makePatDa(data.time);
|
||||
if (!data.archive) {
|
||||
state.notifications.set(time, data.notifications);
|
||||
state.notifications = state.notifications.set(time, data.notifications);
|
||||
}
|
||||
}
|
||||
return state;
|
||||
@ -361,7 +359,9 @@ const timebox = (json: any, state: HarkState): HarkState => {
|
||||
function more(json: any, state: HarkState): HarkState {
|
||||
const data = _.get(json, 'more', false);
|
||||
if (data) {
|
||||
_.forEach(data, d => reduce(d));
|
||||
_.forEach(data, d => {
|
||||
reduce(d, state);
|
||||
});
|
||||
}
|
||||
return state;
|
||||
}
|
||||
@ -403,7 +403,7 @@ function setRead(
|
||||
return state;
|
||||
}
|
||||
timebox[arrIdx].notification.read = read;
|
||||
state.notifications.set(patDa, timebox);
|
||||
state.notifications = state.notifications.set(patDa, timebox);
|
||||
return state;
|
||||
}
|
||||
|
||||
@ -443,9 +443,9 @@ function archive(json: any, state: HarkState): HarkState {
|
||||
);
|
||||
if(unarchived.length === 0) {
|
||||
console.log('deleting entire timebox');
|
||||
state.notifications.delete(time);
|
||||
state.notifications = state.notifications.delete(time);
|
||||
} else {
|
||||
state.notifications.set(time, unarchived);
|
||||
state.notifications = state.notifications.set(time, unarchived);
|
||||
}
|
||||
}
|
||||
return state;
|
||||
|
@ -18,7 +18,7 @@ export default class LaunchReducer {
|
||||
]);
|
||||
}
|
||||
|
||||
const weatherData: WeatherState = _.get(json, 'weather', false);
|
||||
const weatherData: WeatherState | boolean | Record<string, never> = _.get(json, 'weather', false);
|
||||
if (weatherData) {
|
||||
useLaunchState.getState().set(state => {
|
||||
state.weather = weatherData;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user