@@ -2481,4 +2481,112 @@ describe(`Query Collections`, () => {
24812481 } )
24822482 } )
24832483 } )
2484+
2485+ describe ( `includes subqueries` , ( ) => {
2486+ type Project = {
2487+ id : string
2488+ name : string
2489+ }
2490+
2491+ type ProjectIssue = {
2492+ id : string
2493+ title : string
2494+ projectId : string
2495+ }
2496+
2497+ const sampleProjects : Array < Project > = [
2498+ { id : `p1` , name : `Alpha` } ,
2499+ { id : `p2` , name : `Beta` } ,
2500+ ]
2501+
2502+ const sampleProjectIssues : Array < ProjectIssue > = [
2503+ { id : `i1` , title : `Bug in Alpha` , projectId : `p1` } ,
2504+ { id : `i2` , title : `Feature for Alpha` , projectId : `p1` } ,
2505+ { id : `i3` , title : `Bug in Beta` , projectId : `p2` } ,
2506+ ]
2507+
2508+ it ( `should render includes results and reactively update child collections` , async ( ) => {
2509+ const projectsCollection = createCollection (
2510+ mockSyncCollectionOptions < Project > ( {
2511+ id : `includes-react-projects` ,
2512+ getKey : ( p ) => p . id ,
2513+ initialData : sampleProjects ,
2514+ } ) ,
2515+ )
2516+
2517+ const issuesCollection = createCollection (
2518+ mockSyncCollectionOptions < ProjectIssue > ( {
2519+ id : `includes-react-issues` ,
2520+ getKey : ( i ) => i . id ,
2521+ initialData : sampleProjectIssues ,
2522+ } ) ,
2523+ )
2524+
2525+ // Parent hook: runs includes query that produces child Collections
2526+ const { result : parentResult } = renderHook ( ( ) =>
2527+ useLiveQuery ( ( q ) =>
2528+ q . from ( { p : projectsCollection } ) . select ( ( { p } ) => ( {
2529+ id : p . id ,
2530+ name : p . name ,
2531+ issues : q
2532+ . from ( { i : issuesCollection } )
2533+ . where ( ( { i } ) => eq ( i . projectId , p . id ) )
2534+ . select ( ( { i } ) => ( {
2535+ id : i . id ,
2536+ title : i . title ,
2537+ } ) ) ,
2538+ } ) ) ,
2539+ ) ,
2540+ )
2541+
2542+ // Wait for parent to be ready
2543+ await waitFor ( ( ) => {
2544+ expect ( parentResult . current . data ) . toHaveLength ( 2 )
2545+ } )
2546+
2547+ const alphaProject = parentResult . current . data . find (
2548+ ( p : any ) => p . id === `p1` ,
2549+ ) !
2550+ expect ( alphaProject . name ) . toBe ( `Alpha` )
2551+
2552+ // Child hook: subscribes to the child Collection from the parent row,
2553+ // simulating a subcomponent using useLiveQuery(project.issues)
2554+ const { result : childResult } = renderHook ( ( ) =>
2555+ useLiveQuery ( ( alphaProject as any ) . issues ) ,
2556+ )
2557+
2558+ await waitFor ( ( ) => {
2559+ expect ( childResult . current . data ) . toHaveLength ( 2 )
2560+ } )
2561+
2562+ expect ( childResult . current . data ) . toEqual (
2563+ expect . arrayContaining ( [
2564+ expect . objectContaining ( { id : `i1` , title : `Bug in Alpha` } ) ,
2565+ expect . objectContaining ( { id : `i2` , title : `Feature for Alpha` } ) ,
2566+ ] ) ,
2567+ )
2568+
2569+ // Add a new issue to Alpha — the child hook should reactively update
2570+ act ( ( ) => {
2571+ issuesCollection . utils . begin ( )
2572+ issuesCollection . utils . write ( {
2573+ type : `insert` ,
2574+ value : { id : `i4` , title : `New Alpha issue` , projectId : `p1` } ,
2575+ } )
2576+ issuesCollection . utils . commit ( )
2577+ } )
2578+
2579+ await waitFor ( ( ) => {
2580+ expect ( childResult . current . data ) . toHaveLength ( 3 )
2581+ } )
2582+
2583+ expect ( childResult . current . data ) . toEqual (
2584+ expect . arrayContaining ( [
2585+ expect . objectContaining ( { id : `i1` , title : `Bug in Alpha` } ) ,
2586+ expect . objectContaining ( { id : `i2` , title : `Feature for Alpha` } ) ,
2587+ expect . objectContaining ( { id : `i4` , title : `New Alpha issue` } ) ,
2588+ ] ) ,
2589+ )
2590+ } )
2591+ } )
24842592} )
0 commit comments