diff --git a/.github/workflows/deploy-canary.yml b/.github/workflows/deploy-canary.yml index fe05b7e5..f6aaf406 100644 --- a/.github/workflows/deploy-canary.yml +++ b/.github/workflows/deploy-canary.yml @@ -20,7 +20,7 @@ jobs: uses: "google-github-actions/setup-gcloud@v1" - id: deploy name: Deploy - run: ./.github/helpers/deploy.sh tloncorp/landscape garden binnec-dozzod-marnus us-central1-a mainnet-tlon-other-2d ${{ github.event.inputs.tag }} + run: ./.github/helpers/deploy.sh tloncorp/landscape landscape binnec-dozzod-marnus us-central1-a mainnet-tlon-other-2d ${{ github.event.inputs.tag }} env: SSH_SEC_KEY: ${{ secrets.GCP_SSH_SEC_KEY }} SSH_PUB_KEY: ${{ secrets.GCP_SSH_PUB_KEY }} diff --git a/.github/workflows/deploy-external.yml b/.github/workflows/deploy-external.yml index 4aeaeeb6..d1334f30 100644 --- a/.github/workflows/deploy-external.yml +++ b/.github/workflows/deploy-external.yml @@ -20,7 +20,7 @@ jobs: uses: "google-github-actions/setup-gcloud@v1" - id: deploy name: Deploy - run: ./.github/helpers/deploy.sh tloncorp/landscape garden doznec-dozzod-marnus us-central1-a mainnet-tlon-other-2d ${{ github.event.inputs.tag }} + run: ./.github/helpers/deploy.sh tloncorp/landscape landscape doznec-dozzod-marnus us-central1-a mainnet-tlon-other-2d ${{ github.event.inputs.tag }} env: SSH_SEC_KEY: ${{ secrets.GCP_SSH_SEC_KEY }} SSH_PUB_KEY: ${{ secrets.GCP_SSH_PUB_KEY }} diff --git a/.github/workflows/deploy-internal.yml b/.github/workflows/deploy-internal.yml index d7435f24..8a2b7af8 100644 --- a/.github/workflows/deploy-internal.yml +++ b/.github/workflows/deploy-internal.yml @@ -20,7 +20,7 @@ jobs: uses: "google-github-actions/setup-gcloud@v1" - id: deploy name: Deploy - run: ./.github/helpers/deploy.sh tloncorp/landscape garden marnec-dozzod-marnus us-central1-a mainnet-tlon-other-2d ${{ github.event.inputs.tag }} + run: ./.github/helpers/deploy.sh tloncorp/landscape landscape marnec-dozzod-marnus us-central1-a mainnet-tlon-other-2d ${{ github.event.inputs.tag }} env: SSH_SEC_KEY: ${{ secrets.GCP_SSH_SEC_KEY }} SSH_PUB_KEY: ${{ secrets.GCP_SSH_PUB_KEY }} diff --git a/.github/workflows/deploy-live.yml b/.github/workflows/deploy-live.yml index 89aabcbb..f9a738b1 100644 --- a/.github/workflows/deploy-live.yml +++ b/.github/workflows/deploy-live.yml @@ -9,7 +9,7 @@ on: jobs: deploy: runs-on: ubuntu-latest - name: "Release to ~mister-dister-dozzod-dozzod (livenet)" + name: "Release to ~lander-dister-dozzod-dozzod (livenet)" steps: - uses: actions/checkout@v3 - id: 'auth' @@ -21,7 +21,7 @@ jobs: - id: deploy name: Deploy run: - ./.github/helpers/deploy.sh tloncorp/landscape garden mister-dister-dozzod-dozzod us-central1-b mainnet-tlon-other-2d ${{ github.event.inputs.tag }} + ./.github/helpers/deploy.sh tloncorp/landscape landscape mister-dister-dozzod-dozzod us-central1-b mainnet-tlon-other-2d ${{ github.event.inputs.tag }} env: SSH_SEC_KEY: ${{ secrets.GCP_SSH_SEC_KEY }} SSH_PUB_KEY: ${{ secrets.GCP_SSH_PUB_KEY }} diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 638cd85b..e6525484 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -67,7 +67,7 @@ jobs: deploy: runs-on: ubuntu-latest needs: glob - name: "Deploy a glob to ~wannec-dozzod-marzod (devstream)" + name: "Deploy a glob to ~wannec-dozzod-marnus (devstream)" steps: - uses: actions/checkout@v3 with: @@ -82,7 +82,7 @@ jobs: - id: deploy name: Deploy run: - ./.github/helpers/deploy.sh tloncorp/landscape garden wannec-dozzod-marnus us-central1-a mainnet-tlon-other-2d ${{ github.event.inputs.tag }} + ./.github/helpers/deploy.sh tloncorp/landscape landscape wannec-dozzod-marnus us-central1-a mainnet-tlon-other-2d ${{ github.event.inputs.tag }} env: SSH_SEC_KEY: ${{ secrets.GCP_SSH_SEC_KEY }} SSH_PUB_KEY: ${{ secrets.GCP_SSH_PUB_KEY }} diff --git a/desk-dev/lib/hark-store.hoon b/desk-dev/lib/hark-store.hoon deleted file mode 100644 index 739f6c8e..00000000 --- a/desk-dev/lib/hark-store.hoon +++ /dev/null @@ -1,254 +0,0 @@ -/- sur=hark-store -^? -=, sur -=< [. sur] -|% - -++ enjs - =, enjs:format - |% - ++ update - |= upd=^update - ^- json - %+ frond -.upd - ?+ -.upd a+~ - %added (notification +.upd) - %add-note (add-note +.upd) - %timebox (timebox +.upd) - %more (more +.upd) - %read-each (read-each +.upd) - %read-count (place +.upd) - %unread-each (read-each +.upd) - %unread-count (unread-count +.upd) - %saw-place (saw-place +.upd) - %all-stats (all-stats +.upd) - %del-place (place +.upd) - ::%read-note (index +.upd) - ::%note-read (note-read +.upd) - %archived (archived +.upd) - == - :: - ++ add-note - |= [bi=^bin bo=^body] - %- pairs - :~ bin+(bin bi) - body+(body bo) - == - :: - ++ saw-place - |= [p=^place t=(unit ^time)] - %- pairs - :~ place+(place p) - time+?~(t ~ (time u.t)) - == - :: - ++ archived - |= [t=^time l=^lid n=^notification] - %- pairs - :~ lid+(lid l) - time+s+(scot %ud t) - notification+(notification n) - == - :: - ++ note-read - |= * - (pairs ~) - :: - ++ all-stats - |= places=(map ^place ^stats) - ^- json - :- %a - ^- (list json) - %+ turn ~(tap by places) - |= [p=^place s=^stats] - %- pairs - :~ stats+(stats s) - place+(place p) - == - :: - ++ stats - |= s=^stats - ^- json - %- pairs - :~ each+a+(turn ~(tap in each.s) (cork spat (lead %s))) - last+(time last.s) - count+(numb count.s) - == - ++ more - |= upds=(list ^update) - ^- json - a+(turn upds update) - :: - ++ place - |= =^place - %- pairs - :~ desk+s+desk.place - path+s+(spat path.place) - == - :: - ++ bin - |= =^bin - %- pairs - :~ place+(place place.bin) - path+s+(spat path.bin) - == - ++ notification - |= ^notification - ^- json - %- pairs - :~ time+(time date) - bin+(^bin bin) - body+(bodies body) - == - ++ bodies - |= bs=(list ^body) - ^- json - a+(turn bs body) - :: - ++ contents - |= cs=(list ^content) - ^- json - a+(turn cs content) - :: - ++ content - |= c=^content - ^- json - %+ frond -.c - ?- -.c - %ship s+(scot %p ship.c) - %text s+cord.c - == - :: - ++ body - |= ^body - ^- json - %- pairs - :~ title+(contents title) - content+(contents content) - time+(^time time) - link+s+(spat link) - == - :: - ++ binned-notification - |= [=^bin =^notification] - %- pairs - :~ bin+(^bin bin) - notification+(^notification notification) - == - ++ lid - |= l=^lid - ^- json - %+ frond -.l - ?- -.l - ?(%seen %unseen) ~ - %archive s+(scot %ud time.l) - == - :: - ++ timebox - |= [li=^lid l=(list ^notification)] - ^- json - %- pairs - :~ lid+(lid li) - notifications+a+(turn l notification) - == - :: - ++ read-each - |= [p=^place pax=^path] - %- pairs - :~ place+(place p) - path+(path pax) - == - :: - ++ unread-count - |= [p=^place inc=? count=@ud] - %- pairs - :~ place+(place p) - inc+b+inc - count+(numb count) - == - -- -++ dejs - =, dejs:format - |% - ++ ship (su ;~(pfix sig fed:ag)) - :: TODO: fix +stab - :: - ++ pa - |= j=json - ^- path - ?> ?=(%s -.j) - ?: =('/' p.j) / - (stab p.j) - :: - ++ place - %- ot - :~ desk+so - path+pa - == - :: - ++ bin - %- ot - :~ path+pa - place+place - == - :: - ++ read-each - %- ot - :~ place+place - path+pa - == - :: - :: parse date as @ud - :: TODO: move to zuse - ++ sd - |= jon=json - ^- @da - ?> ?=(%s -.jon) - `@da`(rash p.jon dem:ag) - :: - ++ lid - %- of - :~ archive+sd - unseen+ul - seen+ul - == - :: - ++ archive - %- ot - :~ lid+lid - bin+bin - == - ++ content - %- of - :~ text+so - ship+ship - == - :: - ++ body - %- ot - :~ title+(ar content) - content+(ar content) - time+di - binned+pa - link+pa - == - :: - ++ add-note - %- ot - :~ bin+bin - body+body - == - :: - ++ action - ^- $-(json ^action) - %- of - :~ archive-all+ul - archive+archive - opened+ul - read-count+place - read-each+read-each - read-note+bin - add-note+add-note - == - -- --- diff --git a/desk-dev/sur/hark-store.hoon b/desk-dev/sur/hark-store.hoon deleted file mode 100644 index 0a9acf5f..00000000 --- a/desk-dev/sur/hark-store.hoon +++ /dev/null @@ -1,159 +0,0 @@ -^? -:: -:: %hark-store: Notification, unreads store -:: -:: Timeboxing & binning: -:: -:: Unread notifications accumulate in $unreads. They are grouped by -:: their $bin. A notification may become read by either: -:: a) being read by a %read-count or %read-each or %read-note -:: b) being read by a %seen -:: -:: If a) then we insert the corresponding bin into $reads at the -:: current timestamp -:: If b) then we empty $unreads and move all bins to $reads at the -:: current timestamp -:: -:: Unread tracking: -:: Unread tracking has two 'modes' which may be used concurrently, -:: if necessary. -:: -:: count: -:: This stores the unreads as a simple atom, describing the number -:: of unread items. May be increased with %unread-count and -:: set to zero with %read-count. Ideal for high-frequency linear -:: datastructures, e.g. chat -:: each: -:: This stores the unreads as a set of paths, describing the set of -:: unread items. Unreads may be added to the set with %unread-each -:: and removed with %read-each. Ideal for non-linear, low-frequency -:: datastructures, e.g. blogs -:: -|% -:: $place: A location, under which landscape stores stats -:: -:: .desk must match q.byk.bowl -:: Examples: -:: A chat: -:: [%landscape /~dopzod/urbit-help] -:: A note in a notebook: -:: [%landscape /~darrux-landes/feature-requests/12374893234232] -:: A group: -:: [%hark-group-hook /~bitbet-bolbel/urbit-community] -:: Comments on a link -:: [%landscape /~dabben-larbet/urbit-in-the-news/17014118450499614194868/2] -:: -+$ place [=desk =path] -:: -:: $bin: Identifier for grouping notifications -:: -:: Examples -:: A mention in a chat: -:: [/mention %landscape /~dopzod/urbit-help] -:: New messages in a chat -:: [/message %landscape /~dopzod/urbit-help] -:: A new comment in a notebook: -:: [/comment %landscape /~darrux-landes/feature-requests/12374893234232/2] -:: -+$ bin [=path =place] -:: -:: $lid: Reference to a timebox -:: -+$ lid - $% [%archive =time] - [%seen ~] - [%unseen ~] - == -:: $content: Notification content -+$ content - $% [%ship =ship] - [%text =cord] - == -:: -:: $body: A notification body -:: -+$ body - $: title=(list content) - content=(list content) - =time - binned=path - link=path - == -:: -+$ notification - [date=@da =bin body=(list body)] -:: $timebox: Group of notificatons -+$ timebox - (map bin notification) -:: $archive: Archived notifications, ordered by time -+$ archive - ((mop @da timebox) gth) -:: -+$ action - $% :: hook actions - :: - :: %add-note: add a notification - [%add-note =bin =body] - :: - :: %del-place: Underlying resource disappeared, remove all - :: associated notifications - [%del-place =place] - :: %unread-count: Change unread count by .count - [%unread-count =place inc=? count=@ud] - :: %unread-each: Add .path to list of unreads for .place - [%unread-each =place =path] - :: %saw-place: Update last-updated for .place to now.bowl - [%saw-place =place time=(unit time)] - :: store actions - :: - :: %archive: archive single notification - :: if .time is ~, then archiving unread notification - :: else, archiving read notification - [%archive =lid =bin] - :: %read-count: set unread count to zero - [%read-count =place] - :: %read-each: remove path from unreads for .place - [%read-each =place =path] - :: %read-note: Read note at .bin - [%read-note =bin] - :: %archive-all: Archive all notifications - [%archive-all ~] - :: %opened: User opened notifications, reset timeboxing logic. - :: - [%opened ~] - :: - :: XX: previously in hark-store, now deprecated - :: the hooks responsible for creating notifications may offer pokes - :: similar to this - :: [%read-graph =resource] - :: [%read-group =resource] - :: [%remove-graph =resource] - :: - == -:: .stats: Statistics for a .place -:: -+$ stats - $: count=@ud - each=(set path) - last=@da - timebox=(unit @da) - == -:: -+$ update - $% action - :: %more: more updates - [%archived =time =lid =notification] - [%more more=(list update)] - :: %note-read: note has been read with timestamp - [%note-read =time =bin] - [%added =notification] - :: %timebox: description of timebox. - :: - [%timebox =lid =(list notification)] - :: %place-stats: description of .stats for a .place - [%place-stats =place =stats] - :: %place-stats: stats for all .places - [%all-stats places=(map place stats)] - == --- - diff --git a/desk/app/bark.hoon b/desk/app/bark.hoon index edd03283..f70599fc 100644 --- a/desk/app/bark.hoon +++ b/desk/app/bark.hoon @@ -112,7 +112,7 @@ :_ this :~ :* %pass /save-summary/(scot %p src.bowl)/(scot %da requested.u.result) %arvo %k %fard - %garden %save-summary %noun + %landscape %save-summary %noun !>(`[tlon.api mailchimp.api src.bowl summary.u.result]) == == diff --git a/desk/app/contacts.hoon b/desk/app/contacts.hoon new file mode 100644 index 00000000..eb689989 --- /dev/null +++ b/desk/app/contacts.hoon @@ -0,0 +1,508 @@ +/- *contacts +/+ default-agent, dbug, verb +:: performance, keep warm +/+ contacts-json +:: +|% +:: conventions +:: +:: .con: a contact +:: .rof: our profile +:: .rol: our full rolodex +:: .for: foreign profile +:: .sag: foreign subscription state +:: ++| %types ++$ card card:agent:gall ++$ state-0 [%0 rof=$@(~ profile) rol=rolodex] +-- +:: +%- agent:dbug +%+ verb & +^- agent:gall +=| state-0 +=* state - +:: +=< |_ =bowl:gall + +* this . + def ~(. (default-agent this %|) bowl) + cor ~(. raw bowl) + :: + ++ on-init + ^- (quip card _this) + =^ cards state abet:init:cor + [cards this] + :: + ++ on-save !>([state okay]) + :: + ++ on-load + |= old=vase + ^- (quip card _this) + =^ cards state abet:(load:cor old) + [cards this] + :: + ++ on-watch + |= =path + ^- (quip card _this) + =^ cards state abet:(peer:cor path) + [cards this] + :: + ++ on-poke + |= [=mark =vase] + ^- (quip card _this) + =^ cards state abet:(poke:cor mark vase) + [cards this] + :: + ++ on-peek peek:cor + ++ on-leave on-leave:def + :: + ++ on-agent + |= [=wire =sign:agent:gall] + ^- (quip card _this) + =^ cards state abet:(agent:cor wire sign) + [cards this] + :: + ++ on-arvo on-arvo:def + ++ on-fail on-fail:def + -- +:: +|% +:: ++| %help +:: +++ do-edit + |= [c=contact f=field] + ^+ c + ?- -.f + %nickname c(nickname nickname.f) + %bio c(bio bio.f) + %status c(status status.f) + %color c(color color.f) + :: + %avatar ~| "cannot add a data url to avatar!" + ?> ?| ?=(~ avatar.f) + !=('data:' (end 3^5 u.avatar.f)) + == + c(avatar avatar.f) + :: + %cover ~| "cannot add a data url to cover!" + ?> ?| ?=(~ cover.f) + !=('data:' (end 3^5 u.cover.f)) + == + c(cover cover.f) + :: + %add-group c(groups (~(put in groups.c) flag.f)) + :: + %del-group c(groups (~(del in groups.c) flag.f)) + == +:: +++ mono + |= [old=@da new=@da] + ^- @da + ?: (lth old new) new + (add old ^~((div ~s1 (bex 16)))) +:: ++| %state +:: +:: namespaced to avoid accidental direct reference +:: +++ raw + =| out=(list card) + |_ =bowl:gall + :: + +| %generic + :: + ++ abet [(flop out) state] + ++ cor . + ++ emit |=(c=card cor(out [c out])) + ++ give |=(=gift:agent:gall (emit %give gift)) + ++ pass |=([=wire =note:agent:gall] (emit %pass wire note)) + :: + +| %operations + :: + :: |pub: publication mgmt + :: + :: - /news: local updates to our profile and rolodex + :: - /contact: updates to our profile + :: + :: as these publications are trivial, |pub does *not* + :: make use of the +abet pattern. the only behavior of note + :: is wrt the /contact/at/$date path, which exists to minimize + :: redundant network traffic. + :: + :: /epic protocol versions are even more trivial, + :: published ad-hoc, elsewhere. + :: + ++ pub + => |% + :: if this proves to be too slow, the set of paths + :: should be maintained statefully: put on +p-init:pub, + :: filtered at some interval (on +load?) to avoid a space leak. + :: + ++ subs + ^- (set path) + %- ~(rep by sup.bowl) + |= [[duct ship pat=path] acc=(set path)] + ?.(?=([%contact *] pat) acc (~(put in acc) pat)) + :: + ++ fact + |= [pat=(set path) u=update] + ^- gift:agent:gall + [%fact ~(tap in pat) upd:mar !>(u)] + -- + :: + |% + ++ p-anon ?.(?=([@ ^] rof) cor (p-diff ~)) + :: + ++ p-edit + |= l=(list field) + =/ old ?.(?=([@ ^] rof) *contact con.rof) + =/ new (roll l |=([f=field c=_old] (do-edit c f))) + ?: =(old new) + cor + (p-diff:pub new) + :: + ++ p-diff + |= con=$@(~ contact) + =/ p=profile [?~(rof now.bowl (mono wen.rof now.bowl)) con] + (give:(p-news(rof p) our.bowl con) (fact subs full+p)) + :: + ++ p-init + |= wen=(unit @da) + ?~ rof cor + ?~ wen (give (fact ~ full+rof)) + ?: =(u.wen wen.rof) cor + ?>((lth u.wen wen.rof) (give (fact ~ full+rof))) :: no future subs + :: + ++ p-news |=(n=news (give %fact [/news ~] %contact-news !>(n))) + -- + :: + :: +sub: subscription mgmt + :: + :: /epic: foreign protocol versions, |si-epic:s-impl + :: /contact/*: foreign profiles, |s-impl + :: + :: subscription state is tracked per peer in .sag + :: + :: ~: no subscription + :: %want: /contact/* being attempted + :: %fail: /contact/* failed, /epic being attempted + :: %lost: /epic failed + :: %chi: /contact/* established + :: %lev: we're (incompatibly) ahead of the publisher + :: %dex: we're behind the publisher + :: + :: for a given peer, we always have at most one subscription, + :: to either /contact/* or /epic. + :: + ++ sub + |^ |= who=ship + ^+ s-impl + ?< =(our.bowl who) + =/ old (~(get by rol) who) + ~(. s-impl who %live ?=(~ old) (fall old [~ ~])) + :: + ++ s-many + |= [l=(list ship) f=$-(_s-impl _s-impl)] + ^+ cor + %+ roll l + |= [who=@p acc=_cor] + ?: =(our.bowl who) acc + si-abet:(f (sub:acc who)) + :: + ++ s-impl + |_ [who=ship sas=?(%dead %live) new=? foreign] + :: + ++ si-cor . + :: + ++ si-abet + ^+ cor + ?- sas + %live =. rol (~(put by rol) who for sag) + :: NB: this assumes con.for is only set in +si-hear + :: + ?.(new cor (p-news:pub who ~)) + :: + %dead ?: new cor + =. rol (~(del by rol) who) + :: + :: this is not quite right, reflecting *total* deletion + :: as *contact* deletion. but it's close, and keeps /news simpler + :: + (p-news:pub who ~) + == + :: + ++ si-take + |= =sign:agent:gall + ^+ si-cor + ?- -.sign + %poke-ack ~|(strange-poke-ack+wire !!) + :: + %watch-ack ~| strange-watch-ack+wire + ?> ?=(%want sag) + ?~ p.sign si-cor(sag [%chi ~]) + %- (slog 'contact-fail' u.p.sign) + pe-peer:si-epic(sag %fail) + :: + %kick si-heed + :: + :: [compat] we *should* maintain backcompat here + :: + :: by either directly handling or upconverting + :: old actions. but if we don't, we'll fall back + :: to /epic and wait for our peer to upgrade. + :: + :: %fact's from the future are also /epic, + :: in case our peer downgrades. if not, we'll + :: handle it on +load. + :: + %fact ?+ p.cage.sign (si-odd p.cage.sign) + ?(upd:base:mar %contact-update-0) + (si-hear !<(update q.cage.sign)) + == == + + ++ si-hear + |= u=update + ^+ si-cor + ?: &(?=(^ for) (lte wen.u wen.for)) + si-cor + si-cor(for +.u, cor (p-news:pub who con.u)) + :: + ++ si-meet si-cor :: init key in +si-abet + :: + ++ si-heed + ^+ si-cor + ?. ?=(~ sag) + si-cor + =/ pat [%contact ?~(for / /at/(scot %da wen.for))] + %= si-cor + cor (pass /contact %agent [who dap.bowl] %watch pat) + sag %want + == + :: + ++ si-drop si-snub(sas %dead) + :: + ++ si-snub + %_ si-cor + sag ~ + cor ?+ sag cor + ?(%fail [?(%lev %dex) *]) + (pass /epic %agent [who dap.bowl] %leave ~) + :: + ?(%want [%chi *]) + (pass /contact %agent [who dap.bowl] %leave ~) + == == + :: + ++ si-odd + |= =mark + ^+ si-cor + =* upd *upd:base:mar + =* wid ^~((met 3 upd)) + ?. =(upd (end [3 wid] mark)) + ~&(fake-news+mark si-cor) :: XX unsub? + ?~ ver=(slaw %ud (rsh 3^+(wid) mark)) + ~&(weird-news+mark si-cor) :: XX unsub? + ?: =(okay u.ver) + ~|(odd-not-odd+mark !!) :: oops! + =. si-cor si-snub :: unsub before .sag update + =. sag ?:((lth u.ver okay) [%lev ~] [%dex u.ver]) + pe-peer:si-epic + :: + ++ si-epic + |% + ++ pe-take + |= =sign:agent:gall + ^+ si-cor + ?- -.sign + %poke-ack ~|(strange-poke-ack+wire !!) + :: + %watch-ack ?~ p.sign si-cor + %- (slog 'epic-fail' u.p.sign) + si-cor(sag %lost) + :: + %kick ?. ?=(?(%fail [?(%dex %lev) *]) sag) + si-cor :: XX strange + pe-peer + :: + %fact ?+ p.cage.sign + ~&(fact-not-epic+p.cage.sign si-cor) + %epic (pe-hear !<(epic q.cage.sign)) + == == + :: + ++ pe-hear + |= =epic + ^+ si-cor + ?. ?=(?(%fail [?(%dex %lev) *]) sag) + ~|(strange-epic+[okay epic] !!) :: get %kick'd + ?: =(okay epic) + ?: ?=(%fail sag) + si-cor(sag %lost) :: abandon hope + si-heed:si-snub + :: + :: handled generically to support peer downgrade + :: + si-cor(sag ?:((gth epic okay) [%dex epic] [%lev ~])) + :: + ++ pe-peer + si-cor(cor (pass /epic %agent [who dap.bowl] %watch /epic)) + -- + -- + -- + :: +migrate: from :contact-store + :: + :: all known ships, non-default profiles, no subscriptions + :: + ++ migrate + => |% + ++ legacy + |% + +$ rolodex (map ship contact) + +$ resource [=entity name=term] + +$ entity ship + +$ contact + $: nickname=@t + bio=@t + status=@t + color=@ux + avatar=(unit @t) + cover=(unit @t) + groups=(set resource) + last-updated=@da + == + -- + -- + :: + ^+ cor + =/ bas /(scot %p our.bowl)/contact-store/(scot %da now.bowl) + ?. .^(? gu+(weld bas /$)) cor + =/ ful .^(rolodex:legacy gx+(weld bas /all/noun)) + :: + |^ cor(rof us, rol them) + ++ us (biff (~(get by ful) our.bowl) convert) + :: + ++ them + ^- rolodex + %- ~(rep by (~(del by ful) our.bowl)) + |= [[who=ship con=contact:legacy] rol=rolodex] + (~(put by rol) who (convert con) ~) + :: + ++ convert + |= con=contact:legacy + ^- $@(~ profile) + ?: =(*contact:legacy con) ~ + [last-updated.con con(|6 groups.con)] + -- + :: + +| %implementation + :: + ++ init + (emit %pass /migrate %agent [our dap]:bowl %poke noun+!>(%migrate)) + :: + ++ load + |= old-vase=vase + ^+ cor + |^ =+ !<([old=versioned-state cool=epic] old-vase) + =. state + ?- -.old + %0 old + == + :: [compat] if our protocol version changed + :: + :: we first tell the world, then see if we can now understand + :: any of our friends who were sending messages from the future. + :: + ?:(=(okay cool) cor l-bump(cor l-epic)) + :: + +$ versioned-state + $% state-0 + == + :: + ++ l-epic (give %fact [/epic ~] epic+!>(okay)) + :: + ++ l-bump + ^+ cor + %- ~(rep by rol) + |= [[who=ship foreign] =_cor] + :: XX to fully support downgrade, we'd need to also + :: save an epic in %lev + :: + ?. ?& ?=([%dex *] sag) + =(okay ver.sag) + == + cor + si-abet:si-heed:si-snub:(sub:cor who) + -- + :: + ++ poke + |= [=mark =vase] + ^+ cor + :: [compat] we *should* maintain backcompat here + :: + :: by either directly handling or upconverting old actions + :: + ?+ mark ~|(bad-mark+mark !!) + %noun + ?+ q.vase !! + %migrate migrate + == + :: + ?(act:base:mar %contact-action-0) + ?> =(our src):bowl + =/ act !<(action vase) + ?- -.act + %anon p-anon:pub + %edit (p-edit:pub p.act) + %meet (s-many:sub p.act |=(s=_s-impl:sub si-meet:s)) + %heed (s-many:sub p.act |=(s=_s-impl:sub si-heed:s)) + %drop (s-many:sub p.act |=(s=_s-impl:sub si-drop:s)) + %snub (s-many:sub p.act |=(s=_s-impl:sub si-snub:s)) + == + == + :: + ++ peek + |= pat=(pole knot) + ^- (unit (unit cage)) + ?+ pat [~ ~] + [%x %all ~] + =/ lor=rolodex + ?: |(?=(~ rof) ?=(~ con.rof)) rol + (~(put by rol) our.bowl rof ~) + ``contact-rolodex+!>(lor) + :: + [%x %contact her=@ ~] + ?~ who=`(unit @p)`(slaw %p her.pat) + [~ ~] + =/ tac=?(~ contact) + ?: =(our.bowl u.who) ?~(rof ~ con.rof) + =+ (~(get by rol) u.who) + ?: |(?=(~ -) ?=(~ for.u.-)) ~ + con.for.u.- + ?~ tac [~ ~] + ``contact+!>(`contact`tac) + == + :: + ++ peer + |= pat=(pole knot) + ^+ cor + ?+ pat ~|(bad-watch-path+pat !!) + [%contact %at wen=@ ~] (p-init:pub `(slav %da wen.pat)) + [%contact ~] (p-init:pub ~) + [%epic ~] (give %fact ~ epic+!>(okay)) + [%news ~] ~|(local-news+src.bowl ?>(=(our src):bowl cor)) + == + :: + ++ agent + |= [=wire =sign:agent:gall] + ^+ cor + ?+ wire ~|(evil-agent+wire !!) + [%contact ~] si-abet:(si-take:(sub src.bowl) sign) + [%epic ~] si-abet:(pe-take:si-epic:(sub src.bowl) sign) + :: + [%migrate ~] + ?> ?=(%poke-ack -.sign) + ?~ p.sign cor + %- (slog leaf/"{} failed" u.p.sign) + cor + == + -- +-- diff --git a/desk/app/docket.hoon b/desk/app/docket.hoon index 9d0f6151..a4596758 100644 --- a/desk/app/docket.hoon +++ b/desk/app/docket.hoon @@ -174,11 +174,9 @@ =^ cards state ?+ path (on-watch:def path) [%http-response *] - ?> (team:title [our src]:bowl) `state :: [%charges ~] - ?> (team:title [our src]:bowl) `state :: [%glob @ @ ~] @@ -506,7 +504,7 @@ :: ++ handle-get-request ^- simple-payload:http - ?+ [site ext]:req-line (redirect:gen '/apps/grid/') + ?+ [site ext]:req-line (redirect:gen '/apps/landscape/') [[%session ~] [~ %js]] %- inline-js-response (rap 3 'window.ship = "' (rsh 3 (scot %p our.bowl)) '";' ~) diff --git a/desk/app/hark-store.hoon b/desk/app/hark-store.hoon deleted file mode 100644 index f1f8fead..00000000 --- a/desk/app/hark-store.hoon +++ /dev/null @@ -1,550 +0,0 @@ -:: hark-store: notifications and unread counts [landscape] -:: -:: hark-store can store unread counts differently, depending on the -:: resource. -:: - last seen. This way, hark-store simply stores an index into -:: graph-store, which represents the last "seen" item, useful for -:: high-volume applications which are intrinsically time-ordered. i.e. -:: chats, comments -:: - each. Hark-store will store an index for each item that is unread. -:: Usefull for non-linear, low-volume applications, i.e. blogs, -:: collections -:: -/- store=hark-store -/+ verb, dbug, default-agent, re=hark-unreads, agentio -:: -:: -~% %hark-store-top ..part ~ -|% -+$ card card:agent:gall -+$ versioned-state - $% state-2 - state-3 - state-4 - state-5 - state-6 - state-7 - state-8 - state-9 - == -:: -+$ base-state - $: places=(map place:store stats:store) - seen=timebox:store - unseen=timebox:store - =archive:store - half-open=(map bin:store @da) - == -:: -+$ state-2 - [%2 *] -:: -+$ state-3 - [%3 *] -:: -+$ state-4 - [%4 *] -:: -+$ state-5 - [%5 *] -:: -+$ state-6 - [%6 *] -:: -+$ state-7 - [%7 *] -:: -+$ state-8 - [%8 base-state] -:: -+$ state-9 - [%9 base-state] -:: -:: -+$ cached-state - $: by-place=(jug place:store [=lid:store =path]) - ~ - == -+$ inflated-state - [state-9 cached-state] -:: -++ orm ((ordered-map @da timebox:store) gth) --- -:: -=| inflated-state -=* state - -:: -=< -%+ verb | -%- agent:dbug -^- agent:gall -~% %hark-store-agent ..card ~ -|_ =bowl:gall -+* this . - ha ~(. +> bowl) - def ~(. (default-agent this %|) bowl) - io ~(. agentio bowl) - pass pass:io -:: -++ on-init - `this -:: -++ on-save !>(-.state) -++ on-load - |= =old=vase - =/ old - !<(versioned-state old-vase) - =| cards=(list card) - |- ^- (quip card _this) - ?+ -.old - :: pre-dist migration - :_ this - (poke-our:pass %hark-graph-hook hark-graph-migrate+old-vase)^~ - :: - %9 - =. -.state old - =. +.state inflate:ha - :_(this (flop cards)) - :: - %8 - $(-.old %9, archive.old *archive:store) - == -:: -++ on-watch - |= =path - ^- (quip card _this) - ?> (team:title [src our]:bowl) - |^ - ?+ path (on-watch:def path) - [%notes ~] `this - :: - [%updates ~] - :_ this - [%give %fact ~ hark-update+!>(initial-updates)]~ - :: - == - :: - ++ initial-updates - ^- update:store - :- %more - ^- (list update:store) - :~ [%timebox unseen+~ ~(val by unseen)] - [%timebox seen+~ ~(val by seen)] - [%all-stats places] - == - -- -:: -++ on-peek - ~/ %hark-store-peek - |= =path - ^- (unit (unit cage)) - ?+ path (on-peek:def path) - :: - [%x %recent %inbox @ @ ~] - =/ date=@da - (slav %ud i.t.t.t.path) - =/ length=@ud - (slav %ud i.t.t.t.t.path) - :^ ~ ~ %hark-update - !> ^- update:store - :- %more - %+ turn (tab:orm archive `date length) - |= [time=@da =timebox:store] - ^- update:store - [%timebox archive+time ~(val by timebox)] - :: - [%x %all-stats ~] - :^ ~ ~ %hark-update - !> ^- update:store - :- %more - ^- (list update:store) - :~ [%all-stats places] - == - == -:: -++ on-poke - ~/ %hark-store-poke - |= [=mark =vase] - ^- (quip card _this) - |^ - ?> (team:title our.bowl src.bowl) - =^ cards state - ?+ mark (on-poke:def mark vase) - %hark-action (hark-action !<(action:store vase)) - %noun (poke-noun !<(* vase)) - == - [cards this] - :: - ++ poke-noun - |= val=* - ?+ val ~|(%bad-noun-poke !!) - %print ~&(+.state [~ state]) - %clear [~ state(. *inflated-state)] - %sane - ~& +.state - ~& inflate - ?>(=(+.state inflate) `state) - == - :: - ++ poke-us - |= =action:store - ^- card - [%pass / %agent [our dap]:bowl %poke hark-action+!>(action)] - :: - ++ hark-action - |= =action:store - ^- (quip card _state) - abet:(abed:poke-engine:ha action) - -- -:: -++ on-agent on-agent:def -:: -++ on-leave on-leave:def -++ on-arvo - |= [=wire =sign-arvo] - ^- (quip card _this) - ?. ?=([%autoseen ~] wire) - (on-arvo:def wire sign-arvo) - `this -:: -++ on-fail on-fail:def --- -|_ =bowl:gall -+* met ~(. metadata bowl) - io ~(. agentio bowl) - pass pass:io -++ poke-engine - |_ [out=(list update:store) cards=(list card)] - ++ poke-core . - :: - ++ abed - |= in=action:store - ^+ poke-core - ?- -.in - :: - %add-note (add-note +.in) - %del-place (del-place +.in) - %archive (do-archive +.in) - :: - %unread-count (unread-count +.in) - %read-count (read-count +.in) - :: - %read-each (read-each +.in) - %unread-each (unread-each +.in) - :: - %read-note (read-note +.in) - :: - %saw-place (saw-place +.in) - :: - %opened opened - %archive-all archive-all - :: - == - :: - ++ abet - ^- (quip card _state) - :_ state - %+ snoc (flop cards) - [%give %fact ~[/updates] %hark-update !>([%more (flop out)])] - :: - ++ give |=(=update:store poke-core(out [update out])) - ++ emit |=(=card poke-core(cards [card cards])) - :: - :: - :: +| %note - :: - :: notification tracking - ++ put-notifs - |= [time=@da =timebox:store] - poke-core(archive (put:orm archive time timebox)) - :: - ++ put-lid - |= [=lid:store =bin:store =notification:store] - ^+ poke-core - =. by-place (~(put ju by-place) place.bin [lid path.bin]) - ?- -.lid - %seen - poke-core(seen (~(put by seen) bin notification)) - :: - %unseen - poke-core(unseen (~(put by unseen) bin notification)) - :: - %archive - poke-core(archive (~(put re archive) time.lid bin notification)) - == - :: - ++ del-lid - |= [=lid:store =bin:store] - =. by-place (~(del ju by-place) place.bin [lid path.bin]) - ?- -.lid - %seen poke-core(seen (~(del by seen) bin)) - %unseen poke-core(unseen (~(del by unseen) bin)) - %archive poke-core(archive (~(del re archive) time.lid bin)) - == - :: - ++ add-note - |= [=bin:store =body:store] - ^+ poke-core - =. poke-core - (emit (fact:io hark-update+!>([%add-note bin body]) /notes ~)) - =/ existing-notif - (~(gut by unseen) bin *notification:store) - =/ new=notification:store - [now.bowl bin [body body.existing-notif]] - =. poke-core - (put-lid unseen/~ bin new) - (give %added new) - :: - ++ del-place - |= =place:store - =. poke-core (give %del-place place) - =/ notes=(list [=lid:store =path]) - ~(tap in (~(get ju by-place) place)) - |- ^+ poke-core - ?~ notes poke-core - =, i.notes - =. poke-core - (del-lid lid path place) - $(notes t.notes) - :: - ++ do-archive - |= [=lid:store =bin:store] - ^+ poke-core - ~| %already-archived - ?< ?=(%time -.lid) - ~| %non-existent - =/ =notification:store (need (get-lid lid bin)) - =. poke-core (del-lid lid bin) - =. poke-core (put-lid archive+now.bowl bin notification) - (give %archived now.bowl lid notification) - :: - ++ read-note - |= =bin:store - =/ =notification:store - (~(got by unseen) bin) - =. poke-core - (del-lid unseen/~ bin) - =/ =time - (fall timebox:(gut-place place.bin) now.bowl) - =. date.notification time - =. poke-core - (put-lid archive/time bin notification) - (give %note-read time bin) - :: - :: - :: +| %each - :: - :: each unread tracking - :: - ++ unread-each - |= [=place:store =path] - =. poke-core (saw-place place ~) - =. poke-core (give %unread-each place path) - %+ jub-place place - |=(=stats:store stats(each (~(put in each.stats) path))) - :: - ++ read-index-each - |= [=place:store =path] - %- read-bins - %+ skim - ~(tap in ~(key by unseen)) - |= =bin:store - ?. =(place place.bin) %.n - =/ not=notification:store - (~(got by unseen) bin) - (lien body.not |=(=body:store =(binned.body path))) - :: - ++ read-each - |= [=place:store =path] - =. poke-core (read-index-each place path) - =. poke-core (give %read-each place path) - %+ jub-place place - |= =stats:store - %_ stats - timebox `now.bowl - each (~(del in each.stats) path) - == - :: - ++ gut-place - |= =place:store - ?: (~(has by places) place) (~(got by places) place) - =| def=stats:store - def(timebox ~, last now.bowl) - :: - ++ jub-place - |= $: =place:store - f=$-(stats:store stats:store) - == - ^+ poke-core - =/ =stats:store - (gut-place place) - poke-core(places (~(put by places) place (f stats))) - :: - ++ unread-count - |= [=place:store inc=? count=@ud] - =. poke-core - (give %unread-count place inc count) - =. poke-core (saw-place place ~) - =/ f - ?: inc (cury add count) - (curr sub count) - %+ jub-place place - |= =stats:store - stats(count (f count.stats)) - :: - ++ half-archive - |= =place:store - =/ bins=(list [=lid:store =path]) - ~(tap in (~(get ju by-place) place)) - |- - ?~ bins poke-core - =/ =bin:store - [path.i.bins place] - =* lid lid.i.bins - ?: ?=(%archive -.lid) - $(bins t.bins) - =/ seen-place (~(get by seen) bin) - =/ n=(unit notification:store) (get-lid lid bin) - ?~ n $(bins t.bins) - =* note u.n - =/ =time (~(gut by half-open) bin now.bowl) - =? half-open !(~(has by half-open) bin) - (~(put by half-open) bin now.bowl) - =/ existing (get-lid archive/time bin) - =/ new (merge-notification existing note) - =? half-open (lth 30 (lent body.new)) - (~(del by half-open) bin) - =. poke-core - (put-lid archive/time bin new) - =. poke-core (del-lid lid bin) - =. poke-core (give %archived time lid (~(got re archive) time bin)) - $(bins t.bins) - :: - ++ read-count - |= =place:store - =. poke-core (give %read-count place) - =. poke-core (half-archive place) - %+ jub-place place - |= =stats:store - stats(count 0, timebox `now.bowl) - :: - ++ read-bins - |= bins=(list bin:store) - |- - ?~ bins poke-core - =/ core - (read-note i.bins) - $(poke-core core, bins t.bins) - :: - ++ saw-place - |= [=place:store time=(unit time)] - =. poke-core (give %saw-place place time) - %+ jub-place place - |=(=stats:store stats(last (fall time now.bowl))) - :: - ++ archive-seen - =/ seen=(list [=bin:store =notification:store]) ~(tap by seen) - poke-core - :: - ++ opened - =. poke-core (turn-places |=(=stats:store stats(timebox ~))) - =. poke-core (give %opened ~) - %+ roll ~(tap in ~(key by unseen)) - |= [=bin:store out=_poke-core] - (opened-note:out bin) - :: - ++ opened-note - |= =bin:store - ^+ poke-core - =/ old - (~(got by unseen) bin) - =. poke-core - (del-lid unseen/~ bin) - =/ se (~(get by seen) bin) - %^ put-lid seen/~ bin - (merge-notification se old) - :: - ++ archive-all - |^ - =. poke-core (archive-lid unseen/~ unseen) - (archive-lid seen/~ seen) - ++ archive-lid - |= [=lid:store =timebox:store] - %+ roll ~(tap in ~(key by timebox)) - |= [=bin:store out=_poke-core] - (do-archive:out lid bin) - -- - :: - ++ turn-places - |= f=$-(stats:store stats:store) - =/ places ~(tap in ~(key by places)) - |- ^+ poke-core - ?~ places poke-core - =/ core=_poke-core (jub-place i.places f) - $(poke-core core, places t.places) - -- -:: -++ get-lid - |= [=lid:store =bin:store] - =; =timebox:store - (~(get by timebox) bin) - ?- -.lid - %unseen unseen - %seen seen - %archive (fall (get:orm archive time.lid) *timebox:store) - == -:: -++ merge-notification - |= [existing=(unit notification:store) new=notification:store] - ^- notification:store - ?~ existing new - [(max date.u.existing date.new) bin.new (welp body.new body.u.existing)] -:: -:: +key-orm: +key:by for ordered maps -++ key-orm - |= =archive:store - ^- (list @da) - (turn (tap:orm archive) |=([@da *] +<-)) -:: -:: +gut-orm: +gut:by for ordered maps -:: TODO: move to zuse.hoon -++ gut-orm - |= [=archive:store time=@da] - ^- timebox:store - (fall (get:orm archive time) ~) -:: -:: -++ scry - |* [=mold p=path] - ?> ?=(^ p) - ?> ?=(^ t.p) - .^(mold i.p (scot %p our.bowl) i.t.p (scot %da now.bowl) t.t.p) -:: -++ give - |= [paths=(list path) update=update:store] - ^- (list card) - [%give %fact paths [%hark-update !>(update)]]~ -:: -++ tap-nonempty - |= =archive:store - ^- (list [@da timebox:store]) - %+ skim (tap:orm archive) - |=([@da =timebox:store] !=(~(wyt by timebox) 0)) -:: -++ inflate - =. by-place ~ - =. by-place (index-timebox seen+~ seen by-place) - =. by-place (index-timebox unseen+~ unseen by-place) - =. by-place - %+ roll (tap:orm archive) - |= [[=time =timebox:store] out=_by-place] - (index-timebox archive/time timebox out) - +.state -:: -++ index-timebox - |= [=lid:store =timebox:store out=_by-place] - ^+ by-place - %+ roll ~(tap by timebox) - |= [[=bin:store =notification:store] out=_out] - (~(put ju out) place.bin [lid path.bin]) --- diff --git a/desk/app/hark-system-hook.hoon b/desk/app/hark-system-hook.hoon deleted file mode 100644 index e4c49946..00000000 --- a/desk/app/hark-system-hook.hoon +++ /dev/null @@ -1,208 +0,0 @@ -/- hark=hark-store, hood, docket -/+ verb, dbug, default-agent, agentio -|% -+$ card card:agent:gall -+$ state-1 [%1 lagging=_|] -:: -++ lag-interval ~m10 --- -%+ verb | -%- agent:dbug -^- agent:gall -=| state-1 -=* state - -=< -|_ =bowl:gall -+* this . - def ~(. (default-agent this %|) bowl) - io ~(. agentio bowl) - pass pass:io - cc ~(. +> bowl) -++ on-init - ^- (quip card _this) - :_ this - [onboard tire:cy check:lag ~]:cc -:: -++ on-load - |= =vase - ^- (quip card _this) - |^ - =+ !<(old=app-states vase) - =^ cards-1 old - ?. ?=(%0 -.old) `old - [[tire:cy:cc]~ old(- %1)] - ?> ?=(%1 -.old) - =/ cards-tire [tire:cy:cc ~] - [(weld cards-1 cards-tire) this(state old)] - :: - +$ app-states $%(state-0 state-1) - +$ state-0 [%0 lagging=_|] - -- -:: -++ on-save !>(state) -++ on-poke on-poke:def -++ on-peek on-peek:def -++ on-watch on-watch:def -++ on-agent - |= [=wire =sign:agent:gall] - ^- (quip card _this) - ?+ wire (on-agent:def wire sign) - [%kiln %vats ~] `this - == -:: -++ on-arvo - |= [=wire sign=sign-arvo] - ^- (quip card _this) - |^ - ?+ wire (on-arvo:def wire sign) - [%clay %tire ~] take-clay-tire - [%clay %warp * ~] (take-clay-warp i.t.t.wire) - [%check-lag ~] take-check-lag - == - :: - ++ take-check-lag - ^- (quip card _this) - ?> ?=([%behn %wake *] sign) - =+ .^(lag=? %$ (scry:io %$ /zen/lag)) - ?: =(lagging lag) :_(this ~[check:lag:cc]) - :_ this(lagging lag) - :_ ~[check:lag:cc] - ?:(lagging start:lag:cc stop:lag:cc) - :: - ++ take-clay-tire - ^- (quip card _this) - ?> ?=(%tire +<.sign) - ?- -.p.sign - %& [(turn ~(tap in ~(key by p.p.sign)) warp:cy:cc) this] - %| - ?- -.p.p.sign - %zest `this - %warp `this - %wait - =/ =action:hark (~(blocked de:cc desk.p.p.sign) weft.p.p.sign) - :_ this - ~[(poke:ha:cc action)] - == - == - :: - ++ take-clay-warp - |= =desk - ^- (quip card _this) - ?> ?=(%writ +<.sign) - =/ cards - ?. |(=(desk %base) ~(has-docket de:cc desk)) ~ - =/ =action:hark ~(commit de:cc desk) - ~[(poke:ha:cc action)] - [[(warp:cy:cc desk) cards] this] - -- -:: -++ on-fail on-fail:def -++ on-leave on-leave:def --- -|_ =bowl:gall -+* io ~(. agentio bowl) - pass pass:io -:: -++ onboard - ^- card - %- poke:ha - :+ %add-note [/ [q.byk.bowl /onboard]] - :: We special case this in the grid UI, but should include something - :: for third parties - [~[text+'Welcome to urbit'] ~ now.bowl / /] -:: -++ lag - |% - ++ check (~(wait pass /check-lag) (add now.bowl lag-interval)) - ++ place [q.byk.bowl /lag] - ++ body `body:hark`[~[text/'Runtime lagging'] ~ now.bowl / /] - ++ start (poke:ha %add-note [/ place] body) - ++ stop (poke:ha %del-place place) - -- -++ ha - |% - ++ pass ~(. ^pass /hark) - ++ poke - |=(=action:hark (poke-our:pass %hark-store hark-action+!>(action))) - -- -:: -++ cy - |% - ++ tire ~(tire pass /clay/tire) - ++ warp - |= =desk - (~(warp-our pass /clay/warp/[desk]) desk ~ %next %z da+now.bowl /) - -- -:: -++ de - |_ =desk - ++ scry-path (scry:io desk /desk/docket-0) - ++ has-docket .^(? %cu scry-path) - ++ docket .^(docket:^docket %cx scry-path) - ++ hash .^(@uv %cz (scry:io desk ~)) - ++ place `place:hark`[q.byk.bowl /desk/[desk]] - ++ version ud:.^(cass:clay %cw (scry:io desk /)) - ++ body - |= [=path title=cord content=(unit cord)] - ^- body:hark - [~[text+title] ?~(content ~ ~[text/u.content]) now.bowl ~ path] - :: - :: - ++ title-prefix - |= =cord - %+ rap 3 - ?: =(desk %base) - ['System software' cord ~] - ?: has-docket - ['App: "' title:docket '"' cord ~] - ['Desk: ' desk cord ~] - :: - ++ get-version - ?: has-docket - (rap 3 'version: ' (ver version:docket) ~) - (rap 3 'hash: ' (scot %uv hash) ~) - :: - ++ commit - ^- action:hark - ?:(=(1 version) created updated) - :: - ++ created - ^- action:hark - :+ %add-note [/created place] - (body /desk/[desk] (title-prefix ' has been installed') ~) - :: - ++ updated - ^- action:hark - :+ %add-note [/update place] - (body /desk/[desk] (title-prefix (rap 3 ' has been updated to ' get-version ~)) ~) - :: - ++ blocked - |= =weft - ^- action:hark - :+ %add-note [/blocked place] - %^ body /blocked (title-prefix ' is blocked from upgrading') - `(rap 3 'Blocked waiting for system version: ' (scot %ud num.weft) 'K' ~) - :: - ++ ver - |= =version:^docket - =, version - `@t`(rap 3 (num major) '.' (num minor) '.' (num patch) ~) - :: - ++ num - |= a=@ud - `@t`(rsh 4 (scot %ui a)) - -- -++ note - |% - ++ merge - |= [=desk hash=@uv] - ^- (list body:hark) - :_ ~ - :* ~[text+'Desk Updated'] - ~[text+(crip "Desk {(trip desk)} has been updated to hash {(scow %uv hash)}")] - now.bowl - /update/[desk] - / - == - -- --- diff --git a/desk/app/hark.hoon b/desk/app/hark.hoon new file mode 100644 index 00000000..77daa6d6 --- /dev/null +++ b/desk/app/hark.hoon @@ -0,0 +1,427 @@ +/- h=hark +/+ default-agent, verb, dbug +/+ mp=mop-extensions +:: performance, keep warm +/+ hark-json +|% ++$ card card:agent:gall +++ mope ((mp @ud thread:h) lte) +++ yarns-per-update 3 +++ rug-trim-size 10 +++ blanket-size 10 :: page size for blankets +++ gc-interval ~h24 +:: TODO: move to stdlib +++ zip + |* [a=(list) b=(list)] + ^- (list _?>(?=(^ a) ?>(?=(^ b) [i.a i.b]))) + ?~ a ~ + ?~ b ~ + :- [i.a i.b] + $(a t.a, b t.b) +:: +++ quilt-idx + |= =quilt:h + ?~ tal=(ram:on:quilt:h quilt) + 0 + +(key.u.tal) +:: ++$ state-0 + $: %0 + yarns=(map id:h yarn:h) + groups=(map flag:h rug:h) + desks=(map desk rug:h) + all=rug:h + next-gc=@da + == +-- +%- agent:dbug +%+ verb | +=| state-0 +=* state - +=< + |_ =bowl:gall + +* this . + cor ~(. +> [bowl ~]) + def ~(. (default-agent this %|) bowl) + ++ on-init + =^ cards state + abet:set-gc-wake:cor + [cards this] + ++ on-save !>(state) + ++ on-load + |= =vase + =/ old=(unit state-0) + (mole |.(!<(state-0 vase))) + ?~ old on-init + `this(state u.old) + ++ on-poke + |= [=mark =vase] + =^ cards state + abet:(poke:cor mark vase) + [cards this] + ++ on-watch + |= =path + =^ cards state + abet:(watch:cor path) + [cards this] + ++ on-peek peek:cor + ++ on-arvo + |= [=wire sign=sign-arvo] + =^ cards state + abet:(arvo:cor wire sign) + [cards this] + ++ on-agent + |= [=wire =sign:agent:gall] + =^ cards state + abet:(agent:cor wire sign) + [cards this] + ++ on-leave on-leave:def + ++ on-fail on-fail:def + -- +|_ [=bowl:gall cards=(list card)] +++ abet [(flop cards) state] +++ cor . +++ emit |=(=card cor(cards [card cards])) +++ poke + |= [=mark =vase] + ^+ cor + ?+ mark ~|(bad-mark/mark !!) + %hark-action + =+ !<(act=action:h vase) + =. cor (give-ui act) + ?- -.act + %saw-rope (saw-rope rope.act) + %saw-seam (saw-seam seam.act) + %add-yarn (add-yarn +.act) + == + :: + %hark-action-1 + =+ !<(act=action-1:h vase) + ?+ -.act $(mark %hark-action) + %new-yarn + =/ =action:h + :* %add-yarn + all.act + desk.act + :* (end [7 1] (shax eny.bowl)) + rop.act + now.bowl + con.act + wer.act + but.act + == + == + $(mark %hark-action, vase !>(action)) + == + == +++ peek + |= =(pole knot) + ^- (unit (unit cage)) + ?+ pole [~ ~] + :: + [%x %all rest=*] (scry-rug rest.pole all/~ all) + :: + [%x %group ship=@ name=@ rest=*] + =/ =ship (slav %p ship.pole) + =/ =flag:h [ship name.pole] + =/ =rug:h (~(got by groups) flag) + (scry-rug rest.pole group/flag rug) + :: + [%x %desk desk=@ rest=*] + (scry-rug rest.pole desk/desk.pole (~(gut by desks) desk.pole *rug:h)) + :: + [%x %yarn uid=@ ~] + ``hark-yarn+!>((~(got by yarns) (slav %uv uid.pole))) + == +:: +++ is-us =(our src):bowl +:: +++ watch + |= =path + ^+ cor + ?+ path ~|(evil-watch/path !!) + [%ui ~] ?>(is-us cor) + == +:: +++ arvo + |= [=wire sign=sign-arvo] + ^+ cor + ?+ wire ~|(bad-arvo-take/wire !!) + [%gc ~] + =. cor stale + set-gc-wake + == +++ agent + |= [=wire =sign:agent:gall] + ^+ cor + cor +:: +++ scry-rug + |= [=(pole knot) =seam:h =rug:h] + ^- (unit (unit cage)) + ?+ pole [~ ~] + [%skeins ~] ``hark-skeins+!>((rug-to-skeins seam rug)) + [%latest ~] ``hark-carpet+!>((rug-to-carpet seam rug)) + :: + [%quilt idx=@ ~] + =/ idx (slav %ud idx.pole) + ``hark-blanket+!>((rug-to-blanket seam idx rug)) + == +++ rug-to-skeins + |= [=seam:h =rug:h] + ^- (list skein:h) + %+ welp + %+ turn + ~(tap by new.rug) + |= [* =thread:h] + (thread-to-skein thread &) + %+ turn + (top:mope qul.rug blanket-size) + |= [* =thread:h] + (thread-to-skein thread |) +:: +++ thread-to-skein + |= [=thread:h unread=?] + =/ yrns=(list yarn:h) + %+ sort + (turn (thread-to-yarns thread) tail) + |= [a=yarn:h b=yarn:h] + (gth tim.a tim.b) + =/ top=yarn:h (head yrns) + ^- skein:h + :* tim.top + (lent yrns) + (ship-count yrns) + top + unread + == +:: +++ ship-count + |= yrns=(list yarn:h) + ^- @ud + %~ wyt in + %+ roll + yrns + |= [=yarn:h ships=(set ship)] + %- ~(gas in ships) + ^- (list ship) + %+ murn + con.yarn + |= =content:h + ^- (unit ship) + ?@ content ~ + ?+ -.content ~ + %ship (some p.content) + == +:: +++ rug-to-carpet + |= [=seam:h =rug:h] + ^- carpet:h + =- [seam - new.rug (quilt-idx qul.rug)] + %- ~(gas by *(map id:h yarn:h)) + %- zing + %+ turn ~(tap by new.rug) + |= [=rope:h =thread:h] + ^- (list [id:h yarn:h]) + (thread-to-yarns thread) + :: +++ thread-to-yarns + |= =thread:h + ^- (list [id:h yarn:h]) + %+ murn ~(tap in thread) + |= =id:h + ^- (unit [id:h yarn:h]) + ?~ yar=(~(get by yarns) id) + ~ + `[id u.yar] +:: +++ index-quilt + |= [=quilt:h idx=@ud] + (gas:on:quilt:h *quilt:h (bat:mope quilt `idx blanket-size)) +:: +++ rug-to-blanket + |= [=seam:h idx=@ud =rug:h] + ^- blanket:h + =/ indexed + (index-quilt qul.rug idx) + =/ yarns=(map id:h yarn:h) + %- ~(gas by *(map id:h yarn:h)) + %- zing + %+ turn (tap:on:quilt:h indexed) + |= [num=@ud =thread:h] + (thread-to-yarns thread) + [seam yarns indexed] +:: +++ set-gc-wake + =. next-gc (add now.bowl gc-interval) + (emit %pass /gc %arvo %b %wait next-gc) +:: +++ give-ui + |= =action:h + ^+ cor + (emit %give %fact ~[/ui] hark-action+!>(action)) +:: +++ threads-to-update + |= [=seam:h teds=(map @ thread:h)] + ^- * + =- [- seam teds] + ^- (map id:h yarn:h) + %- ~(gas by *(map id:h yarn:h)) + %- zing + %+ turn ~(tap by teds) + |= [=time =thread:h] + %+ scag yarns-per-update + %+ murn ~(tap in thread) + |= =id:h + ^- (unit [id:h yarn:h]) + ?~ yar=(~(get by yarns) id) ~ + `[id u.yar] +:: TODO: namespacing conflicts? +++ saw-thread + |= =rope:h + |= =rug:h + ?~ ted=(~(get by new.rug) rope) rug + =. new.rug (~(del by new.rug) rope) + =/ start (quilt-idx qul.rug) + =. qul.rug (put:on:quilt:h qul.rug start u.ted) + rug +:: +++ saw-rope + |= =rope:h + =/ saw (saw-thread rope) + =. all (saw all) + =. desks + (~(jab by desks) des.rope saw) + =? groups ?=(^ gop.rope) + (~(jab by groups) u.gop.rope saw) + cor +++ rug-to-yarns + |= =rug:h + ^- (map id:h yarn:h) + %- ~(gas by *(map id:h yarn:h)) + ~ + ::^- (list [id:h yarn:h]) + :: %- zing + :: %+ turn ~(tap by new.rug) + :: |= [=rope:h =thread:h] + +:: +stale: garbage collection +:: +++ stale + |^ + =/ ids ~(key by yarns) + =. ids (~(dif in ids) (ids-for-rug all)) + =. ids (~(dif in ids) ids-for-groups) + =. ids (~(dif in ids) ids-for-desks) + =/ ids ~(tap in ids) + |- + ?~ ids cor + $(yarns (~(del by yarns) i.ids), ids t.ids) + ++ trim-rug + |= =rug:h + =* on on:quilt:h + ^+ rug + ?~ hed=(pry:on qul.rug) + rug + :: TODO: bad asymptotics + =+ siz=(lent (tap:on qul.rug)) + ?: (lte siz 50) + rug :: bail if not much there + =/ dip (dip:on ,count=@ud) + =. qul.rug + =< + + %^ dip qul.rug 0 + |= [count=@ud key=@ud =thread:h] + ^- [(unit thread:h) stop=? count=@ud] + =- [~ - +(count)] + (gte count rug-trim-size) + rug + :: + ++ ids-for-rug + |= =rug:h + %- ~(gas in *(set id:h)) + ^- (list id:h) + %+ welp + ^- (list id:h) + %- zing + %+ turn ~(val by new.rug) + |= =thread:h + ~(tap in thread) + ^- (list id:h) + %- zing + %+ turn (tap:on:quilt:h qul.rug) + |= [idx=@ud =thread:h] + ~(tap in thread) + :: + ++ ids-for-desks + =/ des ~(tap in ~(key by desks)) + =| ids=(set id:h) + |- ^+ ids + ?~ des ids + =/ =rug:h (~(got by desks) i.des) + $(ids (~(uni in ids) (ids-for-rug rug)), des t.des) + :: + ++ ids-for-groups + =/ gop ~(tap in ~(key by groups)) + =| ids=(set id:h) + |- ^+ ids + ?~ gop ids + =/ =rug:h (~(got by groups) i.gop) + $(ids (~(uni in ids) (ids-for-rug rug)), gop t.gop) + -- +++ saw-seam + |= =seam:h + =/ fun + |= =rug:h + =/ start (quilt-idx qul.rug) + =/ new ~(val by new.rug) + %_ rug + new ~ + :: + qul + %+ gas:on:quilt:h qul.rug + (zip (gulf start (add start (lent new))) new) + == + =. . + ?- -.seam + %group .(groups (~(jab by groups) flag.seam fun)) + %desk .(desks (~(jab by desks) desk.seam fun)) + %all .(all (fun all)) + == + cor +:: +++ add-yarn + =| [add-all=? add-desk=? =yarn:h] + |% + ++ $ + =. yarns (~(put by yarns) id.yarn yarn) + =. cor weave-all + =. cor weave-group + weave-desk + :: + ++ weave-all + ?. add-all cor + cor(all (weave-rug all all/~)) + ++ weave-rug + |= [=rug:h =seam:h] + =/ =thread:h (~(gut by new.rug) rop.yarn ~) + =. thread (~(put in thread) id.yarn) + =. new.rug (~(put by new.rug) rop.yarn thread) + rug + :: + ++ weave-group + ?~ gop.rop.yarn cor + =* group u.gop.rop.yarn + =/ =rug:h (~(gut by groups) group *rug:h) + =. rug (weave-rug rug group/group) + =. groups (~(put by groups) group rug) + cor + :: + ++ weave-desk + ?. add-desk cor + =/ =rug:h (~(gut by desks) des.rop.yarn *rug:h) + =. rug (weave-rug rug desk/des.rop.yarn) + =. desks (~(put by desks) des.rop.yarn rug) + cor + -- +-- diff --git a/desk/app/settings-store.hoon b/desk/app/settings-store.hoon deleted file mode 100644 index c6989e53..00000000 --- a/desk/app/settings-store.hoon +++ /dev/null @@ -1,202 +0,0 @@ -/- *settings -/+ verb, dbug, default-agent, agentio -|% -+$ card card:agent:gall -+$ versioned-state - $% state-0 - state-1 - state-2 - == -+$ state-0 [%0 settings=settings-0] -+$ state-1 [%1 settings=settings-1] -+$ state-2 [%2 =settings] --- -=| state-2 -=* state - -:: -%- agent:dbug -%+ verb | -^- agent:gall -=< - |_ bol=bowl:gall - +* this . - do ~(. +> bol) - def ~(. (default-agent this %|) bol) - io ~(. agentio bol) - :: - ++ on-init on-init:def - :: - ++ on-save !>(state) - :: - ++ on-load - |= =old=vase - ^- (quip card _this) - =/ old !<(versioned-state old-vase) - |- - ?- -.old - %0 $(old [%1 +.old]) - %1 $(old [%2 (~(put by *^settings) %landscape settings.old)]) - %2 `this(state old) - == - :: - ++ on-poke - |= [mar=mark vas=vase] - ^- (quip card _this) - ?> (team:title our.bol src.bol) - ?. ?=(%settings-event mar) - (on-poke:def mar vas) - =/ evt=event !<(event vas) - =^ cards state - ?- -.evt - %put-bucket (put-bucket:do [desk key bucket]:evt) - %del-bucket (del-bucket:do [desk key]:evt) - %put-entry (put-entry:do [desk buc key val]:evt) - %del-entry (del-entry:do [desk buc key]:evt) - == - [cards this] - :: - ++ on-watch - |= pax=path - ^- (quip card _this) - ?> (team:title our.bol src.bol) - ?+ pax (on-watch:def pax) - [%all ~] - [~ this] - :: - [%desk @ ~] - =* desk i.t.pax - [~ this] - :: - [%bucket @ @ ~] - =* desk i.t.pax - =* bucket-key i.t.t.pax - ?> (~(has bi settings) desk bucket-key) - [~ this] - :: - [%entry @ @ @ ~] - =* desk i.t.pax - =* bucket-key i.t.t.pax - =* entry-key i.t.t.t.pax - =/ bucket (~(got bi settings) desk bucket-key) - ?> (~(has by bucket) entry-key) - [~ this] - == - :: - ++ on-peek - |= pax=path - ^- (unit (unit cage)) - ?+ pax (on-peek:def pax) - [%x %all ~] - ``settings-data+!>(`data`all+settings) - :: - [%x %desk @ ~] - =* desk i.t.t.pax - =/ desk-settings (~(gut by settings) desk ~) - ``settings-data+!>(desk+desk-settings) - :: - [%x %bucket @ @ ~] - =* desk i.t.t.pax - =* buc i.t.t.t.pax - =/ bucket=(unit bucket) (~(get bi settings) desk buc) - ?~ bucket [~ ~] - ``settings-data+!>(`data`bucket+u.bucket) - :: - [%x %entry @ @ @ ~] - =* desk i.t.t.pax - =* buc i.t.t.t.pax - =* key i.t.t.t.t.pax - =/ =bucket (~(gut bi settings) desk buc *bucket) - =/ entry=(unit val) (~(get by bucket) key) - ?~ entry [~ ~] - ``settings-data+!>(`data`entry+u.entry) - :: - [%x %has-bucket @ @ ~] - =/ desk i.t.t.pax - =/ buc i.t.t.t.pax - =/ has-bucket=? (~(has bi settings) desk buc) - ``noun+!>(`?`has-bucket) - :: - [%x %has-entry @ @ @ ~] - =* desk i.t.t.pax - =* buc i.t.t.t.pax - =* key i.t.t.t.t.pax - =/ =bucket (~(gut bi settings) desk buc *bucket) - =/ has-entry=? (~(has by bucket) key) - ``noun+!>(`?`has-entry) - == - :: - ++ on-agent on-agent:def - ++ on-leave on-leave:def - ++ on-arvo on-arvo:def - ++ on-fail on-fail:def - -- -:: -|_ bol=bowl:gall -:: -:: +put-bucket: put a bucket in the top level settings map, overwriting if it -:: already exists -:: -++ put-bucket - |= [=desk =key =bucket] - ^- (quip card _state) - =/ pas=(list path) - :~ /all - /desk/[desk] - /bucket/[desk]/[key] - == - :- [(give-event pas %put-bucket desk key bucket)]~ - state(settings (~(put bi settings) desk key bucket)) -:: -:: +del-bucket: delete a bucket from the top level settings map -:: -++ del-bucket - |= [=desk =key] - ^- (quip card _state) - =/ pas=(list path) - :~ /all - /desk/[desk] - /bucket/[key] - == - :- [(give-event pas %del-bucket desk key)]~ - state(settings (~(del bi settings) desk key)) -:: -:: +put-entry: put an entry in a bucket, overwriting if it already exists -:: if bucket does not yet exist, create it -:: -++ put-entry - |= [=desk buc=key =key =val] - ^- (quip card _state) - =/ pas=(list path) - :~ /all - /desk/[desk] - /bucket/[desk]/[buc] - /entry/[desk]/[buc]/[key] - == - =/ =bucket (~(put by (~(gut bi settings) desk buc *bucket)) key val) - :- [(give-event pas %put-entry desk buc key val)]~ - state(settings (~(put bi settings) desk buc bucket)) -:: -:: +del-entry: delete an entry from a bucket, fail quietly if bucket does not -:: exist -:: -++ del-entry - |= [=desk buc=key =key] - ^- (quip card _state) - =/ pas=(list path) - :~ /all - /desk/[desk] - /bucket/[desk]/[buc] - /entry/[desk]/[buc]/[key] - == - =/ bucket=(unit bucket) (~(get bi settings) desk buc) - ?~ bucket - [~ state] - =. u.bucket (~(del by u.bucket) key) - :- [(give-event pas %del-entry desk buc key)]~ - state(settings (~(put bi settings) desk buc u.bucket)) -:: -++ give-event - |= [pas=(list path) evt=event] - ^- card - [%give %fact pas %settings-event !>(evt)] --- diff --git a/desk/app/vitals.hoon b/desk/app/vitals.hoon index 1aa42e17..c536cfbf 100644 --- a/desk/app/vitals.hoon +++ b/desk/app/vitals.hoon @@ -135,7 +135,7 @@ %arvo %k %fard - %garden :: XX: %landscape? + %landscape %vitals-connection-check %noun !>(ship) @@ -150,7 +150,7 @@ %arvo %k %fard - %garden :: XX: %landscape? + %landscape %vitals-connection-check %noun !>(ship) diff --git a/desk/desk.bill b/desk/desk.bill index 4d9f9cf3..367e8815 100644 --- a/desk/desk.bill +++ b/desk/desk.bill @@ -1,12 +1,11 @@ -:~ %docket - %treaty - %hark-store - %hark-system-hook +:~ %bait + %contacts + %docket + %hark + %reel %settings - %settings-store %storage - %reel - %bait + %treaty %vitals %growl == diff --git a/desk/desk.docket-0 b/desk/desk.docket-0 index 75f942b3..27072532 100644 --- a/desk/desk.docket-0 +++ b/desk/desk.docket-0 @@ -4,7 +4,7 @@ glob-http+['https://bootstrap.urbit.org/glob-0v3.26u3l.bgtqj.v0tu0.t5kpu.91p45.glob' 0v3.26u3l.bgtqj.v0tu0.t5kpu.91p45] ::glob-ames+~zod^0v0 base+'grid' - version+[1 15 0] + version+[2 0 0] website+'https://tlon.io' license+'MIT' == diff --git a/desk/gen/hark/add-note.hoon b/desk/gen/hark/add-note.hoon new file mode 100644 index 00000000..ab76c44f --- /dev/null +++ b/desk/gen/hark/add-note.hoon @@ -0,0 +1,14 @@ +/- h=hark +:- %say +|= $: [now=@da eny=@uvJ =beak] + [[all=? des=? =desk con=(list content:h)] [group=(unit flag:h) thread=path ~]] + == +=/ =id:h (end [7 1] eny) +=/ =rope:h + [group ~ desk thread] +=/ =note:h + [id rope now con ~ ~] +~& > adding/id +:- %hark-action +^- action:h +[%add-note all des note] diff --git a/desk/gen/hark/saw-rope.hoon b/desk/gen/hark/saw-rope.hoon new file mode 100644 index 00000000..4dab8d47 --- /dev/null +++ b/desk/gen/hark/saw-rope.hoon @@ -0,0 +1,8 @@ +/- h=hark +:- %say +|= $: [now=@da eny=@uvJ =beak] + [[=rope:h ~] ~] + == +:- %hark-action +^- action:h +[%saw-rope rope] diff --git a/desk/gen/hark/saw-seam.hoon b/desk/gen/hark/saw-seam.hoon new file mode 100644 index 00000000..3380d230 --- /dev/null +++ b/desk/gen/hark/saw-seam.hoon @@ -0,0 +1,8 @@ +/- h=hark +:- %say +|= $: [now=@da eny=@uvJ =beak] + [[=seam:h ~] ~] + == +:- %hark-action +^- action:h +[%saw-seam seam] diff --git a/desk/lib/contacts-json.hoon b/desk/lib/contacts-json.hoon new file mode 100644 index 00000000..2fc4730a --- /dev/null +++ b/desk/lib/contacts-json.hoon @@ -0,0 +1,131 @@ +/- c=contacts, g=groups +/+ gj=groups-json +|% +++ enjs + =, enjs:format + |% + :: XX shadowed for compat, +ship:enjs removes the ~ + :: + ++ ship + |=(her=@p n+(rap 3 '"' (scot %p her) '"' ~)) + :: + ++ action + |= a=action:c + ^- json + %+ frond -.a + ?- -.a + %anon ~ + %edit a+(turn p.a field) + %meet a+(turn p.a ship) + %heed a+(turn p.a ship) + %drop a+(turn p.a ship) + %snub a+(turn p.a ship) + == + :: + ++ contact + |= c=contact:c + ^- json + %- pairs + :~ nickname+s+nickname.c + bio+s+bio.c + status+s+status.c + color+s+(scot %ux color.c) + avatar+?~(avatar.c ~ s+u.avatar.c) + cover+?~(cover.c ~ s+u.cover.c) + :: + =- groups+a+- + %- ~(rep in groups.c) + |=([f=flag:g j=(list json)] [s+(flag:enjs:gj f) j]) + == + :: + ++ field + |= f=field:c + ^- json + %+ frond -.f + ?- -.f + %nickname s+nickname.f + %bio s+bio.f + %status s+status.f + %color s+(rsh 3^2 (scot %ux color.f)) :: XX confirm + %avatar ?~(avatar.f ~ s+u.avatar.f) + %cover ?~(cover.f ~ s+u.cover.f) + %add-group s+(flag:enjs:gj flag.f) + %del-group s+(flag:enjs:gj flag.f) + == + :: + ++ rolodex + |= r=rolodex:c + ^- json + %- pairs + %- ~(rep by r) + |= [[who=@p foreign:c] j=(list [@t json])] + [[(scot %p who) ?.(?=([@ ^] for) ~ (contact con.for))] j] :: XX stale flag per sub state? + :: + ++ news + |= n=news:c + ^- json + %- pairs + :~ who+(ship who.n) + con+?~(con.n ~ (contact con.n)) + == + -- +:: +++ dejs + =, dejs:format + |% + :: for performance, @p is serialized above to json %n (no escape) + :: for mark roundtrips, ships are parsed from either %s or %n + :: XX do this elsewhere in groups? + :: + ++ ship (se-ne %p) + ++ se-ne + |= aur=@tas + |= jon=json + ?+ jon !! + [%s *] (slav aur p.jon) + :: + [%n *] ~| bad-n+p.jon + =/ wyd (met 3 p.jon) + ?> ?& =('"' (end 3 p.jon)) + =('"' (cut 3 [(dec wyd) 1] p.jon)) + == + (slav aur (cut 3 [1 (sub wyd 2)] p.jon)) + == + :: + ++ action + ^- $-(json action:c) + %- of + :~ anon+ul + edit+(ar field) + meet+(ar ship) + heed+(ar ship) + drop+(ar ship) + snub+(ar ship) + == + :: + ++ contact + ^- $-(json contact:c) + %- ot + :~ nickname+so + bio+so + status+so + color+nu + avatar+(mu so) + cover+(mu so) + groups+(as flag:dejs:gj) + == + :: + ++ field + ^- $-(json field:c) + %- of + :~ nickname+so + bio+so + status+so + color+nu + avatar+(mu so) + cover+(mu so) + add-group+flag:dejs:gj + del-group+flag:dejs:gj + == + -- +-- diff --git a/desk/lib/groups-json.hoon b/desk/lib/groups-json.hoon new file mode 100644 index 00000000..f858e9a0 --- /dev/null +++ b/desk/lib/groups-json.hoon @@ -0,0 +1,21 @@ +/- g=groups +|% +++ enjs + =, enjs:format + |% + ++ flag + |= f=flag:g + (rap 3 (scot %p p.f) '/' q.f ~) + :: + ++ nest + |= n=nest:g + (rap 3 p.n '/' (flag q.n) ~) + -- +++ dejs + =, dejs:format + |% + ++ ship (se %p) + ++ flag (su ;~((glue fas) ;~(pfix sig fed:ag) sym)) + ++ nest (su ;~((glue fas) sym ;~(pfix sig fed:ag))) + -- +-- \ No newline at end of file diff --git a/desk/lib/hark-json.hoon b/desk/lib/hark-json.hoon new file mode 100644 index 00000000..0475aa43 --- /dev/null +++ b/desk/lib/hark-json.hoon @@ -0,0 +1,232 @@ +/- h=hark +/+ groups-json +|% +++ enjs + =, enjs:format + |% + ++ action + |= a=action:h + %+ frond -.a + ?- -.a + %add-yarn (add-yarn +.a) + %saw-seam (seam +.a) + %saw-rope (rope +.a) + == + :: + ++ blanket + |= b=blanket:h + %- pairs + :~ seam/(seam seam.b) + yarns/(yarns yarns.b) + quilt/(quilt quilt.b) + == + :: + ++ quilt + |= q=quilt:h + %- pairs + %+ turn (tap:on:quilt:h q) + |= [num=@ud t=thread:h] + [(scot %ud num) (thread t)] + :: + ++ add-yarn + |= [all=? desk=? yar=yarn:h] + %- pairs + :~ all/b/all + desk/b/desk + yarn/(yarn yar) + == + :: + ++ carpet + |= c=carpet:h + ^- json + %- pairs + :~ seam/(seam seam.c) + yarns/(yarns yarns.c) + cable/(cable cable.c) + stitch/(numb stitch.c) + == + :: + ++ cable + |= c=(map rope:h thread:h) + ^- json + :- %a + %+ turn ~(tap by c) + |= [r=rope:h t=thread:h] + %- pairs + :~ rope/(rope r) + thread/(thread t) + == + :: + ++ skeins + |= sks=(list skein:h) + ^- json + :- %a + %+ turn sks + |= =skein:h + %- pairs + :~ time/(time time.skein) + count/(numb count.skein) + ship-count/(numb ship-count.skein) + top/(yarn top.skein) + unread/b/unread.skein + == + ++ id + |= i=id:h + ^- json + s/(scot %uv i) + :: + ++ thread + |= t=thread:h + ^- json + :- %a + (turn ~(tap in t) id) + :: + ++ threads + |= ts=(map @da thread:h) + %- pairs + %+ turn ~(tap by ts) + |= [tim=@da t=thread:h] + ^- [cord json] + [(scot %da tim) (thread t)] + :: + ++ update + |= u=update:h + %- pairs + :~ yarns/(yarns yarns.u) + seam/(seam seam.u) + threads/(threads threads.u) + == + :: + ++ yarns + |= ys=(map id:h yarn:h) + ^- json + %- pairs + %+ turn ~(tap by ys) + |= [i=id:h y=yarn:h] + [(scot %uv i) (yarn y)] + :: + ++ yarn + |= y=yarn:h + ^- json + %- pairs + :~ id/s/(scot %uv id.y) + rope/(rope rop.y) + time/(time tim.y) + con/a/(turn con.y content) + wer/s/(spat wer.y) + button/~ + == + :: + ++ content + |= c=content:h + ^- json + ?@ c s/c + ?- -.c + %ship (frond ship/s/(scot %p p.c)) + %emph (frond emph/s/p.c) + == + :: + ++ seam + |= s=seam:h + %+ frond -.s + ^- json + ?- -.s + %all ~ + %group s/(flag flag.s) + %desk s/desk.s + == + :: + ++ flag flag:enjs:groups-json + ++ nest nest:enjs:groups-json + :: + ++ rope + |= r=rope:h + ^- json + %- pairs + :~ group/?~(gop.r ~ s/(flag u.gop.r)) + channel/?~(can.r ~ s/(nest u.can.r)) + desk/s/des.r + thread/s/(spat ted.r) + == + -- +:: +++ dejs + =, dejs:format + |% + ++ action + %- of + :~ saw-seam/seam + saw-rope/rope + add-yarn/add-yarn + == + ++ action-1 + %- of + :~ saw-seam/seam + saw-rope/rope + add-yarn/add-yarn + new-yarn/new-yarn + == + :: + ++ seam + %- of + :~ all/ul + desk/so + group/flag + == + :: + ++ add-yarn + %- ot + :~ all/bo + desk/bo + yarn/yarn + == + :: + ++ new-yarn + %- ot + :~ all/bo + desk/bo + rope/rope + con/(ar content) + wer/pa + but/(mu button) + == + :: + ++ button + %- ot + :~ title/so + hanlder/pa + == + :: + ++ content + |= j=json + ^- content:h + ?: ?=([%s *] j) p.j + => .(j `json`j) + %. j + %- of + :~ ship/ship + emph/so + == + :: + ++ yarn + %- ot + :~ id/(se %uvh) + rope/rope + time/(se %da) + con/(ar content) + wer/pa + but/(mu button) + == + :: + ++ flag flag:dejs:groups-json + ++ nest nest:dejs:groups-json + ++ ship ship:dejs:groups-json + ++ rope + %- ot + :~ group/(mu flag) + channel/(mu nest) + desk/so + thread/pa + == + -- +-- diff --git a/desk/lib/hark-store.hoon b/desk/lib/hark-store.hoon deleted file mode 100644 index 739f6c8e..00000000 --- a/desk/lib/hark-store.hoon +++ /dev/null @@ -1,254 +0,0 @@ -/- sur=hark-store -^? -=, sur -=< [. sur] -|% - -++ enjs - =, enjs:format - |% - ++ update - |= upd=^update - ^- json - %+ frond -.upd - ?+ -.upd a+~ - %added (notification +.upd) - %add-note (add-note +.upd) - %timebox (timebox +.upd) - %more (more +.upd) - %read-each (read-each +.upd) - %read-count (place +.upd) - %unread-each (read-each +.upd) - %unread-count (unread-count +.upd) - %saw-place (saw-place +.upd) - %all-stats (all-stats +.upd) - %del-place (place +.upd) - ::%read-note (index +.upd) - ::%note-read (note-read +.upd) - %archived (archived +.upd) - == - :: - ++ add-note - |= [bi=^bin bo=^body] - %- pairs - :~ bin+(bin bi) - body+(body bo) - == - :: - ++ saw-place - |= [p=^place t=(unit ^time)] - %- pairs - :~ place+(place p) - time+?~(t ~ (time u.t)) - == - :: - ++ archived - |= [t=^time l=^lid n=^notification] - %- pairs - :~ lid+(lid l) - time+s+(scot %ud t) - notification+(notification n) - == - :: - ++ note-read - |= * - (pairs ~) - :: - ++ all-stats - |= places=(map ^place ^stats) - ^- json - :- %a - ^- (list json) - %+ turn ~(tap by places) - |= [p=^place s=^stats] - %- pairs - :~ stats+(stats s) - place+(place p) - == - :: - ++ stats - |= s=^stats - ^- json - %- pairs - :~ each+a+(turn ~(tap in each.s) (cork spat (lead %s))) - last+(time last.s) - count+(numb count.s) - == - ++ more - |= upds=(list ^update) - ^- json - a+(turn upds update) - :: - ++ place - |= =^place - %- pairs - :~ desk+s+desk.place - path+s+(spat path.place) - == - :: - ++ bin - |= =^bin - %- pairs - :~ place+(place place.bin) - path+s+(spat path.bin) - == - ++ notification - |= ^notification - ^- json - %- pairs - :~ time+(time date) - bin+(^bin bin) - body+(bodies body) - == - ++ bodies - |= bs=(list ^body) - ^- json - a+(turn bs body) - :: - ++ contents - |= cs=(list ^content) - ^- json - a+(turn cs content) - :: - ++ content - |= c=^content - ^- json - %+ frond -.c - ?- -.c - %ship s+(scot %p ship.c) - %text s+cord.c - == - :: - ++ body - |= ^body - ^- json - %- pairs - :~ title+(contents title) - content+(contents content) - time+(^time time) - link+s+(spat link) - == - :: - ++ binned-notification - |= [=^bin =^notification] - %- pairs - :~ bin+(^bin bin) - notification+(^notification notification) - == - ++ lid - |= l=^lid - ^- json - %+ frond -.l - ?- -.l - ?(%seen %unseen) ~ - %archive s+(scot %ud time.l) - == - :: - ++ timebox - |= [li=^lid l=(list ^notification)] - ^- json - %- pairs - :~ lid+(lid li) - notifications+a+(turn l notification) - == - :: - ++ read-each - |= [p=^place pax=^path] - %- pairs - :~ place+(place p) - path+(path pax) - == - :: - ++ unread-count - |= [p=^place inc=? count=@ud] - %- pairs - :~ place+(place p) - inc+b+inc - count+(numb count) - == - -- -++ dejs - =, dejs:format - |% - ++ ship (su ;~(pfix sig fed:ag)) - :: TODO: fix +stab - :: - ++ pa - |= j=json - ^- path - ?> ?=(%s -.j) - ?: =('/' p.j) / - (stab p.j) - :: - ++ place - %- ot - :~ desk+so - path+pa - == - :: - ++ bin - %- ot - :~ path+pa - place+place - == - :: - ++ read-each - %- ot - :~ place+place - path+pa - == - :: - :: parse date as @ud - :: TODO: move to zuse - ++ sd - |= jon=json - ^- @da - ?> ?=(%s -.jon) - `@da`(rash p.jon dem:ag) - :: - ++ lid - %- of - :~ archive+sd - unseen+ul - seen+ul - == - :: - ++ archive - %- ot - :~ lid+lid - bin+bin - == - ++ content - %- of - :~ text+so - ship+ship - == - :: - ++ body - %- ot - :~ title+(ar content) - content+(ar content) - time+di - binned+pa - link+pa - == - :: - ++ add-note - %- ot - :~ bin+bin - body+body - == - :: - ++ action - ^- $-(json ^action) - %- of - :~ archive-all+ul - archive+archive - opened+ul - read-count+place - read-each+read-each - read-note+bin - add-note+add-note - == - -- --- diff --git a/desk/lib/hark/unreads.hoon b/desk/lib/hark/unreads.hoon deleted file mode 100644 index 2eee299f..00000000 --- a/desk/lib/hark/unreads.hoon +++ /dev/null @@ -1,35 +0,0 @@ -/+ store=hark-store -|_ =archive:store -++ orm ((on @da timebox:store) gth) -++ del - |= [=time =bin:store] - ?~ box=(get:orm archive time) archive - (put:orm archive time (~(del by u.box) bin)) -++ put - |= [=time =bin:store =notification:store] - =/ box=timebox:store (fall (get:orm archive time) ~) - =. box (~(put by box) bin notification) - (put:orm archive time box) -:: -++ get - |= [=time =bin:store] - ^- (unit notification:store) - ?~ box=(get:orm archive time) ~ - (~(get by u.box) bin) -:: -++ got - |= [=time =bin:store] - (need (get time bin)) -:: -++ has - |= [=time =bin:store] - ?~((get time bin) %.n %.y) -:: -++ jab - |= [=time =bin:store f=$-(notification:store notification:store)] - (put time bin (f (got time bin))) -:: -++ job - |= [=time =bin:store f=$-((unit notification:store) notification:store)] - (put time bin (f (get time bin))) --- diff --git a/desk/lib/mark-warmer.hoon b/desk/lib/mark-warmer.hoon new file mode 100644 index 00000000..4b482d1f --- /dev/null +++ b/desk/lib/mark-warmer.hoon @@ -0,0 +1,6 @@ +/$ rolo %contact-rolodex %json +/$ contact %contact %json +/$ skeins %hark-skeins %json +/$ carpet %hark-carpet %json +/$ blanket %hark-blanket %json +~ \ No newline at end of file diff --git a/desk/lib/mop-extensions.hoon b/desk/lib/mop-extensions.hoon new file mode 100644 index 00000000..fe44f793 --- /dev/null +++ b/desk/lib/mop-extensions.hoon @@ -0,0 +1,139 @@ +|* [key=mold val=mold] +=> |% + +$ item [key=key val=val] + -- +~% %mope-comp ..zuse ~ +|= compare=$-([key key] ?) +~% %mope-core ..zuse ~ +|% +:: +bat: tabulate a subset excluding start element with a max count (backwards) +:: +++ bat + |= [a=(tree item) b=(unit key) c=@] + ^- (list item) + |^ + e:(tabulate (del-span a b) b c) + :: + ++ tabulate + |= [a=(tree item) b=(unit key) c=@] + ^- [d=@ e=(list item)] + ?: ?&(?=(~ b) =(c 0)) + [0 ~] + =| f=[d=@ e=(list item)] + |- ^+ f + ?: ?|(?=(~ a) =(d.f c)) f + =. f $(a r.a) + ?: =(d.f c) f + =. f [+(d.f) [n.a e.f]] + ?:(=(d.f c) f $(a l.a)) + :: + ++ del-span + |= [a=(tree item) b=(unit key)] + ^- (tree item) + ?~ a a + ?~ b a + ?: =(key.n.a u.b) + l.a + ?. (compare key.n.a u.b) + $(a l.a) + a(r $(a r.a)) + -- +:: +dop: dip:on but in reverse order (right to left) +:: +++ dop + |* state=mold + |= $: a=(tree item) + =state + f=$-([state item] [(unit val) ? state]) + == + ^+ [state a] + :: acc: accumulator + :: + :: .stop: set to %.y by .f when done traversing + :: .state: threaded through each run of .f and produced by +abet + :: + =/ acc [stop=`?`%.n state=state] + =< abet =< main + |% + ++ this . + ++ abet [state.acc a] + :: +main: main recursive loop; performs a partial inorder traversal + :: + ++ main + ^+ this + :: stop if empty or we've been told to stop + :: + ?: =(~ a) this + ?: stop.acc this + :: reverse in-order traversal: right -> node -> left, until .f sets .stop + :: + =. this right + ?: stop.acc this + =^ del this node + =? this !stop.acc left + :: XX: remove for now; bring back when upstreaming + :: =? a del (nip a) + this + :: +node: run .f on .n.a, updating .a, .state, and .stop + :: + ++ node + ^+ [del=*? this] + :: run .f on node, updating .stop.acc and .state.acc + :: + ?> ?=(^ a) + =^ res acc (f state.acc n.a) + ?~ res + [del=& this] + [del=| this(val.n.a u.res)] + :: +left: recurse on left subtree, copying mutant back into .l.a + :: + ++ left + ^+ this + ?~ a this + =/ lef main(a l.a) + lef(a a(l a.lef)) + :: +right: recurse on right subtree, copying mutant back into .r.a + :: + ++ right + ^+ this + ?~ a this + =/ rig main(a r.a) + rig(a a(r a.rig)) + -- +:: +bot: produce the N leftmost elements +:: +++ bot + |= [a=(tree item) b=@] + ^- (list item) + |^ p:(items-with-remainder a b) + ++ items-with-remainder + |= [a=(tree item) b=@] + ^- (pair (list item) @) + ?~ a [~ b] + ?: =(b 0) [~ 0] + =/ left-result (items-with-remainder l.a b) + ?: =(q.left-result 0) left-result + ?: =(q.left-result 1) [(zing ~[p.left-result ~[n.a]]) (dec q.left-result)] + =/ right-result + (items-with-remainder r.a (dec q.left-result)) + [(zing ~[p.left-result ~[n.a] p.right-result]) q.right-result] + -- +:: +top: produce the N rightmost elements +:: +++ top + |= [a=(tree item) b=@] + ^- (list item) + |^ p:(items-with-remainder a b) + ++ items-with-remainder + |= [a=(tree item) b=@] + ^- (pair (list item) @) + ?~ a [~ b] + ?: =(b 0) [~ 0] + =/ right-result (items-with-remainder r.a b) + ?: =(q.right-result 0) right-result + ?: =(q.right-result 1) [[n.a p.right-result] (dec q.right-result)] + =/ left-result + (items-with-remainder l.a (dec q.right-result)) + [(zing ~[p.left-result ~[n.a] p.right-result]) q.left-result] + -- +-- diff --git a/desk/mar/contact.hoon b/desk/mar/contact.hoon new file mode 100644 index 00000000..be56d2f7 --- /dev/null +++ b/desk/mar/contact.hoon @@ -0,0 +1,14 @@ +/- c=contacts +/+ j=contacts-json +|_ =contact:g +++ grad %noun +++ grow + |% + ++ noun group + ++ json (contact:enjs:j contact) + -- +++ grab + |% + ++ noun contact:g + -- +-- diff --git a/desk/mar/contact/action-0.hoon b/desk/mar/contact/action-0.hoon new file mode 100644 index 00000000..5f51d665 --- /dev/null +++ b/desk/mar/contact/action-0.hoon @@ -0,0 +1,15 @@ +/- c=contacts +/+ j=contacts-json +|_ =action:c +++ grad %noun +++ grow + |% + ++ noun action + ++ json (action:enjs:j action) + -- +++ grab + |% + ++ noun action:c + ++ json action:dejs:j + -- +-- diff --git a/desk/mar/contact/action-1.hoon b/desk/mar/contact/action-1.hoon new file mode 100644 index 00000000..623b233e --- /dev/null +++ b/desk/mar/contact/action-1.hoon @@ -0,0 +1,2 @@ +/= mark /mar/dummy +mark diff --git a/desk/mar/contact/action.hoon b/desk/mar/contact/action.hoon new file mode 100644 index 00000000..f6020423 --- /dev/null +++ b/desk/mar/contact/action.hoon @@ -0,0 +1,2 @@ +/= mark /mar/contact/action-0 +mark diff --git a/desk/mar/contact/news.hoon b/desk/mar/contact/news.hoon new file mode 100644 index 00000000..8d47ec02 --- /dev/null +++ b/desk/mar/contact/news.hoon @@ -0,0 +1,14 @@ +/- c=contacts +/+ j=contacts-json +|_ =news:c +++ grad %noun +++ grow + |% + ++ noun news + ++ json (news:enjs:j news) + -- +++ grab + |% + ++ noun news:c + -- +-- diff --git a/desk/mar/contact/rolodex.hoon b/desk/mar/contact/rolodex.hoon new file mode 100644 index 00000000..ad4049c2 --- /dev/null +++ b/desk/mar/contact/rolodex.hoon @@ -0,0 +1,14 @@ +/- c=contacts +/+ j=contacts-json +|_ rol=rolodex:c +++ grad %noun +++ grow + |% + ++ noun rol + ++ json (rolodex:enjs:j rol) + -- +++ grab + |% + ++ noun rolodex:c + -- +-- diff --git a/desk/mar/contact/update-0.hoon b/desk/mar/contact/update-0.hoon new file mode 100644 index 00000000..3bec8608 --- /dev/null +++ b/desk/mar/contact/update-0.hoon @@ -0,0 +1,12 @@ +/- c=contacts +|_ =update:c +++ grad %noun +++ grow + |% + ++ noun update + -- +++ grab + |% + ++ noun update:c + -- +-- diff --git a/desk/mar/contact/update-1.hoon b/desk/mar/contact/update-1.hoon new file mode 100644 index 00000000..623b233e --- /dev/null +++ b/desk/mar/contact/update-1.hoon @@ -0,0 +1,2 @@ +/= mark /mar/dummy +mark diff --git a/desk/mar/contact/update.hoon b/desk/mar/contact/update.hoon new file mode 100644 index 00000000..f143c73b --- /dev/null +++ b/desk/mar/contact/update.hoon @@ -0,0 +1,2 @@ +/= mark /mar/contact/update-0 +mark diff --git a/desk/mar/dummy.hoon b/desk/mar/dummy.hoon new file mode 100644 index 00000000..6d158660 --- /dev/null +++ b/desk/mar/dummy.hoon @@ -0,0 +1,11 @@ +|_ dum=* +++ grad %noun +++ grow + |% + ++ noun dum + -- +++ grab + |% + +$ noun * + -- +-- diff --git a/desk/mar/epic.hoon b/desk/mar/epic.hoon new file mode 100644 index 00000000..58c84bcb --- /dev/null +++ b/desk/mar/epic.hoon @@ -0,0 +1,12 @@ +/- e=epic +|_ =epic:e +++ grad %noun +++ grow + |% + ++ noun epic + -- +++ grab + |% + ++ noun epic:e + -- +-- diff --git a/desk/mar/hark/action-1.hoon b/desk/mar/hark/action-1.hoon new file mode 100644 index 00000000..463de774 --- /dev/null +++ b/desk/mar/hark/action-1.hoon @@ -0,0 +1,14 @@ +/- h=hark +/+ j=hark-json +|_ action=action-1:h +++ grad %noun +++ grow + |% + ++ noun action + -- +++ grab + |% + ++ noun action-1:h + ++ json action-1:dejs:j + -- +-- diff --git a/desk/mar/hark/action.hoon b/desk/mar/hark/action.hoon index 41badeb1..ca7b0a37 100644 --- a/desk/mar/hark/action.hoon +++ b/desk/mar/hark/action.hoon @@ -1,13 +1,15 @@ -/+ *hark-store -|_ act=action +/- h=hark +/+ j=hark-json +|_ =action:h ++ grad %noun ++ grow |% - ++ noun act + ++ noun action + ++ json (action:enjs:j action) -- ++ grab |% - ++ noun action - ++ json action:dejs + ++ noun action:h + ++ json action:dejs:j -- -- diff --git a/desk/mar/hark/blanket.hoon b/desk/mar/hark/blanket.hoon new file mode 100644 index 00000000..ab09582e --- /dev/null +++ b/desk/mar/hark/blanket.hoon @@ -0,0 +1,14 @@ +/- h=hark +/+ j=hark-json +|_ =blanket:h +++ grad %noun +++ grow + |% + ++ noun blanket + ++ json (blanket:enjs:j blanket) + -- +++ grab + |% + ++ noun blanket:h + -- +-- diff --git a/desk/mar/hark/carpet.hoon b/desk/mar/hark/carpet.hoon new file mode 100644 index 00000000..9c4d93a3 --- /dev/null +++ b/desk/mar/hark/carpet.hoon @@ -0,0 +1,14 @@ +/- h=hark +/+ j=hark-json +|_ =carpet:h +++ grad %noun +++ grow + |% + ++ noun carpet + ++ json (carpet:enjs:j carpet) + -- +++ grab + |% + ++ noun carpet:h + -- +-- diff --git a/desk/mar/hark/skeins.hoon b/desk/mar/hark/skeins.hoon new file mode 100644 index 00000000..301aaebf --- /dev/null +++ b/desk/mar/hark/skeins.hoon @@ -0,0 +1,14 @@ +/- h=hark +/+ j=hark-json +|_ skeins=(list skein:h) +++ grad %noun +++ grow + |% + ++ noun skeins + ++ json (skeins:enjs:j skeins) + -- +++ grab + |% + ++ noun (list skein:h) + -- +-- diff --git a/desk/mar/hark/update.hoon b/desk/mar/hark/update.hoon deleted file mode 100644 index 10fca136..00000000 --- a/desk/mar/hark/update.hoon +++ /dev/null @@ -1,13 +0,0 @@ -/+ *hark-store -|_ upd=update -++ grad %noun -++ grow - |% - ++ noun upd - ++ json (update:enjs upd) - -- -++ grab - |% - ++ noun update - -- --- diff --git a/desk/mar/hark/yarn.hoon b/desk/mar/hark/yarn.hoon new file mode 100644 index 00000000..9a4496fc --- /dev/null +++ b/desk/mar/hark/yarn.hoon @@ -0,0 +1,14 @@ +/- h=hark +/+ j=hark-json +|_ =yarn:h +++ grad %noun +++ grow + |% + ++ noun yarn + ++ json (yarn:enjs:j yarn) + -- +++ grab + |% + ++ noun yarn:h + -- +-- diff --git a/desk/sur/chat-0.hoon b/desk/sur/chat-0.hoon index b4f4559e..713c852e 100644 --- a/desk/sur/chat-0.hoon +++ b/desk/sur/chat-0.hoon @@ -1,9 +1,7 @@ -/- g=groups, graph-store +/- g=groups /- meta -/- metadata-store /- cite /- e=epic -/+ lib-graph=graph-store |% :: $writ: a chat message +$ writ [seal memo] @@ -333,15 +331,4 @@ readers=(set sect:g) writers=(set sect:g) == -++ met metadata-store -+$ club-import [ships=(set ship) =association:met =graph:gra] -+$ club-imports (map flag club-import) -:: -+$ import [writers=(set ship) =association:met =update-log:gra =graph:gra] -:: -+$ imports (map flag import) -:: -++ gra graph-store -++ orm-gra orm:lib-graph -++ orm-log-gra orm-log:lib-graph -- diff --git a/desk/sur/chat-1.hoon b/desk/sur/chat-1.hoon index acaca730..d4c5f806 100644 --- a/desk/sur/chat-1.hoon +++ b/desk/sur/chat-1.hoon @@ -1,9 +1,7 @@ -/- g=groups, graph-store +/- g=groups /- meta -/- metadata-store /- cite /- e=epic -/+ lib-graph=graph-store |% :: $writ: a chat message +$ writ [seal memo] @@ -338,15 +336,4 @@ readers=(set sect:g) writers=(set sect:g) == -++ met metadata-store -+$ club-import [ships=(set ship) =association:met =graph:gra] -+$ club-imports (map flag club-import) -:: -+$ import [writers=(set ship) =association:met =update-log:gra =graph:gra] -:: -+$ imports (map flag import) -:: -++ gra graph-store -++ orm-gra orm:lib-graph -++ orm-log-gra orm-log:lib-graph -- diff --git a/desk/sur/chat.hoon b/desk/sur/chat.hoon index 11f7d0b4..d2e8963f 100644 --- a/desk/sur/chat.hoon +++ b/desk/sur/chat.hoon @@ -1,9 +1,7 @@ -/- g=groups, graph-store, uno=chat-1, zer=chat-0 +/- g=groups, uno=chat-1, zer=chat-0 /- meta -/- metadata-store /- cite /- e=epic -/+ lib-graph=graph-store |% ++ old |% @@ -358,15 +356,4 @@ readers=(set sect:g) writers=(set sect:g) == -++ met metadata-store -+$ club-import [ships=(set ship) =association:met =graph:gra] -+$ club-imports (map flag club-import) -:: -+$ import [writers=(set ship) =association:met =update-log:gra =graph:gra] -:: -+$ imports (map flag import) -:: -++ gra graph-store -++ orm-gra orm:lib-graph -++ orm-log-gra orm-log:lib-graph -- diff --git a/desk/sur/contacts.hoon b/desk/sur/contacts.hoon new file mode 100644 index 00000000..d54de767 --- /dev/null +++ b/desk/sur/contacts.hoon @@ -0,0 +1,89 @@ +/- e=epic, g=groups +|% +:: [compat] protocol-versioning scheme +:: +:: adopted from :groups, slightly modified. +:: +:: for our action/update marks, we +:: - *must* support our version (+okay) +:: - *should* support previous versions (especially actions) +:: - but *can't* support future versions +:: +:: in the case of updates at unsupported protocol versions, +:: we backoff and subscribe for version changes (/epic). +:: (this alone is unlikely to help with future versions, +:: but perhaps our peer will downgrade. in the meantime, +:: we wait to be upgraded.) +:: ++| %compat +++ okay `epic`0 +++ mar + |% + ++ base + |% + +$ act %contact-action + +$ upd %contact-update + -- + :: + ++ act `mark`^~((rap 3 *act:base '-' (scot %ud okay) ~)) + ++ upd `mark`^~((rap 3 *upd:base '-' (scot %ud okay) ~)) + -- +:: ++| %types ++$ contact + $: nickname=@t + bio=@t + status=@t + color=@ux + avatar=(unit @t) + cover=(unit @t) + groups=(set flag:g) + == +:: ++$ foreign [for=$@(~ profile) sag=$@(~ saga)] ++$ profile [wen=@da con=$@(~ contact)] ++$ rolodex (map ship foreign) +:: ++$ epic epic:e ++$ saga + $@ $? %want :: subscribing + %fail :: %want failed + %lost :: epic %fail + ~ :: none intended + == + saga:e +:: ++$ field + $% [%nickname nickname=@t] + [%bio bio=@t] + [%status status=@t] + [%color color=@ux] + [%avatar avatar=(unit @t)] + [%cover cover=(unit @t)] + [%add-group =flag:g] + [%del-group =flag:g] + == +:: ++$ action + :: %anon: delete our profile + :: %edit: change our profile + :: %meet: track a peer + :: %heed: follow a peer + :: %drop: discard a peer + :: %snub: unfollow a peer + :: + $% [%anon ~] + [%edit p=(list field)] + [%meet p=(list ship)] + [%heed p=(list ship)] + [%drop p=(list ship)] + [%snub p=(list ship)] + == +:: ++$ update :: network + $% [%full profile] + == +:: ++$ news :: local + [who=ship con=$@(~ contact)] +-- diff --git a/desk/sur/hark-store.hoon b/desk/sur/hark-store.hoon deleted file mode 100644 index 0a9acf5f..00000000 --- a/desk/sur/hark-store.hoon +++ /dev/null @@ -1,159 +0,0 @@ -^? -:: -:: %hark-store: Notification, unreads store -:: -:: Timeboxing & binning: -:: -:: Unread notifications accumulate in $unreads. They are grouped by -:: their $bin. A notification may become read by either: -:: a) being read by a %read-count or %read-each or %read-note -:: b) being read by a %seen -:: -:: If a) then we insert the corresponding bin into $reads at the -:: current timestamp -:: If b) then we empty $unreads and move all bins to $reads at the -:: current timestamp -:: -:: Unread tracking: -:: Unread tracking has two 'modes' which may be used concurrently, -:: if necessary. -:: -:: count: -:: This stores the unreads as a simple atom, describing the number -:: of unread items. May be increased with %unread-count and -:: set to zero with %read-count. Ideal for high-frequency linear -:: datastructures, e.g. chat -:: each: -:: This stores the unreads as a set of paths, describing the set of -:: unread items. Unreads may be added to the set with %unread-each -:: and removed with %read-each. Ideal for non-linear, low-frequency -:: datastructures, e.g. blogs -:: -|% -:: $place: A location, under which landscape stores stats -:: -:: .desk must match q.byk.bowl -:: Examples: -:: A chat: -:: [%landscape /~dopzod/urbit-help] -:: A note in a notebook: -:: [%landscape /~darrux-landes/feature-requests/12374893234232] -:: A group: -:: [%hark-group-hook /~bitbet-bolbel/urbit-community] -:: Comments on a link -:: [%landscape /~dabben-larbet/urbit-in-the-news/17014118450499614194868/2] -:: -+$ place [=desk =path] -:: -:: $bin: Identifier for grouping notifications -:: -:: Examples -:: A mention in a chat: -:: [/mention %landscape /~dopzod/urbit-help] -:: New messages in a chat -:: [/message %landscape /~dopzod/urbit-help] -:: A new comment in a notebook: -:: [/comment %landscape /~darrux-landes/feature-requests/12374893234232/2] -:: -+$ bin [=path =place] -:: -:: $lid: Reference to a timebox -:: -+$ lid - $% [%archive =time] - [%seen ~] - [%unseen ~] - == -:: $content: Notification content -+$ content - $% [%ship =ship] - [%text =cord] - == -:: -:: $body: A notification body -:: -+$ body - $: title=(list content) - content=(list content) - =time - binned=path - link=path - == -:: -+$ notification - [date=@da =bin body=(list body)] -:: $timebox: Group of notificatons -+$ timebox - (map bin notification) -:: $archive: Archived notifications, ordered by time -+$ archive - ((mop @da timebox) gth) -:: -+$ action - $% :: hook actions - :: - :: %add-note: add a notification - [%add-note =bin =body] - :: - :: %del-place: Underlying resource disappeared, remove all - :: associated notifications - [%del-place =place] - :: %unread-count: Change unread count by .count - [%unread-count =place inc=? count=@ud] - :: %unread-each: Add .path to list of unreads for .place - [%unread-each =place =path] - :: %saw-place: Update last-updated for .place to now.bowl - [%saw-place =place time=(unit time)] - :: store actions - :: - :: %archive: archive single notification - :: if .time is ~, then archiving unread notification - :: else, archiving read notification - [%archive =lid =bin] - :: %read-count: set unread count to zero - [%read-count =place] - :: %read-each: remove path from unreads for .place - [%read-each =place =path] - :: %read-note: Read note at .bin - [%read-note =bin] - :: %archive-all: Archive all notifications - [%archive-all ~] - :: %opened: User opened notifications, reset timeboxing logic. - :: - [%opened ~] - :: - :: XX: previously in hark-store, now deprecated - :: the hooks responsible for creating notifications may offer pokes - :: similar to this - :: [%read-graph =resource] - :: [%read-group =resource] - :: [%remove-graph =resource] - :: - == -:: .stats: Statistics for a .place -:: -+$ stats - $: count=@ud - each=(set path) - last=@da - timebox=(unit @da) - == -:: -+$ update - $% action - :: %more: more updates - [%archived =time =lid =notification] - [%more more=(list update)] - :: %note-read: note has been read with timestamp - [%note-read =time =bin] - [%added =notification] - :: %timebox: description of timebox. - :: - [%timebox =lid =(list notification)] - :: %place-stats: description of .stats for a .place - [%place-stats =place =stats] - :: %place-stats: stats for all .places - [%all-stats places=(map place stats)] - == --- - diff --git a/desk/sur/hark.hoon b/desk/sur/hark.hoon new file mode 100644 index 00000000..c65b121b --- /dev/null +++ b/desk/sur/hark.hoon @@ -0,0 +1,117 @@ +/- g=groups +|% +:: $rope: notification origin +:: +:: Shows where a notification has come from. Used to group +:: notifications into threads ++$ rope + $: gop=(unit flag) :: originating group + can=(unit nest:g) :: originating channel + des=desk :: originating desk + ted=path :: threading identifer + == +:: $thread: notification group +:: ++$ thread (set id) +:: $id: notification identifier ++$ id @uvH +:: $yarn: notification ++$ yarn + $: =id + rop=rope :: origin + tim=time :: time sent + con=(list content) :: content of notification + wer=path :: where to link to in FE + but=(unit button) :: action, if any + == +:: +:: $new-yarn: type for creating yarns ++$ new-yarn + $: all=? + desk=? + rop=rope + con=(list content) + wer=path + but=(unit button) + == +:: ++$ button + $: title=cord + handler=path + == ++$ flag (pair ship term) +:: $content: notification text to be rendered ++$ content + $@ @t + $% [%ship p=ship] + [%emph p=cord] + == +:: $action: Actions for hark +:: +:: %add-yarn adds a notification to the relevant inboxes, indicated +:: by the loobs in the type +:: %saw-seam marks all notifications in an inbox as unread +:: %saw-rope marks a particular rope as read in all inboxes +:: ++$ action + $% [%add-yarn all=? desk=? =yarn] + [%saw-seam =seam] + [%saw-rope =rope] + == +:: +:: $action-1: Actions for hark pt 2 ++$ action-1 + $% [%new-yarn new-yarn] + action + == +:: ++$ update + $: yarns=(map id yarn) + =seam + threads=(map time thread) + == +:: ++$ carpet + $: =seam + yarns=(map id yarn) + cable=(map rope thread) + stitch=@ud + == ++$ blanket + $: =seam + yarns=(map id yarn) + =quilt + == +:: $seam: inbox identifier +:: +:: All notifications end up in one of these inboxes ++$ seam + $% [%group =flag] + [%desk =desk] + [%all ~] + == +:: $rug: notifications inbox +:: .new contains all "unread" notifications, grouped by $rope +:: .qul is an archive +:: ++$ rug + [new=(map rope thread) qul=quilt] +++ quilt + =< quilt + |% + :: $quilt: inbox archive + :: Threads are keyed by an autoincrementing counter that starts at + :: 0 + :: + +$ quilt ((mop @ud thread) lte) + ++ on ((^on @ud thread) lte) + -- +:: +++ skein + $: =time + count=@ud + ship-count=@ud + top=yarn + unread=? + == +-- diff --git a/desk/sys.kelvin b/desk/sys.kelvin index f5efeaa2..5d8a35da 100644 --- a/desk/sys.kelvin +++ b/desk/sys.kelvin @@ -1 +1 @@ -[%zuse 413] +[%zuse 412] diff --git a/desk/ted/hosting/email.hoon b/desk/ted/hosting/email.hoon index d0ee47d6..b2ee53dd 100644 --- a/desk/ted/hosting/email.hoon +++ b/desk/ted/hosting/email.hoon @@ -53,7 +53,7 @@ ?> ?=(%finished -.rep) ?~ full-file.rep (pure:m !>(~)) =/ body=cord q.data.u.full-file.rep - =/ parsed=(unit json) (de-json:html body) + =/ parsed=(unit json) (de:json:html body) ?~ parsed (pure:m !>(~)) ?~ u.parsed (pure:m !>(~)) =/ mined (mine-json u.parsed) diff --git a/desk/ted/mail-hosted-user.hoon b/desk/ted/mail-hosted-user.hoon index 1928dd4a..3e71a7c0 100644 --- a/desk/ted/mail-hosted-user.hoon +++ b/desk/ted/mail-hosted-user.hoon @@ -27,7 +27,7 @@ %- send-raw-card :* %pass /check-email/(scot %p ship.u.args) %arvo %k %fard - %garden %hosting-email %noun + %landscape %hosting-email %noun !>(`[tlon-api-key.u.args ship.u.args]) == ;< [mire=wire mine=sign-arvo] bind:m take-sign-arvo @@ -43,7 +43,7 @@ %- send-raw-card :* %pass /send-mailchimp-email/(scot %p ship.u.args) %arvo %k %fard - %garden %mailchimp-send-template %noun + %landscape %mailchimp-send-template %noun !>(`[mandrill-api-key.u.args (trip email) "landscape-weekly-digest" (template-vars ship.u.args carpet.u.args)]) == ;< [wimp=wire simp=sign-arvo] bind:m take-sign-arvo diff --git a/desk/ted/mailchimp/ping.hoon b/desk/ted/mailchimp/ping.hoon index 45ac8472..145019d7 100644 --- a/desk/ted/mailchimp/ping.hoon +++ b/desk/ted/mailchimp/ping.hoon @@ -18,7 +18,7 @@ header-list=['Content-Type'^'application/json' ~] ^= body %- some %- as-octt:mimes:html - %- en-json:html + %- en:json:html %- pairs:enjs:format :~ ['key' s+(crip api-key)] == diff --git a/desk/ted/mailchimp/send-template.hoon b/desk/ted/mailchimp/send-template.hoon index 2e6e4145..a033ee53 100644 --- a/desk/ted/mailchimp/send-template.hoon +++ b/desk/ted/mailchimp/send-template.hoon @@ -24,7 +24,7 @@ ^= body %- some %- as-octt:mimes:html - %- en-json:html + %- en:json:html %- pairs:enjs:format :~ ['key' s+(crip api-key)] ['template_name' s+(crip template-name)] diff --git a/desk/ted/mailchimp/send.hoon b/desk/ted/mailchimp/send.hoon index 47e52ca0..ea4791dc 100644 --- a/desk/ted/mailchimp/send.hoon +++ b/desk/ted/mailchimp/send.hoon @@ -18,7 +18,7 @@ ^= body %- some %- as-octt:mimes:html - %- en-json:html + %- en:json:html %- pairs:enjs:format :~ ['key' s+(crip api-key)] :- 'message' diff --git a/desk/ted/mailchimp/update-merge-fields.hoon b/desk/ted/mailchimp/update-merge-fields.hoon index f269f8c1..e68ab9cb 100644 --- a/desk/ted/mailchimp/update-merge-fields.hoon +++ b/desk/ted/mailchimp/update-merge-fields.hoon @@ -27,7 +27,7 @@ ^= body %- some %- as-octt:mimes:html - %- en-json:html + %- en:json:html %- pairs:enjs:format ['merge_fields' o+vars]~ == diff --git a/desk/ted/save-summary.hoon b/desk/ted/save-summary.hoon index 839fb6e7..4d2022a2 100644 --- a/desk/ted/save-summary.hoon +++ b/desk/ted/save-summary.hoon @@ -25,7 +25,7 @@ %- send-raw-card :* %pass /check-email/(scot %p ship.args) %arvo %k %fard - %garden %hosting-email %noun + %landscape %hosting-email %noun !>(`[(trip tlon-api-key.args) ship.args]) == ;< [mire=wire mine=sign-arvo] bind:m take-sign-arvo @@ -41,7 +41,7 @@ %- send-raw-card :* %pass /update-merge-fields/(scot %p ship.args) %arvo %k %fard - %garden %mailchimp-update-merge-fields %noun + %landscape %mailchimp-update-merge-fields %noun =; vars=(map @t json) !>(`[mailchimp.args u.mail vars]) %- ~(gas by *(map @t json)) diff --git a/desk/tests/app/hark-store.hoon b/desk/tests/app/hark-store.hoon deleted file mode 100644 index 95230a86..00000000 --- a/desk/tests/app/hark-store.hoon +++ /dev/null @@ -1,103 +0,0 @@ -/- hark=hark-store -/+ *test, re=hark-unreads -/= agent /app/hark-store -|% -++ place - ^- place:hark - [%landscape /graph/~zod/test] -:: -++ bin - ^- bin:hark - [/ place] - -:: -++ body - |= run=@ - :* ~[text/'Title'] - ~[text/(crip "Contents {(scow %ud run)}")] - `time`(add (mul ~s1 run) *time) - / - /test - == -:: -++ add-note - |= run=@ - ^- action:hark - [%add-note bin (body run)] -:: -++ read-count - ^- action:hark - [%read-count place] -:: -+$ state - $: %9 - places=(map place:hark stats:hark) - seen=timebox:hark - unseen=timebox:hark - =archive:hark - half-open=(map bin:hark @da) - == -++ bowl - |= run=@ud - ^- bowl:gall - :* [~zod ~zod %hark-store] - [~ ~] - [run `@uvJ`(shax run) (add (mul run ~s1) *time) [~zod %garden ud+run]] - == --- -|% -:: -++ test-half-open - =| run=@ud - =^ mov1 agent - (~(on-poke agent (bowl run)) %hark-action !>((add-note run))) - =^ mova agent - (~(on-poke agent (bowl run)) %noun !>(%sane)) - =. run +(run) - =^ mov2 agent - (~(on-poke agent (bowl run)) %hark-action !>(read-count)) - =^ mov3 agent - (~(on-poke agent (bowl run)) %noun !>(%sane)) - =/ expected-archive=notification:hark - [(add *time (mul ~s1 0)) bin ~[(body 0)]] - =+ !<(=state on-save:agent) - =/ actual-archive=notification:hark - (~(got re archive.state) (add *time ~s1) bin) - (expect-eq !>(expected-archive) !>(actual-archive)) -:: -++ test-half-open-double - =| run=@ud - =^ mov1 agent - (~(on-poke agent (bowl run)) %hark-action !>((add-note run))) - =. run +(run) - =^ mov2 agent - (~(on-poke agent (bowl run)) %hark-action !>(read-count)) - =. run +(run) - =^ mov3 agent - (~(on-poke agent (bowl run)) %hark-action !>((add-note run))) - =. run +(run) - =^ mov4 agent - (~(on-poke agent (bowl run)) %hark-action !>(read-count)) - =. run +(run) - =^ mov5 agent - (~(on-poke agent (bowl run)) %noun !>(%sane)) - =/ expected-archive=notification:hark - [(add *time (mul ~s1 2)) bin ~[(body 2) (body 0)]] - =+ !<(=state on-save:agent) - =/ actual-archive=notification:hark - (~(got re archive.state) (add *time ~s1) bin) - (expect-eq !>(expected-archive) !>(actual-archive)) -:: -++ test-half-open-capped - =| run=@ud - |- - ?: =(run 31) - =+ !<(=state on-save:agent) - (expect-eq !>(~) !>(half-open.state)) - =^ movs agent - (~(on-poke agent (bowl run)) %hark-action !>((add-note run))) - =^ mavs agent - (~(on-poke agent (bowl run)) %hark-action !>(read-count)) - $(run +(run)) -:: --- diff --git a/ui/src/app.tsx b/ui/src/app.tsx index 9c878ede..d55bf617 100644 --- a/ui/src/app.tsx +++ b/ui/src/app.tsx @@ -30,11 +30,11 @@ const getNoteRedirect = (path: string) => { return `/apps/${desk}`; } - if (path.startsWith('/grid/')) { + if (path.startsWith('/landscape/')) { // Handle links to grid features (preferences, etc) const route = path .split('/') - .filter((el) => el !== 'grid') + .filter((el) => el !== 'landscape') .join('/'); return route; } @@ -68,8 +68,8 @@ const AppRoutes = () => { useEffect(() => { const query = new URLSearchParams(search); - if (query.has('grid-note')) { - const redir = getNoteRedirect(query.get('grid-note')!); + if (query.has('landscape-note')) { + const redir = getNoteRedirect(query.get('landscape-note')!); navigate(redir); } }, [search]); @@ -89,7 +89,7 @@ const AppRoutes = () => { useEffect( handleError(() => { - window.name = 'grid'; + window.name = 'landscape'; bootstrap(); @@ -124,7 +124,7 @@ function Scheduler() { } export function App() { - const base = import.meta.env.MODE === 'mock' ? undefined : '/apps/grid'; + const base = import.meta.env.MODE === 'mock' ? undefined : '/apps/landscape'; return ( diff --git a/ui/src/pages/PermalinkRoutes.tsx b/ui/src/pages/PermalinkRoutes.tsx index bf31950b..81efb04d 100644 --- a/ui/src/pages/PermalinkRoutes.tsx +++ b/ui/src/pages/PermalinkRoutes.tsx @@ -55,7 +55,7 @@ function AppLinkNavigate({ desk, link }: { desk: string; link: string }) { } const query = new URLSearchParams({ - 'grid-link': encodeURIComponent(`/${link}`), + 'landscape-link': encodeURIComponent(`/${link}`), }); const url = `${getAppHref(charge.href)}?${query.toString()}`; diff --git a/ui/src/preferences/InterfacePrefs.tsx b/ui/src/preferences/InterfacePrefs.tsx index a56690bb..daa2db9a 100644 --- a/ui/src/preferences/InterfacePrefs.tsx +++ b/ui/src/preferences/InterfacePrefs.tsx @@ -36,7 +36,7 @@ export function InterfacePrefs() { try { window.navigator.registerProtocolHandler( 'web+urbitgraph', - '/apps/grid/perma?ext=%s', + '/apps/landscape/perma?ext=%s', // @ts-expect-error ts has the wrong types for protocolhandler 'Urbit Links' ); @@ -53,7 +53,7 @@ export function InterfacePrefs() { // @ts-expect-error ts has the wrong types for protocolhandler window.navigator.unregisterProtocolHandler( 'web+urbitgraph', - '/apps/grid/perma?ext=%s' + '/apps/landscape/perma?ext=%s' ); setProtocolHandling(false); } catch (e) { diff --git a/ui/vite.config.ts b/ui/vite.config.ts index 96d0c1d8..64358af1 100644 --- a/ui/vite.config.ts +++ b/ui/vite.config.ts @@ -20,7 +20,7 @@ export default ({ mode }) => { console.log(SHIP_URL); return defineConfig({ - base: mode === 'mock' ? undefined : '/apps/grid/', + base: mode === 'mock' ? undefined : '/apps/landscape/', server: mode === 'mock' ? undefined : { https: true }, build: mode !== 'profile' @@ -50,7 +50,7 @@ export default ({ mode }) => { : [ basicSsl(), urbitPlugin({ - base: 'grid', + base: 'landscape', target: SHIP_URL, changeOrigin: true, secure: false,