@arkstack/cache 0.5.3
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 +21 -0
- package/README.md +71 -0
- package/dist/CacheManager-Do82q7KO.js +709 -0
- package/dist/commands/CacheClearCommand.d.ts +13 -0
- package/dist/commands/CacheClearCommand.js +19 -0
- package/dist/index.d.ts +526 -0
- package/dist/index.js +2 -0
- package/dist/setup.d.ts +1 -0
- package/dist/setup.js +21 -0
- package/package.json +57 -0
- package/stubs/migrations/20260601000000_create_cache_table.ts.stub +21 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { t as Cache } from "../CacheManager-Do82q7KO.js";
|
|
2
|
+
import { Command } from "@h3ravel/musket";
|
|
3
|
+
//#region src/commands/CacheClearCommand.ts
|
|
4
|
+
/**
|
|
5
|
+
* Flush all entries from a cache store.
|
|
6
|
+
*/
|
|
7
|
+
var CacheClearCommand = class extends Command {
|
|
8
|
+
signature = `cache:clear
|
|
9
|
+
{--store= : The cache store to flush. Defaults to the configured default store.}
|
|
10
|
+
`;
|
|
11
|
+
description = "Flush the application cache.";
|
|
12
|
+
async handle() {
|
|
13
|
+
const store = this.option("store");
|
|
14
|
+
await Cache.store(store).flush();
|
|
15
|
+
this.info(`Cache store [${store ?? "default"}] cleared successfully.`);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
//#endregion
|
|
19
|
+
export { CacheClearCommand };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,526 @@
|
|
|
1
|
+
import { DotPath, DotPathValue } from "@arkstack/common";
|
|
2
|
+
|
|
3
|
+
//#region src/Contracts/Store.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* The low level contract every cache store driver must satisfy.
|
|
6
|
+
*
|
|
7
|
+
* Stores are intentionally thin: they only deal in raw key/value persistence
|
|
8
|
+
* and expiration. The higher level convenience API (`remember`, `add`, `pull`,
|
|
9
|
+
* default value resolution, etc.) lives in {@link Repository}, which wraps a
|
|
10
|
+
* store. This keeps drivers simple and behaviour consistent across backends.
|
|
11
|
+
*/
|
|
12
|
+
declare abstract class Store {
|
|
13
|
+
/**
|
|
14
|
+
* Retrieve the value for the given key, or `null` when the key is missing
|
|
15
|
+
* or has expired.
|
|
16
|
+
*
|
|
17
|
+
* @param key
|
|
18
|
+
*/
|
|
19
|
+
abstract get<T = unknown>(key: string): Promise<T | null>;
|
|
20
|
+
/**
|
|
21
|
+
* Store a value for the given key.
|
|
22
|
+
*
|
|
23
|
+
* @param key The cache key.
|
|
24
|
+
* @param value The value to store (will be serialized by the driver).
|
|
25
|
+
* @param seconds Lifetime in seconds, or `null` to store forever.
|
|
26
|
+
* @returns Whether the value was stored.
|
|
27
|
+
*/
|
|
28
|
+
abstract put(key: string, value: unknown, seconds?: number | null): Promise<boolean>;
|
|
29
|
+
/**
|
|
30
|
+
* Store a value that never expires.
|
|
31
|
+
*
|
|
32
|
+
* @param key
|
|
33
|
+
* @param value
|
|
34
|
+
*/
|
|
35
|
+
abstract forever(key: string, value: unknown): Promise<boolean>;
|
|
36
|
+
/**
|
|
37
|
+
* Increment a numeric value, creating it (starting at 0) when absent.
|
|
38
|
+
*
|
|
39
|
+
* @returns The new value, or `false` when the existing value is not numeric.
|
|
40
|
+
*
|
|
41
|
+
* @param key
|
|
42
|
+
* @param value
|
|
43
|
+
*/
|
|
44
|
+
abstract increment(key: string, value?: number): Promise<number | false>;
|
|
45
|
+
/**
|
|
46
|
+
* Decrement a numeric value, creating it (starting at 0) when absent.
|
|
47
|
+
*
|
|
48
|
+
* @returns The new value, or `false` when the existing value is not numeric.
|
|
49
|
+
*
|
|
50
|
+
* @param key
|
|
51
|
+
* @param value
|
|
52
|
+
*/
|
|
53
|
+
abstract decrement(key: string, value?: number): Promise<number | false>;
|
|
54
|
+
/**
|
|
55
|
+
* Remove a single key from the store.
|
|
56
|
+
*
|
|
57
|
+
* @param key
|
|
58
|
+
* @param value
|
|
59
|
+
*/
|
|
60
|
+
abstract forget(key: string): Promise<boolean>;
|
|
61
|
+
/**
|
|
62
|
+
* Remove every entry owned by this store.
|
|
63
|
+
*/
|
|
64
|
+
abstract flush(): Promise<boolean>;
|
|
65
|
+
/**
|
|
66
|
+
* The key prefix applied to every entry by this store.
|
|
67
|
+
*/
|
|
68
|
+
abstract getPrefix(): string;
|
|
69
|
+
}
|
|
70
|
+
//#endregion
|
|
71
|
+
//#region src/types.d.ts
|
|
72
|
+
/**
|
|
73
|
+
* A value, or a function (sync or async) that resolves to a value.
|
|
74
|
+
*
|
|
75
|
+
* Used for cache defaults and the `remember` callbacks.
|
|
76
|
+
*/
|
|
77
|
+
type Resolvable<T> = T | (() => T | Promise<T>);
|
|
78
|
+
/**
|
|
79
|
+
* Time to live for a cache entry.
|
|
80
|
+
*
|
|
81
|
+
* - `number` number of seconds the entry should live.
|
|
82
|
+
* - `Date` an absolute expiry time.
|
|
83
|
+
* - `null` store forever (no expiration).
|
|
84
|
+
*/
|
|
85
|
+
type CacheTtl = number | Date | null;
|
|
86
|
+
/**
|
|
87
|
+
* Built in cache store driver names.
|
|
88
|
+
*/
|
|
89
|
+
type CacheDriverName = 'memory' | 'array' | 'file' | 'redis' | 'database';
|
|
90
|
+
interface FilePayload {
|
|
91
|
+
value: unknown;
|
|
92
|
+
/** Absolute expiry in epoch milliseconds, or `null` for forever. */
|
|
93
|
+
expiresAt: number | null;
|
|
94
|
+
}
|
|
95
|
+
interface MemoryStoreConfig {
|
|
96
|
+
driver: 'memory' | 'array';
|
|
97
|
+
}
|
|
98
|
+
interface FileStoreConfig {
|
|
99
|
+
driver: 'file';
|
|
100
|
+
/** Absolute path to the directory cache files are written to. */
|
|
101
|
+
path: string;
|
|
102
|
+
}
|
|
103
|
+
interface RedisStoreConfig {
|
|
104
|
+
driver: 'redis';
|
|
105
|
+
/** A pre built ioredis connection string, e.g. `redis://localhost:6379`. */
|
|
106
|
+
url?: string;
|
|
107
|
+
host?: string;
|
|
108
|
+
port?: number;
|
|
109
|
+
password?: string;
|
|
110
|
+
db?: number;
|
|
111
|
+
/** Optional per store key prefix applied on top of the global prefix. */
|
|
112
|
+
prefix?: string;
|
|
113
|
+
}
|
|
114
|
+
interface DatabaseStoreConfig {
|
|
115
|
+
driver: 'database';
|
|
116
|
+
/** The table the cache entries are stored in. */
|
|
117
|
+
table: string;
|
|
118
|
+
/** Optional named database connection. */
|
|
119
|
+
connection?: string;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Apps may augment this registry to register custom store driver configs.
|
|
123
|
+
*/
|
|
124
|
+
interface CustomCacheStoreRegistry {}
|
|
125
|
+
type CacheStoreConfig = MemoryStoreConfig | FileStoreConfig | RedisStoreConfig | DatabaseStoreConfig | ({
|
|
126
|
+
driver: string;
|
|
127
|
+
} & Record<string, unknown>);
|
|
128
|
+
interface CacheConfig {
|
|
129
|
+
/**
|
|
130
|
+
* The default cache store used when no store is explicitly requested.
|
|
131
|
+
*/
|
|
132
|
+
default: string;
|
|
133
|
+
/**
|
|
134
|
+
* A string prepended to every cache key to avoid collisions between
|
|
135
|
+
* applications sharing the same backing store.
|
|
136
|
+
*/
|
|
137
|
+
prefix: string;
|
|
138
|
+
/**
|
|
139
|
+
* The configured cache stores. Each entry is keyed by the name used with
|
|
140
|
+
* `Cache.store('<name>')`.
|
|
141
|
+
*/
|
|
142
|
+
stores: Record<string, CacheStoreConfig> & CustomCacheStoreRegistry;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Signature for a custom store factory registered via `Cache.extend`.
|
|
146
|
+
*/
|
|
147
|
+
type CacheStoreFactory = (config: CacheStoreConfig) => Store;
|
|
148
|
+
interface MemoryEntry {
|
|
149
|
+
value: unknown;
|
|
150
|
+
/** Absolute expiry in epoch milliseconds, or `null` for forever. */
|
|
151
|
+
expiresAt: number | null;
|
|
152
|
+
}
|
|
153
|
+
interface CacheRow {
|
|
154
|
+
key: string;
|
|
155
|
+
value: string;
|
|
156
|
+
/** Absolute expiry in epoch seconds, or `null` for forever. */
|
|
157
|
+
expiration: number | null;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Structural type for the `DB` class exported by `@arkstack/database`, declared
|
|
161
|
+
* locally so the cache package does not depend on it at build time (it is an
|
|
162
|
+
* optional peer dependency).
|
|
163
|
+
*/
|
|
164
|
+
interface DatabaseFacade {
|
|
165
|
+
table(table: string): {
|
|
166
|
+
where(where: Record<string, unknown>): {
|
|
167
|
+
first(): Promise<CacheRow | null>;
|
|
168
|
+
delete(): Promise<unknown>;
|
|
169
|
+
};
|
|
170
|
+
updateOrInsert(attributes: Record<string, unknown>, values: Record<string, unknown>): Promise<boolean>;
|
|
171
|
+
delete(): Promise<unknown>;
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Minimal structural type for the slice of the ioredis client we use. Declared
|
|
176
|
+
* locally so the package does not need ioredis types at build time (it is an
|
|
177
|
+
* optional peer dependency).
|
|
178
|
+
*/
|
|
179
|
+
interface RedisClient {
|
|
180
|
+
get(key: string): Promise<string | null>;
|
|
181
|
+
set(key: string, value: string): Promise<unknown>;
|
|
182
|
+
set(key: string, value: string, mode: 'EX', seconds: number): Promise<unknown>;
|
|
183
|
+
del(...keys: string[]): Promise<number>;
|
|
184
|
+
incrby(key: string, value: number): Promise<number>;
|
|
185
|
+
decrby(key: string, value: number): Promise<number>;
|
|
186
|
+
scan(cursor: string, match: 'MATCH', pattern: string, count: 'COUNT', n: number): Promise<[string, string[]]>;
|
|
187
|
+
quit(): Promise<unknown>;
|
|
188
|
+
}
|
|
189
|
+
//#endregion
|
|
190
|
+
//#region src/Repository.d.ts
|
|
191
|
+
/**
|
|
192
|
+
* Normalize a {@link CacheTtl} into a whole number of seconds, or `null` for a
|
|
193
|
+
* forever entry. A non positive duration is treated as already expired and
|
|
194
|
+
* returns `0`, signalling the caller to skip writing.
|
|
195
|
+
*/
|
|
196
|
+
declare const ttlToSeconds: (ttl: CacheTtl) => number | null;
|
|
197
|
+
/**
|
|
198
|
+
* A high level wrapper around a {@link Store} that provides the developer facing
|
|
199
|
+
* cache API. A repository is what `Cache.store()` returns.
|
|
200
|
+
*/
|
|
201
|
+
declare class Repository {
|
|
202
|
+
protected readonly store: Store;
|
|
203
|
+
constructor(store: Store);
|
|
204
|
+
/**
|
|
205
|
+
* Get the underlying store driver.
|
|
206
|
+
*/
|
|
207
|
+
getStore(): Store;
|
|
208
|
+
/**
|
|
209
|
+
* Determine whether an item exists in the cache and has not expired.
|
|
210
|
+
*
|
|
211
|
+
* @param key
|
|
212
|
+
* @returns
|
|
213
|
+
*/
|
|
214
|
+
has(key: string): Promise<boolean>;
|
|
215
|
+
/**
|
|
216
|
+
* Determine whether an item is missing from the cache.
|
|
217
|
+
*
|
|
218
|
+
* @param key
|
|
219
|
+
* @returns
|
|
220
|
+
*/
|
|
221
|
+
missing(key: string): Promise<boolean>;
|
|
222
|
+
/**
|
|
223
|
+
* Retrieve an item from the cache, falling back to `defaultValue` (which may
|
|
224
|
+
* be a callback) when the item is absent.
|
|
225
|
+
*
|
|
226
|
+
* @param key
|
|
227
|
+
* @returns
|
|
228
|
+
*/
|
|
229
|
+
get<T = unknown>(key: string, defaultValue?: Resolvable<T | null>): Promise<T | null>;
|
|
230
|
+
/**
|
|
231
|
+
* Retrieve an item and delete it from the cache in a single call.
|
|
232
|
+
*
|
|
233
|
+
* @param key
|
|
234
|
+
* @param defaultValue
|
|
235
|
+
* @returns
|
|
236
|
+
*/
|
|
237
|
+
pull<T = unknown>(key: string, defaultValue?: Resolvable<T | null>): Promise<T | null>;
|
|
238
|
+
/**
|
|
239
|
+
* Store an item in the cache. A `null`/omitted ttl stores the item forever;
|
|
240
|
+
* a non positive ttl is a no-op that also forgets any existing entry.
|
|
241
|
+
*
|
|
242
|
+
* @param key
|
|
243
|
+
* @param defaultValue
|
|
244
|
+
* @returns
|
|
245
|
+
*/
|
|
246
|
+
put(key: string, value: unknown, ttl?: CacheTtl): Promise<boolean>;
|
|
247
|
+
/**
|
|
248
|
+
* Alias for {@link put}.
|
|
249
|
+
*
|
|
250
|
+
* @param key
|
|
251
|
+
* @param defaultValue
|
|
252
|
+
* @returns
|
|
253
|
+
*/
|
|
254
|
+
set(key: string, value: unknown, ttl?: CacheTtl): Promise<boolean>;
|
|
255
|
+
/**
|
|
256
|
+
* Store an item only if it is not already present. Returns `false` when the
|
|
257
|
+
* key already exists.
|
|
258
|
+
*
|
|
259
|
+
* @param key
|
|
260
|
+
* @param defaultValue
|
|
261
|
+
* @returns
|
|
262
|
+
*/
|
|
263
|
+
add(key: string, value: unknown, ttl?: CacheTtl): Promise<boolean>;
|
|
264
|
+
/**
|
|
265
|
+
* Store an item that never expires.
|
|
266
|
+
*
|
|
267
|
+
* @param key
|
|
268
|
+
* @param defaultValue
|
|
269
|
+
* @returns
|
|
270
|
+
*/
|
|
271
|
+
forever(key: string, value: unknown): Promise<boolean>;
|
|
272
|
+
/**
|
|
273
|
+
* Increment a stored numeric value.
|
|
274
|
+
*
|
|
275
|
+
* @param key
|
|
276
|
+
* @param defaultValue
|
|
277
|
+
* @returns
|
|
278
|
+
*/
|
|
279
|
+
increment(key: string, value?: number): Promise<number | false>;
|
|
280
|
+
/**
|
|
281
|
+
* Decrement a stored numeric value.
|
|
282
|
+
*
|
|
283
|
+
* @param key
|
|
284
|
+
* @param defaultValue
|
|
285
|
+
* @returns
|
|
286
|
+
*/
|
|
287
|
+
decrement(key: string, value?: number): Promise<number | false>;
|
|
288
|
+
/**
|
|
289
|
+
* Get an item from the cache, or execute the callback, store its result for
|
|
290
|
+
* the given ttl, and return it.
|
|
291
|
+
*
|
|
292
|
+
* @param key
|
|
293
|
+
* @param defaultValue
|
|
294
|
+
* @returns
|
|
295
|
+
*/
|
|
296
|
+
remember<T>(key: string, ttl: CacheTtl, callback: () => T | Promise<T>): Promise<T>;
|
|
297
|
+
/**
|
|
298
|
+
* Get an item from the cache, or execute the callback and store its result
|
|
299
|
+
* forever.
|
|
300
|
+
*
|
|
301
|
+
* @param key
|
|
302
|
+
* @param defaultValue
|
|
303
|
+
* @returns
|
|
304
|
+
*/
|
|
305
|
+
rememberForever<T>(key: string, callback: () => T | Promise<T>): Promise<T>;
|
|
306
|
+
/**
|
|
307
|
+
* Alias for {@link rememberForever}.
|
|
308
|
+
*
|
|
309
|
+
* @param key
|
|
310
|
+
* @param callback
|
|
311
|
+
* @returns
|
|
312
|
+
*/
|
|
313
|
+
sear<T>(key: string, callback: () => T | Promise<T>): Promise<T>;
|
|
314
|
+
/**
|
|
315
|
+
* Remove an item from the cache.
|
|
316
|
+
*
|
|
317
|
+
* @param key
|
|
318
|
+
* @param callback
|
|
319
|
+
* @returns
|
|
320
|
+
*/
|
|
321
|
+
forget(key: string): Promise<boolean>;
|
|
322
|
+
/**
|
|
323
|
+
* Alias for {@link forget}.
|
|
324
|
+
*
|
|
325
|
+
* @param key
|
|
326
|
+
* @param callback
|
|
327
|
+
* @returns
|
|
328
|
+
*/
|
|
329
|
+
delete(key: string): Promise<boolean>;
|
|
330
|
+
/**
|
|
331
|
+
* Remove every item from the cache store.
|
|
332
|
+
*
|
|
333
|
+
* @param key
|
|
334
|
+
* @param callback
|
|
335
|
+
* @returns
|
|
336
|
+
*/
|
|
337
|
+
flush(): Promise<boolean>;
|
|
338
|
+
/**
|
|
339
|
+
* Alias for {@link flush}.
|
|
340
|
+
*
|
|
341
|
+
* @param key
|
|
342
|
+
* @param callback
|
|
343
|
+
* @returns
|
|
344
|
+
*/
|
|
345
|
+
clear(): Promise<boolean>;
|
|
346
|
+
}
|
|
347
|
+
//#endregion
|
|
348
|
+
//#region src/CacheManager.d.ts
|
|
349
|
+
/**
|
|
350
|
+
* The cache manager and primary entry point of `@arkstack/cache`.
|
|
351
|
+
*
|
|
352
|
+
* Resolves named cache stores from configuration, memoizes the resulting
|
|
353
|
+
* repositories, and exposes static convenience methods that proxy the default
|
|
354
|
+
* store, e.g.:
|
|
355
|
+
*
|
|
356
|
+
* ```ts
|
|
357
|
+
* await Cache.put('user:1', user, 60)
|
|
358
|
+
* await Cache.store('redis').remember('stats', 300, computeStats)
|
|
359
|
+
* ```
|
|
360
|
+
*/
|
|
361
|
+
declare class Cache {
|
|
362
|
+
private static repositories;
|
|
363
|
+
private static customDrivers;
|
|
364
|
+
/**
|
|
365
|
+
* Resolve a cache repository for the given store name (or the default store
|
|
366
|
+
* when omitted). Repositories are memoized per name.
|
|
367
|
+
*/
|
|
368
|
+
static store(name?: string): Repository;
|
|
369
|
+
/**
|
|
370
|
+
* Alias for {@link store}.
|
|
371
|
+
*/
|
|
372
|
+
static driver(name?: string): Repository;
|
|
373
|
+
/**
|
|
374
|
+
* Register a custom store driver factory, used when a store's `driver` does
|
|
375
|
+
* not match a built in one.
|
|
376
|
+
*/
|
|
377
|
+
static extend(driver: string, factory: CacheStoreFactory): typeof Cache;
|
|
378
|
+
/**
|
|
379
|
+
* Clear the memoized repositories. Mainly useful between tests or after the
|
|
380
|
+
* configuration changes at runtime.
|
|
381
|
+
*/
|
|
382
|
+
static clearResolved(): void;
|
|
383
|
+
/**
|
|
384
|
+
* Build a repository for a configured store from scratch.
|
|
385
|
+
*/
|
|
386
|
+
private static resolve;
|
|
387
|
+
/**
|
|
388
|
+
* Instantiate the concrete {@link Store} for a store config.
|
|
389
|
+
*/
|
|
390
|
+
private static createStore;
|
|
391
|
+
static has(key: string): Promise<boolean>;
|
|
392
|
+
static missing(key: string): Promise<boolean>;
|
|
393
|
+
static get<T = unknown>(key: string, defaultValue?: Resolvable<T | null>): Promise<T | null>;
|
|
394
|
+
static pull<T = unknown>(key: string, defaultValue?: Resolvable<T | null>): Promise<T | null>;
|
|
395
|
+
static put(key: string, value: unknown, ttl?: CacheTtl): Promise<boolean>;
|
|
396
|
+
static set(key: string, value: unknown, ttl?: CacheTtl): Promise<boolean>;
|
|
397
|
+
static add(key: string, value: unknown, ttl?: CacheTtl): Promise<boolean>;
|
|
398
|
+
static forever(key: string, value: unknown): Promise<boolean>;
|
|
399
|
+
static increment(key: string, value?: number): Promise<number | false>;
|
|
400
|
+
static decrement(key: string, value?: number): Promise<number | false>;
|
|
401
|
+
static remember<T>(key: string, ttl: CacheTtl, callback: () => T | Promise<T>): Promise<T>;
|
|
402
|
+
static rememberForever<T>(key: string, callback: () => T | Promise<T>): Promise<T>;
|
|
403
|
+
static forget(key: string): Promise<boolean>;
|
|
404
|
+
static delete(key: string): Promise<boolean>;
|
|
405
|
+
static flush(): Promise<boolean>;
|
|
406
|
+
static clear(): Promise<boolean>;
|
|
407
|
+
}
|
|
408
|
+
//#endregion
|
|
409
|
+
//#region src/config.d.ts
|
|
410
|
+
/**
|
|
411
|
+
* Read a value from the `cache` configuration namespace with a fallback.
|
|
412
|
+
*
|
|
413
|
+
* Mirrors the framework `config()` helper but is scoped to the cache config and
|
|
414
|
+
* never throws when the config file is missing, returning the default instead.
|
|
415
|
+
*
|
|
416
|
+
* @param key Dot path within the cache config.
|
|
417
|
+
* @param defaultValue Value returned when the key is not set.
|
|
418
|
+
*/
|
|
419
|
+
declare const configure: <T extends DotPath<CacheConfig>>(key: T, defaultValue: unknown) => DotPathValue<CacheConfig, T>;
|
|
420
|
+
//#endregion
|
|
421
|
+
//#region src/drivers/MemoryStore.d.ts
|
|
422
|
+
/**
|
|
423
|
+
* An in-process cache store backed by a `Map`.
|
|
424
|
+
*
|
|
425
|
+
* The backing map is shared across every `MemoryStore` instance that uses the
|
|
426
|
+
* same prefix, so resolving the store twice within a process sees the same data
|
|
427
|
+
* (matching how the other backends behave). Great for development and tests; it
|
|
428
|
+
* is not shared across processes.
|
|
429
|
+
*/
|
|
430
|
+
declare class MemoryStore extends Store {
|
|
431
|
+
private readonly prefix;
|
|
432
|
+
private static stores;
|
|
433
|
+
private readonly entries;
|
|
434
|
+
constructor(prefix?: string);
|
|
435
|
+
getPrefix(): string;
|
|
436
|
+
get<T = unknown>(key: string): Promise<T | null>;
|
|
437
|
+
put(key: string, value: unknown, seconds?: number | null): Promise<boolean>;
|
|
438
|
+
forever(key: string, value: unknown): Promise<boolean>;
|
|
439
|
+
increment(key: string, value?: number): Promise<number | false>;
|
|
440
|
+
decrement(key: string, value?: number): Promise<number | false>;
|
|
441
|
+
forget(key: string): Promise<boolean>;
|
|
442
|
+
flush(): Promise<boolean>;
|
|
443
|
+
}
|
|
444
|
+
//#endregion
|
|
445
|
+
//#region src/drivers/FileStore.d.ts
|
|
446
|
+
/**
|
|
447
|
+
* A cache store that persists each entry as a JSON file on disk.
|
|
448
|
+
*
|
|
449
|
+
* Keys are hashed to produce safe, fixed length file names. Expired files are
|
|
450
|
+
* removed lazily on read and ignored otherwise.
|
|
451
|
+
*/
|
|
452
|
+
declare class FileStore extends Store {
|
|
453
|
+
private readonly directory;
|
|
454
|
+
private readonly prefix;
|
|
455
|
+
constructor(directory: string, prefix?: string);
|
|
456
|
+
getPrefix(): string;
|
|
457
|
+
private pathFor;
|
|
458
|
+
private ensureDirectory;
|
|
459
|
+
get<T = unknown>(key: string): Promise<T | null>;
|
|
460
|
+
put(key: string, value: unknown, seconds?: number | null): Promise<boolean>;
|
|
461
|
+
forever(key: string, value: unknown): Promise<boolean>;
|
|
462
|
+
increment(key: string, value?: number): Promise<number | false>;
|
|
463
|
+
decrement(key: string, value?: number): Promise<number | false>;
|
|
464
|
+
forget(key: string): Promise<boolean>;
|
|
465
|
+
flush(): Promise<boolean>;
|
|
466
|
+
}
|
|
467
|
+
//#endregion
|
|
468
|
+
//#region src/drivers/RedisStore.d.ts
|
|
469
|
+
/**
|
|
470
|
+
* A Redis backed cache store using an ioredis compatible client.
|
|
471
|
+
*
|
|
472
|
+
* Values are JSON serialized. Numeric helpers use native `INCRBY`/`DECRBY` so
|
|
473
|
+
* counters stay atomic across processes. `ioredis` is an optional peer
|
|
474
|
+
* dependency; it is imported lazily so applications that never use the redis
|
|
475
|
+
* store don't need it installed.
|
|
476
|
+
*/
|
|
477
|
+
declare class RedisStore extends Store {
|
|
478
|
+
private readonly redisConfig;
|
|
479
|
+
private readonly prefix;
|
|
480
|
+
private client?;
|
|
481
|
+
constructor(redisConfig: RedisStoreConfig, prefix?: string);
|
|
482
|
+
getPrefix(): string;
|
|
483
|
+
private prefixed;
|
|
484
|
+
private connection;
|
|
485
|
+
/**
|
|
486
|
+
* Disconnect the underlying client. Useful for tests and graceful shutdown.
|
|
487
|
+
*/
|
|
488
|
+
disconnect(): Promise<void>;
|
|
489
|
+
get<T = unknown>(key: string): Promise<T | null>;
|
|
490
|
+
put(key: string, value: unknown, seconds?: number | null): Promise<boolean>;
|
|
491
|
+
forever(key: string, value: unknown): Promise<boolean>;
|
|
492
|
+
increment(key: string, value?: number): Promise<number | false>;
|
|
493
|
+
decrement(key: string, value?: number): Promise<number | false>;
|
|
494
|
+
forget(key: string): Promise<boolean>;
|
|
495
|
+
flush(): Promise<boolean>;
|
|
496
|
+
}
|
|
497
|
+
//#endregion
|
|
498
|
+
//#region src/drivers/DatabaseStore.d.ts
|
|
499
|
+
/**
|
|
500
|
+
* A cache store that persists entries in a relational table via
|
|
501
|
+
* `@arkstack/database`.
|
|
502
|
+
*
|
|
503
|
+
* The table is expected to have `key` (string, primary), `value` (text), and
|
|
504
|
+
* `expiration` (nullable integer epoch seconds) columns. Run
|
|
505
|
+
* `ark publish --tag cache-migrations` to add the migration that creates it.
|
|
506
|
+
* `@arkstack/database` is an optional peer dependency and is imported lazily.
|
|
507
|
+
*/
|
|
508
|
+
declare class DatabaseStore extends Store {
|
|
509
|
+
private readonly databaseConfig;
|
|
510
|
+
private readonly prefix;
|
|
511
|
+
private db?;
|
|
512
|
+
constructor(databaseConfig: DatabaseStoreConfig, prefix?: string);
|
|
513
|
+
getPrefix(): string;
|
|
514
|
+
private prefixed;
|
|
515
|
+
private get table();
|
|
516
|
+
private database;
|
|
517
|
+
get<T = unknown>(key: string): Promise<T | null>;
|
|
518
|
+
put(key: string, value: unknown, seconds?: number | null): Promise<boolean>;
|
|
519
|
+
forever(key: string, value: unknown): Promise<boolean>;
|
|
520
|
+
increment(key: string, value?: number): Promise<number | false>;
|
|
521
|
+
decrement(key: string, value?: number): Promise<number | false>;
|
|
522
|
+
forget(key: string): Promise<boolean>;
|
|
523
|
+
flush(): Promise<boolean>;
|
|
524
|
+
}
|
|
525
|
+
//#endregion
|
|
526
|
+
export { Cache, CacheConfig, CacheDriverName, CacheRow, CacheStoreConfig, CacheStoreFactory, CacheTtl, CustomCacheStoreRegistry, DatabaseFacade, DatabaseStore, DatabaseStoreConfig, FilePayload, FileStore, FileStoreConfig, MemoryEntry, MemoryStore, MemoryStoreConfig, RedisClient, RedisStore, RedisStoreConfig, Repository, Resolvable, Store, configure, ttlToSeconds };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as RedisStore, c as DatabaseStore, i as ttlToSeconds, l as Store, n as configure, o as MemoryStore, r as Repository, s as FileStore, t as Cache } from "./CacheManager-Do82q7KO.js";
|
|
2
|
+
export { Cache, DatabaseStore, FileStore, MemoryStore, RedisStore, Repository, Store, configure, ttlToSeconds };
|
package/dist/setup.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
package/dist/setup.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { dirname, join } from "node:path";
|
|
2
|
+
import { Publisher } from "@arkstack/common";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
//#region src/setup.ts
|
|
5
|
+
const root = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
6
|
+
/**
|
|
7
|
+
* Register the artifacts `@arkstack/cache` publishes into the application.
|
|
8
|
+
*
|
|
9
|
+
* Run `ark publish --package @arkstack/cache` (or `--tag cache-migrations`) to
|
|
10
|
+
* copy the migration for the `database` cache store into the app.
|
|
11
|
+
*/
|
|
12
|
+
Publisher.publishes({
|
|
13
|
+
package: "@arkstack/cache",
|
|
14
|
+
tag: "cache-migrations",
|
|
15
|
+
entries: [{
|
|
16
|
+
from: join(root, "stubs/migrations/20260601000000_create_cache_table.ts.stub"),
|
|
17
|
+
to: "src/database/migrations/20260601000000_create_cache_table.ts"
|
|
18
|
+
}]
|
|
19
|
+
});
|
|
20
|
+
//#endregion
|
|
21
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@arkstack/cache",
|
|
3
|
+
"version": "0.5.3",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Cache module for Arkstack, providing a unified, driver based caching layer for the framework.",
|
|
6
|
+
"homepage": "https://arkstack.toneflix.net/guide/cache",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/arkstack-hq/arkstack.git",
|
|
10
|
+
"directory": "packages/cache"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"cache",
|
|
14
|
+
"caching",
|
|
15
|
+
"memory",
|
|
16
|
+
"file",
|
|
17
|
+
"redis",
|
|
18
|
+
"database",
|
|
19
|
+
"store",
|
|
20
|
+
"arkstack"
|
|
21
|
+
],
|
|
22
|
+
"files": [
|
|
23
|
+
"dist",
|
|
24
|
+
"stubs"
|
|
25
|
+
],
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"exports": {
|
|
30
|
+
".": "./dist/index.js",
|
|
31
|
+
"./commands/CacheClearCommand": "./dist/commands/CacheClearCommand.js",
|
|
32
|
+
"./setup": "./dist/setup.js",
|
|
33
|
+
"./package.json": "./package.json"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@arkstack/common": "^0.5.3"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"@h3ravel/musket": "^2.2.1",
|
|
40
|
+
"ioredis": "^5.4.1",
|
|
41
|
+
"@arkstack/contract": "^0.5.3",
|
|
42
|
+
"@arkstack/database": "^0.5.3"
|
|
43
|
+
},
|
|
44
|
+
"peerDependenciesMeta": {
|
|
45
|
+
"@arkstack/database": {
|
|
46
|
+
"optional": true
|
|
47
|
+
},
|
|
48
|
+
"ioredis": {
|
|
49
|
+
"optional": true
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "tsdown",
|
|
54
|
+
"test": "vitest",
|
|
55
|
+
"version:patch": "pnpm version patch"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Migration, SchemaBuilder } from 'arkormx'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Backing table for the `database` cache store (`@arkstack/cache`).
|
|
5
|
+
*
|
|
6
|
+
* Columns: `key` (string primary), `value` (text), `expiration` (nullable
|
|
7
|
+
* epoch seconds). Adjust the table name to match `cache.stores.database.table`.
|
|
8
|
+
*/
|
|
9
|
+
export default class CreateCacheTableMigration extends Migration {
|
|
10
|
+
public async up (schema: SchemaBuilder): Promise<void> {
|
|
11
|
+
schema.createTable('cache', (table) => {
|
|
12
|
+
table.string('key').primary()
|
|
13
|
+
table.text('value')
|
|
14
|
+
table.integer('expiration').nullable()
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public async down (schema: SchemaBuilder): Promise<void> {
|
|
19
|
+
schema.dropTable('cache')
|
|
20
|
+
}
|
|
21
|
+
}
|