You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This topic is open to consider implementation of the Event API, how best to proceed in designing such implementation that will continue to endure through future releases while being supportive of authors of the Vuex ORM ecosystem.
Global Events
As it stands, the @latest release observes selection and mutation hooks. These hooks are triggered on a singleton (the Query class) and accumulated from the models by way of declarative static methods.
The behaviour for event handling will need to change considering Query is no longer a singleton and potentially out-of-scope for such a requirement. However, global hooks still require a singleton for global event listening/broadcasting.
One suggestion being that the database instance, given it is a singleton in instance form and easily accessible, could be a point of listening/emitting. For example:
store.$database.on('query:beforeSelect',handler)
The benefit of this pattern enables event scoping by prefix (in string representation). This is purely for emitting and subscribing to an event. Models can still declare static methods.
Naming Convention
The subject of normalizing or changing the naming convention for these hooks internally are also up for debate. By internally we mean the name of events emitted rather than the method names bound to a model since these model methods do not subscribe to events directly, rather they are declared as reference handlers.
Selection Hooks
The current selection hooks are: beforeSelect, afterWhere, afterOrderBy and afterLimit.
Selection hooks pass a collection of models tappable for mutation to which a query instance is currently processing.
Mutation Hooks
The current mutation hooks are: beforeCreate, afterCreate, beforeUpdate, afterUpdate, beforeDelete and afterDelete.
Mutation hooks pass the model in the current iteration queue for persistence. Should a models handler return false, the model is skipped and not persisted.
Design Limitations
The crux with event handling is that it is stateless therefore a broadcasted event shouldn't be required to read, let alone expect, a response from subscribers – which proves problematic if events such as beforeCreate or beforeSelect may be required to return. The overhead caused by evaluating a response on each model that's listening inclusive of any additional subscribers to the event is cause for concern. In addition, the @latest release already possesses quantitive performance degradation and @next, at the time of writing, has no performance tests in place to verify any improvement on that front. So it's debatable how taxing this may still be.
For that reason, it's worth considering how to proceed with an idiomatic and synchronous Event API. For example, we may well continue to support return values from event handlers, consequently taking the natural hit on performance. Or we decide to cut ties with this approach and leave it down to user-land logic to process data before asking Vuex ORM to persist it.
Ecosystem
The Event API in its current form also works in favour of plugin authors. Not only can the Events API be integrated on objects that extend it, emitting internal events can enable plugin authors to tap into points for plugin logic. This isn't something we necessarily need to give too much thought, since plugin authors will often circumvent default behaviours through monkey-patching, but can grow as required for non-public logic.
Adding to this, plugins can leverage and adapt the Event API for its own use, rather than “bring your own” functionality which further bears weight on an application using assistive plugins.
Discuss.
The text was updated successfully, but these errors were encountered:
We may well continue to support return values from event handlers, consequently taking the natural hit on performance. Or we decide to cut ties with this approach and leave it down to user-land logic to process data before asking Vuex ORM to persist it.
A recursive scenario in this case would be a typical setup with Vuex ORM and Vuex ORM Axios. A user fetches data, transforms it and passes it to Vuex ORM to persist. The decision to ignore persistence could easily be achieved in the Vuex ORM Axios plugin data transformer, or in between fetching, processing and persisting (with or without the axios plugin). Besides, response data that is expected to be dissolved is almost a waste of request & response load and timing.
If return values are of essence for certain events, then we can still achieve this by passing in a curry function that self executes and splice's the model from the array. After all, splice mutates the original array.
Similarly, and this will become evident soon, the Collection API that will be proposed actually has a remove method that accepts a primary key, model instance or a predicate that handles splicing of a collection... So passing in a collection instance and instructing users to use the remove method works in our favour...
If return values are of essence for certain events, then we can still achieve this by passing in a curry function that self executes and splice's the model from the array. After all, splice mutates the original array.
Yeah I also though about this. Mutate the payload directly. It could play nicely with Vue and Vuex since both of them prefer mutating the reactivity state directly rather than returning new object.
Though for select hook, while we could mutate the payload, it would be easier if users can define a hook like this.
This topic is open to consider implementation of the Event API, how best to proceed in designing such implementation that will continue to endure through future releases while being supportive of authors of the Vuex ORM ecosystem.
Global Events
As it stands, the
@latest
release observes selection and mutation hooks. These hooks are triggered on a singleton (theQuery
class) and accumulated from the models by way of declarative static methods.The behaviour for event handling will need to change considering
Query
is no longer a singleton and potentially out-of-scope for such a requirement. However, global hooks still require a singleton for global event listening/broadcasting.One suggestion being that the database instance, given it is a singleton in instance form and easily accessible, could be a point of listening/emitting. For example:
The benefit of this pattern enables event scoping by prefix (in string representation). This is purely for emitting and subscribing to an event. Models can still declare static methods.
Naming Convention
The subject of normalizing or changing the naming convention for these hooks internally are also up for debate. By internally we mean the name of events emitted rather than the method names bound to a model since these model methods do not subscribe to events directly, rather they are declared as reference handlers.
Selection Hooks
The current selection hooks are:
beforeSelect
,afterWhere
,afterOrderBy
andafterLimit
.Selection hooks pass a collection of models tappable for mutation to which a query instance is currently processing.
Mutation Hooks
The current mutation hooks are:
beforeCreate
,afterCreate
,beforeUpdate
,afterUpdate
,beforeDelete
andafterDelete
.Mutation hooks pass the model in the current iteration queue for persistence. Should a models handler return
false
, the model is skipped and not persisted.Design Limitations
The crux with event handling is that it is stateless therefore a broadcasted event shouldn't be required to read, let alone expect, a response from subscribers – which proves problematic if events such as
beforeCreate
orbeforeSelect
may be required to return. The overhead caused by evaluating a response on each model that's listening inclusive of any additional subscribers to the event is cause for concern. In addition, the@latest
release already possesses quantitive performance degradation and@next
, at the time of writing, has no performance tests in place to verify any improvement on that front. So it's debatable how taxing this may still be.For that reason, it's worth considering how to proceed with an idiomatic and synchronous Event API. For example, we may well continue to support return values from event handlers, consequently taking the natural hit on performance. Or we decide to cut ties with this approach and leave it down to user-land logic to process data before asking Vuex ORM to persist it.
Ecosystem
The Event API in its current form also works in favour of plugin authors. Not only can the Events API be integrated on objects that extend it, emitting internal events can enable plugin authors to tap into points for plugin logic. This isn't something we necessarily need to give too much thought, since plugin authors will often circumvent default behaviours through monkey-patching, but can grow as required for non-public logic.
Adding to this, plugins can leverage and adapt the Event API for its own use, rather than “bring your own” functionality which further bears weight on an application using assistive plugins.
Discuss.
The text was updated successfully, but these errors were encountered: