s3db.js 8.2.0 → 9.2.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/PLUGINS.md +507 -0
- package/README.md +14 -10
- package/dist/s3db-cli.js +54741 -0
- package/dist/s3db.cjs.js +2125 -5702
- package/dist/s3db.cjs.js.map +1 -0
- package/dist/s3db.es.js +2114 -5697
- package/dist/s3db.es.js.map +1 -0
- package/package.json +45 -29
- package/src/cli/index.js +426 -0
- package/src/client.class.js +8 -33
- package/src/concerns/advanced-metadata-encoding.js +440 -0
- package/src/concerns/calculator.js +36 -0
- package/src/concerns/metadata-encoding.js +244 -0
- package/src/concerns/optimized-encoding.js +130 -0
- package/src/plugins/backup.plugin.js +1018 -0
- package/src/plugins/cache/memory-cache.class.js +112 -3
- package/src/plugins/index.js +3 -0
- package/src/plugins/scheduler.plugin.js +834 -0
- package/src/plugins/state-machine.plugin.js +543 -0
- package/dist/s3db.cjs.min.js +0 -1
- package/dist/s3db.es.min.js +0 -1
- package/dist/s3db.iife.js +0 -15738
- package/dist/s3db.iife.min.js +0 -1
|
@@ -84,6 +84,7 @@
|
|
|
84
84
|
* - Tags are useful for cache invalidation and monitoring
|
|
85
85
|
* - Case sensitivity affects key matching and storage efficiency
|
|
86
86
|
*/
|
|
87
|
+
import zlib from 'node:zlib';
|
|
87
88
|
import { Cache } from "./cache.class.js"
|
|
88
89
|
|
|
89
90
|
export class MemoryCache extends Cache {
|
|
@@ -93,6 +94,18 @@ export class MemoryCache extends Cache {
|
|
|
93
94
|
this.meta = {};
|
|
94
95
|
this.maxSize = config.maxSize !== undefined ? config.maxSize : 1000;
|
|
95
96
|
this.ttl = config.ttl !== undefined ? config.ttl : 300000;
|
|
97
|
+
|
|
98
|
+
// Compression configuration
|
|
99
|
+
this.enableCompression = config.enableCompression !== undefined ? config.enableCompression : false;
|
|
100
|
+
this.compressionThreshold = config.compressionThreshold !== undefined ? config.compressionThreshold : 1024;
|
|
101
|
+
|
|
102
|
+
// Stats for compression
|
|
103
|
+
this.compressionStats = {
|
|
104
|
+
totalCompressed: 0,
|
|
105
|
+
totalOriginalSize: 0,
|
|
106
|
+
totalCompressedSize: 0,
|
|
107
|
+
compressionRatio: 0
|
|
108
|
+
};
|
|
96
109
|
}
|
|
97
110
|
|
|
98
111
|
async _set(key, data) {
|
|
@@ -106,13 +119,59 @@ export class MemoryCache extends Cache {
|
|
|
106
119
|
delete this.meta[oldestKey];
|
|
107
120
|
}
|
|
108
121
|
}
|
|
109
|
-
|
|
110
|
-
|
|
122
|
+
|
|
123
|
+
// Prepare data for storage
|
|
124
|
+
let finalData = data;
|
|
125
|
+
let compressed = false;
|
|
126
|
+
let originalSize = 0;
|
|
127
|
+
let compressedSize = 0;
|
|
128
|
+
|
|
129
|
+
// Apply compression if enabled
|
|
130
|
+
if (this.enableCompression) {
|
|
131
|
+
try {
|
|
132
|
+
// Serialize data to measure size
|
|
133
|
+
const serialized = JSON.stringify(data);
|
|
134
|
+
originalSize = Buffer.byteLength(serialized, 'utf8');
|
|
135
|
+
|
|
136
|
+
// Compress only if over threshold
|
|
137
|
+
if (originalSize >= this.compressionThreshold) {
|
|
138
|
+
const compressedBuffer = zlib.gzipSync(Buffer.from(serialized, 'utf8'));
|
|
139
|
+
finalData = {
|
|
140
|
+
__compressed: true,
|
|
141
|
+
__data: compressedBuffer.toString('base64'),
|
|
142
|
+
__originalSize: originalSize
|
|
143
|
+
};
|
|
144
|
+
compressedSize = Buffer.byteLength(finalData.__data, 'utf8');
|
|
145
|
+
compressed = true;
|
|
146
|
+
|
|
147
|
+
// Update compression stats
|
|
148
|
+
this.compressionStats.totalCompressed++;
|
|
149
|
+
this.compressionStats.totalOriginalSize += originalSize;
|
|
150
|
+
this.compressionStats.totalCompressedSize += compressedSize;
|
|
151
|
+
this.compressionStats.compressionRatio =
|
|
152
|
+
(this.compressionStats.totalCompressedSize / this.compressionStats.totalOriginalSize).toFixed(2);
|
|
153
|
+
}
|
|
154
|
+
} catch (error) {
|
|
155
|
+
// If compression fails, store uncompressed
|
|
156
|
+
console.warn(`[MemoryCache] Compression failed for key '${key}':`, error.message);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
this.cache[key] = finalData;
|
|
161
|
+
this.meta[key] = {
|
|
162
|
+
ts: Date.now(),
|
|
163
|
+
compressed,
|
|
164
|
+
originalSize,
|
|
165
|
+
compressedSize: compressed ? compressedSize : originalSize
|
|
166
|
+
};
|
|
167
|
+
|
|
111
168
|
return data;
|
|
112
169
|
}
|
|
113
170
|
|
|
114
171
|
async _get(key) {
|
|
115
172
|
if (!Object.prototype.hasOwnProperty.call(this.cache, key)) return null;
|
|
173
|
+
|
|
174
|
+
// Check TTL expiration
|
|
116
175
|
if (this.ttl > 0) {
|
|
117
176
|
const now = Date.now();
|
|
118
177
|
const meta = this.meta[key];
|
|
@@ -123,7 +182,27 @@ export class MemoryCache extends Cache {
|
|
|
123
182
|
return null;
|
|
124
183
|
}
|
|
125
184
|
}
|
|
126
|
-
|
|
185
|
+
|
|
186
|
+
const rawData = this.cache[key];
|
|
187
|
+
|
|
188
|
+
// Check if data is compressed
|
|
189
|
+
if (rawData && typeof rawData === 'object' && rawData.__compressed) {
|
|
190
|
+
try {
|
|
191
|
+
// Decompress data
|
|
192
|
+
const compressedBuffer = Buffer.from(rawData.__data, 'base64');
|
|
193
|
+
const decompressed = zlib.gunzipSync(compressedBuffer).toString('utf8');
|
|
194
|
+
return JSON.parse(decompressed);
|
|
195
|
+
} catch (error) {
|
|
196
|
+
console.warn(`[MemoryCache] Decompression failed for key '${key}':`, error.message);
|
|
197
|
+
// If decompression fails, remove corrupted entry
|
|
198
|
+
delete this.cache[key];
|
|
199
|
+
delete this.meta[key];
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Return uncompressed data
|
|
205
|
+
return rawData;
|
|
127
206
|
}
|
|
128
207
|
|
|
129
208
|
async _del(key) {
|
|
@@ -159,6 +238,36 @@ export class MemoryCache extends Cache {
|
|
|
159
238
|
async keys() {
|
|
160
239
|
return Object.keys(this.cache);
|
|
161
240
|
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Get compression statistics
|
|
244
|
+
* @returns {Object} Compression stats including total compressed items, ratios, and space savings
|
|
245
|
+
*/
|
|
246
|
+
getCompressionStats() {
|
|
247
|
+
if (!this.enableCompression) {
|
|
248
|
+
return { enabled: false, message: 'Compression is disabled' };
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const spaceSavings = this.compressionStats.totalOriginalSize > 0
|
|
252
|
+
? ((this.compressionStats.totalOriginalSize - this.compressionStats.totalCompressedSize) / this.compressionStats.totalOriginalSize * 100).toFixed(2)
|
|
253
|
+
: 0;
|
|
254
|
+
|
|
255
|
+
return {
|
|
256
|
+
enabled: true,
|
|
257
|
+
totalItems: Object.keys(this.cache).length,
|
|
258
|
+
compressedItems: this.compressionStats.totalCompressed,
|
|
259
|
+
compressionThreshold: this.compressionThreshold,
|
|
260
|
+
totalOriginalSize: this.compressionStats.totalOriginalSize,
|
|
261
|
+
totalCompressedSize: this.compressionStats.totalCompressedSize,
|
|
262
|
+
averageCompressionRatio: this.compressionStats.compressionRatio,
|
|
263
|
+
spaceSavingsPercent: spaceSavings,
|
|
264
|
+
memoryUsage: {
|
|
265
|
+
uncompressed: `${(this.compressionStats.totalOriginalSize / 1024).toFixed(2)} KB`,
|
|
266
|
+
compressed: `${(this.compressionStats.totalCompressedSize / 1024).toFixed(2)} KB`,
|
|
267
|
+
saved: `${((this.compressionStats.totalOriginalSize - this.compressionStats.totalCompressedSize) / 1024).toFixed(2)} KB`
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
}
|
|
162
271
|
}
|
|
163
272
|
|
|
164
273
|
export default MemoryCache
|
package/src/plugins/index.js
CHANGED
|
@@ -4,9 +4,12 @@ export { default as Plugin } from './plugin.class.js'
|
|
|
4
4
|
|
|
5
5
|
// plugins:
|
|
6
6
|
export * from './audit.plugin.js'
|
|
7
|
+
export * from './backup.plugin.js'
|
|
7
8
|
export * from './cache.plugin.js'
|
|
8
9
|
export * from './costs.plugin.js'
|
|
9
10
|
export * from './fulltext.plugin.js'
|
|
10
11
|
export * from './metrics.plugin.js'
|
|
11
12
|
export * from './queue-consumer.plugin.js'
|
|
12
13
|
export * from './replicator.plugin.js'
|
|
14
|
+
export * from './scheduler.plugin.js'
|
|
15
|
+
export * from './state-machine.plugin.js'
|