@@ -19,13 +19,13 @@ const RelayProfiler = require('../util/RelayProfiler');
1919const RelayReader = require ( './RelayReader' ) ;
2020const RelayReferenceMarker = require ( './RelayReferenceMarker' ) ;
2121const RelayStoreReactFlightUtils = require ( './RelayStoreReactFlightUtils' ) ;
22+ const RelayStoreSubscriptions = require ( './RelayStoreSubscriptions' ) ;
2223const RelayStoreUtils = require ( './RelayStoreUtils' ) ;
2324
2425const deepFreeze = require ( '../util/deepFreeze' ) ;
2526const defaultGetDataID = require ( './defaultGetDataID' ) ;
2627const hasOverlappingIDs = require ( './hasOverlappingIDs' ) ;
2728const invariant = require ( 'invariant' ) ;
28- const isEmptyObject = require ( '../util/isEmptyObject' ) ;
2929const recycleNodesInto = require ( '../util/recycleNodesInto' ) ;
3030const resolveImmediate = require ( '../util/resolveImmediate' ) ;
3131
@@ -55,13 +55,6 @@ export opaque type InvalidationState = {|
5555 invalidations : Map < DataID , ?number> ,
5656| } ;
5757
58- type Subscription = { |
59- callback : ( snapshot : Snapshot ) => void ,
60- snapshot : Snapshot ,
61- stale : boolean ,
62- backup : ?Snapshot ,
63- | } ;
64-
6558type InvalidationSubscription = { |
6659 callback : ( ) => void ,
6760 invalidationState : InvalidationState ,
@@ -107,7 +100,7 @@ class RelayModernStore implements Store {
107100 | } ,
108101 > ;
109102 _shouldScheduleGC: boolean ;
110- _subscriptions: Set < Subscription > ;
103+ _storeSubscriptions: RelayStoreSubscriptions ;
111104 _updatedRecordIDs: UpdatedRecords ;
112105
113106 constructor (
@@ -150,7 +143,7 @@ class RelayModernStore implements Store {
150143 this . _releaseBuffer = [ ] ;
151144 this . _roots = new Map ( ) ;
152145 this . _shouldScheduleGC = false ;
153- this . _subscriptions = new Set ( ) ;
146+ this . _storeSubscriptions = new RelayStoreSubscriptions ( ) ;
154147 this . _updatedRecordIDs = { } ;
155148
156149 initializeRecordSource ( this . _recordSource ) ;
@@ -303,17 +296,11 @@ class RelayModernStore implements Store {
303296
304297 const source = this . getSource ( ) ;
305298 const updatedOwners = [ ] ;
306- const hasUpdatedRecords = ! isEmptyObject ( this . _updatedRecordIDs ) ;
307- this . _subscriptions . forEach ( subscription => {
308- const owner = this . _updateSubscription (
309- source ,
310- subscription ,
311- hasUpdatedRecords ,
312- ) ;
313- if ( owner != null ) {
314- updatedOwners . push ( owner ) ;
315- }
316- } ) ;
299+ this . _storeSubscriptions . updateSubscriptions (
300+ source ,
301+ this . _updatedRecordIDs ,
302+ updatedOwners ,
303+ ) ;
317304 this . _invalidationSubscriptions . forEach ( subscription => {
318305 this . _updateInvalidationSubscription (
319306 subscription ,
@@ -395,12 +382,7 @@ class RelayModernStore implements Store {
395382 snapshot : Snapshot ,
396383 callback : ( snapshot : Snapshot ) = > void ,
397384 ) : Disposable {
398- const subscription = { backup : null , callback, snapshot, stale : false } ;
399- const dispose = ( ) => {
400- this . _subscriptions . delete ( subscription ) ;
401- } ;
402- this . _subscriptions . add ( subscription ) ;
403- return { dispose } ;
385+ return this . _storeSubscriptions . subscribe ( snapshot , callback ) ;
404386 }
405387
406388 holdGC ( ) : Disposable {
@@ -430,43 +412,6 @@ class RelayModernStore implements Store {
430412 return this . _updatedRecordIDs ;
431413 }
432414
433- // Returns the owner (RequestDescriptor) if the subscription was affected by the
434- // latest update, or null if it was not affected.
435- _updateSubscription (
436- source : RecordSource ,
437- subscription : Subscription ,
438- hasUpdatedRecords : boolean ,
439- ) : ?RequestDescriptor {
440- const { backup, callback, snapshot, stale} = subscription ;
441- const hasOverlappingUpdates =
442- hasUpdatedRecords &&
443- hasOverlappingIDs ( snapshot . seenRecords , this . _updatedRecordIDs ) ;
444- if ( ! stale && ! hasOverlappingUpdates ) {
445- return;
446- }
447- let nextSnapshot : Snapshot =
448- hasOverlappingUpdates || ! backup
449- ? RelayReader . read ( source , snapshot . selector )
450- : backup ;
451- const nextData = recycleNodesInto ( snapshot . data , nextSnapshot . data ) ;
452- nextSnapshot = ( {
453- data : nextData ,
454- isMissingData : nextSnapshot . isMissingData ,
455- seenRecords : nextSnapshot . seenRecords ,
456- selector : nextSnapshot . selector ,
457- missingRequiredFields : nextSnapshot . missingRequiredFields ,
458- } : Snapshot ) ;
459- if ( __DEV__ ) {
460- deepFreeze ( nextSnapshot ) ;
461- }
462- subscription . snapshot = nextSnapshot ;
463- subscription . stale = false ;
464- if ( nextSnapshot . data !== snapshot . data ) {
465- callback ( nextSnapshot ) ;
466- return snapshot . selector . owner ;
467- }
468- }
469-
470415 lookupInvalidationState ( dataIDs : $ReadOnlyArray < DataID > ) : InvalidationState {
471416 const invalidations = new Map ( ) ;
472417 dataIDs . forEach ( dataID => {
@@ -546,29 +491,7 @@ class RelayModernStore implements Store {
546491 name : 'store.snapshot' ,
547492 } ) ;
548493 }
549- this . _subscriptions . forEach ( subscription => {
550- // Backup occurs after writing a new "final" payload(s) and before (re)applying
551- // optimistic changes. Each subscription's `snapshot` represents what was *last
552- // published to the subscriber*, which notably may include previous optimistic
553- // updates. Therefore a subscription can be in any of the following states:
554- // - stale=true: This subscription was restored to a different value than
555- // `snapshot`. That means this subscription has changes relative to its base,
556- // but its base has changed (we just applied a final payload): recompute
557- // a backup so that we can later restore to the state the subscription
558- // should be in.
559- // - stale=false: This subscription was restored to the same value than
560- // `snapshot`. That means this subscription does *not* have changes relative
561- // to its base, so the current `snapshot` is valid to use as a backup.
562- if ( ! subscription . stale ) {
563- subscription . backup = subscription . snapshot ;
564- return ;
565- }
566- const snapshot = subscription . snapshot ;
567- const backup = RelayReader . read ( this . getSource ( ) , snapshot . selector ) ;
568- const nextData = recycleNodesInto ( snapshot . data , backup . data ) ;
569- ( backup : $FlowFixMe ) . data = nextData ; // backup owns the snapshot and can safely mutate
570- subscription . backup = backup ;
571- } ) ;
494+ this . _storeSubscriptions . snapshotSubscriptions ( this . getSource ( ) ) ;
572495 if ( this . _gcRun ) {
573496 this . _gcRun = null ;
574497 this . _shouldScheduleGC = true ;
@@ -594,24 +517,7 @@ class RelayModernStore implements Store {
594517 if ( this . _shouldScheduleGC ) {
595518 this . scheduleGC ( ) ;
596519 }
597- this . _subscriptions . forEach ( subscription => {
598- const backup = subscription . backup ;
599- subscription . backup = null ;
600- if ( backup ) {
601- if ( backup . data !== subscription . snapshot . data ) {
602- subscription . stale = true ;
603- }
604- subscription . snapshot = {
605- data : subscription . snapshot . data ,
606- isMissingData : backup . isMissingData ,
607- seenRecords : backup . seenRecords ,
608- selector : backup . selector ,
609- missingRequiredFields : backup . missingRequiredFields ,
610- } ;
611- } else {
612- subscription . stale = true ;
613- }
614- } ) ;
520+ this . _storeSubscriptions . restoreSubscriptions ( ) ;
615521 }
616522
617523 scheduleGC ( ) {
0 commit comments