Merge branch 'release/next-userspace' into lf/app-sane

This commit is contained in:
Logan Allen 2020-11-19 11:39:48 -06:00
commit b11b343280
505 changed files with 21614 additions and 23373 deletions

1
.gitattributes vendored
View File

@ -1,4 +1,3 @@
bin/* filter=lfs diff=lfs merge=lfs -text bin/* filter=lfs diff=lfs merge=lfs -text
bin/*/* filter=lfs diff=lfs merge=lfs -text bin/*/* filter=lfs diff=lfs merge=lfs -text
pkg/arvo/**/*.js binary
pkg/arvo/**/*.css binary pkg/arvo/**/*.css binary

11
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,11 @@
blank_issues_enabled: true
contact_links:
- name: Landscape design issue
url: https://github.com/urbit/landscape/issues/new?assignees=&labels=design+issue&template=report-a-design-issue.md&title=
about: Submit non-functionality, design-specific issues to the Landscape team here.
- name: Landscape feature request
url: https://github.com/urbit/landscape/issues/new?assignees=&labels=feature+request&template=feature_request.md&title=
about: Landscape is comprised of Tlon's user applications and client for Urbit. Submit Landscape feature requests here.
- name: urbit-dev mailing list
url: https://groups.google.com/a/urbit.org/g/dev
about: Developer questions and discussions also take place on the urbit-dev mailing list.

View File

@ -1,6 +1,6 @@
--- ---
name: OS1 Bug report name: Landscape bug report
about: 'Use this template to file a bug for any OS1 app: Chat, Publish, Links, Groups, about: 'Use this template to file a bug for any Landscape app: Chat, Publish, Links, Groups,
Weather or Clock' Weather or Clock'
title: '' title: ''
labels: landscape labels: landscape

View File

@ -2,12 +2,14 @@
Thank you for your interest in contributing to Urbit. Thank you for your interest in contributing to Urbit.
See [urbit.org/docs/getting-started][start] for basic orientation and usage See [urbit.org/using/install][start] for basic orientation and usage
instructions. You may also want to subscribe to [urbit-dev][list], the Urbit instructions. You may also want to subscribe to [urbit-dev][list], the Urbit
development mailing list. For specific information on contributing to the Urbit development mailing list. For specific information on contributing to the Urbit
interface, see its [contribution guidelines][interface]. interface, see its [contribution guidelines][interface].
[start]: https://urbit.org/docs/getting-started/#arvo For information on Arvo's maintainers, see [pkg/arvo][main].
[start]: https://urbit.org/using/install
[interface]: /pkg/interface/CONTRIBUTING.md [interface]: /pkg/interface/CONTRIBUTING.md
## Fake ships ## Fake ships
@ -36,6 +38,17 @@ To resume a fake ship, just pass the name of the pier:
$ urbit my-fake-zod $ urbit my-fake-zod
``` ```
Fake ships by default use the same pre-compiled kernelspace ('pills') as livenet
ships do: boot pills, which are not always current with `master`. If you wish to
develop using code off the master branch, run the following from the repo
directory:
```
git lfs install
git lfs pull
urbit -F zod -B "bin/solid.pill" -A "pkg/arvo"
```
## Git practice ## Git practice
### Contributing ### Contributing
@ -45,11 +58,10 @@ The canonical source tree is the `master` branch of
`master` when commencing new work; similarly, when we pull in your `master` when commencing new work; similarly, when we pull in your
contribution, we'll do so by merging it to `master`. contribution, we'll do so by merging it to `master`.
Since we use GitHub, it's helpful (though not required) to contribute via a Since we use GitHub, we request you contribute via a GitHub pull request. Tag
GitHub pull request. You can also post patches to the [mailing list][list], the [maintainer][main] for the component. If you have a question for the
email them to maintainers, or request a maintainer pull from your tree directly maintainer, you can direct message them from your Urbit ship using that
-- but note that some maintainers will be more receptive to these methods than information.
others.
When contributing changes, via whatever means, make sure you describe them When contributing changes, via whatever means, make sure you describe them
appropriately. You should attach a reasonably high-level summary of what the appropriately. You should attach a reasonably high-level summary of what the
@ -58,8 +70,8 @@ exist, e.g. a GitHub issue, a mailing list discussion, a UP, etc. [Here][jbpr]
is a good example of a pull request with a useful, concise description. is a good example of a pull request with a useful, concise description.
If your changes replace significant extant functionality, be sure to compare If your changes replace significant extant functionality, be sure to compare
them with the thing you're replacing. You may also want to cc maintainers, them with the thing you're replacing. You may also want to cc reviewers,
reviewers, or other parties who might have a particular interest in what you're or other parties who might have a particular interest in what you're
contributing. contributing.
[jbpr]: https://github.com/urbit/urbit/pull/1782 [jbpr]: https://github.com/urbit/urbit/pull/1782
@ -283,3 +295,4 @@ Questions or other communications about contributing to Urbit can go to
[reba]: https://git-rebase.io/ [reba]: https://git-rebase.io/
[issu]: https://github.com/urbit/urbit/issues [issu]: https://github.com/urbit/urbit/issues
[hoon]: https://urbit.org/docs/learn/hoon/style/ [hoon]: https://urbit.org/docs/learn/hoon/style/
[main]: https://github.com/urbit/urbit/tree/master/pkg/arvo#maintainers

View File

