@rapidrest/core 2.0.0 → 3.0.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/lib/MemoryStore.js +3 -4
- package/dist/lib/MemoryStore.js.map +1 -1
- package/dist/lib/RedisStore.js +129 -0
- package/dist/lib/RedisStore.js.map +1 -0
- package/dist/lib/SimpleStore.js +5 -0
- package/dist/lib/SimpleStore.js.map +1 -0
- package/dist/types/MemoryStore.d.ts +6 -10
- package/dist/types/RedisStore.d.ts +26 -0
- package/dist/types/SimpleStore.d.ts +33 -0
- package/package.json +3 -1
package/dist/lib/MemoryStore.js
CHANGED
|
@@ -15,8 +15,7 @@ import { Destroy } from "./decorators/ObjectDecorators.js";
|
|
|
15
15
|
/** How often the sweep interval reclaims expired, never-reloaded sessions. */
|
|
16
16
|
const SWEEP_INTERVAL_MS = 60000;
|
|
17
17
|
/**
|
|
18
|
-
* Implements a
|
|
19
|
-
* lifetime (TTL) and size.
|
|
18
|
+
* Implements a SimpleStore storage system that uses a local in-memory storage map.
|
|
20
19
|
*
|
|
21
20
|
* @author Jean-Philippe Steinmetz
|
|
22
21
|
*/
|
|
@@ -46,7 +45,7 @@ export class MemoryStore {
|
|
|
46
45
|
}
|
|
47
46
|
return entry.data;
|
|
48
47
|
}
|
|
49
|
-
save(id, data,
|
|
48
|
+
save(id, data, ttl = this.defaultTTL) {
|
|
50
49
|
if (!this.entries.has(id) && this.entries.size >= this.maxSize) {
|
|
51
50
|
// Reclaim space by sweeping expired entries first, then evicting the oldest surviving entries
|
|
52
51
|
this.sweep();
|
|
@@ -59,7 +58,7 @@ export class MemoryStore {
|
|
|
59
58
|
// at its original (oldest) position and `evictOldest()` would evict it ahead of a genuinely idle entry
|
|
60
59
|
// inserted later.
|
|
61
60
|
this.entries.delete(id);
|
|
62
|
-
this.entries.set(id, { data, expiresAt: Date.now() +
|
|
61
|
+
this.entries.set(id, { data, expiresAt: Date.now() + ttl * 1000 });
|
|
63
62
|
}
|
|
64
63
|
delete(id) {
|
|
65
64
|
this.entries.delete(id);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MemoryStore.js","sourceRoot":"","sources":["../../src/MemoryStore.ts"],"names":[],"mappings":";;;;;;;;;AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,+EAA+E;AAC/E,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"MemoryStore.js","sourceRoot":"","sources":["../../src/MemoryStore.ts"],"names":[],"mappings":";;;;;;;;;AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,+EAA+E;AAC/E,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAG3D,8EAA8E;AAC9E,MAAM,iBAAiB,GAAG,KAAM,CAAC;AAEjC;;;;GAIG;AACH,MAAM,OAAO,WAAW;IAWpB;QAVA,2CAA2C;QACpC,eAAU,GAAW,EAAE,CAAC;QAErB,YAAO,GAAqC,IAAI,GAAG,EAAE,CAAC;QAEhE,8CAA8C;QACvC,YAAO,GAAW,KAAK,CAAC;QAK3B,IAAI,CAAC,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,iBAAiB,CAAC,CAAC;QACrE,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC;IAC9B,CAAC;IAED,4FAA4F;IAErF,OAAO;QACV,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC;IAEM,IAAI,CAAC,EAAU;QAClB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnC,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,2CAA2C;QAC3C,IAAI,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YAChC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACxB,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC;IACtB,CAAC;IAEM,IAAI,CAAC,EAAU,EAAE,IAAuB,EAAE,MAAc,IAAI,CAAC,UAAU;QAC1E,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAC7D,8FAA8F;YAC9F,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;gBAChE,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACzC,CAAC;QACL,CAAC;QACD,uGAAuG;QACvG,0GAA0G;QAC1G,uGAAuG;QACvG,kBAAkB;QAClB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACxB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,EAAE,CAAC,CAAC;IACvE,CAAC;IAEM,MAAM,CAAC,EAAU;QACpB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC;IAEO,KAAK;QACT,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YACtD,IAAI,KAAK,CAAC,SAAS,IAAI,GAAG;gBAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC/D,CAAC;IACL,CAAC;CACJ;AA7CU;IADN,OAAO;;;;0CAGP"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
11
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
|
|
12
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
13
|
+
import { CacheUtils } from "./CacheUtils.js";
|
|
14
|
+
import { Destroy } from "./decorators/ObjectDecorators.js";
|
|
15
|
+
/** How often the sweep interval reclaims expired, never-reloaded sessions. */
|
|
16
|
+
const SWEEP_INTERVAL_MS = 60000;
|
|
17
|
+
/**
|
|
18
|
+
* Implements a SimpleStore storage system that combines a local in-memory store optionally backed by Redis. When
|
|
19
|
+
* no Redis client is given, the store behaves as a plain in-memory store (equivalent to `MemoryStore`).
|
|
20
|
+
*
|
|
21
|
+
* @author Jean-Philippe Steinmetz
|
|
22
|
+
*/
|
|
23
|
+
export class RedisStore {
|
|
24
|
+
/**
|
|
25
|
+
* @param client The Redis client to back this store with. When omitted, the store operates purely in-memory.
|
|
26
|
+
*/
|
|
27
|
+
constructor(client) {
|
|
28
|
+
/** The default record TTL (in seconds). */
|
|
29
|
+
this.defaultTTL = 60;
|
|
30
|
+
this.entries = new Map();
|
|
31
|
+
/** The maximum number of records to store. */
|
|
32
|
+
this.maxSize = 10000;
|
|
33
|
+
this.client = client;
|
|
34
|
+
this.sweepTimer = setInterval(() => this.sweep(), SWEEP_INTERVAL_MS);
|
|
35
|
+
this.sweepTimer.unref?.();
|
|
36
|
+
}
|
|
37
|
+
destroy() {
|
|
38
|
+
clearInterval(this.sweepTimer);
|
|
39
|
+
}
|
|
40
|
+
async load(id) {
|
|
41
|
+
const entry = this.entries.get(id);
|
|
42
|
+
if (entry) {
|
|
43
|
+
// If the local copy hasn't expired, it's safe to serve directly.
|
|
44
|
+
if (entry.expiresAt > Date.now()) {
|
|
45
|
+
return entry.data;
|
|
46
|
+
}
|
|
47
|
+
// The local copy has expired, but Redis is the source of truth: another process may have renewed
|
|
48
|
+
// the entry (longer TTL) since we cached it here. Drop the stale local copy and fall through to
|
|
49
|
+
// check Redis instead of reporting "not found" based on local state alone.
|
|
50
|
+
this.entries.delete(id);
|
|
51
|
+
}
|
|
52
|
+
// Without a Redis client, this is a pure in-memory store: a local miss/expiry is a real miss.
|
|
53
|
+
if (!this.client) {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
// The entry wasn't found locally. Try retrieving from redis.
|
|
57
|
+
// We'll also grab the ttl so we can add it to our local map.
|
|
58
|
+
const result = await this.client
|
|
59
|
+
.multi([
|
|
60
|
+
["get", id],
|
|
61
|
+
["ttl", id],
|
|
62
|
+
])
|
|
63
|
+
.exec();
|
|
64
|
+
if (!result) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
const data = result[0][1] ? result[0][1] : undefined;
|
|
68
|
+
const ttl = result[1][1] ?? undefined;
|
|
69
|
+
if (!data) {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
// Store the entry in our in-memory map for faster retrieval in the future. Bound the local map the same
|
|
73
|
+
// way save() does — otherwise repeated load()s of distinct ids that already exist in Redis (a normal
|
|
74
|
+
// read path) would grow the local map without limit, regardless of maxSize.
|
|
75
|
+
if (!this.entries.has(id) && this.entries.size >= this.maxSize) {
|
|
76
|
+
this.sweep();
|
|
77
|
+
while (this.entries.size >= this.maxSize && this.entries.size > 0) {
|
|
78
|
+
CacheUtils.evictOldest(this.entries);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const newEntry = {
|
|
82
|
+
data: JSON.parse(data),
|
|
83
|
+
expiresAt: Date.now() + ttl * 1000,
|
|
84
|
+
};
|
|
85
|
+
this.entries.set(id, newEntry);
|
|
86
|
+
return newEntry.data;
|
|
87
|
+
}
|
|
88
|
+
async save(id, data, ttl = this.defaultTTL) {
|
|
89
|
+
// Write to Redis first (when configured): if it fails (bad connection, etc.), the local cache is left
|
|
90
|
+
// untouched instead of reporting a "saved" value locally that never made it to the shared store other
|
|
91
|
+
// instances read from.
|
|
92
|
+
if (this.client) {
|
|
93
|
+
await this.client.setex(id, ttl, JSON.stringify(data));
|
|
94
|
+
}
|
|
95
|
+
if (!this.entries.has(id) && this.entries.size >= this.maxSize) {
|
|
96
|
+
// Reclaim space by sweeping expired entries first, then evicting the oldest surviving entries
|
|
97
|
+
this.sweep();
|
|
98
|
+
while (this.entries.size >= this.maxSize && this.entries.size > 0) {
|
|
99
|
+
CacheUtils.evictOldest(this.entries);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Delete before re-inserting so a renewed entry moves to the end of the Map's iteration order. A `Map`
|
|
103
|
+
// does not reorder on `set()` of an already-present key, so without this, an actively-renewed entry stays
|
|
104
|
+
// at its original (oldest) position and `evictOldest()` would evict it ahead of a genuinely idle entry
|
|
105
|
+
// inserted later.
|
|
106
|
+
this.entries.delete(id);
|
|
107
|
+
this.entries.set(id, { data, expiresAt: Date.now() + ttl * 1000 });
|
|
108
|
+
}
|
|
109
|
+
async delete(id) {
|
|
110
|
+
this.entries.delete(id);
|
|
111
|
+
if (this.client) {
|
|
112
|
+
await this.client.del(id);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
sweep() {
|
|
116
|
+
const now = Date.now();
|
|
117
|
+
for (const [sessionId, entry] of this.entries.entries()) {
|
|
118
|
+
if (entry.expiresAt <= now)
|
|
119
|
+
this.entries.delete(sessionId);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
__decorate([
|
|
124
|
+
Destroy,
|
|
125
|
+
__metadata("design:type", Function),
|
|
126
|
+
__metadata("design:paramtypes", []),
|
|
127
|
+
__metadata("design:returntype", void 0)
|
|
128
|
+
], RedisStore.prototype, "destroy", null);
|
|
129
|
+
//# sourceMappingURL=RedisStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RedisStore.js","sourceRoot":"","sources":["../../src/RedisStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
|
|
3
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
4
|
+
export {};
|
|
5
|
+
//# sourceMappingURL=SimpleStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SimpleStore.js","sourceRoot":"","sources":["../../src/SimpleStore.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,+EAA+E"}
|
|
@@ -1,25 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
data: Record<string, any>;
|
|
3
|
-
expiresAt: number;
|
|
4
|
-
}
|
|
1
|
+
import { MemoryStoreEntry, SimpleStore } from "./SimpleStore.js";
|
|
5
2
|
/**
|
|
6
|
-
* Implements a
|
|
7
|
-
* lifetime (TTL) and size.
|
|
3
|
+
* Implements a SimpleStore storage system that uses a local in-memory storage map.
|
|
8
4
|
*
|
|
9
5
|
* @author Jean-Philippe Steinmetz
|
|
10
6
|
*/
|
|
11
|
-
export declare class MemoryStore {
|
|
7
|
+
export declare class MemoryStore<T> implements SimpleStore<T> {
|
|
12
8
|
/** The default record TTL (in seconds). */
|
|
13
9
|
defaultTTL: number;
|
|
14
|
-
protected entries: Map<string, MemoryStoreEntry
|
|
10
|
+
protected entries: Map<string, MemoryStoreEntry<T>>;
|
|
15
11
|
/** The maximum number of records to store. */
|
|
16
12
|
maxSize: number;
|
|
17
13
|
private sweepTimer;
|
|
18
14
|
constructor();
|
|
19
15
|
/** Stops the background sweep timer. Call when the owning `SessionManager` is destroyed. */
|
|
20
16
|
destroy(): void;
|
|
21
|
-
load(id: string): Record<string,
|
|
22
|
-
save(id: string, data: Record<string,
|
|
17
|
+
load(id: string): Record<string, T> | undefined;
|
|
18
|
+
save(id: string, data: Record<string, T>, ttl?: number): void;
|
|
23
19
|
delete(id: string): void;
|
|
24
20
|
private sweep;
|
|
25
21
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { MemoryStoreEntry, SimpleStore } from "./SimpleStore.js";
|
|
2
|
+
import type * as ioredis from "ioredis";
|
|
3
|
+
/**
|
|
4
|
+
* Implements a SimpleStore storage system that combines a local in-memory store optionally backed by Redis. When
|
|
5
|
+
* no Redis client is given, the store behaves as a plain in-memory store (equivalent to `MemoryStore`).
|
|
6
|
+
*
|
|
7
|
+
* @author Jean-Philippe Steinmetz
|
|
8
|
+
*/
|
|
9
|
+
export declare class RedisStore<T> implements SimpleStore<T> {
|
|
10
|
+
client?: ioredis.Redis;
|
|
11
|
+
/** The default record TTL (in seconds). */
|
|
12
|
+
defaultTTL: number;
|
|
13
|
+
protected entries: Map<string, MemoryStoreEntry<T>>;
|
|
14
|
+
/** The maximum number of records to store. */
|
|
15
|
+
maxSize: number;
|
|
16
|
+
private sweepTimer;
|
|
17
|
+
/**
|
|
18
|
+
* @param client The Redis client to back this store with. When omitted, the store operates purely in-memory.
|
|
19
|
+
*/
|
|
20
|
+
constructor(client?: ioredis.Redis);
|
|
21
|
+
destroy(): void;
|
|
22
|
+
load(id: string): Promise<Record<string, T> | undefined>;
|
|
23
|
+
save(id: string, data: Record<string, T>, ttl?: number): Promise<void>;
|
|
24
|
+
delete(id: string): Promise<void>;
|
|
25
|
+
private sweep;
|
|
26
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface MemoryStoreEntry<T> {
|
|
2
|
+
data: Record<string, T>;
|
|
3
|
+
expiresAt: number;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Defines an interface for a simple key-value storage system that stores temporary records with a specified
|
|
7
|
+
* lifetime (TTL) and size.
|
|
8
|
+
*
|
|
9
|
+
* @author Jean-Philippe Steinmetz
|
|
10
|
+
*/
|
|
11
|
+
export interface SimpleStore<T> {
|
|
12
|
+
/** The default record TTL (in seconds). */
|
|
13
|
+
defaultTTL: number;
|
|
14
|
+
/** The maximum number of records to store. */
|
|
15
|
+
maxSize: number;
|
|
16
|
+
/**
|
|
17
|
+
* Deletes the record with the given id.
|
|
18
|
+
* @param id The id of the record to delete.
|
|
19
|
+
*/
|
|
20
|
+
delete(id: string): Promise<void> | void;
|
|
21
|
+
/**
|
|
22
|
+
* Retrieves the record with the given id.
|
|
23
|
+
* @param id The id of the record to retrieve.
|
|
24
|
+
*/
|
|
25
|
+
load(id: string): Promise<Record<string, T> | undefined> | Record<string, T> | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Stores the record with the given id for the specified TTL.
|
|
28
|
+
* @param id The id of the record to retrieve.
|
|
29
|
+
* @param data The record to store.
|
|
30
|
+
* @param ttl The number of seconds that the record will be stored.
|
|
31
|
+
*/
|
|
32
|
+
save(id: string, data: Record<string, T>, ttl: number): Promise<void> | void;
|
|
33
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rapidrest/core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "A collection of common utilities and core functionality for rapidly building RESTful applications.",
|
|
5
5
|
"repository": "https://github.com/rapidrest/core.git",
|
|
6
6
|
"author": "RapidREST <rapidrests@gmail.com>",
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"axios": "1.x",
|
|
37
|
+
"ioredis": "6.x",
|
|
37
38
|
"reflect-metadata": "0.2.x",
|
|
38
39
|
"winston": "3.x",
|
|
39
40
|
"winston-transport": "4.x"
|
|
@@ -58,6 +59,7 @@
|
|
|
58
59
|
"eslint-config-prettier": "^10.1.8",
|
|
59
60
|
"eslint-plugin-import": "^2.32.0",
|
|
60
61
|
"eslint-plugin-jsdoc": "^63.0.2",
|
|
62
|
+
"ioredis": "^6.0.0",
|
|
61
63
|
"mkdirp": "^3.0.1",
|
|
62
64
|
"nconf": "^0.13.0",
|
|
63
65
|
"nock": "^14.0.15",
|