relayx-js 1.0.18 → 1.1.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.
@@ -0,0 +1,196 @@
1
+ import { Kvm } from "@nats-io/kv";
2
+ import { ErrorLogging, Logging } from "./utils.js";
3
+
4
+ export class KVStore{
5
+
6
+ #kvManager = null
7
+ #kvStore = null
8
+
9
+ #namespace = null;
10
+
11
+ #logger = null;
12
+ #errorLogger = null;
13
+
14
+ constructor(data){
15
+ this.#namespace = data.namespace;
16
+
17
+ this.#kvManager = new Kvm(data.jetstream)
18
+
19
+ this.#logger = new Logging(data.debug)
20
+
21
+ this.#errorLogger = new ErrorLogging()
22
+ }
23
+
24
+ async init(){
25
+ this.#validateInput()
26
+
27
+ this.#kvStore = await this.#kvManager.open(this.#namespace)
28
+
29
+ return this.#kvStore != null
30
+ }
31
+
32
+ async get(key){
33
+ this.#validateKey(key)
34
+
35
+ try{
36
+ const val = await this.#kvStore.get(key);
37
+
38
+ this.#logger.log("Value for", key)
39
+
40
+ var json = null;
41
+
42
+ json = JSON.parse(val.string())
43
+
44
+ return json
45
+ }catch(err){
46
+ this.#errorLogger.logError({
47
+ err: err,
48
+ op: "kv_read"
49
+ })
50
+
51
+ return null
52
+ }
53
+ }
54
+
55
+ async put(key, value){
56
+ this.#validateKey(key)
57
+ this.#validateValue(value)
58
+
59
+ this.#logger.log(`Creating KV pair for ${key}`)
60
+
61
+ try{
62
+ await this.#kvStore.create(key, JSON.stringify(value))
63
+ }catch(err){
64
+ // The assumption here is that the key might already exist
65
+ try{
66
+ await this.#kvStore.put(key, JSON.stringify(value))
67
+ }catch(err2){
68
+ // The key creation failed because we don't have permission
69
+ this.#errorLogger.logError({
70
+ err: err2,
71
+ op: "kv_write"
72
+ })
73
+ }
74
+ }
75
+ }
76
+
77
+ async delete(key){
78
+ this.#validateKey(key)
79
+
80
+ try{
81
+ await this.#kvStore.purge(key);
82
+ }catch(err){
83
+ // The key delete failed because we don't have permission
84
+ this.#errorLogger.logError({
85
+ err: err,
86
+ op: "kv_delete"
87
+ })
88
+ }
89
+
90
+ }
91
+
92
+ async keys(){
93
+ var keys = [];
94
+
95
+ try{
96
+ var qKeys = await this.#kvStore.keys();
97
+
98
+ for await (const key of qKeys) {
99
+ this.#logger.log("Key: ", key);
100
+ keys.push(key);
101
+ }
102
+ }catch(err){
103
+ this.#errorLogger.logError({
104
+ err: err,
105
+ op: "kv_read"
106
+ })
107
+ }
108
+
109
+ return keys;
110
+
111
+ }
112
+
113
+ // Utility functions
114
+ #validateInput(){
115
+ if(this.#namespace === null || this.#namespace === undefined || this.#namespace == ""){
116
+ throw new Error("$namespace cannot be null / undefined / empty")
117
+ }
118
+ }
119
+
120
+ #validateKey(key){
121
+ if(key == null || key == undefined){
122
+ throw new Error("$key cannot be null / undefined")
123
+ }
124
+
125
+ if(typeof key != "string"){
126
+ throw new Error("$key cannot be a string")
127
+ }
128
+
129
+ if(key == ""){
130
+ throw new Error("$key cannot be empty")
131
+ }
132
+
133
+ // Validate key characters: only a-z, A-Z, 0-9, _, -, ., = and / are allowed
134
+ const validKeyPattern = /^[a-zA-Z0-9_\-\.=\/]+$/;
135
+ if(!validKeyPattern.test(key)){
136
+ throw new Error("$key can only contain alphanumeric characters and the following: _ - . = /")
137
+ }
138
+ }
139
+
140
+ #validateValue(value){
141
+ var valueValid = (
142
+ value === null ||
143
+ typeof value == "string" ||
144
+ typeof value == "number" ||
145
+ typeof value == "boolean" ||
146
+ Array.isArray(value) ||
147
+ this.#isJSON(value)
148
+ );
149
+
150
+ if(!valueValid){
151
+ throw new Error(`$value MUST be null, string, number, boolean, array or json! $value is "${typeof value}"`)
152
+ }
153
+ }
154
+
155
+ #isJSON(data){
156
+ try{
157
+ JSON.stringify(data?.toString())
158
+ return true;
159
+ }catch(err){
160
+ return false
161
+ }
162
+ }
163
+
164
+ // Test helper methods - expose private methods/state for testing
165
+ // Only available when process.env.NODE_ENV == "test"
166
+ testGetNamespace(){
167
+ if(process.env.NODE_ENV !== "test") return undefined;
168
+ return this.#namespace;
169
+ }
170
+
171
+ testIsKvStoreInitialized(){
172
+ if(process.env.NODE_ENV !== "test") return undefined;
173
+ return this.#kvStore != null;
174
+ }
175
+
176
+ testValidateKey(){
177
+ if(process.env.NODE_ENV !== "test") return undefined;
178
+ return (key) => this.#validateKey(key);
179
+ }
180
+
181
+ testValidateValue(){
182
+ if(process.env.NODE_ENV !== "test") return undefined;
183
+ return (value) => this.#validateValue(value);
184
+ }
185
+
186
+ testValidateInput(){
187
+ if(process.env.NODE_ENV !== "test") return undefined;
188
+ return () => this.#validateInput();
189
+ }
190
+
191
+ testIsJSON(){
192
+ if(process.env.NODE_ENV !== "test") return undefined;
193
+ return (data) => this.#isJSON(data);
194
+ }
195
+
196
+ }
@@ -0,0 +1,26 @@
1
+
2
+ export default class Message {
3
+ id = null
4
+ message = null
5
+ topic = null
6
+
7
+ msg = null
8
+
9
+ constructor(message){
10
+ this.id = message.id;
11
+
12
+ this.message = message.message;
13
+
14
+ this.topic = message.topic;
15
+
16
+ this.msg = message.msg;
17
+ }
18
+
19
+ ack(){
20
+ this.msg?.ack()
21
+ }
22
+
23
+ nack(millis){
24
+ this.msg?.nak(millis)
25
+ }
26
+ }