@@ -61,6 +61,13 @@ export const workerSwr = ({
6161
6262 const processResponse = ( response : Response ) => {
6363 const upstreamCacheControl = response . headers . get ( "cache-control" ) ;
64+
65+ // Parse s-maxage for staleAt calculation (when content becomes stale)
66+ // Parse stale-while-revalidate and stale-if-error for the stale serving windows
67+ let sMaxage : number | undefined ;
68+ let staleWhileRevalidate : number | undefined ;
69+ let staleIfError : number | undefined ;
70+
6471 if ( upstreamCacheControl ) {
6572 const directives = upstreamCacheControl
6673 . split ( "," )
@@ -69,18 +76,16 @@ export const workerSwr = ({
6976 for ( const directive of directives ) {
7077 const [ name , value ] = directive . split ( "=" , 2 ) ;
7178
79+ if ( name === "s-maxage" && value ) {
80+ sMaxage = parseInt ( value , 10 ) ;
81+ }
82+
7283 if ( name === "stale-while-revalidate" && value ) {
73- response . headers . set (
74- swrConfig . staleAtHeaderName ,
75- ( Date . now ( ) + parseInt ( value , 10 ) * 1000 ) . toString ( )
76- ) ;
84+ staleWhileRevalidate = parseInt ( value , 10 ) ;
7785 }
7886
7987 if ( name === "stale-if-error" && value ) {
80- response . headers . set (
81- swrConfig . staleErrorAtHeaderName ,
82- ( Date . now ( ) + parseInt ( value , 10 ) * 1000 ) . toString ( )
83- ) ;
88+ staleIfError = parseInt ( value , 10 ) ;
8489 }
8590 }
8691 }
@@ -102,22 +107,43 @@ export const workerSwr = ({
102107 ) ;
103108 }
104109
105- if ( name === "stale-while-revalidate" ) {
106- response . headers . set (
107- swrConfig . staleAtHeaderName ,
108- ( Date . now ( ) + parseInt ( value , 10 ) * 1000 ) . toString ( )
109- ) ;
110+ // Also parse from config directives
111+ if ( name === "s-maxage" && value && sMaxage === undefined ) {
112+ sMaxage = parseInt ( value , 10 ) ;
110113 }
111114
112- if ( name === "stale-if-error" ) {
113- response . headers . set (
114- swrConfig . staleErrorAtHeaderName ,
115- ( Date . now ( ) + parseInt ( value , 10 ) * 1000 ) . toString ( )
116- ) ;
115+ if ( name === "stale-while-revalidate" && value && staleWhileRevalidate === undefined ) {
116+ staleWhileRevalidate = parseInt ( value , 10 ) ;
117+ }
118+
119+ if ( name === "stale-if-error" && value && staleIfError === undefined ) {
120+ staleIfError = parseInt ( value , 10 ) ;
117121 }
118122 }
119123 }
120124
125+ // Set staleAt based on s-maxage (when content becomes "stale" and revalidation should start)
126+ // If no s-maxage, fall back to stale-while-revalidate for backwards compatibility
127+ // If neither, use defaultStaleSeconds
128+ const staleAtSeconds = sMaxage ?? staleWhileRevalidate ?? swrConfig . defaultStaleSeconds ;
129+ response . headers . set (
130+ swrConfig . staleAtHeaderName ,
131+ ( Date . now ( ) + staleAtSeconds * 1000 ) . toString ( )
132+ ) ;
133+
134+ // Set staleErrorAt based on stale-if-error (if present)
135+ if ( staleIfError !== undefined ) {
136+ response . headers . set (
137+ swrConfig . staleErrorAtHeaderName ,
138+ ( Date . now ( ) + staleIfError * 1000 ) . toString ( )
139+ ) ;
140+ } else if ( swrConfig . defaultStaleErrorSeconds ) {
141+ response . headers . set (
142+ swrConfig . staleErrorAtHeaderName ,
143+ ( Date . now ( ) + swrConfig . defaultStaleErrorSeconds * 1000 ) . toString ( )
144+ ) ;
145+ }
146+
121147 if ( varyDirectives ) {
122148 const existingVary =
123149 response . headers
@@ -137,23 +163,6 @@ export const workerSwr = ({
137163 response . headers . set ( "vary" , vary . join ( ", " ) ) ;
138164 }
139165 }
140-
141- if ( ! response . headers . has ( swrConfig . staleAtHeaderName ) ) {
142- response . headers . set (
143- swrConfig . staleAtHeaderName ,
144- ( Date . now ( ) + swrConfig . defaultStaleSeconds * 1000 ) . toString ( )
145- ) ;
146- }
147-
148- if (
149- ! response . headers . has ( swrConfig . staleErrorAtHeaderName ) &&
150- swrConfig . defaultStaleErrorSeconds
151- ) {
152- response . headers . set (
153- swrConfig . staleErrorAtHeaderName ,
154- ( Date . now ( ) + swrConfig . defaultStaleErrorSeconds * 1000 ) . toString ( )
155- ) ;
156- }
157166 } ;
158167
159168 return async ( request : Request , env : any , ctx : ExecutionContext ) => {
0 commit comments