@revealui/cache 0.0.0-canary-20260409021642
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +88 -0
- package/dist/adapters/index.d.ts +72 -0
- package/dist/adapters/index.js +195 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/index.d.ts +448 -0
- package/dist/index.js +926 -0
- package/dist/index.js.map +1 -0
- package/dist/types-CmU1eRbl.d.ts +34 -0
- package/package.json +57 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
import { C as CacheStore } from './types-CmU1eRbl.js';
|
|
2
|
+
export { a as CacheEntry } from './types-CmU1eRbl.js';
|
|
3
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* CDN Configuration and Cache Management
|
|
7
|
+
*
|
|
8
|
+
* Utilities for CDN caching, edge caching, and cache invalidation
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* CDN Cache Configuration
|
|
12
|
+
*/
|
|
13
|
+
interface CDNCacheConfig {
|
|
14
|
+
provider?: 'cloudflare' | 'vercel' | 'fastly' | 'custom';
|
|
15
|
+
zones?: string[];
|
|
16
|
+
ttl?: number;
|
|
17
|
+
staleWhileRevalidate?: number;
|
|
18
|
+
staleIfError?: number;
|
|
19
|
+
bypassCache?: boolean;
|
|
20
|
+
cacheKey?: string[];
|
|
21
|
+
varyHeaders?: string[];
|
|
22
|
+
}
|
|
23
|
+
declare const DEFAULT_CDN_CONFIG: CDNCacheConfig;
|
|
24
|
+
/**
|
|
25
|
+
* Generate Cache-Control header
|
|
26
|
+
*/
|
|
27
|
+
declare function generateCacheControl(config: {
|
|
28
|
+
maxAge?: number;
|
|
29
|
+
sMaxAge?: number;
|
|
30
|
+
staleWhileRevalidate?: number;
|
|
31
|
+
staleIfError?: number;
|
|
32
|
+
public?: boolean;
|
|
33
|
+
private?: boolean;
|
|
34
|
+
immutable?: boolean;
|
|
35
|
+
noCache?: boolean;
|
|
36
|
+
noStore?: boolean;
|
|
37
|
+
}): string;
|
|
38
|
+
/**
|
|
39
|
+
* Cache presets for different asset types
|
|
40
|
+
*/
|
|
41
|
+
declare const CDN_CACHE_PRESETS: {
|
|
42
|
+
readonly immutable: {
|
|
43
|
+
readonly maxAge: 31536000;
|
|
44
|
+
readonly sMaxAge: 31536000;
|
|
45
|
+
readonly public: true;
|
|
46
|
+
readonly immutable: true;
|
|
47
|
+
};
|
|
48
|
+
readonly static: {
|
|
49
|
+
readonly maxAge: 2592000;
|
|
50
|
+
readonly sMaxAge: 31536000;
|
|
51
|
+
readonly staleWhileRevalidate: 86400;
|
|
52
|
+
readonly public: true;
|
|
53
|
+
};
|
|
54
|
+
readonly api: {
|
|
55
|
+
readonly maxAge: 0;
|
|
56
|
+
readonly sMaxAge: 60;
|
|
57
|
+
readonly staleWhileRevalidate: 30;
|
|
58
|
+
readonly public: true;
|
|
59
|
+
};
|
|
60
|
+
readonly page: {
|
|
61
|
+
readonly maxAge: 0;
|
|
62
|
+
readonly sMaxAge: 300;
|
|
63
|
+
readonly staleWhileRevalidate: 60;
|
|
64
|
+
readonly public: true;
|
|
65
|
+
};
|
|
66
|
+
readonly private: {
|
|
67
|
+
readonly maxAge: 300;
|
|
68
|
+
readonly private: true;
|
|
69
|
+
readonly staleWhileRevalidate: 60;
|
|
70
|
+
};
|
|
71
|
+
readonly noCache: {
|
|
72
|
+
readonly noStore: true;
|
|
73
|
+
};
|
|
74
|
+
readonly revalidate: {
|
|
75
|
+
readonly maxAge: 0;
|
|
76
|
+
readonly sMaxAge: 0;
|
|
77
|
+
readonly noCache: true;
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* CDN Purge Configuration
|
|
82
|
+
*/
|
|
83
|
+
interface CDNPurgeConfig {
|
|
84
|
+
provider: 'cloudflare' | 'vercel' | 'fastly';
|
|
85
|
+
apiKey?: string;
|
|
86
|
+
apiSecret?: string;
|
|
87
|
+
zoneId?: string;
|
|
88
|
+
distributionId?: string;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Purge CDN cache
|
|
92
|
+
*/
|
|
93
|
+
declare function purgeCDNCache(urls: string[], config: CDNPurgeConfig): Promise<{
|
|
94
|
+
success: boolean;
|
|
95
|
+
purged: number;
|
|
96
|
+
errors?: string[];
|
|
97
|
+
}>;
|
|
98
|
+
/**
|
|
99
|
+
* Purge by cache tag
|
|
100
|
+
*/
|
|
101
|
+
declare function purgeCacheByTag(tags: string[], config: CDNPurgeConfig): Promise<{
|
|
102
|
+
success: boolean;
|
|
103
|
+
purged: number;
|
|
104
|
+
errors?: string[];
|
|
105
|
+
}>;
|
|
106
|
+
/**
|
|
107
|
+
* Purge everything
|
|
108
|
+
*/
|
|
109
|
+
declare function purgeAllCache(config: CDNPurgeConfig): Promise<{
|
|
110
|
+
success: boolean;
|
|
111
|
+
errors?: string[];
|
|
112
|
+
}>;
|
|
113
|
+
/**
|
|
114
|
+
* CDN cache warming
|
|
115
|
+
*/
|
|
116
|
+
declare function warmCDNCache(urls: string[], options?: {
|
|
117
|
+
concurrency?: number;
|
|
118
|
+
headers?: Record<string, string>;
|
|
119
|
+
}): Promise<{
|
|
120
|
+
warmed: number;
|
|
121
|
+
failed: number;
|
|
122
|
+
errors: string[];
|
|
123
|
+
}>;
|
|
124
|
+
/**
|
|
125
|
+
* Generate cache tags
|
|
126
|
+
*/
|
|
127
|
+
declare function generateCacheTags(resource: {
|
|
128
|
+
type: string;
|
|
129
|
+
id?: string | number;
|
|
130
|
+
related?: string[];
|
|
131
|
+
}): string[];
|
|
132
|
+
/**
|
|
133
|
+
* Edge cache configuration for Vercel
|
|
134
|
+
*/
|
|
135
|
+
declare function generateVercelCacheConfig(preset: keyof typeof CDN_CACHE_PRESETS): {
|
|
136
|
+
headers: {
|
|
137
|
+
'Cache-Control': string;
|
|
138
|
+
'CDN-Cache-Control': string;
|
|
139
|
+
'Vercel-CDN-Cache-Control': string;
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* Edge cache configuration for Cloudflare
|
|
144
|
+
*/
|
|
145
|
+
declare function generateCloudflareConfig(preset: keyof typeof CDN_CACHE_PRESETS, options?: {
|
|
146
|
+
cacheTags?: string[];
|
|
147
|
+
bypassOnCookie?: string;
|
|
148
|
+
}): {
|
|
149
|
+
headers: Record<string, string>;
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* Check if response should be cached
|
|
153
|
+
*/
|
|
154
|
+
declare function shouldCacheResponse(status: number, headers: Headers): boolean;
|
|
155
|
+
/**
|
|
156
|
+
* Calculate cache TTL from headers
|
|
157
|
+
*/
|
|
158
|
+
declare function getCacheTTL(headers: Headers): number;
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Edge Caching and ISR (Incremental Static Regeneration)
|
|
162
|
+
*
|
|
163
|
+
* Utilities for Next.js edge caching, ISR, and on-demand revalidation
|
|
164
|
+
*/
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Next.js extends the standard RequestInit with a `next` property
|
|
168
|
+
* for ISR revalidation and cache tags.
|
|
169
|
+
*/
|
|
170
|
+
interface NextFetchRequestInit extends RequestInit {
|
|
171
|
+
next?: {
|
|
172
|
+
revalidate?: number | false;
|
|
173
|
+
tags?: string[];
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* ISR Configuration
|
|
178
|
+
*/
|
|
179
|
+
interface ISRConfig {
|
|
180
|
+
revalidate?: number | false;
|
|
181
|
+
tags?: string[];
|
|
182
|
+
dynamicParams?: boolean;
|
|
183
|
+
}
|
|
184
|
+
declare const ISR_PRESETS: {
|
|
185
|
+
readonly always: {
|
|
186
|
+
readonly revalidate: 0;
|
|
187
|
+
};
|
|
188
|
+
readonly minute: {
|
|
189
|
+
readonly revalidate: 60;
|
|
190
|
+
};
|
|
191
|
+
readonly fiveMinutes: {
|
|
192
|
+
readonly revalidate: 300;
|
|
193
|
+
};
|
|
194
|
+
readonly hourly: {
|
|
195
|
+
readonly revalidate: 3600;
|
|
196
|
+
};
|
|
197
|
+
readonly daily: {
|
|
198
|
+
readonly revalidate: 86400;
|
|
199
|
+
};
|
|
200
|
+
readonly never: {
|
|
201
|
+
readonly revalidate: false;
|
|
202
|
+
};
|
|
203
|
+
};
|
|
204
|
+
/**
|
|
205
|
+
* Generate static params for ISR
|
|
206
|
+
*/
|
|
207
|
+
declare function generateStaticParams<T>(fetchFn: () => Promise<T[]>, mapFn: (item: T) => Record<string, string>): Promise<Array<Record<string, string>>>;
|
|
208
|
+
/**
|
|
209
|
+
* Revalidate tag
|
|
210
|
+
*/
|
|
211
|
+
declare function revalidateTag(tag: string, secret?: string): Promise<{
|
|
212
|
+
revalidated: boolean;
|
|
213
|
+
error?: string;
|
|
214
|
+
}>;
|
|
215
|
+
/**
|
|
216
|
+
* Revalidate path
|
|
217
|
+
*/
|
|
218
|
+
declare function revalidatePath(path: string, secret?: string): Promise<{
|
|
219
|
+
revalidated: boolean;
|
|
220
|
+
error?: string;
|
|
221
|
+
}>;
|
|
222
|
+
/**
|
|
223
|
+
* Revalidate multiple paths
|
|
224
|
+
*/
|
|
225
|
+
declare function revalidatePaths(paths: string[], secret?: string): Promise<{
|
|
226
|
+
revalidated: number;
|
|
227
|
+
failed: number;
|
|
228
|
+
errors: Array<{
|
|
229
|
+
path: string;
|
|
230
|
+
error: string;
|
|
231
|
+
}>;
|
|
232
|
+
}>;
|
|
233
|
+
/**
|
|
234
|
+
* Revalidate multiple tags
|
|
235
|
+
*/
|
|
236
|
+
declare function revalidateTags(tags: string[], secret?: string): Promise<{
|
|
237
|
+
revalidated: number;
|
|
238
|
+
failed: number;
|
|
239
|
+
errors: Array<{
|
|
240
|
+
tag: string;
|
|
241
|
+
error: string;
|
|
242
|
+
}>;
|
|
243
|
+
}>;
|
|
244
|
+
/**
|
|
245
|
+
* Edge middleware cache configuration
|
|
246
|
+
*/
|
|
247
|
+
interface EdgeCacheConfig {
|
|
248
|
+
cache?: 'force-cache' | 'no-cache' | 'no-store' | 'only-if-cached';
|
|
249
|
+
next?: {
|
|
250
|
+
revalidate?: number | false;
|
|
251
|
+
tags?: string[];
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Create edge cached fetch
|
|
256
|
+
*/
|
|
257
|
+
declare function createEdgeCachedFetch(config?: EdgeCacheConfig): <T>(url: string, options?: NextFetchRequestInit) => Promise<T>;
|
|
258
|
+
/**
|
|
259
|
+
* Unstable cache wrapper (Next.js 14+)
|
|
260
|
+
*/
|
|
261
|
+
declare function createCachedFunction<TArgs extends unknown[], TReturn>(fn: (...args: TArgs) => Promise<TReturn>, options?: {
|
|
262
|
+
tags?: string[];
|
|
263
|
+
revalidate?: number | false;
|
|
264
|
+
}): (...args: TArgs) => Promise<TReturn>;
|
|
265
|
+
/**
|
|
266
|
+
* Edge rate limiting with cache
|
|
267
|
+
*/
|
|
268
|
+
interface EdgeRateLimitConfig {
|
|
269
|
+
limit: number;
|
|
270
|
+
window: number;
|
|
271
|
+
key?: (request: NextRequest) => string;
|
|
272
|
+
}
|
|
273
|
+
declare class EdgeRateLimiter {
|
|
274
|
+
private config;
|
|
275
|
+
private cache;
|
|
276
|
+
constructor(config: EdgeRateLimitConfig);
|
|
277
|
+
/**
|
|
278
|
+
* Check rate limit
|
|
279
|
+
*/
|
|
280
|
+
check(request: NextRequest): {
|
|
281
|
+
allowed: boolean;
|
|
282
|
+
limit: number;
|
|
283
|
+
remaining: number;
|
|
284
|
+
reset: number;
|
|
285
|
+
};
|
|
286
|
+
/**
|
|
287
|
+
* Clean up expired entries
|
|
288
|
+
*/
|
|
289
|
+
cleanup(): void;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Edge geolocation caching
|
|
293
|
+
*/
|
|
294
|
+
interface GeoLocation {
|
|
295
|
+
country?: string;
|
|
296
|
+
region?: string;
|
|
297
|
+
city?: string;
|
|
298
|
+
latitude?: number;
|
|
299
|
+
longitude?: number;
|
|
300
|
+
}
|
|
301
|
+
declare function getGeoLocation(request: NextRequest): GeoLocation | null;
|
|
302
|
+
/**
|
|
303
|
+
* Edge A/B testing with cache
|
|
304
|
+
*/
|
|
305
|
+
declare function getABTestVariant(request: NextRequest, testName: string, variants: string[]): string;
|
|
306
|
+
/**
|
|
307
|
+
* Edge personalization cache
|
|
308
|
+
*/
|
|
309
|
+
interface PersonalizationConfig {
|
|
310
|
+
userId?: string;
|
|
311
|
+
preferences?: Record<string, unknown>;
|
|
312
|
+
location?: GeoLocation;
|
|
313
|
+
device?: 'mobile' | 'tablet' | 'desktop';
|
|
314
|
+
variant?: string;
|
|
315
|
+
}
|
|
316
|
+
declare function getPersonalizationConfig(request: NextRequest): PersonalizationConfig;
|
|
317
|
+
/**
|
|
318
|
+
* Edge cache headers helper
|
|
319
|
+
*/
|
|
320
|
+
declare function setEdgeCacheHeaders(response: NextResponse, config: {
|
|
321
|
+
maxAge?: number;
|
|
322
|
+
sMaxAge?: number;
|
|
323
|
+
staleWhileRevalidate?: number;
|
|
324
|
+
tags?: string[];
|
|
325
|
+
}): NextResponse;
|
|
326
|
+
/**
|
|
327
|
+
* Preload links for critical resources
|
|
328
|
+
*/
|
|
329
|
+
declare function addPreloadLinks(response: NextResponse, resources: Array<{
|
|
330
|
+
href: string;
|
|
331
|
+
as: string;
|
|
332
|
+
type?: string;
|
|
333
|
+
crossorigin?: boolean;
|
|
334
|
+
}>): NextResponse;
|
|
335
|
+
/**
|
|
336
|
+
* Cache warming for ISR pages
|
|
337
|
+
*/
|
|
338
|
+
declare function warmISRCache(paths: string[], baseURL?: string): Promise<{
|
|
339
|
+
warmed: number;
|
|
340
|
+
failed: number;
|
|
341
|
+
errors: Array<{
|
|
342
|
+
path: string;
|
|
343
|
+
error: string;
|
|
344
|
+
}>;
|
|
345
|
+
}>;
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Cache Invalidation Channel
|
|
349
|
+
*
|
|
350
|
+
* Coordinates cache invalidation across instances using a shared database table.
|
|
351
|
+
* Events are written to `_cache_invalidation_events` and consumed by polling.
|
|
352
|
+
*
|
|
353
|
+
* Architecture:
|
|
354
|
+
* - Publisher: writes invalidation event to shared PGlite/PostgreSQL table
|
|
355
|
+
* - Subscriber: polls the table for new events and forwards to local CacheStore
|
|
356
|
+
* - Events auto-expire after TTL to prevent unbounded table growth
|
|
357
|
+
*
|
|
358
|
+
* Future: Replace polling with ElectricSQL shape subscriptions or LISTEN/NOTIFY
|
|
359
|
+
* for real-time push-based invalidation (Phase 5.10C/E).
|
|
360
|
+
*/
|
|
361
|
+
|
|
362
|
+
type InvalidationEventType = 'delete' | 'delete-prefix' | 'delete-tags' | 'clear';
|
|
363
|
+
interface InvalidationEvent {
|
|
364
|
+
id: string;
|
|
365
|
+
type: InvalidationEventType;
|
|
366
|
+
/** Cache keys to delete (for 'delete' type). */
|
|
367
|
+
keys?: string[];
|
|
368
|
+
/** Prefix to match (for 'delete-prefix' type). */
|
|
369
|
+
prefix?: string;
|
|
370
|
+
/** Tags to match (for 'delete-tags' type). */
|
|
371
|
+
tags?: string[];
|
|
372
|
+
/** Instance ID that published the event (for deduplication). */
|
|
373
|
+
sourceInstance: string;
|
|
374
|
+
/** Timestamp when the event was created. */
|
|
375
|
+
createdAt: number;
|
|
376
|
+
}
|
|
377
|
+
interface InvalidationChannelOptions {
|
|
378
|
+
/** Unique instance identifier (used to skip self-published events). */
|
|
379
|
+
instanceId: string;
|
|
380
|
+
/** Poll interval in milliseconds (default: 5000). */
|
|
381
|
+
pollIntervalMs?: number;
|
|
382
|
+
/** Event TTL in seconds — events older than this are pruned (default: 60). */
|
|
383
|
+
eventTtlSeconds?: number;
|
|
384
|
+
}
|
|
385
|
+
interface PGliteInstance {
|
|
386
|
+
exec(query: string): Promise<unknown>;
|
|
387
|
+
query<T = Record<string, unknown>>(query: string, params?: unknown[]): Promise<{
|
|
388
|
+
rows: T[];
|
|
389
|
+
}>;
|
|
390
|
+
close(): Promise<void>;
|
|
391
|
+
}
|
|
392
|
+
declare class CacheInvalidationChannel {
|
|
393
|
+
private db;
|
|
394
|
+
private store;
|
|
395
|
+
private instanceId;
|
|
396
|
+
private pollIntervalMs;
|
|
397
|
+
private eventTtlSeconds;
|
|
398
|
+
private lastSeenTimestamp;
|
|
399
|
+
/** IDs processed at exactly lastSeenTimestamp (prevents re-processing on >= query). */
|
|
400
|
+
private processedAtBoundary;
|
|
401
|
+
private pollTimer;
|
|
402
|
+
private ready;
|
|
403
|
+
constructor(db: PGliteInstance, store: CacheStore, options: InvalidationChannelOptions);
|
|
404
|
+
private init;
|
|
405
|
+
/** Start polling for invalidation events. */
|
|
406
|
+
start(): Promise<void>;
|
|
407
|
+
/** Stop polling. */
|
|
408
|
+
stop(): void;
|
|
409
|
+
/** Publish a key deletion event. */
|
|
410
|
+
publishDelete(...keys: string[]): Promise<void>;
|
|
411
|
+
/** Publish a prefix deletion event. */
|
|
412
|
+
publishDeletePrefix(prefix: string): Promise<void>;
|
|
413
|
+
/** Publish a tag-based deletion event. */
|
|
414
|
+
publishDeleteTags(tags: string[]): Promise<void>;
|
|
415
|
+
/** Publish a clear-all event. */
|
|
416
|
+
publishClear(): Promise<void>;
|
|
417
|
+
private publish;
|
|
418
|
+
/** Poll for new events and apply them to the local cache store. */
|
|
419
|
+
poll(): Promise<number>;
|
|
420
|
+
private applyEvent;
|
|
421
|
+
/** Remove events older than the TTL. */
|
|
422
|
+
private prune;
|
|
423
|
+
/** Release resources. */
|
|
424
|
+
close(): Promise<void>;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Internal logger for @revealui/cache.
|
|
429
|
+
*
|
|
430
|
+
* Defaults to `console`. Consumers should call `configureCacheLogger()`
|
|
431
|
+
* to supply a structured logger (e.g. from `@revealui/utils/logger`).
|
|
432
|
+
*/
|
|
433
|
+
interface CacheLogger {
|
|
434
|
+
warn(message: string, ...args: unknown[]): void;
|
|
435
|
+
error(message: string, ...args: unknown[]): void;
|
|
436
|
+
info(message: string, ...args: unknown[]): void;
|
|
437
|
+
debug(message: string, ...args: unknown[]): void;
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Replace the default console logger with a structured logger.
|
|
441
|
+
*/
|
|
442
|
+
declare function configureCacheLogger(logger: CacheLogger): void;
|
|
443
|
+
/**
|
|
444
|
+
* Get the current cache logger instance.
|
|
445
|
+
*/
|
|
446
|
+
declare function getCacheLogger(): CacheLogger;
|
|
447
|
+
|
|
448
|
+
export { type CDNCacheConfig, type CDNPurgeConfig, CDN_CACHE_PRESETS, CacheInvalidationChannel, type CacheLogger, CacheStore, DEFAULT_CDN_CONFIG, type EdgeCacheConfig, type EdgeRateLimitConfig, EdgeRateLimiter, type GeoLocation, type ISRConfig, ISR_PRESETS, type InvalidationChannelOptions, type InvalidationEvent, type InvalidationEventType, type PersonalizationConfig, addPreloadLinks, configureCacheLogger, createCachedFunction, createEdgeCachedFetch, generateCacheControl, generateCacheTags, generateCloudflareConfig, generateStaticParams, generateVercelCacheConfig, getABTestVariant, getCacheLogger, getCacheTTL, getGeoLocation, getPersonalizationConfig, purgeAllCache, purgeCDNCache, purgeCacheByTag, revalidatePath, revalidatePaths, revalidateTag, revalidateTags, setEdgeCacheHeaders, shouldCacheResponse, warmCDNCache, warmISRCache };
|