I am building something like an ActiveRecord class for documents stored in MongoDB (akin to Mongoose). I have two goals:
Intercept all property setters on a document using a Proxy, and automatically create an update query to be sent to Mongo. I've already found a solution for this problem on SO.
Prevent unnecessary reads from the database. I.e. if a function is performed on a document, and that function only ever sets properties, and doesn't ever use an existing property of the document, then I don't need to read the document from the database, I can directly update it. However, if the function uses any of the document's properties, I'd have to read it from the database first, and only then continue on with the code. Example:
// Don't load the document yet, wait for a property 'read'. const order = new Order({ id: '123abc' }); // Set property. order.destination = 'USA'; // No property 'read', Order class can just directly send a update query to Mongo ({ $set: { destination: 'USA' } }). await order.save();
// Don't load the document yet, wait for a property 'read'. const order = new Order({ id: '123abc' }); // Read 'weight' from the order object/document and then set 'shipmentCost'. // Now that a 'get' operation is performed, Proxy needs to step in and load the document '123abc' from Mongo. // 'weight' will be read from the newly-loaded document. order.shipmentCost = order.weight * 4.5; await order.save();
How would I go about this? It seems pretty trivial: set a 'get' trap on the document object. If it's the first-ever property 'get', load the document from Mongo and cache it. But how do I fit an async operation into a getter?