Skip to content

Instantly share code, notes, and snippets.

@dominictarr dominictarr/index.js
Created Apr 29, 2016

Embed
What would you like to do?
nested-representation-state-transfer.js
'use strict'
var h = require('hyperscript')
/*
running this example:
browserify index.js | indexhtmlify > test.html
# then open in your browser
*/
//turn a function into an updatable widget.
function widget (fn) {
var div = h('div')
function update(tree) {
div.innerHTML = ''
console.log(tree)
div.appendChild(tree)
}
div.call = function (value) {
var tree = fn(value, function (err, tree) {
update(tree)
})
if(tree) update(tree)
return div
}
return div
}
//create a clickable link that calls a function with some value.
function link(name, fn, value) {
return h('a', {href: '#', onclick: function () {
fn(value)
}}, name)
}
/*
ui framework
in REST, we build applications where a Representation of the State
is Transferred.
Here, I experiment with the same idea, except that state representations
can be nested.
In rest, web pages represent states, and links take you between states.
Forms are also used to transfer between states, but do not really change
the model, they essentially just allow you to create parametric links.
So, instead of transiting state at the scale of an entire page at once,
transit the state of _individual widgets_. The web did have some support
for this, via frames/iframes but they layouts possible with frames
are limited because you need a special frameset document, and each
widget must be defined in it's own file which makes maintanence awkward.
This prototype allows multilpe widgets to be nested, following scoping rules
just like javascript. (this prototype is implemented _as javascript_ but
it's intended to work like this)
So, this extends the notion of a link - a link html link has a href,
link text, and _link target_. On a html link, the target can only have a
[few possible values](http://www.w3schools.com/tags/att_link_target.asp)
In our prototype, the link target is a function to be called to retrive
a new state, and the href is a value to pass to that function, similar
to a URL.
*/
var count, abc
var n = 0
//a widget that contains an updating widget.
//the link may control the widget, because it exists in the same scope.
document.body.appendChild(
h('div',
(count = widget(function (_, cb) {
return h('span', n += 1)
})).call(0),
link('inc', count.call)
)
)
//a widget with links that can update itself, because it is defined
//children can see the containing scope.
abc=widget(function (n, cb) {
return h('div', n,
link('inc', abc.call, n + 1),
link('dec', abc.call, n - 1)
)
})
document.body.appendChild(h('div', abc.call(0)))
//and important consequence of using scopes is that a widget imported
//from another module cannot reference things in the parent scope
//unless those things are specifically passed into it. This makes
//modules much easier to reason about, and provides the encapsulation
//needed for modular programming.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.