@geekmidas/cache 0.0.7 → 0.2.0
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/dist/{chunk-DWy1uDak.cjs → chunk-CUT6urMc.cjs} +0 -9
- package/dist/expo.cjs +4 -3
- package/dist/expo.cjs.map +1 -0
- package/dist/expo.d.cts +8 -5
- package/dist/expo.d.cts.map +1 -0
- package/dist/expo.d.mts +8 -5
- package/dist/expo.d.mts.map +1 -0
- package/dist/expo.mjs +3 -2
- package/dist/expo.mjs.map +1 -0
- package/dist/{index-B6eF5Yxi.d.cts → index-BSYYdwRm.d.cts} +8 -5
- package/dist/index-BSYYdwRm.d.cts.map +1 -0
- package/dist/{index-Bv61mxVT.d.mts → index-Dx96gr-9.d.mts} +8 -5
- package/dist/index-Dx96gr-9.d.mts.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/memory.cjs +35 -3
- package/dist/memory.cjs.map +1 -0
- package/dist/memory.d.cts +8 -5
- package/dist/memory.d.cts.map +1 -0
- package/dist/memory.d.mts +8 -5
- package/dist/memory.d.mts.map +1 -0
- package/dist/memory.mjs +34 -3
- package/dist/memory.mjs.map +1 -0
- package/dist/{src-DVpoP03o.mjs → src-CrE4Nl5T.mjs} +2 -1
- package/dist/src-CrE4Nl5T.mjs.map +1 -0
- package/dist/{src-C7d6HaTp.cjs → src-zfYb7mdS.cjs} +3 -2
- package/dist/src-zfYb7mdS.cjs.map +1 -0
- package/dist/upstash.cjs +32 -2
- package/dist/upstash.cjs.map +1 -0
- package/dist/upstash.d.cts +8 -5
- package/dist/upstash.d.cts.map +1 -0
- package/dist/upstash.d.mts +8 -5
- package/dist/upstash.d.mts.map +1 -0
- package/dist/upstash.mjs +31 -2
- package/dist/upstash.mjs.map +1 -0
- package/package.json +6 -2
- package/src/__benchmarks__/memory.bench.ts +51 -0
- package/src/__tests__/cache.spec.ts +138 -105
- package/src/__tests__/integration.spec.ts +277 -268
- package/src/__tests__/memory.spec.ts +129 -129
- package/src/__tests__/upstash.spec.ts +209 -180
- package/src/expo.ts +45 -46
- package/src/index.ts +37 -36
- package/src/memory.ts +28 -27
- package/src/upstash.ts +28 -28
- package/tsconfig.json +9 -0
- package/tsdown.config.ts +1 -1
- package/dist/__tests__/cache.spec.cjs +0 -77
- package/dist/__tests__/cache.spec.d.cts +0 -1
- package/dist/__tests__/cache.spec.d.mts +0 -1
- package/dist/__tests__/cache.spec.mjs +0 -77
- package/dist/__tests__/integration.spec.cjs +0 -235
- package/dist/__tests__/integration.spec.d.cts +0 -1
- package/dist/__tests__/integration.spec.d.mts +0 -1
- package/dist/__tests__/integration.spec.mjs +0 -235
- package/dist/__tests__/memory.spec.cjs +0 -126
- package/dist/__tests__/memory.spec.d.cts +0 -1
- package/dist/__tests__/memory.spec.d.mts +0 -1
- package/dist/__tests__/memory.spec.mjs +0 -126
- package/dist/__tests__/upstash.spec.cjs +0 -201
- package/dist/__tests__/upstash.spec.d.cts +0 -1
- package/dist/__tests__/upstash.spec.d.mts +0 -1
- package/dist/__tests__/upstash.spec.mjs +0 -201
- package/dist/magic-string.es-CBih0MJw.mjs +0 -1014
- package/dist/magic-string.es-KiPEzMtt.cjs +0 -1015
- package/dist/memory-Csy6J-Ak.cjs +0 -39
- package/dist/memory-QDTnSEX5.mjs +0 -33
- package/dist/upstash-CXy_duOa.mjs +0 -31
- package/dist/upstash-u8Hs4sZG.cjs +0 -37
- package/dist/vi.bdSIJ99Y-B-qkABPq.cjs +0 -14955
- package/dist/vi.bdSIJ99Y-CB5havZF.mjs +0 -14951
|
@@ -2,246 +2,275 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
|
2
2
|
import { UpstashCache } from '../upstash';
|
|
3
3
|
|
|
4
4
|
describe('UpstashCache', () => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
let cache: UpstashCache;
|
|
6
|
+
const testKeyPrefix = `test:${Date.now()}:`;
|
|
7
|
+
let testKeys: string[] = [];
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
cache = new UpstashCache('http://localhost:8079', 'example_token');
|
|
11
|
+
testKeys = [];
|
|
12
|
+
});
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
14
|
+
afterEach(async () => {
|
|
15
|
+
// Clean up test keys
|
|
16
|
+
for (const key of testKeys) {
|
|
17
|
+
try {
|
|
18
|
+
await cache.delete(key);
|
|
19
|
+
} catch (_error) {
|
|
20
|
+
// Ignore cleanup errors
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
const getTestKey = (suffix: string): string => {
|
|
26
|
+
const key = `${testKeyPrefix}${suffix}`;
|
|
27
|
+
testKeys.push(key);
|
|
28
|
+
return key;
|
|
29
|
+
};
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
describe('get', () => {
|
|
32
|
+
it('should return undefined for non-existent key', async () => {
|
|
33
|
+
const key = getTestKey('non-existent');
|
|
34
|
+
const result = await cache.get(key);
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
expect(result).toBeUndefined();
|
|
37
|
+
});
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
it('should parse and return JSON value', async () => {
|
|
40
|
+
const key = getTestKey('object');
|
|
41
|
+
const testValue = { id: 1, name: 'test' };
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
await cache.set(key, testValue);
|
|
44
|
+
const result = await cache.get(key);
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
expect(result).toEqual(testValue);
|
|
47
|
+
});
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
it('should handle string values', async () => {
|
|
50
|
+
const key = getTestKey('string');
|
|
51
|
+
const testValue = 'simple string';
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
await cache.set(key, testValue);
|
|
54
|
+
const result = await cache.get(key);
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
expect(result).toBe(testValue);
|
|
57
|
+
});
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
it('should handle number values', async () => {
|
|
60
|
+
const key = getTestKey('number');
|
|
61
|
+
const testValue = 42;
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
await cache.set(key, testValue);
|
|
64
|
+
const result = await cache.get(key);
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
expect(result).toBe(testValue);
|
|
67
|
+
});
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
it('should handle boolean values', async () => {
|
|
70
|
+
const key = getTestKey('boolean');
|
|
71
|
+
const testValue = true;
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
await cache.set(key, testValue);
|
|
74
|
+
const result = await cache.get(key);
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
expect(result).toBe(testValue);
|
|
77
|
+
});
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
it('should handle array values', async () => {
|
|
80
|
+
const key = getTestKey('array');
|
|
81
|
+
const testArray = [1, 2, 3, 'test'];
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
await cache.set(key, testArray);
|
|
84
|
+
const result = await cache.get(key);
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
expect(result).toEqual(testArray);
|
|
87
|
+
});
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
it('should handle null values as undefined', async () => {
|
|
90
|
+
const key = getTestKey('null');
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
await cache.set(key, null);
|
|
93
|
+
const result = await cache.get(key);
|
|
94
94
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
expect(result).toBeUndefined();
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
99
|
+
describe('set', () => {
|
|
100
|
+
it('should store and retrieve object value', async () => {
|
|
101
|
+
const key = getTestKey('set-object');
|
|
102
|
+
const testValue = { id: 1, name: 'test' };
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
await cache.set(key, testValue);
|
|
105
|
+
const result = await cache.get(key);
|
|
106
106
|
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
expect(result).toEqual(testValue);
|
|
108
|
+
});
|
|
109
109
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
it('should store and retrieve string values', async () => {
|
|
111
|
+
const key = getTestKey('set-string');
|
|
112
|
+
const testValue = 'test string';
|
|
113
113
|
|
|
114
|
-
|
|
115
|
-
|
|
114
|
+
await cache.set(key, testValue);
|
|
115
|
+
const result = await cache.get(key);
|
|
116
116
|
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
expect(result).toBe(testValue);
|
|
118
|
+
});
|
|
119
119
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
it('should store and retrieve number values', async () => {
|
|
121
|
+
const key = getTestKey('set-number');
|
|
122
|
+
const testValue = 42;
|
|
123
123
|
|
|
124
|
-
|
|
125
|
-
|
|
124
|
+
await cache.set(key, testValue);
|
|
125
|
+
const result = await cache.get(key);
|
|
126
126
|
|
|
127
|
-
|
|
128
|
-
|
|
127
|
+
expect(result).toBe(testValue);
|
|
128
|
+
});
|
|
129
129
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
130
|
+
it('should store and retrieve boolean values', async () => {
|
|
131
|
+
const key = getTestKey('set-boolean');
|
|
132
|
+
const testValue = true;
|
|
133
133
|
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
await cache.set(key, testValue);
|
|
135
|
+
const result = await cache.get(key);
|
|
136
136
|
|
|
137
|
-
|
|
138
|
-
|
|
137
|
+
expect(result).toBe(testValue);
|
|
138
|
+
});
|
|
139
139
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
140
|
+
it('should store and retrieve array values', async () => {
|
|
141
|
+
const key = getTestKey('set-array');
|
|
142
|
+
const testArray = [1, 2, 3];
|
|
143
143
|
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
await cache.set(key, testArray);
|
|
145
|
+
const result = await cache.get(key);
|
|
146
146
|
|
|
147
|
-
|
|
148
|
-
|
|
147
|
+
expect(result).toEqual(testArray);
|
|
148
|
+
});
|
|
149
149
|
|
|
150
|
-
|
|
151
|
-
|
|
150
|
+
it('should not store and retrieve null values', async () => {
|
|
151
|
+
const key = getTestKey('set-null');
|
|
152
152
|
|
|
153
|
-
|
|
154
|
-
|
|
153
|
+
await cache.set(key, null);
|
|
154
|
+
const result = await cache.get(key);
|
|
155
155
|
|
|
156
|
-
|
|
157
|
-
|
|
156
|
+
expect(result).toBeUndefined();
|
|
157
|
+
});
|
|
158
158
|
|
|
159
|
-
|
|
160
|
-
|
|
159
|
+
it('should overwrite existing values', async () => {
|
|
160
|
+
const key = getTestKey('overwrite');
|
|
161
161
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
162
|
+
await cache.set(key, 'initial');
|
|
163
|
+
await cache.set(key, 'updated');
|
|
164
|
+
const result = await cache.get(key);
|
|
165
165
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
166
|
+
expect(result).toBe('updated');
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
169
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
170
|
+
describe('delete', () => {
|
|
171
|
+
it('should delete existing key', async () => {
|
|
172
|
+
const key = getTestKey('delete-test');
|
|
173
173
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
174
|
+
await cache.set(key, 'value-to-delete');
|
|
175
|
+
await cache.delete(key);
|
|
176
|
+
const result = await cache.get(key);
|
|
177
177
|
|
|
178
|
-
|
|
179
|
-
|
|
178
|
+
expect(result).toBeUndefined();
|
|
179
|
+
});
|
|
180
180
|
|
|
181
|
-
|
|
182
|
-
|
|
181
|
+
it('should handle deletion of non-existent key', async () => {
|
|
182
|
+
const key = getTestKey('non-existent-delete');
|
|
183
183
|
|
|
184
|
-
|
|
185
|
-
|
|
184
|
+
await expect(cache.delete(key)).resolves.not.toThrow();
|
|
185
|
+
});
|
|
186
186
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
187
|
+
it('should only delete specified key', async () => {
|
|
188
|
+
const key1 = getTestKey('delete-key1');
|
|
189
|
+
const key2 = getTestKey('delete-key2');
|
|
190
190
|
|
|
191
|
-
|
|
192
|
-
|
|
191
|
+
await cache.set(key1, 'value1');
|
|
192
|
+
await cache.set(key2, 'value2');
|
|
193
193
|
|
|
194
|
-
|
|
194
|
+
await cache.delete(key1);
|
|
195
195
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
196
|
+
expect(await cache.get(key1)).toBeUndefined();
|
|
197
|
+
expect(await cache.get(key2)).toBe('value2');
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
200
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
user: { id: 1, name: 'John' },
|
|
206
|
-
preferences: ['dark-mode', 'notifications'],
|
|
207
|
-
count: 42,
|
|
208
|
-
};
|
|
201
|
+
describe('ttl', () => {
|
|
202
|
+
it('should return 0 for non-existent key', async () => {
|
|
203
|
+
const key = getTestKey('ttl-non-existent');
|
|
204
|
+
const result = await cache.ttl(key);
|
|
209
205
|
|
|
210
|
-
|
|
211
|
-
|
|
206
|
+
expect(result).toBe(0);
|
|
207
|
+
});
|
|
212
208
|
|
|
213
|
-
|
|
214
|
-
|
|
209
|
+
it('should return positive TTL for existing key with expiry', async () => {
|
|
210
|
+
const key = getTestKey('ttl-with-expiry');
|
|
215
211
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
const complexObject = {
|
|
219
|
-
level1: {
|
|
220
|
-
level2: {
|
|
221
|
-
level3: {
|
|
222
|
-
data: 'deep nested value',
|
|
223
|
-
array: [{ id: 1 }, { id: 2 }],
|
|
224
|
-
},
|
|
225
|
-
},
|
|
226
|
-
},
|
|
227
|
-
};
|
|
212
|
+
await cache.set(key, 'test-value', 3600);
|
|
213
|
+
const result = await cache.ttl(key);
|
|
228
214
|
|
|
229
|
-
|
|
230
|
-
|
|
215
|
+
expect(result).toBeGreaterThan(0);
|
|
216
|
+
expect(result).toBeLessThanOrEqual(3600);
|
|
217
|
+
});
|
|
231
218
|
|
|
232
|
-
|
|
233
|
-
|
|
219
|
+
it('should return TTL in seconds', async () => {
|
|
220
|
+
const key = getTestKey('ttl-seconds');
|
|
234
221
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
getTestKey(suffix),
|
|
238
|
-
);
|
|
239
|
-
const values = ['value1', 'value2', 'value3'];
|
|
222
|
+
await cache.set(key, 'test-value', 60); // 60 seconds
|
|
223
|
+
const result = await cache.ttl(key);
|
|
240
224
|
|
|
241
|
-
|
|
242
|
-
|
|
225
|
+
expect(result).toBeGreaterThan(0);
|
|
226
|
+
expect(result).toBeLessThanOrEqual(60);
|
|
227
|
+
});
|
|
228
|
+
});
|
|
243
229
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
230
|
+
describe('integration scenarios', () => {
|
|
231
|
+
it('should handle round-trip operations', async () => {
|
|
232
|
+
const key = getTestKey('user-session');
|
|
233
|
+
const testData = {
|
|
234
|
+
user: { id: 1, name: 'John' },
|
|
235
|
+
preferences: ['dark-mode', 'notifications'],
|
|
236
|
+
count: 42,
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
await cache.set(key, testData);
|
|
240
|
+
const result = await cache.get(key);
|
|
241
|
+
|
|
242
|
+
expect(result).toEqual(testData);
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
it('should handle complex nested objects', async () => {
|
|
246
|
+
const key = getTestKey('complex');
|
|
247
|
+
const complexObject = {
|
|
248
|
+
level1: {
|
|
249
|
+
level2: {
|
|
250
|
+
level3: {
|
|
251
|
+
data: 'deep nested value',
|
|
252
|
+
array: [{ id: 1 }, { id: 2 }],
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
await cache.set(key, complexObject);
|
|
259
|
+
const result = await cache.get(key);
|
|
260
|
+
|
|
261
|
+
expect(result).toEqual(complexObject);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
it('should handle concurrent operations', async () => {
|
|
265
|
+
const keys = ['concurrent1', 'concurrent2', 'concurrent3'].map((suffix) =>
|
|
266
|
+
getTestKey(suffix),
|
|
267
|
+
);
|
|
268
|
+
const values = ['value1', 'value2', 'value3'];
|
|
269
|
+
|
|
270
|
+
await Promise.all(keys.map((key, i) => cache.set(key, values[i])));
|
|
271
|
+
const results = await Promise.all(keys.map((key) => cache.get(key)));
|
|
272
|
+
|
|
273
|
+
expect(results).toEqual(values);
|
|
274
|
+
});
|
|
275
|
+
});
|
|
247
276
|
});
|
package/src/expo.ts
CHANGED
|
@@ -2,50 +2,49 @@ import { addSeconds } from 'date-fns';
|
|
|
2
2
|
import * as SecureStore from 'expo-secure-store';
|
|
3
3
|
import { type Cache, getExpirationInSeconds } from './index';
|
|
4
4
|
|
|
5
|
-
export class ExpoSecureCache
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
5
|
+
export class ExpoSecureCache implements Cache {
|
|
6
|
+
static getExpiryKey(key: string): string {
|
|
7
|
+
return `${key}:expiresAt`;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async ttl(key: string): Promise<number> {
|
|
11
|
+
const result = await SecureStore.getItemAsync(
|
|
12
|
+
ExpoSecureCache.getExpiryKey(key),
|
|
13
|
+
);
|
|
14
|
+
if (!result) {
|
|
15
|
+
return 0;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const secondsLeft = getExpirationInSeconds(result);
|
|
19
|
+
|
|
20
|
+
return Math.max(secondsLeft, 0);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async get<T>(key: string): Promise<T | undefined> {
|
|
24
|
+
const result = await SecureStore.getItemAsync(key);
|
|
25
|
+
if (!result) {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const expiresAt = await this.ttl(key);
|
|
30
|
+
if (expiresAt === 0) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return JSON.parse(result) as T;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async set<T>(key: string, value: T, ttl: number = 600): Promise<void> {
|
|
38
|
+
const expiresAt = addSeconds(new Date(), ttl).toISOString();
|
|
39
|
+
await SecureStore.setItemAsync(key, JSON.stringify(value));
|
|
40
|
+
await SecureStore.setItemAsync(
|
|
41
|
+
ExpoSecureCache.getExpiryKey(key),
|
|
42
|
+
expiresAt,
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async delete(key: string): Promise<void> {
|
|
47
|
+
await SecureStore.deleteItemAsync(key);
|
|
48
|
+
await SecureStore.deleteItemAsync(ExpoSecureCache.getExpiryKey(key));
|
|
49
|
+
}
|
|
51
50
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,47 +1,48 @@
|
|
|
1
1
|
import { differenceInSeconds } from 'date-fns';
|
|
2
2
|
|
|
3
3
|
export const getExpirationInSeconds = (
|
|
4
|
-
|
|
4
|
+
expiresAt: string | number | Date | undefined | null,
|
|
5
5
|
): number => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
if (!expiresAt) {
|
|
7
|
+
return 0;
|
|
8
|
+
}
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
const expirationDate = new Date(expiresAt);
|
|
11
|
+
const now = new Date();
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
const secondsLeft = differenceInSeconds(expirationDate, now);
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
return Math.max(secondsLeft, 0);
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
export interface Cache
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
18
|
+
export interface Cache {
|
|
19
|
+
/**
|
|
20
|
+
* Retrieves a value from the cache.
|
|
21
|
+
*
|
|
22
|
+
* @param key The key to retrieve the value for.
|
|
23
|
+
* @returns The cached value, or undefined if not found.
|
|
24
|
+
*/
|
|
25
|
+
get<T>(key: string): Promise<T | undefined>;
|
|
26
|
+
/**
|
|
27
|
+
* Sets a value in the cache.
|
|
28
|
+
*
|
|
29
|
+
* @param key The key to set the value for.
|
|
30
|
+
* @param value The value to cache.
|
|
31
|
+
* @param ttl Optional time-to-live in seconds. If not provided, the value will not expire.
|
|
32
|
+
*/
|
|
33
|
+
set<T>(key: string, value: T, ttl?: number): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Deletes a value from the cache.
|
|
36
|
+
*
|
|
37
|
+
* @param key The key to delete from the cache.
|
|
38
|
+
*/
|
|
39
|
+
delete(key: string): Promise<void>;
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Retrieves the time-to-live (TTL) for a cached value.
|
|
43
|
+
*
|
|
44
|
+
* @param key The key to retrieve the TTL for.
|
|
45
|
+
* @returns The TTL in seconds, or 0 if the key does not exist.
|
|
46
|
+
*/
|
|
47
|
+
ttl(key: string): Promise<number>;
|
|
47
48
|
}
|