Closed torgeir closed 9 years ago
I did some work regarding this on a library that would "decorate" immstruct
, by providing utilities to make flux/isomorphic easier by focusing on immutable structures as the central store.
Some caveats I faced was that any element of the keyPath
array can be of any type. So you can't use express-style routing as suggested in https://github.com/facebook/immutable-js/issues/237, nor can you use various amazing routing utilities like https://github.com/aaronblohowiak/routes.js, https://github.com/Matt-Esch/http-hash, or https://github.com/pillarjs/path-to-regexp.
I don't have much code to show yet, since it's still in heavy development. Here is how I would fetch or create node paths that reflect the keyPath
:
var rootNode = new Structure();
function fetchNode(rootNode, keyPath, create) {
var
current = rootNode,
i = 0;
for(i = 0; i < keyPath.length; i++) {
var children = current.get('children', NOT_SET);
if(children === NOT_SET) {
if(create) {
children = current.set('children', Immutable.Map()).get('children');
} else {
current = null;
break;
}
}
var key = keyPath[i];
var current = children.get(key, NOT_SET);
if(current === NOT_SET) {
if(create) {
current = children.set(key, Immutable.Map()).get(key);
} else {
current = null;
break;
}
}
}
return current;
}
Since we can't do something like matching '/foo/:bar'
paths as in express. I'm mulling over the idea of listening via the bubbling and capture event model as is done in DOM.
immstruct already knows the path of .update()
s, can't we simply (in pseudo code)
function on (ev, key, fn) {
structure.on(ev, function (path, old, neww) {
if (path === key)
fn.apply(null, arguments);
});
}
I was thinking something similar, but I decided to go with a structure similar to a trie tree to be efficient on space complexity in the long term.
I've been experimenting with implementing immstruct.listenTo
, and I've run into some interesting issues:
// some promise returning function
var a_listener = co.wrap(function*(results){
// Input:
// results = {
// event: 'change',
// newValue: ...,
// oldValue: ...
// };
// update to execute another listener
struct.cursor('b').update(function(m) {
return m.set('foo', 'bar');
});
// suggestion: wait until listener for ['b'] finishes?
yield immstruct.waitFor(struct, 'b');
// update keypath with no listener
struct.cursor('c').update(function(m) {
return m.set('foo', 'bar');
});
});
var b_listener = co.wrap(function*(results){
// how to handle cycles?
struct.cursor('a').update(function(m) {
return m.set('foo', 'bar');
});
});
var struct = immstruct({ a: {}, b: {}, c: {} });
immstruct.listenTo(struct, ['a'], a_listener);
immstruct.listenTo(struct, ['b'], b_listener);
struct.cursor('a').update(function(m) {
return m.set('foo', 0);
});
// how to handle case when modifying cursor while listener for ['a'] executes?
struct.cursor('a').update(function(m) {
return m.set('foo', 1);
});
Reference cursors should cover this part, no? #30
Yep. This should be closed.
We can easily add listeners to when specific pieces of data inside a structure changes.
Of course, you can aldready do
But something along the lines of this would be nice