@geekmidas/cache 0.0.5 → 0.0.7
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/README.md +68 -3
- package/dist/__tests__/cache.spec.cjs +4 -3
- package/dist/__tests__/cache.spec.mjs +4 -3
- package/dist/__tests__/integration.spec.cjs +3 -2
- package/dist/__tests__/integration.spec.mjs +3 -2
- package/dist/__tests__/memory.spec.cjs +3 -2
- package/dist/__tests__/memory.spec.mjs +3 -2
- package/dist/__tests__/upstash.spec.cjs +2 -2
- package/dist/__tests__/upstash.spec.mjs +2 -2
- package/dist/expo.cjs +7 -7
- package/dist/expo.d.cts +2 -2
- package/dist/expo.d.mts +2 -2
- package/dist/expo.mjs +8 -8
- package/dist/{index-CVen_7Cc.d.mts → index-B6eF5Yxi.d.cts} +9 -1
- package/dist/{index-q3xYn8_0.d.cts → index-Bv61mxVT.d.mts} +9 -1
- package/dist/index.cjs +3 -0
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +3 -0
- package/dist/memory-Csy6J-Ak.cjs +39 -0
- package/dist/memory-QDTnSEX5.mjs +33 -0
- package/dist/memory.cjs +2 -1
- package/dist/memory.d.cts +4 -2
- package/dist/memory.d.mts +4 -2
- package/dist/memory.mjs +2 -1
- package/dist/src-C7d6HaTp.cjs +19 -0
- package/dist/src-DVpoP03o.mjs +13 -0
- package/dist/{upstash-_05vyc5o.mjs → upstash-CXy_duOa.mjs} +5 -0
- package/dist/{upstash-DiFDpOHy.cjs → upstash-u8Hs4sZG.cjs} +5 -0
- package/dist/upstash.cjs +1 -1
- package/dist/upstash.d.cts +2 -1
- package/dist/upstash.d.mts +2 -1
- package/dist/upstash.mjs +1 -1
- package/dist/{vi.bdSIJ99Y-CKSnd2bq.cjs → vi.bdSIJ99Y-B-qkABPq.cjs} +1 -1
- package/dist/{vi.bdSIJ99Y-DffpE2Zw.mjs → vi.bdSIJ99Y-CB5havZF.mjs} +1 -1
- package/package.json +1 -1
- package/src/expo.ts +8 -10
- package/src/index.ts +25 -0
- package/src/memory.ts +22 -2
- package/src/upstash.ts +10 -0
- package/dist/memory-YteQXj7m.mjs +0 -16
- package/dist/memory-n6Iosq6J.cjs +0 -22
- /package/dist/{magic-string.es-BvJNBYzY.mjs → magic-string.es-CBih0MJw.mjs} +0 -0
- /package/dist/{magic-string.es-CKiDiYoS.cjs → magic-string.es-KiPEzMtt.cjs} +0 -0
package/README.md
CHANGED
|
@@ -6,11 +6,12 @@ A type-safe, flexible caching library for TypeScript applications with support f
|
|
|
6
6
|
|
|
7
7
|
- **Type-safe**: Full TypeScript support with generics for strongly-typed cache values
|
|
8
8
|
- **Unified interface**: Common `Cache<T>` interface for all implementations
|
|
9
|
-
- **Multiple backends**: In-memory
|
|
9
|
+
- **Multiple backends**: In-memory, Redis (Upstash), and Expo Secure Store implementations
|
|
10
10
|
- **Async API**: Promise-based interface for consistency across implementations
|
|
11
|
-
- **Flexible TTL**: Support for time-to-live
|
|
11
|
+
- **Flexible TTL**: Support for time-to-live across all implementations
|
|
12
12
|
- **Easy testing**: Simple interface makes mocking and testing straightforward
|
|
13
13
|
- **Modular exports**: Import only what you need
|
|
14
|
+
- **React Native support**: Expo Secure Store implementation for mobile apps
|
|
14
15
|
|
|
15
16
|
## Installation
|
|
16
17
|
|
|
@@ -25,6 +26,11 @@ For Redis support via Upstash:
|
|
|
25
26
|
npm install @upstash/redis
|
|
26
27
|
```
|
|
27
28
|
|
|
29
|
+
For React Native support via Expo:
|
|
30
|
+
```bash
|
|
31
|
+
npm install expo-secure-store
|
|
32
|
+
```
|
|
33
|
+
|
|
28
34
|
## Quick Start
|
|
29
35
|
|
|
30
36
|
### In-Memory Cache
|
|
@@ -208,6 +214,58 @@ await cache.set('user:1', {
|
|
|
208
214
|
const user = await cache.get('user:1');
|
|
209
215
|
```
|
|
210
216
|
|
|
217
|
+
### ExpoSecureCache
|
|
218
|
+
|
|
219
|
+
Secure storage for React Native apps using Expo SecureStore.
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
import { ExpoSecureCache } from '@geekmidas/cache/expo';
|
|
223
|
+
|
|
224
|
+
class ExpoSecureCache<T> implements Cache<T>
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
#### Features
|
|
228
|
+
|
|
229
|
+
- ✅ Secure, encrypted storage on device
|
|
230
|
+
- ✅ TTL support with automatic expiration
|
|
231
|
+
- ✅ Persistent across app restarts
|
|
232
|
+
- ✅ iOS Keychain & Android Keystore backed
|
|
233
|
+
- ❌ React Native/Expo only
|
|
234
|
+
- ❌ Limited storage capacity (varies by platform)
|
|
235
|
+
- ❌ Slower than in-memory cache
|
|
236
|
+
|
|
237
|
+
#### Example
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
import { ExpoSecureCache } from '@geekmidas/cache/expo';
|
|
241
|
+
|
|
242
|
+
interface AuthTokens {
|
|
243
|
+
accessToken: string;
|
|
244
|
+
refreshToken: string;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const cache = new ExpoSecureCache<AuthTokens>();
|
|
248
|
+
|
|
249
|
+
// Store tokens securely with 1 hour TTL
|
|
250
|
+
await cache.set('auth:tokens', {
|
|
251
|
+
accessToken: 'eyJhbGciOiJIUzI1NiIs...',
|
|
252
|
+
refreshToken: 'dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4...'
|
|
253
|
+
}, 3600);
|
|
254
|
+
|
|
255
|
+
// Retrieve tokens
|
|
256
|
+
const tokens = await cache.get('auth:tokens');
|
|
257
|
+
|
|
258
|
+
// Clear tokens on logout
|
|
259
|
+
await cache.delete('auth:tokens');
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
#### Platform Considerations
|
|
263
|
+
|
|
264
|
+
- **iOS**: Uses Keychain Services, data persists across app reinstalls
|
|
265
|
+
- **Android**: Uses Android Keystore, data cleared on app uninstall
|
|
266
|
+
- **Storage Limits**: Approximately 2KB per item on most devices
|
|
267
|
+
- **Performance**: Async operations can be slower than memory cache
|
|
268
|
+
|
|
211
269
|
## Advanced Usage
|
|
212
270
|
|
|
213
271
|
### Type Safety
|
|
@@ -289,7 +347,7 @@ Create cache instances based on configuration:
|
|
|
289
347
|
|
|
290
348
|
```typescript
|
|
291
349
|
interface CacheConfig {
|
|
292
|
-
type: 'memory' | 'redis';
|
|
350
|
+
type: 'memory' | 'redis' | 'expo';
|
|
293
351
|
redis?: {
|
|
294
352
|
url: string;
|
|
295
353
|
token: string;
|
|
@@ -303,6 +361,8 @@ function createCache<T>(config: CacheConfig): Cache<T> {
|
|
|
303
361
|
case 'redis':
|
|
304
362
|
if (!config.redis) throw new Error('Redis config required');
|
|
305
363
|
return new UpstashCache<T>(config.redis.url, config.redis.token);
|
|
364
|
+
case 'expo':
|
|
365
|
+
return new ExpoSecureCache<T>();
|
|
306
366
|
default:
|
|
307
367
|
throw new Error(`Unsupported cache type: ${config.type}`);
|
|
308
368
|
}
|
|
@@ -418,6 +478,11 @@ describe('UserService', () => {
|
|
|
418
478
|
- **Cons**: Network latency, external dependency
|
|
419
479
|
- **Best for**: Production, multi-instance apps, shared cache
|
|
420
480
|
|
|
481
|
+
### ExpoSecureCache
|
|
482
|
+
- **Pros**: Secure, encrypted, persistent on device
|
|
483
|
+
- **Cons**: React Native only, storage limits, slower operations
|
|
484
|
+
- **Best for**: Mobile apps, sensitive data (tokens, credentials)
|
|
485
|
+
|
|
421
486
|
### Key Strategies
|
|
422
487
|
|
|
423
488
|
1. **Use appropriate TTL**: Balance between cache freshness and performance
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
3
|
-
const
|
|
1
|
+
require('../src-C7d6HaTp.cjs');
|
|
2
|
+
const require_memory = require('../memory-Csy6J-Ak.cjs');
|
|
3
|
+
const require_upstash = require('../upstash-u8Hs4sZG.cjs');
|
|
4
|
+
const require_vi_bdSIJ99Y = require('../vi.bdSIJ99Y-B-qkABPq.cjs');
|
|
4
5
|
|
|
5
6
|
//#region src/__tests__/cache.spec.ts
|
|
6
7
|
require_vi_bdSIJ99Y.describe("Cache Interface", () => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { describe, globalExpect, it } from "../vi.bdSIJ99Y-
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
1
|
+
import { describe, globalExpect, it } from "../vi.bdSIJ99Y-CB5havZF.mjs";
|
|
2
|
+
import "../src-DVpoP03o.mjs";
|
|
3
|
+
import { InMemoryCache } from "../memory-QDTnSEX5.mjs";
|
|
4
|
+
import { UpstashCache } from "../upstash-CXy_duOa.mjs";
|
|
4
5
|
|
|
5
6
|
//#region src/__tests__/cache.spec.ts
|
|
6
7
|
describe("Cache Interface", () => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
1
|
+
require('../src-C7d6HaTp.cjs');
|
|
2
|
+
const require_memory = require('../memory-Csy6J-Ak.cjs');
|
|
3
|
+
const require_vi_bdSIJ99Y = require('../vi.bdSIJ99Y-B-qkABPq.cjs');
|
|
3
4
|
|
|
4
5
|
//#region src/__tests__/integration.spec.ts
|
|
5
6
|
require_vi_bdSIJ99Y.describe("Cache Integration Tests", () => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { beforeEach, describe, globalExpect, it } from "../vi.bdSIJ99Y-
|
|
2
|
-
import
|
|
1
|
+
import { beforeEach, describe, globalExpect, it } from "../vi.bdSIJ99Y-CB5havZF.mjs";
|
|
2
|
+
import "../src-DVpoP03o.mjs";
|
|
3
|
+
import { InMemoryCache } from "../memory-QDTnSEX5.mjs";
|
|
3
4
|
|
|
4
5
|
//#region src/__tests__/integration.spec.ts
|
|
5
6
|
describe("Cache Integration Tests", () => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
1
|
+
require('../src-C7d6HaTp.cjs');
|
|
2
|
+
const require_memory = require('../memory-Csy6J-Ak.cjs');
|
|
3
|
+
const require_vi_bdSIJ99Y = require('../vi.bdSIJ99Y-B-qkABPq.cjs');
|
|
3
4
|
|
|
4
5
|
//#region src/__tests__/memory.spec.ts
|
|
5
6
|
require_vi_bdSIJ99Y.describe("InMemoryCache", () => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { beforeEach, describe, globalExpect, it } from "../vi.bdSIJ99Y-
|
|
2
|
-
import
|
|
1
|
+
import { beforeEach, describe, globalExpect, it } from "../vi.bdSIJ99Y-CB5havZF.mjs";
|
|
2
|
+
import "../src-DVpoP03o.mjs";
|
|
3
|
+
import { InMemoryCache } from "../memory-QDTnSEX5.mjs";
|
|
3
4
|
|
|
4
5
|
//#region src/__tests__/memory.spec.ts
|
|
5
6
|
describe("InMemoryCache", () => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const require_upstash = require('../upstash-
|
|
2
|
-
const require_vi_bdSIJ99Y = require('../vi.bdSIJ99Y-
|
|
1
|
+
const require_upstash = require('../upstash-u8Hs4sZG.cjs');
|
|
2
|
+
const require_vi_bdSIJ99Y = require('../vi.bdSIJ99Y-B-qkABPq.cjs');
|
|
3
3
|
|
|
4
4
|
//#region src/__tests__/upstash.spec.ts
|
|
5
5
|
require_vi_bdSIJ99Y.describe("UpstashCache", () => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, globalExpect, it } from "../vi.bdSIJ99Y-
|
|
2
|
-
import { UpstashCache } from "../upstash-
|
|
1
|
+
import { afterEach, beforeEach, describe, globalExpect, it } from "../vi.bdSIJ99Y-CB5havZF.mjs";
|
|
2
|
+
import { UpstashCache } from "../upstash-CXy_duOa.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/__tests__/upstash.spec.ts
|
|
5
5
|
describe("UpstashCache", () => {
|
package/dist/expo.cjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const require_chunk = require('./chunk-DWy1uDak.cjs');
|
|
2
|
+
const require_src = require('./src-C7d6HaTp.cjs');
|
|
2
3
|
const date_fns = require_chunk.__toESM(require("date-fns"));
|
|
3
4
|
const expo_secure_store = require_chunk.__toESM(require("expo-secure-store"));
|
|
4
5
|
|
|
@@ -7,24 +8,23 @@ var ExpoSecureCache = class ExpoSecureCache {
|
|
|
7
8
|
static getExpiryKey(key) {
|
|
8
9
|
return `${key}:expiresAt`;
|
|
9
10
|
}
|
|
10
|
-
async
|
|
11
|
+
async ttl(key) {
|
|
11
12
|
const result = await expo_secure_store.getItemAsync(ExpoSecureCache.getExpiryKey(key));
|
|
12
13
|
if (!result) return 0;
|
|
13
|
-
const
|
|
14
|
-
const secondsLeft = (0, date_fns.differenceInSeconds)(date, /* @__PURE__ */ new Date());
|
|
14
|
+
const secondsLeft = require_src.getExpirationInSeconds(result);
|
|
15
15
|
return Math.max(secondsLeft, 0);
|
|
16
16
|
}
|
|
17
17
|
async get(key) {
|
|
18
18
|
const result = await expo_secure_store.getItemAsync(key);
|
|
19
19
|
if (!result) return void 0;
|
|
20
|
-
const expiresAt = await this.
|
|
20
|
+
const expiresAt = await this.ttl(key);
|
|
21
21
|
if (expiresAt === 0) return void 0;
|
|
22
22
|
return JSON.parse(result);
|
|
23
23
|
}
|
|
24
|
-
async set(key, value, ttl) {
|
|
25
|
-
const expiresAt =
|
|
24
|
+
async set(key, value, ttl = 600) {
|
|
25
|
+
const expiresAt = (0, date_fns.addSeconds)(/* @__PURE__ */ new Date(), ttl).toISOString();
|
|
26
26
|
await expo_secure_store.setItemAsync(key, JSON.stringify(value));
|
|
27
|
-
await expo_secure_store.setItemAsync(ExpoSecureCache.getExpiryKey(key),
|
|
27
|
+
await expo_secure_store.setItemAsync(ExpoSecureCache.getExpiryKey(key), expiresAt);
|
|
28
28
|
}
|
|
29
29
|
async delete(key) {
|
|
30
30
|
await expo_secure_store.deleteItemAsync(key);
|
package/dist/expo.d.cts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Cache } from "./index-
|
|
1
|
+
import { Cache } from "./index-B6eF5Yxi.cjs";
|
|
2
2
|
|
|
3
3
|
//#region src/expo.d.ts
|
|
4
4
|
declare class ExpoSecureCache<T> implements Cache<T> {
|
|
5
5
|
static getExpiryKey(key: string): string;
|
|
6
|
-
|
|
6
|
+
ttl(key: string): Promise<number>;
|
|
7
7
|
get(key: string): Promise<T | undefined>;
|
|
8
8
|
set(key: string, value: T, ttl?: number): Promise<void>;
|
|
9
9
|
delete(key: string): Promise<void>;
|
package/dist/expo.d.mts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Cache } from "./index-
|
|
1
|
+
import { Cache } from "./index-Bv61mxVT.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/expo.d.ts
|
|
4
4
|
declare class ExpoSecureCache<T> implements Cache<T> {
|
|
5
5
|
static getExpiryKey(key: string): string;
|
|
6
|
-
|
|
6
|
+
ttl(key: string): Promise<number>;
|
|
7
7
|
get(key: string): Promise<T | undefined>;
|
|
8
8
|
set(key: string, value: T, ttl?: number): Promise<void>;
|
|
9
9
|
delete(key: string): Promise<void>;
|
package/dist/expo.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getExpirationInSeconds } from "./src-DVpoP03o.mjs";
|
|
2
|
+
import { addSeconds } from "date-fns";
|
|
2
3
|
import * as SecureStore from "expo-secure-store";
|
|
3
4
|
|
|
4
5
|
//#region src/expo.ts
|
|
@@ -6,24 +7,23 @@ var ExpoSecureCache = class ExpoSecureCache {
|
|
|
6
7
|
static getExpiryKey(key) {
|
|
7
8
|
return `${key}:expiresAt`;
|
|
8
9
|
}
|
|
9
|
-
async
|
|
10
|
+
async ttl(key) {
|
|
10
11
|
const result = await SecureStore.getItemAsync(ExpoSecureCache.getExpiryKey(key));
|
|
11
12
|
if (!result) return 0;
|
|
12
|
-
const
|
|
13
|
-
const secondsLeft = differenceInSeconds(date, /* @__PURE__ */ new Date());
|
|
13
|
+
const secondsLeft = getExpirationInSeconds(result);
|
|
14
14
|
return Math.max(secondsLeft, 0);
|
|
15
15
|
}
|
|
16
16
|
async get(key) {
|
|
17
17
|
const result = await SecureStore.getItemAsync(key);
|
|
18
18
|
if (!result) return void 0;
|
|
19
|
-
const expiresAt = await this.
|
|
19
|
+
const expiresAt = await this.ttl(key);
|
|
20
20
|
if (expiresAt === 0) return void 0;
|
|
21
21
|
return JSON.parse(result);
|
|
22
22
|
}
|
|
23
|
-
async set(key, value, ttl) {
|
|
24
|
-
const expiresAt =
|
|
23
|
+
async set(key, value, ttl = 600) {
|
|
24
|
+
const expiresAt = addSeconds(/* @__PURE__ */ new Date(), ttl).toISOString();
|
|
25
25
|
await SecureStore.setItemAsync(key, JSON.stringify(value));
|
|
26
|
-
await SecureStore.setItemAsync(ExpoSecureCache.getExpiryKey(key),
|
|
26
|
+
await SecureStore.setItemAsync(ExpoSecureCache.getExpiryKey(key), expiresAt);
|
|
27
27
|
}
|
|
28
28
|
async delete(key) {
|
|
29
29
|
await SecureStore.deleteItemAsync(key);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
//#region src/index.d.ts
|
|
2
|
+
declare const getExpirationInSeconds: (expiresAt: string | number | Date | undefined | null) => number;
|
|
2
3
|
interface Cache<T> {
|
|
3
4
|
/**
|
|
4
5
|
* Retrieves a value from the cache.
|
|
@@ -20,6 +21,13 @@ interface Cache<T> {
|
|
|
20
21
|
* @param key The key to delete from the cache.
|
|
21
22
|
*/
|
|
22
23
|
delete(key: string): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Retrieves the time-to-live (TTL) for a cached value.
|
|
26
|
+
*
|
|
27
|
+
* @param key The key to retrieve the TTL for.
|
|
28
|
+
* @returns The TTL in seconds, or undefined if the key does not exist.
|
|
29
|
+
*/
|
|
30
|
+
ttl(key: string): Promise<number>;
|
|
23
31
|
}
|
|
24
32
|
//#endregion
|
|
25
|
-
export { Cache };
|
|
33
|
+
export { Cache, getExpirationInSeconds };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
//#region src/index.d.ts
|
|
2
|
+
declare const getExpirationInSeconds: (expiresAt: string | number | Date | undefined | null) => number;
|
|
2
3
|
interface Cache<T> {
|
|
3
4
|
/**
|
|
4
5
|
* Retrieves a value from the cache.
|
|
@@ -20,6 +21,13 @@ interface Cache<T> {
|
|
|
20
21
|
* @param key The key to delete from the cache.
|
|
21
22
|
*/
|
|
22
23
|
delete(key: string): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Retrieves the time-to-live (TTL) for a cached value.
|
|
26
|
+
*
|
|
27
|
+
* @param key The key to retrieve the TTL for.
|
|
28
|
+
* @returns The TTL in seconds, or undefined if the key does not exist.
|
|
29
|
+
*/
|
|
30
|
+
ttl(key: string): Promise<number>;
|
|
23
31
|
}
|
|
24
32
|
//#endregion
|
|
25
|
-
export { Cache };
|
|
33
|
+
export { Cache, getExpirationInSeconds };
|
package/dist/index.cjs
CHANGED
package/dist/index.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Cache } from "./index-
|
|
2
|
-
export { Cache };
|
|
1
|
+
import { Cache, getExpirationInSeconds } from "./index-B6eF5Yxi.cjs";
|
|
2
|
+
export { Cache, getExpirationInSeconds };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Cache } from "./index-
|
|
2
|
-
export { Cache };
|
|
1
|
+
import { Cache, getExpirationInSeconds } from "./index-Bv61mxVT.mjs";
|
|
2
|
+
export { Cache, getExpirationInSeconds };
|
package/dist/index.mjs
CHANGED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-DWy1uDak.cjs');
|
|
2
|
+
const require_src = require('./src-C7d6HaTp.cjs');
|
|
3
|
+
const date_fns = require_chunk.__toESM(require("date-fns"));
|
|
4
|
+
|
|
5
|
+
//#region src/memory.ts
|
|
6
|
+
var InMemoryCache = class {
|
|
7
|
+
store = /* @__PURE__ */ new Map();
|
|
8
|
+
expirations = /* @__PURE__ */ new Map();
|
|
9
|
+
async get(key) {
|
|
10
|
+
const expiration = await this.ttl(key);
|
|
11
|
+
if (!expiration) {
|
|
12
|
+
await this.delete(key);
|
|
13
|
+
return void 0;
|
|
14
|
+
}
|
|
15
|
+
return this.store.get(key);
|
|
16
|
+
}
|
|
17
|
+
async ttl(key) {
|
|
18
|
+
const expiration = this.expirations.get(key);
|
|
19
|
+
if (!expiration) return 0;
|
|
20
|
+
return require_src.getExpirationInSeconds(expiration);
|
|
21
|
+
}
|
|
22
|
+
async set(key, value, ttl = 600) {
|
|
23
|
+
this.store.set(key, value);
|
|
24
|
+
const now = /* @__PURE__ */ new Date();
|
|
25
|
+
const expiresAt = (0, date_fns.addSeconds)(now, ttl);
|
|
26
|
+
this.expirations.set(key, expiresAt);
|
|
27
|
+
}
|
|
28
|
+
async delete(key) {
|
|
29
|
+
this.store.delete(key);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
//#endregion
|
|
34
|
+
Object.defineProperty(exports, 'InMemoryCache', {
|
|
35
|
+
enumerable: true,
|
|
36
|
+
get: function () {
|
|
37
|
+
return InMemoryCache;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { getExpirationInSeconds } from "./src-DVpoP03o.mjs";
|
|
2
|
+
import { addSeconds } from "date-fns";
|
|
3
|
+
|
|
4
|
+
//#region src/memory.ts
|
|
5
|
+
var InMemoryCache = class {
|
|
6
|
+
store = /* @__PURE__ */ new Map();
|
|
7
|
+
expirations = /* @__PURE__ */ new Map();
|
|
8
|
+
async get(key) {
|
|
9
|
+
const expiration = await this.ttl(key);
|
|
10
|
+
if (!expiration) {
|
|
11
|
+
await this.delete(key);
|
|
12
|
+
return void 0;
|
|
13
|
+
}
|
|
14
|
+
return this.store.get(key);
|
|
15
|
+
}
|
|
16
|
+
async ttl(key) {
|
|
17
|
+
const expiration = this.expirations.get(key);
|
|
18
|
+
if (!expiration) return 0;
|
|
19
|
+
return getExpirationInSeconds(expiration);
|
|
20
|
+
}
|
|
21
|
+
async set(key, value, ttl = 600) {
|
|
22
|
+
this.store.set(key, value);
|
|
23
|
+
const now = /* @__PURE__ */ new Date();
|
|
24
|
+
const expiresAt = addSeconds(now, ttl);
|
|
25
|
+
this.expirations.set(key, expiresAt);
|
|
26
|
+
}
|
|
27
|
+
async delete(key) {
|
|
28
|
+
this.store.delete(key);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
//#endregion
|
|
33
|
+
export { InMemoryCache };
|
package/dist/memory.cjs
CHANGED
package/dist/memory.d.cts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { Cache } from "./index-
|
|
1
|
+
import { Cache } from "./index-B6eF5Yxi.cjs";
|
|
2
2
|
|
|
3
3
|
//#region src/memory.d.ts
|
|
4
4
|
declare class InMemoryCache<T> implements Cache<T> {
|
|
5
5
|
private store;
|
|
6
|
+
private expirations;
|
|
6
7
|
get(key: string): Promise<T | undefined>;
|
|
7
|
-
|
|
8
|
+
ttl(key: string): Promise<number>;
|
|
9
|
+
set(key: string, value: T, ttl?: number): Promise<void>;
|
|
8
10
|
delete(key: string): Promise<void>;
|
|
9
11
|
}
|
|
10
12
|
//#endregion
|
package/dist/memory.d.mts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { Cache } from "./index-
|
|
1
|
+
import { Cache } from "./index-Bv61mxVT.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/memory.d.ts
|
|
4
4
|
declare class InMemoryCache<T> implements Cache<T> {
|
|
5
5
|
private store;
|
|
6
|
+
private expirations;
|
|
6
7
|
get(key: string): Promise<T | undefined>;
|
|
7
|
-
|
|
8
|
+
ttl(key: string): Promise<number>;
|
|
9
|
+
set(key: string, value: T, ttl?: number): Promise<void>;
|
|
8
10
|
delete(key: string): Promise<void>;
|
|
9
11
|
}
|
|
10
12
|
//#endregion
|
package/dist/memory.mjs
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-DWy1uDak.cjs');
|
|
2
|
+
const date_fns = require_chunk.__toESM(require("date-fns"));
|
|
3
|
+
|
|
4
|
+
//#region src/index.ts
|
|
5
|
+
const getExpirationInSeconds = (expiresAt) => {
|
|
6
|
+
if (!expiresAt) return 0;
|
|
7
|
+
const expirationDate = new Date(expiresAt);
|
|
8
|
+
const now = /* @__PURE__ */ new Date();
|
|
9
|
+
const secondsLeft = (0, date_fns.differenceInSeconds)(expirationDate, now);
|
|
10
|
+
return Math.max(secondsLeft, 0);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
//#endregion
|
|
14
|
+
Object.defineProperty(exports, 'getExpirationInSeconds', {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function () {
|
|
17
|
+
return getExpirationInSeconds;
|
|
18
|
+
}
|
|
19
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { differenceInSeconds } from "date-fns";
|
|
2
|
+
|
|
3
|
+
//#region src/index.ts
|
|
4
|
+
const getExpirationInSeconds = (expiresAt) => {
|
|
5
|
+
if (!expiresAt) return 0;
|
|
6
|
+
const expirationDate = new Date(expiresAt);
|
|
7
|
+
const now = /* @__PURE__ */ new Date();
|
|
8
|
+
const secondsLeft = differenceInSeconds(expirationDate, now);
|
|
9
|
+
return Math.max(secondsLeft, 0);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
//#endregion
|
|
13
|
+
export { getExpirationInSeconds };
|
|
@@ -10,6 +10,11 @@ var UpstashCache = class {
|
|
|
10
10
|
token
|
|
11
11
|
});
|
|
12
12
|
}
|
|
13
|
+
async ttl(key) {
|
|
14
|
+
const ttl = await this.client.ttl(key);
|
|
15
|
+
if (ttl === -2) return 0;
|
|
16
|
+
return ttl;
|
|
17
|
+
}
|
|
13
18
|
async get(key) {
|
|
14
19
|
const v = await this.client.get(key);
|
|
15
20
|
if (v === null) return void 0;
|
package/dist/upstash.cjs
CHANGED
package/dist/upstash.d.cts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { Cache } from "./index-
|
|
1
|
+
import { Cache } from "./index-B6eF5Yxi.cjs";
|
|
2
2
|
|
|
3
3
|
//#region src/upstash.d.ts
|
|
4
4
|
declare class UpstashCache<T> implements Cache<T> {
|
|
5
5
|
private client;
|
|
6
6
|
constructor(url: string, token: string);
|
|
7
|
+
ttl(key: string): Promise<number>;
|
|
7
8
|
get(key: string): Promise<T | undefined>;
|
|
8
9
|
set(key: string, value: T, ttl?: number): Promise<void>;
|
|
9
10
|
delete(key: string): Promise<void>;
|
package/dist/upstash.d.mts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { Cache } from "./index-
|
|
1
|
+
import { Cache } from "./index-Bv61mxVT.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/upstash.d.ts
|
|
4
4
|
declare class UpstashCache<T> implements Cache<T> {
|
|
5
5
|
private client;
|
|
6
6
|
constructor(url: string, token: string);
|
|
7
|
+
ttl(key: string): Promise<number>;
|
|
7
8
|
get(key: string): Promise<T | undefined>;
|
|
8
9
|
set(key: string, value: T, ttl?: number): Promise<void>;
|
|
9
10
|
delete(key: string): Promise<void>;
|
package/dist/upstash.mjs
CHANGED
|
@@ -11570,7 +11570,7 @@ function offsetToLineNumber(source, offset) {
|
|
|
11570
11570
|
return line + 1;
|
|
11571
11571
|
}
|
|
11572
11572
|
async function saveInlineSnapshots(environment, snapshots) {
|
|
11573
|
-
const MagicString = (await Promise.resolve().then(() => require("./magic-string.es-
|
|
11573
|
+
const MagicString = (await Promise.resolve().then(() => require("./magic-string.es-KiPEzMtt.cjs"))).default;
|
|
11574
11574
|
const files = new Set(snapshots.map((i) => i.file));
|
|
11575
11575
|
await Promise.all(Array.from(files).map(async (file) => {
|
|
11576
11576
|
const snaps = snapshots.filter((i) => i.file === file);
|
|
@@ -11595,7 +11595,7 @@ function offsetToLineNumber(source, offset) {
|
|
|
11595
11595
|
return line + 1;
|
|
11596
11596
|
}
|
|
11597
11597
|
async function saveInlineSnapshots(environment, snapshots) {
|
|
11598
|
-
const MagicString = (await import("./magic-string.es-
|
|
11598
|
+
const MagicString = (await import("./magic-string.es-CBih0MJw.mjs")).default;
|
|
11599
11599
|
const files = new Set(snapshots.map((i) => i.file));
|
|
11600
11600
|
await Promise.all(Array.from(files).map(async (file) => {
|
|
11601
11601
|
const snaps = snapshots.filter((i) => i.file === file);
|
package/package.json
CHANGED
package/src/expo.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { addSeconds } from 'date-fns';
|
|
2
2
|
import * as SecureStore from 'expo-secure-store';
|
|
3
|
-
import type
|
|
3
|
+
import { type Cache, getExpirationInSeconds } from './index';
|
|
4
4
|
|
|
5
5
|
export class ExpoSecureCache<T> implements Cache<T> {
|
|
6
6
|
static getExpiryKey(key: string): string {
|
|
7
7
|
return `${key}:expiresAt`;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
async ttl(key: string): Promise<number> {
|
|
11
11
|
const result = await SecureStore.getItemAsync(
|
|
12
12
|
ExpoSecureCache.getExpiryKey(key),
|
|
13
13
|
);
|
|
@@ -15,9 +15,7 @@ export class ExpoSecureCache<T> implements Cache<T> {
|
|
|
15
15
|
return 0;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
const secondsLeft = differenceInSeconds(date, new Date());
|
|
18
|
+
const secondsLeft = getExpirationInSeconds(result);
|
|
21
19
|
|
|
22
20
|
return Math.max(secondsLeft, 0);
|
|
23
21
|
}
|
|
@@ -29,7 +27,7 @@ export class ExpoSecureCache<T> implements Cache<T> {
|
|
|
29
27
|
return undefined;
|
|
30
28
|
}
|
|
31
29
|
|
|
32
|
-
const expiresAt = await this.
|
|
30
|
+
const expiresAt = await this.ttl(key);
|
|
33
31
|
if (expiresAt === 0) {
|
|
34
32
|
return undefined;
|
|
35
33
|
}
|
|
@@ -37,12 +35,12 @@ export class ExpoSecureCache<T> implements Cache<T> {
|
|
|
37
35
|
return JSON.parse(result) as T;
|
|
38
36
|
}
|
|
39
37
|
|
|
40
|
-
async set(key: string, value: T, ttl
|
|
41
|
-
const expiresAt =
|
|
38
|
+
async set(key: string, value: T, ttl: number = 600): Promise<void> {
|
|
39
|
+
const expiresAt = addSeconds(new Date(), ttl).toISOString();
|
|
42
40
|
await SecureStore.setItemAsync(key, JSON.stringify(value));
|
|
43
41
|
await SecureStore.setItemAsync(
|
|
44
42
|
ExpoSecureCache.getExpiryKey(key),
|
|
45
|
-
|
|
43
|
+
expiresAt,
|
|
46
44
|
);
|
|
47
45
|
}
|
|
48
46
|
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
import { differenceInSeconds } from 'date-fns';
|
|
2
|
+
|
|
3
|
+
export const getExpirationInSeconds = (
|
|
4
|
+
expiresAt: string | number | Date | undefined | null,
|
|
5
|
+
): number => {
|
|
6
|
+
if (!expiresAt) {
|
|
7
|
+
return 0;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const expirationDate = new Date(expiresAt);
|
|
11
|
+
const now = new Date();
|
|
12
|
+
|
|
13
|
+
const secondsLeft = differenceInSeconds(expirationDate, now);
|
|
14
|
+
|
|
15
|
+
return Math.max(secondsLeft, 0);
|
|
16
|
+
};
|
|
17
|
+
|
|
1
18
|
export interface Cache<T> {
|
|
2
19
|
/**
|
|
3
20
|
* Retrieves a value from the cache.
|
|
@@ -19,4 +36,12 @@ export interface Cache<T> {
|
|
|
19
36
|
* @param key The key to delete from the cache.
|
|
20
37
|
*/
|
|
21
38
|
delete(key: string): Promise<void>;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Retrieves the time-to-live (TTL) for a cached value.
|
|
42
|
+
*
|
|
43
|
+
* @param key The key to retrieve the TTL for.
|
|
44
|
+
* @returns The TTL in seconds, or undefined if the key does not exist.
|
|
45
|
+
*/
|
|
46
|
+
ttl(key: string): Promise<number>;
|
|
22
47
|
}
|
package/src/memory.ts
CHANGED
|
@@ -1,14 +1,34 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { addSeconds } from 'date-fns';
|
|
2
|
+
import { type Cache, getExpirationInSeconds } from './';
|
|
2
3
|
|
|
3
4
|
export class InMemoryCache<T> implements Cache<T> {
|
|
4
5
|
private store: Map<string, T> = new Map();
|
|
6
|
+
private expirations: Map<string, Date> = new Map();
|
|
5
7
|
|
|
6
8
|
async get(key: string): Promise<T | undefined> {
|
|
9
|
+
const expiration = await this.ttl(key);
|
|
10
|
+
if (!expiration) {
|
|
11
|
+
await this.delete(key);
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
|
|
7
15
|
return this.store.get(key);
|
|
8
16
|
}
|
|
9
17
|
|
|
10
|
-
async
|
|
18
|
+
async ttl(key: string): Promise<number> {
|
|
19
|
+
const expiration = this.expirations.get(key);
|
|
20
|
+
if (!expiration) {
|
|
21
|
+
return 0;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return getExpirationInSeconds(expiration);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async set(key: string, value: T, ttl: number = 600): Promise<void> {
|
|
11
28
|
this.store.set(key, value);
|
|
29
|
+
const now = new Date();
|
|
30
|
+
const expiresAt = addSeconds(now, ttl);
|
|
31
|
+
this.expirations.set(key, expiresAt);
|
|
12
32
|
}
|
|
13
33
|
|
|
14
34
|
async delete(key: string): Promise<void> {
|
package/src/upstash.ts
CHANGED
|
@@ -11,6 +11,16 @@ export class UpstashCache<T> implements Cache<T> {
|
|
|
11
11
|
});
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
async ttl(key: string): Promise<number> {
|
|
15
|
+
const ttl = await this.client.ttl(key);
|
|
16
|
+
|
|
17
|
+
if (ttl === -2) {
|
|
18
|
+
return 0; // Key does not exist
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return ttl; // Returns TTL in seconds
|
|
22
|
+
}
|
|
23
|
+
|
|
14
24
|
async get(key: string): Promise<T | undefined> {
|
|
15
25
|
const v = await this.client.get(key);
|
|
16
26
|
|
package/dist/memory-YteQXj7m.mjs
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
//#region src/memory.ts
|
|
2
|
-
var InMemoryCache = class {
|
|
3
|
-
store = /* @__PURE__ */ new Map();
|
|
4
|
-
async get(key) {
|
|
5
|
-
return this.store.get(key);
|
|
6
|
-
}
|
|
7
|
-
async set(key, value) {
|
|
8
|
-
this.store.set(key, value);
|
|
9
|
-
}
|
|
10
|
-
async delete(key) {
|
|
11
|
-
this.store.delete(key);
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
//#endregion
|
|
16
|
-
export { InMemoryCache };
|
package/dist/memory-n6Iosq6J.cjs
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
//#region src/memory.ts
|
|
3
|
-
var InMemoryCache = class {
|
|
4
|
-
store = /* @__PURE__ */ new Map();
|
|
5
|
-
async get(key) {
|
|
6
|
-
return this.store.get(key);
|
|
7
|
-
}
|
|
8
|
-
async set(key, value) {
|
|
9
|
-
this.store.set(key, value);
|
|
10
|
-
}
|
|
11
|
-
async delete(key) {
|
|
12
|
-
this.store.delete(key);
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
//#endregion
|
|
17
|
-
Object.defineProperty(exports, 'InMemoryCache', {
|
|
18
|
-
enumerable: true,
|
|
19
|
-
get: function () {
|
|
20
|
-
return InMemoryCache;
|
|
21
|
-
}
|
|
22
|
-
});
|
|
File without changes
|
|
File without changes
|