-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
116 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
# %sink | ||
|
||
%sink is a state replication system between your %gall agent and your Elm airlock. | ||
|
||
%sink allows you to avoid having to manually write subscriptions which send semantic diffs between your %gall agent and the frontend. | ||
|
||
## How it works | ||
|
||
%sink consists of two parts: | ||
1. The %sink library you import into your %gall agent and call appropriate functions at the right points in your agent lifecycle. More on this in a bit. | ||
2. The `Ur.Sub.sink` urbit subscription which reconciles the state and hands you the latest version of %gall agent state that you can then `Deconstruct` into Elm data structures. | ||
|
||
The whole system works by saving the previous version your %gall agent state and diffing the raw nouns that compose your old state and your new state. | ||
On first initialization of the %sink system the whole state you supplied is sent to the frontend. Any subsequent changes are sent as a diff between your old state and your new state. | ||
|
||
## How to use it | ||
|
||
### The %gall agent part | ||
|
||
#### Copying library files | ||
|
||
In order to use %sink you have to copy the following two files into your agent desk into the `lib` directory: | ||
1. [example/urbit/lib/noun-diff.hoon](../example/urbit/lib/noun-diff.hoon) -- contains the algorithm for diffing raw nouns. | ||
2. [example/urbit/lib/sink.hoon](../example/urbit/lib/sink.hoon) -- contains the logic of syncing the state between your agent and your frontend. | ||
|
||
#### Adding sink points into your agent | ||
|
||
First you need to import the %sink library into your agent: | ||
|
||
```hoon | ||
/+ *sink | ||
``` | ||
|
||
Next you need to initialize the sink. Put the following declaration somewhere before your agent door: | ||
|
||
```hoon | ||
=/ snik | ||
:: | ||
:: replace /sync with whatever path you want to use for syncing your state. | ||
%+ sink ~[/sync] | ||
:: | ||
:: This part is a gate that extracts the state you want to sync from your agent state. | ||
:: This allows you to sync only the part of your state that you need, saving resources. | ||
:: If you want to sync the whole state then just pass identity: `|=(x=versioned-state x)` | ||
:: | ||
:: versioned-state should be replaced with whatever the type of your application state is. | ||
|=(stat=versioned-state !!) | ||
:: | ||
:: Next you initialize your sink with your initial agent state. | ||
=/ sink (snik state) | ||
``` | ||
|
||
You can have multiple sinks in the same application to sync different parts of your state on different paths. | ||
|
||
Don't forget to reinitialize your `sink` when your restore your agent state in the `++on-load` arm: | ||
|
||
```hoon | ||
++ on-load | ||
|= old-vase=vase | ||
^- (quip card _this) | ||
=/ state !<(versioned-state old-vase) | ||
:: | ||
:: the `sink (snik state)` is the important bit. | ||
`this(state state, sink (snik state)) | ||
``` | ||
|
||
Lastly, you need to send sink updates whenever you change your state. Most likely this will be in your `++on-poke` arm: | ||
|
||
```hoon | ||
:: | ||
:: This line generates a `card` that you need to pass to arvo and updates | ||
:: the `sink` to reference the latest state of your agent. | ||
=^ card sink (sync:sink state) | ||
``` | ||
|
||
You can look at the [journal.hoon](../example/urbit/app/journal.hoon) for a full example. | ||
|
||
#### Adding sink the the frontend | ||
|
||
For your frontend to recieve %sink updates you need to pass the result of calling `Ur.Sub.sink` to the `urbitSubscriptions` field of `Ur.Run.application` or similar function from `Ur.Run`: | ||
|
||
```elm | ||
main : Ur.Run.Program Model Msg | ||
main = | ||
Ur.Run.application | ||
{ | ||
-- ... | ||
urbitSubscriptions = | ||
Ur.Sub.sink | ||
{ ship = "~zod" | ||
, app = "journal" | ||
, path = [ "sync" ] | ||
, deconstructor = | ||
D.list (D.cell D.bigint D.cord |> D.map (\a b -> ( a, b ))) | ||
|> D.map GotListings | ||
} | ||
-- ... | ||
} | ||
``` | ||
|
||
In the `deconstructor` field you specify a `Deconstructor` the deconstructs _the whole_ state that is being synced form the %gall agent. | ||
|
||
You do not have to deal with diffs. It is handled automatically | ||
|
||
You can look at [example/src/Sink.elm](../exmaple/src/Sink.elm) for a full example. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters