Listening for dare requests could be a useful addition
Such as:...
- Record db mutations in a structured format
- Provide awaits during testing for asynchronous modifications to mutate the db before making a request for that data
- Trigger invalidations of caches
... etc.
Approach
For a given instance of dare. Add the following functions
on<eventname: string, callback>: Assign a callback function to a given event
once<eventname: string, callback>: Assign a callback function to a given event, and once run, immediately remove it.
off<eventname: string, callback>: Remove the callback function from given events
trigger<eventname: string, data: Data>: Trigger an event with data - used internally but nonetheless exposed.
Example: Integration tests example, awaiting for the operation to complete before proceeding
const dare = new Dare(options);
const {promise, resolve} = Promise.withResolvers();
dare.on('patch:member', ({request, response, state}) => {
// The users model was patched
console.log('Request data', request);
console.log('Response data', response);
console.log('state', state);
resolve();
});
// Perform an operation, but dont await it... imagine this is deep within another function and is an incidental operation.
dare.patch('member', {id: 1337}, {favouriteQuote: "If you can't be good, be careful"});
// Test it worked by awaiting the Promise
await promise;
Internally this would trigger the callback defined above after dare.patch('users', ...); operation was completed.
Considerations:
- An array
callbackEvents needs to be maintained internally on each instance of Dare
- When
dare.use creates new instances, the trigger function should also look at parent instances and trigger matching callbackEvents too
- Should model handlers be able to update the
state object and have that pass through to callbackEvents?
- Could
this.once be used internally instead of this.after within Model Method Handlers?
- Should we pass through the entire dare instance with the additional response to the Callback?
- What should happen when the request is skipped or the modification does not affect any rows?
- Should Model's be able to also define events? It would make sense to perhaps keep them together.
- Are there any performance impacts of scanning the CallbackEvents[] for effected rows?
- Callback Event Names
- Is the event name
[method]:[model] appropriate?
- Could wild characters be used to match multiple? i.e.
*:[model]
- Match multiple
patch:users, patch:userEmails or patch:users,userEmails
type ModelName = string;
interface CallbackEvent {
name: `${"patch" | "post" | "delete" | "get"}:${ModelName}`
callback: (Dare) => {},
}
Listening for dare requests could be a useful addition
Such as:...
... etc.
Approach
For a given instance of dare. Add the following functions
on<eventname: string, callback>: Assign a callback function to a given eventonce<eventname: string, callback>: Assign a callback function to a given event, and once run, immediately remove it.off<eventname: string, callback>: Remove the callback function from given eventstrigger<eventname: string, data: Data>: Trigger an event with data - used internally but nonetheless exposed.Example: Integration tests example, awaiting for the operation to complete before proceeding
Internally this would trigger the callback defined above after
dare.patch('users', ...);operation was completed.Considerations:
callbackEventsneeds to be maintained internally on each instance of Daredare.usecreates new instances, thetriggerfunction should also look at parent instances and trigger matching callbackEvents toostateobject and have that pass through to callbackEvents?this.oncebe used internally instead ofthis.afterwithin Model Method Handlers?[method]:[model]appropriate?*:[model]patch:users, patch:userEmailsorpatch:users,userEmails