1- import { type Durations , type Logger , type Entry , type LogData , type Options } from "./types" ;
1+ import { type Durations , type Logger , type Entry , type LogData , type Options , type CacheEntry } from "./types" ;
22import { logger as defaultLogger } from "./lib/logger" ;
33import { RedisLayer } from "./layers/redis-layer" ;
44import { LruLayer } from "./layers/lru-layer" ;
55import { PendingsLayer } from "./layers/pendings-layer" ;
66import { CacheError } from "./lib/error" ;
7+ import { calculateStreamSize } from "./lib/stream" ;
78
89export class CacheHandler {
910 ephemeralLayer : LruLayer ;
1011
1112 persistentLayer : RedisLayer ;
1213
13- private pendingGetsLayer = new PendingsLayer < Entry | undefined | null > ( ) ;
14+ private pendingGetsLayer = new PendingsLayer < CacheEntry | undefined | null > ( ) ;
1415
15- private pendingSetsLayer = new PendingsLayer < Entry | undefined | null > ( ) ;
16+ private pendingSetsLayer = new PendingsLayer < CacheEntry | undefined | null > ( ) ;
1617
1718 private logger : Logger ;
1819
@@ -34,24 +35,24 @@ export class CacheHandler {
3435 this . logger ( { type, status, source, key, message } ) ;
3536 }
3637
37- async get ( key : string ) {
38+ async getEntry ( key : string ) : Promise < CacheEntry | undefined | null > {
3839 const pendingSet = await this . pendingSetsLayer . get ( key ) ;
3940 if ( pendingSet === null ) return undefined ;
4041 if ( pendingSet ) {
4142 this . logOperation ( "GET" , "REVALIDATED" , "NEW" , key ) ;
42- const [ cacheStream , responseStream ] = pendingSet . value . tee ( ) ;
43- pendingSet . value = cacheStream ;
44- return { ...pendingSet , value : responseStream } ;
43+ const [ cacheStream , responseStream ] = pendingSet . entry . value . tee ( ) ;
44+ pendingSet . entry . value = cacheStream ;
45+ return { entry : { ...pendingSet . entry , value : responseStream } , size : pendingSet . size , status : "valid" } ;
4546 }
4647
47- const ephemeralCache = await this . ephemeralLayer . get ( key ) ;
48+ const ephemeralCache = await this . ephemeralLayer . getEntry ( key ) ;
4849 if ( ephemeralCache ) {
4950 if ( ephemeralCache . status === "revalidate" ) {
5051 this . logOperation ( "GET" , "REVALIDATING" , "MEMORY" , key ) ;
5152 return undefined ;
5253 }
5354 this . logOperation ( "GET" , "HIT" , "MEMORY" , key ) ;
54- return ephemeralCache . entry ;
55+ return ephemeralCache ;
5556 }
5657
5758 const pendingGet = await this . pendingGetsLayer . get ( key ) ;
@@ -61,15 +62,15 @@ export class CacheHandler {
6162 }
6263 if ( pendingGet ) {
6364 this . logOperation ( "GET" , "HIT" , "REDIS" , key ) ;
64- const [ cacheStream , responseStream ] = pendingGet . value . tee ( ) ;
65- pendingGet . value = cacheStream ;
66- return { ...pendingGet , value : responseStream } ;
65+ const [ cacheStream , responseStream ] = pendingGet . entry . value . tee ( ) ;
66+ pendingGet . entry . value = cacheStream ;
67+ return { entry : { ...pendingGet . entry , value : responseStream } , size : pendingGet . size , status : "valid" } ;
6768 }
6869
6970 const resolvePending = this . pendingGetsLayer . set ( key ) ;
7071
7172 try {
72- const persistentCache = await this . persistentLayer . get ( key ) ;
73+ const persistentCache = await this . persistentLayer . getEntry ( key ) ;
7374
7475 if ( persistentCache === null ) {
7576 await this . persistentLayer . delete ( key ) ;
@@ -87,7 +88,7 @@ export class CacheHandler {
8788 return undefined ;
8889 }
8990
90- const { entry, status } = persistentCache ;
91+ const { entry, size , status } = persistentCache ;
9192 const [ cacheStream , responseStream ] = entry . value . tee ( ) ;
9293 entry . value = cacheStream ;
9394
@@ -99,9 +100,9 @@ export class CacheHandler {
99100 resolvePending ( undefined ) ;
100101 return undefined ;
101102 }
102- resolvePending ( responseEntry ) ;
103+ resolvePending ( { entry : responseEntry , size , status : "valid" } ) ;
103104 this . logOperation ( "GET" , "HIT" , "REDIS" , key ) ;
104- return responseEntry ;
105+ return { entry : responseEntry , size , status : "valid" } ;
105106 } catch ( error ) {
106107 this . logOperation ( "GET" , "ERROR" , "REDIS" , key , error instanceof Error ? error . message : undefined ) ;
107108 resolvePending ( null ) ;
@@ -110,6 +111,11 @@ export class CacheHandler {
110111 }
111112 }
112113
114+ async get ( key : string ) : Promise < Entry | undefined | null > {
115+ const cacheEntry = await this . getEntry ( key ) ;
116+ return cacheEntry ? cacheEntry . entry : undefined ;
117+ }
118+
113119 async set ( key : string , pendingEntry : Promise < Entry > ) {
114120 const resolvePending = this . pendingSetsLayer . set ( key ) ;
115121
@@ -123,7 +129,10 @@ export class CacheHandler {
123129 try {
124130 await this . persistentLayer . set ( key , { ...entry , value : cacheStreamPersistent } ) ;
125131
126- resolvePending ( entry ) ;
132+ const [ responseStreamSize , responseStreamMain ] = responseStream . tee ( ) ;
133+ entry . value = responseStreamMain ;
134+ const size = await calculateStreamSize ( responseStreamSize ) ;
135+ resolvePending ( { entry, size, status : "valid" } ) ;
127136 this . logOperation ( "SET" , "REVALIDATED" , "NEW" , key ) ;
128137 } catch ( error ) {
129138 resolvePending ( undefined ) ;
@@ -173,11 +182,11 @@ export class CacheHandler {
173182 return ephemeralReady && persistentReady ;
174183 }
175184
176- async keys ( ) : Promise < { ephemeralKeys : string [ ] ; persistentKeys : string [ ] } > {
185+ async keys ( ) : Promise < string [ ] > {
177186 const [ ephemeralKeys , persistentKeys ] = await Promise . all ( [
178187 this . ephemeralLayer . keys ( ) ,
179188 this . persistentLayer . keys ( ) ,
180189 ] ) ;
181- return { ephemeralKeys, persistentKeys } ;
190+ return Array . from ( new Set ( [ ... ephemeralKeys , ... persistentKeys ] ) ) ;
182191 }
183192}
0 commit comments