1+ import sharedMethods from './sharedMethods'
2+ import isEqual from 'lodash/isEqual'
3+
4+ const EMPTY_OBJECT = { }
5+ const EMPTY_ARRAY = [ ]
6+
17export default class RecordCollection {
28 constructor ( table , key ) {
39 this . table = table
10+ this . schema = table . schema
411 this . key = key
12+ this . state = ( table . state . collections || { } ) [ key ] || { }
513 }
614
715 get ids ( ) {
8- return this . _getProps ( ) . ids || [ ]
16+ return this . state . ids || EMPTY_ARRAY
917 }
1018
1119 get length ( ) {
1220 return this . ids . length
1321 }
1422
1523 get meta ( ) {
16- return this . _getProps ( ) . meta || { }
24+ return this . state . meta || EMPTY_OBJECT
1725 }
1826
1927 exists ( ) {
20- return ! ! this . _getProps ( ) . ids
28+ return ! ! this . state . ids
2129 }
2230
2331 all ( ) {
24- const { factory } = this . table . schema . db
25- return this . ids . map ( id => factory . newRecordModel ( id , this . table ) )
32+ return this . ids . map ( id => this . table . getOrDefault ( id ) )
2633 }
2734
2835 value ( ) {
@@ -33,54 +40,55 @@ export default class RecordCollection {
3340 return this . all ( ) . map ( callback )
3441 }
3542
36- filter ( callback ) {
37- return this . all ( ) . filter ( callback )
38- }
39-
4043 set ( ids , meta ) {
41- const props = { ids }
44+ if ( ids == null ) throw new Error ( 'Invalid ids' )
45+ this . _setProp ( 'ids' , ids )
4246 if ( arguments . length > 1 ) {
43- props . meta = meta
47+ this . setMeta ( meta )
4448 }
45- return this . _setProps ( props )
49+ return this
4650 }
4751
4852 setMeta ( meta ) {
49- return this . _setProps ( { meta } )
53+ return this . _setProp ( ' meta' , meta )
5054 }
5155
5256 updateMeta ( meta ) {
53- return this . setMeta ( { ...this . meta , ...meta } )
57+ return this . _setProp ( 'meta' , { ...this . state . meta , ...meta } )
5458 }
5559
5660 insert ( ids , index ) {
61+ if ( ids == null ) throw new Error ( 'Invalid ids' )
5762 Array . isArray ( ids ) || ( ids = [ ids ] )
58- const currentIds = this . ids . slice ( )
5963
60- // Remove duplicate ids from the collection before insertion.
61- if ( currentIds . length ) {
62- ids . forEach ( ( id , i ) => {
63- const idx = currentIds . indexOf ( id )
64+ if ( index == null ) {
65+ const currentIds = this . ids . filter ( id => ids . indexOf ( id ) === - 1 )
66+ return this . set ( currentIds . concat ( ids ) )
67+ } else {
68+ const currentIds = this . ids . slice ( )
6469
65- if ( idx > - 1 ) {
66- currentIds . splice ( idx , 1 )
70+ // Remove duplicate ids from the collection before insertion.
71+ if ( currentIds . length ) {
72+ ids . forEach ( id => {
73+ const idx = currentIds . indexOf ( id )
6774
68- if ( idx < index ) {
69- index --
75+ if ( idx > - 1 ) {
76+ currentIds . splice ( idx , 1 )
77+
78+ if ( idx < index ) {
79+ index --
80+ }
7081 }
71- }
72- } )
73- }
82+ } )
83+ }
7484
75- if ( index == null ) {
76- return this . set ( currentIds . concat ( ids ) )
77- } else {
7885 currentIds . splice ( index , 0 , ...ids )
7986 return this . set ( currentIds )
8087 }
8188 }
8289
8390 insertUnique ( ids , index ) {
91+ if ( ids == null ) throw new Error ( 'Invalid ids' )
8492 Array . isArray ( ids ) || ( ids = [ ids ] )
8593 const currentIds = this . ids . slice ( )
8694
@@ -89,12 +97,16 @@ export default class RecordCollection {
8997 ids = ids . filter ( id => currentIds . indexOf ( id ) === - 1 )
9098 }
9199
92- if ( index == null ) {
93- return this . set ( currentIds . concat ( ids ) )
94- } else {
95- currentIds . splice ( index , 0 , ...ids )
96- return this . set ( currentIds )
100+ if ( ids . length ) {
101+ if ( index == null ) {
102+ this . set ( currentIds . concat ( ids ) )
103+ } else {
104+ currentIds . splice ( index , 0 , ...ids )
105+ this . set ( currentIds )
106+ }
97107 }
108+
109+ return this
98110 }
99111
100112 remove ( ids ) {
@@ -108,46 +120,49 @@ export default class RecordCollection {
108120 }
109121 } )
110122
111- return this . set ( updatedIds )
123+ if ( ids . length !== updatedIds . length ) {
124+ this . set ( updatedIds )
125+ }
126+
127+ return this
112128 }
113129
114130 clear ( ) {
115131 return this . set ( [ ] , { } )
116132 }
117133
118134 delete ( ) {
119- const { state } = this . table
120- let { collections } = state
135+ const tableState = this . table . state
136+ let { collections } = tableState
121137
122138 if ( collections && collections [ this . key ] ) {
123139 collections = { ...collections }
124140 delete collections [ this . key ]
125141
126- this . table . state = { ...state , collections }
142+ this . state = { }
143+ this . table . state = { ...tableState , collections }
127144 this . table . dirty = true
128145 }
129146 }
130147
131- _getProps ( ) {
132- return ( this . table . state . collections || { } ) [ this . key ] || { }
133- }
148+ _setProp ( key , value ) {
149+ if ( isEqual ( this . state [ key ] , value ) ) return
150+ const tableState = this . table . state
134151
135- _setProps ( props ) {
136- const { state } = this . table
137- const { collections = { } } = state
152+ this . state = { ...this . state , [ key ] : value }
138153
139154 this . table . state = {
140- ...state ,
155+ ...tableState ,
141156 collections : {
142- ...collections ,
143- [ this . key ] : {
144- ...collections [ this . key ] ,
145- ...props
146- }
157+ ...tableState . collections ,
158+ [ this . key ] : this . state
147159 }
148160 }
149161
150162 this . table . dirty = true
151- return this
152163 }
153164}
165+
166+ RecordCollection . prototype . find = sharedMethods . find
167+ RecordCollection . prototype . filter = sharedMethods . filter
168+
0 commit comments