| | import { |
| | arrayBufferToString, |
| | stringToUint8Array, |
| | } from '../app-render/encryption-utils' |
| | import type { CacheEntry } from '../lib/cache-handlers/types' |
| | import type { CachedFetchValue } from '../response-cache/types' |
| | import { DYNAMIC_EXPIRE } from '../use-cache/constants' |
| |
|
| | |
| | |
| | |
| | type CacheStore<T> = Pick< |
| | Map<string, T>, |
| | 'entries' | 'keys' | 'size' | 'get' | 'set' |
| | > |
| |
|
| | |
| | |
| | |
| | export type FetchCacheStore = CacheStore<CachedFetchValue> |
| |
|
| | |
| | |
| | |
| | export type EncryptedBoundArgsCacheStore = CacheStore<string> |
| |
|
| | |
| | |
| | |
| | |
| | export type DecryptedBoundArgsCacheStore = CacheStore<string> |
| |
|
| | |
| | |
| | |
| | export interface UseCacheCacheStoreSerialized { |
| | value: string |
| | tags: string[] |
| | stale: number |
| | timestamp: number |
| | expire: number |
| | revalidate: number |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | export type UseCacheCacheStore = CacheStore<Promise<CacheEntry>> |
| |
|
| | |
| | |
| | |
| | |
| | |
| | export function parseUseCacheCacheStore( |
| | entries: Iterable<[string, UseCacheCacheStoreSerialized]> |
| | ): UseCacheCacheStore { |
| | const store = new Map<string, Promise<CacheEntry>>() |
| |
|
| | for (const [ |
| | key, |
| | { value, tags, stale, timestamp, expire, revalidate }, |
| | ] of entries) { |
| | store.set( |
| | key, |
| | Promise.resolve({ |
| | |
| | value: new ReadableStream<Uint8Array>({ |
| | start(controller) { |
| | |
| | controller.enqueue(stringToUint8Array(atob(value))) |
| |
|
| | |
| | controller.close() |
| | }, |
| | }), |
| | tags, |
| | stale, |
| | timestamp, |
| | expire, |
| | revalidate, |
| | }) |
| | ) |
| | } |
| |
|
| | return store |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | export async function serializeUseCacheCacheStore( |
| | entries: IterableIterator<[string, Promise<CacheEntry>]>, |
| | isCacheComponentsEnabled: boolean |
| | ): Promise<Array<[string, UseCacheCacheStoreSerialized] | null>> { |
| | return Promise.all( |
| | Array.from(entries).map(([key, value]) => { |
| | return value |
| | .then(async (entry) => { |
| | if ( |
| | isCacheComponentsEnabled && |
| | (entry.revalidate === 0 || entry.expire < DYNAMIC_EXPIRE) |
| | ) { |
| | |
| | |
| | return null |
| | } |
| |
|
| | const [left, right] = entry.value.tee() |
| | entry.value = right |
| |
|
| | let binaryString: string = '' |
| |
|
| | |
| | |
| | |
| | for await (const chunk of left) { |
| | binaryString += arrayBufferToString(chunk) |
| | } |
| |
|
| | return [ |
| | key, |
| | { |
| | |
| | value: btoa(binaryString), |
| | tags: entry.tags, |
| | stale: entry.stale, |
| | timestamp: entry.timestamp, |
| | expire: entry.expire, |
| | revalidate: entry.revalidate, |
| | }, |
| | ] satisfies [string, UseCacheCacheStoreSerialized] |
| | }) |
| | .catch(() => { |
| | |
| | |
| | return null |
| | }) |
| | }) |
| | ) |
| | } |
| |
|