@@ -77,16 +77,16 @@ export default class Dispatcher extends Scuttlebutt {
7777
7878 this . _isGossipType = this . options . isGossipType
7979
80- // history of all current updates
81- // timestamp-source-sorted for time travel and replay
82- this . _updates = [ ]
8380
8481 // redux methods to wrap
8582 this . _reduxDispatch = ( ) => {
8683 throw new Error ( 'Are you sure you called wrapDispatch?' )
8784 }
8885 this . _reduxGetState = ( ) => {
89- throw new Error ( 'Are you sure you called wrapGetState?' )
86+ // throw new Error('Are you sure you called wrapGetState?')
87+ // this must return a default state for the very first history call,
88+ // before .wrapGetState has been applied in the store enhancer.
89+ return [ ]
9090 }
9191 }
9292
@@ -131,44 +131,50 @@ export default class Dispatcher extends Scuttlebutt {
131131 // implemented for scuttlebutt class
132132 applyUpdate ( update ) {
133133 const [ action , timestamp , source ] = update ,
134- // add our metadata to the action
135- localAction = {
136- ...action ,
137- meta : {
138- ...action . meta ,
139- [ META_TIMESTAMP ] : timestamp ,
140- [ META_SOURCE ] : source
134+ // copy the object so we can modify its properties later
135+ localAction = { meta : { } , ...action } ,
136+ dispatch = ( shouldApply ) => {
137+ if ( ! shouldApply ) {
138+ return
139+ } else if ( this . _customDispatch ) {
140+ this . _customDispatch ( localAction )
141+ } else {
142+ this . _reduxDispatch ( localAction )
141143 }
142144 }
143145
144- // we log all updates to emit in the order we saw them.
145- // not sure if it's better than replaying in order of timestamp (which might
146- // cut down on the amount of time travelling done by all peers), but seems
147- // like the de facto for scuttlebutt models
148- this . _updates . push ( update )
149-
150- // this could be sped up by only sorting as far as the new update
151- this . _updates . sort ( ( a , b ) => orderedHistory . sort (
152- a [ UPDATE_TIMESTAMP ] , b [ UPDATE_TIMESTAMP ] ,
153- a [ UPDATE_SOURCE ] , b [ UPDATE_SOURCE ]
154- ) )
146+ // add our metadata to the action as non-enumerable properties
147+ Object . defineProperty ( localAction . meta , META_TIMESTAMP , {
148+ enumerable : false ,
149+ value : timestamp
150+ } )
151+ Object . defineProperty ( localAction . meta , META_SOURCE , {
152+ enumerable : false ,
153+ value : source
154+ } )
155155
156- if ( this . _customDispatch ) {
157- this . _customDispatch ( localAction )
158- } else {
159- this . _reduxDispatch ( localAction )
160- }
156+ dispatch ( true )
161157
162158 // recieved message succesfully. if false, peers may retry the message.
163159 return true
164160 }
165161
166- // gossip
162+ // reply to gossip with the latest timestamps for the sources we've seen
167163 // implemented for scuttlebutt class
168164 history ( sources ) {
169- return this . _updates . filter ( function ( update ) {
170- return filter ( update , sources )
171- } )
165+ // our state (updates[]) has a similar shape to scuttlebutt's own updates.
166+ return this . _reduxGetState ( ) . reduce ( ( arr , update ) => {
167+ if (
168+ update [ UPDATE_ACTION ]
169+ && this . _isGossipType ( update [ UPDATE_ACTION ] . type )
170+ && filter ( update , sources )
171+ ) {
172+ // scuttlebutt only wants ACTION, TIMESTAMP, SOURCE, and not: SNAPSHOT
173+ arr . push ( update . slice ( 0 , 3 ) )
174+ }
175+
176+ return arr
177+ } , [ ] )
172178 }
173179
174180 // apply an update locally
@@ -186,23 +192,4 @@ export default class Dispatcher extends Scuttlebutt {
186192 super . localUpdate ( action )
187193 }
188194 }
189-
190- // super.localUpdate(this._filterUpdate(action))
191- // Recurse through the value and attempt to prune unserializable leaf objects.
192- // A well-structured app won't be dispatching bad actions like this, so
193- // this might become a dev-only check. also, it's far from foolproof.
194- _filterUpdate ( value ) {
195- if ( typeof value !== 'object' )
196- return value
197-
198- if ( value && value . constructor
199- && / ( ^ S y n t h e t i c | E v e n t $ ) / . test ( value . constructor . name ) )
200- return null
201-
202- const result = { }
203- for ( const prop in value ) {
204- result [ prop ] = this . _filterUpdate ( value [ prop ] ) ;
205- }
206- return result
207- }
208195}
0 commit comments