s3db.js 7.4.1 → 7.5.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 +3 -3
- package/dist/s3db.cjs.js +55 -21
- package/dist/s3db.cjs.min.js +1 -1
- package/dist/s3db.es.js +55 -21
- package/dist/s3db.es.min.js +1 -1
- package/dist/s3db.iife.js +55 -21
- package/dist/s3db.iife.min.js +1 -1
- package/mcp/server.js +1 -1
- package/package.json +1 -1
- package/src/database.class.js +22 -1
- package/src/plugins/cache.plugin.js +4 -4
- package/src/plugins/replicator.plugin.js +19 -19
- package/src/resource.class.js +31 -2
package/dist/s3db.es.js
CHANGED
|
@@ -7606,11 +7606,11 @@ class CachePlugin extends plugin_class_default {
|
|
|
7606
7606
|
await super.setup(database);
|
|
7607
7607
|
}
|
|
7608
7608
|
async onSetup() {
|
|
7609
|
-
if (this.config.driver) {
|
|
7609
|
+
if (this.config.driver && typeof this.config.driver === "object") {
|
|
7610
7610
|
this.driver = this.config.driver;
|
|
7611
|
-
} else if (this.config.
|
|
7611
|
+
} else if (this.config.driver === "memory") {
|
|
7612
7612
|
this.driver = new memory_cache_class_default(this.config.memoryOptions || {});
|
|
7613
|
-
} else if (this.config.
|
|
7613
|
+
} else if (this.config.driver === "filesystem") {
|
|
7614
7614
|
if (this.config.partitionAware) {
|
|
7615
7615
|
this.driver = new PartitionAwareFilesystemCache({
|
|
7616
7616
|
partitionStrategy: this.config.partitionStrategy,
|
|
@@ -11192,6 +11192,14 @@ class Resource extends EventEmitter {
|
|
|
11192
11192
|
this.passphrase = passphrase ?? "secret";
|
|
11193
11193
|
this.versioningEnabled = versioningEnabled;
|
|
11194
11194
|
this.idGenerator = this.configureIdGenerator(customIdGenerator, idSize);
|
|
11195
|
+
if (typeof customIdGenerator === "number" && customIdGenerator > 0) {
|
|
11196
|
+
this.idSize = customIdGenerator;
|
|
11197
|
+
} else if (typeof idSize === "number" && idSize > 0) {
|
|
11198
|
+
this.idSize = idSize;
|
|
11199
|
+
} else {
|
|
11200
|
+
this.idSize = 22;
|
|
11201
|
+
}
|
|
11202
|
+
this.idGeneratorType = this.getIdGeneratorType(customIdGenerator, this.idSize);
|
|
11195
11203
|
this.config = {
|
|
11196
11204
|
cache,
|
|
11197
11205
|
hooks,
|
|
@@ -11247,7 +11255,7 @@ class Resource extends EventEmitter {
|
|
|
11247
11255
|
*/
|
|
11248
11256
|
configureIdGenerator(customIdGenerator, idSize) {
|
|
11249
11257
|
if (typeof customIdGenerator === "function") {
|
|
11250
|
-
return customIdGenerator;
|
|
11258
|
+
return () => String(customIdGenerator());
|
|
11251
11259
|
}
|
|
11252
11260
|
if (typeof customIdGenerator === "number" && customIdGenerator > 0) {
|
|
11253
11261
|
return customAlphabet(urlAlphabet, customIdGenerator);
|
|
@@ -11257,6 +11265,19 @@ class Resource extends EventEmitter {
|
|
|
11257
11265
|
}
|
|
11258
11266
|
return idGenerator;
|
|
11259
11267
|
}
|
|
11268
|
+
/**
|
|
11269
|
+
* Get a serializable representation of the ID generator type
|
|
11270
|
+
* @param {Function|number} customIdGenerator - Custom ID generator function or size
|
|
11271
|
+
* @param {number} idSize - Size for auto-generated IDs
|
|
11272
|
+
* @returns {string|number} Serializable ID generator type
|
|
11273
|
+
* @private
|
|
11274
|
+
*/
|
|
11275
|
+
getIdGeneratorType(customIdGenerator, idSize) {
|
|
11276
|
+
if (typeof customIdGenerator === "function") {
|
|
11277
|
+
return "custom_function";
|
|
11278
|
+
}
|
|
11279
|
+
return idSize;
|
|
11280
|
+
}
|
|
11260
11281
|
/**
|
|
11261
11282
|
* Get resource options (for backward compatibility with tests)
|
|
11262
11283
|
*/
|
|
@@ -13305,7 +13326,7 @@ class Database extends EventEmitter {
|
|
|
13305
13326
|
super();
|
|
13306
13327
|
this.version = "1";
|
|
13307
13328
|
this.s3dbVersion = (() => {
|
|
13308
|
-
const [ok, err, version] = try_fn_default(() => true ? "7.
|
|
13329
|
+
const [ok, err, version] = try_fn_default(() => true ? "7.5.0" : "latest");
|
|
13309
13330
|
return ok ? version : "latest";
|
|
13310
13331
|
})();
|
|
13311
13332
|
this.resources = {};
|
|
@@ -13376,6 +13397,18 @@ class Database extends EventEmitter {
|
|
|
13376
13397
|
const currentVersion = resourceMetadata.currentVersion || "v0";
|
|
13377
13398
|
const versionData = resourceMetadata.versions?.[currentVersion];
|
|
13378
13399
|
if (versionData) {
|
|
13400
|
+
let restoredIdGenerator, restoredIdSize;
|
|
13401
|
+
if (versionData.idGenerator !== void 0) {
|
|
13402
|
+
if (versionData.idGenerator === "custom_function") {
|
|
13403
|
+
restoredIdGenerator = void 0;
|
|
13404
|
+
restoredIdSize = versionData.idSize || 22;
|
|
13405
|
+
} else if (typeof versionData.idGenerator === "number") {
|
|
13406
|
+
restoredIdGenerator = versionData.idGenerator;
|
|
13407
|
+
restoredIdSize = versionData.idSize || versionData.idGenerator;
|
|
13408
|
+
}
|
|
13409
|
+
} else {
|
|
13410
|
+
restoredIdSize = versionData.idSize || 22;
|
|
13411
|
+
}
|
|
13379
13412
|
this.resources[name] = new resource_class_default({
|
|
13380
13413
|
name,
|
|
13381
13414
|
client: this.client,
|
|
@@ -13395,7 +13428,9 @@ class Database extends EventEmitter {
|
|
|
13395
13428
|
autoDecrypt: versionData.autoDecrypt !== void 0 ? versionData.autoDecrypt : true,
|
|
13396
13429
|
hooks: versionData.hooks || {},
|
|
13397
13430
|
versioningEnabled: this.versioningEnabled,
|
|
13398
|
-
map: versionData.map
|
|
13431
|
+
map: versionData.map,
|
|
13432
|
+
idGenerator: restoredIdGenerator,
|
|
13433
|
+
idSize: restoredIdSize
|
|
13399
13434
|
});
|
|
13400
13435
|
}
|
|
13401
13436
|
}
|
|
@@ -13556,6 +13591,8 @@ class Database extends EventEmitter {
|
|
|
13556
13591
|
autoDecrypt: resource.config.autoDecrypt,
|
|
13557
13592
|
cache: resource.config.cache,
|
|
13558
13593
|
hooks: resource.config.hooks,
|
|
13594
|
+
idSize: resource.idSize,
|
|
13595
|
+
idGenerator: resource.idGeneratorType,
|
|
13559
13596
|
createdAt: isNewVersion ? (/* @__PURE__ */ new Date()).toISOString() : existingVersionData?.createdAt
|
|
13560
13597
|
}
|
|
13561
13598
|
}
|
|
@@ -14511,6 +14548,10 @@ class ReplicatorPlugin extends plugin_class_default {
|
|
|
14511
14548
|
}
|
|
14512
14549
|
return filtered;
|
|
14513
14550
|
}
|
|
14551
|
+
async getCompleteData(resource, data) {
|
|
14552
|
+
const [ok, err, completeRecord] = await try_fn_default(() => resource.get(data.id));
|
|
14553
|
+
return ok ? completeRecord : data;
|
|
14554
|
+
}
|
|
14514
14555
|
installEventListeners(resource, database, plugin) {
|
|
14515
14556
|
if (!resource || this.eventListenersInstalled.has(resource.name) || resource.name === this.config.replicatorLogResource) {
|
|
14516
14557
|
return;
|
|
@@ -14529,8 +14570,9 @@ class ReplicatorPlugin extends plugin_class_default {
|
|
|
14529
14570
|
});
|
|
14530
14571
|
resource.on("update", async (data, beforeData) => {
|
|
14531
14572
|
const [ok, error] = await try_fn_default(async () => {
|
|
14532
|
-
const completeData =
|
|
14533
|
-
|
|
14573
|
+
const completeData = await plugin.getCompleteData(resource, data);
|
|
14574
|
+
const dataWithTimestamp = { ...completeData, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
14575
|
+
await plugin.processReplicatorEvent("update", resource.name, completeData.id, dataWithTimestamp, beforeData);
|
|
14534
14576
|
});
|
|
14535
14577
|
if (!ok) {
|
|
14536
14578
|
if (this.config.verbose) {
|
|
@@ -14552,14 +14594,6 @@ class ReplicatorPlugin extends plugin_class_default {
|
|
|
14552
14594
|
});
|
|
14553
14595
|
this.eventListenersInstalled.add(resource.name);
|
|
14554
14596
|
}
|
|
14555
|
-
/**
|
|
14556
|
-
* Get complete data by always fetching the full record from the resource
|
|
14557
|
-
* This ensures we always have the complete data regardless of behavior or data size
|
|
14558
|
-
*/
|
|
14559
|
-
async getCompleteData(resource, data) {
|
|
14560
|
-
const [ok, err, completeRecord] = await try_fn_default(() => resource.get(data.id));
|
|
14561
|
-
return ok ? completeRecord : data;
|
|
14562
|
-
}
|
|
14563
14597
|
async setup(database) {
|
|
14564
14598
|
this.database = database;
|
|
14565
14599
|
const [initOk, initError] = await try_fn_default(async () => {
|
|
@@ -14573,7 +14607,7 @@ class ReplicatorPlugin extends plugin_class_default {
|
|
|
14573
14607
|
throw initError;
|
|
14574
14608
|
}
|
|
14575
14609
|
const [logOk, logError] = await try_fn_default(async () => {
|
|
14576
|
-
if (this.config.
|
|
14610
|
+
if (this.config.persistReplicatorLog) {
|
|
14577
14611
|
const logRes = await database.createResource({
|
|
14578
14612
|
name: this.config.replicatorLogResource,
|
|
14579
14613
|
behavior: "body-overflow",
|
|
@@ -14600,6 +14634,10 @@ class ReplicatorPlugin extends plugin_class_default {
|
|
|
14600
14634
|
});
|
|
14601
14635
|
}
|
|
14602
14636
|
await this.uploadMetadataFile(database);
|
|
14637
|
+
for (const resourceName in database.resources) {
|
|
14638
|
+
const resource = database.resources[resourceName];
|
|
14639
|
+
this.installEventListeners(resource, database, this);
|
|
14640
|
+
}
|
|
14603
14641
|
const originalCreateResource = database.createResource.bind(database);
|
|
14604
14642
|
database.createResource = async (config) => {
|
|
14605
14643
|
const resource = await originalCreateResource(config);
|
|
@@ -14608,10 +14646,6 @@ class ReplicatorPlugin extends plugin_class_default {
|
|
|
14608
14646
|
}
|
|
14609
14647
|
return resource;
|
|
14610
14648
|
};
|
|
14611
|
-
for (const resourceName in database.resources) {
|
|
14612
|
-
const resource = database.resources[resourceName];
|
|
14613
|
-
this.installEventListeners(resource, database, this);
|
|
14614
|
-
}
|
|
14615
14649
|
}
|
|
14616
14650
|
createReplicator(driver, config, resources, client) {
|
|
14617
14651
|
return createReplicator(driver, config, resources, client);
|