s3db.js 9.2.1 → 9.2.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/dist/s3db.cjs.js +115 -32
- package/dist/s3db.cjs.js.map +1 -1
- package/dist/s3db.es.js +115 -32
- package/dist/s3db.es.js.map +1 -1
- package/package.json +1 -1
- package/src/concerns/async-event-emitter.js +2 -2
- package/src/resource.class.js +148 -36
package/dist/s3db.cjs.js
CHANGED
|
@@ -6283,10 +6283,10 @@ class AsyncEventEmitter extends EventEmitter {
|
|
|
6283
6283
|
if (listeners.length === 0) {
|
|
6284
6284
|
return false;
|
|
6285
6285
|
}
|
|
6286
|
-
setImmediate(() => {
|
|
6286
|
+
setImmediate(async () => {
|
|
6287
6287
|
for (const listener of listeners) {
|
|
6288
6288
|
try {
|
|
6289
|
-
listener(...args);
|
|
6289
|
+
await listener(...args);
|
|
6290
6290
|
} catch (error) {
|
|
6291
6291
|
if (event !== "error") {
|
|
6292
6292
|
this.emit("error", error);
|
|
@@ -7473,7 +7473,8 @@ ${errorDetails}`,
|
|
|
7473
7473
|
idSize = 22,
|
|
7474
7474
|
versioningEnabled = false,
|
|
7475
7475
|
events = {},
|
|
7476
|
-
asyncEvents = true
|
|
7476
|
+
asyncEvents = true,
|
|
7477
|
+
asyncPartitions = true
|
|
7477
7478
|
} = config;
|
|
7478
7479
|
this.name = name;
|
|
7479
7480
|
this.client = client;
|
|
@@ -7501,7 +7502,8 @@ ${errorDetails}`,
|
|
|
7501
7502
|
partitions,
|
|
7502
7503
|
autoDecrypt,
|
|
7503
7504
|
allNestedObjectsOptional,
|
|
7504
|
-
asyncEvents
|
|
7505
|
+
asyncEvents,
|
|
7506
|
+
asyncPartitions
|
|
7505
7507
|
};
|
|
7506
7508
|
this.hooks = {
|
|
7507
7509
|
beforeInsert: [],
|
|
@@ -8004,9 +8006,31 @@ ${errorDetails}`,
|
|
|
8004
8006
|
throw errPut;
|
|
8005
8007
|
}
|
|
8006
8008
|
const insertedObject = await this.get(finalId);
|
|
8007
|
-
|
|
8008
|
-
|
|
8009
|
-
|
|
8009
|
+
if (this.config.asyncPartitions && this.config.partitions && Object.keys(this.config.partitions).length > 0) {
|
|
8010
|
+
setImmediate(() => {
|
|
8011
|
+
this.createPartitionReferences(insertedObject).catch((err) => {
|
|
8012
|
+
this.emit("partitionIndexError", {
|
|
8013
|
+
operation: "insert",
|
|
8014
|
+
id: finalId,
|
|
8015
|
+
error: err,
|
|
8016
|
+
message: err.message
|
|
8017
|
+
});
|
|
8018
|
+
});
|
|
8019
|
+
});
|
|
8020
|
+
const nonPartitionHooks = this.hooks.afterInsert.filter(
|
|
8021
|
+
(hook) => !hook.toString().includes("createPartitionReferences")
|
|
8022
|
+
);
|
|
8023
|
+
let finalResult = insertedObject;
|
|
8024
|
+
for (const hook of nonPartitionHooks) {
|
|
8025
|
+
finalResult = await hook(finalResult);
|
|
8026
|
+
}
|
|
8027
|
+
this.emit("insert", finalResult);
|
|
8028
|
+
return finalResult;
|
|
8029
|
+
} else {
|
|
8030
|
+
const finalResult = await this.executeHooks("afterInsert", insertedObject);
|
|
8031
|
+
this.emit("insert", finalResult);
|
|
8032
|
+
return finalResult;
|
|
8033
|
+
}
|
|
8010
8034
|
}
|
|
8011
8035
|
/**
|
|
8012
8036
|
* Retrieve a resource object by ID
|
|
@@ -8235,13 +8259,39 @@ ${errorDetails}`,
|
|
|
8235
8259
|
body: finalBody,
|
|
8236
8260
|
behavior: this.behavior
|
|
8237
8261
|
});
|
|
8238
|
-
|
|
8239
|
-
|
|
8240
|
-
|
|
8241
|
-
|
|
8242
|
-
|
|
8243
|
-
|
|
8244
|
-
|
|
8262
|
+
if (this.config.asyncPartitions && this.config.partitions && Object.keys(this.config.partitions).length > 0) {
|
|
8263
|
+
setImmediate(() => {
|
|
8264
|
+
this.handlePartitionReferenceUpdates(originalData, updatedData).catch((err2) => {
|
|
8265
|
+
this.emit("partitionIndexError", {
|
|
8266
|
+
operation: "update",
|
|
8267
|
+
id,
|
|
8268
|
+
error: err2,
|
|
8269
|
+
message: err2.message
|
|
8270
|
+
});
|
|
8271
|
+
});
|
|
8272
|
+
});
|
|
8273
|
+
const nonPartitionHooks = this.hooks.afterUpdate.filter(
|
|
8274
|
+
(hook) => !hook.toString().includes("handlePartitionReferenceUpdates")
|
|
8275
|
+
);
|
|
8276
|
+
let finalResult = updatedData;
|
|
8277
|
+
for (const hook of nonPartitionHooks) {
|
|
8278
|
+
finalResult = await hook(finalResult);
|
|
8279
|
+
}
|
|
8280
|
+
this.emit("update", {
|
|
8281
|
+
...updatedData,
|
|
8282
|
+
$before: { ...originalData },
|
|
8283
|
+
$after: { ...finalResult }
|
|
8284
|
+
});
|
|
8285
|
+
return finalResult;
|
|
8286
|
+
} else {
|
|
8287
|
+
const finalResult = await this.executeHooks("afterUpdate", updatedData);
|
|
8288
|
+
this.emit("update", {
|
|
8289
|
+
...updatedData,
|
|
8290
|
+
$before: { ...originalData },
|
|
8291
|
+
$after: { ...finalResult }
|
|
8292
|
+
});
|
|
8293
|
+
return finalResult;
|
|
8294
|
+
}
|
|
8245
8295
|
}
|
|
8246
8296
|
/**
|
|
8247
8297
|
* Delete a resource object by ID
|
|
@@ -8286,8 +8336,29 @@ ${errorDetails}`,
|
|
|
8286
8336
|
operation: "delete",
|
|
8287
8337
|
id
|
|
8288
8338
|
});
|
|
8289
|
-
|
|
8290
|
-
|
|
8339
|
+
if (this.config.asyncPartitions && this.config.partitions && Object.keys(this.config.partitions).length > 0) {
|
|
8340
|
+
setImmediate(() => {
|
|
8341
|
+
this.deletePartitionReferences(objectData).catch((err3) => {
|
|
8342
|
+
this.emit("partitionIndexError", {
|
|
8343
|
+
operation: "delete",
|
|
8344
|
+
id,
|
|
8345
|
+
error: err3,
|
|
8346
|
+
message: err3.message
|
|
8347
|
+
});
|
|
8348
|
+
});
|
|
8349
|
+
});
|
|
8350
|
+
const nonPartitionHooks = this.hooks.afterDelete.filter(
|
|
8351
|
+
(hook) => !hook.toString().includes("deletePartitionReferences")
|
|
8352
|
+
);
|
|
8353
|
+
let afterDeleteData = objectData;
|
|
8354
|
+
for (const hook of nonPartitionHooks) {
|
|
8355
|
+
afterDeleteData = await hook(afterDeleteData);
|
|
8356
|
+
}
|
|
8357
|
+
return response;
|
|
8358
|
+
} else {
|
|
8359
|
+
await this.executeHooks("afterDelete", objectData);
|
|
8360
|
+
return response;
|
|
8361
|
+
}
|
|
8291
8362
|
}
|
|
8292
8363
|
/**
|
|
8293
8364
|
* Insert or update a resource object (upsert operation)
|
|
@@ -8980,19 +9051,29 @@ ${errorDetails}`,
|
|
|
8980
9051
|
if (!partitions || Object.keys(partitions).length === 0) {
|
|
8981
9052
|
return;
|
|
8982
9053
|
}
|
|
8983
|
-
|
|
9054
|
+
const promises = Object.entries(partitions).map(async ([partitionName, partition]) => {
|
|
8984
9055
|
const partitionKey = this.getPartitionKey({ partitionName, id: data.id, data });
|
|
8985
9056
|
if (partitionKey) {
|
|
8986
9057
|
const partitionMetadata = {
|
|
8987
9058
|
_v: String(this.version)
|
|
8988
9059
|
};
|
|
8989
|
-
|
|
9060
|
+
return this.client.putObject({
|
|
8990
9061
|
key: partitionKey,
|
|
8991
9062
|
metadata: partitionMetadata,
|
|
8992
9063
|
body: "",
|
|
8993
9064
|
contentType: void 0
|
|
8994
9065
|
});
|
|
8995
9066
|
}
|
|
9067
|
+
return null;
|
|
9068
|
+
});
|
|
9069
|
+
const results = await Promise.allSettled(promises);
|
|
9070
|
+
const failures = results.filter((r) => r.status === "rejected");
|
|
9071
|
+
if (failures.length > 0) {
|
|
9072
|
+
this.emit("partitionIndexWarning", {
|
|
9073
|
+
operation: "create",
|
|
9074
|
+
id: data.id,
|
|
9075
|
+
failures: failures.map((f) => f.reason)
|
|
9076
|
+
});
|
|
8996
9077
|
}
|
|
8997
9078
|
}
|
|
8998
9079
|
/**
|
|
@@ -9093,26 +9174,28 @@ ${errorDetails}`,
|
|
|
9093
9174
|
if (!partitions || Object.keys(partitions).length === 0) {
|
|
9094
9175
|
return;
|
|
9095
9176
|
}
|
|
9096
|
-
|
|
9177
|
+
const updatePromises = Object.entries(partitions).map(async ([partitionName, partition]) => {
|
|
9097
9178
|
const [ok, err] = await tryFn(() => this.handlePartitionReferenceUpdate(partitionName, partition, oldData, newData));
|
|
9098
|
-
|
|
9179
|
+
if (!ok) {
|
|
9180
|
+
return { partitionName, error: err };
|
|
9181
|
+
}
|
|
9182
|
+
return { partitionName, success: true };
|
|
9183
|
+
});
|
|
9184
|
+
await Promise.allSettled(updatePromises);
|
|
9099
9185
|
const id = newData.id || oldData.id;
|
|
9100
|
-
|
|
9186
|
+
const cleanupPromises = Object.entries(partitions).map(async ([partitionName, partition]) => {
|
|
9101
9187
|
const prefix = `resource=${this.name}/partition=${partitionName}`;
|
|
9102
|
-
let allKeys = [];
|
|
9103
9188
|
const [okKeys, errKeys, keys] = await tryFn(() => this.client.getAllKeys({ prefix }));
|
|
9104
|
-
if (okKeys) {
|
|
9105
|
-
|
|
9106
|
-
} else {
|
|
9107
|
-
continue;
|
|
9189
|
+
if (!okKeys) {
|
|
9190
|
+
return;
|
|
9108
9191
|
}
|
|
9109
9192
|
const validKey = this.getPartitionKey({ partitionName, id, data: newData });
|
|
9110
|
-
|
|
9111
|
-
|
|
9112
|
-
|
|
9113
|
-
}
|
|
9193
|
+
const staleKeys = keys.filter((key) => key.endsWith(`/id=${id}`) && key !== validKey);
|
|
9194
|
+
if (staleKeys.length > 0) {
|
|
9195
|
+
const [okDel, errDel] = await tryFn(() => this.client.deleteObjects(staleKeys));
|
|
9114
9196
|
}
|
|
9115
|
-
}
|
|
9197
|
+
});
|
|
9198
|
+
await Promise.allSettled(cleanupPromises);
|
|
9116
9199
|
}
|
|
9117
9200
|
/**
|
|
9118
9201
|
* Handle partition reference update for a specific partition
|
|
@@ -9617,7 +9700,7 @@ class Database extends EventEmitter {
|
|
|
9617
9700
|
this.id = idGenerator(7);
|
|
9618
9701
|
this.version = "1";
|
|
9619
9702
|
this.s3dbVersion = (() => {
|
|
9620
|
-
const [ok, err, version] = tryFn(() => true ? "9.2.
|
|
9703
|
+
const [ok, err, version] = tryFn(() => true ? "9.2.2" : "latest");
|
|
9621
9704
|
return ok ? version : "latest";
|
|
9622
9705
|
})();
|
|
9623
9706
|
this.resources = {};
|