@ -1,27 +1,38 @@
# Urbit # Urbit
A personal server operating function. [Urbit](https://urbit.org) is a personal server stack built from scratch. It
has an identity layer (Azimuth), virtual machine (Vere), and operating system
(Arvo).
> The Urbit address space, Azimuth, is now live on the Ethereum blockchain. You A running Urbit "ship" is designed to operate with other ships peer-to-peer.
> can find it at [`0x223c067f8cf28ae173ee5cafea60ca44c335fecb`][azim] or Urbit is a general-purpose, peer-to-peer computer and network.
> [`azimuth.eth`][aens]. Owners of Azimuth points (galaxies, stars, or planets)
> can view or manage them using [Bridge][brid], and can also use them to boot This repository contains:
> [Arvo][arvo], the Urbit OS.
- The [Arvo OS][arvo]
- [herb][herb], a tool for Unix control of an Urbit ship
- Source code for [Landscape's web interface][land]
- Source code for the [vere][vere] virtual machine.
For more on the identity layer, see [Azimuth][azim]. To manage your Urbit
identity, use [Bridge][brid].
[azim]: https://etherscan.io/address/0x223c067f8cf28ae173ee5cafea60ca44c335fecb
[aens]: https://etherscan.io/address/azimuth.eth
[brid]: https://github.com/urbit/bridge
[arvo]: https://github.com/urbit/urbit/tree/master/pkg/arvo [arvo]: https://github.com/urbit/urbit/tree/master/pkg/arvo
[azim]: https://github.com/urbit/azimuth
[brid]: https://github.com/urbit/bridge
[herb]: https://github.com/urbit/urbit/tree/master/pkg/herb
[land]: https://github.com/urbit/urbit/tree/master/pkg/interface
[vere]: https://github.com/urbit/urbit/tree/master/pkg/urbit
## Install ## Install
To install and run Urbit, please follow the instructions at To install and run Urbit, please follow the instructions at
[urbit.org/docs/getting-started/][start]. You'll be on the live network in a [urbit.org/using/install][start]. You'll be on the live network in a
few minutes. few minutes.
If you're interested in Urbit development, keep reading. If you're interested in Urbit development, keep reading.
[start]: https://urbit.org/docs/getting-started/ [start]: https://urbit.org/using/install/
## Development ## Development
@ -38,7 +49,7 @@ The Makefile in the project's root directory contains useful phony targets for
building, installing, testing, and so on. You can use it to avoid dealing with building, installing, testing, and so on. You can use it to avoid dealing with
Nix explicitly. Nix explicitly.
To build Urbit, for example, use: To build the Urbit virtual machine binary, for example, use:
``` ```
make build make build
@ -68,12 +79,10 @@ Contributions of any form are more than welcome! Please take a look at our
[contributing guidelines][cont] for details on our git practices, coding [contributing guidelines][cont] for details on our git practices, coding
styles, how we manage issues, and so on. styles, how we manage issues, and so on.
You might also be interested in: For instructions on contributing to Landscape, see [its][lcont] guidelines.
- joining the [urbit-dev][list] mailing list. You might also be interested in joining the [urbit-dev][list] mailing list.
- [applying to Hoon School][mail], a course we run to teach the Hoon
programming language and Urbit application development.
[list]: https://groups.google.com/a/urbit.org/forum/#!forum/dev [list]: https://groups.google.com/a/urbit.org/forum/#!forum/dev
[mail]: mailto:support@urbit.org
[cont]: https://github.com/urbit/urbit/blob/master/CONTRIBUTING.md [cont]: https://github.com/urbit/urbit/blob/master/CONTRIBUTING.md
[lcont]: https://github.com/urbit/urbit/blob/master/pkg/interface/CONTRIBUTING.md

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:cfb556a9e6b473f6cf6c75b30a3b12cb986e57df1600dad4383b9d3380cffdb6 oid sha256:76de5b7d0a764af59018acdb78b5bbfb47f93bc166b0179d12501cdc84070f80
size 6263010 size 6316045

View File

@ -33,7 +33,7 @@ To boot a fake ship with a custom pill, use the `-B` flag:
urbit -F zod -A /path/to/arvo -B /path/to.pill -c fakezod urbit -F zod -A /path/to/arvo -B /path/to.pill -c fakezod
``` ```
To run all tests in `/tests`, run `+test` in dojo. `+test /some/path` would only run all tests in `/tests/some/path`. To run all tests in `/tests`, run `-test %/tests` in dojo. To run only the tests in `/tests/some/path`, use `-test %/tests/some/path`.
## Maintainers ## Maintainers
@ -41,20 +41,20 @@ Most parts of Arvo have dedicated maintainers.
* `/sys/hoon`: @pilfer-pandex (~pilfer-pandex) * `/sys/hoon`: @pilfer-pandex (~pilfer-pandex)
* `/sys/zuse`: @pilfer-pandex (~pilfer-pandex) * `/sys/zuse`: @pilfer-pandex (~pilfer-pandex)
* `/sys/arvo`: @jtobin (~nidsut-tomdun) * `/sys/arvo`: @joemfb (~master-morzod)
* `/sys/vane/ames`: @belisarius222 (~rovnys-ricfer) & @joemfb (~master-morzod) * `/sys/vane/ames`: @belisarius222 (~rovnys-ricfer) & @philipcmonk (~wicdev-wisryt)
* `/sys/vane/behn`: @belisarius222 (~rovnys-ricfer) * `/sys/vane/behn`: @belisarius222 (~rovnys-ricfer)
* `/sys/vane/clay`: @philipcmonk (~wicdev-wisryt) * `/sys/vane/clay`: @philipcmonk (~wicdev-wisryt) & @belisarius222 (~rovnys-ricfer)
* `/sys/vane/dill`: @bernardodelaplaz (~rigdyn-sondur) * `/sys/vane/dill`: @joemfb (~master-morzod)
* `/sys/vane/eyre`: @eglaysher (~littel-ponnys) * `/sys/vane/eyre`: @eglaysher (~littel-ponnys)
* `/sys/vane/ford`: @belisarius222 (~rovnys-ricfer) & @eglaysher (~littel-ponnys) * `/sys/vane/gall`: @philipcmonk (~wicdev-wisryt)
* `/sys/vane/gall`: @jtobin (~nidsut-tomdun) * `/sys/vane/jael`: @fang- (~palfun-foslup) & @philipcmonk (~wicdev-wisryt)
* `/sys/vane/jael`: @fang- (~palfun-foslup) & @joemfb (~master-morzod)
* `/app/acme`: @joemfb (~master-morzod) * `/app/acme`: @joemfb (~master-morzod)
* `/app/dns`: @joemfb (~master-morzod) * `/app/dns`: @joemfb (~master-morzod)
* `/app/hall`: @fang- (~palfun-foslup)
* `/app/talk`: @fang- (~palfun-foslup)
* `/app/aqua`: @philipcmonk (~wicdev-wisryt) * `/app/aqua`: @philipcmonk (~wicdev-wisryt)
* `/app/hood`: @belisarius222 (~rovnys-ricfer)
* `/lib/hood/drum`: @philipcmonk (~wicdev-wisryt)
* `/lib/hood/kiln`: @philipcmonk (~wicdev-wisryt)
* `/lib/test`: @eglaysher (~littel-ponnys) * `/lib/test`: @eglaysher (~littel-ponnys)
## Contributing ## Contributing

View File

@ -1,4 +1,4 @@
/- asn1, hall /- asn1
/+ base64, der, primitive-rsa, *pkcs, *jose, default-agent, verb /+ base64, der, primitive-rsa, *pkcs, *jose, default-agent, verb
=, eyre =, eyre
=* rsa primitive-rsa =* rsa primitive-rsa
@ -1023,7 +1023,7 @@
:: ::
=> .(liv (some fig), rod ~) => .(liv (some fig), rod ~)
?> ?=(^ liv) ?> ?=(^ liv)
:: notify :hall :: notify %dill
:: ::
=> =/ msg=cord => =/ msg=cord
%+ rap 3 %+ rap 3
@ -1229,7 +1229,7 @@
:: ::
?: (bad-nonce rep) ?: (bad-nonce rep)
(nonce:effect [act spur]) (nonce:effect [act spur])
:: XX replace with :hall notification :: XX replace with %dill notification
:: ::
~| [%http-response-fail wire] ~| [%http-response-fail wire]
%. [spur rep] %. [spur rep]
@ -1398,7 +1398,7 @@
this this
=. ..emit (queue-next-order 1 | dom) =. ..emit (queue-next-order 1 | dom)
=. ..emit cancel-current-order =. ..emit cancel-current-order
:: notify :hall :: notify %dill
:: ::
=. ..emit =. ..emit
=/ msg=cord =/ msg=cord

View File

@ -10,7 +10,7 @@
:: and trust it to take care of the rest. :: and trust it to take care of the rest.
:: ::
/- view=chat-view, hook=chat-hook, *group, /- view=chat-view, hook=chat-hook, *group,
*permission-store, *group-store, *invite-store, *permission-store, *group-store, inv=invite-store,
sole sole
/+ shoe, default-agent, verb, dbug, store=chat-store, /+ shoe, default-agent, verb, dbug, store=chat-store,
group-store, grpl=group, resource group-store, grpl=group, resource
@ -27,7 +27,7 @@
+$ state-2 +$ state-2
$: %2 $: %2
grams=(list mail) :: all messages grams=(list mail) :: all messages
known=(set [target serial]) :: known message lookup known=(set [target serial:store]) :: known message lookup
count=@ud :: (lent grams) count=@ud :: (lent grams)
bound=(map target glyph) :: bound circle glyphs bound=(map target glyph) :: bound circle glyphs
binds=(jug glyph target) :: circle glyph lookup binds=(jug glyph target) :: circle glyph lookup
@ -54,7 +54,7 @@
:: ::
+$ state-0 +$ state-0
$: grams=(list [[=ship =path] envelope:store]) :: all messages $: grams=(list [[=ship =path] envelope:store]) :: all messages
known=(set [[=ship =path] serial]) :: known message lookup known=(set [[=ship =path] serial:store]) :: known message lookup
count=@ud :: (lent grams) count=@ud :: (lent grams)
bound=(map [=ship =path] glyph) :: bound circle glyphs bound=(map [=ship =path] glyph) :: bound circle glyphs
binds=(jug glyph [=ship =path]) :: circle glyph lookup binds=(jug glyph [=ship =path]) :: circle glyph lookup
@ -161,7 +161,7 @@
%fact %fact
?+ p.cage.sign ~|([%chat-cli-bad-sub-mark wire p.cage.sign] !!) ?+ p.cage.sign ~|([%chat-cli-bad-sub-mark wire p.cage.sign] !!)
%chat-update (diff-chat-update:tc wire !<(update:store q.cage.sign)) %chat-update (diff-chat-update:tc wire !<(update:store q.cage.sign))
%invite-update (handle-invite-update:tc !<(invite-update q.cage.sign)) %invite-update (handle-invite-update:tc !<(update:inv q.cage.sign))
== ==
== ==
[cards this] [cards this]
@ -224,9 +224,9 @@
grams ~ ::NOTE this only impacts historic message lookup in chat-cli grams ~ ::NOTE this only impacts historic message lookup in chat-cli
:: ::
known known
^- (set [target serial]) ^- (set [target serial:store])
%- ~(run in known.u.old) %- ~(run in known.u.old)
|= [t=[ship path] s=serial] |= [t=[ship path] s=serial:store]
[`target`[| t] s] [`target`[| t] s]
:: ::
bound bound
@ -324,7 +324,7 @@
:: +handle-invite-update: get new invites :: +handle-invite-update: get new invites
:: ::
++ handle-invite-update ++ handle-invite-update
|= upd=invite-update |= upd=update:inv
^- (quip card _state) ^- (quip card _state)
?+ -.upd [~ state] ?+ -.upd [~ state]
%invite [[(show-invite:sh-out invite.upd) ~] state] %invite [[(show-invite:sh-out invite.upd) ~] state]
@ -534,10 +534,10 @@
:: ;~(pfix ace ;~(plug i.opt $(opt t.opt))) :: ;~(pfix ace ;~(plug i.opt $(opt t.opt)))
:: -- :: --
:: ::
++ group ;~((glue net) ship sym) ++ group ;~((glue fas) ship sym)
++ tag |*(a=@tas (cold a (jest a))) ::TODO into stdlib ++ tag |*(a=@tas (cold a (jest a))) ::TODO into stdlib
++ ship ;~(pfix sig fed:ag) ++ ship ;~(pfix sig fed:ag)
++ path ;~(pfix net ;~(plug urs:ab (easy ~))) ::NOTE short only, tmp ++ path ;~(pfix fas ;~(plug urs:ab (easy ~))) ::NOTE short only, tmp
:: +mang: un/managed indicator prefix :: +mang: un/managed indicator prefix
:: ::
:: deprecated, as sig prefix is no longer used :: deprecated, as sig prefix is no longer used
@ -619,7 +619,7 @@
++ letter ++ letter
;~ pose ;~ pose
(stag %url turl) (stag %url turl)
(stag %me ;~(pfix vat text)) (stag %me ;~(pfix pat text))
(stag %text ;~(less mic hax text)) (stag %text ;~(less mic hax text))
== ==
:: +turl: url parser :: +turl: url parser
@ -722,12 +722,11 @@
%poke %poke
%invite-action %invite-action
:: ::
!> !> ^- action:inv
^- invite-action :^ %invite %chat
:^ %invite /chat
(shax (jam [our-self where] who)) (shax (jam [our-self where] who))
^- invite ^- invite:inv
[our-self %chat-hook where who ''] [our-self %chat-hook (de-path:resource where) who '']
== ==
:: +set-target: set audience, update prompt :: +set-target: set audience, update prompt
:: ::
@ -865,7 +864,7 @@
|= =letter:store |= =letter:store
^- (quip card _state) ^- (quip card _state)
~! bowl ~! bowl
=/ =serial (shaf %msg-uid eny.bowl) =/ =serial:store (shaf %msg-uid eny.bowl)
:_ state :_ state
^- (list card) ^- (list card)
%+ turn ~(tap in audience) %+ turn ~(tap in audience)
@ -1132,11 +1131,9 @@
:: +show-invite: print incoming invite notification :: +show-invite: print incoming invite notification
:: ::
++ show-invite ++ show-invite
|= invite |= invite:inv
^- card ^- card
%- note (note "invited to: {(scow %p entity.resource)} {(trip name.resource)}")
%+ weld "invited to: "
~(phat tr (path-to-target path))
-- --
:: ::
:: +tr: render targets :: +tr: render targets

View File

@ -1,8 +1,8 @@
:: chat-hook: :: chat-hook [landscape]:
:: mirror chat data from foreign to local based on read permissions :: mirror chat data from foreign to local based on read permissions
:: allow sending chat messages to foreign paths based on write perms :: allow sending chat messages to foreign paths based on write perms
:: ::
/- *permission-store, *invite-store, *metadata-store, /- *permission-store, inv=invite-store, *metadata-store,
*permission-hook, *group-store, *permission-group-hook, ::TMP for upgrade *permission-hook, *group-store, *permission-group-hook, ::TMP for upgrade
hook=chat-hook, hook=chat-hook,
view=chat-view, view=chat-view,
@ -22,8 +22,14 @@
state-5 state-5
state-6 state-6
state-7 state-7
state-8
state-9
state-10
== ==
:: ::
+$ state-10 [%10 state-base]
+$ state-9 [%9 state-base]
+$ state-8 [%8 state-base]
+$ state-7 [%7 state-base] +$ state-7 [%7 state-base]
+$ state-6 [%6 state-base] +$ state-6 [%6 state-base]
+$ state-5 [%5 state-base] +$ state-5 [%5 state-base]
@ -46,7 +52,7 @@
+$ poke +$ poke
$% [%chat-action action:store] $% [%chat-action action:store]
[%permission-action permission-action] [%permission-action permission-action]
[%invite-action invite-action] [%invite-action action:inv]
[%chat-view-action action:view] [%chat-view-action action:view]
== ==
:: ::
@ -54,7 +60,7 @@
$% [%chat-update update:store] $% [%chat-update update:store]
== ==
-- --
=| state-7 =| state-10
=* state - =* state -
:: ::
%- agent:dbug %- agent:dbug
@ -71,7 +77,7 @@
++ on-init ++ on-init
^- (quip card _this) ^- (quip card _this)
:_ this(invite-created %.y) :_ this(invite-created %.y)
:~ (invite-poke:cc [%create /chat]) :~ (invite-poke:cc [%create %chat])
[%pass /invites %agent [our.bol %invite-store] %watch /invitatory/chat] [%pass /invites %agent [our.bol %invite-store] %watch /invitatory/chat]
watch-groups:cc watch-groups:cc
== ==
@ -83,8 +89,20 @@
=/ old !<(versioned-state old-vase) =/ old !<(versioned-state old-vase)
=| cards=(list card) =| cards=(list card)
|- |-
?: ?=(%7 -.old) ?: ?=(%10 -.old)
[cards this(state old)] [cards this(state old)]
?: ?=(%9 -.old)
=. cards
:_ cards
[%pass /self-poke %agent [our.bol %chat-hook] %poke %noun !>(%run-upg9)]
$(-.old %10)
?: ?=(%8 -.old)
$(-.old %9)
?: ?=(%7 -.old)
=. cards
:_ cards
[%pass /self-poke %agent [our.bol %chat-hook] %poke %noun !>(%run-upg7)]
$(-.old %8)
?: ?=(%6 -.old) ?: ?=(%6 -.old)
=. cards =. cards
%+ weld cards %+ weld cards
@ -160,6 +178,17 @@
^- (list (list card)) ^- (list (list card))
(turn ~(tap in keys) generate-cards) (turn ~(tap in keys) generate-cards)
== ==
::
++ scry-for
|* [=mold app=term =path]
.^ mold
%gx
(scot %p our.bol)
app
(scot %da now.bol)
(snoc `^path`path %noun)
==
::
++ kick-old-subs ++ kick-old-subs
|= old-path=path |= old-path=path
^- (list card) ^- (list card)
@ -335,7 +364,8 @@
?+ mark (on-poke:def mark vase) ?+ mark (on-poke:def mark vase)
%json (poke-json:cc !<(json vase)) %json (poke-json:cc !<(json vase))
%chat-action (poke-chat-action:cc !<(action:store vase)) %chat-action (poke-chat-action:cc !<(action:store vase))
%noun (poke-noun:cc !<(?(%fix-dm %fix-out-of-sync) vase)) %noun
(poke-noun:cc !<(?(%fix-dm %fix-out-of-sync %run-upg7 %run-upg9) vase))
:: ::
%chat-hook-action %chat-hook-action
(poke-chat-hook-action:cc !<(action:hook vase)) (poke-chat-hook-action:cc !<(action:hook vase))
@ -376,7 +406,7 @@
:: ::
%invite-update %invite-update
=^ cards state =^ cards state
(fact-invite-update:cc wire !<(invite-update q.cage.sign)) (fact-invite-update:cc wire !<(update:inv q.cage.sign))
[cards this] [cards this]
:: ::
%group-update %group-update
@ -398,15 +428,100 @@
++ grp ~(. grpl bol) ++ grp ~(. grpl bol)
:: ::
++ poke-noun ++ poke-noun
|= a=?(%fix-dm %fix-out-of-sync) |= a=?(%fix-dm %fix-out-of-sync %run-upg7 %run-upg9)
^- (quip card _state) ^- (quip card _state)
|^ |^
:_ state
?- a ?- a
%fix-dm (fix-dm %fix-dm) %fix-dm [(fix-dm %fix-dm) state]
%fix-out-of-sync (fix-out-of-sync %fix-out-of-sync) %fix-out-of-sync [(fix-out-of-sync %fix-out-of-sync) state]
%run-upg7 run-7-to-8
%run-upg9 run-9-to-10
== ==
:: ::
++ scry-for
|* [=mold app=term =path]
.^ mold
%gx
(scot %p our.bol)
app
(scot %da now.bol)
(snoc `^path`path %noun)
==
::
++ add-synced
|= [=ship =path]
^- card
=- [%pass / %agent [our.bol %chat-hook] %poke %chat-hook-action -]
!>(`action:hook`[%add-synced ship path %.y])
::
++ add-owned
|= [=path history=?]
^- card
=- [%pass / %agent [our.bol %chat-hook] %poke %chat-hook-action -]
!>(`action:hook`[%add-owned path history])
::
++ run-7-to-8
^- (quip card _state)
:_ state
=/ subscribers=(jug path ship)
%+ roll ~(val by sup.bol)
|= [[=ship =path] out=(jug path ship)]
:: /(mailbox|backlog)/~ship/resource.name
::
?. ?=([@ @ @ *] path) out
=/ pax=^path [i.t.path i.t.t.path ~]
(~(put ju out) pax ship)
=/ group ~(. grpl bol)
^- (list card)
%+ murn ~(tap in ~(key by synced.state))
|= =path
^- (unit card)
?> ?=([@ @ ~] path)
=/ group-paths (groups-of-chat path)
?~ group-paths ~
=/ members (members-from-path:group i.group-paths)
?: (is-managed-path:group i.group-paths) ~
=/ ships=(set ship) (~(get ju subscribers) path)
%- some
=+ [%invite path (~(dif in members) ships)]
[%pass /inv %agent [our.bol %chat-view] %poke %chat-view-action !>(-)]
::
++ run-9-to-10
^- (quip card _state)
:_
=/ list-paths=(list path)
%+ murn ~(tap in ~(key by synced.state))
|= =app=path
^- (unit path)
?~ (groups-of-chat app-path)
`app-path
~
|-
?~ list-paths
state
=. synced.state (~(del by synced.state) i.list-paths)
$(list-paths t.list-paths)
%+ weld
^- (list card)
%+ roll ~(tap in ~(key by wex.bol))
|= [[=wire =ship =term] out=(list card)]
?> ?=([@ *] wire)
?. ?&(=(ship our.bol) =(term %chat-hook))
out
:_ out
=- [%pass / %agent [our.bol %chat-hook] %poke %chat-hook-action !>(-)]
[%remove t.wire]
=/ chat-keys=(set path) (scry-for (set path) %chat-store [%keys ~])
^- (list card)
%+ turn ~(tap in chat-keys)
|= =app=path
^- card
?> ?=([@ @ ~] app-path)
=/ =ship (slav %p i.app-path)
?: =(ship our.bol)
(add-owned app-path %.y)
(add-synced ship app-path)
::
++ fix-out-of-sync ++ fix-out-of-sync
|= b=%fix-out-of-sync |= b=%fix-out-of-sync
^- (list card) ^- (list card)
@ -523,6 +638,7 @@
:: ::
%add-synced %add-synced
?> (team:title our.bol src.bol) ?> (team:title our.bol src.bol)
?< =(ship.act our.bol)
?: (~(has by synced) path.act) [~ state] ?: (~(has by synced) path.act) [~ state]
=. synced (~(put by synced) path.act ship.act) =. synced (~(put by synced) path.act ship.act)
?. ask-history.act ?. ask-history.act
@ -603,15 +719,18 @@
== ==
:: ::
++ fact-invite-update ++ fact-invite-update
|= [wir=wire fact=invite-update] |= [wir=wire fact=update:inv]
^- (quip card _state) ^- (quip card _state)
:_ state :_ state
?+ -.fact ~ ?+ -.fact ~
%accepted %accepted
=/ ask-history ?~((chat-scry path.invite.fact) %.y %.n) =* resource resource.invite.fact
=* shp ship.invite.fact =/ =path [(scot %p entity.resource) name.resource ~]
=* app-path path.invite.fact :_ ~
~[(chat-view-poke [%join shp app-path ask-history])] %- chat-view-poke
:^ %join ship.invite.fact
path
?=(~ (chat-scry path))
== ==
:: ::
++ fact-group-update ++ fact-group-update
@ -789,13 +908,7 @@
?: =(i.t.wir '~') ?: =(i.t.wir '~')
?> ?=(^ chat) ?> ?=(^ chat)
(migrate-listen t.chat) (migrate-listen t.chat)
:_ state [~ state]
%. ~[(chat-view-poke %delete chat)]
%- slog
:* leaf+"chat-hook failed subscribe on {(spud chat)}"
leaf+"stack trace:"
u.saw
==
== ==
:: ::
++ chat-poke ++ chat-poke
@ -809,9 +922,9 @@
[%pass / %agent [our.bol %chat-view] %poke %chat-view-action !>(act)] [%pass / %agent [our.bol %chat-view] %poke %chat-view-action !>(act)]
:: ::
++ invite-poke ++ invite-poke
|= act=invite-action |= =action:inv
^- card ^- card
[%pass / %agent [our.bol %invite-store] %poke %invite-action !>(act)] [%pass / %agent [our.bol %invite-store] %poke %invite-action !>(action)]
:: ::
++ sec-to-perm ++ sec-to-perm
|= [pax=path =kind] |= [pax=path =kind]
@ -826,9 +939,9 @@
[%mailbox pax] [%mailbox pax]
:: ::
++ invite-scry ++ invite-scry
|= uid=serial |= uid=serial:inv
^- (unit invite) ^- (unit invite:inv)
%^ scry (unit invite) %^ scry (unit invite:inv)
%invite-store %invite-store
/invite/chat/(scot %uv uid) /invite/chat/(scot %uv uid)
:: ::

View File

@ -1,4 +1,6 @@
:: chat-store: data store that holds linear sequences of chat messages :: chat-store [landscape]:
::
:: data store that holds linear sequences of chat messages
:: ::
/+ store=chat-store, default-agent, verb, dbug, group-store /+ store=chat-store, default-agent, verb, dbug, group-store
~% %chat-store-top ..is ~ ~% %chat-store-top ..is ~

View File

@ -1,10 +1,12 @@
:: chat-view: sets up chat JS client, paginates data, and combines commands :: chat-view [landscape]:
::
:: sets up chat JS client, paginates data, and combines commands
:: into semantic actions for the UI :: into semantic actions for the UI
:: ::
/- *permission-store, /- *permission-store,
*permission-hook, *permission-hook,
*group, *group,
*invite-store, inv=invite-store,
*metadata-store, *metadata-store,
group-hook, group-hook,
*permission-group-hook, *permission-group-hook,
@ -218,8 +220,7 @@
~& %chat-already-exists ~& %chat-already-exists
~ ~
%- zing %- zing
:~ (create-chat app-path.act allow-history.act) :~ %- create-group
%- create-group
:* group-path.act :* group-path.act
app-path.act app-path.act
policy.act policy.act
@ -229,6 +230,7 @@
managed.act managed.act
== ==
(create-metadata title.act description.act group-path.act app-path.act) (create-metadata title.act description.act group-path.act app-path.act)
(create-chat app-path.act allow-history.act)
== ==
:: ::
%delete %delete
@ -295,6 +297,7 @@
~[(chat-hook-poke %add-synced ship.act app-path.act ask-history.act)] ~[(chat-hook-poke %add-synced ship.act app-path.act ask-history.act)]
=/ rid=resource =/ rid=resource
(de-path:resource ship+app-path.act) (de-path:resource ship+app-path.act)
?: =(our.bol entity.rid) ~
=/ =cage =/ =cage
:- %group-update :- %group-update
!> ^- action:group-store !> ^- action:group-store
@ -404,13 +407,14 @@
^- card ^- card
=/ managed=? =/ managed=?
!=(ship+app-path group-path) !=(ship+app-path group-path)
=/ =invite =/ =invite:inv
:* our.bol :* our.bol
?:(managed %contact-hook %chat-hook) ?:(managed %contact-hook %chat-hook)
?:(managed group-path app-path) (de-path:resource ?:(managed group-path ship+app-path))
ship '' ship ''
== ==
=/ act=invite-action [%invite ?:(managed /contacts /chat) (shaf %msg-uid eny.bol) invite] =/ act=action:inv
[%invite ?:(managed %contacts %chat) (shaf %msg-uid eny.bol) invite]
[%pass / %agent [our.bol %invite-hook] %poke %invite-action !>(act)] [%pass / %agent [our.bol %invite-hook] %poke %invite-action !>(act)]
:: ::
++ chat-scry ++ chat-scry
@ -484,8 +488,8 @@
(en-path:resource rid) (en-path:resource rid)
?> ?=(^ path) ?> ?=(^ path)
:~ (group-pull-hook-poke %add ship rid) :~ (group-pull-hook-poke %add ship rid)
(chat-hook-poke %add-synced ship t.path ask-history)
(metadata-hook-poke %add-synced ship path) (metadata-hook-poke %add-synced ship path)
(chat-hook-poke %add-synced ship t.path ask-history)
== ==
:: ::
++ diff-chat-update ++ diff-chat-update

View File

@ -1,4 +1,6 @@
:: clock: deprecated, should be removed :: clock [landscape]:
::
:: deprecated, should be removed
:: ::
/+ *server, default-agent, verb, dbug /+ *server, default-agent, verb, dbug
=, format =, format

View File

@ -1,9 +1,10 @@
:: contact-hook: :: contact-hook [landscape]
::
:: ::
/- group-hook, /- group-hook,
*contact-hook, *contact-hook,
*contact-view, *contact-view,
*invite-store, inv=invite-store,
*metadata-hook, *metadata-hook,
*metadata-store, *metadata-store,
*group *group
@ -43,7 +44,7 @@
++ on-init ++ on-init
^- (quip card _this) ^- (quip card _this)
:_ this(invite-created %.y) :_ this(invite-created %.y)
:~ (invite-poke:cc [%create /contacts]) :~ (invite-poke:cc [%create %contacts])
[%pass /inv %agent [our.bol %invite-store] %watch /invitatory/contacts] [%pass /inv %agent [our.bol %invite-store] %watch /invitatory/contacts]
[%pass /group %agent [our.bol %group-store] %watch /groups] [%pass /group %agent [our.bol %group-store] %watch /groups]
== ==
@ -472,25 +473,10 @@
(contact-poke [%delete path]) (contact-poke [%delete path])
(contact-poke [%remove path ship]) (contact-poke [%remove path ship])
== ==
::
++ send-invite-poke
|= [=path =ship]
^- card
=/ =invite
:* our.bol %contact-hook
path ship ''
==
=/ act=invite-action [%invite /contacts (shaf %msg-uid eny.bol) invite]
[%pass / %agent [our.bol %invite-hook] %poke %invite-action !>(act)]
-- --
:: ::
++ group-hook-poke
|= =action:group-hook
^- card
[%pass / %agent [our.bol %group-hook] %poke %group-hook-action !>(action)]
::
++ invite-poke ++ invite-poke
|= act=invite-action |= act=action:inv
^- card ^- card
[%pass / %agent [our.bol %invite-store] %poke %invite-action !>(act)] [%pass / %agent [our.bol %invite-store] %poke %invite-action !>(act)]
:: ::
@ -499,26 +485,6 @@
^- card ^- card
[%pass / %agent [our.bol %contact-store] %poke %contact-action !>(act)] [%pass / %agent [our.bol %contact-store] %poke %contact-action !>(act)]
:: ::
++ contact-view-poke
|= act=contact-view-action
^- card
[%pass / %agent [our.bol %contact-view] %poke %contact-view-action !>(act)]
::
++ group-poke
|= act=action:group-store
^- card
[%pass / %agent [our.bol %group-store] %poke %group-action !>(act)]
::
++ metadata-poke
|= act=metadata-action
^- card
[%pass / %agent [our.bol %metadata-store] %poke %metadata-action !>(act)]
::
++ metadata-hook-poke
|= act=metadata-hook-action
^- card
[%pass / %agent [our.bol %metadata-hook] %poke %metadata-hook-action !>(act)]
::
++ contacts-scry ++ contacts-scry
|= pax=path |= pax=path
^- (unit contacts) ^- (unit contacts)
@ -530,16 +496,6 @@
== ==
.^((unit contacts) %gx pax) .^((unit contacts) %gx pax)
:: ::
++ invite-scry
|= uid=serial
^- (unit invite)
=/ pax
;: weld
/(scot %p our.bol)/invite-store/(scot %da now.bol)
/invite/contacts/(scot %uv uid)/noun
==
.^((unit invite) %gx pax)
::
++ group-scry ++ group-scry
|= pax=path |= pax=path
.^ (unit group) .^ (unit group)

View File

@ -1,4 +1,6 @@
:: contact-store: data store that holds group-based contact data :: contact-store [landscape]:
::
:: data store that holds group-based contact data
:: ::
/+ *contact-json, default-agent, dbug /+ *contact-json, default-agent, dbug
|% |%

View File

@ -1,9 +1,11 @@
:: contact-view: sets up contact JS client and combines commands :: contact-view [landscape]:
::
:: sets up contact JS client and combines commands
:: into semantic actions for the UI :: into semantic actions for the UI
:: ::
/- /-
group-hook, group-hook,
*invite-store, inv=invite-store,
*contact-hook, *contact-hook,
*metadata-store, *metadata-store,
*metadata-hook, *metadata-hook,
@ -159,27 +161,22 @@
%+ turn %+ turn
~(tap in pending.policy.act) ~(tap in pending.policy.act)
|= =ship |= =ship
(send-invite our.bol %contacts path ship '') (send-invite our.bol %contacts rid ship '')
== ==
:: ::
%join %join
=/ =path
(en-path:resource resource.act)
=/ =cage =/ =cage
:- %group-update :- %group-update
!> ^- update:group-store !> ^- update:group-store
[%add-members resource.act (sy our.bol ~)] [%add-members resource.act (sy our.bol ~)]
=/ =wire =/ =wire
[%join-group path] [%join-group (en-path:resource resource.act)]
[%pass wire %agent [entity.resource.act %group-push-hook] %poke cage]~ [%pass wire %agent [entity.resource.act %group-push-hook] %poke cage]~
:: ::
%invite %invite
=* rid resource.act =* rid resource.act
=/ =path =/ =group (need (scry-group:grp rid))
(en-path:resource rid) :- (send-invite entity.rid %contacts rid ship.act text.act)
=/ =group
(need (scry-group:grp rid))
:- (send-invite entity.rid %contacts path ship.act text.act)
?. ?=(%invite -.policy.group) ~ ?. ?=(%invite -.policy.group) ~
~[(add-pending rid ship.act)] ~[(add-pending rid ship.act)]
:: ::
@ -274,12 +271,12 @@
[%pass / %agent [entity.rid app] %poke cage] [%pass / %agent [entity.rid app] %poke cage]
:: ::
++ send-invite ++ send-invite
|= =invite |= =invite:inv
^- card ^- card
=/ =cage =/ =cage
:- %invite-action :- %invite-action
!> ^- invite-action !> ^- action:inv
[%invite /contacts (shaf %invite-uid eny.bol) invite] [%invite %contacts (shaf %invite-uid eny.bol) invite]
[%pass / %agent [recipient.invite %invite-hook] %poke cage] [%pass / %agent [recipient.invite %invite-hook] %poke cage]
:: ::
++ contact-poke ++ contact-poke

View File

@ -380,17 +380,19 @@
'connected'^b+!-.state 'connected'^b+!-.state
'expiry'^?-(-.state %& (time date.p.state), %| ~) 'expiry'^?-(-.state %& (time date.p.state), %| ~)
'next-id'^(numb next-id) 'next-id'^(numb next-id)
'last-ack'^(time last-ack)
'unacked'^a+(turn (sort (turn ~(tap in events) head) dor) numb) 'unacked'^a+(turn (sort (turn ~(tap in events) head) dor) numb)
:: ::
:- 'subscriptions' :- 'subscriptions'
:- %a :- %a
%+ turn ~(tap by subscriptions) %+ turn ~(tap by subscriptions)
|= [=wire [=^ship app=term =^path *]] |= [id=@ud [=^ship app=term =^path *]]
%- pairs %- pairs
:~ 'wire'^(^path wire) :~ 'id'^(numb id)
'ship'^(^ship ship) 'ship'^(^ship ship)
'app'^s+app 'app'^s+app
'path'^(^path path) 'path'^(^path path)
'unacked'^(numb (~(gut by unacked) id 0))
== ==
== ==
== ==

File diff suppressed because one or more lines are too long

View File

@ -165,7 +165,7 @@
== ==
== ==
:: ::
;~ pfix net ;~ pfix fas
;~ pose ;~ pose
(parse-variable (cold %sur hep) ;~(pfix gap parse-cables)) (parse-variable (cold %sur hep) ;~(pfix gap parse-cables))
(parse-variable (cold %lib lus) ;~(pfix gap parse-cables)) (parse-variable (cold %lib lus) ;~(pfix gap parse-cables))
@ -179,8 +179,8 @@
++ parse-sink ++ parse-sink
;~ pose ;~ pose
;~(plug (cold %file tar) parse-beam) ;~(plug (cold %file tar) parse-beam)
;~(plug (cold %flat vat) (most net sym)) ;~(plug (cold %flat pat) (most fas sym))
;~(plug (cold %pill dot) (most net sym)) ;~(plug (cold %pill dot) (most fas sym))
;~(plug (cold %http lus) (stag %post parse-url)) ;~(plug (cold %http lus) (stag %post parse-url))
;~(plug (cold %http hep) (stag %put parse-url)) ;~(plug (cold %http hep) (stag %put parse-url))
(stag %show (cook $?($1 $2 $3 $4 $5) (cook lent (stun [1 5] wut)))) (stag %show (cook $?($1 $2 $3 $4 $5) (cook lent (stun [1 5] wut))))
@ -218,7 +218,7 @@
;~(plug (cold %ur lus) parse-url) ;~(plug (cold %ur lus) parse-url)
;~(plug (cold %ge lus) parse-model) ;~(plug (cold %ge lus) parse-model)
;~(plug (cold %te hep) sym (star ;~(pfix ace parse-source))) ;~(plug (cold %te hep) sym (star ;~(pfix ace parse-source)))
;~(plug (cold %as pad) sym ;~(pfix ace parse-source)) ;~(plug (cold %as pam) sym ;~(pfix ace parse-source))
;~(plug (cold %do cab) parse-hoon ;~(pfix ace parse-source)) ;~(plug (cold %do cab) parse-hoon ;~(pfix ace parse-source))
parse-value parse-value
== ==
@ -228,7 +228,7 @@
;~ pose ;~ pose
;~ plug ;~ plug
;~(pfix sig fed:ag) ;~(pfix sig fed:ag)
;~(pose ;~(pfix net sym) (easy default-app)) ;~(pose ;~(pfix fas sym) (easy default-app))
== ==
%+ stag our %+ stag our
;~(pose sym (easy default-app)) ;~(pose sym (easy default-app))
@ -263,7 +263,7 @@
auri:de-purl:html auri:de-purl:html
:: ::
++ parse-model ;~(plug parse-server parse-config) ++ parse-model ;~(plug parse-server parse-config)
++ parse-server (stag 0 (most net sym)) ++ parse-server (stag 0 (most fas sym))
++ parse-hoon tall:hoon-parser ++ parse-hoon tall:hoon-parser
:: ::
++ parse-rood ++ parse-rood
@ -284,9 +284,10 @@
== ==
++ parse-value ++ parse-value
;~ pose ;~ pose
(stag %sa ;~(pfix tar pad sym)) ;~(plug (cold %as pam) sym ;~(pfix ace parse-source))
(stag %sa ;~(pfix tar pam sym))
(stag %ex parse-hoon) (stag %ex parse-hoon)
(stag %tu (ifix [lac rac] (most ace parse-source))) (stag %tu (ifix [sel ser] (most ace parse-source)))
== ==
:: ::
++ parse-config ++ parse-config

View File

@ -1,5 +1,9 @@
:: file-server [landscape]:
::
:: mounts HTTP endpoints for Landscape (and third-party) user applications
::
/- srv=file-server, glob /- srv=file-server, glob
/+ *server, default-agent, verb, dbug /+ *server, default-agent, verb, dbug, version
|% |%
+$ card card:agent:gall +$ card card:agent:gall
+$ serving (map url-base=path [=content public=? single-page=?]) +$ serving (map url-base=path [=content public=? single-page=?])
@ -316,24 +320,11 @@
++ on-peek ++ on-peek
|= =path |= =path
^- (unit (unit cage)) ^- (unit (unit cage))
|^
?+ path (on-peek:def path) ?+ path (on-peek:def path)
[%x %clay %base %hash ~] ``hash+!>(base-hash) [%x %clay %base %hash ~]
=/ versions (base-hash:version [our now]:bowl)
``hash+!>(?~(versions 0v0 (end 0 25 i.versions)))
== ==
:: stolen from +trouble
:: TODO: move to a lib?
++ base-hash
^- @uv
=+ .^ ota=(unit [=ship =desk =aeon:clay])
%gx /(scot %p our.bowl)/hood/(scot %da now.bowl)/kiln/ota/noun
==
?~ ota
*@uv
=/ parent (scot %p ship.u.ota)
=+ .^(=cass:clay %cs /[parent]/[desk.u.ota]/1/late/foo)
%^ end 0 25
.^(@uv %cz /[parent]/[desk.u.ota]/(scot %ud ud.cass))
--
++ on-agent on-agent:def ++ on-agent on-agent:def
++ on-fail on-fail:def ++ on-fail on-fail:def
-- --

View File

@ -1,7 +1,11 @@
:: glob [landscape]:
::
:: prompts content delivery and Gall state storage for Landscape JS blob
::
/- glob /- glob
/+ default-agent, verb, dbug /+ default-agent, verb, dbug
|% |%
++ hash 0v6.8fpt6.7mcjg.nb019.df3fo.haav6 ++ hash 0v5.67obv.15auf.c2rc7.jpcu2.iain3
+$ state-0 [%0 hash=@uv glob=(unit (each glob:glob tid=@ta))] +$ state-0 [%0 hash=@uv glob=(unit (each glob:glob tid=@ta))]
+$ all-states +$ all-states
$% state-0 $% state-0
@ -81,20 +85,33 @@
%glob-make %glob-make
:_ this :_ this
=/ home=path /(scot %p our.bowl)/home/(scot %da now.bowl) =/ home=path /(scot %p our.bowl)/home/(scot %da now.bowl)
=+ .^(=tube:clay %cc (weld home /js/mime)) =+ .^(=js=tube:clay %cc (weld home /js/mime))
=+ .^(=map=tube:clay %cc (weld home /map/mime))
=+ .^(arch %cy (weld home /app/landscape/js/bundle)) =+ .^(arch %cy (weld home /app/landscape/js/bundle))
=/ bundle=path =/ bundle-hash=@t
%- need %- need
^- (unit path) ^- (unit @t)
%- ~(rep by dir) %- ~(rep by dir)
|= [[file=@t ~] out=(unit path)] |= [[file=@t ~] out=(unit @t)]
?^ out out ?^ out out
?. =((end 3 5 file) 'index') ?. ?& =((end 3 6 file) 'index.')
~ !=('sj.' (end 3 3 (swp 3 file)))
`/[file]/js ==
=+ .^(js=@t %cx :(weld home /app/landscape/js/bundle bundle)) out
=+ !<(=mime (tube !>(js))) ``@t`(rsh 3 6 file)
=/ =glob:glob (~(put by *glob:glob) bundle mime) =/ js-name
(cat 3 'index.' bundle-hash)
=/ map-name
(cat 3 js-name '.js')
=+ .^(js=@t %cx :(weld home /app/landscape/js/bundle /[js-name]/js))
=+ .^(map=@t %cx :(weld home /app/landscape/js/bundle /[map-name]/map))
=+ !<(=js=mime (js-tube !>(js)))
=+ !<(=map=mime (map-tube !>(map)))
=/ =glob:glob
%- ~(gas by *glob:glob)
:~ /[js-name]/js^js-mime
/[map-name]/map^map-mime
==
=/ =path /(cat 3 'glob-' (scot %uv (sham glob)))/glob =/ =path /(cat 3 'glob-' (scot %uv (sham glob)))/glob
[%pass /make %agent [our.bowl %hood] %poke %drum-put !>([path (jam glob)])]~ [%pass /make %agent [our.bowl %hood] %poke %drum-put !>([path (jam glob)])]~
:: ::

View File

@ -0,0 +1,50 @@
/- *resource
/+ store=graph-store, graph, default-agent, verb, dbug, pull-hook
~% %graph-pull-hook-top ..is ~
|%
+$ card card:agent:gall
++ config
^- config:pull-hook
:* %graph-store
update:store
%graph-update
%graph-push-hook
==
--
::
%- agent:dbug
^- agent:gall
%- (agent:pull-hook config)
^- (pull-hook:pull-hook config)
|_ =bowl:gall
+* this .
def ~(. (default-agent this %|) bowl)
dep ~(. (default:pull-hook this config) bowl)
gra ~(. graph bowl)
::
++ on-init on-init:def
++ on-save !>(~)
++ on-load on-load:def
++ on-poke on-poke:def
++ on-peek on-peek:def
++ on-arvo on-arvo:def
++ on-fail on-fail:def
++ on-agent on-agent:def
++ on-watch on-watch:def
++ on-leave on-leave:def
++ on-pull-nack
|= [=resource =tang]
^- (quip card _this)
:_ this
?. (~(has in get-keys:gra) resource) ~
=- [%pass /pull-nack %agent [our.bowl %graph-store] %poke %graph-update -]~
!> ^- update:store
[%0 now.bowl [%archive-graph resource]]
::
++ on-pull-kick
|= =resource
^- (unit path)
=/ maybe-time (peek-update-log:gra resource)
?~ maybe-time `/
`/(scot %da u.maybe-time)
--

View File

@ -0,0 +1,146 @@
/+ store=graph-store
/+ metadata
/+ res=resource
/+ graph
/+ group
/+ default-agent
/+ dbug
/+ push-hook
~% %graph-push-hook-top ..is ~
|%
+$ card card:agent:gall
++ config
^- config:push-hook
:* %graph-store
/updates
update:store
%graph-update
%graph-pull-hook
==
::
+$ agent (push-hook:push-hook config)
::
++ is-allowed
|= [=resource:res =bowl:gall requires-admin=?]
^- ?
=/ grp ~(. group bowl)
=/ met ~(. metadata bowl)
=/ group-paths (groups-from-resource:met [%graph (en-path:res resource)])
?~ group-paths %.n
?: requires-admin
(is-admin:grp src.bowl i.group-paths)
?| (is-member:grp src.bowl i.group-paths)
(is-admin:grp src.bowl i.group-paths)
==
::
++ is-allowed-remove
|= [=resource:res indices=(set index:store) =bowl:gall]
^- ?
=/ gra ~(. graph bowl)
?. (is-allowed resource bowl %.n)
%.n
%+ levy
~(tap in indices)
|= =index:store
^- ?
=/ =node:store
(got-node:gra resource index)
?| =(author.post.node src.bowl)
(is-allowed resource bowl %.y)
==
--
::
%- agent:dbug
^- agent:gall
%- (agent:push-hook config)
^- agent
|_ =bowl:gall
+* this .
def ~(. (default-agent this %|) bowl)
grp ~(. group bowl)
gra ~(. graph bowl)
::
++ on-init on-init:def
++ on-save !>(~)
++ on-load on-load:def
++ on-poke on-poke:def
++ on-agent on-agent:def
++ on-watch on-watch:def
++ on-leave on-leave:def
++ on-peek on-peek:def
++ on-arvo on-arvo:def
++ on-fail on-fail:def
::
++ should-proxy-update
|= =vase
^- ?
=/ =update:store !<(update:store vase)
?- -.q.update
%add-graph (is-allowed resource.q.update bowl %.y)
%remove-graph (is-allowed resource.q.update bowl %.y)
%add-nodes (is-allowed resource.q.update bowl %.n)
%remove-nodes (is-allowed-remove resource.q.update indices.q.update bowl)
%add-signatures (is-allowed resource.uid.q.update bowl %.n)
%remove-signatures (is-allowed resource.uid.q.update bowl %.y)
%archive-graph (is-allowed resource.q.update bowl %.y)
%unarchive-graph %.n
%add-tag %.n
%remove-tag %.n
%keys %.n
%tags %.n
%tag-queries %.n
%run-updates (is-allowed resource.q.update bowl %.y)
==
::
++ resource-for-update
|= =vase
^- (unit resource:res)
=/ =update:store !<(update:store vase)
?- -.q.update
%add-graph `resource.q.update
%remove-graph `resource.q.update
%add-nodes `resource.q.update
%remove-nodes `resource.q.update
%add-signatures `resource.uid.q.update
%remove-signatures `resource.uid.q.update
%archive-graph `resource.q.update
%unarchive-graph ~
%add-tag ~
%remove-tag ~
%keys ~
%tags ~
%tag-queries ~
%run-updates `resource.q.update
==
::
++ initial-watch
|= [=path =resource:res]
^- vase
?> (is-allowed resource bowl %.n)
!> ^- update:store
?~ path
:: new subscribe
::
(get-graph:gra resource)
:: resubscribe
::
?~ (get-update-log:gra resource)
(get-graph:gra resource)
=/ =time (slav %da i.path)
=/ =update-log:store (get-update-log-subset:gra resource time)
[%0 now.bowl [%run-updates resource update-log]]
::
++ take-update
|= =vase
^- [(list card) agent]
=/ =update:store !<(update:store vase)
?+ -.q.update [~ this]
%remove-graph
:_ this
[%give %kick ~[resource+(en-path:res resource.q.update)] ~]~
::
%archive-graph
:_ this
[%give %kick ~[resource+(en-path:res resource.q.update)] ~]~
==
--

View File

@ -1,17 +1,26 @@
:: graph-store [landscape]
::
::
/+ store=graph-store, sigs=signatures, res=resource, default-agent, dbug /+ store=graph-store, sigs=signatures, res=resource, default-agent, dbug
~% %graph-store-top ..is ~ ~% %graph-store-top ..is ~
|% |%
+$ card card:agent:gall +$ card card:agent:gall
+$ versioned-state +$ versioned-state
$% state-0 $% state-0
state-1
state-2
== ==
:: ::
+$ state-0 [%0 network:store] +$ state-0 [%0 network:store]
+$ state-1 [%1 network:store]
+$ state-2 [%2 network:store]
::
++ orm orm:store ++ orm orm:store
++ orm-log orm-log:store ++ orm-log orm-log:store
+$ debug-input [%validate-graph =resource:store]
-- --
:: ::
=| state-0 =| state-2
=* state - =* state -
:: ::
%- agent:dbug %- agent:dbug
@ -24,9 +33,160 @@
++ on-init [~ this] ++ on-init [~ this]
++ on-save !>(state) ++ on-save !>(state)
++ on-load ++ on-load
|= old=vase |= =old=vase
^- (quip card _this) ^- (quip card _this)
[~ this(state !<(state-0 old))] =+ !<(old=versioned-state old-vase)
=| cards=(list card)
|^
?- -.old
%0
%_ $
-.old %1
::
validators.old
(~(put in validators.old) %graph-validator-link)
::
cards
%+ weld cards
%+ turn
~(tap in (~(put in validators.old) %graph-validator-link))
|= validator=@t
^- card
=/ =wire /validator/[validator]
=/ =rave:clay [%sing %b [%da now.bowl] /[validator]]
[%pass wire %arvo %c %warp our.bowl [%home `rave]]
::
graphs.old
%- ~(run by graphs.old)
|= [=graph:store q=(unit mark)]
^- [graph:store (unit mark)]
:- (convert-unix-timestamped-graph graph)
?^ q q
`%graph-validator-link
::
update-logs.old
%- ~(run by update-logs.old)
|=(a=* *update-log:store)
==
::
%1
%_ $
-.old %2
graphs.old (~(run by graphs.old) change-revision-graph)
::
update-logs.old
%- ~(run by update-logs.old)
|=(a=* *update-log:store)
==
::
%2 [cards this(state old)]
==
::
++ change-revision-graph
|= [=graph:store q=(unit mark)]
^- [graph:store (unit mark)]
|^
:_ q
?+ q graph
[~ %graph-validator-link] convert-links
[~ %graph-validator-publish] convert-publish
==
::
++ convert-links
%+ gas:orm *graph:store
%+ turn (tap:orm graph)
|= [=atom =node:store]
^- [^atom node:store]
:: top-level
::
:+ atom post.node
?: ?=(%empty -.children.node)
[%empty ~]
:- %graph
%+ gas:orm *graph:store
%+ turn (tap:orm p.children.node)
|= [=^atom =node:store]
^- [^^atom node:store]
:: existing comments get turned into containers for revisions
::
:^ atom
post.node(contents ~, hash ~)
%graph
%+ gas:orm *graph:store
:_ ~ :- %1
:_ [%empty ~]
post.node(index (snoc index.post.node atom), hash ~)
::
++ convert-publish
%+ gas:orm *graph:store
%+ turn (tap:orm graph)
|= [=atom =node:store]
^- [^atom node:store]
:: top-level
::
:+ atom post.node
?: ?=(%empty -.children.node)
[%empty ~]
:- %graph
%+ gas:orm *graph:store
%+ turn (tap:orm p.children.node)
|= [=^atom =node:store]
^- [^^atom node:store]
:: existing container for publish note revisions
::
?+ atom !!
%1 [atom node]
%2
:+ atom post.node
?: ?=(%empty -.children.node)
[%empty ~]
:- %graph
%+ gas:orm *graph:store
%+ turn (tap:orm p.children.node)
|= [=^^atom =node:store]
^- [^^^atom node:store]
:+ atom post.node(contents ~, hash ~)
:- %graph
%+ gas:orm *graph:store
:_ ~ :- %1
:_ [%empty ~]
post.node(index (snoc index.post.node atom), hash ~)
==
--
::
++ maybe-unix-to-da
|= =atom
^- @
:: (bex 127) is roughly 226AD
?. (lte atom (bex 127))
atom
(add ~1970.1.1 (div (mul ~s1 atom) 1.000))
::
++ convert-unix-timestamped-node
|= =node:store
^- node:store
=. index.post.node
(convert-unix-timestamped-index index.post.node)
?. ?=(%graph -.children.node)
node
:+ post.node
%graph
(convert-unix-timestamped-graph p.children.node)
::
++ convert-unix-timestamped-index
|= =index:store
(turn index maybe-unix-to-da)
::
++ convert-unix-timestamped-graph
|= =graph:store
%+ gas:orm *graph:store
%+ turn
(tap:orm graph)
|= [=atom =node:store]
^- [^atom node:store]
:- (maybe-unix-to-da atom)
(convert-unix-timestamped-node node)
--
:: ::
++ on-watch ++ on-watch
~/ %graph-store-watch ~/ %graph-store-watch
@ -57,6 +217,7 @@
=^ cards state =^ cards state
?+ mark (on-poke:def mark vase) ?+ mark (on-poke:def mark vase)
%graph-update (graph-update !<(update:store vase)) %graph-update (graph-update !<(update:store vase))
%noun (debug !<(debug-input vase))
== ==
[cards this] [cards this]
:: ::
@ -65,6 +226,7 @@
^- (quip card _state) ^- (quip card _state)
|^ |^
?> ?=(%0 -.update) ?> ?=(%0 -.update)
=? p.update =(p.update *time) now.bowl
?- -.q.update ?- -.q.update
%add-graph (add-graph +.q.update) %add-graph (add-graph +.q.update)
%remove-graph (remove-graph +.q.update) %remove-graph (remove-graph +.q.update)
@ -83,23 +245,30 @@
== ==
:: ::
++ add-graph ++ add-graph
|= [=resource:store =graph:store mark=(unit mark:store)] |= $: =resource:store
=graph:store
mark=(unit mark:store)
overwrite=?
==
^- (quip card _state) ^- (quip card _state)
?< (~(has by archive) resource) ?> ?| overwrite
?< (~(has by graphs) resource) ?& !(~(has by archive) resource)
!(~(has by graphs) resource)
== ==
?> (validate-graph graph mark) ?> (validate-graph graph mark)
:_ %_ state :_ %_ state
graphs (~(put by graphs) resource [graph mark]) graphs (~(put by graphs) resource [graph mark])
update-logs (~(put by update-logs) resource (gas:orm-log ~ ~)) update-logs (~(put by update-logs) resource (gas:orm-log ~ ~))
archive (~(del by archive) resource)
validators validators
?~ mark validators ?~ mark validators
(~(put in validators) u.mark) (~(put in validators) u.mark)
== ==
%- zing %- zing
:~ (give [/updates /keys ~] [%add-graph resource graph mark]) :~ (give [/updates /keys ~] [%add-graph resource graph mark overwrite])
?~ mark ~ ?~ mark ~
?: (~(has in validators) u.mark) ~ ?: (~(has in validators) u.mark) ~
=/ wire (weld /graph (en-path:res resource)) =/ wire /validator/[u.mark]
=/ =rave:clay [%sing %b [%da now.bowl] /[u.mark]] =/ =rave:clay [%sing %b [%da now.bowl] /[u.mark]]
[%pass wire %arvo %c %warp our.bowl [%home `rave]]~ [%pass wire %arvo %c %warp our.bowl [%home `rave]]~
== ==
@ -185,7 +354,7 @@
=/ =hash:store `@ux`(sham validated-portion) =/ =hash:store `@ux`(sham validated-portion)
?~ hash.p node(signatures.post *signatures:store) ?~ hash.p node(signatures.post *signatures:store)
~| "signatures do not match the calculated hash" ~| "signatures do not match the calculated hash"
?> (are-signatures-valid:sigs signatures.p hash now.bowl) ?> (are-signatures-valid:sigs our.bowl signatures.p hash now.bowl)
~| "hash of post does not match calculated hash" ~| "hash of post does not match calculated hash"
?> =(hash u.hash.p) ?> =(hash u.hash.p)
node node
@ -293,7 +462,7 @@
~| "cannot add signatures to a node missing a hash" ~| "cannot add signatures to a node missing a hash"
?> ?=(^ hash.post.node) ?> ?=(^ hash.post.node)
~| "signatures did not match public keys!" ~| "signatures did not match public keys!"
?> (are-signatures-valid:sigs signatures u.hash.post.node now.bowl) ?> (are-signatures-valid:sigs our.bowl signatures u.hash.post.node now.bowl)
node(signatures.post (~(uni in signatures) signatures.post.node)) node(signatures.post (~(uni in signatures) signatures.post.node))
~| "child graph does not exist to add signatures to!" ~| "child graph does not exist to add signatures to!"
?> ?=(%graph -.children.node) ?> ?=(%graph -.children.node)
@ -392,52 +561,57 @@
^- (quip card _state) ^- (quip card _state)
?< (~(has by archive) resource) ?< (~(has by archive) resource)
?> (~(has by graphs) resource) ?> (~(has by graphs) resource)
:_ state =/ updates=(list [=time upd=logged-update:store])
%+ turn (tap:orm-log update-log) (tap:orm-log update-log)
|= [=time update=logged-update:store] =| cards=(list card)
^- card |- ^- (quip card _state)
?> ?=(%0 -.update) ?~ updates
:* %pass [cards state]
/run-updates/(scot %da time) =* update upd.i.updates
%agent =^ crds state
[our.bowl %graph-store] %- graph-update
%poke ^- update:store
:- %graph-update ?- -.q.update
!> %add-nodes update(resource.q resource)
^- update:store %remove-nodes update(resource.q resource)
?- -.q.update %add-signatures update(resource.uid.q resource)
%add-nodes update(resource.q resource) %remove-signatures update(resource.uid.q resource)
%remove-nodes update(resource.q resource)
%add-signatures update(resource.uid.q resource)
%remove-signatures update(resource.uid.q resource)
==
==
::
++ validate-graph
|= [=graph:store mark=(unit mark:store)]
^- ?
?~ mark %.y
?~ graph %.y
=/ =dais:clay
.^ =dais:clay
%cb
/(scot %p our.bowl)/[q.byk.bowl]/(scot %da now.bowl)/[u.mark]
== ==
%+ roll (tap:orm graph) $(cards (weld cards crds), updates t.updates)
|= [[=atom =node:store] out=?]
?& out
=(%& -:(mule |.((vale:dais [atom post.node]))))
?- -.children.node
%empty %.y
%graph ^$(graph p.children.node)
==
==
:: ::
++ give ++ give
|= [paths=(list path) update=update-0:store] |= [paths=(list path) update=update-0:store]
^- (list card) ^- (list card)
[%give %fact paths [%graph-update !>([%0 now.bowl update])]]~ [%give %fact paths [%graph-update !>([%0 now.bowl update])]]~
-- --
::
++ debug
|= =debug-input
^- (quip card _state)
=/ [=graph:store mark=(unit mark:store)]
(~(got by graphs) resource.debug-input)
?> (validate-graph graph mark)
[~ state]
::
++ validate-graph
|= [=graph:store mark=(unit mark:store)]
^- ?
?~ mark %.y
?~ graph %.y
=/ =dais:clay
.^ =dais:clay
%cb
/(scot %p our.bowl)/[q.byk.bowl]/(scot %da now.bowl)/[u.mark]
==
%+ roll (tap:orm graph)
|= [[=atom =node:store] out=?]
?& out
=(%& -:(mule |.((vale:dais [atom post.node]))))
?- -.children.node
%empty %.y
%graph ^$(graph p.children.node)
==
==
-- --
:: ::
++ on-peek ++ on-peek
@ -447,16 +621,53 @@
|^ |^
?> (team:title our.bowl src.bowl) ?> (team:title our.bowl src.bowl)
?+ path (on-peek:def path) ?+ path (on-peek:def path)
[%x %keys ~] ``noun+!>(~(key by graphs)) [%x %graph-mark @ @ ~]
[%x %tags ~] ``noun+!>(~(key by tag-queries)) =/ =ship (slav %p i.t.t.path)
[%x %tag-queries ~] ``noun+!>(tag-queries) =/ =term i.t.t.t.path
=/ result=(unit marked-graph:store)
(~(get by graphs) [ship term])
?~ result [~ ~]
``noun+!>(q.u.result)
::
[%x %keys ~]
:- ~ :- ~ :- %graph-update
!>(`update:store`[%0 now.bowl [%keys ~(key by graphs)]])
::
[%x %tags ~]
:- ~ :- ~ :- %graph-update
!>(`update:store`[%0 now.bowl [%tags ~(key by tag-queries)]])
::
[%x %tag-queries ~]
:- ~ :- ~ :- %graph-update
!>(`update:store`[%0 now.bowl [%tag-queries tag-queries]])
::
[%x %graph @ @ ~] [%x %graph @ @ ~]
=/ =ship (slav %p i.t.t.path) =/ =ship (slav %p i.t.t.path)
=/ =term i.t.t.t.path =/ =term i.t.t.t.path
=/ result=(unit marked-graph:store) =/ result=(unit marked-graph:store)
(~(get by graphs) [ship term]) (~(get by graphs) [ship term])
?~ result [~ ~] ?~ result [~ ~]
``noun+!>(u.result) :- ~ :- ~ :- %graph-update
!> ^- update:store
:+ %0
now.bowl
[%add-graph [ship term] `graph:store`p.u.result q.u.result %.y]
::
:: note: near-duplicate of /x/graph
::
[%x %archive @ @ ~]
=/ =ship (slav %p i.t.t.path)
=/ =term i.t.t.t.path
=/ result=(unit marked-graph:store)
(~(get by archive) [ship term])
?~ result
~& no-archived-graph+[ship term]
[~ ~]
:- ~ :- ~ :- %graph-update
!> ^- update:store
:+ %0
now.bowl
[%add-graph [ship term] `graph:store`p.u.result q.u.result %.y]
:: ::
[%x %graph-subset @ @ @ @ ~] [%x %graph-subset @ @ @ @ ~]
=/ =ship (slav %p i.t.t.path) =/ =ship (slav %p i.t.t.path)
@ -466,37 +677,31 @@
=/ graph=(unit marked-graph:store) =/ graph=(unit marked-graph:store)
(~(get by graphs) [ship term]) (~(get by graphs) [ship term])
?~ graph [~ ~] ?~ graph [~ ~]
``noun+!>(`graph:store`(subset:orm p.u.graph start end)) :- ~ :- ~ :- %graph-update
!> ^- update:store
:+ %0 now.bowl
:+ %add-nodes
[ship term]
%- ~(gas by *(map index:store node:store))
%+ turn (tap:orm `graph:store`(subset:orm p.u.graph start end))
|= [=atom =node:store]
^- [index:store node:store]
[~[atom] node]
:: ::
[%x %node @ @ @ *] [%x %node @ @ @ *]
=/ =ship (slav %p i.t.t.path) =/ =ship (slav %p i.t.t.path)
=/ =term i.t.t.t.path =/ =term i.t.t.t.path
=/ =index:store =/ =index:store
(turn t.t.t.t.path |=(=cord (slav %ud cord))) (turn t.t.t.t.path (cury slav %ud))
=/ node=(unit node:store) (get-node ship term index) =/ node=(unit node:store) (get-node ship term index)
?~ node [~ ~] ?~ node [~ ~]
``noun+!>(u.node) :- ~ :- ~ :- %graph-update
:: !> ^- update:store
[%x %post @ @ @ *] :+ %0
=/ =ship (slav %p i.t.t.path) now.bowl
=/ =term i.t.t.t.path :+ %add-nodes
=/ =index:store [ship term]
(turn t.t.t.t.path |=(=cord (slav %ud cord))) (~(gas by *(map index:store node:store)) [index u.node] ~)
=/ node=(unit node:store) (get-node ship term index)
?~ node [~ ~]
``noun+!>(post.u.node)
::
[%x %node-children @ @ @ *]
=/ =ship (slav %p i.t.t.path)
=/ =term i.t.t.t.path
=/ =index:store
(turn t.t.t.t.path |=(=cord (slav %ud cord)))
=/ node=(unit node:store) (get-node ship term index)
?~ node [~ ~]
?- -.children.u.node
%empty [~ ~]
%graph ``noun+!>(p.children.u.node)
==
:: ::
[%x %node-children-subset @ @ @ @ @ *] [%x %node-children-subset @ @ @ @ @ *]
=/ =ship (slav %p i.t.t.path) =/ =ship (slav %p i.t.t.path)
@ -509,8 +714,29 @@
?~ node [~ ~] ?~ node [~ ~]
?- -.children.u.node ?- -.children.u.node
%empty [~ ~] %empty [~ ~]
%graph ``noun+!>(`graph:store`(subset:orm p.children.u.node start end)) %graph
:- ~ :- ~ :- %graph-update
!> ^- update:store
:+ %0
now.bowl
:+ %add-nodes
[ship term]
%- ~(gas by *(map index:store node:store))
%+ turn (tap:orm `graph:store`(subset:orm p.children.u.node end start))
|= [=atom =node:store]
^- [index:store node:store]
[(snoc index atom) node]
== ==
::
[%x %update-log-subset @ @ @ @ ~]
=/ =ship (slav %p i.t.t.path)
=/ =term i.t.t.t.path
=/ start=(unit time) (slaw %da i.t.t.t.t.path)
=/ end=(unit time) (slaw %da i.t.t.t.t.t.path)
=/ update-log=(unit update-log:store) (~(get by update-logs) [ship term])
?~ update-log [~ ~]
:: orm-log is ordered backwards, so swap start and end
``noun+!>((subset:orm-log u.update-log end start))
:: ::
[%x %update-log @ @ ~] [%x %update-log @ @ ~]
=/ =ship (slav %p i.t.t.path) =/ =ship (slav %p i.t.t.path)
@ -554,15 +780,15 @@
++ on-arvo ++ on-arvo
|= [=wire =sign-arvo] |= [=wire =sign-arvo]
^- (quip card _this) ^- (quip card _this)
?+ -.sign-arvo (on-arvo:def wire sign-arvo) ?+ wire (on-arvo:def wire sign-arvo)
%c ::
:: old wire, do nothing
[%graph *] [~ this]
::
[%validator @ ~]
:_ this :_ this
?> ?=([%graph @ *] wire) =* validator i.t.wire
=/ =resource:store (de-path:res t.wire) =/ =rave:clay [%next %b [%da now.bowl] /[validator]]
=/ gra=(unit marked-graph:store) (~(get by graphs) resource)
?~ gra ~
?~ q.u.gra ~
=/ =rave:clay [%next %b [%da now.bowl] /[u.q.u.gra]]
[%pass wire %arvo %c %warp our.bowl [%home `rave]]~ [%pass wire %arvo %c %warp our.bowl [%home `rave]]~
== ==
:: ::

View File

@ -1,4 +1,6 @@
:: group-hook: allow syncing group data from foreign paths to local paths :: group-hook [landscape]:
::
:: allow syncing group data from foreign paths to local paths
:: ::
/- *group, hook=group-hook, *invite-store /- *group, hook=group-hook, *invite-store
/+ default-agent, verb, dbug, store=group-store, grpl=group, pull-hook, push-hook, resource /+ default-agent, verb, dbug, store=group-store, grpl=group, pull-hook, push-hook, resource

View File

@ -1,5 +1,6 @@
:: group-hook: allow syncing group data from foreign paths to local paths :: group-hook [landscape]:
:: ::
:: allow syncing group data from foreign paths to local paths
:: ::
/- *group, hook=group-hook, *invite-store, *resource /- *group, hook=group-hook, *invite-store, *resource
/+ default-agent, verb, dbug, store=group-store, grpl=group, pull-hook /+ default-agent, verb, dbug, store=group-store, grpl=group, pull-hook

View File

@ -1,5 +1,6 @@
:: group-hook: allow syncing group data from foreign paths to local paths :: group-hook [landscape]:
:: ::
:: allow syncing group data from foreign paths to local paths
:: ::
/- *group, hook=group-hook, *invite-store /- *group, hook=group-hook, *invite-store
/+ default-agent, verb, dbug, store=group-store, grpl=group, push-hook, /+ default-agent, verb, dbug, store=group-store, grpl=group, push-hook,

View File

@ -1,4 +1,6 @@
:: group-store: Store groups of ships :: group-store [landscape]:
::
:: Store groups of ships
:: ::
:: group-store stores groups of ships, so that resources in other apps can be :: group-store stores groups of ships, so that resources in other apps can be
:: associated with a group. The current model of group-store rolls :: associated with a group. The current model of group-store rolls

View File

@ -0,0 +1,214 @@
:: hark-chat-hook: notifications for chat-store [landscape]
::
/- store=hark-store, post, group-store, metadata-store, hook=hark-chat-hook
/+ resource, metadata, default-agent, dbug, chat-store, grpl=group
::
~% %hark-chat-hook-top ..is ~
|%
+$ card card:agent:gall
+$ versioned-state
$% state-0
==
::
+$ state-0
$: %0
watching=(set path)
mentions=_&
==
::
--
::
=| state-0
=* state -
::
=>
|_ =bowl:gall
::
++ give
|= [paths=(list path) =update:hook]
^- (list card)
[%give %fact paths hark-chat-hook-update+!>(update)]~
::
++ watch-chat
^- card
[%pass /chat %agent [our.bowl %chat-store] %watch /all]
--
%- agent:dbug
^- agent:gall
~% %hark-chat-hook-agent ..card ~
|_ =bowl:gall
+* this .
ha ~(. +> bowl)
def ~(. (default-agent this %|) bowl)
met ~(. metadata bowl)
grp ~(. grpl bowl)
::
++ on-init
:_ this
~[watch-chat:ha]
::
++ on-save !>(state)
++ on-load
|= old=vase
^- (quip card _this)
:_ this(state !<(state-0 old))
?: (~(has by wex.bowl) [/chat our.bowl %chat-store])
~
~[watch-chat:ha]
::
++ on-watch
|= =path
^- (quip card _this)
=^ cards state
?+ path (on-watch:def path)
::
[%updates ~]
:_ state
%+ give:ha ~
:* %initial
watching
==
==
[cards this]
::
++ on-poke
~/ %hark-chat-hook-poke
|= [=mark =vase]
^- (quip card _this)
|^
?> (team:title our.bowl src.bowl)
=^ cards state
?+ mark (on-poke:def mark vase)
%hark-chat-hook-action
(hark-chat-hook-action !<(action:hook vase))
==
[cards this]
::
++ hark-chat-hook-action
|= =action:hook
^- (quip card _state)
|^
:- (give:ha ~[/updates] action)
?- -.action
%listen (listen +.action)
%ignore (ignore +.action)
%set-mentions (set-mentions +.action)
==
++ listen
|= chat=path
^+ state
state(watching (~(put in watching) chat))
::
++ ignore
|= chat=path
^+ state
state(watching (~(del in watching) chat))
::
++ set-mentions
|= ment=?
^+ state
state(mentions ment)
--
--
::
++ on-agent
~/ %hark-chat-hook-agent
|= [=wire =sign:agent:gall]
^- (quip card _this)
|^
?+ -.sign (on-agent:def wire sign)
%kick
:_ this
?. ?=([%chat ~] wire)
~
~[watch-chat:ha]
::
%fact
?. ?=(%chat-update p.cage.sign)
(on-agent:def wire sign)
=^ cards state
(chat-update !<(update:chat-store q.cage.sign))
[cards this]
==
::
++ chat-update
|= =update:chat-store
^- (quip card _state)
?+ -.update `state
%initial (process-initial +.update)
%create (process-new +.update)
::
%message
:_ state
(process-envelope path.update envelope.update)
::
%messages
:_ state
%- zing
(turn envelopes.update (cury process-envelope path.update))
==
++ process-initial
|= =inbox:chat-store
^- (quip card _state)
=/ keys=(list path)
~(tap in ~(key by inbox))
=| cards=(list card)
|-
?~ keys
[cards state]
=* path i.keys
=^ cs state
(process-new path)
$(cards (weld cards cs), keys t.keys)
::
++ process-new
|= chat=path
^- (quip card _state)
=/ groups=(list path)
(groups-from-resource:met %chat chat)
?~ groups
`state
?: (is-managed-path:grp i.groups)
`state
`state(watching (~(put in watching) chat))
::
++ is-mention
|= =envelope:chat-store
?. ?=(%text -.letter.envelope) %.n
?& mentions
?= ^
(find (scow %p our.bowl) (trip text.letter.envelope))
==
::
++ is-notification
|= [=path =envelope:chat-store]
?& (~(has in watching) path)
!=(author.envelope our.bowl)
==
::
++ process-envelope
|= [=path =envelope:chat-store]
^- (list card)
=/ mention=?
(is-mention envelope)
?. ?|(mention (is-notification path envelope))
~
=/ =index:store
[%chat path mention]
=/ =contents:store
[%chat ~[envelope]]
~[(poke-store %add index when.envelope %.n contents)]
::
++ poke-store
|= =action:store
^- card
=- [%pass /store %agent [our.bowl %hark-store] %poke -]
hark-action+!>(action)
--
::
++ on-peek on-peek:def
::
++ on-leave on-leave:def
++ on-arvo on-arvo:def
++ on-fail on-fail:def
--

View File

@ -0,0 +1,267 @@
:: hark-graph-hook: notifications for graph-store [landscape]
::
/- store=hark-store, post, group-store, metadata-store, hook=hark-graph-hook
/+ resource, metadata, default-agent, dbug, graph-store
::
~% %hark-graph-hook-top ..is ~
|%
+$ card card:agent:gall
+$ versioned-state
$% state-0
==
::
+$ state-0
$: %0
watching=(set [resource index:post])
mentions=_&
watch-on-self=_&
==
::
--
::
=| state-0
=* state -
::
=>
|_ =bowl:gall
::
++ 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:hook]
^- (list card)
[%give %fact paths hark-graph-hook-update+!>(update)]~
::
++ watch-graph
^- card
[%pass /graph %agent [our.bowl %graph-store] %watch /updates]
--
%- agent:dbug
^- agent:gall
~% %hark-graph-hook-agent ..card ~
|_ =bowl:gall
+* this .
ha ~(. +> bowl)
def ~(. (default-agent this %|) bowl)
met ~(. metadata bowl)
::
++ on-init
:_ this
~[watch-graph:ha]
::
++ on-save !>(state)
++ on-load
|= old=vase
^- (quip card _this)
`this(state !<(state-0 old))
::
++ on-watch
|= =path
^- (quip card _this)
=^ cards state
?+ path (on-watch:def path)
::
[%updates ~]
:_ state
%+ give:ha ~
:* %initial
watching
mentions
watch-on-self
==
==
[cards this]
::
++ on-poke
~/ %hark-graph-hook-poke
|= [=mark =vase]
^- (quip card _this)
|^
?> (team:title our.bowl src.bowl)
=^ cards state
?+ mark (on-poke:def mark vase)
%hark-graph-hook-action
(hark-graph-hook-action !<(action:hook vase))
==
[cards this]
::
++ hark-graph-hook-action
|= =action:hook
^- (quip card _state)
|^
:- (give:ha ~[/updates] action)
?- -.action
%listen (listen +.action)
%ignore (ignore +.action)
%set-mentions (set-mentions +.action)
%set-watch-on-self (set-watch-on-self +.action)
==
++ listen
|= [graph=resource =index:post]
^+ state
state(watching (~(put in watching) [graph index]))
::
++ ignore
|= [graph=resource =index:post]
^+ state
state(watching (~(del in watching) [graph index]))
::
++ set-mentions
|= ment=?
^+ state
state(mentions ment)
::
++ set-watch-on-self
|= self=?
^+ state
state(watch-on-self self)
--
--
::
++ on-agent
~/ %hark-graph-hook-agent
|= [=wire =sign:agent:gall]
^- (quip card _this)
|^
?+ -.sign (on-agent:def wire sign)
%kick
:_ this
?. ?=([%graph ~] wire)
~
~[watch-graph:ha]
::
%fact
?. ?=(%graph-update p.cage.sign)
(on-agent:def wire sign)
=^ cards state
(graph-update !<(update:graph-store q.cage.sign))
[cards this]
==
++ add-graph
|= rid=resource
^- (quip card _state)
?. &(watch-on-self =(our.bowl entity.rid))
[~ state]
`state(watching (~(put in watching) [rid ~]))
::
++ graph-update
|= =update:graph-store
^- (quip card _state)
?: ?=(%add-graph -.q.update)
(add-graph resource.q.update)
?. ?=(%add-nodes -.q.update)
[~ state]
=/ group=resource
(need (group-from-app-resource:met %graph resource.q.update))
=/ =metadata:metadata-store
(need (peek-metadata:met %graph group resource.q.update))
=* rid resource.q.update
=+ %+ scry:ha
,mark=(unit mark)
/gx/graph-store/graph-mark/(scot %p entity.rid)/[name.rid]/noun
=+ %+ scry:ha
,=tube:clay
/cc/[q.byk.bowl]/[(fall mark %graph-validator-link)]/notification-kind
=/ nodes=(list [p=index:graph-store q=node:graph-store])
~(tap by nodes.q.update)
=| cards=(list card)
|^
?~ nodes
[cards state]
=* index p.i.nodes
=* node q.i.nodes
=^ node-cards state
(check-node node tube)
%_ $
nodes t.nodes
cards (weld node-cards cards)
==
::
++ check-node-children
|= [=node:graph-store =tube:clay]
^- (quip card _state)
?: ?=(%empty -.children.node)
[~ state]
=/ children=(list [=atom =node:graph-store])
(tap:orm:graph-store p.children.node)
=| cards=(list card)
|- ^- (quip card _state)
?~ children
[cards state]
=^ new-cards state
(check-node node.i.children tube)
%_ $
cards (weld cards new-cards)
children t.children
==
::
++ check-node
|= [=node:graph-store =tube:clay]
^- (quip card _state)
=^ child-cards state
(check-node-children node tube)
?: =(our.bowl author.post.node)
=^ self-cards state
(self-post node)
:_ state
(weld child-cards self-cards)
=+ !< notif-kind=(unit [name=@t parent-lent=@ud])
(tube !>([0 post.node]))
?~ notif-kind
[child-cards state]
=/ desc=@t
?: (is-mention contents.post.node)
%mention
name.u.notif-kind
=/ parent=index:post
(scag parent-lent.u.notif-kind index.post.node)
?. ?| =(desc %mention)
(~(has in watching) [rid parent])
==
[child-cards state]
=/ notif-index=index:store
[%graph group rid module.metadata desc]
=/ =contents:store
[%graph (limo post.node ~)]
:_ state
%+ snoc child-cards
(add-unread notif-index [time-sent.post.node %.n contents])
::
++ is-mention
|= contents=(list content:post)
^- ?
?. mentions %.n
?~ contents %.n
?. ?=(%mention -.i.contents)
$(contents t.contents)
?: =(our.bowl ship.i.contents)
%.y
$(contents t.contents)
::
++ self-post
|= =node:graph-store
^- (quip card _state)
?. ?=(%.y watch-on-self)
[~ state]
`state(watching (~(put in watching) [rid index.post.node]))
::
++ add-unread
|= [=index:store =notification:store]
^- card
=- [%pass / %agent [our.bowl %hark-store] %poke -]
hark-action+!>([%add index notification])
::
--
--
::
++ on-peek on-peek:def
::
++ on-leave on-leave:def
++ on-arvo on-arvo:def
++ on-fail on-fail:def
--

View File

@ -0,0 +1,169 @@
:: hark-group-hook: notifications for groups [landscape]
::
/- store=hark-store, post, group-store, metadata-store, hook=hark-group-hook
/+ resource, metadata, default-agent, dbug, graph-store
::
~% %hark-group-hook-top ..is ~
|%
+$ card card:agent:gall
+$ versioned-state
$% state-0
==
::
+$ state-0
$: %0
watching=(set resource)
==
::
--
::
=| state-0
=* state -
::
=<
%- agent:dbug
^- agent:gall
~% %hark-group-hook-agent ..card ~
|_ =bowl:gall
+* this .
ha ~(. +> bowl)
def ~(. (default-agent this %|) bowl)
met ~(. metadata bowl)
::
++ on-init
:_ this
:~ watch-metadata:ha
watch-groups:ha
==
::
++ on-save !>(state)
++ on-load
|= old=vase
^- (quip card _this)
`this(state !<(state-0 old))
::
++ on-watch
|= =path
?. ?=([%updates ~] path)
(on-watch:def path)
:_ this
=; =cage
[%give %fact ~ cage]~
:- %hark-group-hook-update
!> ^- update:hook
[%initial watching]
::
++ on-poke
~/ %hark-group-hook-poke
|= [=mark =vase]
^- (quip card _this)
|^
?> (team:title our.bowl src.bowl)
=^ cards state
?+ mark (on-poke:def mark vase)
%hark-group-hook-action
(hark-group-hook-action !<(action:hook vase))
==
[cards this]
::
++ hark-group-hook-action
|= =action:hook
^- (quip card _state)
|^
?- -.action
%listen (listen +.action)
%ignore (ignore +.action)
==
++ listen
|= group=resource
^- (quip card _state)
:- (give %listen group)
state(watching (~(put in watching) group))
::
++ ignore
|= group=resource
^- (quip card _state)
:- (give %ignore group)
state(watching (~(del in watching) group))
::
++ give
|= =update:hook
^- (list card)
[%give %fact ~[/updates] %hark-group-hook-update !>(update)]~
--
--
::
++ on-agent
~/ %hark-group-hook-agent
|= [=wire =sign:agent:gall]
^- (quip card _this)
|^
?+ -.sign (on-agent:def wire sign)
%kick
:_ this
?+ wire ~
[%group ~] ~[watch-groups:ha]
[%metadata ~] ~[watch-metadata:ha]
==
::
%fact
?+ p.cage.sign (on-agent:def wire sign)
%group-update
=^ cards state
(group-update !<(update:group-store q.cage.sign))
[cards this]
::
%metadata-update
=^ cards state
(metadata-update !<(metadata-update:metadata-store q.cage.sign))
[cards this]
==
==
::
++ group-update
|= =update:group-store
^- (quip card _state)
?. ?=(?(%add-members %remove-members) -.update)
[~ state]
?. (~(has in watching) resource.update)
[~ state]
=/ =contents:store
[%group ~[update]]
=/ =notification:store [now.bowl %.n contents]
=/ =index:store
[%group resource.update -.update]
:_ state
~[(add-unread index notification)]
:: +metadata-update is stubbed for now, for the following reasons
:: - There's no semantic difference in metadata-store between
:: adding and editing a channel
:: - We have no way of retrieving old metadata to e.g. get a
:: channel's old name when it is renamed
++ metadata-update
|= update=metadata-update:metadata-store
^- (quip card _state)
[~ state]
::
++ add-unread
|= [=index:store =notification:store]
^- card
=- [%pass / %agent [our.bowl %hark-store] %poke -]
hark-action+!>([%add index notification])
--
::
++ on-peek on-peek:def
++ on-leave on-leave:def
++ on-arvo on-arvo:def
++ on-fail on-fail:def
--
|_ =bowl:gall
+* met ~(. metadata bowl)
::
++ watch-groups
^- card
[%pass /group %agent [our.bowl %group-store] %watch /groups]
::
++ watch-metadata
^- card
[%pass /metadata %agent [our.bowl %metadata-store] %watch /updates]
--

View File

@ -0,0 +1,363 @@
:: hark-store: notifications [landscape]
::
/- store=hark-store, post, group-store, metadata-store
/+ resource, metadata, default-agent, dbug, graph-store
::
~% %hark-store-top ..is ~
|%
+$ card card:agent:gall
+$ versioned-state
$% state-0
==
::
+$ state-0
$: %0
=notifications:store
archive=notifications:store
last-seen=@da
dnd=_|
==
+$ inflated-state
$: state-0
cache
==
:: $cache: useful to have precalculated, but can be derived from state
:: albeit expensively
+$ cache
$: unread-count=@ud
by-index=(jug index:store @da)
~
==
::
++ orm ((ordered-map @da timebox:store) gth)
--
::
=| inflated-state
=* state -
::
=<
%- agent:dbug
^- agent:gall
~% %hark-store-agent ..card ~
|_ =bowl:gall
+* this .
ha ~(. +> bowl)
def ~(. (default-agent this %|) bowl)
met ~(. metadata bowl)
::
++ on-init
:_ this
~[autoseen-timer]
::
++ on-save !>(-.state)
++ on-load
|= =old=vase
^- (quip card _this)
=/ old
!<(state-0 old-vase)
=. notifications.old
(gas:orm *notifications:store (tap:orm notifications.old))
=. archive.old
(gas:orm *notifications:store (tap:orm archive.old))
`this(-.state old, +.state (inflate-cache old))
::
++ on-watch
|= =path
^- (quip card _this)
|^
?+ path (on-watch:def path)
::
[%updates ~]
:_ this
[%give %fact ~ hark-update+!>(initial-updates)]~
==
::
++ initial-updates
^- update:store
:- %more
^- (list update:store)
:- unreads
:+ [%set-dnd dnd]
[%count unread-count]
%+ weld
%+ turn
%+ scag 3
(tap-nonempty:ha archive)
(timebox-update &)
%+ turn
%+ scag 3
(tap-nonempty:ha notifications)
(timebox-update |)
::
++ unreads
^- update:store
:- %unreads
^- (list [index:store @ud])
%+ turn
~(tap by by-index)
|=([=index:store =(set @da)] [index ~(wyt in set)])
::
++ timebox-update
|= archived=?
|= [time=@da =timebox:store]
^- update:store
[%timebox time archived ~(tap by timebox)]
--
::
++ on-peek
|= =path
^- (unit (unit cage))
?+ path (on-peek:def path)
::
[%x %recent ?(%archive %inbox) @ @ ~]
=/ is-archive
=(%archive i.t.t.path)
=/ offset=@ud
(slav %ud i.t.t.t.path)
=/ length=@ud
(slav %ud i.t.t.t.t.path)
:^ ~ ~ %hark-update
!> ^- update:store
:- %more
%+ turn
%+ scag length
%+ slag offset
%- tap-nonempty:ha
?:(is-archive archive notifications)
|= [time=@da =timebox:store]
^- update:store
:^ %timebox time is-archive
~(tap by timebox)
==
::
++ 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))
==
[cards this]
::
++ hark-action
|= =action:store
^- (quip card _state)
|^
?- -.action
%add (add +.action)
%archive (do-archive +.action)
%seen seen
%read (read +.action)
%read-index (read-index +.action)
%unread (unread +.action)
%set-dnd (set-dnd +.action)
==
++ add
|= [=index:store =notification:store]
^- (quip card _state)
=/ =timebox:store
(gut-orm:ha notifications last-seen)
=/ existing-notif
(~(get by timebox) index)
=/ new=notification:store
?~ existing-notif
notification
(merge-notification:ha u.existing-notif notification)
=/ new-timebox=timebox:store
(~(put by timebox) index new)
:- (give:ha [/updates]~ %added last-seen index new)
%_ state
+ ?~(existing-notif (upd-unreads:ha index last-seen %.n) +.state)
notifications (put:orm notifications last-seen new-timebox)
==
++ read-index
|= =index:store
^- (quip card _state)
=/ times=(list @da)
~(tap in (~(gut by by-index) index ~))
=| cards=(list card)
|-
?~ times
[cards state]
=* time i.times
=^ crds state
(read time index)
$(cards (weld cards crds), times t.times)
::
++ do-archive
|= [time=@da =index:store]
^- (quip card _state)
=/ =timebox:store
(gut-orm:ha notifications time)
=/ =notification:store
(~(got by timebox) index)
=/ new-timebox=timebox:store
(~(del by timebox) index)
:- (give:ha [/updates]~ %archive time index)
%_ state
+ ?.(read.notification (upd-unreads:ha index time %.y) +.state)
::
notifications
(put:orm notifications time new-timebox)
::
archive
%^ jub-orm:ha archive time
|= archive-box=timebox:store
^- timebox:store
(~(put by archive-box) index notification(read %.y))
==
::
++ read
|= [time=@da =index:store]
^- (quip card _state)
:- (give:ha [/updates]~ %read time index)
%_ state
+ (upd-unreads:ha index time %.y)
unread-count (dec unread-count)
notifications (change-read-status:ha time index %.y)
==
::
++ unread
|= [time=@da =index:store]
^- (quip card _state)
:- (give:ha [/updates]~ %unread time index)
%_ state
+ (upd-unreads:ha index time %.n)
unread-count +(unread-count)
notifications (change-read-status:ha time index %.n)
==
::
++ seen
^- (quip card _state)
:_ state(last-seen now.bowl)
:~ cancel-autoseen:ha
autoseen-timer:ha
==
::
++ set-dnd
|= d=?
^- (quip card _state)
:_ state(dnd d)
(give:ha [/updates]~ %set-dnd d)
--
--
::
++ 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)
?> ?=([%b %wake *] sign-arvo)
:_ this(last-seen now.bowl)
~[autoseen-timer:ha]
::
++ on-fail on-fail:def
--
|_ =bowl:gall
+* met ~(. metadata bowl)
::
++ tap-nonempty
|= =notifications:store
^- (list [@da timebox:store])
%+ skip (tap:orm notifications)
|=([@da =timebox:store] =(0 ~(wyt by timebox)))
::
++ merge-notification
|= [existing=notification:store new=notification:store]
^- notification:store
?- -.contents.existing
::
%chat
?> ?=(%chat -.contents.new)
existing(list.contents (weld list.contents.existing list.contents.new))
::
%graph
?> ?=(%graph -.contents.new)
existing(list.contents (weld list.contents.existing list.contents.new))
::
%group
?> ?=(%group -.contents.new)
existing(list.contents (weld list.contents.existing list.contents.new))
==
::
++ change-read-status
|= [time=@da =index:store read=?]
^+ notifications
%^ jub-orm notifications time
|= =timebox:store
%+ ~(jab by timebox) index
|= =notification:store
?> !=(read read.notification)
notification(read read)
:: +key-orm: +key:by for ordered maps
++ key-orm
|= =notifications:store
^- (list @da)
(turn (tap:orm notifications) |=([key=@da =timebox:store] key))
:: +jub-orm: combo +jab/+gut for ordered maps
:: TODO: move to zuse.hoon
++ jub-orm
|= [=notifications:store time=@da fun=$-(timebox:store timebox:store)]
^- notifications:store
=/ =timebox:store
(fun (gut-orm notifications time))
(put:orm notifications time timebox)
:: +gut-orm: +gut:by for ordered maps
:: TODO: move to zuse.hoon
++ gut-orm
|= [=notifications:store time=@da]
^- timebox:store
(fall (get:orm notifications time) ~)
::
++ autoseen-interval ~h3
++ cancel-autoseen
^- card
[%pass /autoseen %arvo %b %rest (add last-seen autoseen-interval)]
::
++ autoseen-timer
^- card
[%pass /autoseen %arvo %b %wait (add now.bowl autoseen-interval)]
::
++ give
|= [paths=(list path) update=update:store]
^- (list card)
[%give %fact paths [%hark-update !>(update)]]~
::
++ upd-unreads
|= [=index:store time=@da read=?]
^+ +.state
%_ +.state
::
by-index
%. [index time]
?: read
~(del ju by-index)
~(put ju by-index)
==
::
++ inflate-cache
|= state-0
^+ +.state
=/ nots=(list [p=@da =timebox:store])
(tap:orm notifications)
|- =* outer $
?~ nots
+.state
=/ unreads ~(tap by timebox.i.nots)
|- =* inner $
?~ unreads
outer(nots t.nots)
=* notification q.i.unreads
=* index p.i.unreads
?: read.notification
inner(unreads t.unreads)
=. +.state
(upd-unreads index p.i.nots %.n)
inner(unreads t.unreads)
--

