@@ -7,9 +7,14 @@ const types = {
77}
88
99export default function ( ComposeAPI ) {
10+ // Records are keyed by moduleID + recordID, not recordID alone: modules backed
11+ // by external databases can reuse the same (int) recordID across different
12+ // modules, so a bare recordID is not a unique key across the shared set.
13+ const recordKey = ( moduleID , recordID ) => `${ moduleID } /${ recordID } `
14+
1015 // Batching state for resolveRecords (shared across all dispatches)
1116 const pendingBatches = new Map ( ) // key: `${namespaceID}/${moduleID}` -> { ids, resolvers, namespaceID, moduleID }
12- const inflightIDs = new Set ( )
17+ const inflightKeys = new Set ( ) // moduleID/recordID keys currently being fetched
1318 let flushTimer = null
1419
1520 function flushResolves ( commit ) {
@@ -24,7 +29,7 @@ export default function (ComposeAPI) {
2429 continue
2530 }
2631
27- recordIDs . forEach ( id => inflightIDs . add ( id ) )
32+ recordIDs . forEach ( id => inflightKeys . add ( recordKey ( moduleID , id ) ) )
2833 commit ( types . pending )
2934
3035 const query = recordIDs . map ( id => `recordID = ${ id } ` ) . join ( ' OR ' )
@@ -34,7 +39,7 @@ export default function (ComposeAPI) {
3439 commit ( types . updateSet , set )
3540 } )
3641 . finally ( ( ) => {
37- recordIDs . forEach ( id => inflightIDs . delete ( id ) )
42+ recordIDs . forEach ( id => inflightKeys . delete ( recordKey ( moduleID , id ) ) )
3843 commit ( types . completed )
3944 resolvers . forEach ( r => r ( ) )
4045 } )
@@ -53,13 +58,19 @@ export default function (ComposeAPI) {
5358 pending : ( state ) => state . pending ,
5459
5560 findByID ( state ) {
56- return ( ID ) => state . set . find ( ( { recordID } ) => ID === recordID )
61+ // moduleID is optional for backwards compatibility, but should be passed
62+ // whenever known to disambiguate records that share a recordID across modules
63+ return ( ID , moduleID = undefined ) => state . set . find (
64+ ( r ) => ID === r . recordID && ( moduleID === undefined || r . moduleID === moduleID ) ,
65+ )
5766 } ,
5867
5968 findByIDs ( state ) {
60- return ( IDs ) => {
69+ return ( IDs , moduleID = undefined ) => {
6170 const idSet = new Set ( IDs . flat ( ) )
62- return state . set . filter ( ( { recordID } ) => idSet . has ( recordID ) )
71+ return state . set . filter (
72+ ( r ) => idSet . has ( r . recordID ) && ( moduleID === undefined || r . moduleID === moduleID ) ,
73+ )
6374 }
6475 } ,
6576
@@ -82,9 +93,13 @@ export default function (ComposeAPI) {
8293 return Promise . resolve ( )
8394 }
8495
85- // Filter out records already in the store or currently being fetched
86- const knownIDs = new Set ( getters . set . map ( ( { recordID } ) => recordID ) )
87- recordIDs = recordIDs . filter ( id => ! knownIDs . has ( id ) && ! inflightIDs . has ( id ) )
96+ // Filter out records already in the store or currently being fetched.
97+ // Scope "known" to this module so a matching recordID in another module
98+ // doesn't mask a record we still need to fetch here.
99+ const knownIDs = new Set (
100+ getters . set . filter ( ( { moduleID : mID } ) => mID === moduleID ) . map ( ( { recordID } ) => recordID ) ,
101+ )
102+ recordIDs = recordIDs . filter ( id => ! knownIDs . has ( id ) && ! inflightKeys . has ( recordKey ( moduleID , id ) ) )
88103
89104 if ( recordIDs . length === 0 ) {
90105 return Promise . resolve ( )
@@ -142,17 +157,19 @@ export default function (ComposeAPI) {
142157 return
143158 }
144159
145- // Build index map for O(1) lookups
146- const indexByID = new Map ( state . set . map ( ( { recordID } , i ) => [ recordID , i ] ) )
160+ // Build index map for O(1) lookups, keyed by moduleID+recordID so records
161+ // from different modules that share a recordID don't overwrite each other
162+ const indexByKey = new Map ( state . set . map ( ( r , i ) => [ recordKey ( r . moduleID , r . recordID ) , i ] ) )
147163
148164 set . forEach ( newItem => {
149165 newItem = JSON . parse ( JSON . stringify ( newItem ) )
150166
151- const oldIndex = indexByID . get ( newItem . recordID )
167+ const key = recordKey ( newItem . moduleID , newItem . recordID )
168+ const oldIndex = indexByKey . get ( key )
152169 if ( oldIndex !== undefined ) {
153170 state . set . splice ( oldIndex , 1 , newItem )
154171 } else {
155- indexByID . set ( newItem . recordID , state . set . length )
172+ indexByKey . set ( key , state . set . length )
156173 state . set . push ( newItem )
157174 }
158175 } )
@@ -163,7 +180,7 @@ export default function (ComposeAPI) {
163180 state . set . splice ( 0 )
164181
165182 // Clean up batching state
166- inflightIDs . clear ( )
183+ inflightKeys . clear ( )
167184 clearTimeout ( flushTimer )
168185 pendingBatches . clear ( )
169186 } ,
0 commit comments