@@ -2468,7 +2468,7 @@ test("preserves admitted prompts when hydration races with promotion", async ()
24682468 ] )
24692469 expect ( sync . session . input . list ( sessionID ) ) . toEqual ( [ messageID ] )
24702470
2471- const refresh = sync . session . message . sync ( sessionID )
2471+ const refresh = sync . session . pending . sync ( sessionID ) . then ( ( ) => sync . session . message . sync ( sessionID ) )
24722472 await requested . promise
24732473 emitEvent ( events , {
24742474 id : "evt_prompted_1" ,
@@ -2504,31 +2504,21 @@ test("preserves admitted prompts when hydration races with promotion", async ()
25042504 }
25052505} )
25062506
2507- test ( "preserves an admitted prompt when hydration races with promotion " , async ( ) => {
2507+ test ( "preserves admissions that arrive while pending work hydrates " , async ( ) => {
25082508 const events = createEventStream ( )
2509- const sessionID = "session-hydration-race"
2510- const messageID = "msg_initial_user"
2511- let resolveMessages ! : ( response : Response ) => void
2512- let requestMessages ! : ( ) => void
2513- const requested = new Promise < void > ( ( resolve ) => {
2514- requestMessages = resolve
2515- } )
2509+ const sessionID = "session-pending-race"
2510+ const messageID = "msg_late_user"
2511+ const requested = Promise . withResolvers < void > ( )
2512+ const response = Promise . withResolvers < Response > ( )
25162513 const calls = createFetch ( ( url ) => {
2517- if ( url . pathname !== `/api/session/${ sessionID } /message` ) return
2518- requestMessages ( )
2519- return new Promise < Response > ( ( resolve ) => {
2520- resolveMessages = resolve
2521- } )
2514+ if ( url . pathname !== `/api/session/${ sessionID } /pending` ) return
2515+ requested . resolve ( )
2516+ return response . promise
25222517 } , events )
25232518 let data ! : ReturnType < typeof useData >
2524- let ready ! : ( ) => void
2525- const mounted = new Promise < void > ( ( resolve ) => {
2526- ready = resolve
2527- } )
25282519
25292520 function Probe ( ) {
25302521 data = useData ( )
2531- onMount ( ready )
25322522 return < box />
25332523 }
25342524
@@ -2545,129 +2535,32 @@ test("preserves an admitted prompt when hydration races with promotion", async (
25452535 ) )
25462536
25472537 try {
2548- await mounted
2549- emitEvent ( events , {
2550- id : "evt_initial_admitted" ,
2551- created : 1 ,
2552- type : "session.input.admitted" ,
2553- durable : durable ( sessionID ) ,
2554- data : {
2555- sessionID,
2556- inputID : messageID ,
2557- input : { type : "user" , data : { text : "Initial prompt" } , delivery : "steer" } ,
2558- } ,
2559- } )
2560- await wait ( ( ) => data . session . message . get ( sessionID , messageID ) ?. type === "user" )
2561-
2562- const refresh = data . session . message . sync ( sessionID )
2563- await requested
2564- emitEvent ( events , {
2565- id : "evt_initial_promoted" ,
2566- created : 2 ,
2567- type : "session.input.promoted" ,
2568- durable : durable ( sessionID , 1 ) ,
2569- data : { sessionID, inputID : messageID } ,
2570- } )
2571- await wait ( ( ) => data . session . input . list ( sessionID ) . length === 0 )
2572-
2573- resolveMessages ( json ( { data : [ ] , cursor : { } } ) )
2574- await refresh
2575-
2576- expect ( data . session . message . get ( sessionID , messageID ) ) . toMatchObject ( {
2577- id : messageID ,
2578- type : "user" ,
2579- text : "Initial prompt" ,
2580- time : { created : 2 } ,
2581- } )
2582- } finally {
2583- app . renderer . destroy ( )
2584- }
2585- } )
2586-
2587- /*
2588- test("preserves an admitted prompt when hydration races with promotion", async () => {
2589- const events = createEventStream()
2590- const sessionID = "session-hydration-race"
2591- const messageID = "msg_initial_user"
2592- let resolveMessages!: (response: Response) => void
2593- let requestMessages!: () => void
2594- const requested = new Promise<void>((resolve) => {
2595- requestMessages = resolve
2596- })
2597- const calls = createFetch((url) => {
2598- if (url.pathname !== `/api/session/${sessionID}/message`) return
2599- requestMessages()
2600- return new Promise<Response>((resolve) => {
2601- resolveMessages = resolve
2602- })
2603- }, events)
2604- let data!: ReturnType<typeof useData>
2605- let ready!: () => void
2606- const mounted = new Promise<void>((resolve) => {
2607- ready = resolve
2608- })
2609-
2610- function Probe() {
2611- data = useData()
2612- onMount(ready)
2613- return <box />
2614- }
2615-
2616- const app = await testRender(() => (
2617- <TestTuiContexts>
2618- <SDKProvider client={createClient(calls.fetch)} api={createApi(calls.fetch)}>
2619- <ProjectProvider>
2620- <DataProvider>
2621- <Probe />
2622- </DataProvider>
2623- </ProjectProvider>
2624- </SDKProvider>
2625- </TestTuiContexts>
2626- ))
2627-
2628- try {
2629- await mounted
2538+ const sync = data . session . pending . sync ( sessionID )
2539+ await requested . promise
26302540 emitEvent ( events , {
2631- id: "evt_initial_admitted ",
2541+ id : "evt_late_admitted " ,
26322542 created : 1 ,
26332543 type : "session.input.admitted" ,
26342544 durable : durable ( sessionID ) ,
26352545 data : {
26362546 sessionID,
26372547 inputID : messageID ,
2638- input: { type: "user", data: { text: "Initial prompt " }, delivery: "steer" },
2548+ input : { type : "user" , data : { text : "late " } , delivery : "steer" } ,
26392549 } ,
26402550 } )
2641- await wait(() => data.session.message.get(sessionID, messageID)?.type === "user")
2642-
2643- const refresh = data.session.message.refresh(sessionID)
2644- await requested
2645- emitEvent(events, {
2646- id: "evt_initial_promoted",
2647- created: 2,
2648- type: "session.input.promoted",
2649- durable: durable(sessionID, 1),
2650- data: { sessionID, inputID: messageID },
2651- })
2652- await wait(() => data.session.input.list(sessionID).length === 0)
2653-
2654- resolveMessages(json({ data: [], cursor: {} }))
2655- await refresh
2551+ await wait ( ( ) => data . session . pending . list ( sessionID ) . length === 1 )
2552+ response . resolve ( json ( { data : [ ] } ) )
2553+ await sync
26562554
2657- expect(data.session.message.get(sessionID, messageID)).toMatchObject({
2658- id: messageID,
2659- type: "user",
2660- text: "Initial prompt",
2661- time: { created: 2 },
2662- })
2555+ expect ( data . session . pending . list ( sessionID ) . map ( ( item ) => item . id ) ) . toEqual ( [ messageID ] )
2556+ expect ( data . session . input . list ( sessionID ) ) . toEqual ( [ messageID ] )
2557+ expect ( data . session . message . get ( sessionID , messageID ) ) . toMatchObject ( { text : "late" } )
26632558 } finally {
26642559 app . renderer . destroy ( )
26652560 }
26662561} )
26672562
26682563test ( "skips initial instruction state and projects later updates with their message ID" , async ( ) => {
2669- */
2670- test ( "projects live instruction updates with their message ID" , async ( ) => {
26712564 const events = createEventStream ( )
26722565 const calls = createFetch ( undefined , events )
26732566 let sync ! : ReturnType < typeof useData >
0 commit comments