@@ -25,15 +25,53 @@ interface Context {
2525 current : Record < PartID , Query | undefined > ;
2626}
2727
28+ const revisions = new Map < string , string > ( ) ;
29+
30+ const deepEqualResourceNames = (
31+ a : ResourceName [ ] ,
32+ b : ResourceName [ ]
33+ ) : boolean => {
34+ if ( a . length !== b . length ) {
35+ return false ;
36+ }
37+
38+ return a . every ( ( item , i ) => JSON . stringify ( item ) === JSON . stringify ( b [ i ] ) ) ;
39+ } ;
40+
41+ /**
42+ * sorts resource names by local/remote -> type -> name (alphabetical)
43+ * to produce a list like:
44+ *
45+ * component a
46+ * component z
47+ * service b
48+ * component remote:c
49+ * service remote:b
50+ * @param resourceNames
51+ */
52+ const sortResourceNames = ( resourceNames : ResourceName [ ] ) => {
53+ resourceNames . sort ( ( { type, name } , { type : otherType , name : otherName } ) => {
54+ // sort all non-remote resources before remote resources
55+ if ( name . includes ( ':' ) !== otherName . includes ( ':' ) ) {
56+ return name . includes ( ':' ) ? 1 : - 1 ;
57+ }
58+
59+ // sort alphabetically within type
60+ // sort components before services
61+ return type === otherType
62+ ? name . localeCompare ( otherName )
63+ : type . localeCompare ( otherType ) ;
64+ } ) ;
65+ } ;
66+
2867export const provideResourceNamesContext = ( ) => {
2968 const machineStatuses = useMachineStatuses ( ) ;
3069 const clients = useRobotClients ( ) ;
3170
71+ const partIDs = $derived ( Object . keys ( clients . current ) ) ;
3272 const options = $derived (
33- Object . entries ( clients . current ) . map ( ( [ partID , client ] ) => {
34- const revision =
35- machineStatuses . current [ partID ] ?. data ?. config ?. revision ?? '' ;
36-
73+ partIDs . map ( ( partID ) => {
74+ const client = clients . current [ partID ] ;
3775 return queryOptions ( {
3876 enabled : client !== undefined ,
3977 queryKey : [
@@ -42,14 +80,16 @@ export const provideResourceNamesContext = () => {
4280 partID ,
4381 'robotClient' ,
4482 'resourceNames' ,
45- revision ,
4683 ] ,
84+ staleTime : Infinity ,
4785 queryFn : async ( ) => {
4886 if ( ! client ) {
4987 throw new Error ( 'No client' ) ;
5088 }
5189
52- return client . resourceNames ( ) ;
90+ const resourceNames = await client . resourceNames ( ) ;
91+ sortResourceNames ( resourceNames ) ;
92+ return resourceNames ;
5393 } ,
5494 } ) ;
5595 } )
@@ -58,18 +98,40 @@ export const provideResourceNamesContext = () => {
5898 const queries = fromStore (
5999 createQueries ( {
60100 queries : toStore ( ( ) => options ) ,
61- combine : ( results ) => {
62- const partIDs = Object . keys ( clients . current ) ;
63- return Object . fromEntries (
64- results . map ( ( result , index ) => [ partIDs [ index ] , result ] )
65- ) ;
66- } ,
67101 } )
68102 ) ;
69103
104+ /**
105+ * Individually refetch part resource names based on revision
106+ */
107+ $effect ( ( ) => {
108+ let index = 0 ;
109+
110+ for ( const partID of partIDs ) {
111+ const revision =
112+ machineStatuses . current [ partID ] ?. data ?. config ?. revision ?? '' ;
113+ const lastRevision = revisions . get ( partID ) ;
114+ revisions . set ( partID , revision ) ;
115+
116+ if ( ! lastRevision ) continue ;
117+
118+ if ( revision !== lastRevision ) {
119+ queries . current [ index ] ?. refetch ( ) ;
120+ }
121+
122+ index += 1 ;
123+ }
124+ } ) ;
125+
126+ const current = $derived (
127+ Object . fromEntries (
128+ queries . current . map ( ( result , index ) => [ partIDs [ index ] , result ] )
129+ )
130+ ) ;
131+
70132 setContext < Context > ( key , {
71133 get current ( ) {
72- return queries . current ;
134+ return current ;
73135 } ,
74136 } ) ;
75137} ;
@@ -84,15 +146,26 @@ export const useResourceNames = (
84146 const resourceSubtype = $derived (
85147 typeof subtype === 'function' ? subtype ( ) : subtype
86148 ) ;
149+ const error = $derived ( query ?. error ?? undefined ) ;
150+ const fetching = $derived ( query ?. isFetching ?? true ) ;
151+
87152 const filtered = $derived (
88153 subtype ? data . filter ( ( value ) => value . subtype === resourceSubtype ) : data
89154 ) ;
90- const error = $derived ( query ?. error ?? undefined ) ;
91- const fetching = $derived ( query ?. isFetching ?? true ) ;
155+
156+ let current = $state . raw < ResourceName [ ] > ( [ ] ) ;
157+ let last : ResourceName [ ] = [ ] ;
158+
159+ $effect . pre ( ( ) => {
160+ if ( ! deepEqualResourceNames ( last , filtered ) ) {
161+ last = current ;
162+ current = filtered ;
163+ }
164+ } ) ;
92165
93166 return {
94167 get current ( ) {
95- return filtered ;
168+ return current ;
96169 } ,
97170 get error ( ) {
98171 return error ;
0 commit comments