11import type { WorkspaceLastViewedTarget } from "@coder-studio/core" ;
2+ import type { Store } from "jotai" ;
23import { useAtomValue , useSetAtom , useStore } from "jotai" ;
34import { useCallback } from "react" ;
45import { lastViewedTargetAtom } from "../../../atoms/app-ui" ;
@@ -9,6 +10,32 @@ interface PersistWorkspaceLastViewedTargetInput {
910 sessionId ?: string ;
1011}
1112
13+ const confirmedTargetByStore = new WeakMap < Store , WorkspaceLastViewedTarget | null > ( ) ;
14+ const optimisticTargetsByStore = new WeakMap < Store , WeakSet < WorkspaceLastViewedTarget > > ( ) ;
15+
16+ function getOptimisticTargets ( store : Store ) : WeakSet < WorkspaceLastViewedTarget > {
17+ const existing = optimisticTargetsByStore . get ( store ) ;
18+ if ( existing ) {
19+ return existing ;
20+ }
21+
22+ const next = new WeakSet < WorkspaceLastViewedTarget > ( ) ;
23+ optimisticTargetsByStore . set ( store , next ) ;
24+ return next ;
25+ }
26+
27+ function getConfirmedTarget ( store : Store ) : WorkspaceLastViewedTarget | null {
28+ const currentTarget = store . get ( lastViewedTargetAtom ) ;
29+ const optimisticTargets = getOptimisticTargets ( store ) ;
30+
31+ if ( currentTarget && ! optimisticTargets . has ( currentTarget ) ) {
32+ confirmedTargetByStore . set ( store , currentTarget ) ;
33+ return currentTarget ;
34+ }
35+
36+ return confirmedTargetByStore . get ( store ) ?? null ;
37+ }
38+
1239export function usePersistWorkspaceLastViewedTarget ( ) {
1340 const dispatch = useAtomValue ( dispatchCommandAtom ) ;
1441 const setLastViewedTarget = useSetAtom ( lastViewedTargetAtom ) ;
@@ -17,6 +44,8 @@ export function usePersistWorkspaceLastViewedTarget() {
1744 return useCallback (
1845 async ( { workspaceId, sessionId } : PersistWorkspaceLastViewedTargetInput ) => {
1946 const lastViewedTarget = store . get ( lastViewedTargetAtom ) ;
47+ const optimisticTargets = getOptimisticTargets ( store ) ;
48+ getConfirmedTarget ( store ) ;
2049
2150 if ( ! workspaceId ) {
2251 return null ;
@@ -34,25 +63,38 @@ export function usePersistWorkspaceLastViewedTarget() {
3463 sessionId,
3564 updatedAt : Date . now ( ) ,
3665 } ;
37- const previousTarget = lastViewedTarget ;
66+ optimisticTargets . add ( optimisticTarget ) ;
3867 setLastViewedTarget ( optimisticTarget ) ;
3968
4069 const result = await dispatch < WorkspaceLastViewedTarget > ( "workspace.lastViewedTarget.set" , {
4170 workspaceId,
4271 sessionId,
4372 } ) ;
4473
45- if ( store . get ( lastViewedTargetAtom ) !== optimisticTarget ) {
46- return store . get ( lastViewedTargetAtom ) ;
74+ const latestTarget = store . get ( lastViewedTargetAtom ) ;
75+
76+ if ( result . ok && result . data ) {
77+ confirmedTargetByStore . set ( store , result . data ) ;
78+
79+ if ( latestTarget === optimisticTarget ) {
80+ optimisticTargets . delete ( optimisticTarget ) ;
81+ setLastViewedTarget ( result . data ) ;
82+ return result . data ;
83+ }
84+
85+ optimisticTargets . delete ( optimisticTarget ) ;
86+ return latestTarget ;
4787 }
4888
49- if ( ! result . ok || ! result . data ) {
50- setLastViewedTarget ( previousTarget ) ;
51- return optimisticTarget ;
89+ if ( latestTarget === optimisticTarget ) {
90+ const confirmedTarget = getConfirmedTarget ( store ) ;
91+ optimisticTargets . delete ( optimisticTarget ) ;
92+ setLastViewedTarget ( confirmedTarget ) ;
93+ return confirmedTarget ;
5294 }
5395
54- setLastViewedTarget ( result . data ) ;
55- return result . data ;
96+ optimisticTargets . delete ( optimisticTarget ) ;
97+ return latestTarget ;
5698 } ,
5799 [ dispatch , setLastViewedTarget , store ]
58100 ) ;
0 commit comments