mirror of
https://github.com/fooflington/selfdefined.git
synced 2025-06-10 21:01:41 +00:00
update
This commit is contained in:
33
node_modules/immutable/contrib/cursor/README.md
generated
vendored
Normal file
33
node_modules/immutable/contrib/cursor/README.md
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
Cursors
|
||||
-------
|
||||
|
||||
Cursors allow you to hold a reference to a path in a nested immutable data
|
||||
structure, allowing you to pass smaller sections of a larger nested
|
||||
collection to portions of your application while maintaining a central point
|
||||
aware of changes to the entire data structure: an `onChange` function which is
|
||||
called whenever a cursor or sub-cursor calls `update`.
|
||||
|
||||
This is particularly useful when used in conjuction with component-based UI
|
||||
libraries like [React](http://facebook.github.io/react/) or to simulate
|
||||
"state" throughout an application while maintaining a single flow of logic.
|
||||
|
||||
|
||||
```javascript
|
||||
var Immutable = require('immutable');
|
||||
var Cursor = require('immutable/contrib/cursor');
|
||||
|
||||
var data = Immutable.fromJS({ a: { b: { c: 1 } } });
|
||||
var cursor = Cursor.from(data, ['a', 'b'], newData => {
|
||||
data = newData;
|
||||
});
|
||||
|
||||
// ... elsewhere ...
|
||||
|
||||
cursor.get('c'); // 1
|
||||
cursor = cursor.update('c', x => x + 1);
|
||||
cursor.get('c'); // 2
|
||||
|
||||
// ... back to data ...
|
||||
|
||||
data.getIn(['a', 'b', 'c']); // 2
|
||||
```
|
400
node_modules/immutable/contrib/cursor/__tests__/Cursor.ts.skip
generated
vendored
Normal file
400
node_modules/immutable/contrib/cursor/__tests__/Cursor.ts.skip
generated
vendored
Normal file
@ -0,0 +1,400 @@
|
||||
/**
|
||||
* Copyright (c) 2014-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
///<reference path='../../../resources/jest.d.ts'/>
|
||||
///<reference path='../../../dist/immutable.d.ts'/>
|
||||
///<reference path='../index.d.ts'/>
|
||||
|
||||
jest.autoMockOff();
|
||||
|
||||
import Immutable = require('immutable');
|
||||
import Cursor = require('immutable/contrib/cursor');
|
||||
|
||||
describe('Cursor', () => {
|
||||
|
||||
beforeEach(function () {
|
||||
this.addMatchers({
|
||||
toValueEqual: function (expected) {
|
||||
var actual = this.actual;
|
||||
if (!Immutable.is(expected, this.actual)) {
|
||||
this.message = 'Expected\n' + this.actual + '\nto equal\n' + expected;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
var json = { a: { b: { c: 1 } } };
|
||||
|
||||
it('gets from its path', () => {
|
||||
var data = Immutable.fromJS(json);
|
||||
var cursor = Cursor.from(data);
|
||||
|
||||
expect(cursor.deref()).toBe(data);
|
||||
|
||||
var deepCursor = cursor.cursor(['a', 'b']);
|
||||
expect(deepCursor.deref().toJS()).toEqual(json.a.b);
|
||||
expect(deepCursor.deref()).toBe(data.getIn(['a', 'b']));
|
||||
expect(deepCursor.get('c')).toBe(1);
|
||||
|
||||
var leafCursor = deepCursor.cursor('c');
|
||||
expect(leafCursor.deref()).toBe(1);
|
||||
|
||||
var missCursor = leafCursor.cursor('d');
|
||||
expect(missCursor.deref()).toBe(undefined);
|
||||
});
|
||||
|
||||
it('gets return new cursors', () => {
|
||||
var data = Immutable.fromJS(json);
|
||||
var cursor = Cursor.from(data);
|
||||
var deepCursor = cursor.getIn(['a', 'b']);
|
||||
expect(deepCursor.deref()).toBe(data.getIn(['a', 'b']));
|
||||
});
|
||||
|
||||
it('gets return new cursors using List', () => {
|
||||
var data = Immutable.fromJS(json);
|
||||
var cursor = Cursor.from(data);
|
||||
var deepCursor = cursor.getIn(Immutable.fromJS(['a', 'b']));
|
||||
expect(deepCursor.deref()).toBe(data.getIn(Immutable.fromJS(['a', 'b'])));
|
||||
});
|
||||
|
||||
it('cursor return new cursors of correct type', () => {
|
||||
var data = Immutable.fromJS({ a: [1, 2, 3] });
|
||||
var cursor = Cursor.from(data);
|
||||
var deepCursor = <any>cursor.cursor('a');
|
||||
expect(deepCursor.findIndex).toBeDefined();
|
||||
});
|
||||
|
||||
it('can be treated as a value', () => {
|
||||
var data = Immutable.fromJS(json);
|
||||
var cursor = Cursor.from(data, ['a', 'b']);
|
||||
expect(cursor.toJS()).toEqual(json.a.b);
|
||||
expect(cursor).toValueEqual(data.getIn(['a', 'b']));
|
||||
expect(cursor.size).toBe(1);
|
||||
expect(cursor.get('c')).toBe(1);
|
||||
});
|
||||
|
||||
it('can be value compared to a primitive', () => {
|
||||
var data = Immutable.Map({ a: 'A' });
|
||||
var aCursor = Cursor.from(data, 'a');
|
||||
expect(aCursor.size).toBe(undefined);
|
||||
expect(aCursor.deref()).toBe('A');
|
||||
expect(Immutable.is(aCursor, 'A')).toBe(true);
|
||||
});
|
||||
|
||||
it('updates at its path', () => {
|
||||
var onChange = jest.genMockFunction();
|
||||
|
||||
var data = Immutable.fromJS(json);
|
||||
var aCursor = Cursor.from(data, 'a', onChange);
|
||||
|
||||
var deepCursor = aCursor.cursor(['b', 'c']);
|
||||
expect(deepCursor.deref()).toBe(1);
|
||||
|
||||
// cursor edits return new cursors:
|
||||
var newDeepCursor = deepCursor.update(x => x + 1);
|
||||
expect(newDeepCursor.deref()).toBe(2);
|
||||
var call1 = onChange.mock.calls[0];
|
||||
expect(call1[0]).toValueEqual(Immutable.fromJS({a:{b:{c:2}}}));
|
||||
expect(call1[1]).toBe(data);
|
||||
expect(call1[2]).toEqual(['a', 'b', 'c']);
|
||||
|
||||
var newestDeepCursor = newDeepCursor.update(x => x + 1);
|
||||
expect(newestDeepCursor.deref()).toBe(3);
|
||||
var call2 = onChange.mock.calls[1];
|
||||
expect(call2[0]).toValueEqual(Immutable.fromJS({a:{b:{c:3}}}));
|
||||
expect(call2[1]).toValueEqual(Immutable.fromJS({a:{b:{c:2}}}));
|
||||
expect(call2[2]).toEqual(['a', 'b', 'c']);
|
||||
|
||||
// meanwhile, data is still immutable:
|
||||
expect(data.toJS()).toEqual(json);
|
||||
|
||||
// as is the original cursor.
|
||||
expect(deepCursor.deref()).toBe(1);
|
||||
var otherNewDeepCursor = deepCursor.update(x => x + 10);
|
||||
expect(otherNewDeepCursor.deref()).toBe(11);
|
||||
var call3 = onChange.mock.calls[2];
|
||||
expect(call3[0]).toValueEqual(Immutable.fromJS({a:{b:{c:11}}}));
|
||||
expect(call3[1]).toBe(data);
|
||||
expect(call3[2]).toEqual(['a', 'b', 'c']);
|
||||
|
||||
// and update has been called exactly thrice.
|
||||
expect(onChange.mock.calls.length).toBe(3);
|
||||
});
|
||||
|
||||
it('updates with the return value of onChange', () => {
|
||||
var onChange = jest.genMockFunction();
|
||||
|
||||
var data = Immutable.fromJS(json);
|
||||
var deepCursor = Cursor.from(data, ['a', 'b', 'c'], onChange);
|
||||
|
||||
onChange.mockReturnValueOnce(undefined);
|
||||
// onChange returning undefined has no effect
|
||||
var newCursor = deepCursor.update(x => x + 1);
|
||||
expect(newCursor.deref()).toBe(2);
|
||||
var call1 = onChange.mock.calls[0];
|
||||
expect(call1[0]).toValueEqual(Immutable.fromJS({a:{b:{c:2}}}));
|
||||
expect(call1[1]).toBe(data);
|
||||
expect(call1[2]).toEqual(['a', 'b', 'c']);
|
||||
|
||||
onChange.mockReturnValueOnce(Immutable.fromJS({a:{b:{c:11}}}));
|
||||
// onChange returning something else has an effect
|
||||
newCursor = newCursor.update(x => 999);
|
||||
expect(newCursor.deref()).toBe(11);
|
||||
var call2 = onChange.mock.calls[1];
|
||||
expect(call2[0]).toValueEqual(Immutable.fromJS({a:{b:{c:999}}}));
|
||||
expect(call2[1]).toValueEqual(Immutable.fromJS({a:{b:{c:2}}}));
|
||||
expect(call2[2]).toEqual(['a', 'b', 'c']);
|
||||
|
||||
// and update has been called exactly twice
|
||||
expect(onChange.mock.calls.length).toBe(2);
|
||||
});
|
||||
|
||||
it('has map API for update shorthand', () => {
|
||||
var onChange = jest.genMockFunction();
|
||||
|
||||
var data = Immutable.fromJS(json);
|
||||
var aCursor = Cursor.from(data, 'a', onChange);
|
||||
var bCursor = aCursor.cursor('b');
|
||||
var cCursor = bCursor.cursor('c');
|
||||
|
||||
expect(bCursor.set('c', 10).deref()).toValueEqual(
|
||||
Immutable.fromJS({ c: 10 })
|
||||
);
|
||||
|
||||
var call1 = onChange.mock.calls[0];
|
||||
expect(call1[0]).toValueEqual(Immutable.fromJS({a:{b:{c:10}}}));
|
||||
expect(call1[1]).toBe(data);
|
||||
expect(call1[2]).toEqual(['a', 'b', 'c']);
|
||||
});
|
||||
|
||||
it('creates maps as necessary', () => {
|
||||
var data = Immutable.Map();
|
||||
var cursor = Cursor.from(data, ['a', 'b', 'c']);
|
||||
expect(cursor.deref()).toBe(undefined);
|
||||
cursor = cursor.set('d', 3);
|
||||
expect(cursor.deref()).toValueEqual(Immutable.Map({d: 3}));
|
||||
});
|
||||
|
||||
it('can set undefined', () => {
|
||||
var data = Immutable.Map();
|
||||
var cursor = Cursor.from(data, ['a', 'b', 'c']);
|
||||
expect(cursor.deref()).toBe(undefined);
|
||||
cursor = cursor.set('d', undefined);
|
||||
expect(cursor.toJS()).toEqual({d: undefined});
|
||||
});
|
||||
|
||||
it('has the sequence API', () => {
|
||||
var data = Immutable.Map({a: 1, b: 2, c: 3});
|
||||
var cursor = Cursor.from(data);
|
||||
expect(cursor.map((x: number) => x * x)).toValueEqual(Immutable.Map({a: 1, b: 4, c: 9}));
|
||||
});
|
||||
|
||||
it('can push values on a List', () => {
|
||||
var onChange = jest.genMockFunction();
|
||||
var data = Immutable.fromJS({a: {b: [0, 1, 2]}});
|
||||
var cursor = Cursor.from(data, ['a', 'b'], onChange);
|
||||
|
||||
expect(cursor.push(3,4)).toValueEqual(Immutable.List([0, 1, 2, 3, 4]));
|
||||
|
||||
var call = onChange.mock.calls[0];
|
||||
expect(call[0]).toValueEqual(Immutable.fromJS({a: {b: [0, 1, 2, 3, 4]}}));
|
||||
expect(call[1]).toBe(data);
|
||||
expect(call[2]).toEqual(['a', 'b']);
|
||||
});
|
||||
|
||||
it('can pop values of a List', () => {
|
||||
var onChange = jest.genMockFunction();
|
||||
var data = Immutable.fromJS({a: {b: [0, 1, 2]}});
|
||||
var cursor = Cursor.from(data, ['a', 'b'], onChange);
|
||||
|
||||
expect(cursor.pop()).toValueEqual(Immutable.List([0, 1]));
|
||||
|
||||
var call = onChange.mock.calls[0];
|
||||
expect(call[0]).toValueEqual(Immutable.fromJS({a: {b: [0, 1]}}));
|
||||
expect(call[1]).toBe(data);
|
||||
expect(call[2]).toEqual(['a', 'b']);
|
||||
});
|
||||
|
||||
it('can unshift values on a List', () => {
|
||||
var onChange = jest.genMockFunction();
|
||||
var data = Immutable.fromJS({a: {b: [0, 1, 2]}});
|
||||
var cursor = Cursor.from(data, ['a', 'b'], onChange);
|
||||
|
||||
expect(cursor.unshift(-2, -1)).toValueEqual(Immutable.List([-2, -1, 0, 1, 2]));
|
||||
|
||||
var call = onChange.mock.calls[0];
|
||||
expect(call[0]).toValueEqual(Immutable.fromJS({a: {b: [-2, -1, 0, 1, 2]}}));
|
||||
expect(call[1]).toBe(data);
|
||||
expect(call[2]).toEqual(['a', 'b']);
|
||||
});
|
||||
|
||||
it('can shift values of a List', () => {
|
||||
var onChange = jest.genMockFunction();
|
||||
var data = Immutable.fromJS({a: {b: [0, 1, 2]}});
|
||||
var cursor = Cursor.from(data, ['a', 'b'], onChange);
|
||||
|
||||
expect(cursor.shift()).toValueEqual(Immutable.List([1, 2]));
|
||||
|
||||
var call = onChange.mock.calls[0];
|
||||
expect(call[0]).toValueEqual(Immutable.fromJS({a: {b: [1, 2]}}));
|
||||
expect(call[1]).toBe(data);
|
||||
expect(call[2]).toEqual(['a', 'b']);
|
||||
});
|
||||
|
||||
|
||||
it('returns wrapped values for sequence API', () => {
|
||||
var data = Immutable.fromJS({a: {v: 1}, b: {v: 2}, c: {v: 3}});
|
||||
var onChange = jest.genMockFunction();
|
||||
var cursor = Cursor.from(data, onChange);
|
||||
|
||||
var found = cursor.find(map => map.get('v') === 2);
|
||||
expect(typeof found.deref).toBe('function'); // is a cursor!
|
||||
found = found.set('v', 20);
|
||||
|
||||
var call = onChange.mock.calls[0];
|
||||
expect(call[0]).toValueEqual(Immutable.fromJS({a: {v: 1}, b: {v: 20}, c: {v: 3}}));
|
||||
expect(call[1]).toBe(data);
|
||||
expect(call[2]).toEqual(['b', 'v']);
|
||||
});
|
||||
|
||||
it('returns wrapped values for iteration API', () => {
|
||||
var jsData = [{val: 0}, {val: 1}, {val: 2}];
|
||||
var data = Immutable.fromJS(jsData);
|
||||
var cursor = Cursor.from(data);
|
||||
cursor.forEach(function (c, i) {
|
||||
expect(typeof c.deref).toBe('function'); // is a cursor!
|
||||
expect(c.get('val')).toBe(i);
|
||||
});
|
||||
});
|
||||
|
||||
it('can map over values to get subcursors', () => {
|
||||
var data = Immutable.fromJS({a: {v: 1}, b: {v: 2}, c: {v: 3}});
|
||||
var cursor = Cursor.from(data);
|
||||
|
||||
var mapped = cursor.map(val => {
|
||||
expect(typeof val.deref).toBe('function'); // mapped values are cursors.
|
||||
return val;
|
||||
}).toMap();
|
||||
// Mapped is not a cursor, but it is a sequence of cursors.
|
||||
expect(typeof (<any>mapped).deref).not.toBe('function');
|
||||
expect(typeof (<any>mapped.get('a')).deref).toBe('function');
|
||||
|
||||
// Same for indexed cursors
|
||||
var data2 = Immutable.fromJS({x: [{v: 1}, {v: 2}, {v: 3}]});
|
||||
var cursor2 = Cursor.from(data2);
|
||||
|
||||
var mapped2 = cursor2.get('x').map(val => {
|
||||
expect(typeof val.deref).toBe('function'); // mapped values are cursors.
|
||||
return val;
|
||||
}).toList();
|
||||
// Mapped is not a cursor, but it is a sequence of cursors.
|
||||
expect(typeof mapped2.deref).not.toBe('function');
|
||||
expect(typeof mapped2.get(0).deref).toBe('function');
|
||||
});
|
||||
|
||||
it('can have mutations apply with a single callback', () => {
|
||||
var onChange = jest.genMockFunction();
|
||||
var data = Immutable.fromJS({'a': 1});
|
||||
|
||||
var c1 = Cursor.from(data, onChange);
|
||||
var c2 = c1.withMutations(m => m.set('b', 2).set('c', 3).set('d', 4));
|
||||
|
||||
expect(c1.deref().toObject()).toEqual({'a': 1});
|
||||
expect(c2.deref().toObject()).toEqual({'a': 1, 'b': 2, 'c': 3, 'd': 4});
|
||||
expect(onChange.mock.calls.length).toBe(1);
|
||||
});
|
||||
|
||||
it('can use withMutations on an unfulfilled cursor', () => {
|
||||
var onChange = jest.genMockFunction();
|
||||
var data = Immutable.fromJS({});
|
||||
|
||||
var c1 = Cursor.from(data, ['a', 'b', 'c'], onChange);
|
||||
var c2 = c1.withMutations(m => m.set('x', 1).set('y', 2).set('z', 3));
|
||||
|
||||
expect(c1.deref()).toEqual(undefined);
|
||||
expect(c2.deref()).toValueEqual(Immutable.fromJS(
|
||||
{ x: 1, y: 2, z: 3 }
|
||||
));
|
||||
expect(onChange.mock.calls.length).toBe(1);
|
||||
});
|
||||
|
||||
it('maintains indexed sequences', () => {
|
||||
var data = Immutable.fromJS([]);
|
||||
var c = Cursor.from(data);
|
||||
expect(c.toJS()).toEqual([]);
|
||||
});
|
||||
|
||||
it('properly acts as an iterable', () => {
|
||||
var data = Immutable.fromJS({key: {val: 1}});
|
||||
var c = Cursor.from(data).values();
|
||||
var c1 = c.next().value.get('val');
|
||||
expect(c1).toBe(1);
|
||||
});
|
||||
|
||||
it('can update deeply', () => {
|
||||
var onChange = jest.genMockFunction();
|
||||
var data = Immutable.fromJS({a:{b:{c:1}}});
|
||||
var c = Cursor.from(data, ['a'], onChange);
|
||||
var c1 = c.updateIn(['b', 'c'], x => x * 10);
|
||||
expect(c1.getIn(['b', 'c'])).toBe(10);
|
||||
|
||||
var call = onChange.mock.calls[0];
|
||||
expect(call[0]).toValueEqual(Immutable.fromJS({a:{b:{c:10}}}));
|
||||
expect(call[1]).toBe(data);
|
||||
expect(call[2]).toEqual(['a', 'b', 'c']);
|
||||
});
|
||||
|
||||
it('can set deeply', () => {
|
||||
var onChange = jest.genMockFunction();
|
||||
var data = Immutable.fromJS({a:{b:{c:1}}});
|
||||
var c = Cursor.from(data, ['a'], onChange);
|
||||
var c1 = c.setIn(['b', 'c'], 10);
|
||||
expect(c1.getIn(['b', 'c'])).toBe(10);
|
||||
|
||||
var call = onChange.mock.calls[0];
|
||||
expect(call[0]).toValueEqual(Immutable.fromJS({a:{b:{c:10}}}));
|
||||
expect(call[1]).toBe(data);
|
||||
expect(call[2]).toEqual(['a', 'b', 'c']);
|
||||
});
|
||||
|
||||
it('can get Record value as a property', () => {
|
||||
var User = Immutable.Record({ name: 'John' });
|
||||
var users = Immutable.List.of(new User());
|
||||
var data = Immutable.Map({'users': users});
|
||||
var cursor = Cursor.from(data, ['users']);
|
||||
expect(cursor.first().name).toBe('John');
|
||||
});
|
||||
|
||||
it('can set value of a cursor directly', () => {
|
||||
var onChange = jest.genMockFunction();
|
||||
var data = Immutable.fromJS({a:1});
|
||||
var c = Cursor.from(data, ['a'], onChange);
|
||||
var c1 = c.set(2);
|
||||
expect(c1.deref()).toBe(2);
|
||||
|
||||
var call = onChange.mock.calls[0];
|
||||
expect(call[0]).toValueEqual(Immutable.fromJS({a:2}));
|
||||
expect(call[1]).toBe(data);
|
||||
expect(call[2]).toEqual(['a']);
|
||||
});
|
||||
|
||||
it('can set value of a cursor to undefined directly', () => {
|
||||
var onChange = jest.genMockFunction();
|
||||
var data = Immutable.fromJS({a:1});
|
||||
var c = Cursor.from(data, ['a'], onChange);
|
||||
var c1 = c.set(undefined);
|
||||
expect(c1.deref()).toBe(undefined);
|
||||
|
||||
var call = onChange.mock.calls[0];
|
||||
expect(call[0]).toValueEqual(Immutable.fromJS({a:undefined}));
|
||||
expect(call[1]).toBe(data);
|
||||
expect(call[2]).toEqual(['a']);
|
||||
});
|
||||
|
||||
});
|
290
node_modules/immutable/contrib/cursor/index.d.ts
generated
vendored
Normal file
290
node_modules/immutable/contrib/cursor/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,290 @@
|
||||
/**
|
||||
* Copyright (c) 2014-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Cursors
|
||||
* -------
|
||||
*
|
||||
* Cursors allow you to hold a reference to a path in a nested immutable data
|
||||
* structure, allowing you to pass smaller sections of a larger nested
|
||||
* collection to portions of your application while maintaining a central point
|
||||
* aware of changes to the entire data structure.
|
||||
*
|
||||
* This is particularly useful when used in conjuction with component-based UI
|
||||
* libraries like [React](http://facebook.github.io/react/) or to simulate
|
||||
* "state" throughout an application while maintaining a single flow of logic.
|
||||
*
|
||||
* Cursors provide a simple API for getting the value at that path
|
||||
* (the equivalent of `this.getIn(keyPath)`), updating the value at that path
|
||||
* (the equivalent of `this.updateIn(keyPath)`), and getting a sub-cursor
|
||||
* starting from that path.
|
||||
*
|
||||
* When updated, a new root collection is created and provided to the `onChange`
|
||||
* function provided to the first call to `Cursor(map, onChange)`.
|
||||
*
|
||||
* When this cursor's (or any of its sub-cursors') `update` method is called,
|
||||
* the resulting new data structure will be provided to the `onChange`
|
||||
* function. Use this callback to keep track of the most current value or
|
||||
* update the rest of your application.
|
||||
*/
|
||||
|
||||
/// <reference path='../../dist/immutable.d.ts'/>
|
||||
|
||||
declare module __Cursor {
|
||||
|
||||
export function from(
|
||||
collection: Immutable.Collection<any, any>,
|
||||
onChange?: (newValue: any, oldValue?: any, keyPath?: Array<any>) => any
|
||||
): Cursor;
|
||||
export function from(
|
||||
collection: Immutable.Collection<any, any>,
|
||||
keyPath: Array<any>,
|
||||
onChange?: (newValue: any, oldValue?: any, keyPath?: Array<any>) => any
|
||||
): Cursor;
|
||||
export function from(
|
||||
collection: Immutable.Collection<any, any>,
|
||||
key: any,
|
||||
onChange?: (newValue: any, oldValue?: any, keyPath?: Array<any>) => any
|
||||
): Cursor;
|
||||
|
||||
|
||||
export interface Cursor extends Immutable.Seq<any, any> {
|
||||
|
||||
/**
|
||||
* Returns a sub-cursor following the key-path starting from this cursor.
|
||||
*/
|
||||
cursor(subKeyPath: Array<any>): Cursor;
|
||||
cursor(subKey: any): Cursor;
|
||||
|
||||
/**
|
||||
* Returns the value at the cursor, if the cursor path does not yet exist,
|
||||
* returns `notSetValue`.
|
||||
*/
|
||||
deref(notSetValue?: any): any;
|
||||
|
||||
/**
|
||||
* Returns the value at the `key` in the cursor, or `notSetValue` if it
|
||||
* does not exist.
|
||||
*
|
||||
* If the key would return a collection, a new Cursor is returned.
|
||||
*/
|
||||
get(key: any, notSetValue?: any): any;
|
||||
|
||||
/**
|
||||
* Returns the value at the `keyPath` in the cursor, or `notSetValue` if it
|
||||
* does not exist.
|
||||
*
|
||||
* If the keyPath would return a collection, a new Cursor is returned.
|
||||
*/
|
||||
getIn(keyPath: Array<any>, notSetValue?: any): any;
|
||||
getIn(keyPath: Immutable.Iterable<any, any>, notSetValue?: any): any;
|
||||
|
||||
/**
|
||||
* Sets `value` at `key` in the cursor, returning a new cursor to the same
|
||||
* point in the new data.
|
||||
*
|
||||
* If only one parameter is provided, it is set directly as the cursor's value.
|
||||
*/
|
||||
set(key: any, value: any): Cursor;
|
||||
set(value: any): Cursor;
|
||||
|
||||
/**
|
||||
* Deletes `key` from the cursor, returning a new cursor to the same
|
||||
* point in the new data.
|
||||
*
|
||||
* Note: `delete` cannot be safely used in IE8
|
||||
* @alias remove
|
||||
*/
|
||||
delete(key: any): Cursor;
|
||||
remove(key: any): Cursor;
|
||||
|
||||
/**
|
||||
* Clears the value at this cursor, returning a new cursor to the same
|
||||
* point in the new data.
|
||||
*/
|
||||
clear(): Cursor;
|
||||
|
||||
/**
|
||||
* Updates the value in the data this cursor points to, triggering the
|
||||
* callback for the root cursor and returning a new cursor pointing to the
|
||||
* new data.
|
||||
*/
|
||||
update(updater: (value: any) => any): Cursor;
|
||||
update(key: any, updater: (value: any) => any): Cursor;
|
||||
update(key: any, notSetValue: any, updater: (value: any) => any): Cursor;
|
||||
|
||||
/**
|
||||
* @see `Map#merge`
|
||||
*/
|
||||
merge(...iterables: Immutable.Iterable<any, any>[]): Cursor;
|
||||
merge(...iterables: {[key: string]: any}[]): Cursor;
|
||||
|
||||
/**
|
||||
* @see `Map#mergeWith`
|
||||
*/
|
||||
mergeWith(
|
||||
merger: (previous?: any, next?: any) => any,
|
||||
...iterables: Immutable.Iterable<any, any>[]
|
||||
): Cursor;
|
||||
mergeWith(
|
||||
merger: (previous?: any, next?: any) => any,
|
||||
...iterables: {[key: string]: any}[]
|
||||
): Cursor;
|
||||
|
||||
/**
|
||||
* @see `Map#mergeDeep`
|
||||
*/
|
||||
mergeDeep(...iterables: Immutable.Iterable<any, any>[]): Cursor;
|
||||
mergeDeep(...iterables: {[key: string]: any}[]): Cursor;
|
||||
|
||||
/**
|
||||
* @see `Map#mergeDeepWith`
|
||||
*/
|
||||
mergeDeepWith(
|
||||
merger: (previous?: any, next?: any) => any,
|
||||
...iterables: Immutable.Iterable<any, any>[]
|
||||
): Cursor;
|
||||
mergeDeepWith(
|
||||
merger: (previous?: any, next?: any) => any,
|
||||
...iterables: {[key: string]: any}[]
|
||||
): Cursor;
|
||||
|
||||
// Deep persistent changes
|
||||
|
||||
/**
|
||||
* Returns a new Cursor having set `value` at this `keyPath`. If any keys in
|
||||
* `keyPath` do not exist, a new immutable Map will be created at that key.
|
||||
*/
|
||||
setIn(keyPath: Array<any>, value: any): Cursor;
|
||||
setIn(keyPath: Immutable.Iterable<any, any>, value: any): Cursor;
|
||||
|
||||
/**
|
||||
* Returns a new Cursor with provided `values` appended
|
||||
*/
|
||||
push(...values: Array<any>): Cursor;
|
||||
|
||||
/**
|
||||
* Returns a new Cursor with a size ones less than this Cursor,
|
||||
* excluding the last index in this Cursor.
|
||||
*/
|
||||
pop(): Cursor;
|
||||
|
||||
/**
|
||||
* Returns a new Cursor with the provided `values` prepended,
|
||||
* shifting other values ahead to higher indices.
|
||||
*/
|
||||
unshift(...values: Array<any>): Cursor;
|
||||
|
||||
/**
|
||||
* Returns a new Cursor with a size ones less than this Cursor, excluding
|
||||
* the first index in this Cursor, shifting all other values to a lower index.
|
||||
*/
|
||||
shift(): Cursor;
|
||||
|
||||
/**
|
||||
* Returns a new Cursor having removed the value at this `keyPath`.
|
||||
*
|
||||
* @alias removeIn
|
||||
*/
|
||||
deleteIn(keyPath: Array<any>): Cursor;
|
||||
deleteIn(keyPath: Immutable.Iterable<any, any>): Cursor;
|
||||
removeIn(keyPath: Array<any>): Cursor;
|
||||
removeIn(keyPath: Immutable.Iterable<any, any>): Cursor;
|
||||
|
||||
/**
|
||||
* Returns a new Cursor having applied the `updater` to the value found at
|
||||
* the keyPath.
|
||||
*
|
||||
* If any keys in `keyPath` do not exist, new Immutable `Map`s will
|
||||
* be created at those keys. If the `keyPath` does not already contain a
|
||||
* value, the `updater` function will be called with `notSetValue`, if
|
||||
* provided, otherwise `undefined`.
|
||||
*
|
||||
* If the `updater` function returns the same value it was called with, then
|
||||
* no change will occur. This is still true if `notSetValue` is provided.
|
||||
*/
|
||||
updateIn(
|
||||
keyPath: Array<any>,
|
||||
updater: (value: any) => any
|
||||
): Cursor;
|
||||
updateIn(
|
||||
keyPath: Array<any>,
|
||||
notSetValue: any,
|
||||
updater: (value: any) => any
|
||||
): Cursor;
|
||||
updateIn(
|
||||
keyPath: Immutable.Iterable<any, any>,
|
||||
updater: (value: any) => any
|
||||
): Cursor;
|
||||
updateIn(
|
||||
keyPath: Immutable.Iterable<any, any>,
|
||||
notSetValue: any,
|
||||
updater: (value: any) => any
|
||||
): Cursor;
|
||||
|
||||
/**
|
||||
* A combination of `updateIn` and `merge`, returning a new Cursor, but
|
||||
* performing the merge at a point arrived at by following the keyPath.
|
||||
* In other words, these two lines are equivalent:
|
||||
*
|
||||
* x.updateIn(['a', 'b', 'c'], abc => abc.merge(y));
|
||||
* x.mergeIn(['a', 'b', 'c'], y);
|
||||
*
|
||||
*/
|
||||
mergeIn(
|
||||
keyPath: Immutable.Iterable<any, any>,
|
||||
...iterables: Immutable.Iterable<any, any>[]
|
||||
): Cursor;
|
||||
mergeIn(
|
||||
keyPath: Array<any>,
|
||||
...iterables: Immutable.Iterable<any, any>[]
|
||||
): Cursor;
|
||||
mergeIn(
|
||||
keyPath: Array<any>,
|
||||
...iterables: {[key: string]: any}[]
|
||||
): Cursor;
|
||||
|
||||
/**
|
||||
* A combination of `updateIn` and `mergeDeep`, returning a new Cursor, but
|
||||
* performing the deep merge at a point arrived at by following the keyPath.
|
||||
* In other words, these two lines are equivalent:
|
||||
*
|
||||
* x.updateIn(['a', 'b', 'c'], abc => abc.mergeDeep(y));
|
||||
* x.mergeDeepIn(['a', 'b', 'c'], y);
|
||||
*
|
||||
*/
|
||||
mergeDeepIn(
|
||||
keyPath: Immutable.Iterable<any, any>,
|
||||
...iterables: Immutable.Iterable<any, any>[]
|
||||
): Cursor;
|
||||
mergeDeepIn(
|
||||
keyPath: Array<any>,
|
||||
...iterables: Immutable.Iterable<any, any>[]
|
||||
): Cursor;
|
||||
mergeDeepIn(
|
||||
keyPath: Array<any>,
|
||||
...iterables: {[key: string]: any}[]
|
||||
): Cursor;
|
||||
|
||||
// Transient changes
|
||||
|
||||
/**
|
||||
* Every time you call one of the above functions, a new immutable value is
|
||||
* created and the callback is triggered. If you need to apply a series of
|
||||
* mutations to a Cursor without triggering the callback repeatedly,
|
||||
* `withMutations()` creates a temporary mutable copy of the value which
|
||||
* can apply mutations in a highly performant manner. Afterwards the
|
||||
* callback is triggered with the final value.
|
||||
*/
|
||||
withMutations(mutator: (mutable: any) => any): Cursor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
declare module 'immutable/contrib/cursor' {
|
||||
export = __Cursor
|
||||
}
|
341
node_modules/immutable/contrib/cursor/index.js
generated
vendored
Normal file
341
node_modules/immutable/contrib/cursor/index.js
generated
vendored
Normal file
@ -0,0 +1,341 @@
|
||||
/**
|
||||
* Copyright (c) 2014-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Cursor is expected to be required in a node or other CommonJS context:
|
||||
*
|
||||
* var Cursor = require('immutable/contrib/cursor');
|
||||
*
|
||||
* If you wish to use it in the browser, please check out Browserify or WebPack!
|
||||
*/
|
||||
|
||||
var Immutable = require('../../');
|
||||
var Iterable = Immutable.Iterable;
|
||||
var Iterator = Iterable.Iterator;
|
||||
var Seq = Immutable.Seq;
|
||||
var Map = Immutable.Map;
|
||||
var Record = Immutable.Record;
|
||||
|
||||
|
||||
function cursorFrom(rootData, keyPath, onChange) {
|
||||
if (arguments.length === 1) {
|
||||
keyPath = [];
|
||||
} else if (typeof keyPath === 'function') {
|
||||
onChange = keyPath;
|
||||
keyPath = [];
|
||||
} else {
|
||||
keyPath = valToKeyPath(keyPath);
|
||||
}
|
||||
return makeCursor(rootData, keyPath, onChange);
|
||||
}
|
||||
|
||||
|
||||
var KeyedCursorPrototype = Object.create(Seq.Keyed.prototype);
|
||||
var IndexedCursorPrototype = Object.create(Seq.Indexed.prototype);
|
||||
|
||||
function KeyedCursor(rootData, keyPath, onChange, size) {
|
||||
this.size = size;
|
||||
this._rootData = rootData;
|
||||
this._keyPath = keyPath;
|
||||
this._onChange = onChange;
|
||||
}
|
||||
KeyedCursorPrototype.constructor = KeyedCursor;
|
||||
|
||||
function IndexedCursor(rootData, keyPath, onChange, size) {
|
||||
this.size = size;
|
||||
this._rootData = rootData;
|
||||
this._keyPath = keyPath;
|
||||
this._onChange = onChange;
|
||||
}
|
||||
IndexedCursorPrototype.constructor = IndexedCursor;
|
||||
|
||||
KeyedCursorPrototype.toString = function() {
|
||||
return this.__toString('Cursor {', '}');
|
||||
}
|
||||
IndexedCursorPrototype.toString = function() {
|
||||
return this.__toString('Cursor [', ']');
|
||||
}
|
||||
|
||||
KeyedCursorPrototype.deref =
|
||||
KeyedCursorPrototype.valueOf =
|
||||
IndexedCursorPrototype.deref =
|
||||
IndexedCursorPrototype.valueOf = function(notSetValue) {
|
||||
return this._rootData.getIn(this._keyPath, notSetValue);
|
||||
}
|
||||
|
||||
KeyedCursorPrototype.get =
|
||||
IndexedCursorPrototype.get = function(key, notSetValue) {
|
||||
return this.getIn([key], notSetValue);
|
||||
}
|
||||
|
||||
KeyedCursorPrototype.getIn =
|
||||
IndexedCursorPrototype.getIn = function(keyPath, notSetValue) {
|
||||
keyPath = listToKeyPath(keyPath);
|
||||
if (keyPath.length === 0) {
|
||||
return this;
|
||||
}
|
||||
var value = this._rootData.getIn(newKeyPath(this._keyPath, keyPath), NOT_SET);
|
||||
return value === NOT_SET ? notSetValue : wrappedValue(this, keyPath, value);
|
||||
}
|
||||
|
||||
IndexedCursorPrototype.set =
|
||||
KeyedCursorPrototype.set = function(key, value) {
|
||||
if(arguments.length === 1) {
|
||||
return updateCursor(this, function() { return key; }, []);
|
||||
} else {
|
||||
return updateCursor(this, function (m) { return m.set(key, value); }, [key]);
|
||||
}
|
||||
}
|
||||
|
||||
IndexedCursorPrototype.push = function(/* values */) {
|
||||
var args = arguments;
|
||||
return updateCursor(this, function (m) {
|
||||
return m.push.apply(m, args);
|
||||
});
|
||||
}
|
||||
|
||||
IndexedCursorPrototype.pop = function() {
|
||||
return updateCursor(this, function (m) {
|
||||
return m.pop();
|
||||
});
|
||||
}
|
||||
|
||||
IndexedCursorPrototype.unshift = function(/* values */) {
|
||||
var args = arguments;
|
||||
return updateCursor(this, function (m) {
|
||||
return m.unshift.apply(m, args);
|
||||
});
|
||||
}
|
||||
|
||||
IndexedCursorPrototype.shift = function() {
|
||||
return updateCursor(this, function (m) {
|
||||
return m.shift();
|
||||
});
|
||||
}
|
||||
|
||||
IndexedCursorPrototype.setIn =
|
||||
KeyedCursorPrototype.setIn = Map.prototype.setIn;
|
||||
|
||||
KeyedCursorPrototype.remove =
|
||||
KeyedCursorPrototype['delete'] =
|
||||
IndexedCursorPrototype.remove =
|
||||
IndexedCursorPrototype['delete'] = function(key) {
|
||||
return updateCursor(this, function (m) { return m.remove(key); }, [key]);
|
||||
}
|
||||
|
||||
IndexedCursorPrototype.removeIn =
|
||||
IndexedCursorPrototype.deleteIn =
|
||||
KeyedCursorPrototype.removeIn =
|
||||
KeyedCursorPrototype.deleteIn = Map.prototype.deleteIn;
|
||||
|
||||
KeyedCursorPrototype.clear =
|
||||
IndexedCursorPrototype.clear = function() {
|
||||
return updateCursor(this, function (m) { return m.clear(); });
|
||||
}
|
||||
|
||||
IndexedCursorPrototype.update =
|
||||
KeyedCursorPrototype.update = function(keyOrFn, notSetValue, updater) {
|
||||
return arguments.length === 1 ?
|
||||
updateCursor(this, keyOrFn) :
|
||||
this.updateIn([keyOrFn], notSetValue, updater);
|
||||
}
|
||||
|
||||
IndexedCursorPrototype.updateIn =
|
||||
KeyedCursorPrototype.updateIn = function(keyPath, notSetValue, updater) {
|
||||
return updateCursor(this, function (m) {
|
||||
return m.updateIn(keyPath, notSetValue, updater);
|
||||
}, keyPath);
|
||||
}
|
||||
|
||||
IndexedCursorPrototype.merge =
|
||||
KeyedCursorPrototype.merge = function(/*...iters*/) {
|
||||
var args = arguments;
|
||||
return updateCursor(this, function (m) {
|
||||
return m.merge.apply(m, args);
|
||||
});
|
||||
}
|
||||
|
||||
IndexedCursorPrototype.mergeWith =
|
||||
KeyedCursorPrototype.mergeWith = function(merger/*, ...iters*/) {
|
||||
var args = arguments;
|
||||
return updateCursor(this, function (m) {
|
||||
return m.mergeWith.apply(m, args);
|
||||
});
|
||||
}
|
||||
|
||||
IndexedCursorPrototype.mergeIn =
|
||||
KeyedCursorPrototype.mergeIn = Map.prototype.mergeIn;
|
||||
|
||||
IndexedCursorPrototype.mergeDeep =
|
||||
KeyedCursorPrototype.mergeDeep = function(/*...iters*/) {
|
||||
var args = arguments;
|
||||
return updateCursor(this, function (m) {
|
||||
return m.mergeDeep.apply(m, args);
|
||||
});
|
||||
}
|
||||
|
||||
IndexedCursorPrototype.mergeDeepWith =
|
||||
KeyedCursorPrototype.mergeDeepWith = function(merger/*, ...iters*/) {
|
||||
var args = arguments;
|
||||
return updateCursor(this, function (m) {
|
||||
return m.mergeDeepWith.apply(m, args);
|
||||
});
|
||||
}
|
||||
|
||||
IndexedCursorPrototype.mergeDeepIn =
|
||||
KeyedCursorPrototype.mergeDeepIn = Map.prototype.mergeDeepIn;
|
||||
|
||||
KeyedCursorPrototype.withMutations =
|
||||
IndexedCursorPrototype.withMutations = function(fn) {
|
||||
return updateCursor(this, function (m) {
|
||||
return (m || Map()).withMutations(fn);
|
||||
});
|
||||
}
|
||||
|
||||
KeyedCursorPrototype.cursor =
|
||||
IndexedCursorPrototype.cursor = function(subKeyPath) {
|
||||
subKeyPath = valToKeyPath(subKeyPath);
|
||||
return subKeyPath.length === 0 ? this : subCursor(this, subKeyPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* All iterables need to implement __iterate
|
||||
*/
|
||||
KeyedCursorPrototype.__iterate =
|
||||
IndexedCursorPrototype.__iterate = function(fn, reverse) {
|
||||
var cursor = this;
|
||||
var deref = cursor.deref();
|
||||
return deref && deref.__iterate ? deref.__iterate(
|
||||
function (v, k) { return fn(wrappedValue(cursor, [k], v), k, cursor); },
|
||||
reverse
|
||||
) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* All iterables need to implement __iterator
|
||||
*/
|
||||
KeyedCursorPrototype.__iterator =
|
||||
IndexedCursorPrototype.__iterator = function(type, reverse) {
|
||||
var deref = this.deref();
|
||||
var cursor = this;
|
||||
var iterator = deref && deref.__iterator &&
|
||||
deref.__iterator(Iterator.ENTRIES, reverse);
|
||||
return new Iterator(function () {
|
||||
if (!iterator) {
|
||||
return { value: undefined, done: true };
|
||||
}
|
||||
var step = iterator.next();
|
||||
if (step.done) {
|
||||
return step;
|
||||
}
|
||||
var entry = step.value;
|
||||
var k = entry[0];
|
||||
var v = wrappedValue(cursor, [k], entry[1]);
|
||||
return {
|
||||
value: type === Iterator.KEYS ? k : type === Iterator.VALUES ? v : [k, v],
|
||||
done: false
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
KeyedCursor.prototype = KeyedCursorPrototype;
|
||||
IndexedCursor.prototype = IndexedCursorPrototype;
|
||||
|
||||
|
||||
var NOT_SET = {}; // Sentinel value
|
||||
|
||||
function makeCursor(rootData, keyPath, onChange, value) {
|
||||
if (arguments.length < 4) {
|
||||
value = rootData.getIn(keyPath);
|
||||
}
|
||||
var size = value && value.size;
|
||||
var CursorClass = Iterable.isIndexed(value) ? IndexedCursor : KeyedCursor;
|
||||
var cursor = new CursorClass(rootData, keyPath, onChange, size);
|
||||
|
||||
if (value instanceof Record) {
|
||||
defineRecordProperties(cursor, value);
|
||||
}
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
function defineRecordProperties(cursor, value) {
|
||||
try {
|
||||
value._keys.forEach(setProp.bind(undefined, cursor));
|
||||
} catch (error) {
|
||||
// Object.defineProperty failed. Probably IE8.
|
||||
}
|
||||
}
|
||||
|
||||
function setProp(prototype, name) {
|
||||
Object.defineProperty(prototype, name, {
|
||||
get: function() {
|
||||
return this.get(name);
|
||||
},
|
||||
set: function(value) {
|
||||
if (!this.__ownerID) {
|
||||
throw new Error('Cannot set on an immutable record.');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function wrappedValue(cursor, keyPath, value) {
|
||||
return Iterable.isIterable(value) ? subCursor(cursor, keyPath, value) : value;
|
||||
}
|
||||
|
||||
function subCursor(cursor, keyPath, value) {
|
||||
if (arguments.length < 3) {
|
||||
return makeCursor( // call without value
|
||||
cursor._rootData,
|
||||
newKeyPath(cursor._keyPath, keyPath),
|
||||
cursor._onChange
|
||||
);
|
||||
}
|
||||
return makeCursor(
|
||||
cursor._rootData,
|
||||
newKeyPath(cursor._keyPath, keyPath),
|
||||
cursor._onChange,
|
||||
value
|
||||
);
|
||||
}
|
||||
|
||||
function updateCursor(cursor, changeFn, changeKeyPath) {
|
||||
var deepChange = arguments.length > 2;
|
||||
var newRootData = cursor._rootData.updateIn(
|
||||
cursor._keyPath,
|
||||
deepChange ? Map() : undefined,
|
||||
changeFn
|
||||
);
|
||||
var keyPath = cursor._keyPath || [];
|
||||
var result = cursor._onChange && cursor._onChange.call(
|
||||
undefined,
|
||||
newRootData,
|
||||
cursor._rootData,
|
||||
deepChange ? newKeyPath(keyPath, changeKeyPath) : keyPath
|
||||
);
|
||||
if (result !== undefined) {
|
||||
newRootData = result;
|
||||
}
|
||||
return makeCursor(newRootData, cursor._keyPath, cursor._onChange);
|
||||
}
|
||||
|
||||
function newKeyPath(head, tail) {
|
||||
return head.concat(listToKeyPath(tail));
|
||||
}
|
||||
|
||||
function listToKeyPath(list) {
|
||||
return Array.isArray(list) ? list : Immutable.Iterable(list).toArray();
|
||||
}
|
||||
|
||||
function valToKeyPath(val) {
|
||||
return Array.isArray(val) ? val :
|
||||
Iterable.isIterable(val) ? val.toArray() :
|
||||
[val];
|
||||
}
|
||||
|
||||
exports.from = cursorFrom;
|
Reference in New Issue
Block a user