on master help sign in
enough tree
commit8801080b4d1fac7389250fd1dde46eb60598136a authorGalen Wolfe-Pauly <mailroom@office-for.com> dateThu 25 Feb 2016, 23:09 (11 years ago) parent42fdcba
1 file changed+90−4
docs/walkthroughs/tree.md+90−4
docs/walkthroughs/tree.md+90−4
@@ -117,19 +117,105 @@ Optional properties:
117117- `match`: Tag name to match. If you wanted to only match `h2` tags it could be `match="h2"`
118118- `noHeader`: By default we add a 'Table of Contents' header to the top. Remove it with `noHeader="true"`.
119119
120−## Module basics
120+## Implementation
121121
122−A module is a
122+On the frontend Tree is mostly just a standard Flux app: components generate actions that get dispatched to stores which are picked up by components. If you're not familiar with Flux, [this overview](https://facebook.github.io/flux/docs/overview.html) is a good place to start.
123123
124−## Implementation
124+As a file browser Tree does a simple job: it fetches data and keeps a cache of what it has seen. To do this simple job we do three fancy things: `manx` to JSON encoding, the Async component and Modules.
125+
126+### `manx` to JSON format
127+
128+Since we want to use React to manage our DOM lifecycle we actually transfer the DOM structure of each page as JSON over the wire, and 'reactify' it on the client side.
129+
130+On the Urbit side we actually have a type for html: `++manx`. Our wire format for sending HTML as JSON is really similar to a `++manx`. If you're not interested here's what the json looks like:
131+
132+```
133+"string" || {gn:"string", ga:{key:"string", [...]}, c:[...]}
134+```
135+
136+To make this clearer let's look at some HTML and it's JSON representation:
137+
138+```
139+<div class="blue">
140+ <h1>Title</h1>
141+</div>
142+```
125143
144+```
145+{gn:"div", ga:{className:"blue"}, [
146+ {gn:"h1", ga:null, "Title"}
147+]}
148+```
126149
150+To see the mechanics of how this is handled on the frontend, checkout `components/Reactify.coffee` in the `urbit/tree` repo.
127151
128152### Async component
129153
130−### manx JSON format
154+Each of our components (even those we fetched from the server) can depend on data that may not exist in our stores we wrap our components in a general-purpose Async component. You can find the component in `components/Async.coffee` in the `urbit/tree` repo.
155+
156+When we say that we just fetch HTML as JSON it's actually slightly more complicated. When we fetch a node in the filesystem we might not want to fetch its entire contents. Sometimes we just get the title as a part of a list of children, sometimes we might get a snippet (in a list with previews), and sometimes we get the whole thing. On the Urbit side these results are provided by `ren/tree/json`.
157+
158+From the perspective of the frontend we just send queries on a path that obey a simple API. To see this in action, here's our `BodyComponent`:
159+
160+```
161+query {
162+ body:'r'
163+ name:'t'
164+ path:'t'
165+ meta:'j'
166+ sein:'t'
167+}
168+```
169+
170+Here we're asking for the body, name, path, metadata and parent of the current path. When it loads that data gets passed to our component as props.
171+
172+### Module basics
173+
174+A module is a special component that can kind of 'take over' the page. It can change properties of the nav bar as well as load custom scripts / css.
175+
176+Talk, for example, looks like this:
177+
178+```
179+<module nav_title="Talk" nav_no-dpad="" nav_no-sibs="" nav_subnav="talk-station">
180+ <script src="/~~/~/at/lib/js/urb.js" />
181+ <script src="/talk/main.js" />
182+ <link href="/talk/main.css" rel="stylesheet" />
183+ <talk></talk>
184+</module>
185+```
186+
187+A module will first download all the scripts and styles that it specifies before trying to load any contained components. This means that you can define React components in external scripts and a module can be entirely self contained. The `<talk>` component isn't a part of Tree — it's loaded first before it's executed.
188+
189+If you're interested in seeing how a module works you can check out the source for Talk [here](https://github.com/urbit/talk). Dojo also ships on your Urbit, its source is [here](https://github.com/urbit/sole).
131190
132191## `urb.js`
133192
193+The most basic interface between your browser and your Urbit is `urb.js`. This small library provides the basic utilities for sending and receiving messages from an Urbit.
194+
195+### `window.urb.appl`
196+
197+Each JSON message sent to your Urbit needs an app endpoint. Can be set as a global `window.urb.appl` or set on a per-request basis in the payload to `send()`.
198+
199+### `window.urb.oryx`
200+
201+CSRF token. Written to the page by `%eyre`, our webserver, when logged in. Required part of any authenticated request and included by default.
202+
203+### `window.urb.req(method,url,params,json,cb)`
204+
205+Our basic request wrapper. You can see here how a request needs to be packaged to be properly understood by your Urbit.
206+
207+### `window.urb.subscribe({path:"string"})`
208+
209+Subscribe to an endpoint. Subscription data is returned through the continuous long poll.
210+
211+### `window.urb.unsubscribe({path:"string"})`
212+
213+Close subscription on specified path.
214+
215+### `window.urb.poll()`
216+
217+Mechanics of the continuous long poll. Used mostly internally.
134218
219+### `window.urb.util`
135220
221+Library of utility and helper functions.