montycat 1.0.2
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/README.md +20 -0
- package/dist/classes/generic.d.ts +162 -0
- package/dist/classes/generic.js +274 -0
- package/dist/core/engine.d.ts +113 -0
- package/dist/core/engine.js +284 -0
- package/dist/core/inmemory.d.ts +98 -0
- package/dist/core/inmemory.js +150 -0
- package/dist/core/persistent.d.ts +98 -0
- package/dist/core/persistent.js +136 -0
- package/dist/core/schema.d.ts +93 -0
- package/dist/core/schema.js +113 -0
- package/dist/core/store.d.ts +13 -0
- package/dist/core/store.js +13 -0
- package/dist/functions/storeGenericFunctions.d.ts +54 -0
- package/dist/functions/storeGenericFunctions.js +160 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/package.json +36 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { runQuery, convertToBinaryQuery, convertCustomKey } from '../functions/storeGenericFunctions.js';
|
|
2
|
+
import GenericKV from '../classes/generic.js';
|
|
3
|
+
/**
|
|
4
|
+
* Persistent class that extends GenericKV for persistent keyspace operations.
|
|
5
|
+
* It provides methods for inserting, updating, and retrieving data in a persistent store.
|
|
6
|
+
*/
|
|
7
|
+
class Persistent extends GenericKV {
|
|
8
|
+
static persistent = true;
|
|
9
|
+
static distributed = false;
|
|
10
|
+
static cache = null;
|
|
11
|
+
static compression = false;
|
|
12
|
+
keyspace;
|
|
13
|
+
constructor(options) {
|
|
14
|
+
super(options);
|
|
15
|
+
this.keyspace = options.keyspace;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Inserts a value into the persistent store.
|
|
19
|
+
* @param value - The value to insert.
|
|
20
|
+
* @return A promise that resolves with the result of the insertion.
|
|
21
|
+
*/
|
|
22
|
+
static async insertValue({ value = {} } = {}) {
|
|
23
|
+
this.command = "insert_value";
|
|
24
|
+
const query = convertToBinaryQuery(this, { value });
|
|
25
|
+
return runQuery(this, query);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Inserts a key-value pair into the persistent store.
|
|
29
|
+
* @param key - The key for the value.
|
|
30
|
+
* @param value - The value to insert.
|
|
31
|
+
* @return A promise that resolves with the result of the insertion.
|
|
32
|
+
*/
|
|
33
|
+
static async insertCustomKey({ customKey }) {
|
|
34
|
+
if (!customKey) {
|
|
35
|
+
throw new Error("No key provided");
|
|
36
|
+
}
|
|
37
|
+
this.command = "insert_custom_key";
|
|
38
|
+
const query = convertToBinaryQuery(this, { key: convertCustomKey(customKey) });
|
|
39
|
+
return runQuery(this, query);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Inserts a custom key-value pair into the persistent store.
|
|
43
|
+
* @param customKey - The custom key for the value.
|
|
44
|
+
* @param value - The value to insert.
|
|
45
|
+
* @return A promise that resolves with the result of the insertion.
|
|
46
|
+
*/
|
|
47
|
+
static async insertCustomKeyValue({ customKey, value = {} }) {
|
|
48
|
+
if (!customKey) {
|
|
49
|
+
throw new Error("No key provided");
|
|
50
|
+
}
|
|
51
|
+
this.command = "insert_custom_key_value";
|
|
52
|
+
const query = convertToBinaryQuery(this, { key: convertCustomKey(customKey), value });
|
|
53
|
+
return runQuery(this, query);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Updates a value in the persistent store.
|
|
57
|
+
* @param key - The key for the value to update.
|
|
58
|
+
* @param customKey - The custom key for the value to update.
|
|
59
|
+
* @param value - The new value to set.
|
|
60
|
+
* @return A promise that resolves with the result of the update.
|
|
61
|
+
*/
|
|
62
|
+
static async updateValue({ key = "", customKey = null, value = {} } = {}) {
|
|
63
|
+
const effectiveKey = customKey ? convertCustomKey(customKey) : key;
|
|
64
|
+
if (!effectiveKey) {
|
|
65
|
+
throw new Error("No key provided");
|
|
66
|
+
}
|
|
67
|
+
this.command = "update_value";
|
|
68
|
+
const query = convertToBinaryQuery(this, { key: effectiveKey, value });
|
|
69
|
+
return runQuery(this, query);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Retrieves a value from the persistent store.
|
|
73
|
+
* @param key - The key for the value to retrieve.
|
|
74
|
+
* @param customKey - The custom key for the value to retrieve.
|
|
75
|
+
* @return A promise that resolves with the retrieved value.
|
|
76
|
+
*/
|
|
77
|
+
static async insertBulk({ bulk = [] } = {}) {
|
|
78
|
+
if (!bulk || bulk.length === 0) {
|
|
79
|
+
throw new Error("No values provided");
|
|
80
|
+
}
|
|
81
|
+
this.command = "insert_bulk";
|
|
82
|
+
const query = convertToBinaryQuery(this, { bulkValues: bulk });
|
|
83
|
+
return runQuery(this, query);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Retrieves a value from the persistent store.
|
|
87
|
+
* @param key - The key for the value to retrieve.
|
|
88
|
+
* @param customKey - The custom key for the value to retrieve.
|
|
89
|
+
* @return A promise that resolves with the retrieved value.
|
|
90
|
+
*/
|
|
91
|
+
static async getKeys({ limitOutput = { start: 0, stop: 0 } } = {}) {
|
|
92
|
+
this.command = "get_keys";
|
|
93
|
+
const query = convertToBinaryQuery(this, { limitOutput });
|
|
94
|
+
return runQuery(this, query);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Updates the cache and compression settings for the persistent store.
|
|
98
|
+
* @param cache - The cache settings to apply.
|
|
99
|
+
* @param compression - Whether to enable compression.
|
|
100
|
+
* @return A promise that resolves with the result of the update.
|
|
101
|
+
*/
|
|
102
|
+
static async updateCacheAndCompression() {
|
|
103
|
+
const query = {
|
|
104
|
+
raw: [
|
|
105
|
+
"update-cache-compression", "store", this.store, "keyspace", this.keyspace, "persistent", "y",
|
|
106
|
+
"cache", this.cache ? this.cache : null, "compression", this.compression ? "y" : "n"
|
|
107
|
+
],
|
|
108
|
+
credentials: [this.username, this.password],
|
|
109
|
+
};
|
|
110
|
+
return await runQuery(this, JSON.stringify(query));
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Creates a keyspace in the persistent store.
|
|
114
|
+
* @return A promise that resolves with the result of the keyspace creation.
|
|
115
|
+
*/
|
|
116
|
+
static async createKeyspace() {
|
|
117
|
+
const query = {
|
|
118
|
+
raw: [
|
|
119
|
+
"create-keyspace", "store", this.store, "keyspace", this.keyspace, "persistent", this.persistent ? "y" : "n",
|
|
120
|
+
"cache", this.cache ? this.cache : null, "compression", this.compression ? "y" : "n"
|
|
121
|
+
],
|
|
122
|
+
credentials: [this.username, this.password],
|
|
123
|
+
};
|
|
124
|
+
return await runQuery(this, JSON.stringify(query));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
;
|
|
128
|
+
/**
|
|
129
|
+
* PersistentDistributed class that extends Persistent for distributed persistent keyspace operations.
|
|
130
|
+
* It provides methods for distributed operations in a persistent store.
|
|
131
|
+
*/
|
|
132
|
+
class PersistentDistributed extends Persistent {
|
|
133
|
+
static distributed = true;
|
|
134
|
+
}
|
|
135
|
+
;
|
|
136
|
+
export { Persistent, PersistentDistributed };
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import GenericKV from '../classes/generic.js';
|
|
2
|
+
/** * Interface for schema properties
|
|
3
|
+
* @interface
|
|
4
|
+
*/
|
|
5
|
+
/** * Interface for pointer configuration
|
|
6
|
+
* @interface
|
|
7
|
+
*/
|
|
8
|
+
interface PointerConfig {
|
|
9
|
+
keyspace: {
|
|
10
|
+
keyspace: string;
|
|
11
|
+
} | GenericKV;
|
|
12
|
+
key?: string | number;
|
|
13
|
+
customKey?: string;
|
|
14
|
+
}
|
|
15
|
+
/** * Interface for timestamp configuration
|
|
16
|
+
* @interface
|
|
17
|
+
*/
|
|
18
|
+
interface TimestampConfig {
|
|
19
|
+
timestamp: string;
|
|
20
|
+
}
|
|
21
|
+
/** * Interface for timestamp range configuration
|
|
22
|
+
* @interface
|
|
23
|
+
*/
|
|
24
|
+
interface TimestampRangeConfig {
|
|
25
|
+
startTimestamp: string;
|
|
26
|
+
endTimestamp: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Schema class
|
|
30
|
+
* @class
|
|
31
|
+
* @param properties - The properties of the schema
|
|
32
|
+
* @property {Record<string, string>} metadata - The metadata object containing field types
|
|
33
|
+
* @returns The schema object
|
|
34
|
+
* @example
|
|
35
|
+
* const schema = new Schema({ username: 'user', location: 'city' });
|
|
36
|
+
*
|
|
37
|
+
* Metadata is used to define the types of properties to enforce in the schema.
|
|
38
|
+
* Types can be 'String', 'Number', 'Pointer', 'Timestamp', "Object", "Array".
|
|
39
|
+
*
|
|
40
|
+
* @throws {Error} If a required property is missing or not defined
|
|
41
|
+
* @throws {Error} If a property is not defined in the schema
|
|
42
|
+
* @throws {Error} If a pointer is not valid (missing keyspace or key)
|
|
43
|
+
*/
|
|
44
|
+
declare class Schema {
|
|
45
|
+
[key: string]: any;
|
|
46
|
+
static metadata: Record<string, string> | null;
|
|
47
|
+
constructor(properties: {
|
|
48
|
+
[key: string]: any;
|
|
49
|
+
});
|
|
50
|
+
validate(): void;
|
|
51
|
+
get className(): string;
|
|
52
|
+
serialize(): Schema;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Pointer class
|
|
56
|
+
* @class
|
|
57
|
+
* @param config - The pointer configuration
|
|
58
|
+
* @returns The pointer object
|
|
59
|
+
*/
|
|
60
|
+
declare class Pointer {
|
|
61
|
+
private key?;
|
|
62
|
+
private keyspace;
|
|
63
|
+
constructor({ keyspace, key, customKey }: PointerConfig);
|
|
64
|
+
setupPointer(): [string, string];
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Timestamp class
|
|
68
|
+
* @class
|
|
69
|
+
* @param timestamp - The timestamp object
|
|
70
|
+
* @returns The timestamp object
|
|
71
|
+
* @example
|
|
72
|
+
* const timestamp = new Timestamp({ timestamp: Date.now() });
|
|
73
|
+
*/
|
|
74
|
+
declare class Timestamp {
|
|
75
|
+
timestamp: string;
|
|
76
|
+
constructor({ timestamp }: TimestampConfig);
|
|
77
|
+
static after: {
|
|
78
|
+
new (after: number | string): {
|
|
79
|
+
after_timestamp: number | string;
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
static before: {
|
|
83
|
+
new (before: number | string): {
|
|
84
|
+
before_timestamp: number | string;
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
static range: {
|
|
88
|
+
new ({ startTimestamp, endTimestamp }: TimestampRangeConfig): {
|
|
89
|
+
range_timestamp: [number | string, number | string];
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
export { Schema, Pointer, Timestamp };
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { convertCustomKey } from '../functions/storeGenericFunctions.js';
|
|
2
|
+
/**
|
|
3
|
+
* Schema class
|
|
4
|
+
* @class
|
|
5
|
+
* @param properties - The properties of the schema
|
|
6
|
+
* @property {Record<string, string>} metadata - The metadata object containing field types
|
|
7
|
+
* @returns The schema object
|
|
8
|
+
* @example
|
|
9
|
+
* const schema = new Schema({ username: 'user', location: 'city' });
|
|
10
|
+
*
|
|
11
|
+
* Metadata is used to define the types of properties to enforce in the schema.
|
|
12
|
+
* Types can be 'String', 'Number', 'Pointer', 'Timestamp', "Object", "Array".
|
|
13
|
+
*
|
|
14
|
+
* @throws {Error} If a required property is missing or not defined
|
|
15
|
+
* @throws {Error} If a property is not defined in the schema
|
|
16
|
+
* @throws {Error} If a pointer is not valid (missing keyspace or key)
|
|
17
|
+
*/
|
|
18
|
+
class Schema {
|
|
19
|
+
static metadata = null;
|
|
20
|
+
// how to check metadata type?
|
|
21
|
+
constructor(properties) {
|
|
22
|
+
Object.assign(this, properties);
|
|
23
|
+
}
|
|
24
|
+
validate() {
|
|
25
|
+
Object.keys(this).forEach((key) => {
|
|
26
|
+
if (this[key] === undefined) {
|
|
27
|
+
throw new Error(`Property ${key} is missing`);
|
|
28
|
+
}
|
|
29
|
+
if (!this.hasOwnProperty(key)) {
|
|
30
|
+
throw new Error(`Property ${key} is not defined`);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
get className() {
|
|
35
|
+
return this.constructor.name;
|
|
36
|
+
}
|
|
37
|
+
serialize() {
|
|
38
|
+
if (Object.values(this).some((value) => value instanceof Pointer)) {
|
|
39
|
+
this.pointers = {};
|
|
40
|
+
}
|
|
41
|
+
if (Object.values(this).some((value) => value instanceof Timestamp)) {
|
|
42
|
+
this.timestamps = {};
|
|
43
|
+
}
|
|
44
|
+
this.schema = this.className;
|
|
45
|
+
this.validate();
|
|
46
|
+
Object.keys(this).forEach((key) => {
|
|
47
|
+
if (this[key] instanceof Pointer) {
|
|
48
|
+
this.pointers[key] = this[key].setupPointer();
|
|
49
|
+
delete this[key];
|
|
50
|
+
}
|
|
51
|
+
if (this[key] instanceof Timestamp) {
|
|
52
|
+
this.timestamps[key] = this[key].timestamp;
|
|
53
|
+
delete this[key];
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
return { ...this };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Pointer class
|
|
61
|
+
* @class
|
|
62
|
+
* @param config - The pointer configuration
|
|
63
|
+
* @returns The pointer object
|
|
64
|
+
*/
|
|
65
|
+
class Pointer {
|
|
66
|
+
key;
|
|
67
|
+
keyspace;
|
|
68
|
+
constructor({ keyspace, key = '', customKey = '' }) {
|
|
69
|
+
this.keyspace = keyspace.keyspace;
|
|
70
|
+
this.key = key ? key.toString() : customKey ? convertCustomKey(customKey) : undefined;
|
|
71
|
+
}
|
|
72
|
+
setupPointer() {
|
|
73
|
+
if (this.keyspace && this.key) {
|
|
74
|
+
return [this.keyspace, this.key];
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
throw new Error('Pointer is not valid. Please provide a keyspace and a key.');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Timestamp class
|
|
83
|
+
* @class
|
|
84
|
+
* @param timestamp - The timestamp object
|
|
85
|
+
* @returns The timestamp object
|
|
86
|
+
* @example
|
|
87
|
+
* const timestamp = new Timestamp({ timestamp: Date.now() });
|
|
88
|
+
*/
|
|
89
|
+
class Timestamp {
|
|
90
|
+
timestamp;
|
|
91
|
+
constructor({ timestamp }) {
|
|
92
|
+
this.timestamp = timestamp;
|
|
93
|
+
}
|
|
94
|
+
static after = class After {
|
|
95
|
+
after_timestamp;
|
|
96
|
+
constructor(after) {
|
|
97
|
+
this.after_timestamp = after;
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
static before = class Before {
|
|
101
|
+
before_timestamp;
|
|
102
|
+
constructor(before) {
|
|
103
|
+
this.before_timestamp = before;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
static range = class Range {
|
|
107
|
+
range_timestamp;
|
|
108
|
+
constructor({ startTimestamp, endTimestamp }) {
|
|
109
|
+
this.range_timestamp = [startTimestamp, endTimestamp];
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
export { Schema, Pointer, Timestamp };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { InMemory, InMemoryDistributed } from './inmemory.js';
|
|
2
|
+
import { Persistent, PersistentDistributed } from './persistent.js';
|
|
3
|
+
/**
|
|
4
|
+
* Keyspace class that provides access to different keyspace implementations.
|
|
5
|
+
* It serves as a factory for creating instances of InMemory and Persistent keyspaces.
|
|
6
|
+
*/
|
|
7
|
+
declare class Keyspace {
|
|
8
|
+
static InMemory: typeof InMemory;
|
|
9
|
+
static Persistent: typeof Persistent;
|
|
10
|
+
static InMemoryDistributed: typeof InMemoryDistributed;
|
|
11
|
+
static PersistentDistributed: typeof PersistentDistributed;
|
|
12
|
+
}
|
|
13
|
+
export default Keyspace;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { InMemory, InMemoryDistributed } from './inmemory.js';
|
|
2
|
+
import { Persistent, PersistentDistributed } from './persistent.js';
|
|
3
|
+
/**
|
|
4
|
+
* Keyspace class that provides access to different keyspace implementations.
|
|
5
|
+
* It serves as a factory for creating instances of InMemory and Persistent keyspaces.
|
|
6
|
+
*/
|
|
7
|
+
class Keyspace {
|
|
8
|
+
static InMemory = InMemory;
|
|
9
|
+
static Persistent = Persistent;
|
|
10
|
+
static InMemoryDistributed = InMemoryDistributed;
|
|
11
|
+
static PersistentDistributed = PersistentDistributed;
|
|
12
|
+
}
|
|
13
|
+
export default Keyspace;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for handling custom keys and values in a generic store.
|
|
3
|
+
* These functions include converting custom keys, processing bulk keys and values,
|
|
4
|
+
* and converting values to a binary query format.
|
|
5
|
+
*/
|
|
6
|
+
declare function convertCustomKey(key: string): string;
|
|
7
|
+
/** * Converts an array of custom keys to their hashed string representations.
|
|
8
|
+
* @param keys - An array of keys, which can be strings or numbers.
|
|
9
|
+
* @returns An array of hashed string representations of the keys.
|
|
10
|
+
* */
|
|
11
|
+
declare function convertCustomKeys(keys: string[]): string[];
|
|
12
|
+
/**
|
|
13
|
+
* Converts an object of custom keys and values to their hashed string representations.
|
|
14
|
+
* @param keysValues - An object where keys can be strings or numbers, and values can be any type.
|
|
15
|
+
* @returns An object with hashed string keys and original values.
|
|
16
|
+
*/
|
|
17
|
+
declare function convertCustomKeysValues(keysValues: {
|
|
18
|
+
[key: string]: any;
|
|
19
|
+
}): {
|
|
20
|
+
[key: string]: any;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Processes bulk keys and values, converting any Timestamp or Pointer instances
|
|
24
|
+
* to their appropriate string representations and hashing the keys.
|
|
25
|
+
* @param bulkKeysValues - An object containing bulk keys and values.
|
|
26
|
+
* @returns An object with processed keys and values.
|
|
27
|
+
*/
|
|
28
|
+
declare function processBulkKeysValues(bulkKeysValues: {
|
|
29
|
+
[key: string]: any;
|
|
30
|
+
}): {
|
|
31
|
+
[key: string]: any;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Converts a class instance to a binary query string.
|
|
35
|
+
* @param cls - The class instance containing store properties.
|
|
36
|
+
* @param options - An object containing various options for the query.
|
|
37
|
+
* @returns A JSON string representing the binary query.
|
|
38
|
+
* */
|
|
39
|
+
declare function convertToBinaryQuery(cls: any, options?: {
|
|
40
|
+
[key: string]: any;
|
|
41
|
+
}): string;
|
|
42
|
+
/**
|
|
43
|
+
* Runs a query against the store using the provided class instance.
|
|
44
|
+
* @param cls - The class instance containing store properties.
|
|
45
|
+
* @param query - The query string to execute.
|
|
46
|
+
* @returns A promise that resolves with the result of the query.
|
|
47
|
+
*/
|
|
48
|
+
declare function runQuery(cls: any, query: string): Promise<unknown>;
|
|
49
|
+
/**
|
|
50
|
+
* Displays the properties of a store class instance.
|
|
51
|
+
* @param cls - The class instance containing store properties.
|
|
52
|
+
*/
|
|
53
|
+
declare function showStoreProperties(cls: any): void;
|
|
54
|
+
export { convertCustomKey, convertCustomKeys, convertCustomKeysValues, convertToBinaryQuery, runQuery, showStoreProperties, processBulkKeysValues };
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import xxhash from 'xxhashjs';
|
|
2
|
+
import { sendData } from '../core/engine.js';
|
|
3
|
+
import { Timestamp, Pointer } from '../core/schema.js';
|
|
4
|
+
/**
|
|
5
|
+
* Utility functions for handling custom keys and values in a generic store.
|
|
6
|
+
* These functions include converting custom keys, processing bulk keys and values,
|
|
7
|
+
* and converting values to a binary query format.
|
|
8
|
+
*/
|
|
9
|
+
function convertCustomKey(key) {
|
|
10
|
+
return xxhash.h32().update(key.toString()).digest().toNumber().toString();
|
|
11
|
+
}
|
|
12
|
+
/** * Converts an array of custom keys to their hashed string representations.
|
|
13
|
+
* @param keys - An array of keys, which can be strings or numbers.
|
|
14
|
+
* @returns An array of hashed string representations of the keys.
|
|
15
|
+
* */
|
|
16
|
+
function convertCustomKeys(keys) {
|
|
17
|
+
return keys.map(convertCustomKey);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Converts an object of custom keys and values to their hashed string representations.
|
|
21
|
+
* @param keysValues - An object where keys can be strings or numbers, and values can be any type.
|
|
22
|
+
* @returns An object with hashed string keys and original values.
|
|
23
|
+
*/
|
|
24
|
+
function convertCustomKeysValues(keysValues) {
|
|
25
|
+
return Object.fromEntries(Object.entries(keysValues).map(([key, value]) => [convertCustomKey(key), value]));
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Processes bulk keys and values, converting any Timestamp or Pointer instances
|
|
29
|
+
* to their appropriate string representations and hashing the keys.
|
|
30
|
+
* @param bulkKeysValues - An object containing bulk keys and values.
|
|
31
|
+
* @returns An object with processed keys and values.
|
|
32
|
+
*/
|
|
33
|
+
function processBulkKeysValues(bulkKeysValues) {
|
|
34
|
+
const bulkKeysValuesProcessed = {};
|
|
35
|
+
Object.keys(bulkKeysValues).forEach((key) => {
|
|
36
|
+
const entry = bulkKeysValues[key];
|
|
37
|
+
if (entry instanceof Object) {
|
|
38
|
+
const inner = entry;
|
|
39
|
+
Object.keys(inner).forEach((prop) => {
|
|
40
|
+
const value = inner[prop];
|
|
41
|
+
if (value instanceof Timestamp) {
|
|
42
|
+
inner[prop] = value.timestamp;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
if (entry instanceof Pointer) {
|
|
46
|
+
bulkKeysValues[key] = entry.setupPointer();
|
|
47
|
+
}
|
|
48
|
+
const processedKey = !isNaN(Number(key)) ? key : convertCustomKey(key);
|
|
49
|
+
bulkKeysValuesProcessed[processedKey] = JSON.stringify(bulkKeysValues[key]);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
return bulkKeysValuesProcessed;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Converts a class instance to a binary query string.
|
|
56
|
+
* @param cls - The class instance containing store properties.
|
|
57
|
+
* @param options - An object containing various options for the query.
|
|
58
|
+
* @returns A JSON string representing the binary query.
|
|
59
|
+
* */
|
|
60
|
+
function convertToBinaryQuery(cls, options = {}) {
|
|
61
|
+
const { key = null, value = {}, expireSec = 0, bulkValues = [], bulkKeys = [], bulkKeysValues = {}, searchCriteria = {}, limitOutput = { start: 0, stop: 0 }, withPointers = false, schema = null, } = options;
|
|
62
|
+
const { processedValue, foundSchema } = processValue(value);
|
|
63
|
+
const { processedBulkValues, uniqueSchema } = processBulkValues(bulkValues);
|
|
64
|
+
const bulkKeysValuesProcessed = processBulkKeysValues(bulkKeysValues);
|
|
65
|
+
return JSON.stringify({
|
|
66
|
+
username: cls.username,
|
|
67
|
+
password: cls.password,
|
|
68
|
+
namespace: cls.namespace,
|
|
69
|
+
store: cls.store,
|
|
70
|
+
keyspace: cls.keyspace,
|
|
71
|
+
persistent: cls.persistent,
|
|
72
|
+
distributed: cls.distributed,
|
|
73
|
+
limit_output: limitOutput,
|
|
74
|
+
key,
|
|
75
|
+
value: JSON.stringify(processedValue),
|
|
76
|
+
command: cls.command,
|
|
77
|
+
expire: expireSec,
|
|
78
|
+
bulk_values: processedBulkValues.map(v => JSON.stringify(v)),
|
|
79
|
+
bulk_keys: bulkKeys,
|
|
80
|
+
bulk_keys_values: bulkKeysValuesProcessed,
|
|
81
|
+
search_criteria: JSON.stringify(searchCriteria),
|
|
82
|
+
with_pointers: withPointers,
|
|
83
|
+
schema: foundSchema ? foundSchema : uniqueSchema ? uniqueSchema : schema,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Processes a single value, converting any Timestamp or Pointer instances
|
|
88
|
+
* to their appropriate string representations.
|
|
89
|
+
* @param value - The value to process, which can be any type.
|
|
90
|
+
* @returns An object containing the processed value and the found schema, if any.
|
|
91
|
+
*/
|
|
92
|
+
function processValue(value) {
|
|
93
|
+
let foundSchema = null;
|
|
94
|
+
if (value) {
|
|
95
|
+
if (value instanceof Object) {
|
|
96
|
+
if (value.hasOwnProperty('schema')) {
|
|
97
|
+
foundSchema = value['schema'];
|
|
98
|
+
delete value['schema'];
|
|
99
|
+
}
|
|
100
|
+
for (const prop in value) {
|
|
101
|
+
if (value[prop] instanceof Timestamp) {
|
|
102
|
+
value[prop] = value[prop].timestamp; // Convert Timestamp to ISO string
|
|
103
|
+
}
|
|
104
|
+
if (value[prop] instanceof Pointer) {
|
|
105
|
+
value[prop] = value[prop].setupPointer(); // Serialize Pointer
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return { processedValue: value, foundSchema };
|
|
110
|
+
}
|
|
111
|
+
return { processedValue: value, foundSchema };
|
|
112
|
+
}
|
|
113
|
+
/** * Processes an array of bulk values, converting any Timestamp or Pointer instances
|
|
114
|
+
* to their appropriate string representations and ensuring all values have the same schema.
|
|
115
|
+
* @param bulkValues - An array of values to process.
|
|
116
|
+
* @returns An object containing the processed bulk values and the unique schema, if any.
|
|
117
|
+
*/
|
|
118
|
+
function processBulkValues(bulkValues) {
|
|
119
|
+
let arrayWithValues = [];
|
|
120
|
+
let uniqueSchemas = new Set();
|
|
121
|
+
if (bulkValues.length > 0) {
|
|
122
|
+
bulkValues.forEach((val, i) => {
|
|
123
|
+
const { processedValue, foundSchema } = processValue(val);
|
|
124
|
+
if (foundSchema) {
|
|
125
|
+
if (uniqueSchemas.size > 1) {
|
|
126
|
+
throw new Error("Bulk values must have the same schema");
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
uniqueSchemas.add(foundSchema);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
arrayWithValues.push(processedValue);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return { processedBulkValues: arrayWithValues, uniqueSchema: uniqueSchemas.size > 0 ? uniqueSchemas.values().next().value : null };
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Runs a query against the store using the provided class instance.
|
|
139
|
+
* @param cls - The class instance containing store properties.
|
|
140
|
+
* @param query - The query string to execute.
|
|
141
|
+
* @returns A promise that resolves with the result of the query.
|
|
142
|
+
*/
|
|
143
|
+
async function runQuery(cls, query) {
|
|
144
|
+
return sendData(cls.host, cls.port, query);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Displays the properties of a store class instance.
|
|
148
|
+
* @param cls - The class instance containing store properties.
|
|
149
|
+
*/
|
|
150
|
+
function showStoreProperties(cls) {
|
|
151
|
+
console.log(`Store Name: ${cls.store}\n` +
|
|
152
|
+
`Store Namespace: ${cls.namespace}\n` +
|
|
153
|
+
`Persistent: ${cls.persistent}\n` +
|
|
154
|
+
`Distributed: ${cls.distributed}\n` +
|
|
155
|
+
`Host: ${cls.host}\n` +
|
|
156
|
+
`Port: ${cls.port}\n` +
|
|
157
|
+
`Username: ${cls.username}\n` +
|
|
158
|
+
`Password: ${cls.password}\n`);
|
|
159
|
+
}
|
|
160
|
+
export { convertCustomKey, convertCustomKeys, convertCustomKeysValues, convertToBinaryQuery, runQuery, showStoreProperties, processBulkKeysValues };
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "montycat",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "A Node.js client for MontyCat, NoSQL store utilizing Data Mesh architecture.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
17
|
+
"build": "tsc",
|
|
18
|
+
"start": "node dist/index.js",
|
|
19
|
+
"dev": "tsc --watch"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [],
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/json-bigint": "^1.0.4",
|
|
24
|
+
"@types/node": "^24.1.0",
|
|
25
|
+
"@types/xxhashjs": "^0.2.4",
|
|
26
|
+
"typescript": "^5.9.2"
|
|
27
|
+
},
|
|
28
|
+
"author": "MontyGovernance",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"json-bigint": "^1.0.0",
|
|
32
|
+
"xxhash": "^0.3.0",
|
|
33
|
+
"xxhash-wasm": "^1.0.2",
|
|
34
|
+
"xxhashjs": "^0.2.2"
|
|
35
|
+
}
|
|
36
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ESNext",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "node",
|
|
6
|
+
"outDir": "./dist",
|
|
7
|
+
"declaration": true,
|
|
8
|
+
"declarationDir": "./dist",
|
|
9
|
+
"emitDeclarationOnly": false,
|
|
10
|
+
"rootDir": "./src",
|
|
11
|
+
"strict": true,
|
|
12
|
+
"esModuleInterop": true,
|
|
13
|
+
"skipLibCheck": true,
|
|
14
|
+
"forceConsistentCasingInFileNames": true,
|
|
15
|
+
"experimentalDecorators": true,
|
|
16
|
+
"emitDecoratorMetadata": true
|
|
17
|
+
},
|
|
18
|
+
"include": ["src/**/*"],
|
|
19
|
+
"exclude": ["node_modules", "dist"]
|
|
20
|
+
}
|