101
pkg/arvo/app/herm.hoon Normal file
View File

@ -0,0 +1,101 @@
:: herm: stand-in for term.c with http interface
::
/+ default-agent, dbug, verb
=, able:jael
|%
+$ state-0 [%0 ~]
--
::
=| state-0
=* state -
%+ verb |
%- agent:dbug
^- agent:gall
=> |%
++ request-tube
|= [bowl:gall from=mark to=mark next=?]
^- card:agent:gall
:* %pass /tube/[from]/[to]
%arvo %c %warp
our q.byk ~
::
?: next
[%next %c da+now /[from]/[to]]
[%sing %c da+now /[from]/[to]]
==
--
|_ =bowl:gall
+* this .
def ~(. (default-agent this %|) bowl)
::
++ on-init
^- (quip card:agent:gall _this)
:_ this
:: set up dill session subscription,
:: and ensure the tubes we use are in cache
::
:~ [%pass [%view %$ ~] %arvo %d %view ~]
(request-tube bowl %blit %json |)
(request-tube bowl %json %belt |)
==
::
++ on-save !>([%0 ~])
++ on-load
|= old=vase
^- (quip card:agent:gall _this)
[~ this(state [%0 ~])]
::
++ on-watch
|= =path
^- (quip card:agent:gall _this)
?> ?=([%session @ ~] path)
:_ this
:: scry prompt and cursor position out of dill for initial response
::
=/ base=^path
/dx/(scot %p our.bowl)//(scot %da now.bowl)/sessions
:~ [%give %fact ~ %blit !>(.^(blit:dill (weld base //line)))]
[%give %fact ~ %blit !>(`blit:dill`hop+.^(@ud (weld base //cursor)))]
==
::
++ on-arvo
|= [=wire =sign-arvo]
^- (quip card:agent:gall _this)
?+ wire !!
:: pass on dill blits for the session
::
[%view %$ ~]
?. ?=([%d %blit *] sign-arvo)
~| [%unexpected-sign [- +<]:sign-arvo]
!!
:_ this
%+ turn p.sign-arvo
|= =blit:dill
[%give %fact [%session %$ ~]~ %blit !>(blit)]
::
:: ensure the tubes we need remain in cache
::
[%tube @ @ ~]
=* from i.t.wire
=* to i.t.t.wire
?. ?=([%c %writ *] sign-arvo)
~| [%unexpected-sign [- +<]:sign-arvo]
!!
:_ this
[(request-tube bowl from to &)]~
==
::
++ on-poke
|= [=mark =vase]
^- (quip card:agent:gall _this)
?. ?=(%belt mark)
~| [%unexpected-mark mark]
!!
:_ this
[%pass [%belt %$ ~] %arvo %d %belt !<(belt:dill vase)]~
::
++ on-leave on-leave:def
++ on-peek on-peek:def
++ on-agent on-agent:def
++ on-fail on-fail:def
--

View File

@ -2,7 +2,7 @@
/+ drum=hood-drum, helm=hood-helm, kiln=hood-kiln /+ drum=hood-drum, helm=hood-helm, kiln=hood-kiln
|% |%
+$ state +$ state
$: %9 $: %11
drum=state:drum drum=state:drum
helm=state:helm helm=state:helm
kiln=state:kiln kiln=state:kiln
@ -12,6 +12,8 @@
[ver=?(%1 %2 %3 %4 %5 %6) lac=(map @tas fin-any-state)] [ver=?(%1 %2 %3 %4 %5 %6) lac=(map @tas fin-any-state)]
[%7 drum=state:drum helm=state:helm kiln=state:kiln] [%7 drum=state:drum helm=state:helm kiln=state:kiln]
[%8 drum=state:drum helm=state:helm kiln=state:kiln] [%8 drum=state:drum helm=state:helm kiln=state:kiln]
[%9 drum=state:drum helm=state:helm kiln=state:kiln]
[%10 drum=state:drum helm=state:helm kiln=state:kiln]
== ==
+$ any-state-tuple +$ any-state-tuple
$: drum=any-state:drum $: drum=any-state:drum
@ -64,7 +66,7 @@
=^ d drum.state (on-load:drum-core -.old drum.tup) =^ d drum.state (on-load:drum-core -.old drum.tup)
=^ h helm.state (on-load:helm-core -.old helm.tup) =^ h helm.state (on-load:helm-core -.old helm.tup)
=^ k kiln.state (on-load:kiln-core -.old kiln.tup) =^ k kiln.state (on-load:kiln-core -.old kiln.tup)
[:(weld d h k) this] [:(welp d h k) this]
:: ::
++ on-poke ++ on-poke
|= [=mark =vase] |= [=mark =vase]

View File

@ -1,121 +1,121 @@
:: invite-hook: receive invites from any source :: invite-hook [landscape]: receive invites from any source
:: ::
:: only handles %invite actions. accepts json, but only from the host team. :: only handles %invite actions:
:: can be poked by the host team to send an invite out to someone. :: - can be poked by the host team to send an invite out to someone.
:: can be poked by foreign ships to send an invite to us. :: - can be poked by foreign ships to send an invite to us.
:: ::
/+ *invite-json, default-agent, verb, dbug /- *invite-store
/+ default-agent, dbug
:: ::
|% |%
+$ state-0 [%0 ~] +$ state-0 [%0 ~]
::
+$ card card:agent:gall +$ card card:agent:gall
-- --
:: ::
=| state-0 =| state-0
=* state - =* state -
::
%+ verb |
%- agent:dbug %- agent:dbug
^- agent:gall ^- agent:gall
=< ::
|_ =bowl:gall |_ =bowl:gall
+* this . +* this .
do ~(. +> bowl) def ~(. (default-agent this %|) bowl)
def ~(. (default-agent this %|) bowl) ::
:: ++ on-init [~ this]
++ on-init ++ on-save !>(state)
^- (quip card _this) ++ on-load
[~ this] |= old=vase
:: ^- (quip card _this)
++ on-save !>(state) [~ this(state !<(state-0 old))]
++ on-load ::
|= old=vase ++ on-poke
^- (quip card _this) |= [=mark =vase]
[~ this(state !<(state-0 old))] ^- (quip card _this)
:: |^
++ on-poke :_ this
|= [=mark =vase] ?+ mark (on-poke:def mark vase)
^- (quip card _this) %invite-action
:_ this =/ act=action !<(action vase)
?+ mark (on-poke:def mark vase) ?+ -.act ~
%json %invites
:: only accept json from ourselves. ?. (team:title [our src]:bowl) ~
:: outgoing. we must be inviting other ships. send them each an invite
:: ::
?> (team:title our.bowl src.bowl) %+ turn ~(tap in recipients.invites.act)
=/ act (json-to-action !<(json vase)) |= recipient=ship
?> ?=(%invite -.act) ^- card
[(invite-hook-poke:do recipient.invite.act act)]~ ?< (team:title our.bowl recipient)
%+ invite-hook-poke recipient
:^ %invite term.act uid.act
^- invite
:* ship.invites.act
app.invites.act
resource.invites.act
recipient
text.invites.act
==
:: ::
%invite-action %invite
=/ act=invite-action !<(invite-action vase) ?: (team:title [our src]:bowl)
?. ?=(%invite -.act) ~
?: (team:title our.bowl src.bowl)
:: outgoing. we must be inviting another ship. send them the invite. :: outgoing. we must be inviting another ship. send them the invite.
:: ::
?< (team:title our.bowl recipient.invite.act) ?< (team:title our.bowl recipient.invite.act)
[(invite-hook-poke:do recipient.invite.act act)]~ [(invite-hook-poke recipient.invite.act act)]~
:: else incoming. ensure invitatory exists and invite is not a duplicate. :: else incoming. ensure invitatory exists and invite is not a duplicate.
:: ::
?> ?=(^ (invitatory-scry:do path.act)) ?> ?=(^ (invitatory-scry term.act))
?> ?=(~ (invite-scry:do path.act uid.act)) ?> ?=(~ (invite-scry term.act uid.act))
[(invite-poke:do path.act act)]~ [(invite-poke term.act act)]~
==
==
::
++ invite-hook-poke
|= [=ship =action]
^- card
:* %pass
/invite-hook
%agent
[ship %invite-hook]
%poke
%invite-action
!>(action)
== ==
:: ::
++ on-peek on-peek:def ++ invite-poke
++ on-watch on-watch:def |= [=term =action]
++ on-leave on-leave:def ^- card
++ on-agent on-agent:def :* %pass
++ on-arvo on-arvo:def /[term]
++ on-fail on-fail:def %agent
[our.bowl %invite-store]
%poke
%invite-action
!>(action)
==
::
++ invitatory-scry
|= =term
.^ (unit invitatory)
%gx
%+ weld
/(scot %p our.bowl)/invite-store/(scot %da now.bowl)/invitatory
/[term]/noun
==
::
++ invite-scry
|= [=term uid=serial]
.^ (unit invite)
%gx
%+ weld
/(scot %p our.bowl)/invite-store/(scot %da now.bowl)/invite
/[term]/(scot %uv uid)/noun
==
-- --
:: ::
|_ =bowl:gall ++ on-peek on-peek:def
:: ++ on-watch on-watch:def
++ invite-hook-poke ++ on-leave on-leave:def
|= [=ship action=invite-action] ++ on-agent on-agent:def
^- card ++ on-arvo on-arvo:def
:* %pass ++ on-fail on-fail:def
/invite-hook
%agent
[ship %invite-hook]
%poke
%invite-action
!>(action)
==
::
++ invite-poke
|= [=path action=invite-action]
^- card
:* %pass
path
%agent
[our.bowl %invite-store]
%poke
%invite-action
!>(action)
==
::
++ invitatory-scry
|= pax=path
^- (unit invitatory)
=. pax
;: weld
/(scot %p our.bowl)/invite-store/(scot %da now.bowl)/invitatory
pax
/noun
==
.^((unit invitatory) %gx pax)
::
++ invite-scry
|= [pax=path uid=serial]
^- (unit invite)
=. pax
;: weld
/(scot %p our.bowl)/invite-store/(scot %da now.bowl)/invite
pax
/(scot %uv uid)/noun
==
.^((unit invite) %gx pax)
-- --

View File

@ -1,183 +1,209 @@
/+ *invite-json, default-agent, dbug :: invite-store [landscape]
/- store=invite-store
/+ res=resource, default-agent, dbug
|% |%
+$ card card:agent:gall +$ card card:agent:gall
::
+$ versioned-state +$ versioned-state
$% state-zero $% state-0
state-1
== ==
:: ::
+$ state-zero +$ invitatory-0 (map serial:store invite-0)
$: %0 +$ invite-0
=invites $: =ship :: ship to subscribe to upon accepting invite
app=@tas :: app to subscribe to upon accepting invite
=path :: path to subscribe to upon accepting invite
recipient=ship :: recipient to receive invite
text=cord :: text to describe the invite
== ==
::
+$ state-0 [%0 invites=(map path invitatory-0)]
+$ state-1 [%1 =invites:store]
-- --
:: ::
=| state-zero =| state-1
=* state - =* state -
%- agent:dbug %- agent:dbug
^- agent:gall ^- agent:gall
=< ::
|_ bol=bowl:gall |_ =bowl:gall
+* this . +* this .
inv-core +> def ~(. (default-agent this %|) bowl)
ic ~(. inv-core bol) ::
def ~(. (default-agent this %|) bol) ++ on-init
++ on-init on-init:def ^- (quip card _this)
++ on-save !>(state) :- ~
++ on-load %_ this
|= old=vase invites.state
`this(state !<(state-zero old)) %- ~(gas by *invites:store)
[%graph *invitatory:store]~
==
::
++ on-save !>(state)
++ on-load
|= old-vase=vase
=/ old !<(versioned-state old-vase)
?: ?=(%1 -.old)
`this(state old)
:- =- [%pass / %agent [our.bowl %invite-store] %poke %invite-action -]~
!> ^- action:store
[%create %graph]
%= this
state
:- %1
%- ~(gas by *invites:store)
%+ murn ~(tap by invites.old)
|= [=path =invitatory-0]
^- (unit [term invitatory:store])
?. ?=([@ ~] path) ~
:- ~
:- i.path
%- ~(gas by *invitatory:store)
%+ murn ~(tap by invitatory-0)
|= [=serial:store =invite-0]
^- (unit [serial:store invite:store])
=/ resource=(unit resource:res) (de-path-soft:res path.invite-0)
?~ resource ~
:- ~
:- serial
^- invite:store
:* ship.invite-0
app.invite-0
u.resource
recipient.invite-0
text.invite-0
==
==
::
++ on-agent on-agent:def
++ on-arvo on-arvo:def
++ on-leave on-leave:def
++ on-fail on-fail:def
::
++ on-watch
|= =path
^- (quip card _this)
?> (team:title our.bowl src.bowl)
=/ cards=(list card)
?+ path (on-watch:def path)
[%all ~] [%give %fact ~ %invite-update !>([%initial invites])]~
[%updates ~] ~
[%invitatory @ ~]
=/ inv=invitatory:store (~(got by invites) i.t.path)
[%give %fact ~ %invite-update !>([%invitatory inv])]~
==
[cards this]
::
++ on-poke
|= [=mark =vase]
^- (quip card _this)
|^
?> (team:title our.bowl src.bowl)
=^ cards state
?+ mark (on-poke:def mark vase)
%invite-action (poke-invite-action !<(action:store vase))
==
[cards this]
:: ::
++ on-poke ++ poke-invite-action
|= [=mark =vase] |= =action:store
^- (quip card _this) ^- (quip card _state)
?> (team:title our.bol src.bol) ?- -.action
=^ cards state %create (handle-create +.action)
?+ mark (on-poke:def mark vase) %delete (handle-delete +.action)
%json (poke-invite-action:ic (json-to-action !<(json vase))) %invite (handle-invite +.action)
%invite-action (poke-invite-action:ic !<(invite-action vase)) %accept (handle-accept +.action)
== %decline (handle-decline +.action)
[cards this] %invites ~|('only send this to %invite-hook' !!)
::
++ on-watch
|= =path
^- (quip card _this)
=/ cards=(list card)
?+ path (on-watch:def path)
[%all ~] [%give %fact ~ %invite-update !>([%initial invites])]~
[%updates ~] ~
[%invitatory *]
=/ inv=invitatory (~(got by invites) t.path)
[%give %fact ~ %invite-update !>([%invitatory inv])]~
==
[cards this]
::
++ on-leave on-leave:def
++ on-peek
|= =path
^- (unit (unit cage))
?+ path (on-peek:def path)
[%x %all ~] (peek-x-all:ic t.t.path)
[%x %invitatory *] (peek-x-invitatory:ic t.t.path)
[%x %invite *] (peek-x-invite:ic t.t.path)
== ==
:: ::
++ on-agent on-agent:def ++ handle-create
++ on-arvo on-arvo:def |= =term
++ on-fail on-fail:def ^- (quip card _state)
?: (~(has by invites) term)
[~ state]
:- (send-diff term [%create term])
state(invites (~(put by invites) term *invitatory:store))
::
++ handle-delete
|= =term
^- (quip card _state)
?. (~(has by invites) term)
[~ state]
:- (send-diff term [%delete term])
state(invites (~(del by invites) term))
::
++ handle-invite
|= [=term =serial:store =invite:store]
^- (quip card _state)
?. (~(has by invites) term)
[~ state]
=/ container (~(got by invites) term)
=. serial (sham eny.bowl)
=. container (~(put by container) serial invite)
:- (send-diff term [%invite term serial invite])
state(invites (~(put by invites) term container))
::
++ handle-accept
|= [=term =serial:store]
^- (quip card _state)
?. (~(has by invites) term)
[~ state]
=/ container (~(got by invites) term)
=/ invite (~(get by container) serial)
?~ invite
[~ state]
=. container (~(del by container) serial)
:- (send-diff term [%accepted term serial u.invite])
state(invites (~(put by invites) term container))
::
++ handle-decline
|= [=term =serial:store]
^- (quip card _state)
?. (~(has by invites) term)
[~ state]
=/ container (~(got by invites) term)
=/ invite (~(get by container) serial)
?~ invite
[~ state]
=. container (~(del by container) serial)
:- (send-diff term [%decline term serial])
state(invites (~(put by invites) term container))
::
++ update-subscribers
|= [=path =update:store]
^- card
[%give %fact ~[path] %invite-update !>(update)]
::
++ send-diff
|= [=term =update:store]
^- (list card)
:~ (update-subscribers /all update)
(update-subscribers /updates update)
(update-subscribers /invitatory/[term] update)
==
-- --
:: ::
|_ bol=bowl:gall ++ on-peek
:: |= =path
++ peek-x-all
|= pax=path
^- (unit (unit cage)) ^- (unit (unit cage))
[~ ~ %noun !>(invites)] ?+ path (on-peek:def path)
:: [%x %all ~]
++ peek-x-invitatory ``noun+!>(invites)
|= pax=path ::
^- (unit (unit cage)) [%x %invitatory @ ~]
?~ pax :^ ~ ~ %noun
~ !> ^- (unit invitatory:store)
=/ invitatory=(unit invitatory) (~(get by invites) pax) (~(get by invites) i.t.t.path)
[~ ~ %noun !>(invitatory)] ::
:: [%x %invite @ @ ~]
++ peek-x-invite =* term i.t.t.path
|= pax=path =/ =serial:store (slav %uv i.t.t.t.path)
^- (unit (unit cage)) ?. (~(has by invites) term)
:: /:path/:uid ~
=/ pas (flop pax) =/ =invitatory:store (~(got by invites) term)
?~ pas :^ ~ ~ %noun
~ !> ^- (unit invite:store)
=/ uid=serial (slav %uv i.pas) (~(get by invitatory) serial)
=. pax (scag (dec (lent pax)) `(list @ta)`pax)
=/ invitatory=(unit invitatory) (~(get by invites) pax)
?~ invitatory
~
=/ invite=(unit invite) (~(get by u.invitatory) uid)
[~ ~ %noun !>(invite)]
::
++ poke-invite-action
|= action=invite-action
^- (quip card _state)
?> (team:title our.bol src.bol)
?- -.action
%create (handle-create action)
%delete (handle-delete action)
%invite (handle-invite action)
%accept (handle-accept action)
%decline (handle-decline action)
== ==
::
++ handle-create
|= act=invite-action
^- (quip card _state)
?> ?=(%create -.act)
?: (~(has by invites) path.act)
[~ state]
:- (send-diff path.act act)
state(invites (~(put by invites) path.act *invitatory))
::
++ handle-delete
|= act=invite-action
^- (quip card _state)
?> ?=(%delete -.act)
?. (~(has by invites) path.act)
[~ state]
:- (send-diff path.act act)
state(invites (~(del by invites) path.act))
::
++ handle-invite
|= act=invite-action
^- (quip card _state)
?> ?=(%invite -.act)
?. (~(has by invites) path.act)
[~ state]
=/ container (~(got by invites) path.act)
=. uid.act (sham eny.bol)
=. container (~(put by container) uid.act invite.act)
:- (send-diff path.act act)
state(invites (~(put by invites) path.act container))
::
++ handle-accept
|= act=invite-action
^- (quip card _state)
?> ?=(%accept -.act)
?. (~(has by invites) path.act)
[~ state]
=/ container (~(got by invites) path.act)
=/ invite (~(get by container) uid.act)
?~ invite
[~ state]
=. container (~(del by container) uid.act)
:- (send-diff path.act [%accepted path.act uid.act u.invite])
state(invites (~(put by invites) path.act container))
::
++ handle-decline
|= act=invite-action
^- (quip card _state)
?> ?=(%decline -.act)
?. (~(has by invites) path.act)
[~ state]
=/ container (~(got by invites) path.act)
=/ invite (~(get by container) uid.act)
?~ invite
[~ state]
=. container (~(del by container) uid.act)
:- (send-diff path.act act)
state(invites (~(put by invites) path.act container))
::
++ update-subscribers
|= [pax=path upd=invite-update]
^- card
[%give %fact ~[pax] %invite-update !>(upd)]
::
++ send-diff
|= [pax=path upd=invite-update]
^- (list card)
:~ (update-subscribers /all upd)
(update-subscribers /updates upd)
(update-subscribers [%invitatory pax] upd)
==
::
-- --

View File

@ -1,3 +1,7 @@
:: invite-view [landscape]:
::
:: deprecated
::
/+ default-agent /+ default-agent
^- agent:gall ^- agent:gall
|_ =bowl:gall |_ =bowl:gall

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 453 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 611 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 693 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 951 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1010 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 679 B

View File

@ -21,9 +21,9 @@
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>
<div id="portal-root"></div>
<script src="/~landscape/js/channel.js"></script> <script src="/~landscape/js/channel.js"></script>
<script src="/~landscape/js/session.js"></script> <script src="/~landscape/js/session.js"></script>
<script src="/~landscape/js/bundle/index.5c70804296e13e8973c3.js"></script> <script src="/~landscape/js/bundle/index.cf90ee9625a2551fe672.js"></script>
<script src="https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js"></script>
</body> </body>
</html> </html>

View File

@ -66,7 +66,7 @@ class Channel {
} }
deleteOnUnload() { deleteOnUnload() {
window.addEventListener("unload", (event) => { window.addEventListener("beforeunload", (event) => {
this.delete(); this.delete();
}); });
} }
@ -103,14 +103,16 @@ class Channel {
path, path,
connectionErrFunc = () => {}, connectionErrFunc = () => {},
eventFunc = () => {}, eventFunc = () => {},
quitFunc = () => {}) { quitFunc = () => {},
subAckFunc = () => {}) {
let id = this.nextId(); let id = this.nextId();
this.outstandingSubscriptions.set( this.outstandingSubscriptions.set(
id, id,
{ {
err: connectionErrFunc, err: connectionErrFunc,
event: eventFunc, event: eventFunc,
quit: quitFunc quit: quitFunc,
subAck: subAckFunc
} }
); );
@ -165,9 +167,11 @@ class Channel {
// The server side puts messages it sends us in a queue until we // The server side puts messages it sends us in a queue until we
// acknowledge that we received it. // acknowledge that we received it.
// //
let x = JSON.stringify( let payload = [{action: "ack", "event-id": parseInt(this.lastEventId)}];
[{action: "ack", "event-id": parseInt(this.lastEventId)}, j] if(j) {
); payload.push(j)
}
let x = JSON.stringify(payload);
req.send(x); req.send(x);
this.lastEventId = this.lastAcknowledgedEventId; this.lastEventId = this.lastAcknowledgedEventId;
@ -205,13 +209,16 @@ class Channel {
} else if (obj.response == "subscribe" || } else if (obj.response == "subscribe" ||
(obj.response == "poke" && !!subFuncs)) { (obj.response == "poke" && !!subFuncs)) {
let funcs = subFuncs; let funcs = subFuncs;
// on a response to a subscribe, we only notify the caller on err
//
if (obj.hasOwnProperty("err")) { if (obj.hasOwnProperty("err")) {
funcs["err"](obj.err); funcs["err"](obj.err);
this.outstandingSubscriptions.delete(obj.id); this.outstandingSubscriptions.delete(obj.id);
} else if (obj.hasOwnProperty("ok")) {
funcs["subAck"](obj);
} }
} else if (obj.response == "diff") { } else if (obj.response == "diff") {
// ack subscription
this.sendJSONToChannel();
let funcs = subFuncs; let funcs = subFuncs;
funcs["event"](obj.json); funcs["event"](obj.json);
} else if (obj.response == "quit") { } else if (obj.response == "quit") {

View File

@ -247,7 +247,7 @@
(~(put by builds) uri q.r.u.p.gift) (~(put by builds) uri q.r.u.p.gift)
=. ford-diagnostics =. ford-diagnostics
(~(del by ford-diagnostics) uri) (~(del by ford-diagnostics) uri)
=+ .^(=open:clay %cs /(scot %p our.bow)/home/(scot %da now.bow)/open) =+ .^(=open:clay %cs /(scot %p our.bow)/home/(scot %da now.bow)/open/foo)
=/ =type -:(open (uri-to-path:build uri)) =/ =type -:(open (uri-to-path:build uri))
=. preludes =. preludes
(~(put by preludes) uri type) (~(put by preludes) uri type)

View File

@ -1,3 +1,7 @@
:: launch [landscape]:
::
:: registers Landscape (and third party) applications, tiles
::
/+ store=launch-store, default-agent, dbug /+ store=launch-store, default-agent, dbug
|% |%
+$ card card:agent:gall +$ card card:agent:gall
@ -7,6 +11,8 @@
[%2 *] [%2 *]
[%3 *] [%3 *]
[%4 state-zero] [%4 state-zero]
[%5 state-zero]
[%6 state-zero]
== ==
:: ::
+$ state-zero +$ state-zero
@ -16,7 +22,7 @@
== ==
-- --
:: ::
=| [%4 state-zero] =| [%6 state-zero]
=* state - =* state -
%- agent:dbug %- agent:dbug
^- agent:gall ^- agent:gall
@ -31,59 +37,81 @@
%_ new-state %_ new-state
tiles tiles
%- ~(gas by *tiles:store) %- ~(gas by *tiles:store)
%+ turn `(list term)`[%chat %publish %links %weather %clock %dojo ~] %+ turn `(list term)`[%weather %clock %term ~]
|= =term |= =term
:- term :- term
^- tile:store ^- tile:store
?+ term [[%custom ~] %.y] ?+ term [[%custom ~] %.y]
%chat [[%basic 'Chat' '/~landscape/img/Chat.png' '/~chat'] %.y] %term [[%basic 'Terminal' '/~landscape/img/term.png' '/~term'] %.y]
%links [[%basic 'Links' '/~landscape/img/Links.png' '/~link'] %.y]
%dojo [[%basic 'Dojo' '/~landscape/img/Dojo.png' '/~dojo'] %.y]
%publish
[[%basic 'Publish' '/~landscape/img/Publish.png' '/~publish'] %.y]
== ==
tile-ordering [%chat %publish %links %weather %clock %dojo ~] tile-ordering [%weather %clock %term ~]
== ==
[~ this(state [%4 new-state])] [~ this(state [%6 new-state])]
:: ::
++ on-save !>(state) ++ on-save !>(state)
++ on-load ++ on-load
|= old=vase |= old=vase
^- (quip card _this) ^- (quip card _this)
=/ old-state !<(versioned-state old) =/ old-state !<(versioned-state old)
=| cards=(list card)
|- ^- (quip card _this)
?: ?=(%6 -.old-state)
[cards this(state old-state)]
?: ?=(%5 -.old-state)
:: replace %dojo with %term
::
=. tiles.old-state
%+ ~(put by (~(del by tiles.old-state) %dojo))
%term
:_ is-shown:(~(gut by tiles.old-state) %dojo *tile:store)
[%basic 'Terminal' '/~landscape/img/term.png' '/~term']
=. tile-ordering.old-state
%+ turn tile-ordering.old-state
|=(t=term ?:(=(%dojo t) %term t))
$(old-state [%6 +.old-state])
?: ?=(%4 -.old-state) ?: ?=(%4 -.old-state)
:- [%pass / %arvo %e %disconnect [~ /]]~ =. cards
this(state old-state) %+ snoc cards
[%pass / %arvo %e %disconnect [~ /]]
=. tiles.old-state
(~(del by tiles.old-state) %chat)
=. tiles.old-state
(~(del by tiles.old-state) %publish)
=. tiles.old-state
(~(del by tiles.old-state) %links)
=. tile-ordering.old-state
(skip tile-ordering.old-state |=(=term ?=(?(%links %chat %publish) term)))
$(old-state [%5 +.old-state])
=/ new-state *state-zero =/ new-state *state-zero
=. new-state =. new-state
%_ new-state %_ new-state
tiles tiles
%- ~(gas by *tiles:store) %- ~(gas by *tiles:store)
%+ turn `(list term)`[%chat %publish %links %weather %clock %dojo ~] %+ turn `(list term)`[%weather %clock %dojo ~]
|= =term |= =term
:- term :- term
^- tile:store ^- tile:store
?+ term [[%custom ~] %.y] ?+ term [[%custom ~] %.y]
%chat [[%basic 'Chat' '/~landscape/img/Chat.png' '/~chat'] %.y]
%links [[%basic 'Links' '/~landscape/img/Links.png' '/~link'] %.y]
%dojo [[%basic 'Dojo' '/~landscape/img/Dojo.png' '/~dojo'] %.y] %dojo [[%basic 'Dojo' '/~landscape/img/Dojo.png' '/~dojo'] %.y]
%publish
[[%basic 'Publish' '/~landscape/img/Publish.png' '/~publish'] %.y]
== ==
tile-ordering [%chat %publish %links %weather %clock %dojo ~] tile-ordering [%weather %clock %dojo ~]
== ==
:_ this(state [%4 new-state]) %_ $
%+ welp old-state [%5 new-state]
:~ [%pass / %arvo %e %disconnect [~ /]] ::
:* %pass /srv %agent [our.bowl %file-server] cards
%poke %file-server-action %+ welp
!>([%serve-dir / /app/landscape %.n %.y]) :~ [%pass / %arvo %e %disconnect [~ /]]
== :* %pass /srv %agent [our.bowl %file-server]
== %poke %file-server-action
%+ turn ~(tap by wex.bowl) !>([%serve-dir / /app/landscape %.n %.y])
|= [[=wire =ship =term] *] ==
^- card ==
[%pass wire %agent [ship term] %leave ~] %+ turn ~(tap by wex.bowl)
|= [[=wire =ship =term] *]
^- card
[%pass wire %agent [ship term] %leave ~]
==
:: ::
++ on-poke ++ on-poke
|= [=mark =vase] |= [=mark =vase]

View File

@ -1,644 +1,52 @@
:: link-listen-hook: get your friends' bookmarks :: link-listen-hook: no longer in use
:: ::
:: keeps track of a listening=(set app-path). users can manually add to and /+ default-agent, verb, dbug
:: remove from this set.
::
:: for all ships in groups associated with those resources, we subscribe to
:: their link's local-pages and annotations at the resource path (through
:: link-proxy-hook), and forward all entries into our link-store as
:: submissions and comments.
::
:: if a subscription to a target fails, we assume it's because their
:: metadata+groups definition hasn't been updated to include us yet.
:: we retry with exponential backoff, maxing out at one hour timeouts.
:: to expede this process, we prod other potential listeners when we add
:: them to our metadata+groups definition.
::
::
/- listen-hook=link-listen-hook, *metadata-store, *group, *link
/+ mdl=metadata, default-agent, verb, dbug, group-store, grpl=group, resource, store=link-store
:: ::
~% %link-listen-hook-top ..is ~ ~% %link-listen-hook-top ..is ~
|% |%
+$ versioned-state +$ versioned-state
$% [%0 state-0] $% [%0 *]
[%1 state-1] [%1 *]
[%2 state-2] [%2 *]
[%3 state-3] [%3 *]
[%4 ~]
== ==
+$ state-3 state-1
+$ state-2 state-1
+$ state-1
$: listening=(set app-path)
state-0
==
+$ state-0
$: retry-timers=(map target @dr)
:: reasoning: the resources we're subscribed to,
:: and the groups that cause that.
::
:: we don't strictly need to track this in state, but doing so heavily
:: simplifies logic and reduces the amount of big scries we do.
:: this also gives us the option to check & restore subscriptions,
:: should we ever need that.
::
reasoning=(jug [ship app-path] group-path)
==
::
+$ what-target ?(%local-pages %annotations)
+$ target
$: what=what-target
who=ship
where=path
==
++ wire-to-target
|= =wire
^- target
?> ?=([what-target @ ^] wire)
[i.wire (slav %p i.t.wire) t.t.wire]
++ target-to-wire
|= target
^- wire
[what (scot %p who) where]
::
+$ card card:agent:gall +$ card card:agent:gall
-- --
:: ::
=| [%3 state-3] =| [%4 ~]
=* state - =* state -
:: ::
%- agent:dbug %- agent:dbug
%+ verb | %+ verb |
^- agent:gall ^- agent:gall
=<
|_ =bowl:gall
+* this .
do ~(. +> bowl)
def ~(. (default-agent this %|) bowl)
::
++ on-init
^- (quip card _this)
:_ this
~[watch-metadata:do watch-groups:do]
::
++ on-save !>(state)
++ on-load
|= =vase
^- (quip card _this)
=/ old=versioned-state
!<(versioned-state vase)
=| cards=(list card)
|-
=* upgrade-loop $
?- -.old
%3 [cards this(state old)]
::
%2
:_ this(state [%3 +.old])
%+ welp cards
:~ [%pass /groups %agent [our.bowl %group-store] %leave ~]
watch-groups:do
==
::
%1
:: the upgrade from 0 left out local-only collections.
:: here, we pull those back in.
::
=. listening.old
(~(run in ~(key by reasoning.old)) tail)
=/ resources=(list [=group-path =app-path])
%~ tap in
%. %link
%~ get ju
.^ (jug app-name [group-path app-path])
%gy
(scot %p our.bowl)
%metadata-store
(scot %da now.bowl)
/app-indices
==
|-
?~ resources
upgrade-loop(old [%2 +.old])
=, i.resources
=/ members=(set ship)
(members-from-path:grp:do group-path)
:: if we're the only group member, this got incorrectly ignored
:: during 0's upgrade logic. watch it now.
::
?. &(=(1 ~(wyt in members)) (~(has in members) our.bowl))
$(resources t.resources)
=^ more-cards state
(handle-listen-action:do %watch app-path)
$(resources t.resources, cards (weld more-cards cards))
::
%0
=/ listening=(set app-path)
(~(run in ~(key by reasoning.old)) tail)
$(old [%1 listening +.old])
==
::
++ on-agent
|= [=wire =sign:agent:gall]
^- (quip card _this)
=^ cards state
?+ wire ~|([dap.bowl %weird-agent-wire wire] !!)
[%metadata ~]
(take-metadata-sign:do sign)
::
[%groups ~]
(take-groups-sign:do sign)
::
[%links ?(%local-pages %annotations) @ ^]
(take-link-sign:do (wire-to-target t.wire) sign)
::
[%forward ^]
(take-forward-sign:do t.wire sign)
::
[%prod *]
?> ?=(%poke-ack -.sign)
?~ p.sign [~ state]
%- (slog leaf+"prod failed" u.p.sign)
[~ state]
==
[cards this]
::
++ on-poke
|= [=mark =vase]
?+ mark (on-poke:def mark vase)
%link-listen-poke
=/ =path !<(path vase)
:_ this
%+ weld
(take-retry:do %local-pages src.bowl path)
(take-retry:do %annotations src.bowl path)
::
%link-listen-action
?> (team:title [our src]:bowl)
=^ cards state
~| p.vase
(handle-listen-action:do !<(action:listen-hook vase))
[cards this]
==
::
++ on-arvo
|= [=wire =sign-arvo]
^- (quip card _this)
?+ sign-arvo (on-arvo:def wire sign-arvo)
[%g %done *]
?~ error.sign-arvo [~ this]
=/ =tank leaf+"{(trip dap.bowl)}'s message went wrong!"
%- (slog tank tang.u.error.sign-arvo)
[~ this]
::
[%b %wake *]
?> ?=([%retry @ @ ^] wire)
?^ error.sign-arvo
=/ =tank leaf+"wake on {(spud wire)} went wrong!"
%- (slog tank u.error.sign-arvo)
[~ this]
:_ this
(take-retry:do (wire-to-target t.wire))
==
::
++ on-peek
|= =path
^- (unit (unit cage))
?+ path ~
[%x %listening ~] ``noun+!>(listening)
[%x %listening ^] ``noun+!>((~(has in listening) t.t.path))
==
::
++ on-watch
|= =path
^- (quip card _this)
?. ?=([%listening ~] path) (on-watch:def path)
?> (team:title [our src]:bowl)
:_ this
[%give %fact ~ %link-listen-update !>([%listening listening])]~
::
++ on-leave on-leave:def
++ on-fail on-fail:def
--
::
::
|_ =bowl:gall |_ =bowl:gall
+* md ~(. mdl bowl) +* this .
++ grp ~(. grpl bowl) def ~(. (default-agent this %|) bowl)
:: ::
:: user actions & updates ++ on-init [~ this]
:: ++ on-save !>(state)
++ handle-listen-action ++ on-load
|= =action:listen-hook |= =vase
^- (quip card _state) ^- (quip card _this)
::NOTE no-opping where appropriate happens further down the call stack. :_ this
:: we *could* no-op here, as %watch when we're already listening should :- [%pass /groups %agent [our.bowl %group-store] %leave ~]
:: result in no-ops all the way down, but walking through everything %+ turn ~(tap in ~(key by wex.bowl))
:: makes this a nice "resurrect if broken unexpectedly" option. |= [=wire =ship =term]
::
=* app-path path.action
=^ cards listening
^- (quip card _listening)
=/ had=? (~(has in listening) app-path)
?- -.action
%watch
:_ (~(put in listening) app-path)
?:(had ~ [(send-update action)]~)
::
%leave
:_ (~(del in listening) app-path)
?.(had ~ [(send-update action)]~)
==
=/ groups=(list group-path)
(groups-from-resource:md %link app-path)
|-
?~ groups [cards state]
=^ more-cards state
?- -.action
%watch (listen-to-group app-path i.groups)
%leave (leave-from-group app-path i.groups)
==
$(cards (weld cards more-cards), groups t.groups)
::
++ send-update
|= =update:listen-hook
^- card ^- card
[%give %fact ~[/listening] %link-listen-update !>(update)] [%pass wire %agent [ship term] %leave ~]
:: ::
:: metadata subscription ++ on-arvo
:: |= [=wire =sign-arvo]
++ watch-metadata ^- (quip card _this)
^- card ?+ sign-arvo (on-arvo:def wire sign-arvo)
[%pass /metadata %agent [our.bowl %metadata-store] %watch /app-name/link] [%b *] [~ this]
::
++ take-metadata-sign
|= =sign:agent:gall
^- (quip card _state)
?- -.sign
%poke-ack ~|([dap.bowl %unexpected-poke-ack /metadata] !!)
%kick [[watch-metadata]~ state]
::
%watch-ack
?~ p.sign [~ state]
=/ =tank
:- %leaf
"{(trip dap.bowl)} failed subscribe to metadata store. very wrong!"
%- (slog tank u.p.sign)
[~ state]
::
%fact
=* mark p.cage.sign
=* vase q.cage.sign
?. ?=(%metadata-update mark)
~| [dap.bowl %unexpected-mark mark]
!!
%- handle-metadata-update
!<(metadata-update vase)
== ==
:: ::
++ handle-metadata-update ++ on-agent on-agent:def
|= upd=metadata-update ++ on-poke on-poke:def
^- (quip card _state) ++ on-peek on-peek:def
?+ -.upd [~ state] ++ on-watch on-watch:def
%add ++ on-leave on-leave:def
?> =(%link app-name.resource.upd) ++ on-fail on-fail:def
:: auto-listen to collections in unmanaged groups only
::
=/ rid=resource
(de-path:resource group-path.upd)
=/ =group
(need (scry-group:grp rid))
?. hidden.group
[~ state]
=, resource.upd
=^ update listening
^- (quip card _listening)
?: (~(has in listening) app-path)
[~ listening]
:- [(send-update %watch app-path)]~
(~(put in listening) app-path)
=^ cards state
(listen-to-group app-path group-path.upd)
[(weld update cards) state]
::
%remove
?> =(%link app-name.resource.upd)
=? listening
?=(~ (groups-from-resource:md %link app-path.resource.upd))
(~(del in listening) app-path.resource.upd)
(leave-from-group app-path.resource.upd group-path.upd)
==
::
:: groups subscriptions
::
++ watch-groups
^- card
[%pass /groups %agent [our.bowl %group-store] %watch /groups]
::
++ take-groups-sign
|= =sign:agent:gall
^- (quip card _state)
?- -.sign
%poke-ack ~|([dap.bowl %unexpected-poke-ack /groups] !!)
%kick [[watch-groups]~ state]
::
%watch-ack
?~ p.sign [~ state]
=/ =tank
:- %leaf
"{(trip dap.bowl)} failed subscribe to groups. very wrong!"
%- (slog tank u.p.sign)
[~ state]
::
%fact
=* mark p.cage.sign
=* vase q.cage.sign
?+ mark ~|([dap.bowl %unexpected-mark mark] !!)
%group-initial [~ state] ::NOTE initial handled using metadata
%group-update (handle-group-update !<(update:group-store vase))
==
==
::
++ handle-group-update
|= upd=update:group-store
^- (quip card _state)
?. ?=(?(%add-members %initial-group %remove-members) -.upd)
[~ state]
=/ =path
(en-path:resource resource.upd)
=/ socs=(list app-path)
(app-paths-from-group:md %link path)
=/ whos=(list ship)
?- -.upd
%add-members ~(tap in ships.upd)
%remove-members ~(tap in ships.upd)
%initial-group ~(tap in members.group.upd)
==
=| cards=(list card)
|-
=* loop-socs $
?~ socs [cards state]
?. (~(has in listening) i.socs)
loop-socs(socs t.socs)
|-
=* loop-whos $
?~ whos loop-socs(socs t.socs)
=^ caz state
?. ?=(%remove-members -.upd)
(listen-to-peer i.socs path i.whos)
?: =(our.bowl i.whos)
(handle-listen-action %leave i.socs)
(leave-from-peer i.socs path i.whos)
loop-whos(whos t.whos, cards (weld cards caz))
::
:: link subscriptions
::
++ listen-to-group
|= [=app-path =group-path]
^- (quip card _state)
=/ peers=(list ship)
~| group-path
%~ tap in
(members-from-path:grp group-path)
=| cards=(list card)
|-
?~ peers [cards state]
=^ caz state
(listen-to-peer app-path group-path i.peers)
$(peers t.peers, cards (weld cards caz))
::
++ leave-from-group
|= [=app-path =group-path]
^- (quip card _state)
=/ peers=(list ship)
%~ tap in
(members-from-path:grp group-path)
=| cards=(list card)
|-
?~ peers [cards state]
=^ caz state
(leave-from-peer app-path group-path i.peers)
$(peers t.peers, cards (weld cards caz))
::
++ listen-to-peer
|= [=app-path =group-path who=ship]
^- (quip card _state)
?: =(our.bowl who)
[~ state]
:_ =- state(reasoning -)
(~(put ju reasoning) [who app-path] group-path)
:- (prod-other-listener who app-path)
?^ (~(get ju reasoning) [who app-path])
~
(start-link-subscriptions who app-path)
::
++ leave-from-peer
|= [=app-path =group-path who=ship]
^- (quip card _state)
?: =(our.bowl who)
[~ state]
=. reasoning (~(del ju reasoning) [who app-path] group-path)
::NOTE leaving is always safe, so we just do it unconditionally
(end-link-subscriptions who app-path)
::
++ start-link-subscriptions
|= [=ship =app-path]
^- (list card)
:~ (start-link-subscription %local-pages ship app-path)
(start-link-subscription %annotations ship app-path)
==
::
++ start-link-subscription
|= =target
^- card
:* %pass
[%links (target-to-wire target)]
%agent
[who.target %link-proxy-hook]
%watch
?- what.target
%local-pages [what where]:target
%annotations [what %$ where]:target
==
==
::
++ end-link-subscriptions
|= [who=ship where=path]
^- (quip card _state)
=. retry-timers (~(del by retry-timers) [%local-pages who where])
=. retry-timers (~(del by retry-timers) [%annotations who where])
:_ state
|^ ~[(end %local-pages) (end %annotations)]
::
++ end
|= what=what-target
:* %pass
[%links (target-to-wire what who where)]
%agent
[who %link-proxy-hook]
%leave
~
==
--
::
++ prod-other-listener
|= [who=ship where=path]
^- card
:* %pass
[%prod (scot %p who) where]
%agent
[who %link-listen-hook]
%poke
%link-listen-poke
!>(where)
==
::
++ take-link-sign
|= [=target =sign:agent:gall]
^- (quip card _state)
?- -.sign
%poke-ack ~|([dap.bowl %unexpected-poke-ack /links target] !!)
%kick [[(start-link-subscription target)]~ state]
::
%watch-ack
?~ p.sign
=. retry-timers (~(del by retry-timers) target)
[~ state]
:: our subscription request got rejected,
:: most likely because our group definition is out of sync with theirs.
:: set timer for retry.
::
(start-retry target)
::
%fact
=* mark p.cage.sign
=* vase q.cage.sign
?+ mark ~|([dap.bowl %unexpected-mark mark] !!)
%link-initial
%- handle-link-initial
[who.target where.target !<(initial:store vase)]
::
%link-update
%- handle-link-update
[who.target where.target !<(update:store vase)]
==
==
::
++ start-retry
|= =target
^- (quip card _state)
=/ timer=@dr
%+ min ~h1
%+ mul 2
(~(gut by retry-timers) target ~s15)
=. retry-timers
(~(put by retry-timers) target timer)
:_ state
:_ ~
:* %pass
[%retry (target-to-wire target)]
[%arvo %b %wait (add now.bowl timer)]
==
::
++ take-retry
|= =target
^- (list card)
:: relevant: whether :who is still associated with resource :where
::
=; relevant=?
?. relevant ~
[(start-link-subscription target)]~
?. (~(has in listening) where.target)
|
?: %- ~(has by wex.bowl)
[[%links (target-to-wire target)] who.target %link-proxy-hook]
|
%+ lien (groups-from-resource:md %link where.target)
|= =group-path
^- ?
%. who.target
~(has in (members-from-path:grp group-path))
::
++ do-link-action
|= [=wire =action:store]
^- card
:* %pass
wire
%agent
[our.bowl %link-store]
%poke
%link-action
!>(action)
==
::
++ handle-link-initial
|= [who=ship where=path =initial:store]
^- (quip card _state)
?> =(src.bowl who)
?+ -.initial ~|([dap.bowl %unexpected-initial -.initial] !!)
%local-pages
=/ =pages (~(got by pages.initial) where)
(handle-link-update who where [%local-pages where pages])
::
%annotations
=/ urls=(list [=url =notes])
~(tap by (~(got by notes.initial) where))
=| cards=(list card)
|- ^- (quip card _state)
?~ urls [cards state]
=^ caz state
^- (quip card _state)
=, i.urls
(handle-link-update who where [%annotations where url notes])
$(urls t.urls, cards (weld cards caz))
==
::
++ handle-link-update
|= [who=ship where=path =update:store]
^- (quip card _state)
?> =(src.bowl who)
:_ state
?+ -.update ~|([dap.bowl %unexpected-update -.update] !!)
%local-pages
%+ turn pages.update
|= =page
%+ do-link-action
[%forward %local-page (scot %p who) where]
[%hear where who page]
::
%annotations
%+ turn notes.update
|= =note
^- card
%+ do-link-action
`wire`[%forward %annotation (scot %p who) where]
`action:store`[%read where url.update `comment`[who note]]
==
::
++ take-forward-sign
|= [=wire =sign:agent:gall]
^- (quip card _state)
~| [%unexpected-sign on=[%forward wire] -.sign]
?> ?=(%poke-ack -.sign)
?~ p.sign [~ state]
=/ =tank
:- %leaf
;: weld
(trip dap.bowl)
" failed to save submission from "
(spud wire)
==
%- (slog tank u.p.sign)
[~ state]
::
++ scry-for
|* [=mold =app-name =path]
.^ mold
%gx
(scot %p our.bowl)
app-name
(scot %da now.bowl)
(snoc `^path`path %noun)
==
-- --

View File

@ -1,337 +1,46 @@
:: link-proxy-hook: make local pages available to foreign ships :: link-proxy-hook: no longer in use
:: ::
:: this is a "proxy" style hook, relaying foreign subscriptions into local /+ default-agent, verb, dbug
:: stores if permission conditions are met.
:: the patterns herein should one day be generalized into a proxy-hook lib.
::
:: this uses metadata-store to discover resources and their associated
:: groups. it sets the permission condition to be that a ship must be in a
:: group associated with the resource it's subscribing to.
:: we check this on-watch, but also subscribe to metadata & groups so that
:: we can kick subscriptions if needed (eg ship removed from group).
::
:: we deduplicate incoming subscriptions on the same path, ensuring we have
:: exactly one local subscription per unique incoming subscription path.
:: this comes at the cost of assuming that the store's initial response is
:: whatever's returned by the scry at that path, but perhaps that should
:: become part of the stores standard anyway.
::
:: when adding support for new paths, the only things you'll likely want
:: to touch are +permitted, +initial-response, & +kick-proxies.
::
/- *link, *metadata-store, *group
/+ metadata, default-agent, verb, dbug, group-store, grpl=group,
resource, store=link-store
~% %link-proxy-hook-top ..is ~ ~% %link-proxy-hook-top ..is ~
|% |%
+$ state-0
$: %0
::TODO we use this to detect "first sub started" and "last sub left",
:: but can't we use [wex sup]:bowl for that?
active=(map path (set ship))
==
+$ state-1
$: %1
active=(map path (set ship))
==
::
+$ versioned-state +$ versioned-state
$% state-0 $% [%0 *]
state-1 [%1 *]
[%2 ~]
== ==
:: ::
+$ card card:agent:gall +$ card card:agent:gall
-- --
:: ::
=| state-1 =| [%2 ~]
=* state - =* state -
:: ::
%- agent:dbug %- agent:dbug
%+ verb | %+ verb |
^- agent:gall ^- agent:gall
=<
|_ =bowl:gall
+* this .
do ~(. +> bowl)
def ~(. (default-agent this %&) bowl)
::
++ on-init
^- (quip card _this)
:_ this
~[watch-groups:do watch-metadata:do]
::
++ on-save !>(state)
++ on-load
|= old-vase=vase
^- (quip card _this)
=/ old
!<(versioned-state old-vase)
?- -.old
%1 [~ this(state old)]
::
%0
:_ this(state [%1 +.old])
:~ [%pass /groups %agent [our.bowl %group-store] %leave ~]
watch-groups:do
==
==
::
++ on-watch
|= =path
^- (quip card _this)
:: the local ship should just use link-store directly
::TODO do we want to allow this anyway, to avoid client-side target checks?
::
?< (team:title [our src]:bowl)
?> (permitted:do src.bowl path)
=^ cards state
(start-proxy:do src.bowl path)
[cards this]
::
++ on-leave
|= =path
^- (quip card _this)
=^ cards state
(stop-proxy:do src.bowl path)
[cards this]
::
++ on-agent
|= [=wire =sign:agent:gall]
^- (quip card _this)
?: ?=([%groups ~] wire)
=^ cards state
(take-groups-sign:do sign)
[cards this]
?: ?=([%proxy ^] wire)
=^ cards state
(handle-proxy-sign t.wire sign)
[cards this]
~| [dap.bowl %weird-wire wire]
!!
::
++ on-poke on-poke:def
++ on-peek on-peek:def
++ on-arvo on-arvo:def
++ on-fail on-fail:def
--
::
|_ =bowl:gall |_ =bowl:gall
+* md ~(. metadata bowl) +* this .
grp ~(. grpl bowl) def ~(. (default-agent this %&) bowl)
:: ::
:: permissions ++ on-init on-init:def
++ on-save !>(state)
++ on-load
|= old-vase=vase
^- (quip card _this)
=/ paths
%+ turn ~(val by sup.bowl)
|=([=ship =path] path)
:_ this
:- [%pass /groups %agent [our.bowl %group-store] %leave ~]
?~ paths ~
[%give %kick paths ~]~
:: ::
++ permitted ++ on-watch on-watch:def
|= [who=ship =path] ++ on-leave on-leave:def
^- ? ++ on-agent on-agent:def
:: we only expose /local-pages and /annotations, ++ on-poke on-poke:def
:: to ships in the groups associated with the resource. ++ on-peek on-peek:def
:: (no url-specific annotations subscriptions, either.) ++ on-arvo on-arvo:def
:: ++ on-fail on-fail:def
=/ target=(unit ^path)
?: ?=([%local-pages ^] path)
`t.path
?: ?=([%annotations ~ ^] path)
`t.t.path
~
?~ target |
%+ lien (groups-from-resource:md %link u.target)
|= =group-path
^- ?
(~(has in (members-from-path:grp group-path)) who)
::
++ kick-revoked-permissions
|= [=path who=(list ship)]
^- (list card)
%+ murn who
|= =ship
^- (unit card)
:: no need to remove to ourselves
::
?: =(our.bowl ship) ~
?: (permitted ship path) ~
`(kick-proxies ship path)
::
:: metadata subscription
::
++ watch-metadata
^- card
[%pass /metadata %agent [our.bowl %metadata-store] %watch /app-name/link]
::
++ take-metadata-sign
|= =sign:agent:gall
^- (quip card _state)
?- -.sign
%poke-ack ~|([dap.bowl %unexpected-poke-ack /metadata] !!)
%kick [[watch-metadata]~ state]
::
%watch-ack
?~ p.sign [~ state]
=/ =tank
:- %leaf
"{(trip dap.bowl)} failed subscribe to metadata store. very wrong!"
%- (slog tank u.p.sign)
[~ state]
::
%fact
=* mark p.cage.sign
=* vase q.cage.sign
?. ?=(%metadata-update mark)
~| [dap.bowl %unexpected-mark mark]
!!
%- handle-metadata-update
!<(metadata-update vase)
==
::
++ handle-metadata-update
|= upd=metadata-update
^- (quip card _state)
:_ state
?. ?=(%remove -.upd) ~
?> =(%link app-name.resource.upd)
:: if a group is no longer associated with a resource,
:: we need to re-check permissions for everyone in that group.
::
%+ kick-revoked-permissions
app-path.resource.upd
%~ tap in
(members-from-path:grp group-path.upd)
::
:: groups subscription
::TODO largely copied from link-listen-hook. maybe make a store-listener lib?
::
++ watch-groups
^- card
[%pass /groups %agent [our.bowl %group-store] %watch /groups]
::
++ take-groups-sign
|= =sign:agent:gall
^- (quip card _state)
?- -.sign
%poke-ack ~|([dap.bowl %unexpected-poke-ack /groups] !!)
%kick [[watch-groups]~ state]
::
%watch-ack
?~ p.sign [~ state]
=/ =tank
:- %leaf
"{(trip dap.bowl)} failed subscribe to group store. very wrong!"
%- (slog tank u.p.sign)
[~ state]
::
%fact
=* mark p.cage.sign
=* vase q.cage.sign
?+ mark ~|([dap.bowl %unexpected-mark mark] !!)
%group-initial [~ state]
%group-update (handle-group-update !<(update:group-store vase))
==
==
::
++ handle-group-update
|= upd=update:group-store
^- (quip card _state)
:_ state
?. ?=(%remove-members -.upd) ~
:: if someone was removed from a group, find all link resources associated
:: with that group, then kick their subscriptions if they're no longer
::
%- zing
%+ turn (app-paths-from-group:md %link (en-path:resource resource.upd))
|= =app-path
^- (list card)
%+ kick-revoked-permissions
app-path
~(tap in ships.upd)
::
:: proxy subscriptions
::
++ kick-proxies
|= [who=ship =path]
^- card
=- [%give %kick - `who]
:~ [%local-pages path]
[%annotations %$ path]
==
::
++ handle-proxy-sign
|= [=wire =sign:agent:gall]
^- (quip card _state)
?- -.sign
%poke-ack ~|([dap.bowl %unexpected-poke-ack wire] !!)
%fact [[%give %fact ~[wire] cage.sign]~ state]
%kick [[(proxy-pass-link-store wire %watch wire)]~ state]
::
%watch-ack
?~ p.sign [~ state]
=/ =tank
:- %leaf
"{(trip dap.bowl)} failed subscribe to link-store. very wrong!"
%- (slog tank u.p.sign)
[~ state]
==
::
++ proxy-pass-link-store
|= [=path =task:agent:gall]
^- card
:* %pass
[%proxy path]
%agent
[our.bowl %link-store]
task
==
::
++ initial-response
|= =path
^- card
=; =initial:store
[%give %fact ~ %link-initial !>(initial)]
?+ path !!
[%local-pages ^]
[%local-pages (scry-for (map ^path pages) %link-store path)]
::
[%annotations %$ ^]
[%annotations (scry-for (per-path-url notes) %link-store path)]
==
::
++ start-proxy
|= [who=ship =path]
^- (quip card _state)
:_ state(active (~(put ju active) path who))
:_ ~
:: if we already have a local subscription open,
::
?. =(~ (~(get ju active) path))
:: gather the initial response ourselves, and send that.
::
(initial-response path)
:: else, open a local subscription,
:: sending outward its initial response when we hear it.
::
(proxy-pass-link-store path %watch path)
::
++ stop-proxy
|= [who=ship =path]
^- (quip card _state)
=. active (~(del ju active) path who)
:_ state
:: if there are still subscriptions remaining, do nothing.
::
?. =(~ (~(get ju active) path)) ~
:: else, close the local subscription.
::
[(proxy-pass-link-store path %leave ~)]~
::
:: helpers
::
++ scry-for
|* [=mold =app-name =path]
.^ mold
%gx
(scot %p our.bowl)
app-name
(scot %da now.bowl)
(snoc `^path`path %noun)
==
-- --

View File

@ -1,59 +1,13 @@
:: link: social bookmarking :: link [landscape]:
:: ::
:: the paths under which links are submitted are generally expected to /- *link, gra=graph-store, *resource
:: correspond to existing group paths. for strictly-local collections of /+ store=link-store, graph-store, default-agent, verb, dbug
:: links, arbitrary paths are probably fair game, but could trip up
:: primitive ui implementations.
::
:: urls in paths are expected to be encoded using +wood, for @ta sanity.
:: generally, use /lib/link's +build-discussion-path.
::
:: see link-listen-hook to see what's synced in, and similarly
:: see link-proxy-hook to see what's exposed.
::
:: scry and subscription paths:
::
:: (map path pages) %local-pages
:: /local-pages our saved pages
:: /local-pages/some-path our saved pages on path
::
:: (map path submissions) %submissions
:: /submissions all submissions we've seen
:: /submissions/some-path all submissions we've seen on path
::
:: (map path (map url notes)) %annotations
:: /annotations our comments
:: /annotations/wood-url our comments on url
:: /annotations/wood-url/some-path our comments on url on path
:: /annotations//some-path our comments on path
::
:: (map path (map url comments)) %discussions
:: /discussions all comments
:: /discussions/wood-url all comments on url
:: /discussions/wood-url/some-path all comments on url on path
:: /discussions//some-path all comments on path
::
:: subscription-only paths:
::
:: [path url] %observation
:: /seen updates whenever an item is seen
::
:: scry-only paths:
::
::
:: (map path (set url))
:: /unseen the ones we haven't seen yet
::
:: (set url)
:: /unseen/some-path the ones we haven't seen here yet
::
:: ?
:: /seen/wood-url/some-path have we seen this here
::
/- *link
/+ store=link-store, default-agent, verb, dbug
:: ::
|% |%
+$ spore-any $%(spore-1 state-0)
+$ state-any $%(state-1 state-0)
+$ spore-1 [%1 cards=*]
+$ state-1 [%1 cards=(list card)]
+$ state-0 +$ state-0
$: %0 $: %0
by-group=(map path links) by-group=(map path links)
@ -76,414 +30,119 @@
+$ card card:agent:gall +$ card card:agent:gall
-- --
:: ::
=| state-0 =| state-1
=* state - =* state -
:: ::
%- agent:dbug %- agent:dbug
%+ verb | %+ verb |
^- agent:gall ^- agent:gall
=<
|_ =bowl:gall
+* this .
do ~(. +> bowl)
def ~(. (default-agent this %|) bowl)
::
++ on-init on-init:def
++ on-save !>(state)
++ on-load
|= old=vase
^- (quip card _this)
[~ this(state !<(state-0 old))]
::
++ on-poke
|= [=mark =vase]
^- (quip card _this)
?> (team:title [our src]:bowl) ::TODO /lib/store
=^ cards state
?+ mark (on-poke:def mark vase)
::TODO move json conversion into mark once mark performance improves
%json (do-action:do (action:dejs:store !<(json vase)))
%link-action (do-action:do !<(action:store vase))
==
[cards this]
::
++ on-peek
|= =path
^- (unit (unit cage))
?+ path (on-peek:def path)
[%y ?(%local-pages %submissions) ~]
``noun+!>(~(key by by-group))
::
[%x %local-pages *]
``noun+!>((get-local-pages:do t.t.path))
::
[%x %submissions *]
``noun+!>((get-submissions:do t.t.path))
::
[%y ?(%annotations %discussions) *]
=/ [spath=^path surl=url]
(break-discussion-path:store t.t.path)
=- ``noun+!>(-)
::
?: =(~ surl)
:: no url, provide urls that have comments
::
^- (set url)
?~ spath
:: no path, find urls accross all paths
::
%- ~(rep by discussions)
|= [[* discussions=(map url discussion)] urls=(set url)]
%- ~(uni in urls)
~(key by discussions)
:: specified path, find urls for that specific path
::
%~ key by
(~(gut by discussions) spath *(map url *))
:: specified url and path, nothing to list here
::
?^ spath !!
:: no path, find paths with comments for this url
::
^- (set ^path)
%- ~(rep by discussions)
|= [[=^path urls=(map url discussion)] paths=(set ^path)]
?. (~(has by urls) surl) paths
(~(put in paths) path)
::
[%x %annotations *]
``noun+!>((get-annotations:do t.t.path))
::
[%x %discussions *]
``noun+!>((get-discussions:do t.t.path))
::
[%x %seen @ ^]
``noun+!>((is-seen:do t.t.path))
::
[%x %unseen ~]
``noun+!>(get-all-unseen:do)
::
[%x %unseen ^]
``noun+!>((get-unseen:do t.t.path))
==
::
++ on-watch
|= =path
^- (quip card _this)
?> (team:title [our src]:bowl) ::TODO /lib/store
:_ this
|^ ?+ path (on-watch:def path)
[%local-pages *]
%+ give %link-initial
^- initial:store
[%local-pages (get-local-pages:do t.path)]
::
[%submissions *]
%+ give %link-initial
^- initial:store
[%submissions (get-submissions:do t.path)]
::
[%annotations *]
%+ give %link-initial
^- initial:store
[%annotations (get-annotations:do t.path)]
::
[%discussions *]
%+ give %link-initial
^- initial:store
[%discussions (get-discussions:do t.path)]
::
[%seen ~]
~
==
::
++ give
|* [=mark =noun]
^- (list card)
[%give %fact ~ mark !>(noun)]~
::
++ give-single
|* [=mark =noun]
^- card
[%give %fact ~ mark !>(noun)]
--
::
++ on-leave on-leave:def
++ on-agent on-agent:def
++ on-arvo on-arvo:def
++ on-fail on-fail:def
--
::
|_ =bowl:gall |_ =bowl:gall
+* this .
do ~(. +> bowl)
def ~(. (default-agent this %|) bowl)
:: ::
:: writing ++ on-init on-init:def
:: ++ on-save !>(state)
++ do-action ++ on-load
|= =action:store |= old=vase
^- (quip card _state) ^- (quip card _this)
?- -.action
%save (save-page +.action)
%note (note-note +.action)
%seen (seen-submission +.action)
:: ::
%hear (hear-submission +.action) =/ s !<(spore-any old)
%read (read-comment +.action) ?: ?=(%1 -.s)
== [~ this(state s(cards ~))]
:: +save-page: save a page ourselves :: defer card emission to later event
::
++ save-page
|= [=path title=@t =url]
^- (quip card _state)
?< |(=(~ path) =(~ title) =(~ url))
:: add page to group ours
:: ::
=/ =links (~(gut by by-group) path *links) =; [cards=(list card) that=_this]
=/ =page [title url now.bowl] :_ that(state [%1 cards])
=. ours.links [page ours.links] [%pass /load %arvo %b %wait now.bowl]~
=. by-group (~(put by by-group) path links)
:: do generic submission logic
:: ::
=^ submission-cards state :_ this(state *state-1)
(hear-submission path [our.bowl page]) =/ orm orm:graph-store
:: mark page as seen (because we submitted it ourselves) |^ ^- (list card)
:: %- zing
=^ seen-cards state %+ turn ~(tap by by-group.s)
(seen-submission path `url) |= [=path =links]
:: send updates to subscribers
::
:_ state
:_ (weld submission-cards seen-cards)
:+ %give %fact
:+ :~ /local-pages
[%local-pages path]
==
%link-update
!>([%local-pages path [page]~])
:: +note-note: save a note for a url
::
++ note-note
|= [=path =url udon=@t]
^- (quip card _state)
?< |(=(~ path) =(~ url) =(~ udon))
:: add note to discussion ours
::
=/ urls (~(gut by discussions) path *(map ^url discussion))
=/ =discussion (~(gut by urls) url *discussion)
=/ =note [now.bowl udon]
=. ours.discussion [note ours.discussion]
=. urls (~(put by urls) url discussion)
=. discussions (~(put by discussions) path urls)
:: do generic comment logic
::
=^ cards state
(read-comment path url [our.bowl note])
:: send updates to subscribers
::
:_ state
^- (list card) ^- (list card)
:_ cards ?. ?=([@ ~] path)
:+ %give %fact (on-bad-path path links)
:+ :~ /annotations =/ =resource [our.bowl i.path]
[%annotations %$ path] :_ [(archive-graph resource)]~
[%annotations (build-discussion-path:store url)] %+ add-graph resource
[%annotations (build-discussion-path:store path url)] ^- graph:gra
%+ gas:orm ~
=/ comments (~(gut by discussions.s) path *(map url discussion))
%+ turn submissions.links
|= sub=submission
^- [atom node:gra]
:- time.sub
=/ contents ~[text+title.sub url+url.sub]
=/ parent-hash `@ux`(sham ~ ship.sub time.sub contents)
:- ^- post:gra
:* author=ship.sub
index=~[time.sub]
time-sent=time.sub
contents
hash=`parent-hash
signatures=~
== ==
%link-update ^- internal-graph:gra
!>([%annotations path url [note]~]) =/ dis (~(get by comments) url.sub)
:: +seen-submission: mark url as seen/read ?~ dis
:: [%empty ~]
:: if no url specified, all under path are marked as read :- %graph
:: ^- graph:gra
++ seen-submission %+ gas:orm ~
|= [=path murl=(unit url)] %+ turn comments.u.dis
^- (quip card _state) |= [=ship =time udon=@t]
=/ =links (~(gut by by-group) path *links) ^- [atom node:gra]
:: new: urls we want to, but haven't yet, marked as seen :- time
:_ `internal-graph:gra`[%empty ~]
=/ contents ~[text+udon]
:* author=ship
index=~[time.sub time]
time-sent=time
contents
hash=``@ux`(sham `parent-hash ship time contents)
signatures=~
==
:: ::
=/ new=(set url) ++ on-bad-path
%. seen.links |= [=path =links]
%~ dif in ^- (list card)
^- (set url) ~& discarding-malformed-links+[path links]
?^ murl (sy ~[u.murl]) ~
%- ~(gas in *(set url))
%+ turn submissions.links
|=(submission url)
?: =(~ new) [~ state]
=. seen.links (~(uni in seen.links) new)
:_ state(by-group (~(put by by-group) path links))
[%give %fact ~[/seen] %link-update !>([%observation path new])]~
:: +hear-submission: record page someone else saved
::
++ hear-submission
|= [=path =submission]
^- (quip card _state)
?< =(~ path)
:: add link to group submissions
:: ::
=/ =links (~(gut by by-group) path *links) ++ add-graph
=^ added submissions.links |= [=resource =graph:gra]
?: ?=(^ (find ~[submission] submissions.links)) ^- card
[| submissions.links] %- poke-graph-store
:- & [%0 now.bowl %add-graph resource graph `%graph-validator-link %.y]
(submissions:merge:store submissions.links ~[submission])
=. by-group (~(put by by-group) path links)
:: add submission to global sites
:: ::
=/ =site (site-from-url:store url.submission) ++ archive-graph
=. by-site (~(add ja by-site) site [path submission]) |= =resource
:: send updates to subscribers ^- card
%- poke-graph-store
[%0 now.bowl %archive-graph resource]
:: ::
:_ state ++ poke-graph-store
?. added ~ |= =update:gra
:_ ~ ^- card
:+ %give %fact :* %pass /migrate-link %agent [our.bowl %graph-store]
:+ :~ /submissions %poke %graph-update !>(update)
[%submissions path] ==
==
%link-update
!>([%submissions path [submission]~])
:: +read-comment: record a comment someone else made
::
++ read-comment
|= [=path =url =comment]
^- (quip card _state)
:: add comment to url's discussion
::
=/ urls (~(gut by discussions) path *(map ^url discussion))
=/ =discussion (~(gut by urls) url *discussion)
=^ added comments.discussion
?: ?=(^ (find ~[comment] comments.discussion))
[| comments.discussion]
:- &
(comments:merge:store comments.discussion ~[comment])
=. urls (~(put by urls) url discussion)
=. discussions (~(put by discussions) path urls)
:: send updates to subscribers
::
:_ state
?. added ~
:_ ~
:+ %give %fact
:+ :~ /discussions
[%discussions '' path]
[%discussions (build-discussion-path:store url)]
[%discussions (build-discussion-path:store path url)]
==
%link-update
!>([%discussions path url [comment]~])
::
:: reading
::
++ get-local-pages
|= =path
^- (map ^path pages)
?~ path
:: all paths
::
%- ~(run by by-group)
|=(links ours)
:: specific path
::
%+ ~(put by *(map ^path pages)) path
ours:(~(gut by by-group) path *links)
::
++ get-submissions
|= =path
^- (map ^path submissions)
?~ path
:: all paths
::
%- ~(run by by-group)
|=(links submissions)
:: specific path
::
%+ ~(put by *(map ^path submissions)) path
submissions:(~(gut by by-group) path *links)
::
++ get-all-unseen
^- (jug path url)
%- ~(rut by by-group)
|= [=path *]
(get-unseen path)
::
++ get-unseen
|= =path
^- (set url)
=/ =links
(~(gut by by-group) path *links)
%- ~(gas in *(set url))
%+ murn submissions.links
|= submission
?: (~(has in seen.links) url) ~
(some url)
::
++ is-seen
|= =path
^- ?
=/ [=^path =url]
(break-discussion-path:store path)
%. url
%~ has in
seen:(~(gut by by-group) path *links)
::
::
++ get-annotations
|= =path
^- (per-path-url notes)
=/ args=[=^path =url]
(break-discussion-path:store path)
|^ ?~ path
:: all paths
::
(~(run by discussions) get-ours)
:: specific path
::
%+ ~(put by *(per-path-url notes)) path.args
%- get-ours
%+ ~(gut by discussions) path.args
*(map url discussion)
::
++ get-ours
|= m=(map url discussion)
^- (map url notes)
?: =(~ url.args)
:: all urls
::
%- ~(run by m)
|=(discussion ours)
:: specific url
::
%+ ~(put by *(map url notes)) url.args
ours:(~(gut by m) url.args *discussion)
-- --
:: ::
++ get-discussions ++ on-poke on-poke:def
|= =path ++ on-peek on-peek:def
^- (per-path-url comments) ++ on-watch on-watch:def
=/ args=[=^path =url] ++ on-leave on-leave:def
(break-discussion-path:store path) ++ on-agent on-agent:def
|^ ?~ path ++ on-arvo
:: all paths |= [=wire =sign-arvo]
:: ^- (quip card _this)
(~(run by discussions) get-comments) ?+ sign-arvo (on-arvo:def wire sign-arvo)
:: specific path [%b %wake *]
:: [cards.state this]
%+ ~(put by *(per-path-url comments)) path.args ==
%- get-comments ++ on-fail on-fail:def
%+ ~(gut by discussions) path.args
*(map url discussion)
::
++ get-comments
|= m=(map url discussion)
^- (map url comments)
?: =(~ url.args)
:: all urls
::
%- ~(run by m)
|=(discussion comments)
:: specific url
::
%+ ~(put by *(map url comments)) url.args
comments:(~(gut by m) url.args *discussion)
--
-- --

View File

@ -1,626 +1,39 @@
:: link-view: frontend endpoints :: link-view: no longer in use
:: /+ default-agent, verb, dbug
:: endpoints, mapping onto link-store's paths. p is for page as in pagination.
:: only the /0/submissions endpoint provides updates.
:: as with link-store, urls are expected to use +wood encoding.
::
:: /json/0/submissions initial + updates for all
:: /json/[p]/submissions/[collection] page for one collection
:: /json/[p]/discussions/[wood-url]/[collection] page for url in collection
:: /json/[n]/submission/[wood-url]/[collection] nth matching submission
:: /json/seen mark-as-read updates
::
/- *link, view=link-view
/- *invite-store, group-store
/- listen-hook=link-listen-hook
/- group-hook, permission-hook, permission-group-hook
/- metadata-hook, contact-view
/- pull-hook, *group
/+ store=link-store, metadata, *server, default-agent, verb, dbug, grpl=group
/+ group-store, resource
~% %link-view-top ..is ~ ~% %link-view-top ..is ~
::
::
|% |%
+$ versioned-state +$ versioned-state
$% state-0 $% [%0 ~]
state-1 [%1 ~]
== [%2 ~]
+$ state-0
$: %0
~
==
::
+$ state-1
$: %1
~
== ==
:: ::
+$ card card:agent:gall +$ card card:agent:gall
-- --
:: ::
=| state-1 =| [%2 ~]
=* state - =* state -
:: ::
%+ verb | %+ verb |
%- agent:dbug %- agent:dbug
^- agent:gall ^- agent:gall
=<
|_ =bowl:gall
+* this .
do ~(. +> bowl)
def ~(. (default-agent this %|) bowl)
::
++ on-init
^- (quip card _this)
:_ this
:~ [%pass /submissions %agent [our.bowl %link-store] %watch /submissions]
[%pass /discussions %agent [our.bowl %link-store] %watch /discussions]
[%pass /seen %agent [our.bowl %link-store] %watch /seen]
::
=+ [%invite-action !>([%create /link])]
[%pass /invitatory/create %agent [our.bowl %invite-store] %poke -]
::
=+ /invitatory/link
[%pass - %agent [our.bowl %invite-store] %watch -]
:* %pass /srv %agent [our.bowl %file-server]
%poke %file-server-action
!>([%serve-dir /'~link' /app/landscape %.n %.y])
==
==
::
++ on-save !>(state)
++ on-load
|= old-vase=vase
^- (quip card _this)
=/ old !<(versioned-state old-vase)
?- -.old
%1 [~ this]
%0
:_ this(state [%1 ~])
:- [%pass /connect %arvo %e %disconnect [~ /'~link']]
:~ :* %pass /srv %agent [our.bowl %file-server]
%poke %file-server-action
!>([%serve-dir /'~link' /app/landscape %.n %.y])
== ==
==
::
++ on-poke
|= [=mark =vase]
^- (quip card _this)
?> (team:title our.bowl src.bowl)
:_ this
?+ mark (on-poke:def mark vase)
%link-action
[(handle-action:do !<(action:store vase)) ~]
::
%link-view-action
(handle-view-action:do !<(action:view vase))
==
::
++ on-watch
|= =path
^- (quip card _this)
?: ?=([%json %seen ~] path)
[~ this]
?: ?=([%tile ~] path)
:_ this
~[give-tile-data:do]
?. ?=([%json @ @ *] path)
(on-watch:def path)
=/ p=@ud (slav %ud i.t.path)
?+ t.t.path (on-watch:def path)
[%submissions ~]
:_ this
(give-initial-submissions:do p ~)
::
[%submissions ^]
:_ this
(give-initial-submissions:do p t.t.t.path)
::
[%submission @ ^]
:_ this
(give-specific-submission:do p (break-discussion-path:store t.t.t.path))
::
[%discussions @ ^]
:_ this
(give-initial-discussions:do p (break-discussion-path:store t.t.t.path))
==
::
++ on-agent
|= [=wire =sign:agent:gall]
^- (quip card _this)
?+ -.sign (on-agent:def wire sign)
%poke-ack
?. ?=([%join-group @ @ @ @ ~] wire)
(on-agent:def wire sign)
?^ p.sign
(on-agent:def wire sign)
=/ rid=resource
(de-path:resource t.t.wire)
=/ host=ship
(slav %p i.t.wire)
:_ this
(joined-group:do host rid)
::
%kick
:_ this
=/ app=term
?: ?=([%invites *] wire)
%invite-store
%link-store
[%pass wire %agent [our.bowl app] %watch wire]~
::
%fact
=* mark p.cage.sign
=* vase q.cage.sign
?+ mark (on-agent:def wire sign)
%invite-update [(handle-invite-update:do !<(invite-update vase)) this]
%link-initial [~ this]
::
%link-update
:_ this
:- (send-update:do !<(update:store vase))
?: =(/discussions wire) ~
~[give-tile-data:do]
==
==
::
++ on-arvo
|= [=wire =sign-arvo]
^- (quip card _this)
?. ?=([%e %bound *] sign-arvo)
(on-arvo:def wire sign-arvo)
~? !accepted.sign-arvo
[dap.bowl "bind rejected!" binding.sign-arvo]
[~ this]
::
++ on-peek on-peek:def
++ on-leave on-leave:def
++ on-fail on-fail:def
--
::
~% %link-view-logic ..card ~
|_ =bowl:gall |_ =bowl:gall
+* md ~(. metadata bowl) +* this .
grp ~(. grpl bowl) def ~(. (default-agent this %|) bowl)
:: ::
++ page-size 25 ++ on-init [~ this]
++ get-paginated ++ on-save !>(state)
|* [page=(unit @ud) list=(list)] ++ on-load
^- [total=@ud pages=@ud page=_list] |= old-vase=vase
=/ l=@ud (lent list) ^- (quip card _this)
:+ l :_ this(state [%2 ~])
%+ add (div l page-size) [%pass /connect %arvo %e %disconnect [~ /'~link']]~
(min 1 (mod l page-size))
?~ page list
%+ swag
[(mul u.page page-size) page-size]
list
:: ::
++ page-to-json ++ on-poke on-poke:def
=, enjs:format ++ on-watch on-watch:def
|* $: page-number=@ud ++ on-agent on-agent:def
[total-items=@ud total-pages=@ud page=(list)] ++ on-arvo on-arvo:def
item-to-json=$-(* json) ++ on-peek on-peek:def
== ++ on-leave on-leave:def
^- json ++ on-fail on-fail:def
%- pairs
:~ 'totalItems'^(numb total-items)
'totalPages'^(numb total-pages)
'pageNumber'^(numb page-number)
'page'^a+(turn page item-to-json)
==
++ do-poke
|= [app=term =mark =vase]
^- card
[%pass /create/[app]/[mark] %agent [our.bowl app] %poke mark vase]
::
++ joined-group
|= [host=ship rid=resource]
^- (list card)
=/ =path
(en-path:resource rid)
:~
:: sync the group
::
%^ do-poke %group-pull-hook
%pull-hook-action
!> ^- action:pull-hook
[%add host rid]
::
:: sync the metadata
::
%^ do-poke %metadata-hook
%metadata-hook-action
!> ^- metadata-hook-action:metadata-hook
[%add-synced host path]
::
:: sync the collection
::
%^ do-poke %link-listen-hook
%link-listen-action
!> ^- action:listen-hook
[%watch ~[name.rid]]
==
::
++ handle-invite-update
|= upd=invite-update
^- (list card)
?. ?=(%accepted -.upd) ~
?. =(/link path.upd) ~
=/ rid=resource
(de-path:resource path.invite.upd)
:~ :: add self
:* %pass
[%join-group (scot %p ship.invite.upd) path.invite.upd]
%agent [entity.rid %group-push-hook]
%poke %group-update
!> ^- action:group-store
[%add-members rid (sy our.bowl ~)]
== ==
::
++ handle-action
|= =action:store
^- card
[%pass /action %agent [our.bowl %link-store] %poke %link-action !>(action)]
::
++ handle-view-action
|= act=action:view
^- (list card)
?- -.act
%create (handle-create +.act)
%delete (handle-delete +.act)
%invite (handle-invite +.act)
==
::
++ handle-create
|= [=path title=@t description=@t members=create-members:view real-group=?]
^- (list card)
=/ group-path=^path
?- -.members
%group path.members
::
%ships
[%ship (scot %p our.bowl) path]
==
=; group-setup=(list card)
%+ weld group-setup
:~ :: add collection to metadata-store
::
%^ do-poke %metadata-hook
%metadata-action
!> ^- metadata-action:md
:^ %add group-path
[%link path]
%* . *metadata:md
title title
description description
date-created now.bowl
creator our.bowl
==
::
:: expose the metadata
::
%^ do-poke %metadata-hook
%metadata-hook-action
!> ^- metadata-hook-action:metadata-hook
[%add-owned group-path]
::
:: watch the collection ourselves
::
%^ do-poke %link-listen-hook
%link-listen-action
!> ^- action:listen-hook
[%watch path]
==
?: ?=(%group -.members) ~
:: if the group is "real", make contact-view do the heavy lifting
=/ rid=resource
(de-path:resource group-path)
?: real-group
:- %^ do-poke %contact-view
%contact-view-action
!> ^- contact-view-action:contact-view
[%groupify rid title description]
%+ turn ~(tap in ships.members)
|= =ship
^- card
%^ do-poke %invite-hook
%invite-action
!> ^- invite-action
:^ %invite /link
(sham group-path eny.bowl)
:* our.bowl
%group-hook
group-path
ship
title
==
:: for "unmanaged" groups, do it ourselves
::
=/ =policy
[%invite ships.members]
:* :: create the new group
::
%^ do-poke %group-store
%group-action
!> ^- action:group-store
[%add-group rid policy %.y]
::
:: send invites
::
%+ turn ~(tap in ships.members)
|= =ship
^- card
%^ do-poke %invite-hook
%invite-action
!> ^- invite-action
:^ %invite /link
(sham group-path eny.bowl)
:* our.bowl
%group-hook
group-path
ship
title
==
==
::
++ handle-delete
|= =path
^- (list card)
=/ groups=(list ^path)
(groups-from-resource:md [%link path])
%- zing
%+ turn groups
|= =group=^path
=/ rid=resource
(de-path:resource group-path)
%+ snoc
^- (list card)
:: if it's a real group, we can't/shouldn't unsync it. this leaves us with
:: no way to stop propagation of collection deletion.
::
?. ?=([%'~' ^] group-path) ~
:: if it's an unmanaged group, we just stop syncing the group & metadata,
:: and clean up the group (after un-hooking it, to not push deletion).
::
:~ %^ do-poke %group-hook
%group-hook-action
!> ^- action:group-hook
[%remove rid]
::
%^ do-poke %metadata-hook
%metadata-hook-action
!> ^- metadata-hook-action:metadata-hook
[%remove group-path]
::
%^ do-poke %group-store
%group-action
!> ^- action:group-store
[%remove-group rid ~]
==
:: remove collection from metadata-store
::
%^ do-poke %metadata-store
%metadata-action
!> ^- metadata-action:md
[%remove group-path [%link path]]
::
++ handle-invite
|= [=path ships=(set ship)]
^- (list card)
%- zing
%+ turn (groups-from-resource:md %link path)
|= =group=^path
^- (list card)
=/ rid=resource
(de-path:resource group-path)
=/ =group
(need (scry-group:grp rid))
%- zing
:~
?. ?=(%invite -.policy.group)
~
:~ %^ do-poke %group-store
%group-action
!> ^- action:group-store
[%change-policy rid %invite %add-invites ships]
==
::
%+ turn ~(tap in ships)
|= =ship
^- card
%^ do-poke %invite-hook
%invite-action
!> ^- invite-action
:^ %invite /link
(sham group-path eny.bowl)
:* our.bowl
%group-pull-hook
group-path
ship
(rsh 3 1 (spat path))
==
==
:: +give-tile-data: total unread count as json object
::
::NOTE the full recalc of totals here probably isn't the end of the world.
:: but in case it is, well, here it is.
::
++ give-tile-data
^- card
=; =json
[%give %fact ~[/tile] %json !>(json)]
%+ frond:enjs:format 'unseen'
%- numb:enjs:format
%- %~ rep in
(scry-for (jug path url) /unseen)
|= [[=path unseen=(set url)] total=@ud]
%+ add total
~(wyt in unseen)
::
:: +give-initial-submissions: page of submissions on path
::
:: for the / path, give page for every path
::
:: result is in the shape of: {
:: "/some/path": {
:: totalItems: 1,
:: totalPages: 1,
:: pageNumber: 0,
:: page: [
:: { commentCount: 1, ...restOfTheSubmission }
:: ]
:: },
:: "/maybe/more": { etc }
:: }
::
++ give-initial-submissions
~/ %link-view-initial-submissions
|= [p=@ud =requested=path]
^- (list card)
:_ :: only keep the base case alive (for updates), kick all others
::
?: &(=(0 p) ?=(~ requested-path)) ~
[%give %kick ~ ~]~
=; =json
[%give %fact ~ %json !>(json)]
%+ frond:enjs:format 'link-update'
%+ frond:enjs:format 'initial-submissions'
%- pairs:enjs:format
%+ turn
%~ tap by
%+ scry-for (map path submissions)
[%submissions requested-path]
|= [=path =submissions]
^- [@t json]
:- (spat path)
=; =json
:: add unseen count
::
?> ?=(%o -.json)
:- %o
%+ ~(put by p.json) 'unseenCount'
%- numb:enjs:format
%~ wyt in
%+ scry-for (set url)
[%unseen path]
?: &(=(0 p) ?=(~ requested-path))
:: for a broad-scope initial result, only give total counts
::
=, enjs:format
%- pairs
=+ l=(lent submissions)
:~ 'totalItems'^(numb l)
'totalPages'^(numb (div l page-size))
==
%^ page-to-json p
%+ get-paginated `p
submissions
|= =submission
^- json
=/ =json (submission:enjs:store submission)
?> ?=([%o *] json)
:: add in seen status
::
=. p.json
%+ ~(put by p.json) 'seen'
:- %b
%+ scry-for ?
[%seen (build-discussion-path:store path url.submission)]
:: add in comment count
::
=; comment-count=@ud
:- %o
%+ ~(put by p.json) 'commentCount'
(numb:enjs:format comment-count)
%- lent
~| [path url.submission]
^- comments
=- (~(got by (~(got by -) path)) url.submission)
%+ scry-for (per-path-url comments)
:- %discussions
(build-discussion-path:store path url.submission)
::
++ give-specific-submission
|= [n=@ud =path =url]
:_ [%give %kick ~ ~]~
=; =json
[%give %fact ~ %json !>(json)]
%+ frond:enjs:format 'link-update'
%+ frond:enjs:format 'submission'
^- json
=; sub=(unit submission)
?~ sub ~
(submission:enjs:store u.sub)
=/ =submissions
=- (~(got by -) path)
%+ scry-for (map ^path submissions)
[%submissions path]
|-
?~ submissions ~
=* sub i.submissions
?. =(url.sub url)
$(submissions t.submissions)
?: =(0 n) `sub
$(n (dec n), submissions t.submissions)
::
++ give-initial-discussions
|= [p=@ud =path =url]
^- (list card)
:_ ?: =(0 p) ~
[%give %kick ~ ~]~
=; =json
[%give %fact ~ %json !>(json)]
%+ frond:enjs:format 'link-update'
%+ frond:enjs:format 'initial-discussions'
%^ page-to-json p
%+ get-paginated `p
=- (~(got by (~(got by -) path)) url)
%+ scry-for (per-path-url comments)
[%discussions (build-discussion-path:store path url)]
comment:enjs:store
::
++ send-update
|= =update:store
^- card
?+ -.update ~|([dap.bowl %unexpected-update -.update] !!)
%submissions
%+ give-json
%+ frond:enjs:format 'link-update'
(update:enjs:store update)
:~ /json/0/submissions
(weld /json/0/submissions path.update)
==
::
%discussions
%+ give-json
%+ frond:enjs:format 'link-update'
(update:enjs:store update)
:_ ~
%+ weld /json/0/discussions
(build-discussion-path:store [path url]:update)
::
%observation
%+ give-json
%+ frond:enjs:format 'link-update'
(update:enjs:store update)
~[/json/seen]
==
::
++ give-json
|= [=json paths=(list path)]
^- card
[%give %fact paths %json !>(json)]
::
++ scry-for
|* [=mold =path]
.^ mold
%gx
(scot %p our.bowl)
%link-store
(scot %da now.bowl)
(snoc `^path`path %noun)
==
-- --

View File

@ -1,4 +1,6 @@
:: metadata-hook: allow syncing foreign metadata :: metadata-hook [landscape]:
::
:: allow syncing foreign metadata
:: ::
:: watch paths: :: watch paths:
:: /group/%group-path all updates related to this group :: /group/%group-path all updates related to this group

View File

@ -1,4 +1,6 @@
:: metadata-store: data store for application metadata and mappings :: metadata-store [landscape]:
::
:: data store for application metadata and mappings
:: between groups and resources within applications :: between groups and resources within applications
:: ::
:: group-paths are expected to be an existing group path :: group-paths are expected to be an existing group path
@ -8,7 +10,7 @@
:: encode group-path and app-path using (scot %t (spat group-path)) :: encode group-path and app-path using (scot %t (spat group-path))
:: ::
:: +watch paths: :: +watch paths:
:: /all assocations + updates :: /all associations + updates
:: /updates just updates :: /updates just updates
:: /app-name/%app-name specific app's associations + updates :: /app-name/%app-name specific app's associations + updates
:: ::
@ -25,162 +27,247 @@
/+ *metadata-json, default-agent, verb, dbug, resource /+ *metadata-json, default-agent, verb, dbug, resource
|% |%
+$ card card:agent:gall +$ card card:agent:gall
:: +$ base-state-0
:: $: associations=associations-0
+$ state-base
$: =associations
group-indices=(jug group-path md-resource) group-indices=(jug group-path md-resource)
app-indices=(jug app-name [group-path app-path]) app-indices=(jug app-name [group-path app-path])
resource-indices=(jug md-resource group-path) resource-indices=(jug md-resource group-path)
== ==
:: ::
+$ state-zero +$ associations-0 (map [group-path md-resource] metadata-0)
$: %0 ::
state-base +$ metadata-0
$: title=@t
description=@t
color=@ux
date-created=@da
creator=@p
== ==
:: ::
+$ state-one +$ base-state-1
$: %1 $: associations=associations
state-base group-indices=(jug group-path md-resource)
== app-indices=(jug app-name [group-path app-path])
:: resource-indices=(jug md-resource group-path)
+$ state-two
$: %2
state-base
== ==
:: ::
+$ state-0 [%0 base-state-0]
+$ state-1 [%1 base-state-0]
+$ state-2 [%2 base-state-0]
+$ state-3 [%3 base-state-1]
+$ state-4 [%4 base-state-1]
+$ state-5 [%5 base-state-1]
+$ state-6 [%6 base-state-1]
+$ versioned-state +$ versioned-state
$% state-zero $% state-0
state-one state-1
state-two state-2
state-3
state-4
state-5
state-6
== ==
-- --
:: ::
=| state-two =| state-6
=* state - =* state -
%+ verb | %+ verb |
%- agent:dbug %- agent:dbug
^- agent:gall ^- agent:gall
=< =<
|_ =bowl:gall |_ =bowl:gall
+* this . +* this .
metadata-core +> mc ~(. +> bowl)
mc ~(. metadata-core bowl) def ~(. (default-agent this %|) bowl)
def ~(. (default-agent this %|) bowl)
:: ::
++ on-init on-init:def ++ on-init on-init:def
++ on-save !>(state) ++ on-save !>(state)
++ on-load ++ on-load
|= =vase |= =vase
^- (quip card _this) ^- (quip card _this)
=/ old =/ old !<(versioned-state vase)
!<(versioned-state vase)
=| cards=(list card) =| cards=(list card)
|-
|^ |^
?: ?=(%2 -.old) ?: ?=(%6 -.old)
[cards this(state old)] [cards this(state old)]
?: ?=(%5 -.old)
=/ =^associations
(migrate-app-to-graph-store %publish associations.old)
%_ $
-.old %6
associations.old associations
::
resource-indices.old
(rebuild-resource-indices associations)
::
app-indices.old
(rebuild-app-indices associations)
::
group-indices.old
(rebuild-group-indices associations)
==
?: ?=(%4 -.old)
%_ $
-.old %5
::
resource-indices.old
(rebuild-resource-indices associations.old)
::
app-indices.old
(rebuild-app-indices associations.old)
::
group-indices.old
(rebuild-group-indices associations.old)
==
?: ?=(%3 -.old)
$(old [%4 +.old])
?: ?=(%2 -.old)
=/ new-state=state-3
%* . *state-3
associations
%- malt
%+ murn ~(tap by associations.old)
|= [[=group-path =md-resource] m=metadata-0]
^- (unit [[^group-path ^md-resource] metadata])
?: =(app-name.md-resource %link) ~
`[[group-path md-resource] (old-md-to-new m)]
==
$(old new-state)
?: ?=(%1 -.old) ?: ?=(%1 -.old)
%_ $ %_ $
old [%2 +.old] old [%2 +.old]
:: ::
cards cards
%+ murn %+ murn ~(tap in ~(key by group-indices.old))
~(tap in ~(key by group-indices.old))
|= =group-path |= =group-path
^- (unit card) ^- (unit card)
=/ rid=(unit resource) =/ rid (de-path-soft:resource group-path)
(de-path-soft:resource group-path)
?~ rid ~ ?~ rid ~
?: =(our.bowl entity.u.rid) ?: =(our.bowl entity.u.rid)
`(poke-md-hook %add-owned group-path) `(poke-md-hook %add-owned group-path)
`(poke-md-hook %add-synced entity.u.rid group-path) `(poke-md-hook %add-synced entity.u.rid group-path)
== ==
=/ new-state=state-one =/ new-state-1=state-1
%* . *state-one %* . *state-1
associations (migrate-associations associations.old) associations (migrate-associations associations.old)
group-indices (migrate-group-indices group-indices.old) group-indices (migrate-group-indices group-indices.old)
app-indices (migrate-app-indices app-indices.old) app-indices (migrate-app-indices app-indices.old)
resource-indices (migrate-resource-indices resource-indices.old) resource-indices (migrate-resource-indices resource-indices.old)
== ==
$(old new-state) $(old new-state-1)
::
++ rebuild-resource-indices
|= =^associations
%- ~(gas ju *(jug md-resource group-path))
%+ turn ~(tap in ~(key by associations))
|= [g=group-path r=md-resource]
^- [md-resource group-path]
[r g]
::
++ rebuild-group-indices
|= =^associations
%- ~(gas ju *(jug group-path md-resource))
~(tap in ~(key by associations))
::
++ rebuild-app-indices
|= =^associations
%- ~(gas ju *(jug app-name [group-path app-path]))
%+ turn ~(tap in ~(key by associations))
|= [g=group-path r=md-resource]
^- [app-name [group-path app-path]]
[app-name.r [g app-path.r]]
::
++ migrate-app-to-graph-store
|= [app=@tas =^associations]
^+ associations
%- malt
%+ turn ~(tap by associations)
|= [[=group-path =md-resource] m=metadata]
^- [[^group-path ^md-resource] metadata]
?. =(app-name.md-resource app)
[[group-path md-resource] m]
=/ new-app-path=path
?. ?=([@ @ ~] app-path.md-resource)
app-path.md-resource
ship+app-path.md-resource
[[group-path [%graph new-app-path]] m(module app)]
:: ::
++ poke-md-hook ++ poke-md-hook
|= act=metadata-hook-action |= act=metadata-hook-action
^- card ^- card
=/ =cage =/ =cage metadata-hook-action+!>(act)
:_ !>(act)
%metadata-hook-action
[%pass / %agent [our.bowl %metadata-hook] %poke cage] [%pass / %agent [our.bowl %metadata-hook] %poke cage]
:: ::
++ new-group-path ++ new-group-path
|= =group-path |= =group-path
ship+(new-app-path group-path) ship+(new-app-path group-path)
::
++ new-app-path ++ new-app-path
|= =app-path |= =app-path
^- path ^- path
?> ?=(^ app-path) ?> ?=(^ app-path)
?: =('~' i.app-path) ?:(=('~' i.app-path) t.app-path app-path)
t.app-path ::
app-path ++ old-md-to-new
|= m=metadata-0
^- metadata
%* . *metadata
title title.m
description description.m
color color.m
date-created date-created.m
creator creator.m
module *term
==
:: ::
++ migrate-md-resource ++ migrate-md-resource
|= md-resource |= md-resource
^- md-resource ^- md-resource
?: =(%chat app-name) ?: =(%chat app-name) [%chat (new-app-path app-path)]
[%chat (new-app-path app-path)] ?: =(%contacts app-name) [%contacts ship+app-path]
?: =(%contacts app-name)
[%contacts ship+app-path]
[app-name app-path] [app-name app-path]
:: ::
++ migrate-resource-indices ++ migrate-resource-indices
|= resource-indices=(jug md-resource group-path) |= resource-indices=(jug md-resource group-path)
^- (jug md-resource group-path) ^- (jug md-resource group-path)
%- malt %- malt
%+ turn %+ turn ~(tap by resource-indices)
~(tap by resource-indices)
|= [=md-resource paths=(set group-path)] |= [=md-resource paths=(set group-path)]
:_ (~(run in paths) new-group-path) :- (migrate-md-resource md-resource)
(migrate-md-resource md-resource) (~(run in paths) new-group-path)
:: ::
++ migrate-app-indices ++ migrate-app-indices
|= app-indices=(jug app-name [group-path app-path]) |= app-indices=(jug app-name [group-path app-path])
%- malt %- malt
%+ turn %+ turn ~(tap by app-indices)
~(tap by app-indices)
|= [app=term indices=(set [=group-path =app-path])] |= [app=term indices=(set [=group-path =app-path])]
:- app :- app
%- ~(run in indices) %- ~(run in indices)
|= [=group-path =app-path] |= [=group-path =app-path]
:- (new-group-path group-path) :- (new-group-path group-path)
?: =(%chat app) ?: =(%chat app) (new-app-path app-path)
(new-app-path app-path) ?: =(%contacts app) ship+app-path
?: =(%contacts app)
ship+app-path
app-path app-path
:: ::
++ migrate-group-indices ++ migrate-group-indices
|= group-indices=(jug group-path md-resource) |= group-indices=(jug group-path md-resource)
%- malt %- malt
%+ turn %+ turn ~(tap by group-indices)
~(tap by group-indices)
|= [=group-path resources=(set md-resource)] |= [=group-path resources=(set md-resource)]
:- (new-group-path group-path) :- (new-group-path group-path)
%- sy %- sy
%+ turn %+ turn ~(tap in resources)
~(tap in resources)
migrate-md-resource migrate-md-resource
:: ::
++ migrate-associations ++ migrate-associations
|= =^associations |= associations=associations-0
%- malt %- malt
%+ turn %+ turn ~(tap by associations)
~(tap by associations) |= [[g=group-path r=md-resource] m=metadata-0]
|= [[=group-path =md-resource] =metadata] :_ m
:_ metadata [(new-group-path g) (migrate-md-resource r)]
:_ (migrate-md-resource md-resource)
(new-group-path group-path)
-- --
:: ::
++ on-poke ++ on-poke
@ -202,11 +289,12 @@
:- ~ :- ~
%+ roll ~(tap in res) %+ roll ~(tap in res)
|= [r=md-resource out=_state] |= [r=md-resource out=_state]
=. resource-indices.out (~(del by resource-indices.out) r) =: resource-indices.out (~(del by resource-indices.out) r)
=. app-indices.out associations.out (~(del by associations.out) group r)
app-indices.out
%- ~(del ju app-indices.out) %- ~(del ju app-indices.out)
[app-name.r group app-path.r] [app-name.r group app-path.r]
=. associations.out (~(del by associations.out) group r) ==
out out
== ==
[cards this] [cards this]
@ -218,8 +306,12 @@
|^ |^
=/ cards=(list card) =/ cards=(list card)
?+ path (on-watch:def path) ?+ path (on-watch:def path)
[%all ~] (give %metadata-update !>([%associations associations])) [%all ~]
[%updates ~] ~ (give %metadata-update !>([%associations associations]))
::
[%updates ~]
~
::
[%app-name @ ~] [%app-name @ ~]
=/ =app-name i.t.path =/ =app-name i.t.path
=/ app-indices (metadata-for-app:mc app-name) =/ app-indices (metadata-for-app:mc app-name)
@ -233,8 +325,6 @@
[%give %fact ~ cage]~ [%give %fact ~ cage]~
-- --
:: ::
++ on-leave on-leave:def
::
++ on-peek ++ on-peek
|= =path |= =path
^- (unit (unit cage)) ^- (unit (unit cage))
@ -252,16 +342,17 @@
``noun+!>((metadata-for-group:mc group-path)) ``noun+!>((metadata-for-group:mc group-path))
:: ::
[%x %metadata @ @ @ ~] [%x %metadata @ @ @ ~]
=/ =group-path (stab (slav %t i.t.t.path)) =/ =group-path (stab (slav %t i.t.t.path))
=/ =md-resource [`@tas`i.t.t.t.path (stab (slav %t i.t.t.t.t.path))] =/ =md-resource [`term`i.t.t.t.path (stab (slav %t i.t.t.t.t.path))]
``noun+!>((~(get by associations) [group-path md-resource])) ``noun+!>((~(get by associations) [group-path md-resource]))
:: ::
[%x %resource @ *] [%x %resource @ *]
=/ app=@tas i.t.t.path =/ app=term i.t.t.path
=/ app-path=^path t.t.t.path =/ app-path=^path t.t.t.path
``noun+!>((~(get by resource-indices) app app-path)) ``noun+!>((~(get by resource-indices) app app-path))
== ==
:: ::
++ on-leave on-leave:def
++ on-agent on-agent:def ++ on-agent on-agent:def
++ on-arvo on-arvo:def ++ on-arvo on-arvo:def
++ on-fail on-fail:def ++ on-fail on-fail:def
@ -273,20 +364,17 @@
^- (quip card _state) ^- (quip card _state)
?> (team:title our.bowl src.bowl) ?> (team:title our.bowl src.bowl)
?- -.act ?- -.act
%add %add (handle-add group-path.act resource.act metadata.act)
(handle-add group-path.act resource.act metadata.act) %remove (handle-remove group-path.act resource.act)
::
%remove
(handle-remove group-path.act resource.act)
== ==
:: ::
++ handle-add ++ handle-add
|= [=group-path =md-resource =metadata] |= [=group-path =md-resource =metadata]
^- (quip card _state) ^- (quip card _state)
:- %+ send-diff app-name.md-resource :- %+ send-diff app-name.md-resource
?. (~(has by resource-indices) md-resource) ?: (~(has by resource-indices) md-resource)
[%add group-path md-resource metadata] [%update-metadata group-path md-resource metadata]
[%update-metadata group-path md-resource metadata] [%add group-path md-resource metadata]
%= state %= state
associations associations
(~(put by associations) [group-path md-resource] metadata) (~(put by associations) [group-path md-resource] metadata)
@ -295,7 +383,9 @@
(~(put ju group-indices) group-path md-resource) (~(put ju group-indices) group-path md-resource)
:: ::
app-indices app-indices
(~(put ju app-indices) app-name.md-resource [group-path app-path.md-resource]) %+ ~(put ju app-indices)
app-name.md-resource
[group-path app-path.md-resource]
:: ::
resource-indices resource-indices
(~(put ju resource-indices) md-resource group-path) (~(put ju resource-indices) md-resource group-path)
@ -313,7 +403,9 @@
(~(del ju group-indices) group-path md-resource) (~(del ju group-indices) group-path md-resource)
:: ::
app-indices app-indices
(~(del ju app-indices) app-name.md-resource [group-path app-path.md-resource]) %+ ~(del ju app-indices)
app-name.md-resource
[group-path app-path.md-resource]
:: ::
resource-indices resource-indices
(~(del ju resource-indices) md-resource group-path) (~(del ju resource-indices) md-resource group-path)

View File

@ -0,0 +1,222 @@
:: observe-hook:
::
:: helper that observes an app at a particular path and forwards all facts
:: to a particular thread. kills the subscription if the thread crashes
::
/- sur=observe-hook
/+ default-agent, dbug
::
|%
+$ card card:agent:gall
+$ versioned-state
$% state-0
==
::
+$ serial @uv
+$ state-0 [%0 observers=(map serial observer:sur)]
++ got-by-val
|= [a=(map serial observer:sur) b=observer:sur]
^- serial
%- need
%+ roll ~(tap by a)
|= [[key=serial val=observer:sur] output=(unit serial)]
?:(=(val b) `key output)
--
::
%- agent:dbug
=| state-0
=* state -
::
^- agent:gall
|_ =bowl:gall
+* this .
def ~(. (default-agent this %|) bowl)
::
++ on-init
|^ ^- (quip card _this)
:_ this
:_ ~
(act /inv-gra [%watch %invite-store /invitatory/graph %invite-accepted-graph])
::
++ act
|= [=wire =action:sur]
^- card
:* %pass
wire
%agent
[our.bowl %observe-hook]
%poke
%observe-action
!> ^- action:sur
action
==
--
::
++ on-save !>(state)
++ on-load
|= old-vase=vase
^- (quip card _this)
`this(state !<(state-0 old-vase))
::
++ on-poke
|= [=mark =vase]
^- (quip card _this)
?> (team:title our.bowl src.bowl)
?. ?=(%observe-action mark)
(on-poke:def mark vase)
=/ =action:sur !<(action:sur vase)
=* observer observer.action
=/ vals (silt ~(val by observers))
?- -.action
%watch
?: ?|(=(app.observer %spider) =(app.observer %observe-hook))
~|('we avoid infinite loops' !!)
?: (~(has in vals) observer)
~|('duplicate observer' !!)
:_ this(observers (~(put by observers) (sham eny.bowl) observer))
:_ ~
:* %pass
/observer/(scot %uv (sham eny.bowl))
%agent
[our.bowl app.observer]
%watch
path.observer
==
::
%ignore
?. (~(has in vals) observer)
~|('cannot remove nonexistent observer' !!)
=/ key (got-by-val observers observer)
:_ this(observers (~(del by observers) key))
:_ ~
:* %pass
/observer/(scot %uv key)
%agent
[our.bowl app.observer]
%leave
~
==
==
::
++ on-agent
|= [=wire =sign:agent:gall]
^- (quip card _this)
|^
?+ wire (on-agent:def wire sign)
[%observer @ ~] on-observer
[%thread-result @ ~] on-thread-result
[%thread-start @ @ ~] on-thread-start
==
::
++ on-observer
?> ?=([%observer @ ~] wire)
?+ -.sign (on-agent:def wire sign)
%watch-ack
?~ p.sign [~ this]
=/ =serial (slav %uv i.t.wire)
~& watch-ack-deleting-observer+(~(got by observers) serial)
[~ this(observers (~(del by observers) serial))]
::
%kick
=/ =serial (slav %uv i.t.wire)
=/ =observer:sur (~(got by observers) serial)
:_ this
:_ ~
:* %pass
wire
%agent
[our.bowl app.observer]
%watch
path.observer
==
::
%fact
=/ =serial (slav %uv i.t.wire)
=/ =observer:sur (~(got by observers) serial)
=/ tid (scot %uv (sham eny.bowl))
:_ this
:~ :* %pass
[%thread-result i.t.wire ~]
%agent
[our.bowl %spider]
%watch
[%thread-result tid ~]
==
:* %pass
[%thread-start i.t.wire tid ~]
%agent
[our.bowl %spider]
%poke
%spider-start
!>([~ `tid thread.observer (slop q.cage.sign !>(~))])
== ==
==
::
++ on-thread-result
?> ?=([%thread-result @ ~] wire)
?+ -.sign (on-agent:def wire sign)
%kick [~ this]
%watch-ack [~ this]
::
%fact
?. =(p.cage.sign %thread-fail)
:_ this
:_ ~
:* %pass
wire
%agent
[our.bowl %spider]
%leave
~
==
=/ =serial (slav %uv i.t.wire)
=/ =observer:sur (~(got by observers) serial)
~& observer-failed+observer
:_ this(observers (~(del by observers) serial))
:~ :* %pass
[%observer i.t.wire ~]
%agent
[our.bowl app.observer]
%leave
~
==
:* %pass
wire
%agent
[our.bowl %spider]
%leave
~
==
==
==
::
++ on-thread-start
?> ?=([%thread-start @ @ ~] wire)
?. ?=(%poke-ack -.sign) (on-agent:def wire sign)
?~ p.sign [~ this]
=/ =serial (slav %uv i.t.wire)
=/ =observer:sur (~(got by observers) serial)
~& added-invalid-observer+observer
:_ this(observers (~(del by observers) serial))
:~ :* %pass
[%observer i.t.wire ~]
%agent
[our.bowl app.observer]
%leave
~
==
:* %pass
wire
%agent
[our.bowl app.observer]
%leave
~
== ==
--
::
++ on-watch on-watch:def
++ on-leave on-leave:def
++ on-peek on-peek:def
++ on-arvo on-arvo:def
++ on-fail on-fail:def
--

View File

@ -1,45 +1,22 @@
:: permission-group-hook: groups into permissions :: permission-group-hook [landscape]: deprecated
:: ::
:: mirror the ships in specified groups to specified permission paths /+ default-agent
:: ::
/- *group-store, *permission-group-hook =| [%1 ~]
/+ *permission-json, default-agent, verb, dbug
::
|%
+$ state
$% [%0 state-0]
==
::
+$ group-path path
::
+$ permission-path path
::
+$ state-0
$: relation=(map group-path (set permission-path))
==
::
+$ card card:agent:gall
--
::
=| state-0
=* state - =* state -
:: ::
%+ verb |
%- agent:dbug
^- agent:gall ^- agent:gall
|_ =bowl:gall |_ =bowl:gall
+* this . +* this .
do ~(. +> bowl)
def ~(. (default-agent this %|) bowl) def ~(. (default-agent this %|) bowl)
:: ::
++ on-init on-init:def ++ on-init on-init:def
++ on-save !>(state) ++ on-save !>(state)
++ on-load ++ on-load
|= old=vase |= old=vase
^- (quip card _this) [~ this]
[~ this(state !<(state-0 old))]
:: ::
++ on-poke on-poke:def ++ on-poke on-poke:def
++ on-agent on-agent:def ++ on-agent on-agent:def
++ on-peek on-peek:def ++ on-peek on-peek:def
++ on-watch on-watch:def ++ on-watch on-watch:def

View File

@ -1,347 +1,26 @@
:: permission-hook: mirror remote permissions :: permission-hook [landscape]: deprecated
:: ::
:: allows mirroring permissions between local and foreign ships. /+ default-agent
:: local permission path are exposed according to the permssion paths
:: configured for them as `access-control`.
:: ::
/- *permission-hook =| [%1 ~]
/+ *permission-json, default-agent, verb, dbug
::
~% %permission-hook-top ..is ~
|%
+$ state
$% [%0 state-0]
==
::
+$ owner-access [ship=ship access-control=path]
::
+$ state-0
$: synced=(map path owner-access)
access-control=(map path (set path))
boned=(map wire (list bone))
==
::
+$ card card:agent:gall
--
::
=| state-0
=* state - =* state -
:: ::
%- agent:dbug
%+ verb |
^- agent:gall ^- agent:gall
=<
|_ =bowl:gall
+* this .
do ~(. +> bowl)
def ~(. (default-agent this %|) bowl)
::
++ on-init on-init:def
++ on-save !>(state)
++ on-load
|= old=vase
^- (quip card _this)
[~ this(state !<(state-0 old))]
::
++ on-poke
|= [=mark =vase]
^- (quip card _this)
?+ mark (on-poke:def mark vase)
%permission-hook-action
=^ cards state
(handle-permission-hook-action:do !<(permission-hook-action vase))
[cards this]
==
::
++ on-watch
|= =path
^- (quip card _this)
?. ?=([%permission ^] path) (on-watch:def path)
=^ cards state
(handle-watch-permission:do t.path)
[cards this]
::
++ on-agent
|= [=wire =sign:agent:gall]
^- (quip card _this)
?- -.sign
%poke-ack (on-agent:def wire sign)
::
%fact
?. ?=(%permission-update p.cage.sign)
(on-agent:def wire sign)
=^ cards state
(handle-permission-update:do wire !<(permission-update q.cage.sign))
[cards this]
::
%watch-ack
?~ p.sign [~ this]
?> ?=(^ wire)
:_ this(synced (~(del by synced) t.wire))
::NOTE we could've gotten rejected for permission reasons, so we don't
:: try to resubscribe automatically.
%. ~
%- slog
:* leaf+"permission-hook failed subscribe on {(spud t.wire)}"
leaf+"stack trace:"
u.p.sign
==
::
%kick
?> ?=([* ^] wire)
:: if we're not actively using it, we can safely ignore the %kick.
::
?. (~(has by synced) t.wire)
[~ this]
:: otherwise, resubscribe.
::
=/ =owner-access (~(got by synced) t.wire)
:_ this
[%pass wire %agent [ship.owner-access %permission-hook] %watch wire]~
==
::
++ on-leave on-leave:def
++ on-peek on-peek:def
++ on-arvo on-arvo:def
++ on-fail on-fail:def
--
::
|_ =bowl:gall |_ =bowl:gall
++ handle-permission-hook-action +* this .
|= act=permission-hook-action def ~(. (default-agent this %|) bowl)
^- (quip card _state)
?- -.act
%add-owned
?> (team:title our.bowl src.bowl)
?: (~(has by synced) owned.act)
[~ state]
=. synced (~(put by synced) owned.act [our.bowl access.act])
=. access-control
(~(put ju access-control) access.act owned.act)
=/ perm-path [%permission owned.act]
:_ state
[%pass perm-path %agent [our.bowl %permission-store] %watch perm-path]~
::
%add-synced
?> (team:title our.bowl src.bowl)
?: (~(has by synced) path.act)
[~ state]
=. synced (~(put by synced) path.act [ship.act ~])
=/ perm-path [%permission path.act]
:_ state
[%pass perm-path %agent [ship.act %permission-hook] %watch perm-path]~
::
%remove
=/ owner-access=(unit owner-access)
(~(get by synced) path.act)
?~ owner-access
[~ state]
:: if we own it, and it's us asking,
::
?: ?& =(ship.u.owner-access our.bowl)
(team:title our.bowl src.bowl)
==
:: delete the permission path and its subscriptions from this hook.
::
:- :- [%give %kick [%permission path.act]~ ~]
(leave-permission path.act)
%_ state
synced (~(del by synced) path.act)
::
access-control
(~(del by access-control) access-control.u.owner-access)
==
:: else, if either source = ship or source = us,
::
?: |(=(ship.u.owner-access src.bowl) (team:title our.bowl src.bowl))
:: delete a foreign ship's path.
::
:- (leave-permission path.act)
%_ state
synced (~(del by synced) path.act)
boned (~(del by boned) [%permission path.act])
==
:: else, ignore action entirely.
::
[~ state]
==
:: ::
++ handle-watch-permission ++ on-init on-init:def
|= =path ++ on-save !>(state)
^- (quip card _state) ++ on-load
=/ =owner-access (~(got by synced) path) |= old=vase
?> =(our.bowl ship.owner-access) [~ this]
:: scry permissions to check if subscriber is allowed ++ on-poke on-poke:def
:: ++ on-watch on-watch:def
?> (permitted src.bowl access-control.owner-access) ++ on-agent on-agent:def
=/ pem (permission-scry path) ++ on-leave on-leave:def
:_ state ++ on-peek on-peek:def
[%give %fact ~ %permission-update !>([%create path pem])]~ ++ on-arvo on-arvo:def
:: ++ on-fail on-fail:def
++ handle-permission-update
|= [=wire diff=permission-update]
^- (quip card _state)
?: (team:title our.bowl src.bowl)
(handle-local diff)
(handle-foreign diff)
::
++ handle-local
|= diff=permission-update
^- (quip card _state)
?- -.diff
%initial [~ state]
%create [~ state]
%add (change-local-permission %add [path who]:diff)
%remove (change-local-permission %remove [path who]:diff)
::
%delete
?. (~(has by synced) path.diff)
[~ state]
=/ control=(unit path)
=+ (~(got by synced) path.diff)
?. =(our.bowl ship) ~
`access-control
:_ %_ state
synced (~(del by synced) path.diff)
access-control ?~ control access-control
(~(del ju access-control) u.control path.diff)
==
:_ ~
:* %pass
[%permission path.diff]
%agent
[our.bowl %permission-store]
[%leave ~]
==
==
::
++ change-local-permission
|= [kind=?(%add %remove) pax=path who=(set ship)]
^- (quip card _state)
:_ state
:- ?- kind
%add (update-subscribers [%permission pax] [%add pax who])
%remove (update-subscribers [%permission pax] [%remove pax who])
==
=/ access-paths=(unit (set path)) (~(get by access-control) pax)
:: check if this path changes the access permissions for other paths
?~ access-paths ~
(quit-subscriptions kind pax who u.access-paths)
::
++ handle-foreign
|= diff=permission-update
^- (quip card _state)
?- -.diff
%initial [~ state]
?(%create %add %remove)
(change-foreign-permission path.diff diff)
::
%delete
?> ?=([* ^] path.diff)
=/ owner-access=(unit owner-access)
(~(get by synced) path.diff)
?~ owner-access
[~ state]
?. =(ship.u.owner-access src.bowl)
[~ state]
:_ state(synced (~(del by synced) path.diff))
:~ (permission-poke diff)
::
:* %pass
[%permission path.diff]
%agent
[src.bowl %permission-hook]
[%leave ~]
==
==
==
::
++ change-foreign-permission
|= [=path diff=permission-update]
^- (quip card _state)
?> ?=([* ^] path)
=/ owner-access=(unit owner-access)
(~(get by synced) path)
:_ state
?~ owner-access ~
?. =(src.bowl ship.u.owner-access) ~
[(permission-poke diff)]~
::
++ quit-subscriptions
|= $: kind=?(%add %remove)
perm-path=path
who=(set ship)
access-paths=(set path)
==
^- (list card)
=/ perm (permission-scry perm-path)
:: if the change resolves to "allow",
::
?. ?| ?&(=(%black kind.perm) =(%add kind))
?&(=(%white kind.perm) =(%remove kind))
==
:: do nothing.
~
:: else, it resolves to "deny"/"ban".
:: kick subscriptions for all ships, at all affected paths.
::
%- zing
%+ turn ~(tap in who)
|= check-ship=ship
^- (list card)
%+ turn ~(tap in access-paths)
|= access-path=path
[%give %kick [%permission access-path]~ `check-ship]
::
++ permission-scry
|= pax=path
^- permission
=. pax
;: weld
/(scot %p our.bowl)/permission-store/(scot %da now.bowl)/permission
pax
/noun
==
(need .^((unit permission) %gx pax))
::
++ permitted
|= [who=ship =path]
.^ ?
%gx
(scot %p our.bowl)
%permission-store
(scot %da now.bowl)
%permitted
(scot %p src.bowl)
(snoc path %noun)
==
::
++ permission-poke
|= act=permission-action
^- card
:* %pass
/permission-action
%agent
[our.bowl %permission-store]
%poke
%permission-action
!>(act)
==
::
++ update-subscribers
|= [=path upd=permission-update]
^- card
[%give %fact ~[path] %permission-update !>(upd)]
::
++ leave-permission
|= =path
^- (list card)
=/ owner-access=(unit owner-access)
(~(get by synced) path)
?~ owner-access ~
:_ ~
=/ perm-path [%permission path]
?: =(ship.u.owner-access our.bowl)
[%pass perm-path %agent [our.bowl %permission-store] %leave ~]
[%pass perm-path %agent [ship.u.owner-access %permission-hook] %leave ~]
-- --

View File

@ -1,201 +1,36 @@
:: permission-store: track black- and whitelists of ships :: permission-store [landscape]: deprecated
::
/- *permission-store
/+ default-agent, verb, dbug
:: ::
/+ default-agent
|% |%
+$ card card:agent:gall +$ card card:agent:gall
::
+$ versioned-state +$ versioned-state
$% state-zero $% state-0
state-1
== ==
:: ::
+$ state-zero +$ state-0 [%0 *]
$: %0 +$ state-1 [%1 ~]
permissions=permission-map
==
-- --
=| state-zero ::
=| state-1
=* state - =* state -
:: ::
%- agent:dbug
%+ verb |
^- agent:gall ^- agent:gall
=< |_ =bowl:gall
|_ =bowl:gall +* this .
+* this . def ~(. (default-agent this %|) bowl)
permission-core +>
pc ~(. permission-core bowl)
def ~(. (default-agent this %|) bowl)
::
++ on-init on-init:def
++ on-save !>(state)
++ on-load
|= old=vase
`this(state !<(state-zero old))
::
++ on-poke
|= [=mark =vase]
^- (quip card _this)
?> (team:title our.bowl src.bowl)
=^ cards state
?: ?=(%permission-action mark)
(poke-permission-action:pc !<(permission-action vase))
(on-poke:def mark vase)
[cards this]
::
++ on-watch
|= =path
^- (quip card _this)
?> (team:title our.bowl src.bowl)
|^
=/ cards=(list card)
?+ path (on-watch:def path)
[%all ~] (give %permission-update !>([%initial permissions]))
[%updates ~] ~
[%permission @ *]
=/ =vase !>([%create t.path (~(got by permissions) t.path)])
(give %permission-update vase)
==
[cards this]
::
++ give
|= =cage
^- (list card)
[%give %fact ~ cage]~
--
::
++ on-leave on-leave:def
++ on-peek
|= =path
^- (unit (unit cage))
?+ path (on-peek:def path)
[%x %keys ~] ``noun+!>(~(key by permissions))
[%x %permission *]
?~ t.t.path ~
``noun+!>((~(get by permissions) t.t.path))
::
[%x %permitted @ *]
?~ t.t.t.path ~
=/ pem (~(get by permissions) t.t.t.path)
?~ pem ~
=/ who (slav %p i.t.t.path)
=/ has (~(has in who.u.pem) who)
``noun+!>(?-(kind.u.pem %black !has, %white has))
==
++ on-agent on-agent:def
++ on-arvo on-arvo:def
++ on-fail on-fail:def
--
:: ::
|_ bol=bowl:gall ++ on-init on-init:def
++ on-save !>(state)
++ on-load
|= old=vase
[~ this]
:: ::
++ poke-permission-action ++ on-poke on-poke:def
|= action=permission-action ++ on-peek on-peek:def
^- (quip card _state) ++ on-watch on-watch:def
?> (team:title our.bol src.bol) ++ on-leave on-leave:def
?- -.action ++ on-agent on-agent:def
%initial [~ state] ++ on-arvo on-arvo:def
%add (handle-add action) ++ on-fail on-fail:def
%remove (handle-remove action)
%create (handle-create action)
%delete (handle-delete action)
%allow (handle-allow action)
%deny (handle-deny action)
==
::
++ handle-add
|= act=permission-action
^- (quip card _state)
?> ?=(%add -.act)
?~ path.act
[~ state]
:: TODO: calculate diff
:: =+ new=(~(dif in who.what.action) who.u.pem)
:: ?~(new ~ `what.action(who new))
?. (~(has by permissions) path.act)
[~ state]
:- (send-diff path.act act)
=/ perm (~(got by permissions) path.act)
=. who.perm (~(uni in who.perm) who.act)
state(permissions (~(put by permissions) path.act perm))
::
++ handle-remove
|= act=permission-action
^- (quip card _state)
?> ?=(%remove -.act)
?~ path.act
[~ state]
?. (~(has by permissions) path.act)
[~ state]
=/ perm (~(got by permissions) path.act)
=. who.perm (~(dif in who.perm) who.act)
:: TODO: calculate diff
:: =+ new=(~(int in who.what.action) who.u.pem)
:: ?~(new ~ `what.action(who new))
:- (send-diff path.act act)
state(permissions (~(put by permissions) path.act perm))
::
++ handle-create
|= act=permission-action
^- (quip card _state)
?> ?=(%create -.act)
?~ path.act
[~ state]
?: (~(has by permissions) path.act)
[~ state]
:: TODO: calculate diff
:- (send-diff path.act act)
state(permissions (~(put by permissions) path.act permission.act))
::
++ handle-delete
|= act=permission-action
^- (quip card _state)
?> ?=(%delete -.act)
?~ path.act
[~ state]
?. (~(has by permissions) path.act)
[~ state]
:- (send-diff path.act act)
state(permissions (~(del by permissions) path.act))
::
++ handle-allow
|= act=permission-action
^- (quip card _state)
?> ?=(%allow -.act)
?~ path.act
[~ state]
=/ perm (~(get by permissions) path.act)
?~ perm
[~ state]
?: =(kind.u.perm %white)
(handle-add [%add +.act])
(handle-remove [%remove +.act])
::
++ handle-deny
|= act=permission-action
^- (quip card _state)
?> ?=(%deny -.act)
?~ path.act
[~ state]
=/ perm (~(get by permissions) path.act)
?~ perm
[~ state]
?: =(kind.u.perm %black)
(handle-add [%add +.act])
(handle-remove [%remove +.act])
::
++ update-subscribers
|= [pax=path upd=permission-update]
^- (list card)
[%give %fact ~[pax] %permission-update !>(upd)]~
::
++ send-diff
|= [pax=path upd=permission-update]
^- (list card)
%- zing
:~ (update-subscribers /all upd)
(update-subscribers /updates upd)
(update-subscribers [%permission pax] upd)
==
-- --

View File

@ -1,4 +1,6 @@
:: pool-group-hook: maintain groups based on invite pool :: pool-group-hook [landscape]:
::
:: maintain groups based on invite pool
:: ::
:: looks at our invite tree, adds our siblings to group at +group-path :: looks at our invite tree, adds our siblings to group at +group-path
:: ::

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,7 @@
:: s3-store [landscape]:
::
:: stores s3 keys for uploading and sharing images and objects
::
/- *s3 /- *s3
/+ s3-json, default-agent, verb, dbug /+ s3-json, default-agent, verb, dbug
~% %s3-top ..is ~ ~% %s3-top ..is ~

View File

@ -6,7 +6,11 @@
/+ shoe, verb, dbug, default-agent /+ shoe, verb, dbug, default-agent
|% |%
+$ state-0 [%0 ~] +$ state-0 [%0 ~]
+$ command ~ +$ command
$? %demo
%row
%table
==
:: ::
+$ card card:shoe +$ card card:shoe
-- --
@ -41,22 +45,46 @@
++ command-parser ++ command-parser
|= sole-id=@ta |= sole-id=@ta
^+ |~(nail *(like [? command])) ^+ |~(nail *(like [? command]))
(cold [& ~] (jest 'demo')) %+ stag &
(perk %demo %row %table ~)
:: ::
++ tab-list ++ tab-list
|= sole-id=@ta |= sole-id=@ta
^- (list [@t tank]) ^- (list [@t tank])
:~ ['demo' leaf+"run example command"] :~ ['demo' leaf+"run example command"]
['row' leaf+"print a row"]
['table' leaf+"display a table"]
== ==
:: ::
++ on-command ++ on-command
|= [sole-id=@ta =command] |= [sole-id=@ta =command]
^- (quip card _this) ^- (quip card _this)
=- [[%shoe ~ %sole -]~ this] =; [to=(list _sole-id) fec=shoe-effect:shoe]
=/ =tape "{(scow %p src.bowl)} ran the command" [[%shoe to fec]~ this]
?. =(src our):bowl ?- command
[%txt tape] %demo
[%klr [[`%br ~ `%g] [(crip tape)]~]~] :- ~
:- %sole
=/ =tape "{(scow %p src.bowl)} ran the command"
?. =(src our):bowl
[%txt tape]
[%klr [[`%br ~ `%g] [(crip tape)]~]~]
::
%row
:- [sole-id]~
:+ %row
~[8 27 35 5]
~[p+src.bowl da+now.bowl t+'plenty room here!' t+'less here!']
::
%table
:- [sole-id]~
:^ %table
~[t+'ship' t+'date' t+'long text' t+'tldr']
~[8 27 35 5]
:~ ~[p+src.bowl da+now.bowl t+'plenty room here!' t+'less here!']
~[p+~marzod t+'yesterday' t+'sometimes:\0anewlines' t+'newlines']
==
==
:: ::
++ can-connect ++ can-connect
|= sole-id=@ta |= sole-id=@ta

View File

@ -1,73 +1,4 @@
:: soto [tombstone]: former dojo relay for urbit's landscape interface
:: ::
:: Soto: A Dojo relay for Urbit's Landscape interface /+ default-agent
:: Relays sole-effects to subscribers and forwards sole-action pokes (default-agent *agent:gall %|)
::
/- sole
/+ *soto, default-agent
|%
+$ card card:agent:gall
::
+$ versioned-state
$@ state-null
state-zero
::
+$ state-null ~
::
+$ state-zero [%0 ~]
--
=| state-zero
=* state -
^- agent:gall
|_ bol=bowl:gall
+* this .
soto-core +>
sc ~(. soto-core bol)
def ~(. (default-agent this %|) bol)
::
++ on-init
:_ this
:_ ~
:* %pass /srv %agent [our.bol %file-server]
%poke %file-server-action
!>([%serve-dir /'~dojo' /app/landscape %.n %.y])
==
++ on-save !>(state)
::
++ on-load
|= old-vase=vase
=/ old
!<(versioned-state old-vase)
?^ old
[~ this(state old)]
:_ this(state [%0 ~])
:~ [%pass /bind/soto %arvo %e %disconnect [~ /'~dojo']]
:* %pass /srv %agent [our.bol %file-server]
%poke %file-server-action
!>([%serve-dir /'~dojo' /app/landscape %.n %.y])
==
==
::
++ on-poke on-poke:def
++ on-watch
|= pax=path
^- (quip card _this)
?+ pax (on-watch:def pax)
[%sototile ~]
:_ this
[%give %fact ~ %json !>(~)]~
==
::
++ on-agent on-agent:def
::
++ on-arvo
|= [wir=wire sin=sign-arvo]
^- (quip card _this)
?: ?=(%bound +<.sin)
[~ this]
(on-arvo:def wir sin)
::
++ on-fail on-fail:def
++ on-leave on-leave:def
++ on-peek on-peek:def
::
--

View File

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

View File

@ -1,8 +0,0 @@
:- ~[comments+&]
;>
# Static
You can put static files in here to serve them to the web. Actually, you can put static files anywhere in `/web` and see them in a browser.
Docs on static publishing with urbit are forthcoming — but feel free to drop markdown files in `/web` to try it out.

37
pkg/arvo/app/time.hoon Normal file
View File

@ -0,0 +1,37 @@
::
/+ default-agent, verb
::
|%
::
+$ card card:agent:gall
--
^- agent:gall
|_ =bowl:gall
+* this .
def ~(. (default-agent this %|) bowl)
::
++ on-init [~ this]
++ on-save !>(~)
++ on-load _on-init
++ on-poke
|= [=mark =vase]
?+ mark !!
%noun :_ this
[%pass /(scot %da now.bowl) %arvo %b %wait `@da`+(now.bowl)]~
==
::
++ on-watch on-watch:def
++ on-leave on-leave:def
++ on-peek on-peek:def
++ on-agent on-agent:def
++ on-arvo
|= [=wire sign=sign-arvo]
^- (quip card _this)
?+ wire !!
[@ ~]
?> ?=(%wake +<.sign)
~& [%took `@dr`(sub now.bowl (slav %da i.wire))]
[~ this]
==
++ on-fail on-fail:def
--

View File

@ -1,3 +1,7 @@
:: weather [landscape]:
::
:: holds latlong, gets weather data from API, passes it on to subscribers
::
/+ *server, default-agent, verb, dbug /+ *server, default-agent, verb, dbug
=, format =, format
:: ::

View File

@ -0,0 +1,6 @@
:: eyre: give cors configuration
::
:- %say
|= [[now=@da eny=@uvJ =beak] ~ ~]
:- %noun
.^(cors-registry:eyre %ex /(scot %p p.beak)//(scot %da now)/cors)

View File

@ -3,8 +3,8 @@
/+ *graph-store /+ *graph-store
:- %say :- %say
|= $: [now=@da eny=@uvJ =beak] |= $: [now=@da eny=@uvJ =beak]
[[=resource mark=(unit mark) ~] ~] [[=resource mark=(unit mark) overwrite=? ~] ~]
== ==
:- %graph-update :- %graph-update
^- update ^- update
[%0 now [%add-graph resource (gas:orm ~ ~) mark]] [%0 now [%add-graph resource (gas:orm ~ ~) mark overwrite]]

View File

@ -0,0 +1,14 @@
/+ graph-store
::
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
[[=ship graph=term ~] ~]
==
:- %graph-update
=/ our (scot %p p.bec)
=/ wen (scot %da now)
=/ who (scot %p ship)
::
.^ update:graph-store
/gx/[our]/graph-store/[wen]/archive/[who]/[graph]/graph-update
==

View File

@ -0,0 +1,9 @@
/+ graph-store
::
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
[[graph=term =path ~] ~]
==
:- %graph-update
=- ~& update=- -
.^(=update:graph-store %cx path)

View File

@ -23,7 +23,7 @@
:- ?- b :- ?- b
~ "/" :: XX !! maybe? ~ "/" :: XX !! maybe?
{$hood ^} "|{(path-heps t.b)}" {$hood ^} "|{(path-heps t.b)}"
^ "+{(path-heps b)}" :: XX deal with :hall|foo ^ "+{(path-heps b)}" :: XX deal with :graph-store|foo
== ==
=/ c (to-wain:format a) =/ c (to-wain:format a)
?~ c "~" ?~ c "~"

View File

@ -0,0 +1,30 @@
:: Helm: query or reset login code for web
::
:::: /hoon/code/hood/gen
::
/? 310
::
::::
::
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
[arg=?(~ [%reset ~]) ~]
==
=* our p.bec
:- %helm-code
?~ arg
=/ code=tape
%+ slag 1
%+ scow %p
.^(@p %j /(scot %p our)/code/(scot %da now)/(scot %p our))
=/ step=tape
%+ scow %ud
.^(@ud %j /(scot %p our)/step/(scot %da now)/(scot %p our))
%- %- slog
:~ [%leaf code]
[%leaf (weld "current step=" step)]
[%leaf "use |code %reset to invalidate this and generate a new code"]
==
~
?> =(%reset -.arg)
%reset

View File

@ -0,0 +1,5 @@
:: eyre: allow cors requests from origin
::
:- %say
|= [^ [=origin:eyre ~] ~]
[%helm-cors-approve origin]

View File

@ -0,0 +1,5 @@
:: eyre: disallow cors requests from origin
::
:- %say
|= [^ [=origin:eyre ~] ~]
[%helm-cors-reject origin]

View File

@ -0,0 +1,13 @@
:: Helm: unify memory
::
:::: /hoon/meld/hood/gen
::
/? 310
::
::::
::
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
[arg=~ ~]
==
[%helm-meld ~]

View File

@ -3,6 +3,7 @@
:::: /hoon/merge/hood/gen :::: /hoon/merge/hood/gen
:: ::
/? 310 /? 310
/* help-text %txt /gen/hood/merge/help/txt
=, clay =, clay
:: ::
|% |%
@ -14,12 +15,13 @@
:: ::
:- %say :- %say
|= $: {now/@da eny/@uvJ bek/beak} |= $: {now/@da eny/@uvJ bek/beak}
{arg/{?(sorc {syd/$@(desk beaky) sorc})} cas/case gem/?(germ $auto)} {arg/{?(~ sorc {syd/$@(desk beaky) sorc})} cas/case gem/?(germ $auto)}
== ==
=* our p.bek =* our p.bek
|^ :- %kiln-merge |^ :- %kiln-merge
^- {syd/desk her/ship sud/desk cas/case gem/?(germ $auto)} ^- $@(~ {syd/desk her/ship sud/desk cas/case gem/?(germ $auto)})
?- arg ?- arg
~ ((slog (turn help-text |=(=@t leaf+(trip t)))) ~)
{@ @ ~} {@ @ ~}
=+(arg [sud ?.(=(our her) her (sein:title p.bek now her)) sud (opt-case da+now) gem]) =+(arg [sud ?.(=(our her) her (sein:title p.bek now her)) sud (opt-case da+now) gem])
:: ::

View File

@ -0,0 +1,110 @@
Usage:
|merge %destination-desk ~source-ship %source-desk
|merge %destination-desk ~source-ship %source-desk, =gem %strategy
|merge %destination-desk ~source-ship %source-desk, =cas ud+5
We support various merge strategies. A "commit" is a snapshot of
the files with a list of parents plus a date. Most commits have
one parent; a "merge" commit is a commit with two parents. The
%home desk starts with an initial commit with no parents; commits
with several parents ("octopus merges") are possible but we don't
generate them right now.
Unless otherwise specified, all of the following create a new commit
with the source and destination commits as parents.
Several strategies need a "merge-base". They find it by identifying
the most recent common ancestor of the two desks. If none, fail
with %merge-no-merge-base; if there are two or more, pick one.
%init: the only way to create a desk. Not a true merge, since it
simply assigns the source commit to the destination.
%fine: if source or destination are in the ancestry of each other,
use the newer one; else abort. If the destination is ahead of the
source, succeed but do nothing. If the source is ahead of the
destination, assign the next revision number to the source commit.
Some call this "fast-forward".
%meet: combine changes, failing if both sides changed the same file.
Specifically, take diff(merge-base,source) and
diff(merge-base,destination) and combine them as long as those diffs
touch different files.
%mate: combine changes, failing if both sides changed the same part
of a file. Identical to %meet, except that some marks, like %hoon,
allow intelligent merge of changes to different parts of a file.
%meld: combine changes; if both sides changed the same part of a
file, use the version of the file in the merge-base.
%only-this: create a merge commit with exactly the contents of the
destination desk.
%only-that: create a merge commit with exactly the contents of the
source commit.
%take-this: create a merge commit with exactly the contents of the
destination desk except take any files from the source commit which
are not in the destination desk.
%take-that: create a merge commit with exactly the contents of the
source commit except preserve any files from the destination desk
which are not in the source commit.
%meet-this: merge as in %meet, except if both sides changed the same
file, use the version in the destination desk.
%meet-that: merge as in %meet, except if both sides changed the same
file, use the version in the source commit.
# Examples and notes:
The most common merge strategy is %mate, which is a normal 3-way
merge which aborts on conflict.
%take-that is useful to "force" an OTA. After running %take-that,
you're guaranteed to have exactly the files in the source commit plus
any files you separately added.
We speak of merging into a destination *desk* from a source *commit*
because while you can only merge on top of a desk, you can merge from
historical commits. For example,
|merge %old our %home, =cas ud+5, =gem %init
will create a new desk called %old with the 5th commit in %home.
You can revert the contents of a desk to what they were yesterday
with
|merge %home our %home, =cas da+(sub now ~d1), =gem %only-that
Note this is a normal %only-that merge, which means you're creating a
*new* commit with the old *contents*.
%meld is rarely used on its own, however if you specify %auto or
omit the merge strategy, %kiln will run a %meld merge into a scratch
desk and then annotate the conflicts there.
If you resolve merge conflicts manually, for example by mounting the
desks, copying the files in unix and then running |commit, you
should usually run an %only-this merge. This will not change the
newly-fixed contents of your desk, but it will record that the merge
happened so that those conflicts don't reappear in later merges.
If you get a %merge-no-merge-base error, this means you're trying to
merge two desks which have no common ancestors. You need to give
them a common ancestor by choosing a merge strategy which doesn't
need a merge-base, like %only-this, %only-that, %take-this, or
%take-that.
%take-this could be useful to install 3rd party software, but you
couldn't get subsequent updates this way, since the files would
already exist in the destination desk. Something like "take only
the files which aren't in my OTA source or any other 3rd party app"
would be basically correct. This would require a parameter listing
the desks to not conflict with.
%meet-this and %meet-that imply the existence of %mate-this and
%mate-that, but those don't exist yet.

View File

@ -0,0 +1,13 @@
:: Helm: trim kernel state
::
:::: /hoon/trim/hood/gen
::
/? 310
::
::::
::
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
[arg=?(~ [pri=@ud ~]) ~]
==
[%helm-trim ?~(arg 1 pri.arg)]

View File

@ -0,0 +1,20 @@
:: :metadata-store|remove: remove resource from group
:: Usage:
:: :metadata-store|remove
:: <group-name> <app-name> <channel-path>
:: %urbit-community %chat /~darrux-landes/general-503
::
:: You can acquire the channel-path with
:: :metadata-store +dbug [%state '(~(got by group-indices) <group-path>)'
:: and looking for the entry with an app-path that is similar to the
:: title of the channel
::
/- *metadata-store
/+ resource
:- %say
|= $: [now=@da eny=@uvJ =beak]
[[group=term app=term =path ~] ~]
==
:- %metadata-action
^- metadata-action
[%remove (en-path:resource [p.beak group]) app path]

View File

@ -1,5 +1,15 @@
:: Print useful diagnostic information :: Print useful diagnostic information
:: ::
:: base-hash: loosely, the most recent successfully applied update.
:: Technically, the mergebase of %home with OTA source
:: sour-hash: most recently downloaded update (not necessarily applied)
:: home-hash: hash of %home desk, which may differ if you have changed
:: it, for example with notebooks or 3rd party apps
:: kids-hash: hash of the %kids desk, which is what you serve to your
:: children
:: glob-hash: hash of the glob, which is the js for landscape
::
/+ version
:- %say :- %say
|= [[now=time * bec=beak] ~ ~] |= [[now=time * bec=beak] ~ ~]
=* our p.bec =* our p.bec
@ -7,7 +17,8 @@
:- %noun :- %noun
=< =<
:~ :~
[%base-hash base-hash] [%base-hash (base-hash:version our now)]
[%sour-hash sour-hash]
[%home-hash .^(@uv %cz (pathify ~.home ~))] [%home-hash .^(@uv %cz (pathify ~.home ~))]
[%kids-hash .^(@uv %cz (pathify ~.kids ~))] [%kids-hash .^(@uv %cz (pathify ~.kids ~))]
[%glob-hash glob-state] [%glob-hash glob-state]
@ -43,7 +54,7 @@
rift=ryft rift=ryft
== ==
:: ::
++ base-hash ++ sour-hash
=+ .^ ota=(unit [=ship =desk =aeon:clay]) =+ .^ ota=(unit [=ship =desk =aeon:clay])
%gx /(scot %p our)/hood/(scot %da now)/kiln/ota/noun %gx /(scot %p our)/hood/(scot %da now)/kiln/ota/noun
== ==

View File

@ -3,6 +3,7 @@
:: pad: include padding when encoding, require when decoding :: pad: include padding when encoding, require when decoding
:: url: use url-safe characters '-' for '+' and '_' for '/' :: url: use url-safe characters '-' for '+' and '_' for '/'
:: ::
::
=+ [pad=& url=|] =+ [pad=& url=|]
|% |%
:: ::

View File

@ -81,11 +81,11 @@
++ derivation-path ++ derivation-path
;~ pfix ;~ pfix
;~(pose (jest 'm/') (easy ~)) ;~(pose (jest 'm/') (easy ~))
%+ most net %+ most fas
;~ pose ;~ pose
%+ cook %+ cook
|=(i=@ (add i (bex 31))) |=(i=@ (add i (bex 31)))
;~(sfix dem say) ;~(sfix dem soq)
:: ::
dem dem
== == == ==

View File

@ -41,9 +41,17 @@
:: ::
%state %state
=? grab.dbug =('' grab.dbug) '-' =? grab.dbug =('' grab.dbug) '-'
=- [(sell -)]~ =; product=^vase
[(sell product)]~
=/ state=^vase
:: if the underlying app has implemented a /dbug/state scry endpoint,
:: use that vase in place of +on-save's.
::
=/ result=(each ^vase tang)
(mule |.(q:(need (need (on-peek:ag /x/dbug/state)))))
?:(?=(%& -.result) p.result on-save:ag)
%+ slap %+ slap
(slop on-save:ag !>([bowl=bowl ..zuse])) (slop state !>([bowl=bowl ..zuse]))
(ream grab.dbug) (ream grab.dbug)
:: ::
%incoming %incoming

View File

@ -34,6 +34,79 @@
++ enjs ++ enjs
=, enjs:format =, enjs:format
|% |%
::
++ signatures
|= s=^signatures
^- json
[%a (turn ~(tap in s) signature)]
::
++ signature
|= s=^signature
^- json
%- pairs
:~ [%signature s+(scot %ux p.s)]
[%ship (ship q.s)]
[%life (numb r.s)]
==
::
++ index
|= i=^index
^- json
?: =(~ i) s+'/'
=/ j=^tape ""
|-
?~ i [%s (crip j)]
=/ k=json (numb i.i)
?> ?=(%n -.k)
%_ $
i t.i
j (weld j (weld "/" (trip +.k)))
==
::
++ uid
|= u=^uid
^- json
%- pairs
:~ [%resource (enjs:res resource.u)]
[%index (index index.u)]
==
::
++ content
|= c=^content
^- json
?- -.c
%mention (frond %mention (ship ship.c))
%text (frond %text s+text.c)
%url (frond %url s+url.c)
%reference (frond %reference (uid uid.c))
%code
%+ frond %code
%- pairs
:- [%expression s+expression.c]
:_ ~
:- %output
:: virtualize output rendering, +tank:enjs:format might crash
::
=/ result=(each (list json) tang)
(mule |.((turn output.c tank)))
?- -.result
%& a+p.result
%| a+[a+[%s '[[output rendering error]]']~]~
==
==
::
++ post
|= p=^post
^- json
%- pairs
:~ [%author (ship author.p)]
[%index (index index.p)]
[%time-sent (time time-sent.p)]
[%contents [%a (turn contents.p content)]]
[%hash ?~(hash.p ~ s+(scot %ux u.hash.p))]
[%signatures (signatures signatures.p)]
==
::
++ update ++ update
|= upd=^update |= upd=^update
^- json ^- json
@ -50,6 +123,7 @@
:~ [%resource (enjs:res resource.upd)] :~ [%resource (enjs:res resource.upd)]
[%graph (graph graph.upd)] [%graph (graph graph.upd)]
[%mark ?~(mark.upd ~ s+u.mark.upd)] [%mark ?~(mark.upd ~ s+u.mark.upd)]
[%overwrite b+overwrite.upd]
== ==
:: ::
%remove-graph %remove-graph
@ -132,20 +206,6 @@
:~ (index [a]~) :~ (index [a]~)
(node n) (node n)
== ==
::
++ index
|= i=^index
^- json
=/ j=^tape ""
|-
?~ i [%s (crip j)]
=/ k=json (numb i.i)
?> ?=(%n -.k)
%_ $
i t.i
j (weld j (weld "/" (trip +.k)))
==
::
++ node ++ node
|= n=^node |= n=^node
^- json ^- json
@ -158,41 +218,7 @@
== ==
== ==
:: ::
++ post ::
|= p=^post
^- json
%- pairs
:~ [%author (ship author.p)]
[%index (index index.p)]
[%time-sent (time time-sent.p)]
[%contents [%a (turn contents.p content)]]
[%hash ?~(hash.p ~ s+(scot %ux u.hash.p))]
[%signatures (signatures signatures.p)]
==
::
++ content
|= c=^content
^- json
?- -.c
%text (frond %text s+text.c)
%url (frond %url s+url.c)
%reference (frond %reference (uid uid.c))
%code
%+ frond %code
%- pairs
:- [%expression s+expression.c]
:_ ~
:- %output
:: virtualize output rendering, +tank:enjs:format might crash
::
=/ result=(each (list json) tang)
(mule |.((turn output.c tank)))
?- -.result
%& a+p.result
%| a+[a+[%s '[[output rendering error]]']~]~
==
==
::
++ nodes ++ nodes
|= m=(map ^index ^node) |= m=(map ^index ^node)
^- json ^- json
@ -210,27 +236,6 @@
^- json ^- json
[%a (turn ~(tap in i) index)] [%a (turn ~(tap in i) index)]
:: ::
++ uid
|= u=^uid
^- json
%- pairs
:~ [%resource (enjs:res resource.u)]
[%index (index index.u)]
==
::
++ signatures
|= s=^signatures
^- json
[%a (turn ~(tap in s) signature)]
::
++ signature
|= s=^signature
^- json
%- pairs
:~ [%signature s+(scot %ux p.s)]
[%ship (ship q.s)]
[%life (numb r.s)]
==
-- --
-- --
:: ::
@ -247,20 +252,24 @@
|% |%
++ decode ++ decode
%- of %- of
:~ [%add-graph add-graph] :~ [%add-nodes add-nodes]
[%remove-graph remove-graph]
[%add-nodes add-nodes]
[%remove-nodes remove-nodes] [%remove-nodes remove-nodes]
[%add-signatures add-signatures] [%add-signatures add-signatures]
[%remove-signatures remove-signatures] [%remove-signatures remove-signatures]
::
[%add-graph add-graph]
[%remove-graph remove-graph]
::
[%add-tag add-tag] [%add-tag add-tag]
[%remove-tag remove-tag] [%remove-tag remove-tag]
::
[%archive-graph archive-graph] [%archive-graph archive-graph]
[%unarchive-graph unarchive-graph] [%unarchive-graph unarchive-graph]
[%run-updates run-updates]
::
[%keys keys] [%keys keys]
[%tags tags] [%tags tags]
[%tag-queries tag-queries] [%tag-queries tag-queries]
[%run-updates run-updates]
== ==
:: ::
++ add-graph ++ add-graph
@ -268,6 +277,7 @@
:~ [%resource dejs:res] :~ [%resource dejs:res]
[%graph graph] [%graph graph]
[%mark (mu so)] [%mark (mu so)]
[%overwrite bo]
== ==
:: ::
++ graph ++ graph
@ -291,14 +301,19 @@
[%nodes nodes] [%nodes nodes]
== ==
:: ::
++ nodes (op ;~(pfix net (more net dem)) node) ++ nodes (op ;~(pfix fas (more fas dem)) node)
:: ::
++ node ++ node
%- ot %- ot
:~ [%post post] :~ [%post post]
:: TODO: support adding nodes with children by supporting the [%children internal-graph]
:: graph key ==
[%children (of [%empty ul]~)] ::
++ internal-graph
^- $-(json ^internal-graph)
%- of
:~ [%empty ul]
[%graph graph]
== ==
:: ::
++ post ++ post
@ -313,7 +328,8 @@
:: ::
++ content ++ content
%- of %- of
:~ [%text so] :~ [%mention (su ;~(pfix sig fed:ag))]
[%text so]
[%url so] [%url so]
[%reference uid] [%reference uid]
[%code eval] [%code eval]
@ -362,7 +378,7 @@
[%index index] [%index index]
== ==
:: ::
++ index (su ;~(pfix net (more net dem))) ++ index (su ;~(pfix fas (more fas dem)))
:: ::
++ add-tag ++ add-tag
%- ot %- ot

View File

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

View File

@ -13,12 +13,44 @@
:: ::
++ get-graph ++ get-graph
|= res=resource |= res=resource
^- marked-graph:store ^- update:store
%+ scry-for marked-graph:store %+ scry-for update:store
/graph/(scot %p entity.res)/[name.res] /graph/(scot %p entity.res)/[name.res]
:: ::
++ peek-log ++ got-node
|= [res=resource =index:store]
^- node:store
=+ %+ scry-for ,=update:store
%+ weld
/node/(scot %p entity.res)/[name.res]
(turn index (cury scot %ud))
?> ?=(%0 -.update)
?> ?=(%add-nodes -.q.update)
?> ?=(^ nodes.q.update)
q.n.nodes.q.update
::
++ get-update-log
|= rid=resource
^- update-log:store
%+ scry-for update-log:store
/update-log/(scot %p entity.rid)/[name.rid]
::
++ peek-update-log
|= res=resource |= res=resource
^- (unit time) ^- (unit time)
(scry-for (unit time) /peek-update-log/(scot %p entity.res)/[name.res]) (scry-for (unit time) /peek-update-log/(scot %p entity.res)/[name.res])
::
++ get-update-log-subset
|= [res=resource start=@da]
^- update-log:store
%+ scry-for update-log:store
/update-log-subset/(scot %p entity.res)/[name.res]/(scot %da start)/'~'
::
++ get-keys
^- resources
=+ %+ scry-for ,=update:store
/keys
?> ?=(%0 -.update)
?> ?=(%keys -.q.update)
resources.q.update
-- --

View File

@ -48,6 +48,13 @@
^- ? ^- ?
=- (~(has in -) ship) =- (~(has in -) ship)
(members-from-path group-path) (members-from-path group-path)
::
++ is-admin
|= [=ship =group-path]
^- ?
=/ tags tags:(fall (scry-group-path group-path) *group)
=/ admins=(set ^ship) (~(gut by tags) %admin ~)
(~(has in admins) ship)
:: +role-for-ship: get role for user :: +role-for-ship: get role for user
:: ::
:: Returns ~ if no such group exists or user is not :: Returns ~ if no such group exists or user is not
@ -77,6 +84,7 @@
?: (~(has in members.group) ship) ?: (~(has in members.group) ship)
[~ ~] [~ ~]
~ ~
::
++ can-join-from-path ++ can-join-from-path
|= [=path =ship] |= [=path =ship]
%+ scry-for %+ scry-for

View File

@ -0,0 +1,30 @@
/- sur=hark-chat-hook
^?
=< [. sur]
=, sur
|%
++ dejs
=, dejs:format
|%
++ action
%- of
:~ listen+pa
ignore+pa
set-mentions+bo
==
--
::
++ enjs
=, enjs:format
|%
++ update
|= upd=^update
%+ frond -.upd
?- -.upd
?(%listen %ignore) (path chat.upd)
%set-mentions b+mentions.upd
%initial a+(turn ~(tap in watching.upd) path)
==
--
--

View File

@ -0,0 +1,66 @@
/- sur=hark-graph-hook, post
/+ graph-store, resource
^?
=< [. sur]
=, sur
|%
++ dejs
=, dejs:format
|%
::
++ index
^- $-(json index:graph-store)
(su ;~(pfix net (more net dem)))
::
++ graph-index
%- ot
:~ graph+dejs-path:resource
index+index
==
::
++ action
%- of
:~ listen+graph-index
ignore+graph-index
set-mentions+bo
set-watch-on-self+bo
==
--
::
++ enjs
=, enjs:format
|%
::
++ graph-index
|= [graph=resource =index:post]
%- pairs
:~ graph+s+(enjs-path:resource graph)
index+(index:enjs:graph-store index)
==
::
++ action
|= act=^action
^- json
%+ frond -.act
?- -.act
%set-watch-on-self b+watch-on-self.act
%set-mentions b+mentions.act
?(%listen %ignore) (graph-index graph.act index.act)
==
::
::
::
++ update
|= upd=^update
^- json
?. ?=(%initial -.upd)
(action upd)
%+ frond -.upd
%- pairs
:~ 'watchOnSelf'^b+watch-on-self.upd
'mentions'^b+mentions.upd
:+ %watching %a
(turn ~(tap in watching.upd) graph-index)
==
--
--

View File

@ -0,0 +1,34 @@
/- sur=hark-group-hook
/+ resource
^?
=< [. sur]
=, sur
|%
++ dejs
=, dejs:format
|%
++ action
%- of
:~ listen+dejs-path:resource
ignore+dejs-path:resource
==
--
::
++ enjs
=, enjs:format
|%
++ res
(cork enjs-path:resource (lead %s))
::
++ update
|= upd=^update
%+ frond -.upd
?- -.upd
?(%listen %ignore) (res group.upd)
::
%initial
:- %a
(turn ~(tap in watching.upd) res)
==
--
--

Some files were not shown because too many files have changed in this diff Show More