s3db.js 8.0.1 → 8.0.3
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 +114 -39
- package/README.md +1 -25
- package/dist/s3db.cjs.js +79 -26
- package/dist/s3db.cjs.min.js +1 -1
- package/dist/s3db.es.js +79 -26
- package/dist/s3db.es.min.js +1 -1
- package/dist/s3db.iife.js +79 -26
- package/dist/s3db.iife.min.js +1 -1
- package/package.json +1 -1
- package/src/client.class.js +1 -1
- package/src/database.class.js +3 -1
- package/src/plugins/cache/memory-cache.class.js +2 -2
- package/src/plugins/cache.plugin.js +75 -21
- package/src/resource.class.js +11 -5
package/PLUGINS.md
CHANGED
|
@@ -81,41 +81,83 @@ await users.list(); // Cached result
|
|
|
81
81
|
|
|
82
82
|
| Parameter | Type | Default | Description |
|
|
83
83
|
|-----------|------|---------|-------------|
|
|
84
|
-
| `driver` | string | `'s3'` | Cache driver: `'memory'` or `'
|
|
85
|
-
| `ttl` | number | `300000` | Time-to-live in milliseconds (5 minutes) |
|
|
86
|
-
| `maxSize` | number | `1000` | Maximum number of items in cache
|
|
84
|
+
| `driver` | string | `'s3'` | Cache driver: `'memory'`, `'s3'`, or `'filesystem'` |
|
|
85
|
+
| `ttl` | number | `300000` | Time-to-live in milliseconds (5 minutes) - global setting |
|
|
86
|
+
| `maxSize` | number | `1000` | Maximum number of items in cache - global setting |
|
|
87
|
+
| `config` | object | `{}` | Driver-specific configuration options (can override global settings) |
|
|
87
88
|
| `includePartitions` | boolean | `true` | Include partition values in cache keys |
|
|
88
89
|
| `driver` | object | `null` | Custom cache driver instance |
|
|
89
|
-
| `memoryOptions` | object | `{}` | Options for memory cache driver |
|
|
90
|
-
| `s3Options` | object | `{}` | Options for S3 cache driver |
|
|
91
90
|
|
|
92
|
-
|
|
91
|
+
**Configuration Priority:** Driver-specific `config` options override global plugin settings. For example, if you set `ttl: 600000` at the plugin level and `ttl: 1800000` in the driver config, the driver will use 1800000 (30 minutes) while the global setting serves as the default for any drivers that don't specify their own TTL.
|
|
92
|
+
|
|
93
|
+
### Driver Configuration Options
|
|
94
|
+
|
|
95
|
+
The `config` object contains driver-specific options. Note that `ttl` and `maxSize` can be configured at the plugin level (applies to all operations) or in the driver config (driver-specific override).
|
|
96
|
+
|
|
97
|
+
#### Memory Driver (`driver: 'memory'`)
|
|
93
98
|
|
|
94
99
|
| Parameter | Type | Default | Description |
|
|
95
100
|
|-----------|------|---------|-------------|
|
|
96
|
-
| `
|
|
97
|
-
| `
|
|
98
|
-
| `checkPeriod` | number | `600000` | Cleanup interval in milliseconds |
|
|
101
|
+
| `ttl` | number | inherited | TTL override for memory cache (inherits from plugin level) |
|
|
102
|
+
| `maxSize` | number | inherited | Max items override for memory cache (inherits from plugin level) |
|
|
99
103
|
|
|
100
|
-
|
|
104
|
+
#### S3 Driver (`driver: 's3'`)
|
|
101
105
|
|
|
102
106
|
| Parameter | Type | Default | Description |
|
|
103
107
|
|-----------|------|---------|-------------|
|
|
104
|
-
| `
|
|
105
|
-
| `
|
|
108
|
+
| `ttl` | number | inherited | TTL override for S3 cache (inherits from plugin level) |
|
|
109
|
+
| `keyPrefix` | string | `'cache'` | S3 key prefix for cache objects |
|
|
106
110
|
| `client` | object | Database client | Custom S3 client instance |
|
|
107
111
|
|
|
112
|
+
**Note:** S3 cache automatically uses gzip compression for all cached values.
|
|
113
|
+
|
|
114
|
+
#### Filesystem Driver (`driver: 'filesystem'`)
|
|
115
|
+
|
|
116
|
+
| Parameter | Type | Default | Description |
|
|
117
|
+
|-----------|------|---------|-------------|
|
|
118
|
+
| `directory` | string | required | Directory path to store cache files |
|
|
119
|
+
| `ttl` | number | inherited | TTL override for filesystem cache (inherits from plugin level) |
|
|
120
|
+
| `prefix` | string | `'cache'` | Prefix for cache filenames |
|
|
121
|
+
| `enableCompression` | boolean | `true` | Whether to compress cache values using gzip |
|
|
122
|
+
| `compressionThreshold` | number | `1024` | Minimum size in bytes to trigger compression |
|
|
123
|
+
| `createDirectory` | boolean | `true` | Whether to create the directory if it doesn't exist |
|
|
124
|
+
| `fileExtension` | string | `'.cache'` | File extension for cache files |
|
|
125
|
+
| `enableMetadata` | boolean | `true` | Whether to store metadata alongside cache data |
|
|
126
|
+
| `maxFileSize` | number | `10485760` | Maximum file size in bytes (10MB) |
|
|
127
|
+
| `enableStats` | boolean | `false` | Whether to track cache statistics |
|
|
128
|
+
| `enableCleanup` | boolean | `true` | Whether to automatically clean up expired files |
|
|
129
|
+
| `cleanupInterval` | number | `300000` | Interval in milliseconds to run cleanup (5 minutes) |
|
|
130
|
+
| `encoding` | string | `'utf8'` | File encoding to use |
|
|
131
|
+
| `fileMode` | number | `0o644` | File permissions in octal notation |
|
|
132
|
+
|
|
108
133
|
### 🔧 Easy Example
|
|
109
134
|
|
|
110
135
|
```javascript
|
|
111
136
|
import { S3db, CachePlugin } from 's3db.js';
|
|
112
137
|
|
|
138
|
+
// Memory cache example with global settings
|
|
113
139
|
const s3db = new S3db({
|
|
114
140
|
connectionString: "s3://ACCESS_KEY:SECRET_KEY@BUCKET_NAME/databases/myapp",
|
|
115
141
|
plugins: [new CachePlugin({
|
|
116
142
|
driver: 'memory',
|
|
117
|
-
ttl: 600000, // 10 minutes
|
|
118
|
-
maxSize: 500
|
|
143
|
+
ttl: 600000, // 10 minutes - applies to all cache operations
|
|
144
|
+
maxSize: 500 // 500 items max - applies to all cache operations
|
|
145
|
+
})]
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// Filesystem cache example with driver-specific override
|
|
149
|
+
const s3dbWithFileCache = new S3db({
|
|
150
|
+
connectionString: "s3://ACCESS_KEY:SECRET_KEY@BUCKET_NAME/databases/myapp",
|
|
151
|
+
plugins: [new CachePlugin({
|
|
152
|
+
driver: 'filesystem',
|
|
153
|
+
ttl: 900000, // 15 minutes - global default
|
|
154
|
+
maxSize: 2000, // 2000 items max - global default
|
|
155
|
+
config: {
|
|
156
|
+
directory: './cache',
|
|
157
|
+
ttl: 1800000, // 30 minutes - overrides global for filesystem only
|
|
158
|
+
enableCompression: true,
|
|
159
|
+
enableCleanup: true
|
|
160
|
+
}
|
|
119
161
|
})]
|
|
120
162
|
});
|
|
121
163
|
|
|
@@ -143,46 +185,78 @@ const result3 = await products.count(); // Fresh data
|
|
|
143
185
|
### 🚀 Advanced Configuration Example
|
|
144
186
|
|
|
145
187
|
```javascript
|
|
146
|
-
import { S3db, CachePlugin, MemoryCache, S3Cache } from 's3db.js';
|
|
188
|
+
import { S3db, CachePlugin, MemoryCache, S3Cache, FilesystemCache } from 's3db.js';
|
|
147
189
|
|
|
148
190
|
// Custom cache driver with advanced configuration
|
|
149
191
|
const customCache = new MemoryCache({
|
|
150
192
|
maxSize: 2000,
|
|
151
|
-
ttl: 900000
|
|
152
|
-
checkPeriod: 300000, // 5 minutes cleanup
|
|
153
|
-
algorithm: 'lru' // Least Recently Used
|
|
193
|
+
ttl: 900000 // 15 minutes
|
|
154
194
|
});
|
|
155
195
|
|
|
156
|
-
|
|
196
|
+
// Advanced cache configuration with global settings
|
|
197
|
+
const s3dbWithAdvancedCache = new S3db({
|
|
157
198
|
connectionString: "s3://ACCESS_KEY:SECRET_KEY@BUCKET_NAME/databases/myapp",
|
|
158
199
|
plugins: [new CachePlugin({
|
|
159
|
-
driver:
|
|
160
|
-
includePartitions: true,
|
|
200
|
+
driver: 'filesystem',
|
|
161
201
|
|
|
162
|
-
//
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
ttl: 3600000, // 1 hour S3 cache
|
|
167
|
-
compression: true,
|
|
168
|
-
encryption: true
|
|
169
|
-
},
|
|
202
|
+
// Global cache settings (apply to all operations)
|
|
203
|
+
ttl: 3600000, // 1 hour default
|
|
204
|
+
maxSize: 5000, // 5000 items max
|
|
205
|
+
includePartitions: true,
|
|
170
206
|
|
|
171
|
-
//
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
207
|
+
// Driver-specific configuration
|
|
208
|
+
config: {
|
|
209
|
+
directory: './data/cache',
|
|
210
|
+
prefix: 'app-cache',
|
|
211
|
+
ttl: 7200000, // 2 hours - overrides global TTL for filesystem
|
|
212
|
+
enableCompression: true,
|
|
213
|
+
compressionThreshold: 512, // Compress files > 512 bytes
|
|
214
|
+
enableCleanup: true,
|
|
215
|
+
cleanupInterval: 600000, // 10 minutes
|
|
216
|
+
enableMetadata: true,
|
|
217
|
+
maxFileSize: 5242880, // 5MB per file
|
|
218
|
+
enableStats: true,
|
|
219
|
+
fileMode: 0o644,
|
|
220
|
+
encoding: 'utf8'
|
|
178
221
|
}
|
|
179
222
|
})]
|
|
180
223
|
});
|
|
181
224
|
|
|
182
|
-
|
|
225
|
+
// Multiple cache configuration examples
|
|
226
|
+
const s3dbWithS3Cache = new S3db({
|
|
227
|
+
connectionString: "s3://ACCESS_KEY:SECRET_KEY@BUCKET_NAME/databases/myapp",
|
|
228
|
+
plugins: [new CachePlugin({
|
|
229
|
+
driver: 's3',
|
|
230
|
+
ttl: 3600000, // 1 hour - global TTL
|
|
231
|
+
includePartitions: true,
|
|
232
|
+
config: {
|
|
233
|
+
keyPrefix: 'app-cache'
|
|
234
|
+
}
|
|
235
|
+
})]
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
const s3dbWithMemoryCache = new S3db({
|
|
239
|
+
connectionString: "s3://ACCESS_KEY:SECRET_KEY@BUCKET_NAME/databases/myapp",
|
|
240
|
+
plugins: [new CachePlugin({
|
|
241
|
+
driver: 'memory',
|
|
242
|
+
ttl: 600000, // 10 minutes - global TTL
|
|
243
|
+
maxSize: 5000, // 5000 items max - global limit
|
|
244
|
+
includePartitions: true
|
|
245
|
+
})]
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
const s3dbWithCustomCache = new S3db({
|
|
249
|
+
connectionString: "s3://ACCESS_KEY:SECRET_KEY@BUCKET_NAME/databases/myapp",
|
|
250
|
+
plugins: [new CachePlugin({
|
|
251
|
+
driver: customCache, // Custom driver instance
|
|
252
|
+
includePartitions: true
|
|
253
|
+
})]
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
await s3dbWithAdvancedCache.connect();
|
|
183
257
|
|
|
184
258
|
// Access cache methods on resources
|
|
185
|
-
const users =
|
|
259
|
+
const users = s3dbWithAdvancedCache.resource('users');
|
|
186
260
|
|
|
187
261
|
// Generate custom cache keys
|
|
188
262
|
const cacheKey = await users.cacheKeyFor({
|
|
@@ -3888,7 +3962,8 @@ const s3db = new S3db({
|
|
|
3888
3962
|
// Performance optimization
|
|
3889
3963
|
new CachePlugin({
|
|
3890
3964
|
driver: 'memory',
|
|
3891
|
-
ttl: 600000
|
|
3965
|
+
ttl: 600000, // 10 minutes
|
|
3966
|
+
maxSize: 1000
|
|
3892
3967
|
}),
|
|
3893
3968
|
|
|
3894
3969
|
// Cost tracking
|
package/README.md
CHANGED
|
@@ -357,13 +357,7 @@ A logical container for your resources, stored in a specific S3 prefix.
|
|
|
357
357
|
|
|
358
358
|
```javascript
|
|
359
359
|
const s3db = new S3db({
|
|
360
|
-
connectionString: "s3://ACCESS_KEY:SECRET_KEY@BUCKET_NAME/databases/myapp"
|
|
361
|
-
// Optional: Customize HTTP client for performance
|
|
362
|
-
httpClientOptions: {
|
|
363
|
-
keepAlive: true,
|
|
364
|
-
maxSockets: 50,
|
|
365
|
-
timeout: 60000
|
|
366
|
-
}
|
|
360
|
+
connectionString: "s3://ACCESS_KEY:SECRET_KEY@BUCKET_NAME/databases/myapp"
|
|
367
361
|
});
|
|
368
362
|
```
|
|
369
363
|
|
|
@@ -404,24 +398,6 @@ Built-in validation using [@icebob/fastest-validator](https://github.com/icebob/
|
|
|
404
398
|
|
|
405
399
|
s3db.js is designed for high performance with optimized defaults and configurable settings:
|
|
406
400
|
|
|
407
|
-
#### HTTP Client Optimization
|
|
408
|
-
|
|
409
|
-
The default HTTP client configuration is optimized for most applications:
|
|
410
|
-
|
|
411
|
-
```javascript
|
|
412
|
-
// Default optimized settings
|
|
413
|
-
const s3db = new S3db({
|
|
414
|
-
connectionString: "s3://ACCESS_KEY:SECRET_KEY@BUCKET_NAME/databases/myapp",
|
|
415
|
-
httpClientOptions: {
|
|
416
|
-
keepAlive: true, // Connection reuse for better performance
|
|
417
|
-
keepAliveMsecs: 1000, // 1 second keep-alive duration
|
|
418
|
-
maxSockets: 50, // Balanced concurrency
|
|
419
|
-
maxFreeSockets: 10, // Good connection pool utilization
|
|
420
|
-
timeout: 60000 // 60 second timeout
|
|
421
|
-
}
|
|
422
|
-
});
|
|
423
|
-
```
|
|
424
|
-
|
|
425
401
|
#### Bulk Operations Performance
|
|
426
402
|
|
|
427
403
|
Use bulk operations for better performance with large datasets:
|
package/dist/s3db.cjs.js
CHANGED
|
@@ -6627,8 +6627,8 @@ class MemoryCache extends Cache {
|
|
|
6627
6627
|
super(config);
|
|
6628
6628
|
this.cache = {};
|
|
6629
6629
|
this.meta = {};
|
|
6630
|
-
this.maxSize = config.maxSize
|
|
6631
|
-
this.ttl = config.ttl
|
|
6630
|
+
this.maxSize = config.maxSize !== void 0 ? config.maxSize : 1e3;
|
|
6631
|
+
this.ttl = config.ttl !== void 0 ? config.ttl : 3e5;
|
|
6632
6632
|
}
|
|
6633
6633
|
async _set(key, data) {
|
|
6634
6634
|
if (this.maxSize > 0 && Object.keys(this.cache).length >= this.maxSize) {
|
|
@@ -7486,37 +7486,81 @@ class PartitionAwareFilesystemCache extends FilesystemCache {
|
|
|
7486
7486
|
class CachePlugin extends plugin_class_default {
|
|
7487
7487
|
constructor(options = {}) {
|
|
7488
7488
|
super(options);
|
|
7489
|
-
this.
|
|
7490
|
-
this.
|
|
7491
|
-
|
|
7492
|
-
|
|
7493
|
-
|
|
7494
|
-
|
|
7495
|
-
|
|
7496
|
-
|
|
7489
|
+
this.driverName = options.driver || "s3";
|
|
7490
|
+
this.ttl = options.ttl;
|
|
7491
|
+
this.maxSize = options.maxSize;
|
|
7492
|
+
this.config = options.config || {};
|
|
7493
|
+
this.includePartitions = options.includePartitions !== false;
|
|
7494
|
+
this.partitionStrategy = options.partitionStrategy || "hierarchical";
|
|
7495
|
+
this.partitionAware = options.partitionAware !== false;
|
|
7496
|
+
this.trackUsage = options.trackUsage !== false;
|
|
7497
|
+
this.preloadRelated = options.preloadRelated !== false;
|
|
7498
|
+
this.legacyConfig = {
|
|
7499
|
+
memoryOptions: options.memoryOptions,
|
|
7500
|
+
filesystemOptions: options.filesystemOptions,
|
|
7501
|
+
s3Options: options.s3Options,
|
|
7502
|
+
driver: options.driver
|
|
7497
7503
|
};
|
|
7498
7504
|
}
|
|
7499
7505
|
async setup(database) {
|
|
7500
7506
|
await super.setup(database);
|
|
7501
7507
|
}
|
|
7502
7508
|
async onSetup() {
|
|
7503
|
-
if (this.
|
|
7504
|
-
this.driver = this.
|
|
7505
|
-
} else if (this.
|
|
7506
|
-
|
|
7507
|
-
|
|
7508
|
-
|
|
7509
|
+
if (this.driverName && typeof this.driverName === "object") {
|
|
7510
|
+
this.driver = this.driverName;
|
|
7511
|
+
} else if (this.driverName === "memory") {
|
|
7512
|
+
const driverConfig = {
|
|
7513
|
+
...this.legacyConfig.memoryOptions,
|
|
7514
|
+
// Legacy support (lowest priority)
|
|
7515
|
+
...this.config
|
|
7516
|
+
// New config format (medium priority)
|
|
7517
|
+
};
|
|
7518
|
+
if (this.ttl !== void 0) {
|
|
7519
|
+
driverConfig.ttl = this.ttl;
|
|
7520
|
+
}
|
|
7521
|
+
if (this.maxSize !== void 0) {
|
|
7522
|
+
driverConfig.maxSize = this.maxSize;
|
|
7523
|
+
}
|
|
7524
|
+
this.driver = new memory_cache_class_default(driverConfig);
|
|
7525
|
+
} else if (this.driverName === "filesystem") {
|
|
7526
|
+
const driverConfig = {
|
|
7527
|
+
...this.legacyConfig.filesystemOptions,
|
|
7528
|
+
// Legacy support (lowest priority)
|
|
7529
|
+
...this.config
|
|
7530
|
+
// New config format (medium priority)
|
|
7531
|
+
};
|
|
7532
|
+
if (this.ttl !== void 0) {
|
|
7533
|
+
driverConfig.ttl = this.ttl;
|
|
7534
|
+
}
|
|
7535
|
+
if (this.maxSize !== void 0) {
|
|
7536
|
+
driverConfig.maxSize = this.maxSize;
|
|
7537
|
+
}
|
|
7538
|
+
if (this.partitionAware) {
|
|
7509
7539
|
this.driver = new PartitionAwareFilesystemCache({
|
|
7510
|
-
partitionStrategy: this.
|
|
7511
|
-
trackUsage: this.
|
|
7512
|
-
preloadRelated: this.
|
|
7513
|
-
...
|
|
7540
|
+
partitionStrategy: this.partitionStrategy,
|
|
7541
|
+
trackUsage: this.trackUsage,
|
|
7542
|
+
preloadRelated: this.preloadRelated,
|
|
7543
|
+
...driverConfig
|
|
7514
7544
|
});
|
|
7515
7545
|
} else {
|
|
7516
|
-
this.driver = new FilesystemCache(
|
|
7546
|
+
this.driver = new FilesystemCache(driverConfig);
|
|
7517
7547
|
}
|
|
7518
7548
|
} else {
|
|
7519
|
-
|
|
7549
|
+
const driverConfig = {
|
|
7550
|
+
client: this.database.client,
|
|
7551
|
+
// Required for S3Cache
|
|
7552
|
+
...this.legacyConfig.s3Options,
|
|
7553
|
+
// Legacy support (lowest priority)
|
|
7554
|
+
...this.config
|
|
7555
|
+
// New config format (medium priority)
|
|
7556
|
+
};
|
|
7557
|
+
if (this.ttl !== void 0) {
|
|
7558
|
+
driverConfig.ttl = this.ttl;
|
|
7559
|
+
}
|
|
7560
|
+
if (this.maxSize !== void 0) {
|
|
7561
|
+
driverConfig.maxSize = this.maxSize;
|
|
7562
|
+
}
|
|
7563
|
+
this.driver = new s3_cache_class_default(driverConfig);
|
|
7520
7564
|
}
|
|
7521
7565
|
this.installDatabaseHooks();
|
|
7522
7566
|
this.installResourceHooks();
|
|
@@ -9621,7 +9665,7 @@ class Client extends EventEmitter {
|
|
|
9621
9665
|
}) {
|
|
9622
9666
|
super();
|
|
9623
9667
|
this.verbose = verbose;
|
|
9624
|
-
this.id = id ?? idGenerator();
|
|
9668
|
+
this.id = id ?? idGenerator(77);
|
|
9625
9669
|
this.parallelism = parallelism;
|
|
9626
9670
|
this.config = new ConnectionString(connectionString);
|
|
9627
9671
|
this.httpClientOptions = {
|
|
@@ -11208,10 +11252,18 @@ class Resource extends EventEmitter {
|
|
|
11208
11252
|
*/
|
|
11209
11253
|
constructor(config = {}) {
|
|
11210
11254
|
super();
|
|
11211
|
-
this._instanceId =
|
|
11255
|
+
this._instanceId = idGenerator(7);
|
|
11212
11256
|
const validation = validateResourceConfig(config);
|
|
11213
11257
|
if (!validation.isValid) {
|
|
11214
|
-
|
|
11258
|
+
const errorDetails = validation.errors.map((err) => ` \u2022 ${err}`).join("\n");
|
|
11259
|
+
throw new ResourceError(
|
|
11260
|
+
`Invalid Resource ${config.name || "[unnamed]"} configuration:
|
|
11261
|
+
${errorDetails}`,
|
|
11262
|
+
{
|
|
11263
|
+
resourceName: config.name,
|
|
11264
|
+
validation: validation.errors
|
|
11265
|
+
}
|
|
11266
|
+
);
|
|
11215
11267
|
}
|
|
11216
11268
|
const {
|
|
11217
11269
|
name,
|
|
@@ -13382,9 +13434,10 @@ var resource_class_default = Resource;
|
|
|
13382
13434
|
class Database extends EventEmitter {
|
|
13383
13435
|
constructor(options) {
|
|
13384
13436
|
super();
|
|
13437
|
+
this.id = idGenerator(7);
|
|
13385
13438
|
this.version = "1";
|
|
13386
13439
|
this.s3dbVersion = (() => {
|
|
13387
|
-
const [ok, err, version] = try_fn_default(() => true ? "8.0.
|
|
13440
|
+
const [ok, err, version] = try_fn_default(() => true ? "8.0.2" : "latest");
|
|
13388
13441
|
return ok ? version : "latest";
|
|
13389
13442
|
})();
|
|
13390
13443
|
this.resources = {};
|