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.es.js
CHANGED
|
@@ -6279,10 +6279,10 @@ class AsyncEventEmitter extends EventEmitter {
|
|
|
6279
6279
|
if (listeners.length === 0) {
|
|
6280
6280
|
return false;
|
|
6281
6281
|
}
|
|
6282
|
-
setImmediate(() => {
|
|
6282
|
+
setImmediate(async () => {
|
|
6283
6283
|
for (const listener of listeners) {
|
|
6284
6284
|
try {
|
|
6285
|
-
listener(...args);
|
|
6285
|
+
await listener(...args);
|
|
6286
6286
|
} catch (error) {
|
|
6287
6287
|
if (event !== "error") {
|
|
6288
6288
|
this.emit("error", error);
|
|
@@ -7469,7 +7469,8 @@ ${errorDetails}`,
|
|
|
7469
7469
|
idSize = 22,
|
|
7470
7470
|
versioningEnabled = false,
|
|
7471
7471
|
events = {},
|
|
7472
|
-
asyncEvents = true
|
|
7472
|
+
asyncEvents = true,
|
|
7473
|
+
asyncPartitions = true
|
|
7473
7474
|
} = config;
|
|
7474
7475
|
this.name = name;
|
|
7475
7476
|
this.client = client;
|
|
@@ -7497,7 +7498,8 @@ ${errorDetails}`,
|
|
|
7497
7498
|
partitions,
|
|
7498
7499
|
autoDecrypt,
|
|
7499
7500
|
allNestedObjectsOptional,
|
|
7500
|
-
asyncEvents
|
|
7501
|
+
asyncEvents,
|
|
7502
|
+
asyncPartitions
|
|
7501
7503
|
};
|
|
7502
7504
|
this.hooks = {
|
|
7503
7505
|
beforeInsert: [],
|
|
@@ -8000,9 +8002,31 @@ ${errorDetails}`,
|
|
|
8000
8002
|
throw errPut;
|
|
8001
8003
|
}
|
|
8002
8004
|
const insertedObject = await this.get(finalId);
|
|
8003
|
-
|
|
8004
|
-
|
|
8005
|
-
|
|
8005
|
+
if (this.config.asyncPartitions && this.config.partitions && Object.keys(this.config.partitions).length > 0) {
|
|
8006
|
+
setImmediate(() => {
|
|
8007
|
+
this.createPartitionReferences(insertedObject).catch((err) => {
|
|
8008
|
+
this.emit("partitionIndexError", {
|
|
8009
|
+
operation: "insert",
|
|
8010
|
+
id: finalId,
|
|
8011
|
+
error: err,
|
|
8012
|
+
message: err.message
|
|
8013
|
+
});
|
|
8014
|
+
});
|
|
8015
|
+
});
|
|
8016
|
+
const nonPartitionHooks = this.hooks.afterInsert.filter(
|
|
8017
|
+
(hook) => !hook.toString().includes("createPartitionReferences")
|
|
8018
|
+
);
|
|
8019
|
+
let finalResult = insertedObject;
|
|
8020
|
+
for (const hook of nonPartitionHooks) {
|
|
8021
|
+
finalResult = await hook(finalResult);
|
|
8022
|
+
}
|
|
8023
|
+
this.emit("insert", finalResult);
|
|
8024
|
+
return finalResult;
|
|
8025
|
+
} else {
|
|
8026
|
+
const finalResult = await this.executeHooks("afterInsert", insertedObject);
|
|
8027
|
+
this.emit("insert", finalResult);
|
|
8028
|
+
return finalResult;
|
|
8029
|
+
}
|
|
8006
8030
|
}
|
|
8007
8031
|
/**
|
|
8008
8032
|
* Retrieve a resource object by ID
|
|
@@ -8231,13 +8255,39 @@ ${errorDetails}`,
|
|
|
8231
8255
|
body: finalBody,
|
|
8232
8256
|
behavior: this.behavior
|
|
8233
8257
|
});
|
|
8234
|
-
|
|
8235
|
-
|
|
8236
|
-
|
|
8237
|
-
|
|
8238
|
-
|
|
8239
|
-
|
|
8240
|
-
|
|
8258
|
+
if (this.config.asyncPartitions && this.config.partitions && Object.keys(this.config.partitions).length > 0) {
|
|
8259
|
+
setImmediate(() => {
|
|
8260
|
+
this.handlePartitionReferenceUpdates(originalData, updatedData).catch((err2) => {
|
|
8261
|
+
this.emit("partitionIndexError", {
|
|
8262
|
+
operation: "update",
|
|
8263
|
+
id,
|
|
8264
|
+
error: err2,
|
|
8265
|
+
message: err2.message
|
|
8266
|
+
});
|
|
8267
|
+
});
|
|
8268
|
+
});
|
|
8269
|
+
const nonPartitionHooks = this.hooks.afterUpdate.filter(
|
|
8270
|
+
(hook) => !hook.toString().includes("handlePartitionReferenceUpdates")
|
|
8271
|
+
);
|
|
8272
|
+
let finalResult = updatedData;
|
|
8273
|
+
for (const hook of nonPartitionHooks) {
|
|
8274
|
+
finalResult = await hook(finalResult);
|
|
8275
|
+
}
|
|
8276
|
+
this.emit("update", {
|
|
8277
|
+
...updatedData,
|
|
8278
|
+
$before: { ...originalData },
|
|
8279
|
+
$after: { ...finalResult }
|
|
8280
|
+
});
|
|
8281
|
+
return finalResult;
|
|
8282
|
+
} else {
|
|
8283
|
+
const finalResult = await this.executeHooks("afterUpdate", updatedData);
|
|
8284
|
+
this.emit("update", {
|
|
8285
|
+
...updatedData,
|
|
8286
|
+
$before: { ...originalData },
|
|
8287
|
+
$after: { ...finalResult }
|
|
8288
|
+
});
|
|
8289
|
+
return finalResult;
|
|
8290
|
+
}
|
|
8241
8291
|
}
|
|
8242
8292
|
/**
|
|
8243
8293
|
* Delete a resource object by ID
|
|
@@ -8282,8 +8332,29 @@ ${errorDetails}`,
|
|
|
8282
8332
|
operation: "delete",
|
|
8283
8333
|
id
|
|
8284
8334
|
});
|
|
8285
|
-
|
|
8286
|
-
|
|
8335
|
+
if (this.config.asyncPartitions && this.config.partitions && Object.keys(this.config.partitions).length > 0) {
|
|
8336
|
+
setImmediate(() => {
|
|
8337
|
+
this.deletePartitionReferences(objectData).catch((err3) => {
|
|
8338
|
+
this.emit("partitionIndexError", {
|
|
8339
|
+
operation: "delete",
|
|
8340
|
+
id,
|
|
8341
|
+
error: err3,
|
|
8342
|
+
message: err3.message
|
|
8343
|
+
});
|
|
8344
|
+
});
|
|
8345
|
+
});
|
|
8346
|
+
const nonPartitionHooks = this.hooks.afterDelete.filter(
|
|
8347
|
+
(hook) => !hook.toString().includes("deletePartitionReferences")
|
|
8348
|
+
);
|
|
8349
|
+
let afterDeleteData = objectData;
|
|
8350
|
+
for (const hook of nonPartitionHooks) {
|
|
8351
|
+
afterDeleteData = await hook(afterDeleteData);
|
|
8352
|
+
}
|
|
8353
|
+
return response;
|
|
8354
|
+
} else {
|
|
8355
|
+
await this.executeHooks("afterDelete", objectData);
|
|
8356
|
+
return response;
|
|
8357
|
+
}
|
|
8287
8358
|
}
|
|
8288
8359
|
/**
|
|
8289
8360
|
* Insert or update a resource object (upsert operation)
|
|
@@ -8976,19 +9047,29 @@ ${errorDetails}`,
|
|
|
8976
9047
|
if (!partitions || Object.keys(partitions).length === 0) {
|
|
8977
9048
|
return;
|
|
8978
9049
|
}
|
|
8979
|
-
|
|
9050
|
+
const promises = Object.entries(partitions).map(async ([partitionName, partition]) => {
|
|
8980
9051
|
const partitionKey = this.getPartitionKey({ partitionName, id: data.id, data });
|
|
8981
9052
|
if (partitionKey) {
|
|
8982
9053
|
const partitionMetadata = {
|
|
8983
9054
|
_v: String(this.version)
|
|
8984
9055
|
};
|
|
8985
|
-
|
|
9056
|
+
return this.client.putObject({
|
|
8986
9057
|
key: partitionKey,
|
|
8987
9058
|
metadata: partitionMetadata,
|
|
8988
9059
|
body: "",
|
|
8989
9060
|
contentType: void 0
|
|
8990
9061
|
});
|
|
8991
9062
|
}
|
|
9063
|
+
return null;
|
|
9064
|
+
});
|
|
9065
|
+
const results = await Promise.allSettled(promises);
|
|
9066
|
+
const failures = results.filter((r) => r.status === "rejected");
|
|
9067
|
+
if (failures.length > 0) {
|
|
9068
|
+
this.emit("partitionIndexWarning", {
|
|
9069
|
+
operation: "create",
|
|
9070
|
+
id: data.id,
|
|
9071
|
+
failures: failures.map((f) => f.reason)
|
|
9072
|
+
});
|
|
8992
9073
|
}
|
|
8993
9074
|
}
|
|
8994
9075
|
/**
|
|
@@ -9089,26 +9170,28 @@ ${errorDetails}`,
|
|
|
9089
9170
|
if (!partitions || Object.keys(partitions).length === 0) {
|
|
9090
9171
|
return;
|
|
9091
9172
|
}
|
|
9092
|
-
|
|
9173
|
+
const updatePromises = Object.entries(partitions).map(async ([partitionName, partition]) => {
|
|
9093
9174
|
const [ok, err] = await tryFn(() => this.handlePartitionReferenceUpdate(partitionName, partition, oldData, newData));
|
|
9094
|
-
|
|
9175
|
+
if (!ok) {
|
|
9176
|
+
return { partitionName, error: err };
|
|
9177
|
+
}
|
|
9178
|
+
return { partitionName, success: true };
|
|
9179
|
+
});
|
|
9180
|
+
await Promise.allSettled(updatePromises);
|
|
9095
9181
|
const id = newData.id || oldData.id;
|
|
9096
|
-
|
|
9182
|
+
const cleanupPromises = Object.entries(partitions).map(async ([partitionName, partition]) => {
|
|
9097
9183
|
const prefix = `resource=${this.name}/partition=${partitionName}`;
|
|
9098
|
-
let allKeys = [];
|
|
9099
9184
|
const [okKeys, errKeys, keys] = await tryFn(() => this.client.getAllKeys({ prefix }));
|
|
9100
|
-
if (okKeys) {
|
|
9101
|
-
|
|
9102
|
-
} else {
|
|
9103
|
-
continue;
|
|
9185
|
+
if (!okKeys) {
|
|
9186
|
+
return;
|
|
9104
9187
|
}
|
|
9105
9188
|
const validKey = this.getPartitionKey({ partitionName, id, data: newData });
|
|
9106
|
-
|
|
9107
|
-
|
|
9108
|
-
|
|
9109
|
-
}
|
|
9189
|
+
const staleKeys = keys.filter((key) => key.endsWith(`/id=${id}`) && key !== validKey);
|
|
9190
|
+
if (staleKeys.length > 0) {
|
|
9191
|
+
const [okDel, errDel] = await tryFn(() => this.client.deleteObjects(staleKeys));
|
|
9110
9192
|
}
|
|
9111
|
-
}
|
|
9193
|
+
});
|
|
9194
|
+
await Promise.allSettled(cleanupPromises);
|
|
9112
9195
|
}
|
|
9113
9196
|
/**
|
|
9114
9197
|
* Handle partition reference update for a specific partition
|
|
@@ -9613,7 +9696,7 @@ class Database extends EventEmitter {
|
|
|
9613
9696
|
this.id = idGenerator(7);
|
|
9614
9697
|
this.version = "1";
|
|
9615
9698
|
this.s3dbVersion = (() => {
|
|
9616
|
-
const [ok, err, version] = tryFn(() => true ? "9.2.
|
|
9699
|
+
const [ok, err, version] = tryFn(() => true ? "9.2.2" : "latest");
|
|
9617
9700
|
return ok ? version : "latest";
|
|
9618
9701
|
})();
|
|
9619
9702
|
this.resources = {};
|