@@ -5,12 +5,22 @@ import util from '../shared/util.ts'
55import type { RouterURL } from '../types.ts'
66import type { Application } from './app.ts'
77
8+ export type SSRData = {
9+ expires : number
10+ value : any
11+ }
12+
13+ export type SSROutput = {
14+ html : string
15+ data : Record < string , SSRData > | null
16+ }
17+
818/** The framework render result of SSR. */
919export type FrameworkRenderResult = {
1020 head : string [ ]
1121 body : string
1222 scripts : Record < string , any > [ ]
13- data : Record < string , string > | null
23+ data : Record < string , SSRData > | null
1424}
1525
1626/** The framework renderer for SSR. */
@@ -26,7 +36,7 @@ export type FrameworkRenderer = {
2636export class Renderer {
2737 #app: Application
2838 #renderer: FrameworkRenderer
29- #cache: Map < string , Map < string , [ string , any ] > >
39+ #cache: Map < string , Map < string , SSROutput > >
3040
3141 constructor ( app : Application ) {
3242 this . #app = app
@@ -41,25 +51,36 @@ export class Renderer {
4151 async useCache (
4252 namespace : string ,
4353 key : string ,
44- render : ( ) => Promise < [ string , any ] >
54+ render : ( ) => Promise < [ string , Record < string , SSRData > | null ] >
4555 ) : Promise < [ string , any ] > {
4656 let cache = this . #cache. get ( namespace )
4757 if ( cache === undefined ) {
4858 cache = new Map ( )
4959 this . #cache. set ( namespace , cache )
5060 }
51- const cached = cache . get ( key )
52- if ( cached !== undefined ) {
53- return cached
61+ if ( cache . has ( key ) ) {
62+ const { html, data } = cache . get ( key ) !
63+ let expires = 0
64+ if ( data !== null ) {
65+ Object . values ( data ) . forEach ( ( { expires : _expires } ) => {
66+ if ( expires === 0 || ( _expires > 0 && _expires < expires ) ) {
67+ expires = _expires
68+ }
69+ } )
70+ }
71+ if ( expires === 0 || Date . now ( ) < expires ) {
72+ return [ html , data ]
73+ }
74+ cache . delete ( key )
5475 }
55- const ret = await render ( )
76+ let [ html , data ] = await render ( )
5677 if ( namespace !== '-' ) {
5778 this . #app. getCodeInjects ( 'ssr' ) ?. forEach ( transform => {
58- ret [ 0 ] = transform ( key , ret [ 0 ] )
79+ html = transform ( key , html )
5980 } )
6081 }
61- cache . set ( key , ret )
62- return ret
82+ cache . set ( key , { html , data } )
83+ return [ html , data ]
6384 }
6485
6586 clearCache ( url ?: string ) {
@@ -71,7 +92,7 @@ export class Renderer {
7192 }
7293
7394 /** render page base the given location. */
74- async renderPage ( url : RouterURL , nestedModules : RouteModule [ ] ) : Promise < [ string , any ] > {
95+ async renderPage ( url : RouterURL , nestedModules : RouteModule [ ] ) : Promise < [ string , Record < string , SSRData > | null ] > {
7596 const start = performance . now ( )
7697 const isDev = this . #app. isDev
7798 const appModule = this . #app. findModuleByName ( 'app' )
0 commit comments