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/dist/s3db.cjs.js +32 -8
- package/dist/s3db.cjs.js.map +1 -1
- package/dist/s3db.es.js +32 -8
- package/dist/s3db.es.js.map +1 -1
- package/package.json +1 -1
- package/src/plugins/eventual-consistency.plugin.js +40 -6
- package/src/resource.class.js +4 -2
package/package.json
CHANGED
|
@@ -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
|
-
|
|
892
|
-
|
|
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
|
package/src/resource.class.js
CHANGED
|
@@ -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.
|
|
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.
|
|
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
|
}
|