@gravito/stasis 1.0.0-beta.4 → 1.0.0-beta.6

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.
@@ -0,0 +1,450 @@
1
+ import { PlanetCore, GravitoOrbit } from 'gravito-core';
2
+
3
+ declare class LockTimeoutError extends Error {
4
+ name: string;
5
+ }
6
+ interface CacheLock {
7
+ acquire(): Promise<boolean>;
8
+ release(): Promise<void>;
9
+ block<T>(seconds: number, callback: () => Promise<T> | T, options?: {
10
+ sleepMillis?: number;
11
+ }): Promise<T>;
12
+ }
13
+ declare function sleep(ms: number): Promise<void>;
14
+
15
+ type CacheKey = string;
16
+ /**
17
+ * Laravel-like TTL:
18
+ * - `number` = seconds from now
19
+ * - `Date` = absolute expiry time
20
+ * - `null` = forever
21
+ * - `undefined` = store default / repository default (when applicable)
22
+ */
23
+ type CacheTtl = number | Date | null | undefined;
24
+ type CacheValue<T = unknown> = T | null;
25
+ declare function normalizeCacheKey(key: string): string;
26
+ declare function ttlToExpiresAt(ttl: CacheTtl, now?: number): number | null | undefined;
27
+ declare function isExpired(expiresAt: number | null | undefined, now?: number): boolean;
28
+
29
+ interface CacheStore {
30
+ get<T = unknown>(key: CacheKey): Promise<CacheValue<T>>;
31
+ put(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<void>;
32
+ add(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<boolean>;
33
+ forget(key: CacheKey): Promise<boolean>;
34
+ flush(): Promise<void>;
35
+ increment(key: CacheKey, value?: number): Promise<number>;
36
+ decrement(key: CacheKey, value?: number): Promise<number>;
37
+ lock?(name: string, seconds?: number): CacheLock | undefined;
38
+ }
39
+ interface TaggableStore {
40
+ flushTags(tags: readonly string[]): Promise<void>;
41
+ tagKey(key: string, tags: readonly string[]): string;
42
+ tagIndexAdd(tags: readonly string[], taggedKey: string): void;
43
+ tagIndexRemove(taggedKey: string): void;
44
+ }
45
+ declare function isTaggableStore(store: CacheStore): store is CacheStore & TaggableStore;
46
+
47
+ type CacheEventMode = 'sync' | 'async' | 'off';
48
+ type CacheEvents = {
49
+ hit?: (key: string) => void | Promise<void>;
50
+ miss?: (key: string) => void | Promise<void>;
51
+ write?: (key: string) => void | Promise<void>;
52
+ forget?: (key: string) => void | Promise<void>;
53
+ flush?: () => void | Promise<void>;
54
+ };
55
+ type CacheRepositoryOptions = {
56
+ prefix?: string;
57
+ defaultTtl?: CacheTtl;
58
+ events?: CacheEvents;
59
+ eventsMode?: CacheEventMode;
60
+ throwOnEventError?: boolean;
61
+ onEventError?: (error: unknown, event: keyof CacheEvents, payload: {
62
+ key?: string;
63
+ }) => void;
64
+ };
65
+ declare class CacheRepository {
66
+ protected readonly store: CacheStore;
67
+ protected readonly options: CacheRepositoryOptions;
68
+ constructor(store: CacheStore, options?: CacheRepositoryOptions);
69
+ private emit;
70
+ protected key(key: CacheKey): string;
71
+ protected flexibleFreshUntilKey(fullKey: string): string;
72
+ protected putMetaKey(metaKey: string, value: unknown, ttl: CacheTtl): Promise<void>;
73
+ protected forgetMetaKey(metaKey: string): Promise<void>;
74
+ get<T = unknown>(key: CacheKey, defaultValue?: T | (() => T | Promise<T>)): Promise<T | null>;
75
+ has(key: CacheKey): Promise<boolean>;
76
+ missing(key: CacheKey): Promise<boolean>;
77
+ put(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<void>;
78
+ set(key: CacheKey, value: unknown, ttl?: CacheTtl): Promise<void>;
79
+ add(key: CacheKey, value: unknown, ttl?: CacheTtl): Promise<boolean>;
80
+ forever(key: CacheKey, value: unknown): Promise<void>;
81
+ remember<T = unknown>(key: CacheKey, ttl: CacheTtl, callback: () => Promise<T> | T): Promise<T>;
82
+ rememberForever<T = unknown>(key: CacheKey, callback: () => Promise<T> | T): Promise<T>;
83
+ many<T = unknown>(keys: readonly CacheKey[]): Promise<Record<string, T | null>>;
84
+ putMany(values: Record<string, unknown>, ttl: CacheTtl): Promise<void>;
85
+ /**
86
+ * Laravel-like flexible cache (stale-while-revalidate).
87
+ *
88
+ * - `ttlSeconds`: how long the value is considered fresh
89
+ * - `staleSeconds`: how long the stale value may be served while a refresh happens
90
+ */
91
+ flexible<T = unknown>(key: CacheKey, ttlSeconds: number, staleSeconds: number, callback: () => Promise<T> | T): Promise<T>;
92
+ private refreshFlexible;
93
+ pull<T = unknown>(key: CacheKey, defaultValue?: T): Promise<T | null>;
94
+ forget(key: CacheKey): Promise<boolean>;
95
+ delete(key: CacheKey): Promise<boolean>;
96
+ flush(): Promise<void>;
97
+ clear(): Promise<void>;
98
+ increment(key: string, value?: number): Promise<number>;
99
+ decrement(key: string, value?: number): Promise<number>;
100
+ lock(name: string, seconds?: number): CacheLock | undefined;
101
+ tags(tags: readonly string[]): CacheRepository;
102
+ /**
103
+ * Get the underlying store
104
+ */
105
+ getStore(): CacheStore;
106
+ }
107
+
108
+ interface RateLimiterResponse {
109
+ allowed: boolean;
110
+ remaining: number;
111
+ reset: number;
112
+ }
113
+ declare class RateLimiter {
114
+ private store;
115
+ constructor(store: CacheStore);
116
+ /**
117
+ * Attempt to acquire a lock
118
+ * @param key - The unique key (e.g., "ip:127.0.0.1")
119
+ * @param maxAttempts - Maximum number of attempts allowed
120
+ * @param decaySeconds - Time in seconds until the limit resets
121
+ */
122
+ attempt(key: string, maxAttempts: number, decaySeconds: number): Promise<RateLimiterResponse>;
123
+ /**
124
+ * Clear the limiter for a key
125
+ */
126
+ clear(key: string): Promise<void>;
127
+ }
128
+
129
+ type StoreConfig = {
130
+ driver: 'memory';
131
+ maxItems?: number;
132
+ } | {
133
+ driver: 'file';
134
+ directory: string;
135
+ } | {
136
+ driver: 'redis';
137
+ connection?: string;
138
+ prefix?: string;
139
+ } | {
140
+ driver: 'null';
141
+ } | {
142
+ driver: 'provider';
143
+ };
144
+ type CacheConfig = {
145
+ default?: string;
146
+ prefix?: string;
147
+ defaultTtl?: CacheTtl;
148
+ stores?: Record<string, StoreConfig & {
149
+ provider?: CacheStore;
150
+ }>;
151
+ };
152
+ declare class CacheManager {
153
+ private readonly storeFactory;
154
+ private readonly config;
155
+ private readonly events?;
156
+ private readonly eventOptions?;
157
+ private stores;
158
+ constructor(storeFactory: (name: string) => CacheStore, config?: CacheConfig, events?: CacheEvents | undefined, eventOptions?: {
159
+ mode?: CacheEventMode;
160
+ throwOnError?: boolean;
161
+ onError?: (error: unknown, event: keyof CacheEvents, payload: {
162
+ key?: string;
163
+ }) => void;
164
+ } | undefined);
165
+ /**
166
+ * Get a rate limiter instance for a store
167
+ * @param name - Store name (optional, defaults to default store)
168
+ */
169
+ limiter(name?: string): RateLimiter;
170
+ store(name?: string): CacheRepository;
171
+ /**
172
+ * Retrieve an item from the cache.
173
+ *
174
+ * @param key - The unique cache key.
175
+ * @param defaultValue - The default value if the key is missing (can be a value or a closure).
176
+ * @returns The cached value or the default.
177
+ *
178
+ * @example
179
+ * ```typescript
180
+ * const value = await cache.get('user:1', { name: 'Guest' });
181
+ * ```
182
+ */
183
+ get<T = unknown>(key: string, defaultValue?: T | (() => T | Promise<T>)): Promise<T | null>;
184
+ /**
185
+ * Check if an item exists in the cache.
186
+ */
187
+ has(key: string): Promise<boolean>;
188
+ /**
189
+ * Check if an item is missing from the cache.
190
+ */
191
+ missing(key: string): Promise<boolean>;
192
+ /**
193
+ * Store an item in the cache.
194
+ *
195
+ * @param key - The unique cache key.
196
+ * @param value - The value to store.
197
+ * @param ttl - Time to live in seconds (or Date).
198
+ *
199
+ * @example
200
+ * ```typescript
201
+ * await cache.put('key', 'value', 60); // 60 seconds
202
+ * ```
203
+ */
204
+ put(key: string, value: unknown, ttl: CacheTtl): Promise<void>;
205
+ /**
206
+ * Store an item in the cache (alias for put with optional TTL).
207
+ */
208
+ set(key: string, value: unknown, ttl?: CacheTtl): Promise<void>;
209
+ /**
210
+ * Store an item in the cache if it doesn't already exist.
211
+ *
212
+ * @returns True if added, false if it already existed.
213
+ */
214
+ add(key: string, value: unknown, ttl?: CacheTtl): Promise<boolean>;
215
+ /**
216
+ * Store an item in the cache indefinitely.
217
+ */
218
+ forever(key: string, value: unknown): Promise<void>;
219
+ /**
220
+ * Get an item from the cache, or execute the callback and store the result.
221
+ *
222
+ * @param key - The cache key.
223
+ * @param ttl - Time to live if the item is missing.
224
+ * @param callback - Closure to execute on miss.
225
+ * @returns The cached or fetched value.
226
+ *
227
+ * @example
228
+ * ```typescript
229
+ * const user = await cache.remember('user:1', 60, async () => {
230
+ * return await db.findUser(1);
231
+ * });
232
+ * ```
233
+ */
234
+ remember<T = unknown>(key: string, ttl: CacheTtl, callback: () => Promise<T> | T): Promise<T>;
235
+ /**
236
+ * Get an item from the cache, or execute the callback and store the result forever.
237
+ */
238
+ rememberForever<T = unknown>(key: string, callback: () => Promise<T> | T): Promise<T>;
239
+ /**
240
+ * Retrieve multiple items from the cache.
241
+ */
242
+ many<T = unknown>(keys: readonly string[]): Promise<Record<string, T | null>>;
243
+ /**
244
+ * Store multiple items in the cache.
245
+ */
246
+ putMany(values: Record<string, unknown>, ttl: CacheTtl): Promise<void>;
247
+ /**
248
+ * Get an item from the cache, allowing stale data while refreshing in background.
249
+ *
250
+ * @param key - Cache key.
251
+ * @param ttlSeconds - How long the value is considered fresh.
252
+ * @param staleSeconds - How long to serve stale data while refreshing.
253
+ * @param callback - Closure to refresh the data.
254
+ */
255
+ flexible<T = unknown>(key: string, ttlSeconds: number, staleSeconds: number, callback: () => Promise<T> | T): Promise<T>;
256
+ /**
257
+ * Retrieve an item from the cache and delete it.
258
+ */
259
+ pull<T = unknown>(key: string, defaultValue?: T): Promise<T | null>;
260
+ /**
261
+ * Remove an item from the cache.
262
+ */
263
+ forget(key: string): Promise<boolean>;
264
+ /**
265
+ * Remove an item from the cache (alias for forget).
266
+ */
267
+ delete(key: string): Promise<boolean>;
268
+ /**
269
+ * Remove all items from the cache.
270
+ */
271
+ flush(): Promise<void>;
272
+ /**
273
+ * Clear the entire cache (alias for flush).
274
+ */
275
+ clear(): Promise<void>;
276
+ /**
277
+ * Increment an integer item in the cache.
278
+ */
279
+ increment(key: string, value?: number): Promise<number>;
280
+ /**
281
+ * Decrement an integer item in the cache.
282
+ */
283
+ decrement(key: string, value?: number): Promise<number>;
284
+ /**
285
+ * Get a lock instance.
286
+ *
287
+ * @param name - Lock name.
288
+ * @param seconds - Lock duration.
289
+ * @returns CacheLock instance.
290
+ */
291
+ lock(name: string, seconds?: number): CacheLock | undefined;
292
+ /**
293
+ * Access a tagged cache section (only supported by some stores).
294
+ */
295
+ tags(tags: readonly string[]): CacheRepository;
296
+ }
297
+
298
+ type FileStoreOptions = {
299
+ directory: string;
300
+ };
301
+ declare class FileStore implements CacheStore {
302
+ private options;
303
+ constructor(options: FileStoreOptions);
304
+ private ensureDir;
305
+ private filePathForKey;
306
+ get<T = unknown>(key: CacheKey): Promise<CacheValue<T>>;
307
+ put(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<void>;
308
+ add(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<boolean>;
309
+ forget(key: CacheKey): Promise<boolean>;
310
+ flush(): Promise<void>;
311
+ increment(key: CacheKey, value?: number): Promise<number>;
312
+ decrement(key: CacheKey, value?: number): Promise<number>;
313
+ lock(name: string, seconds?: number): CacheLock;
314
+ }
315
+
316
+ type MemoryStoreOptions = {
317
+ maxItems?: number;
318
+ };
319
+ declare class MemoryStore implements CacheStore, TaggableStore {
320
+ private options;
321
+ private entries;
322
+ private locks;
323
+ private tagToKeys;
324
+ private keyToTags;
325
+ constructor(options?: MemoryStoreOptions);
326
+ private touchLRU;
327
+ private pruneIfNeeded;
328
+ private cleanupExpired;
329
+ get<T = unknown>(key: CacheKey): Promise<CacheValue<T>>;
330
+ put(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<void>;
331
+ add(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<boolean>;
332
+ forget(key: CacheKey): Promise<boolean>;
333
+ flush(): Promise<void>;
334
+ increment(key: CacheKey, value?: number): Promise<number>;
335
+ decrement(key: CacheKey, value?: number): Promise<number>;
336
+ lock(name: string, seconds?: number): CacheLock;
337
+ tagKey(key: string, tags: readonly string[]): string;
338
+ tagIndexAdd(tags: readonly string[], taggedKey: string): void;
339
+ tagIndexRemove(taggedKey: string): void;
340
+ flushTags(tags: readonly string[]): Promise<void>;
341
+ }
342
+
343
+ declare class NullStore implements CacheStore {
344
+ get<T = unknown>(_key: CacheKey): Promise<CacheValue<T>>;
345
+ put(_key: CacheKey, _value: unknown, _ttl: CacheTtl): Promise<void>;
346
+ add(_key: CacheKey, _value: unknown, _ttl: CacheTtl): Promise<boolean>;
347
+ forget(_key: CacheKey): Promise<boolean>;
348
+ flush(): Promise<void>;
349
+ increment(_key: CacheKey, _value?: number): Promise<number>;
350
+ decrement(_key: CacheKey, _value?: number): Promise<number>;
351
+ }
352
+
353
+ type RedisStoreOptions = {
354
+ connection?: string;
355
+ prefix?: string;
356
+ };
357
+ declare class RedisStore implements CacheStore, TaggableStore {
358
+ private connectionName?;
359
+ constructor(options?: RedisStoreOptions);
360
+ private get client();
361
+ get<T = unknown>(key: CacheKey): Promise<CacheValue<T>>;
362
+ put(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<void>;
363
+ add(key: CacheKey, value: unknown, ttl: CacheTtl): Promise<boolean>;
364
+ forget(key: CacheKey): Promise<boolean>;
365
+ flush(): Promise<void>;
366
+ increment(key: CacheKey, value?: number): Promise<number>;
367
+ decrement(key: CacheKey, value?: number): Promise<number>;
368
+ tagKey(key: string, _tags: readonly string[]): string;
369
+ tagIndexAdd(tags: readonly string[], taggedKey: string): Promise<void>;
370
+ tagIndexRemove(_taggedKey: string): Promise<void>;
371
+ flushTags(tags: readonly string[]): Promise<void>;
372
+ lock(name: string, seconds?: number): CacheLock;
373
+ }
374
+
375
+ interface CacheProvider {
376
+ get<T = unknown>(key: string): Promise<T | null>;
377
+ set(key: string, value: unknown, ttl?: number): Promise<void>;
378
+ delete(key: string): Promise<void>;
379
+ clear(): Promise<void>;
380
+ }
381
+ interface CacheService {
382
+ get<T = unknown>(key: string): Promise<T | null>;
383
+ set(key: string, value: unknown, ttl?: CacheTtl): Promise<void>;
384
+ delete(key: string): Promise<boolean>;
385
+ clear(): Promise<void>;
386
+ remember<T>(key: string, ttl: CacheTtl, callback: () => Promise<T> | T): Promise<T>;
387
+ }
388
+ declare class MemoryCacheProvider implements CacheProvider {
389
+ private store;
390
+ get<T = unknown>(key: string): Promise<T | null>;
391
+ set(key: string, value: unknown, ttl?: number): Promise<void>;
392
+ delete(key: string): Promise<void>;
393
+ clear(): Promise<void>;
394
+ }
395
+ type OrbitCacheStoreConfig = {
396
+ driver: 'memory';
397
+ maxItems?: number;
398
+ } | {
399
+ driver: 'file';
400
+ directory: string;
401
+ } | {
402
+ driver: 'redis';
403
+ connection?: string;
404
+ prefix?: string;
405
+ } | {
406
+ driver: 'null';
407
+ } | {
408
+ driver: 'custom';
409
+ store: CacheStore;
410
+ } | {
411
+ driver: 'provider';
412
+ provider: CacheProvider;
413
+ };
414
+ interface OrbitCacheOptions {
415
+ exposeAs?: string;
416
+ default?: string;
417
+ prefix?: string;
418
+ defaultTtl?: CacheTtl;
419
+ stores?: Record<string, OrbitCacheStoreConfig>;
420
+ eventsMode?: CacheEventMode;
421
+ throwOnEventError?: boolean;
422
+ onEventError?: (error: unknown, event: keyof CacheEvents, payload: {
423
+ key?: string;
424
+ }) => void;
425
+ provider?: CacheProvider;
426
+ defaultTTL?: number;
427
+ }
428
+ /**
429
+ * OrbitStasis - Cache Orbit
430
+ *
431
+ * Provides caching functionality for Gravito applications.
432
+ */
433
+ declare class OrbitStasis implements GravitoOrbit {
434
+ private options?;
435
+ private manager;
436
+ constructor(options?: OrbitCacheOptions | undefined);
437
+ install(core: PlanetCore): void;
438
+ getCache(): CacheManager;
439
+ }
440
+ declare function orbitCache(core: PlanetCore, options?: OrbitCacheOptions): CacheManager;
441
+ /** @deprecated Use OrbitStasis instead */
442
+ declare const OrbitCache: typeof OrbitStasis;
443
+ declare module 'gravito-core' {
444
+ interface GravitoVariables {
445
+ /** Cache manager for caching operations */
446
+ cache?: CacheManager;
447
+ }
448
+ }
449
+
450
+ export { type CacheConfig, type CacheEventMode, type CacheEvents, type CacheKey, type CacheLock, CacheManager, type CacheProvider, CacheRepository, type CacheRepositoryOptions, type CacheService, type CacheStore, type CacheTtl, type CacheValue, FileStore, type FileStoreOptions, LockTimeoutError, MemoryCacheProvider, MemoryStore, type MemoryStoreOptions, NullStore, OrbitCache, type OrbitCacheOptions, type OrbitCacheStoreConfig, OrbitStasis, RateLimiter, type RateLimiterResponse, RedisStore, type RedisStoreOptions, type StoreConfig, type TaggableStore, orbitCache as default, isExpired, isTaggableStore, normalizeCacheKey, sleep, ttlToExpiresAt };