s3db.js 8.0.1 → 8.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/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 `'s3'` |
85
- | `ttl` | number | `300000` | Time-to-live in milliseconds (5 minutes) |
86
- | `maxSize` | number | `1000` | Maximum number of items in cache (memory driver) |
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
- ### Memory Driver Options (`memoryOptions`)
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
- | `maxSize` | number | `1000` | Maximum items in memory |
97
- | `ttl` | number | `300000` | Default TTL in milliseconds |
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
- ### S3 Driver Options (`s3Options`)
104
+ #### S3 Driver (`driver: 's3'`)
101
105
 
102
106
  | Parameter | Type | Default | Description |
103
107
  |-----------|------|---------|-------------|
104
- | `bucket` | string | Same as database | S3 bucket for cache storage |
105
- | `prefix` | string | `'cache/'` | S3 key prefix for cache objects |
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, // 15 minutes
152
- checkPeriod: 300000, // 5 minutes cleanup
153
- algorithm: 'lru' // Least Recently Used
193
+ ttl: 900000 // 15 minutes
154
194
  });
155
195
 
156
- const s3db = new S3db({
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: customCache,
160
- includePartitions: true,
200
+ driver: 'filesystem',
161
201
 
162
- // S3 cache fallback for persistence
163
- s3Options: {
164
- bucket: 'my-cache-bucket',
165
- prefix: 'app-cache/',
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
- // Memory cache for speed
172
- memoryOptions: {
173
- maxSize: 5000,
174
- ttl: 600000, // 10 minutes memory cache
175
- checkPeriod: 120000, // 2 minutes cleanup
176
- evictionPolicy: 'lru',
177
- stats: true // Enable cache statistics
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
- await s3db.connect();
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 = s3db.resource('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 || 0;
6631
- this.ttl = config.ttl || 0;
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.driver = options.driver;
7490
- this.config = {
7491
- includePartitions: options.includePartitions !== false,
7492
- partitionStrategy: options.partitionStrategy || "hierarchical",
7493
- partitionAware: options.partitionAware !== false,
7494
- trackUsage: options.trackUsage !== false,
7495
- preloadRelated: options.preloadRelated !== false,
7496
- ...options
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.config.driver && typeof this.config.driver === "object") {
7504
- this.driver = this.config.driver;
7505
- } else if (this.config.driver === "memory") {
7506
- this.driver = new memory_cache_class_default(this.config.memoryOptions || {});
7507
- } else if (this.config.driver === "filesystem") {
7508
- if (this.config.partitionAware) {
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.config.partitionStrategy,
7511
- trackUsage: this.config.trackUsage,
7512
- preloadRelated: this.config.preloadRelated,
7513
- ...this.config.filesystemOptions
7540
+ partitionStrategy: this.partitionStrategy,
7541
+ trackUsage: this.trackUsage,
7542
+ preloadRelated: this.preloadRelated,
7543
+ ...driverConfig
7514
7544
  });
7515
7545
  } else {
7516
- this.driver = new FilesystemCache(this.config.filesystemOptions || {});
7546
+ this.driver = new FilesystemCache(driverConfig);
7517
7547
  }
7518
7548
  } else {
7519
- this.driver = new s3_cache_class_default({ client: this.database.client, ...this.config.s3Options || {} });
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();
@@ -13384,7 +13428,7 @@ class Database extends EventEmitter {
13384
13428
  super();
13385
13429
  this.version = "1";
13386
13430
  this.s3dbVersion = (() => {
13387
- const [ok, err, version] = try_fn_default(() => true ? "8.0.0" : "latest");
13431
+ const [ok, err, version] = try_fn_default(() => true ? "8.0.2" : "latest");
13388
13432
  return ok ? version : "latest";
13389
13433
  })();
13390
13434
  this.resources = {};