@@ -3,11 +3,32 @@ import { useLanguage } from '@/intl/client';
33import { t } from '@/intl/translate' ;
44import { Icon } from '@gitbook/icons' ;
55import { useEffect , useState } from 'react' ;
6+ import { create } from 'zustand' ;
67import { useVisitedPages } from '../Insights' ;
78import { usePageContext } from '../PageContext' ;
89import { Loading } from '../primitives' ;
910import { streamLinkPageSummary } from './server-actions/streamLinkPageSummary' ;
1011
12+ const useSummaries = create < {
13+ cache : Map < string , string > ;
14+ setSummary : ( key : string , summary : string ) => void ;
15+ } > ( ( set ) => ( {
16+ cache : new Map ( ) ,
17+ setSummary : ( key , summary ) =>
18+ set ( ( state ) => {
19+ const newCache = new Map ( state . cache ) ;
20+ newCache . set ( key , summary ) ;
21+ return { cache : newCache } ;
22+ } ) ,
23+ } ) ) ;
24+
25+ /**
26+ * Get a unique cache key for a page summary
27+ */
28+ function getCacheKey ( targetSpaceId : string , targetPageId : string ) : string {
29+ return `${ targetSpaceId } :${ targetPageId } ` ;
30+ }
31+
1132/**
1233 * Summarise a page's content for use in a link preview
1334 */
@@ -21,15 +42,26 @@ export function AIPageLinkSummary(props: {
2142 const { targetSpaceId, targetPageId, linkPreview, linkTitle, showTrademark = true } = props ;
2243
2344 const currentPage = usePageContext ( ) ;
24-
2545 const language = useLanguage ( ) ;
2646 const visitedPages = useVisitedPages ( ( state ) => state . pages ) ;
27- const [ highlight , setHighlight ] = useState ( '' ) ;
47+ const [ summary , setSummary ] = useState ( '' ) ;
48+ const cacheKey = getCacheKey ( targetSpaceId , targetPageId ) ;
49+ const { cachedSummary, setCachedSummary } = useSummaries ( ( state ) => {
50+ return {
51+ cachedSummary : state . cache . get ( cacheKey ) ?? '' ,
52+ setCachedSummary : state . setSummary ,
53+ } ;
54+ } ) ;
2855
2956 useEffect ( ( ) => {
3057 let canceled = false ;
3158
32- setHighlight ( '' ) ;
59+ setSummary ( '' ) ;
60+
61+ if ( cachedSummary ) {
62+ setSummary ( cachedSummary ) ;
63+ return ;
64+ }
3365
3466 ( async ( ) => {
3567 const stream = await streamLinkPageSummary ( {
@@ -43,9 +75,16 @@ export function AIPageLinkSummary(props: {
4375 visitedPages,
4476 } ) ;
4577
78+ let generatedSummary = '' ;
4679 for await ( const highlight of stream ) {
4780 if ( canceled ) return ;
48- setHighlight ( highlight ?? '' ) ;
81+ generatedSummary = highlight ?? '' ;
82+ setSummary ( generatedSummary ) ;
83+ }
84+
85+ // Cache the complete summary
86+ if ( generatedSummary ) {
87+ setCachedSummary ( cacheKey , generatedSummary ) ;
4988 }
5089 } ) ( ) ;
5190
@@ -61,6 +100,9 @@ export function AIPageLinkSummary(props: {
61100 linkPreview ,
62101 linkTitle ,
63102 visitedPages ,
103+ cachedSummary ,
104+ cacheKey ,
105+ setCachedSummary ,
64106 ] ) ;
65107
66108 const shimmerBlocks = [
@@ -76,14 +118,14 @@ export function AIPageLinkSummary(props: {
76118 < div className = "flex flex-col gap-1" >
77119 < div className = "flex w-screen items-center gap-1 font-semibold text-tint text-xs uppercase leading-tight tracking-wide" >
78120 { showTrademark ? (
79- < Loading className = "size-4" busy = { ! highlight || highlight . length === 0 } />
121+ < Loading className = "size-4" busy = { ! summary || summary . length === 0 } />
80122 ) : (
81123 < Icon icon = "sparkle" className = "size-3" />
82124 ) }
83125 < h6 className = "text-tint" > { t ( language , 'link_tooltip_ai_summary' ) } </ h6 >
84126 </ div >
85- { highlight . length > 0 ? (
86- < p className = "animate-fadeIn" > { highlight } </ p >
127+ { summary . length > 0 ? (
128+ < p className = "animate-fadeIn" > { summary } </ p >
87129 ) : (
88130 < div className = "mt-2 flex flex-wrap gap-2" >
89131 { shimmerBlocks . map ( ( block , index ) => (
@@ -94,7 +136,7 @@ export function AIPageLinkSummary(props: {
94136 ) ) }
95137 </ div >
96138 ) }
97- { highlight . length > 0 ? (
139+ { summary . length > 0 ? (
98140 < div className = "animate-fadeIn text-tint-subtle text-xs" >
99141 { t ( language , 'link_tooltip_ai_summary_description' ) }
100142 </ div >
0 commit comments