@@ -17,6 +17,7 @@ type Person = {
1717 age : number
1818 email : string
1919 isActive : boolean
20+ team : string
2021}
2122
2223type Issue = {
@@ -33,20 +34,23 @@ const initialPersons: Array<Person> = [
3334 age : 30 ,
3435 email : `john.doe@example.com` ,
3536 isActive : true ,
37+ team : `team1` ,
3638 } ,
3739 {
3840 id : `2` ,
3941 name : `Jane Doe` ,
4042 age : 25 ,
4143 email : `jane.doe@example.com` ,
4244 isActive : true ,
45+ team : `team2` ,
4346 } ,
4447 {
4548 id : `3` ,
4649 name : `John Smith` ,
4750 age : 35 ,
4851 email : `john.smith@example.com` ,
4952 isActive : true ,
53+ team : `team1` ,
5054 } ,
5155]
5256
@@ -592,6 +596,116 @@ describe(`Query Collections`, () => {
592596 // Restore console.log
593597 console . log = originalConsoleLog
594598 } )
599+
600+ it ( `should be able to query a result collection` , async ( ) => {
601+ const emitter = mitt ( )
602+
603+ // Create collection with mutation capability
604+ const collection = new Collection < Person > ( {
605+ id : `optimistic-changes-test` ,
606+ sync : {
607+ sync : ( { begin, write, commit } ) => {
608+ // Listen for sync events
609+ emitter . on ( `*` , ( _ , changes ) => {
610+ begin ( )
611+ ; ( changes as Array < PendingMutation > ) . forEach ( ( change ) => {
612+ write ( {
613+ key : change . key ,
614+ type : change . type ,
615+ value : change . changes as Person ,
616+ } )
617+ } )
618+ commit ( )
619+ } )
620+ } ,
621+ } ,
622+ } )
623+
624+ // Sync from initial state
625+ act ( ( ) => {
626+ emitter . emit (
627+ `sync` ,
628+ initialPersons . map ( ( person ) => ( {
629+ key : person . id ,
630+ type : `insert` ,
631+ changes : person ,
632+ } ) )
633+ )
634+ } )
635+
636+ // Initial query
637+ const { result } = renderHook ( ( ) => {
638+ return useLiveQuery ( ( q ) =>
639+ q
640+ . from ( { collection } )
641+ . where ( `@age` , `>` , 30 )
642+ . keyBy ( `@id` )
643+ . select ( `@id` , `@name` , `@team` )
644+ . orderBy ( { "@id" : `asc` } )
645+ )
646+ } )
647+
648+ // Grouped query derived from initial query
649+ const { result : groupedResult } = renderHook ( ( ) => {
650+ return useLiveQuery ( ( q ) =>
651+ q
652+ . from ( { queryResult : result . current . collection } )
653+ . groupBy ( `@team` )
654+ . keyBy ( `@team` )
655+ . select ( `@team` , { count : { COUNT : `@id` } } )
656+ )
657+ } )
658+
659+ // Verify initial grouped results
660+ expect ( groupedResult . current . state . size ) . toBe ( 1 )
661+ expect ( groupedResult . current . state . get ( `team1` ) ) . toEqual ( {
662+ team : `team1` ,
663+ count : 1 ,
664+ } )
665+
666+ // Insert two new users in different teams
667+ act ( ( ) => {
668+ emitter . emit ( `sync` , [
669+ {
670+ key : `5` ,
671+ type : `insert` ,
672+ changes : {
673+ id : `5` ,
674+ name : `Sarah Jones` ,
675+ age : 32 ,
676+ email : `sarah.jones@example.com` ,
677+ isActive : true ,
678+ team : `team1` ,
679+ } ,
680+ } ,
681+ {
682+ key : `6` ,
683+ type : `insert` ,
684+ changes : {
685+ id : `6` ,
686+ name : `Mike Wilson` ,
687+ age : 38 ,
688+ email : `mike.wilson@example.com` ,
689+ isActive : true ,
690+ team : `team2` ,
691+ } ,
692+ } ,
693+ ] )
694+ } )
695+
696+ await waitForChanges ( )
697+
698+ // Verify the grouped results include the new team members
699+ expect ( groupedResult . current . state . size ) . toBe ( 2 )
700+ expect ( groupedResult . current . state . get ( `team1` ) ) . toEqual ( {
701+ team : `team1` ,
702+ count : 2 ,
703+ } )
704+ expect ( groupedResult . current . state . get ( `team2` ) ) . toEqual ( {
705+ team : `team2` ,
706+ count : 1 ,
707+ } )
708+ } )
595709} )
596710
597711async function waitForChanges ( ms = 0 ) {
0 commit comments