This commit is contained in:
tatianamac
2019-11-26 14:50:43 -08:00
parent 8a55660ed0
commit 6d5445ecc5
13894 changed files with 2233957 additions and 0 deletions

33
node_modules/immutable/contrib/cursor/README.md generated vendored Normal file
View 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
```

View 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
View 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
View 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;