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.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
- const finalResult = await this.executeHooks("afterInsert", insertedObject);
8004
- this.emit("insert", finalResult);
8005
- return finalResult;
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
- const finalResult = await this.executeHooks("afterUpdate", updatedData);
8235
- this.emit("update", {
8236
- ...updatedData,
8237
- $before: { ...originalData },
8238
- $after: { ...finalResult }
8239
- });
8240
- return finalResult;
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
- await this.executeHooks("afterDelete", objectData);
8286
- return response;
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
- for (const [partitionName, partition] of Object.entries(partitions)) {
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
- await this.client.putObject({
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
- for (const [partitionName, partition] of Object.entries(partitions)) {
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
- for (const [partitionName, partition] of Object.entries(partitions)) {
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
- allKeys = keys;
9102
- } else {
9103
- continue;
9185
+ if (!okKeys) {
9186
+ return;
9104
9187
  }
9105
9188
  const validKey = this.getPartitionKey({ partitionName, id, data: newData });
9106
- for (const key of allKeys) {
9107
- if (key.endsWith(`/id=${id}`) && key !== validKey) {
9108
- const [okDel, errDel] = await tryFn(() => this.client.deleteObject(key));
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.1" : "latest");
9699
+ const [ok, err, version] = tryFn(() => true ? "9.2.2" : "latest");
9617
9700
  return ok ? version : "latest";
9618
9701
  })();
9619
9702
  this.resources = {};