Skip to content

Instantly share code, notes, and snippets.

@dashed
Created March 3, 2015 08:33
Show Gist options
  • Save dashed/27c0d2a20d8e53e1447e to your computer and use it in GitHub Desktop.
Save dashed/27c0d2a20d8e53e1447e to your computer and use it in GitHub Desktop.
const Immutable = require('immutable');
const Cursor = require('immutable/contrib/cursor');
const immstruct = require('immstruct');
const Iterable = Immutable.Iterable;
/**
(work in progress)
Wrapped immutable.js cursors:
- cursor.refresh() returns fresh cursor
- cursor.path() get keyPath
- cursor.back() go to 'back up' to a fresh ancestor cursor
**/
function cursorFrom(structure, keyPath) {
const cursor = structure.cursor(keyPath);
return wrapCursor(structure, cursor, keyPath);
}
function wrapCursor(structure, _cursor, _keyPath) {
const keyPath = valToKeyPath(_keyPath);
const oldMethods = {
cursor: _cursor.cursor,
get: _cursor.get,
getIn: _cursor.getIn,
};
_cursor.refresh = function() {
const newCursor = structure.cursor(keyPath);
return wrapCursor(structure, newCursor, keyPath);
};
_cursor.back = function() {
if(keyPath.length == 0) return;
const newkeyPath = keyPath.slice(0, -1);
const newCursor = structure.cursor(newkeyPath);
return wrapCursor(structure, newCursor, newkeyPath);
};
_cursor.path = function() {
return keyPath;
}
// wrap methods
_cursor.cursor = function(subKeyPath) {
const subKeyPath = valToKeyPath(subKeyPath);
const newCursor = oldMethods.cursor.call(_cursor, subKeyPath);
const newkeyPath = keyPath.concat(subKeyPath);
return wrapCursor(structure, newCursor, newkeyPath);
};
_cursor.get = function() {
const ret = oldMethods.get.apply(_cursor, arguments);
return Iterable.isIterable(ret) ? wrapCursor(structure, ret, newkeyPath) : ret;
}
_cursor.getIn = function() {
const ret = oldMethods.getIn.apply(_cursor, arguments);
return Iterable.isIterable(ret) ? wrapCursor(structure, ret, newkeyPath) : ret;
}
const methods = [
'set',
'delete',
'remove',
'clear',
'update',
'merge',
'mergeWith',
'mergeDeep',
'mergeDeepWith',
'setIn',
'deleteIn',
'removeIn',
'updateIn',
'mergeIn',
'mergeDeepIn',
'withMutations'
];
for(let idx in methods) {
const method = methods[idx];
const oldMethod = _cursor[method];
_cursor[method] = wrapMethod(oldMethod, structure, _cursor, keyPath);
}
return _cursor;
}
function valToKeyPath(val) {
return Array.isArray(val) ? val :
Iterable.isIterable(val) ? val.toArray() :
[val];
}
function wrapMethod(method, structure, cursor, keyPath) {
return function() {
const newCursor = method.apply(cursor, arguments);
return wrapCursor(structure, newCursor, keyPath);
}
}
exports.from = cursorFrom;
////////
const map1 = Immutable.fromJS({ 'foo': 'bar', 'baz': [1,2,3] });
const structure = immstruct(map1);
structure.on('swap', function() {
// console.log('swap');
})
const c1 = structure.cursor('baz');
const c2 = cursorFrom(structure, 'baz');
console.log(c1 === c2); // => false
const c3 = c2.cursor('1').update(() => 42);
console.log(c2.cursor('1').deref()) // => 2
console.log(c3.deref()) // => 42
const c4 = c2.refresh();
console.log(c4.cursor('1').deref()) // => 42
console.log(c4.cursor('1').update(() => 24))
const c5 = c3.back();
console.log(c5.toJS()) // => [ 1, 24, 3 ]
console.log(c5.back()) // => Cursor { foo: "bar", baz: Cursor [ 1, 24, 3 ] }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment