11import type { DocHandle , Patch } from '@automerge/automerge-repo' ;
22import * as Schema from 'effect/Schema' ;
3- import { type QueryEntry , decodedEntitiesCache } from './decodedEntitiesCache.js' ;
3+ import { type DecodedEntitiesCacheEntry , type QueryEntry , decodedEntitiesCache } from './decodedEntitiesCache.js' ;
4+ import { entityRelationParentsMap } from './entityRelationParentsMap.js' ;
45import { getEntityRelations } from './getEntityRelations.js' ;
56import { hasValidTypesProperty } from './hasValidTypesProperty.js' ;
67import { isReferenceField } from './isReferenceField.js' ;
7- import { relationParentQueries } from './relationParentQueries.js' ;
88import type { AnyNoContext , DocumentContent , Entity } from './types.js' ;
99
1010const documentChangeListener : {
@@ -44,7 +44,7 @@ const subscribeToDocumentChanges = (handle: DocHandle<DocumentContent>) => {
4444 // reference to reduce the amount of O(n) operations per query to 1
4545 const touchedQueries = new Set < Array < string > > ( ) ;
4646
47- const touchedRelationParentQueries = new Set < QueryEntry > ( ) ;
47+ const touchedRelationParents = new Set < DecodedEntitiesCacheEntry > ( ) ;
4848
4949 // loop over all changed entities and update the cache
5050 for ( const entityId of changedEntities ) {
@@ -77,27 +77,27 @@ const subscribeToDocumentChanges = (handle: DocHandle<DocumentContent>) => {
7777 for ( const [ key , value ] of Object . entries ( decoded ) ) {
7878 if ( Array . isArray ( value ) ) {
7979 for ( const relationEntity of value ) {
80- let relationParentQueriesEntry = relationParentQueries . get ( relationEntity . id ) ;
81- if ( ! relationParentQueriesEntry ) {
82- relationParentQueriesEntry = [ ] ;
83- relationParentQueries . set ( relationEntity . id , relationParentQueriesEntry ) ;
80+ let relationParentEntry = entityRelationParentsMap . get ( relationEntity . id ) ;
81+ if ( ! relationParentEntry ) {
82+ relationParentEntry = [ ] ;
83+ entityRelationParentsMap . set ( relationEntity . id , relationParentEntry ) ;
8484 }
8585
86- relationParentQueriesEntry . push ( query ) ;
86+ relationParentEntry . push ( cacheEntry ) ;
8787 }
8888 }
8989 }
9090 }
9191
9292 entityTypes . add ( typeName ) ;
9393
94- // gather all the queries of impacted parent relation queries
95- if ( relationParentQueries . has ( entityId ) ) {
96- const queries = relationParentQueries . get ( entityId ) ;
97- if ( ! queries ) return ;
94+ // gather all the decodedEntitiesCacheEntries
95+ if ( entityRelationParentsMap . has ( entityId ) ) {
96+ const decodedEntitiesCacheEntries = entityRelationParentsMap . get ( entityId ) ;
97+ if ( ! decodedEntitiesCacheEntries ) return ;
9898
99- for ( const query of queries ) {
100- touchedRelationParentQueries . add ( query ) ;
99+ for ( const entry of decodedEntitiesCacheEntries ) {
100+ touchedRelationParents . add ( entry ) ;
101101 }
102102 }
103103 }
@@ -122,12 +122,12 @@ const subscribeToDocumentChanges = (handle: DocHandle<DocumentContent>) => {
122122 }
123123
124124 // gather all the queries of impacted parent relation queries
125- if ( relationParentQueries . has ( entityId ) ) {
126- const queries = relationParentQueries . get ( entityId ) ;
127- if ( ! queries ) return ;
125+ if ( entityRelationParentsMap . has ( entityId ) ) {
126+ const decodedEntitiesCacheEntries = entityRelationParentsMap . get ( entityId ) ;
127+ if ( ! decodedEntitiesCacheEntries ) return ;
128128
129- for ( const query of queries ) {
130- touchedRelationParentQueries . add ( query ) ;
129+ for ( const entry of decodedEntitiesCacheEntries ) {
130+ touchedRelationParents . add ( entry ) ;
131131 }
132132 }
133133 }
@@ -156,10 +156,13 @@ const subscribeToDocumentChanges = (handle: DocHandle<DocumentContent>) => {
156156
157157 // trigger all the listeners of the parent relation queries
158158 // TODO: align with the touchedQueries to avoid unnecessary trigger calls
159- for ( const query of touchedRelationParentQueries ) {
160- query . isInvalidated = true ;
161- for ( const listener of query . listeners ) {
162- listener ( ) ;
159+ for ( const decodedEntitiesCacheEntry of touchedRelationParents ) {
160+ decodedEntitiesCacheEntry . isInvalidated = true ;
161+ for ( const query of decodedEntitiesCacheEntry . queries . values ( ) ) {
162+ query . isInvalidated = true ;
163+ for ( const listener of query . listeners ) {
164+ listener ( ) ;
165+ }
163166 }
164167 }
165168 } ;
@@ -218,10 +221,11 @@ export function subscribeToFindMany<const S extends AnyNoContext>(
218221
219222 const getEntities = ( ) => {
220223 const cacheEntry = decodedEntitiesCache . get ( typeName ) ;
221- const query = cacheEntry ?. queries . get ( queryKey ) ;
224+ if ( ! cacheEntry ) return stableEmptyArray ;
225+ const query = cacheEntry . queries . get ( queryKey ) ;
222226 if ( ! query ) return stableEmptyArray ;
223227
224- if ( ! query . isInvalidated ) {
228+ if ( ! cacheEntry . isInvalidated && ! query . isInvalidated ) {
225229 return query . data ;
226230 }
227231
@@ -239,17 +243,18 @@ export function subscribeToFindMany<const S extends AnyNoContext>(
239243 }
240244 }
241245
246+ cacheEntry . isInvalidated = false ;
242247 query . isInvalidated = false ;
243248 return query . data ;
244249 } ;
245250
246251 if ( ! decodedEntitiesCache . has ( typeName ) ) {
247252 const entities = findMany ( handle , type ) ;
248253 const entitiesMap = new Map ( ) ;
249- const relationParentQueries = new Map ( ) ;
254+ const relationParent = new Map ( ) ;
250255 for ( const entity of entities ) {
251256 entitiesMap . set ( entity . id , entity ) ;
252- relationParentQueries . set ( entity . id , new Map ( ) ) ;
257+ relationParent . set ( entity . id , new Map ( ) ) ;
253258 }
254259
255260 const queries = new Map < string , QueryEntry > ( ) ;
@@ -265,6 +270,7 @@ export function subscribeToFindMany<const S extends AnyNoContext>(
265270 type,
266271 entities : entitiesMap ,
267272 queries,
273+ isInvalidated : false ,
268274 } ) ;
269275 }
270276
@@ -281,26 +287,20 @@ export function subscribeToFindMany<const S extends AnyNoContext>(
281287 const typeName = type . name ;
282288 const entities = findMany ( handle , type ) ;
283289
284- if ( decodedEntitiesCache . has ( typeName ) ) {
285- // add a listener to the existing query
286- const cacheEntry = decodedEntitiesCache . get ( typeName ) ;
287-
288- for ( const entity of entities ) {
289- cacheEntry ?. entities . set ( entity . id , entity ) ;
290- }
291- } else {
290+ if ( ! decodedEntitiesCache . has ( typeName ) ) {
292291 const entitiesMap = new Map ( ) ;
293- const relationParentQueries = new Map ( ) ;
292+ const relationParent = new Map ( ) ;
294293 for ( const entity of entities ) {
295294 entitiesMap . set ( entity . id , entity ) ;
296- relationParentQueries . set ( entity . id , new Map ( ) ) ;
295+ relationParent . set ( entity . id , new Map ( ) ) ;
297296 }
298297
299298 decodedEntitiesCache . set ( typeName , {
300299 decoder : decode ,
301300 type,
302301 entities : entitiesMap ,
303302 queries : new Map ( ) ,
303+ isInvalidated : false ,
304304 } ) ;
305305 }
306306 }
0 commit comments