// @flow import * as Immutable from 'immutable'; export type Updater = (oldValue: TProp) => TProp; export default class ImmutableModel { _state: Immutable.Map; constructor(state: Immutable.Map) { this._state = state; } getState() { return this._state; } clone(value: Immutable.Map): this { const constructor = this.constructor; return value === this._state ? this : new constructor(value); } get(property: string): any { return this._state.get(property); } set(property: string, value: any): this { return this.clone(this._state.set(property, value)); } update(property: string, updater: Updater): this { return this.clone(this._state.update(property, updater)); } getIn(properties: string[]): any { return this._state.getIn(properties); } setIn(properties: string[], value: any): this { return this.clone(this._state.setIn(properties, value)); } updateIn( properties: Array, notSetValue: TProp | Updater, updater?: Updater ): this { return this.clone(this._state.updateIn(properties, notSetValue, updater)); } has(property: string): boolean { return this._state.has(property); } equals(other: any): boolean { return this._state.equals(other); } addToMap(property: string, key: TKey, value: TValue): this { const map: Immutable.Map = this.get(property); return this.clone(this._state.set(property, map.set(key, value))); } removeFromMap(property: string, key: TKey): this { const map: Immutable.Map = this.get(property); return this.clone(this._state.set(property, map.remove(key))); } addToList(property: string, value: TProp): this { return this.clone(this._state.update(property, Immutable.List(), lst => lst.push(value))); } concatToList(property: string, ...value: Array): this { return this.clone(this._state.update(property, Immutable.List(), lst => lst.concat(...value))); } removeFromList(property: string, index: number): this { const list: Immutable.List = this.get(property); return this.clone(this._state.set(property, list.remove(index))); } addToSet(property: string, value: TProp): this { const collection: Immutable.Set = this.get(property); return this.clone(this._state.set(property, collection.add(value))); } removeFromSet(property: string, value: TProp): this { const list: Immutable.Set = this.get(property); return this.clone(this._state.set(property, list.remove(value))); } }