@rsdk/nats.kv 5.4.0-next.4 → 5.4.0-next.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/dist/kv-storage.d.ts +14 -3
- package/dist/kv-storage.js +53 -11
- package/dist/kv-storage.js.map +1 -1
- package/dist/nats-kv.service.js +1 -1
- package/dist/nats-kv.service.js.map +1 -1
- package/package.json +4 -4
- package/src/kv-storage.ts +64 -10
- package/src/nats-kv.service.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [5.4.0-next.6](https://github.com/R-Vision/rsdk/compare/v5.4.0-next.5...v5.4.0-next.6) (2024-11-28)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @rsdk/nats.kv
|
|
9
|
+
|
|
10
|
+
## [5.4.0-next.5](https://github.com/R-Vision/rsdk/compare/v5.4.0-next.4...v5.4.0-next.5) (2024-11-28)
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
* get meta for kv entry ([#309](https://github.com/R-Vision/rsdk/issues/309)) ([ff8c39d](https://github.com/R-Vision/rsdk/commit/ff8c39d2cc072230931023c9d1e2cef716fa3eaf))
|
|
15
|
+
|
|
6
16
|
## [5.4.0-next.4](https://github.com/R-Vision/rsdk/compare/v5.4.0-next.3...v5.4.0-next.4) (2024-11-27)
|
|
7
17
|
|
|
8
18
|
### Bug Fixes
|
package/dist/kv-storage.d.ts
CHANGED
|
@@ -1,15 +1,25 @@
|
|
|
1
1
|
import type { ILogger } from '@rsdk/logging';
|
|
2
|
-
import type { KV, KvDeleteOptions,
|
|
2
|
+
import type { KV, KvDeleteOptions, KvPutOptions, KvStatus, NatsConnection, Payload } from 'nats';
|
|
3
3
|
import type { NatsKvEntry } from './interfaces/nats-kv-entry.interface';
|
|
4
|
+
import type { NatsKvEntryMeta } from './interfaces/nats-kv-entry-meta.interface';
|
|
4
5
|
import type { DecodeFunc } from './types/decode-func.type';
|
|
5
6
|
export declare class KvStorage {
|
|
6
7
|
private readonly storage;
|
|
7
8
|
private readonly logger;
|
|
8
|
-
|
|
9
|
+
private readonly bucketName;
|
|
10
|
+
private readonly connection;
|
|
11
|
+
constructor(storage: KV, logger: ILogger, bucketName: string, connection: NatsConnection);
|
|
9
12
|
getKeys(filter?: string | string[]): Promise<string[]>;
|
|
10
13
|
getAllWithMeta<Decode extends DecodeFunc>(decode: Decode, filter?: string | string[]): Promise<NatsKvEntry<Decode>[]>;
|
|
11
14
|
get<Decode extends DecodeFunc>(key: string, decode: Decode): Promise<ReturnType<Decode> | null>;
|
|
12
|
-
getWithMeta(key: string): Promise<
|
|
15
|
+
getWithMeta<Decode extends DecodeFunc>(key: string, decode: Decode): Promise<NatsKvEntry<Decode> | null>;
|
|
16
|
+
/**
|
|
17
|
+
* Получает мета-информацию о ключе в хранилище KV (без данных).
|
|
18
|
+
*
|
|
19
|
+
* @param {string} key - Ключ, для которого необходимо получить мета-информацию.
|
|
20
|
+
* @returns {Promise<NatsKvEntryMeta | null>} Объект метаданных (NatsKvEntryMeta), если данные найдены, или `null`, если данные отсутствуют.
|
|
21
|
+
*/
|
|
22
|
+
getMeta(key: string): Promise<NatsKvEntryMeta | null>;
|
|
13
23
|
getAll<Decode extends DecodeFunc>(decode: Decode, filter?: string | string[]): Promise<ReturnType<Decode>[]>;
|
|
14
24
|
status(): Promise<KvStatus>;
|
|
15
25
|
put(key: string, data: Payload, opts?: Partial<KvPutOptions>): Promise<number>;
|
|
@@ -20,4 +30,5 @@ export declare class KvStorage {
|
|
|
20
30
|
* для безопасного взаимодействия.
|
|
21
31
|
*/
|
|
22
32
|
getRawStorage(): KV;
|
|
33
|
+
private createMeta;
|
|
23
34
|
}
|
package/dist/kv-storage.js
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.KvStorage = void 0;
|
|
4
|
+
const nats_1 = require("nats");
|
|
4
5
|
class KvStorage {
|
|
5
6
|
storage;
|
|
6
7
|
logger;
|
|
7
|
-
|
|
8
|
+
bucketName;
|
|
9
|
+
connection;
|
|
10
|
+
constructor(storage, logger, bucketName, connection) {
|
|
8
11
|
this.storage = storage;
|
|
9
12
|
this.logger = logger;
|
|
13
|
+
this.bucketName = bucketName;
|
|
14
|
+
this.connection = connection;
|
|
10
15
|
}
|
|
11
16
|
async getKeys(filter) {
|
|
12
17
|
const keysIterator = await this.storage.keys(filter);
|
|
@@ -32,12 +37,7 @@ class KvStorage {
|
|
|
32
37
|
}
|
|
33
38
|
result.push({
|
|
34
39
|
data: decode(entry.value),
|
|
35
|
-
meta:
|
|
36
|
-
created: entry.created,
|
|
37
|
-
length: entry.length,
|
|
38
|
-
operation: entry.operation,
|
|
39
|
-
revision: entry.revision,
|
|
40
|
-
},
|
|
40
|
+
meta: this.createMeta(entry),
|
|
41
41
|
});
|
|
42
42
|
}
|
|
43
43
|
this.logger.trace('Getting all entries from KV: KV entries received', {
|
|
@@ -46,13 +46,47 @@ class KvStorage {
|
|
|
46
46
|
return result;
|
|
47
47
|
}
|
|
48
48
|
async get(key, decode) {
|
|
49
|
-
const entry = await this.getWithMeta(key);
|
|
49
|
+
const entry = await this.getWithMeta(key, decode);
|
|
50
|
+
return entry?.data ?? null;
|
|
51
|
+
}
|
|
52
|
+
async getWithMeta(key, decode) {
|
|
53
|
+
const entry = await this.storage.get(key);
|
|
50
54
|
if (!entry)
|
|
51
55
|
return null;
|
|
52
|
-
return
|
|
56
|
+
return {
|
|
57
|
+
data: decode(entry.value),
|
|
58
|
+
meta: this.createMeta(entry),
|
|
59
|
+
};
|
|
53
60
|
}
|
|
54
|
-
|
|
55
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Получает мета-информацию о ключе в хранилище KV (без данных).
|
|
63
|
+
*
|
|
64
|
+
* @param {string} key - Ключ, для которого необходимо получить мета-информацию.
|
|
65
|
+
* @returns {Promise<NatsKvEntryMeta | null>} Объект метаданных (NatsKvEntryMeta), если данные найдены, или `null`, если данные отсутствуют.
|
|
66
|
+
*/
|
|
67
|
+
async getMeta(key) {
|
|
68
|
+
// HACK: данный костыль с JetStream необходим из-за отсутствия в библиотеке функции получения меты без данных
|
|
69
|
+
const streamName = `KV_${this.bucketName}`;
|
|
70
|
+
const subject = `$KV.${this.bucketName}.${key}`;
|
|
71
|
+
const consumer = await this.connection
|
|
72
|
+
.jetstream()
|
|
73
|
+
.consumers.get(streamName, {
|
|
74
|
+
headers_only: true,
|
|
75
|
+
filterSubjects: subject,
|
|
76
|
+
deliver_policy: nats_1.DeliverPolicy.LastPerSubject,
|
|
77
|
+
});
|
|
78
|
+
const msgs = await consumer.fetch({ max_messages: 1, expires: 1000 });
|
|
79
|
+
for await (const msg of msgs) {
|
|
80
|
+
msg.ack();
|
|
81
|
+
return {
|
|
82
|
+
created: new Date((0, nats_1.millis)(msg.info.timestampNanos)),
|
|
83
|
+
length: +(msg.headers?.get('Nats-Msg-Size') || '0'),
|
|
84
|
+
operation: msg.headers?.get('KV-Operation') ||
|
|
85
|
+
'PUT',
|
|
86
|
+
revision: msg.info.streamSequence,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
56
90
|
}
|
|
57
91
|
async getAll(decode, filter) {
|
|
58
92
|
const entries = await this.getAllWithMeta(decode, filter);
|
|
@@ -75,6 +109,14 @@ class KvStorage {
|
|
|
75
109
|
getRawStorage() {
|
|
76
110
|
return this.storage;
|
|
77
111
|
}
|
|
112
|
+
createMeta(entry) {
|
|
113
|
+
return {
|
|
114
|
+
created: entry.created,
|
|
115
|
+
length: entry.length,
|
|
116
|
+
operation: entry.operation,
|
|
117
|
+
revision: entry.revision,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
78
120
|
}
|
|
79
121
|
exports.KvStorage = KvStorage;
|
|
80
122
|
//# sourceMappingURL=kv-storage.js.map
|
package/dist/kv-storage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kv-storage.js","sourceRoot":"","sources":["../src/kv-storage.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"kv-storage.js","sourceRoot":"","sources":["../src/kv-storage.ts"],"names":[],"mappings":"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"}
|
package/dist/nats-kv.service.js
CHANGED
|
@@ -41,7 +41,7 @@ let NatsKvService = class NatsKvService {
|
|
|
41
41
|
connectionName: this.nats.info,
|
|
42
42
|
bucketName,
|
|
43
43
|
});
|
|
44
|
-
return new kv_storage_1.KvStorage(kv, this.logger);
|
|
44
|
+
return new kv_storage_1.KvStorage(kv, this.logger, bucketName, this.nats);
|
|
45
45
|
}
|
|
46
46
|
catch (error) {
|
|
47
47
|
this.logger.error('Failed to get or create KV store', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nats-kv.service.js","sourceRoot":"","sources":["../src/nats-kv.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAuE;AACvE,yCAA+C;AAC/C,qCAA6D;AAE7D,mDAA4E;AAI5E,6CAAyC;AAGlC,IAAM,aAAa,GAAnB,MAAM,aAAa;IAGL;IAEA;IAJnB,YAEmB,MAAe,EAEf,IAAoB;QAFpB,WAAM,GAAN,MAAM,CAAS;QAEf,SAAI,GAAJ,IAAI,CAAgB;IACpC,CAAC;IAEJ;;OAEG;IACI,KAAK,CAAC,MAAM,CAAC,EAClB,UAAU,EACV,MAAM,EACN,GAAG,IAAI,EAIR;QACC,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAElD,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI;iBACvB,SAAS,CAAC,SAAS,CAAC;iBACpB,KAAK,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YAE9B,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;gBAC1C,MAAM,IAAI,0BAAiB,CAAC,WAAW,UAAU,YAAY,CAAC,CAAC;YACjE,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE;gBACxC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI;gBAC9B,UAAU;aACX,CAAC,CAAC;YAEH,OAAO,IAAI,sBAAS,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"nats-kv.service.js","sourceRoot":"","sources":["../src/nats-kv.service.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rsdk/nats.kv",
|
|
3
|
-
"version": "5.4.0-next.
|
|
3
|
+
"version": "5.4.0-next.6",
|
|
4
4
|
"description": "Nats NestJS key-Value storage",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"license": "Apache License 2.0",
|
|
@@ -14,10 +14,10 @@
|
|
|
14
14
|
"@nestjs-plugins/nestjs-nats-jetstream-transport": "^2.2.6",
|
|
15
15
|
"lodash": "^4.17.21",
|
|
16
16
|
"nats": "^2.28.0",
|
|
17
|
-
"typescript": "
|
|
17
|
+
"typescript": "5.5.4"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
|
-
"@grpc/grpc-js": "^1.10.
|
|
20
|
+
"@grpc/grpc-js": "^1.10.11",
|
|
21
21
|
"@nestjs/common": "^10.0.0",
|
|
22
22
|
"@nestjs/config": "^3.2.3",
|
|
23
23
|
"@nestjs/core": "^10.0.0",
|
|
@@ -38,5 +38,5 @@
|
|
|
38
38
|
"rxjs": "^7.8.1"
|
|
39
39
|
},
|
|
40
40
|
"nx": {},
|
|
41
|
-
"gitHead": "
|
|
41
|
+
"gitHead": "acc1405be758b5ba4d2e8eda8d34b3c4f60a813f"
|
|
42
42
|
}
|
package/src/kv-storage.ts
CHANGED
|
@@ -5,16 +5,21 @@ import type {
|
|
|
5
5
|
KvEntry,
|
|
6
6
|
KvPutOptions,
|
|
7
7
|
KvStatus,
|
|
8
|
+
NatsConnection,
|
|
8
9
|
Payload,
|
|
9
10
|
} from 'nats';
|
|
11
|
+
import { DeliverPolicy, millis } from 'nats';
|
|
10
12
|
|
|
11
13
|
import type { NatsKvEntry } from './interfaces/nats-kv-entry.interface';
|
|
14
|
+
import type { NatsKvEntryMeta } from './interfaces/nats-kv-entry-meta.interface';
|
|
12
15
|
import type { DecodeFunc } from './types/decode-func.type';
|
|
13
16
|
|
|
14
17
|
export class KvStorage {
|
|
15
18
|
constructor(
|
|
16
19
|
private readonly storage: KV,
|
|
17
20
|
private readonly logger: ILogger,
|
|
21
|
+
private readonly bucketName: string,
|
|
22
|
+
private readonly connection: NatsConnection,
|
|
18
23
|
) {}
|
|
19
24
|
|
|
20
25
|
public async getKeys(filter?: string | string[]): Promise<string[]> {
|
|
@@ -51,12 +56,7 @@ export class KvStorage {
|
|
|
51
56
|
|
|
52
57
|
result.push({
|
|
53
58
|
data: decode(entry.value),
|
|
54
|
-
meta:
|
|
55
|
-
created: entry.created,
|
|
56
|
-
length: entry.length,
|
|
57
|
-
operation: entry.operation,
|
|
58
|
-
revision: entry.revision,
|
|
59
|
-
},
|
|
59
|
+
meta: this.createMeta(entry),
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -71,15 +71,60 @@ export class KvStorage {
|
|
|
71
71
|
key: string,
|
|
72
72
|
decode: Decode,
|
|
73
73
|
): Promise<ReturnType<Decode> | null> {
|
|
74
|
-
const entry = await this.getWithMeta(key);
|
|
74
|
+
const entry = await this.getWithMeta(key, decode);
|
|
75
|
+
|
|
76
|
+
return entry?.data ?? null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public async getWithMeta<Decode extends DecodeFunc>(
|
|
80
|
+
key: string,
|
|
81
|
+
decode: Decode,
|
|
82
|
+
): Promise<NatsKvEntry<Decode> | null> {
|
|
83
|
+
const entry = await this.storage.get(key);
|
|
75
84
|
|
|
76
85
|
if (!entry) return null;
|
|
77
86
|
|
|
78
|
-
return
|
|
87
|
+
return {
|
|
88
|
+
data: decode(entry.value),
|
|
89
|
+
meta: this.createMeta(entry),
|
|
90
|
+
};
|
|
79
91
|
}
|
|
80
92
|
|
|
81
|
-
|
|
82
|
-
|
|
93
|
+
/**
|
|
94
|
+
* Получает мета-информацию о ключе в хранилище KV (без данных).
|
|
95
|
+
*
|
|
96
|
+
* @param {string} key - Ключ, для которого необходимо получить мета-информацию.
|
|
97
|
+
* @returns {Promise<NatsKvEntryMeta | null>} Объект метаданных (NatsKvEntryMeta), если данные найдены, или `null`, если данные отсутствуют.
|
|
98
|
+
*/
|
|
99
|
+
public async getMeta(key: string): Promise<NatsKvEntryMeta | null> {
|
|
100
|
+
// HACK: данный костыль с JetStream необходим из-за отсутствия в библиотеке функции получения меты без данных
|
|
101
|
+
const streamName = `KV_${this.bucketName}`;
|
|
102
|
+
const subject = `$KV.${this.bucketName}.${key}`;
|
|
103
|
+
|
|
104
|
+
const consumer = await this.connection
|
|
105
|
+
.jetstream()
|
|
106
|
+
.consumers.get(streamName, {
|
|
107
|
+
headers_only: true,
|
|
108
|
+
filterSubjects: subject,
|
|
109
|
+
deliver_policy: DeliverPolicy.LastPerSubject,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const msgs = await consumer.fetch({ max_messages: 1, expires: 1000 });
|
|
113
|
+
|
|
114
|
+
for await (const msg of msgs) {
|
|
115
|
+
msg.ack();
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
created: new Date(millis(msg.info.timestampNanos)),
|
|
119
|
+
length: +(msg.headers?.get('Nats-Msg-Size') || '0'),
|
|
120
|
+
operation:
|
|
121
|
+
(msg.headers?.get('KV-Operation') as 'PUT' | 'DEL' | 'PURGE') ||
|
|
122
|
+
'PUT',
|
|
123
|
+
revision: msg.info.streamSequence,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return null;
|
|
83
128
|
}
|
|
84
129
|
|
|
85
130
|
public async getAll<Decode extends DecodeFunc>(
|
|
@@ -118,4 +163,13 @@ export class KvStorage {
|
|
|
118
163
|
public getRawStorage(): KV {
|
|
119
164
|
return this.storage;
|
|
120
165
|
}
|
|
166
|
+
|
|
167
|
+
private createMeta(entry: KvEntry): NatsKvEntryMeta {
|
|
168
|
+
return {
|
|
169
|
+
created: entry.created,
|
|
170
|
+
length: entry.length,
|
|
171
|
+
operation: entry.operation,
|
|
172
|
+
revision: entry.revision,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
121
175
|
}
|
package/src/nats-kv.service.ts
CHANGED