1+ import React from 'react' ;
2+
13import type { Reducer , Selector } from '@reduxjs/toolkit' ;
24import { createSelector } from '@reduxjs/toolkit' ;
35
@@ -51,61 +53,60 @@ export const schemaApi = api.injectEndpoints({
5153 }
5254 } ,
5355 } ) ,
54- getSchema : builder . query < TEvDescribeSchemeResult & { partial ?: boolean } , { path : string } > ( {
56+ getSchema : builder . query <
57+ { [ path : string ] : TEvDescribeSchemeResult & { partial ?: boolean } } ,
58+ { path : string }
59+ > ( {
5560 queryFn : async ( { path} , { signal} ) => {
5661 try {
5762 const data = await window . api . getSchema ( { path} , { signal} ) ;
58- return { data : data ?? { } } ;
63+ return { data : data ? { [ path ] : data , ... getSchemaChildren ( data ) } : { } } ;
5964 } catch ( error ) {
6065 return { error} ;
6166 }
6267 } ,
6368 keepUnusedDataFor : Infinity ,
64- forceRefetch : ( { endpointState} ) => {
65- const data = endpointState ?. data ;
66- if ( data && typeof data === 'object' && 'partial' in data && data . partial ) {
67- return true ;
68- }
69- return false ;
69+ serializeQueryArgs : ( { queryArgs : { path} } ) => {
70+ const parts = path . split ( '/' ) ;
71+ return { path : parts [ 0 ] || parts [ 1 ] } ;
7072 } ,
71- onQueryStarted : async ( { path } , { dispatch , getState , queryFulfilled } ) => {
72- const { data} = await queryFulfilled ;
73+ merge : ( existing , incoming , { arg : { path } } ) => {
74+ const { [ path ] : data , ... children } = incoming ;
7375 if ( data ) {
74- const state = getState ( ) ;
75- const { PathDescription : { Children = [ ] } = { } } = data ;
76- for ( const child of Children ) {
77- const { Name = '' } = child ;
78- const childPath = `${ path } /${ Name } ` ;
79- const cachedData = schemaApi . endpoints . getSchema . select ( { path : childPath } ) (
80- state ,
81- ) . data ;
82- if ( ! cachedData ) {
83- // not full data, but it contains PathType, which ensures seamless switch between nodes
84- dispatch (
85- schemaApi . util . upsertQueryData (
86- 'getSchema' ,
87- { path : childPath } ,
88- { PathDescription : { Self : child } , partial : true } ,
89- ) ,
90- ) ;
91- }
92- }
76+ return {
77+ ...children ,
78+ ...existing ,
79+ [ path ] : data ,
80+ } ;
9381 }
82+ return existing ;
9483 } ,
9584 } ) ,
9685 } ) ,
9786 overrideExisting : 'throw' ,
9887} ) ;
9988
89+ function getSchemaChildren ( data : TEvDescribeSchemeResult ) {
90+ const children : { [ path : string ] : TEvDescribeSchemeResult & { partial ?: boolean } } = { } ;
91+ const { PathDescription : { Children = [ ] } = { } , Path : path } = data ;
92+ for ( const child of Children ) {
93+ const { Name = '' } = child ;
94+ const childPath = `${ path } /${ Name } ` ;
95+ children [ childPath ] = { PathDescription : { Self : child } , Path : childPath , partial : true } ;
96+ }
97+ return children ;
98+ }
99+
100100const getSchemaSelector = createSelector (
101101 ( path : string ) => path ,
102102 ( path ) => schemaApi . endpoints . getSchema . select ( { path} ) ,
103103) ;
104104
105105const selectGetSchema = createSelector (
106106 ( state : RootState ) => state ,
107+ ( _state : RootState , path : string ) => path ,
107108 ( _state : RootState , path : string ) => getSchemaSelector ( path ) ,
108- ( state , selectTabletsInfo ) => selectTabletsInfo ( state ) . data ,
109+ ( state , path , selectTabletsInfo ) => selectTabletsInfo ( state ) . data ?. [ path ] ,
109110) ;
110111
111112const selectSchemaChildren = ( state : RootState , path : string ) =>
@@ -127,3 +128,19 @@ export const selectSchemaMergedChildrenPaths: Selector<
127128 : undefined ;
128129 } ,
129130) ;
131+
132+ export function useGetSchemaQuery ( { path} : { path : string } ) {
133+ const { currentData, isFetching, error, refetch} = schemaApi . useGetSchemaQuery ( { path} ) ;
134+
135+ const data = currentData ?. [ path ] ;
136+ const isLoading = isFetching && data === undefined ;
137+
138+ const shouldLoad = ! isLoading && ( ( ! data && ! error ) || data ?. partial ) ;
139+ React . useEffect ( ( ) => {
140+ if ( shouldLoad ) {
141+ refetch ( ) ;
142+ }
143+ } , [ refetch , path , shouldLoad ] ) ;
144+
145+ return { data, isLoading, error} ;
146+ }
0 commit comments