1 | /**
|
---|
2 | * Copyright (c) 2014-present, Facebook, Inc.
|
---|
3 | *
|
---|
4 | * This source code is licensed under the MIT license found in the
|
---|
5 | * LICENSE file in the root directory of this source tree.
|
---|
6 | */
|
---|
7 |
|
---|
8 | /**
|
---|
9 | * Cursors
|
---|
10 | * -------
|
---|
11 | *
|
---|
12 | * Cursors allow you to hold a reference to a path in a nested immutable data
|
---|
13 | * structure, allowing you to pass smaller sections of a larger nested
|
---|
14 | * collection to portions of your application while maintaining a central point
|
---|
15 | * aware of changes to the entire data structure.
|
---|
16 | *
|
---|
17 | * This is particularly useful when used in conjuction with component-based UI
|
---|
18 | * libraries like [React](http://facebook.github.io/react/) or to simulate
|
---|
19 | * "state" throughout an application while maintaining a single flow of logic.
|
---|
20 | *
|
---|
21 | * Cursors provide a simple API for getting the value at that path
|
---|
22 | * (the equivalent of `this.getIn(keyPath)`), updating the value at that path
|
---|
23 | * (the equivalent of `this.updateIn(keyPath)`), and getting a sub-cursor
|
---|
24 | * starting from that path.
|
---|
25 | *
|
---|
26 | * When updated, a new root collection is created and provided to the `onChange`
|
---|
27 | * function provided to the first call to `Cursor(map, onChange)`.
|
---|
28 | *
|
---|
29 | * When this cursor's (or any of its sub-cursors') `update` method is called,
|
---|
30 | * the resulting new data structure will be provided to the `onChange`
|
---|
31 | * function. Use this callback to keep track of the most current value or
|
---|
32 | * update the rest of your application.
|
---|
33 | */
|
---|
34 |
|
---|
35 | /// <reference path='../../dist/immutable.d.ts'/>
|
---|
36 |
|
---|
37 | declare module __Cursor {
|
---|
38 |
|
---|
39 | export function from(
|
---|
40 | collection: Immutable.Collection<any, any>,
|
---|
41 | onChange?: (newValue: any, oldValue?: any, keyPath?: Array<any>) => any
|
---|
42 | ): Cursor;
|
---|
43 | export function from(
|
---|
44 | collection: Immutable.Collection<any, any>,
|
---|
45 | keyPath: Array<any>,
|
---|
46 | onChange?: (newValue: any, oldValue?: any, keyPath?: Array<any>) => any
|
---|
47 | ): Cursor;
|
---|
48 | export function from(
|
---|
49 | collection: Immutable.Collection<any, any>,
|
---|
50 | key: any,
|
---|
51 | onChange?: (newValue: any, oldValue?: any, keyPath?: Array<any>) => any
|
---|
52 | ): Cursor;
|
---|
53 |
|
---|
54 |
|
---|
55 | export interface Cursor extends Immutable.Seq<any, any> {
|
---|
56 |
|
---|
57 | /**
|
---|
58 | * Returns a sub-cursor following the key-path starting from this cursor.
|
---|
59 | */
|
---|
60 | cursor(subKeyPath: Array<any>): Cursor;
|
---|
61 | cursor(subKey: any): Cursor;
|
---|
62 |
|
---|
63 | /**
|
---|
64 | * Returns the value at the cursor, if the cursor path does not yet exist,
|
---|
65 | * returns `notSetValue`.
|
---|
66 | */
|
---|
67 | deref(notSetValue?: any): any;
|
---|
68 |
|
---|
69 | /**
|
---|
70 | * Returns the value at the `key` in the cursor, or `notSetValue` if it
|
---|
71 | * does not exist.
|
---|
72 | *
|
---|
73 | * If the key would return a collection, a new Cursor is returned.
|
---|
74 | */
|
---|
75 | get(key: any, notSetValue?: any): any;
|
---|
76 |
|
---|
77 | /**
|
---|
78 | * Returns the value at the `keyPath` in the cursor, or `notSetValue` if it
|
---|
79 | * does not exist.
|
---|
80 | *
|
---|
81 | * If the keyPath would return a collection, a new Cursor is returned.
|
---|
82 | */
|
---|
83 | getIn(keyPath: Array<any>, notSetValue?: any): any;
|
---|
84 | getIn(keyPath: Immutable.Iterable<any, any>, notSetValue?: any): any;
|
---|
85 |
|
---|
86 | /**
|
---|
87 | * Sets `value` at `key` in the cursor, returning a new cursor to the same
|
---|
88 | * point in the new data.
|
---|
89 | *
|
---|
90 | * If only one parameter is provided, it is set directly as the cursor's value.
|
---|
91 | */
|
---|
92 | set(key: any, value: any): Cursor;
|
---|
93 | set(value: any): Cursor;
|
---|
94 |
|
---|
95 | /**
|
---|
96 | * Deletes `key` from the cursor, returning a new cursor to the same
|
---|
97 | * point in the new data.
|
---|
98 | *
|
---|
99 | * Note: `delete` cannot be safely used in IE8
|
---|
100 | * @alias remove
|
---|
101 | */
|
---|
102 | delete(key: any): Cursor;
|
---|
103 | remove(key: any): Cursor;
|
---|
104 |
|
---|
105 | /**
|
---|
106 | * Clears the value at this cursor, returning a new cursor to the same
|
---|
107 | * point in the new data.
|
---|
108 | */
|
---|
109 | clear(): Cursor;
|
---|
110 |
|
---|
111 | /**
|
---|
112 | * Updates the value in the data this cursor points to, triggering the
|
---|
113 | * callback for the root cursor and returning a new cursor pointing to the
|
---|
114 | * new data.
|
---|
115 | */
|
---|
116 | update(updater: (value: any) => any): Cursor;
|
---|
117 | update(key: any, updater: (value: any) => any): Cursor;
|
---|
118 | update(key: any, notSetValue: any, updater: (value: any) => any): Cursor;
|
---|
119 |
|
---|
120 | /**
|
---|
121 | * @see `Map#merge`
|
---|
122 | */
|
---|
123 | merge(...iterables: Immutable.Iterable<any, any>[]): Cursor;
|
---|
124 | merge(...iterables: {[key: string]: any}[]): Cursor;
|
---|
125 |
|
---|
126 | /**
|
---|
127 | * @see `Map#mergeWith`
|
---|
128 | */
|
---|
129 | mergeWith(
|
---|
130 | merger: (previous?: any, next?: any) => any,
|
---|
131 | ...iterables: Immutable.Iterable<any, any>[]
|
---|
132 | ): Cursor;
|
---|
133 | mergeWith(
|
---|
134 | merger: (previous?: any, next?: any) => any,
|
---|
135 | ...iterables: {[key: string]: any}[]
|
---|
136 | ): Cursor;
|
---|
137 |
|
---|
138 | /**
|
---|
139 | * @see `Map#mergeDeep`
|
---|
140 | */
|
---|
141 | mergeDeep(...iterables: Immutable.Iterable<any, any>[]): Cursor;
|
---|
142 | mergeDeep(...iterables: {[key: string]: any}[]): Cursor;
|
---|
143 |
|
---|
144 | /**
|
---|
145 | * @see `Map#mergeDeepWith`
|
---|
146 | */
|
---|
147 | mergeDeepWith(
|
---|
148 | merger: (previous?: any, next?: any) => any,
|
---|
149 | ...iterables: Immutable.Iterable<any, any>[]
|
---|
150 | ): Cursor;
|
---|
151 | mergeDeepWith(
|
---|
152 | merger: (previous?: any, next?: any) => any,
|
---|
153 | ...iterables: {[key: string]: any}[]
|
---|
154 | ): Cursor;
|
---|
155 |
|
---|
156 | // Deep persistent changes
|
---|
157 |
|
---|
158 | /**
|
---|
159 | * Returns a new Cursor having set `value` at this `keyPath`. If any keys in
|
---|
160 | * `keyPath` do not exist, a new immutable Map will be created at that key.
|
---|
161 | */
|
---|
162 | setIn(keyPath: Array<any>, value: any): Cursor;
|
---|
163 | setIn(keyPath: Immutable.Iterable<any, any>, value: any): Cursor;
|
---|
164 |
|
---|
165 | /**
|
---|
166 | * Returns a new Cursor with provided `values` appended
|
---|
167 | */
|
---|
168 | push(...values: Array<any>): Cursor;
|
---|
169 |
|
---|
170 | /**
|
---|
171 | * Returns a new Cursor with a size ones less than this Cursor,
|
---|
172 | * excluding the last index in this Cursor.
|
---|
173 | */
|
---|
174 | pop(): Cursor;
|
---|
175 |
|
---|
176 | /**
|
---|
177 | * Returns a new Cursor with the provided `values` prepended,
|
---|
178 | * shifting other values ahead to higher indices.
|
---|
179 | */
|
---|
180 | unshift(...values: Array<any>): Cursor;
|
---|
181 |
|
---|
182 | /**
|
---|
183 | * Returns a new Cursor with a size ones less than this Cursor, excluding
|
---|
184 | * the first index in this Cursor, shifting all other values to a lower index.
|
---|
185 | */
|
---|
186 | shift(): Cursor;
|
---|
187 |
|
---|
188 | /**
|
---|
189 | * Returns a new Cursor having removed the value at this `keyPath`.
|
---|
190 | *
|
---|
191 | * @alias removeIn
|
---|
192 | */
|
---|
193 | deleteIn(keyPath: Array<any>): Cursor;
|
---|
194 | deleteIn(keyPath: Immutable.Iterable<any, any>): Cursor;
|
---|
195 | removeIn(keyPath: Array<any>): Cursor;
|
---|
196 | removeIn(keyPath: Immutable.Iterable<any, any>): Cursor;
|
---|
197 |
|
---|
198 | /**
|
---|
199 | * Returns a new Cursor having applied the `updater` to the value found at
|
---|
200 | * the keyPath.
|
---|
201 | *
|
---|
202 | * If any keys in `keyPath` do not exist, new Immutable `Map`s will
|
---|
203 | * be created at those keys. If the `keyPath` does not already contain a
|
---|
204 | * value, the `updater` function will be called with `notSetValue`, if
|
---|
205 | * provided, otherwise `undefined`.
|
---|
206 | *
|
---|
207 | * If the `updater` function returns the same value it was called with, then
|
---|
208 | * no change will occur. This is still true if `notSetValue` is provided.
|
---|
209 | */
|
---|
210 | updateIn(
|
---|
211 | keyPath: Array<any>,
|
---|
212 | updater: (value: any) => any
|
---|
213 | ): Cursor;
|
---|
214 | updateIn(
|
---|
215 | keyPath: Array<any>,
|
---|
216 | notSetValue: any,
|
---|
217 | updater: (value: any) => any
|
---|
218 | ): Cursor;
|
---|
219 | updateIn(
|
---|
220 | keyPath: Immutable.Iterable<any, any>,
|
---|
221 | updater: (value: any) => any
|
---|
222 | ): Cursor;
|
---|
223 | updateIn(
|
---|
224 | keyPath: Immutable.Iterable<any, any>,
|
---|
225 | notSetValue: any,
|
---|
226 | updater: (value: any) => any
|
---|
227 | ): Cursor;
|
---|
228 |
|
---|
229 | /**
|
---|
230 | * A combination of `updateIn` and `merge`, returning a new Cursor, but
|
---|
231 | * performing the merge at a point arrived at by following the keyPath.
|
---|
232 | * In other words, these two lines are equivalent:
|
---|
233 | *
|
---|
234 | * x.updateIn(['a', 'b', 'c'], abc => abc.merge(y));
|
---|
235 | * x.mergeIn(['a', 'b', 'c'], y);
|
---|
236 | *
|
---|
237 | */
|
---|
238 | mergeIn(
|
---|
239 | keyPath: Immutable.Iterable<any, any>,
|
---|
240 | ...iterables: Immutable.Iterable<any, any>[]
|
---|
241 | ): Cursor;
|
---|
242 | mergeIn(
|
---|
243 | keyPath: Array<any>,
|
---|
244 | ...iterables: Immutable.Iterable<any, any>[]
|
---|
245 | ): Cursor;
|
---|
246 | mergeIn(
|
---|
247 | keyPath: Array<any>,
|
---|
248 | ...iterables: {[key: string]: any}[]
|
---|
249 | ): Cursor;
|
---|
250 |
|
---|
251 | /**
|
---|
252 | * A combination of `updateIn` and `mergeDeep`, returning a new Cursor, but
|
---|
253 | * performing the deep merge at a point arrived at by following the keyPath.
|
---|
254 | * In other words, these two lines are equivalent:
|
---|
255 | *
|
---|
256 | * x.updateIn(['a', 'b', 'c'], abc => abc.mergeDeep(y));
|
---|
257 | * x.mergeDeepIn(['a', 'b', 'c'], y);
|
---|
258 | *
|
---|
259 | */
|
---|
260 | mergeDeepIn(
|
---|
261 | keyPath: Immutable.Iterable<any, any>,
|
---|
262 | ...iterables: Immutable.Iterable<any, any>[]
|
---|
263 | ): Cursor;
|
---|
264 | mergeDeepIn(
|
---|
265 | keyPath: Array<any>,
|
---|
266 | ...iterables: Immutable.Iterable<any, any>[]
|
---|
267 | ): Cursor;
|
---|
268 | mergeDeepIn(
|
---|
269 | keyPath: Array<any>,
|
---|
270 | ...iterables: {[key: string]: any}[]
|
---|
271 | ): Cursor;
|
---|
272 |
|
---|
273 | // Transient changes
|
---|
274 |
|
---|
275 | /**
|
---|
276 | * Every time you call one of the above functions, a new immutable value is
|
---|
277 | * created and the callback is triggered. If you need to apply a series of
|
---|
278 | * mutations to a Cursor without triggering the callback repeatedly,
|
---|
279 | * `withMutations()` creates a temporary mutable copy of the value which
|
---|
280 | * can apply mutations in a highly performant manner. Afterwards the
|
---|
281 | * callback is triggered with the final value.
|
---|
282 | */
|
---|
283 | withMutations(mutator: (mutable: any) => any): Cursor;
|
---|
284 | }
|
---|
285 |
|
---|
286 | }
|
---|
287 |
|
---|
288 | declare module 'immutable/contrib/cursor' {
|
---|
289 | export = __Cursor
|
---|
290 | } |
---|