index.d.ts 8.6 KB

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