@@ -3,6 +3,12 @@ import { createStore, produce, reconcile } from "solid-js/store"
33import { Binary } from "@opencode-ai/util/binary"
44import { retry } from "@opencode-ai/util/retry"
55import { createSimpleContext } from "@opencode-ai/ui/context"
6+ import {
7+ clearSessionPrefetch ,
8+ getSessionPrefetch ,
9+ getSessionPrefetchPromise ,
10+ setSessionPrefetch ,
11+ } from "./global-sync/session-prefetch"
612import { useGlobalSync } from "./global-sync"
713import { useSDK } from "./sdk"
814import type { Message , Part } from "@opencode-ai/sdk/v2/client"
@@ -160,6 +166,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
160166
161167 const evict = ( directory : string , setStore : Setter , sessionIDs : string [ ] ) => {
162168 if ( sessionIDs . length === 0 ) return
169+ clearSessionPrefetch ( directory , sessionIDs )
163170 for ( const sessionID of sessionIDs ) {
164171 globalSync . todo . set ( sessionID , undefined )
165172 }
@@ -217,6 +224,12 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
217224 }
218225 setMeta ( "limit" , key , input . limit )
219226 setMeta ( "complete" , key , next . complete )
227+ setSessionPrefetch ( {
228+ directory : input . directory ,
229+ sessionID : input . sessionID ,
230+ limit : input . limit ,
231+ complete : next . complete ,
232+ } )
220233 } )
221234 } )
222235 . finally ( ( ) => {
@@ -280,54 +293,82 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
280293 parts : input . parts ,
281294 } )
282295 } ,
283- async sync ( sessionID : string ) {
296+ async sync ( sessionID : string , opts ?: { force ?: boolean } ) {
284297 const directory = sdk . directory
285298 const client = sdk . client
286299 const [ store , setStore ] = globalSync . child ( directory )
287300 const key = keyFor ( directory , sessionID )
288- const hasSession = Binary . search ( store . session , sessionID , ( s ) => s . id ) . found
289301
290302 touch ( directory , setStore , sessionID )
291303
292- if ( store . message [ sessionID ] !== undefined && hasSession && meta . limit [ key ] !== undefined ) return
293-
294- const limit = meta . limit [ key ] ?? messagePageSize
295-
296- const sessionReq = hasSession
297- ? Promise . resolve ( )
298- : retry ( ( ) => client . session . get ( { sessionID } ) ) . then ( ( session ) => {
299- if ( ! tracked ( directory , sessionID ) ) return
300- const data = session . data
301- if ( ! data ) return
302- setStore (
303- "session" ,
304- produce ( ( draft ) => {
305- const match = Binary . search ( draft , sessionID , ( s ) => s . id )
306- if ( match . found ) {
307- draft [ match . index ] = data
308- return
309- }
310- draft . splice ( match . index , 0 , data )
311- } ) ,
312- )
313- } )
314-
315- const messagesReq = loadMessages ( {
316- directory,
317- client,
318- setStore,
319- sessionID,
320- limit,
321- } )
304+ const seeded = getSessionPrefetch ( directory , sessionID )
305+ if ( seeded && store . message [ sessionID ] !== undefined && meta . limit [ key ] === undefined ) {
306+ batch ( ( ) => {
307+ setMeta ( "limit" , key , seeded . limit )
308+ setMeta ( "complete" , key , seeded . complete )
309+ setMeta ( "loading" , key , false )
310+ } )
311+ }
322312
323- return runInflight ( inflight , key , ( ) => Promise . all ( [ sessionReq , messagesReq ] ) . then ( ( ) => { } ) )
313+ return runInflight ( inflight , key , async ( ) => {
314+ const pending = getSessionPrefetchPromise ( directory , sessionID )
315+ if ( pending ) {
316+ await pending
317+ const seeded = getSessionPrefetch ( directory , sessionID )
318+ if ( seeded && store . message [ sessionID ] !== undefined && meta . limit [ key ] === undefined ) {
319+ batch ( ( ) => {
320+ setMeta ( "limit" , key , seeded . limit )
321+ setMeta ( "complete" , key , seeded . complete )
322+ setMeta ( "loading" , key , false )
323+ } )
324+ }
325+ }
326+
327+ const hasSession = Binary . search ( store . session , sessionID , ( s ) => s . id ) . found
328+ const cached = store . message [ sessionID ] !== undefined && meta . limit [ key ] !== undefined
329+ if ( cached && hasSession && ! opts ?. force ) return
330+
331+ const limit = meta . limit [ key ] ?? messagePageSize
332+ const sessionReq =
333+ hasSession && ! opts ?. force
334+ ? Promise . resolve ( )
335+ : retry ( ( ) => client . session . get ( { sessionID } ) ) . then ( ( session ) => {
336+ if ( ! tracked ( directory , sessionID ) ) return
337+ const data = session . data
338+ if ( ! data ) return
339+ setStore (
340+ "session" ,
341+ produce ( ( draft ) => {
342+ const match = Binary . search ( draft , sessionID , ( s ) => s . id )
343+ if ( match . found ) {
344+ draft [ match . index ] = data
345+ return
346+ }
347+ draft . splice ( match . index , 0 , data )
348+ } ) ,
349+ )
350+ } )
351+
352+ const messagesReq =
353+ cached && ! opts ?. force
354+ ? Promise . resolve ( )
355+ : loadMessages ( {
356+ directory,
357+ client,
358+ setStore,
359+ sessionID,
360+ limit,
361+ } )
362+
363+ await Promise . all ( [ sessionReq , messagesReq ] )
364+ } )
324365 } ,
325- async diff ( sessionID : string ) {
366+ async diff ( sessionID : string , opts ?: { force ?: boolean } ) {
326367 const directory = sdk . directory
327368 const client = sdk . client
328369 const [ store , setStore ] = globalSync . child ( directory )
329370 touch ( directory , setStore , sessionID )
330- if ( store . session_diff [ sessionID ] !== undefined ) return
371+ if ( store . session_diff [ sessionID ] !== undefined && ! opts ?. force ) return
331372
332373 const key = keyFor ( directory , sessionID )
333374 return runInflight ( inflightDiff , key , ( ) =>
@@ -337,7 +378,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
337378 } ) ,
338379 )
339380 } ,
340- async todo ( sessionID : string ) {
381+ async todo ( sessionID : string , opts ?: { force ?: boolean } ) {
341382 const directory = sdk . directory
342383 const client = sdk . client
343384 const [ store , setStore ] = globalSync . child ( directory )
@@ -348,7 +389,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
348389 if ( cached === undefined ) {
349390 globalSync . todo . set ( sessionID , existing )
350391 }
351- return
392+ if ( ! opts ?. force ) return
352393 }
353394
354395 if ( cached !== undefined ) {
0 commit comments