s3db.js 9.2.1 → 9.3.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/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
- const finalResult = await this.executeHooks("afterInsert", insertedObject);
8008
- this.emit("insert", finalResult);
8009
- return finalResult;
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
- const finalResult = await this.executeHooks("afterUpdate", updatedData);
8239
- this.emit("update", {
8240
- ...updatedData,
8241
- $before: { ...originalData },
8242
- $after: { ...finalResult }
8243
- });
8244
- return finalResult;
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
- await this.executeHooks("afterDelete", objectData);
8290
- return response;
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
- for (const [partitionName, partition] of Object.entries(partitions)) {
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
- await this.client.putObject({
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
- for (const [partitionName, partition] of Object.entries(partitions)) {
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
- for (const [partitionName, partition] of Object.entries(partitions)) {
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
- allKeys = keys;
9106
- } else {
9107
- continue;
9189
+ if (!okKeys) {
9190
+ return;
9108
9191
  }
9109
9192
  const validKey = this.getPartitionKey({ partitionName, id, data: newData });
9110
- for (const key of allKeys) {
9111
- if (key.endsWith(`/id=${id}`) && key !== validKey) {
9112
- const [okDel, errDel] = await tryFn(() => this.client.deleteObject(key));
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.1" : "latest");
9703
+ const [ok, err, version] = tryFn(() => true ? "9.3.0" : "latest");
9621
9704
  return ok ? version : "latest";
9622
9705
  })();
9623
9706
  this.resources = {};