11import ComposableCache from "@opennextjs/aws/adapters/composable-cache" ;
2- import {
3- fromReadableStream ,
4- toReadableStream ,
5- } from "@opennextjs/aws/utils/stream" ;
62import { vi } from "vitest" ;
73
84describe ( "Composable cache handler" , ( ) => {
@@ -19,7 +15,7 @@ describe("Composable cache handler", () => {
1915 timestamp : Date . now ( ) ,
2016 expire : Date . now ( ) + 1000 ,
2117 revalidate : 3600 ,
22- value : "test-value" ,
18+ value : new Blob ( [ "test-value" ] ) ,
2319 } ,
2420 lastModified : Date . now ( ) ,
2521 } ) ,
@@ -132,7 +128,7 @@ describe("Composable cache handler", () => {
132128 type : "route" ,
133129 body : "{}" ,
134130 tags : [ ] ,
135- value : "test-value" ,
131+ value : new Blob ( [ "test-value" ] ) ,
136132 } ,
137133 lastModified : Date . now ( ) ,
138134 } ) ;
@@ -185,7 +181,7 @@ describe("Composable cache handler", () => {
185181
186182 it ( "should return pending write promise if available" , async ( ) => {
187183 const pendingEntry = Promise . resolve ( {
188- value : toReadableStream ( "pending-value" ) ,
184+ value : new Blob ( [ "pending-value" ] ) . stream ( ) ,
189185 tags : [ "tag1" ] ,
190186 stale : 0 ,
191187 timestamp : Date . now ( ) ,
@@ -214,8 +210,9 @@ describe("Composable cache handler", () => {
214210
215211 it ( "should set cache entry and handle tags in original mode" , async ( ) => {
216212 tagCache . mode = "original" ;
213+ const blob = new Blob ( [ "test-value" ] ) ;
217214 const entry = {
218- value : toReadableStream ( "test-value" ) ,
215+ value : blob . stream ( ) ,
219216 tags : [ "tag1" , "tag2" ] ,
220217 stale : 0 ,
221218 timestamp : Date . now ( ) ,
@@ -229,7 +226,7 @@ describe("Composable cache handler", () => {
229226 "test-key" ,
230227 expect . objectContaining ( {
231228 tags : [ "tag1" , "tag2" ] ,
232- value : "test-value" ,
229+ value : expect . any ( Blob ) ,
233230 } ) ,
234231 "composable" ,
235232 ) ;
@@ -241,7 +238,7 @@ describe("Composable cache handler", () => {
241238 tagCache . getByPath . mockResolvedValueOnce ( [ "tag1" ] ) ;
242239
243240 const entry = {
244- value : toReadableStream ( "test-value" ) ,
241+ value : new Blob ( [ "test-value" ] ) . stream ( ) ,
245242 tags : [ "tag1" , "tag2" , "tag3" ] ,
246243 stale : 0 ,
247244 timestamp : Date . now ( ) ,
@@ -262,7 +259,7 @@ describe("Composable cache handler", () => {
262259 tagCache . getByPath . mockResolvedValueOnce ( [ "tag1" , "tag2" ] ) ;
263260
264261 const entry = {
265- value : toReadableStream ( "test-value" ) ,
262+ value : new Blob ( [ "test-value" ] ) . stream ( ) ,
266263 tags : [ "tag1" , "tag2" ] ,
267264 stale : 0 ,
268265 timestamp : Date . now ( ) ,
@@ -279,7 +276,7 @@ describe("Composable cache handler", () => {
279276 tagCache . mode = "nextMode" ;
280277
281278 const entry = {
282- value : toReadableStream ( "test-value" ) ,
279+ value : new Blob ( [ "test-value" ] ) . stream ( ) ,
283280 tags : [ "tag1" , "tag2" ] ,
284281 stale : 0 ,
285282 timestamp : Date . now ( ) ,
@@ -293,9 +290,10 @@ describe("Composable cache handler", () => {
293290 expect ( tagCache . writeTags ) . not . toHaveBeenCalled ( ) ;
294291 } ) ;
295292
296- it ( "should convert ReadableStream to string" , async ( ) => {
293+ it ( "should store Blob directly" , async ( ) => {
294+ const blob = new Blob ( [ "test-content" ] ) ;
297295 const entry = {
298- value : toReadableStream ( "test-content" ) ,
296+ value : blob . stream ( ) ,
299297 tags : [ "tag1" ] ,
300298 stale : 0 ,
301299 timestamp : Date . now ( ) ,
@@ -308,7 +306,7 @@ describe("Composable cache handler", () => {
308306 expect ( incrementalCache . set ) . toHaveBeenCalledWith (
309307 "test-key" ,
310308 expect . objectContaining ( {
311- value : "test-content" ,
309+ value : expect . any ( Blob ) ,
312310 } ) ,
313311 "composable" ,
314312 ) ;
@@ -437,8 +435,9 @@ describe("Composable cache handler", () => {
437435 describe ( "integration tests" , ( ) => {
438436 it ( "should handle complete cache lifecycle" , async ( ) => {
439437 // Set a cache entry
438+ const blob = new Blob ( [ "integration-test" ] ) ;
440439 const entry = {
441- value : toReadableStream ( "integration-test" ) ,
440+ value : blob . stream ( ) ,
442441 tags : [ "integration-tag" ] ,
443442 stale : 0 ,
444443 timestamp : Date . now ( ) ,
@@ -452,7 +451,7 @@ describe("Composable cache handler", () => {
452451 expect ( incrementalCache . set ) . toHaveBeenCalledWith (
453452 "integration-key" ,
454453 expect . objectContaining ( {
455- value : "integration-test" ,
454+ value : expect . any ( Blob ) ,
456455 tags : [ "integration-tag" ] ,
457456 } ) ,
458457 "composable" ,
@@ -462,7 +461,7 @@ describe("Composable cache handler", () => {
462461 incrementalCache . get . mockResolvedValueOnce ( {
463462 value : {
464463 ...entry ,
465- value : "integration-test" ,
464+ value : blob ,
466465 } ,
467466 lastModified : Date . now ( ) ,
468467 } ) ;
@@ -474,13 +473,21 @@ describe("Composable cache handler", () => {
474473 expect ( result ?. tags ) . toEqual ( [ "integration-tag" ] ) ;
475474
476475 // Convert the stream back to verify content
477- const content = await fromReadableStream ( result ! . value ) ;
476+ const reader = result ! . value . getReader ( ) ;
477+ const chunks : Uint8Array [ ] = [ ] ;
478+ let readResult : ReadableStreamReadResult < Uint8Array > ;
479+ while ( ! ( readResult = await reader . read ( ) ) . done ) {
480+ chunks . push ( readResult . value ) ;
481+ }
482+ const content = new TextDecoder ( ) . decode (
483+ new Uint8Array ( chunks . flatMap ( ( c ) => Array . from ( c ) ) ) ,
484+ ) ;
478485 expect ( content ) . toBe ( "integration-test" ) ;
479486 } ) ;
480487
481488 it ( "should handle concurrent get/set operations" , async ( ) => {
482489 const entry1 = {
483- value : toReadableStream ( "concurrent-1" ) ,
490+ value : new Blob ( [ "concurrent-1" ] ) . stream ( ) ,
484491 tags : [ "tag1" ] ,
485492 stale : 0 ,
486493 timestamp : Date . now ( ) ,
@@ -489,7 +496,7 @@ describe("Composable cache handler", () => {
489496 } ;
490497
491498 const entry2 = {
492- value : toReadableStream ( "concurrent-2" ) ,
499+ value : new Blob ( [ "concurrent-2" ] ) . stream ( ) ,
493500 tags : [ "tag2" ] ,
494501 stale : 0 ,
495502 timestamp : Date . now ( ) ,
@@ -513,10 +520,28 @@ describe("Composable cache handler", () => {
513520 expect ( results [ 2 ] ) . toBeDefined ( ) ;
514521 expect ( results [ 3 ] ) . toBeDefined ( ) ;
515522
516- const content1 = await fromReadableStream ( results [ 2 ] ! . value ) ;
523+ // Convert stream 1 to text
524+ const reader1 = results [ 2 ] ! . value . getReader ( ) ;
525+ const chunks1 : Uint8Array [ ] = [ ] ;
526+ let readResult1 : ReadableStreamReadResult < Uint8Array > ;
527+ while ( ! ( readResult1 = await reader1 . read ( ) ) . done ) {
528+ chunks1 . push ( readResult1 . value ) ;
529+ }
530+ const content1 = new TextDecoder ( ) . decode (
531+ new Uint8Array ( chunks1 . flatMap ( ( c ) => Array . from ( c ) ) ) ,
532+ ) ;
517533 expect ( content1 ) . toBe ( "concurrent-1" ) ;
518534
519- const content2 = await fromReadableStream ( results [ 3 ] ! . value ) ;
535+ // Convert stream 2 to text
536+ const reader2 = results [ 3 ] ! . value . getReader ( ) ;
537+ const chunks2 : Uint8Array [ ] = [ ] ;
538+ let readResult2 : ReadableStreamReadResult < Uint8Array > ;
539+ while ( ! ( readResult2 = await reader2 . read ( ) ) . done ) {
540+ chunks2 . push ( readResult2 . value ) ;
541+ }
542+ const content2 = new TextDecoder ( ) . decode (
543+ new Uint8Array ( chunks2 . flatMap ( ( c ) => Array . from ( c ) ) ) ,
544+ ) ;
520545 expect ( content2 ) . toBe ( "concurrent-2" ) ;
521546 } ) ;
522547 } ) ;
0 commit comments