@@ -17,8 +17,8 @@ const logger = getAppLogger('volume-store')
1717
1818/** Payload shape matching Rust's `VolumesChangedPayload`. */
1919interface VolumesChangedPayload {
20- data : VolumeInfo [ ]
21- timedOut : boolean
20+ data : VolumeInfo [ ]
21+ timedOut : boolean
2222}
2323
2424let volumes = $state < VolumeInfo [ ] > ( [ ] )
@@ -32,23 +32,23 @@ let unlistenVolumesChanged: UnlistenFn | undefined
3232
3333/** Returns the current volume list. Reactive. */
3434export function getVolumes ( ) : VolumeInfo [ ] {
35- return volumes
35+ return volumes
3636}
3737
3838/** Returns whether the last volume listing timed out (some volumes may be missing). Reactive. */
3939export function getVolumesTimedOut ( ) : boolean {
40- return timedOut
40+ return timedOut
4141}
4242
4343/** Returns whether a volume refresh is in progress. Reactive. */
4444export function isVolumesRefreshing ( ) : boolean {
45- return refreshing
45+ return refreshing
4646}
4747
4848/** Returns whether a retry just completed but the listing is still timed out. Reactive.
4949 * Auto-resets to false after 3 seconds. */
5050export function isVolumeRetryFailed ( ) : boolean {
51- return retryFailed
51+ return retryFailed
5252}
5353
5454/**
@@ -57,15 +57,15 @@ export function isVolumeRetryFailed(): boolean {
5757 * Used by the retry button when the initial listing timed out.
5858 */
5959export function requestVolumeRefresh ( ) : void {
60- if ( refreshing ) return
60+ if ( refreshing ) return
6161
62- refreshing = true
63- retryFailed = false
64- if ( retryFailedTimer ) clearTimeout ( retryFailedTimer )
62+ refreshing = true
63+ retryFailed = false
64+ if ( retryFailedTimer ) clearTimeout ( retryFailedTimer )
6565
66- // Tell the backend to re-broadcast. The result arrives via the
67- // `volumes-changed` event listener, which handles retryFailed.
68- void refreshVolumes ( )
66+ // Tell the backend to re-broadcast. The result arrives via the
67+ // `volumes-changed` event listener, which handles retryFailed.
68+ void refreshVolumes ( )
6969}
7070
7171/**
@@ -79,55 +79,55 @@ export function requestVolumeRefresh(): void {
7979 * Idempotent — calling multiple times is safe.
8080 */
8181export async function initVolumeStore ( ) : Promise < void > {
82- if ( initialized ) return
83-
84- // Subscribe to backend-pushed volume list updates
85- unlistenVolumesChanged = await listen < VolumesChangedPayload > ( 'volumes-changed' , ( event ) => {
86- receivedEvent = true
87- volumes = event . payload . data
88- timedOut = event . payload . timedOut
89-
90- // Detect retry failure: we were refreshing and it's still timed out
91- if ( refreshing ) {
92- refreshing = false
93- if ( event . payload . timedOut ) {
94- retryFailed = true
95- retryFailedTimer = setTimeout ( ( ) => {
96- retryFailed = false
97- } , 3000 )
98- }
99- }
100-
101- logger . debug ( 'volumes-changed: {count} volumes, timedOut={timedOut}' , {
102- count : event . payload . data . length ,
103- timedOut : event . payload . timedOut ,
104- } )
105- } )
106-
107- // Bootstrap: fetch initial list via IPC (in case the backend event
108- // fired before we subscribed, or hasn't fired yet)
109- const result = await listVolumes ( )
110- // Only use bootstrap data if no event has arrived yet
111- if ( ! receivedEvent ) {
112- volumes = result . data
113- timedOut = result . timedOut
114- logger . debug ( 'Bootstrap: {count} volumes' , { count : result . data . length } )
82+ if ( initialized ) return
83+
84+ // Subscribe to backend-pushed volume list updates
85+ unlistenVolumesChanged = await listen < VolumesChangedPayload > ( 'volumes-changed' , ( event ) => {
86+ receivedEvent = true
87+ volumes = event . payload . data
88+ timedOut = event . payload . timedOut
89+
90+ // Detect retry failure: we were refreshing and it's still timed out
91+ if ( refreshing ) {
92+ refreshing = false
93+ if ( event . payload . timedOut ) {
94+ retryFailed = true
95+ retryFailedTimer = setTimeout ( ( ) => {
96+ retryFailed = false
97+ } , 3000 )
98+ }
11599 }
116100
117- initialized = true
118- logger . debug ( 'Volume store initialized' )
101+ logger . debug ( 'volumes-changed: {count} volumes, timedOut={timedOut}' , {
102+ count : event . payload . data . length ,
103+ timedOut : event . payload . timedOut ,
104+ } )
105+ } )
106+
107+ // Bootstrap: fetch initial list via IPC (in case the backend event
108+ // fired before we subscribed, or hasn't fired yet)
109+ const result = await listVolumes ( )
110+ // Only use bootstrap data if no event has arrived yet
111+ if ( ! receivedEvent ) {
112+ volumes = result . data
113+ timedOut = result . timedOut
114+ logger . debug ( 'Bootstrap: {count} volumes' , { count : result . data . length } )
115+ }
116+
117+ initialized = true
118+ logger . debug ( 'Volume store initialized' )
119119}
120120
121121/** Cleans up the volume store. Call on app shutdown. */
122122export function cleanupVolumeStore ( ) : void {
123- unlistenVolumesChanged ?.( )
124- unlistenVolumesChanged = undefined
125- volumes = [ ]
126- timedOut = false
127- refreshing = false
128- retryFailed = false
129- if ( retryFailedTimer ) clearTimeout ( retryFailedTimer )
130- retryFailedTimer = null
131- receivedEvent = false
132- initialized = false
123+ unlistenVolumesChanged ?.( )
124+ unlistenVolumesChanged = undefined
125+ volumes = [ ]
126+ timedOut = false
127+ refreshing = false
128+ retryFailed = false
129+ if ( retryFailedTimer ) clearTimeout ( retryFailedTimer )
130+ retryFailedTimer = null
131+ receivedEvent = false
132+ initialized = false
133133}
0 commit comments