s3db.js 10.0.8 → 10.0.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "s3db.js",
3
- "version": "10.0.8",
3
+ "version": "10.0.9",
4
4
  "description": "Use AWS S3, the world's most reliable document storage, as a database with this ORM.",
5
5
  "main": "dist/s3db.cjs.js",
6
6
  "module": "dist/s3db.es.js",
@@ -886,12 +886,46 @@ export class EventualConsistencyPlugin extends Plugin {
886
886
  );
887
887
  }
888
888
 
889
- // Update the original record
890
- const [updateOk, updateErr] = await tryFn(() =>
891
- this.targetResource.update(originalId, {
892
- [this.config.field]: consolidatedValue
893
- })
894
- );
889
+ // Update the original record (upsert if it doesn't exist)
890
+ const [updateOk, updateErr] = await tryFn(async () => {
891
+ // Try update first
892
+ const [ok, err] = await tryFn(() =>
893
+ this.targetResource.update(originalId, {
894
+ [this.config.field]: consolidatedValue
895
+ })
896
+ );
897
+
898
+ // If update failed because record doesn't exist, try insert
899
+ if (!ok && (err?.code === 'NoSuchKey' || err?.code === 'NotFound')) {
900
+ if (this.config.verbose) {
901
+ console.log(
902
+ `[EventualConsistency] ${this.config.resource}.${this.config.field} - ` +
903
+ `Record ${originalId} doesn't exist, creating with ${this.config.field}=${consolidatedValue}`
904
+ );
905
+ }
906
+
907
+ // Create minimal record with just the field value
908
+ return await this.targetResource.insert({
909
+ id: originalId,
910
+ [this.config.field]: consolidatedValue
911
+ });
912
+ }
913
+
914
+ if (!ok) {
915
+ throw err;
916
+ }
917
+
918
+ return ok;
919
+ });
920
+
921
+ if (!updateOk) {
922
+ console.error(
923
+ `[EventualConsistency] ${this.config.resource}.${this.config.field} - ` +
924
+ `FAILED to update ${originalId}: ${updateErr?.message || updateErr}`,
925
+ { error: updateErr, consolidatedValue, currentValue }
926
+ );
927
+ throw updateErr;
928
+ }
895
929
 
896
930
  if (updateOk) {
897
931
  // Mark transactions as applied (skip synthetic ones) - use PromisePool for controlled concurrency
@@ -223,12 +223,14 @@ export class Resource extends AsyncEventEmitter {
223
223
  // Multiple listeners for this event
224
224
  for (const listener of listeners) {
225
225
  if (typeof listener === 'function') {
226
- this.on(eventName, listener);
226
+ // Bind listener to resource context so it has access to this.database
227
+ this.on(eventName, listener.bind(this));
227
228
  }
228
229
  }
229
230
  } else if (typeof listeners === 'function') {
230
231
  // Single listener for this event
231
- this.on(eventName, listeners);
232
+ // Bind listener to resource context so it has access to this.database
233
+ this.on(eventName, listeners.bind(this));
232
234
  }
233
235
  }
234
236
  }