From 2352d083e0ec1a4fb5dc012806287d071faef33a Mon Sep 17 00:00:00 2001 From: Gerald Gayowsky Date: Wed, 14 Aug 2019 13:02:07 -0400 Subject: [PATCH 1/9] Add RFC text --- text/0000-deprecate-evented-mixin.md | 68 ++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 text/0000-deprecate-evented-mixin.md diff --git a/text/0000-deprecate-evented-mixin.md b/text/0000-deprecate-evented-mixin.md new file mode 100644 index 0000000000..45d15330e4 --- /dev/null +++ b/text/0000-deprecate-evented-mixin.md @@ -0,0 +1,68 @@ +- Start Date: 2019-08-14 +- Relevant Team(s): Ember.js +- RFC PR: (after opening the RFC PR, update this with a link to it and update the file name) +- Tracking: (leave this empty) + +# Deprecate Evented Mixin + +## Summary + +Deprecation support for the `Evented` Mixin. + +## Motivation + +Mixins in Ember can only be used when inheriting from an EmberObject, and with the introduction of native javascript classes the syntax to use them looks a little odd. + +``` +class MyClass extends EmberObject.extend(Evented) { } +``` + +Furthermore, the Evented Mixin is just a wrapper around a set of functions exposed from `@ember/object/events`. + +Deprecating the Evented Mixin, should make it easier for applications reduce the dependency on EmberObject and make it easier to switch to native class syntax. + +## Transition Path + +As mentioned in the motivation, the `@ember/objects/events` package already exposes the functionality of the Evented mixin + +There is a one to one mapping for each function in the Evented mixin as listed below: + +On: +`eventedObj.on(eventName, target, method)` -> `addListener(eventedObj, eventName, target, method)` + +One: +`eventedObj.one(eventName, target, method)` -> `addListener(eventedObj, eventName, target, method, true)` + +Off: +`eventedObj.off(eventName, target, method)` -> `removeListener(eventedObj, eventName, target, method)` + +Trigger: +`eventedObj.trigger(eventName, param1, param2, ..., paramN)` -> `sendEvent(eventedObj, eventName, [param1, param2, ..., paramN])` + +Has: +`eventedObj.has(eventName)` -> `hasListeners(eventedObj, eventName)` + +Currently `hasListeners` is not a function that can be imported from `@ember/object/events`. `hasListeners` would need to be exported for this deprecation to be possible. + +To assist with this transition, it should be possible to provide a codemod that updates the application to make use of the events functions/ + +## How We Teach This + +The guides currently make no mention of the Evented mixin. Thus, the best place to teach this would be in the API documentation for the Evented mixin. + +The Evented page could be updated to direct users to make use of the `@ember/object/events` package instead. +For each function in the Evented Mixin (`has`, `off`, `on`, `one`, `trigger`) an example could be shown of how to write the code using the functions exposed in the `@ember/object/events` package, similar to above. + +It should be possible to provide a codemod, to assist with this transition. + +## Drawbacks + +This RFC introduces churn in existing apps that make use of the Evented Mixin. + +## Alternatives + +Do not deprecate the Evented Mixin + +## Unresolved questions + +None From 9f5d63e5fbc5e9b251a55f71b10084dd2882e9bc Mon Sep 17 00:00:00 2001 From: Gerald Gayowsky Date: Wed, 14 Aug 2019 13:09:47 -0400 Subject: [PATCH 2/9] Some more formatting --- text/0000-deprecate-evented-mixin.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/text/0000-deprecate-evented-mixin.md b/text/0000-deprecate-evented-mixin.md index 45d15330e4..1b0da88522 100644 --- a/text/0000-deprecate-evented-mixin.md +++ b/text/0000-deprecate-evented-mixin.md @@ -27,21 +27,20 @@ As mentioned in the motivation, the `@ember/objects/events` package already expo There is a one to one mapping for each function in the Evented mixin as listed below: -On: +* On: `eventedObj.on(eventName, target, method)` -> `addListener(eventedObj, eventName, target, method)` -One: +* One: `eventedObj.one(eventName, target, method)` -> `addListener(eventedObj, eventName, target, method, true)` -Off: +* Off: `eventedObj.off(eventName, target, method)` -> `removeListener(eventedObj, eventName, target, method)` -Trigger: +* Trigger: `eventedObj.trigger(eventName, param1, param2, ..., paramN)` -> `sendEvent(eventedObj, eventName, [param1, param2, ..., paramN])` -Has: -`eventedObj.has(eventName)` -> `hasListeners(eventedObj, eventName)` - +* Has: +`eventedObj.has(eventName)` -> `hasListeners(eventedObj, eventName)` Currently `hasListeners` is not a function that can be imported from `@ember/object/events`. `hasListeners` would need to be exported for this deprecation to be possible. To assist with this transition, it should be possible to provide a codemod that updates the application to make use of the events functions/ @@ -51,7 +50,8 @@ To assist with this transition, it should be possible to provide a codemod that The guides currently make no mention of the Evented mixin. Thus, the best place to teach this would be in the API documentation for the Evented mixin. The Evented page could be updated to direct users to make use of the `@ember/object/events` package instead. -For each function in the Evented Mixin (`has`, `off`, `on`, `one`, `trigger`) an example could be shown of how to write the code using the functions exposed in the `@ember/object/events` package, similar to above. + +For each function in the Evented Mixin (`has`, `off`, `on`, `one`, `trigger`) an example could be shown of how to write the code using the functions exposed in the `@ember/object/events` package (similarly as listed in the transition path section). It should be possible to provide a codemod, to assist with this transition. From 38ac58dd8dcfee12658bd1f633515dc8888929a3 Mon Sep 17 00:00:00 2001 From: Gerald Gayowsky Date: Wed, 14 Aug 2019 14:20:11 -0400 Subject: [PATCH 3/9] Integrate some feedback from the dev-rfc channel --- text/0000-deprecate-evented-mixin.md | 43 +++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/text/0000-deprecate-evented-mixin.md b/text/0000-deprecate-evented-mixin.md index 1b0da88522..27c9311e4e 100644 --- a/text/0000-deprecate-evented-mixin.md +++ b/text/0000-deprecate-evented-mixin.md @@ -1,5 +1,5 @@ - Start Date: 2019-08-14 -- Relevant Team(s): Ember.js +- Relevant Team(s): Ember.js, Learning - RFC PR: (after opening the RFC PR, update this with a link to it and update the file name) - Tracking: (leave this empty) @@ -17,15 +17,15 @@ Mixins in Ember can only be used when inheriting from an EmberObject, and with t class MyClass extends EmberObject.extend(Evented) { } ``` -Furthermore, the Evented Mixin is just a wrapper around a set of functions exposed from `@ember/object/events`. +Furthermore, the Evented Mixin is just a wrapper around a set of functions from the `@ember/object/events` package. Deprecating the Evented Mixin, should make it easier for applications reduce the dependency on EmberObject and make it easier to switch to native class syntax. ## Transition Path -As mentioned in the motivation, the `@ember/objects/events` package already exposes the functionality of the Evented mixin +As mentioned in the motivation, the `@ember/objects/events` package mostly exposes the functionality of the Evented mixin (aside from the method `Evented.has`) -There is a one to one mapping for each function in the Evented mixin as listed below: +There is a straightforward mapping from an Evented mixin method to a function provided by `@ember/object/events` as listed below: * On: `eventedObj.on(eventName, target, method)` -> `addListener(eventedObj, eventName, target, method)` @@ -43,15 +43,44 @@ There is a one to one mapping for each function in the Evented mixin as listed b `eventedObj.has(eventName)` -> `hasListeners(eventedObj, eventName)` Currently `hasListeners` is not a function that can be imported from `@ember/object/events`. `hasListeners` would need to be exported for this deprecation to be possible. -To assist with this transition, it should be possible to provide a codemod that updates the application to make use of the events functions/ +To assist with this transition, it should be possible to provide a codemod that updates the application to make use of the events functions. ## How We Teach This The guides currently make no mention of the Evented mixin. Thus, the best place to teach this would be in the API documentation for the Evented mixin. -The Evented page could be updated to direct users to make use of the `@ember/object/events` package instead. +The Evented class could be marked as deprecated, and the class documentation could provide direction to use the `@ember/object/events` package instead. + +Each function in the Evented Mixin (`has`, `off`, `on`, `one`, `trigger`) could be deprecated. An example of how to modify the Evented method to make use of the corresponding functions exposed in the `@ember/object/events` package would be great. + +For example (from the documetation of the `trigger` method): + +``` +person.on('didEat', function(food) { + console.log('person ate some ' + food); +}); + +person.trigger('didEat', 'broccoli'); + +// outputs: person ate some broccoli +``` + +could be written as + +``` +import { addListener, sendEvent } from '@ember/object/events'; + +... + +addListener(person, 'didEat', function(foo) { + console.log('person ate some ' + food); +}); + +sendEvent(person, 'didEat', ['brocolli']); + +// outputs: person ate some broccoli +``` -For each function in the Evented Mixin (`has`, `off`, `on`, `one`, `trigger`) an example could be shown of how to write the code using the functions exposed in the `@ember/object/events` package (similarly as listed in the transition path section). It should be possible to provide a codemod, to assist with this transition. From 2e19fe28d21d24f5d88ee1b3d99bb109e1561f5d Mon Sep 17 00:00:00 2001 From: Gerald Gayowsky Date: Thu, 15 Aug 2019 08:43:18 -0400 Subject: [PATCH 4/9] Update RFC date --- text/0000-deprecate-evented-mixin.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0000-deprecate-evented-mixin.md b/text/0000-deprecate-evented-mixin.md index 27c9311e4e..fc1f3b7218 100644 --- a/text/0000-deprecate-evented-mixin.md +++ b/text/0000-deprecate-evented-mixin.md @@ -1,4 +1,4 @@ -- Start Date: 2019-08-14 +- Start Date: 2019-08-15 - Relevant Team(s): Ember.js, Learning - RFC PR: (after opening the RFC PR, update this with a link to it and update the file name) - Tracking: (leave this empty) From 6006ea343afdbb4714c483d75bc1a2faa2548019 Mon Sep 17 00:00:00 2001 From: Gerald Gayowsky Date: Thu, 15 Aug 2019 09:12:26 -0400 Subject: [PATCH 5/9] Add RFC PR link --- text/0000-deprecate-evented-mixin.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0000-deprecate-evented-mixin.md b/text/0000-deprecate-evented-mixin.md index fc1f3b7218..19d3e91789 100644 --- a/text/0000-deprecate-evented-mixin.md +++ b/text/0000-deprecate-evented-mixin.md @@ -1,6 +1,6 @@ - Start Date: 2019-08-15 - Relevant Team(s): Ember.js, Learning -- RFC PR: (after opening the RFC PR, update this with a link to it and update the file name) +- RFC PR: https://github.com/emberjs/rfcs/pull/528 - Tracking: (leave this empty) # Deprecate Evented Mixin From e46e9333774934b349277234c15757f8a0c8e53e Mon Sep 17 00:00:00 2001 From: Gerald Gayowsky Date: Fri, 23 Aug 2019 15:06:39 -0400 Subject: [PATCH 6/9] Update the RFC to deprecate all events --- text/0000-deprecate-evented-mixin.md | 167 +++++++++++++++++++++------ 1 file changed, 132 insertions(+), 35 deletions(-) diff --git a/text/0000-deprecate-evented-mixin.md b/text/0000-deprecate-evented-mixin.md index 19d3e91789..a48efd2ccf 100644 --- a/text/0000-deprecate-evented-mixin.md +++ b/text/0000-deprecate-evented-mixin.md @@ -3,59 +3,151 @@ - RFC PR: https://github.com/emberjs/rfcs/pull/528 - Tracking: (leave this empty) -# Deprecate Evented Mixin +# Deprecate Eventing from Ember ## Summary -Deprecation support for the `Evented` Mixin. +Deprecation support for Events within Ember. + +This includes deprcating the `Evented` Mixin, and methods exposed in the `@ember/object/events` and `@ember/object/evented` packages ## Motivation -Mixins in Ember can only be used when inheriting from an EmberObject, and with the introduction of native javascript classes the syntax to use them looks a little odd. +Eventing is something that is no longer core to Ember, as eventing is no longer used internally after changes from all the work on Octane. + +One pillar of the Ember 2019-2020 roadmap is to "Continue Simplifying Ember". This deprecation aligns with that pillar as deprecating eventing will reduce the surface area of Ember and ensure that Ember is not maintaining a feature that is available and stable in several other libraries. + +## Transition Path + +If a developer still wishes to use the eventing pattern, the recommendation is to use a third-party library. + +There are several eventing libraries available which are stable and well supported. Some examples include, but are not limited to: +* events (https://www.npmjs.com/package/events) +* eventemitter3 (https://www.npmjs.com/package/eventemitter3) +* event-kit (https://www.npmjs.com/package/event-kit) + +Any objects that currently make use eventing pattern will need to create an instance of an emitter and use that emitter instance to subscribe to and emit events. + +For example this code which makes use of the Evented mixin: + +``` +import Evented, { on } from `@ember/object/evented'; +const EventedObject = EmberObject.extend(Evented, { + eventHandler: on('outputMessage', function() { + console.log('Outputting message from handler inside object'); + }) +}); +const eventedObj = EventedObject.create({}) + +const handler = (params1, param2) => { console.log(`Let's ${param1} ${param2}!`); }; +eventedObj.on('outputMessage', handler); +eventedObj.trigger('outputMessage', 'Deprecate', 'Events'); +/* console log + * Outputting message from handler inside object + * Let's Deprecate Events! + */ +eventedObj.off('outputMessage', handler) ``` -class MyClass extends EmberObject.extend(Evented) { } + +and this functionally equivalent code which makes use of the methods from the `@ember/object/events` package: + ``` +import { addListener, removeListener, sendEvent } from `@ember/object/events; -Furthermore, the Evented Mixin is just a wrapper around a set of functions from the `@ember/object/events` package. +const EventedObject = EmberObject.extend({ + init() { + addListener(this, 'outputMessage', this, 'eventHandler'); + }, -Deprecating the Evented Mixin, should make it easier for applications reduce the dependency on EmberObject and make it easier to switch to native class syntax. + eventHandler() { + console.log('Outputting message from handler inside object'); + } +}); +const eventedObj = EventedObject.create({}); + +const handler = () => { console.log('Outputting message from handler outside object'); }; +addListener(eventedObj, 'outputMessage', handler); +sendEvent(eventedObj, 'outputMessage', ['Deprecate', 'Events']); +/* console log + * Outputting message from handler inside object + * Let's Deprecate Events! + */ +removeListener(eventedObj, 'outputMessage', handler); +``` -## Transition Path +can be rewritten using the third-party library `eventemitter3` as such + +``` +import EventEmitter from 'eventemitter3'; -As mentioned in the motivation, the `@ember/objects/events` package mostly exposes the functionality of the Evented mixin (aside from the method `Evented.has`) +const EventedObject = EmberObject.extend({ + init() { + this.emitter = new EventEmitter(); + this.emitter.on('outputMessage', this.eventHandler, this); + }, -There is a straightforward mapping from an Evented mixin method to a function provided by `@ember/object/events` as listed below: + eventHandler() { + console.log('Outputting message from handler inside object'); + } +}); -* On: -`eventedObj.on(eventName, target, method)` -> `addListener(eventedObj, eventName, target, method)` +const eventedObj = EventedObject.create({}); +const handler = (params1, param2) => { console.log(`Let's ${param1} ${param2}!`); }; +eventedObj.emitter.on('outputMessage', handler); +eventedObj.emitter.emit('outputMessage', 'Deprecate', 'Events'); +/* console log + * Outputting message from handler inside object + * Let's Deprecate Events! + */ +eventedObj.emitter.off('outputMessage', handler); +``` -* One: -`eventedObj.one(eventName, target, method)` -> `addListener(eventedObj, eventName, target, method, true)` +To be more specific each Evented mixin method and each function exported by `@ember/object/events` has a straightforward mapping to a method in the `eventemitter3` library as follows: -* Off: -`eventedObj.off(eventName, target, method)` -> `removeListener(eventedObj, eventName, target, method)` +* on/addListener: +`eventedObj.on(eventName, target, method)` OR `addListener(eventedObj, eventName, target, method)` OR `handler: on(eventName, method)` corresponds to +``` +eventedObj.emitter.on(eventName, method, target) +``` -* Trigger: -`eventedObj.trigger(eventName, param1, param2, ..., paramN)` -> `sendEvent(eventedObj, eventName, [param1, param2, ..., paramN])` +* one/addListener: +`eventedObj.one(eventName, target, method)` or `addListener(eventedObj, eventName, target, method, true)` corresponds to +``` +eventedObj.emitter.once(eventName, method, target); +``` + +* off/removeListener: +`eventedObj.off(eventName, target, method)` or `removeListener(eventedObj, eventName, target, method)` corresponds to +``` +eventedObj.emitter.off(eventName, method, target); +``` -* Has: -`eventedObj.has(eventName)` -> `hasListeners(eventedObj, eventName)` -Currently `hasListeners` is not a function that can be imported from `@ember/object/events`. `hasListeners` would need to be exported for this deprecation to be possible. +* trigger/sendEvent: +`eventedObj.trigger(eventName, param1, param2, ..., paramN)` or `sendEvent(eventedObj, eventName, [param1, param2, ..., paramN])` corresponds to +``` +eventedObj.emitter.emit(eventName, param1, param2, ..., paramN); +``` -To assist with this transition, it should be possible to provide a codemod that updates the application to make use of the events functions. +* has: +`eventedObj.has(eventName)` would correspond to +``` +eventedObj.emitter.listenerCount(eventName) > 0 +``` ## How We Teach This -The guides currently make no mention of the Evented mixin. Thus, the best place to teach this would be in the API documentation for the Evented mixin. - -The Evented class could be marked as deprecated, and the class documentation could provide direction to use the `@ember/object/events` package instead. +The guides currently make no mention of the Evented mixin or the methods exposed in `@ember/objects/events`. Thus, the best place to teach this would be in the API documentation. -Each function in the Evented Mixin (`has`, `off`, `on`, `one`, `trigger`) could be deprecated. An example of how to modify the Evented method to make use of the corresponding functions exposed in the `@ember/object/events` package would be great. +The Evented Mixin and each function in the Evented Mixin (`has`, `off`, `on`, `one`, `trigger`) would be marked as deprecated and the mixin/function documentation could point to this RFC or explicitly include an example of how to make use of a third-party library instead. +Similarly, each function exported from `@ember/object/events` could be deprecated and include an example of how to make use of a third-party library. For example (from the documetation of the `trigger` method): ``` +const Person = EmberObject.extend(Evented); +const person = PersonCreate(); + person.on('didEat', function(food) { console.log('person ate some ' + food); }); @@ -68,30 +160,35 @@ person.trigger('didEat', 'broccoli'); could be written as ``` -import { addListener, sendEvent } from '@ember/object/events'; +import EventEmitter from 'event'; -... +const Person = EmberObject.extend({ + init() { + this._super(...arguments); + this.emitter = new EventEmitter() + } +} -addListener(person, 'didEat', function(foo) { +person.emitter.on('didEat', function(foo) { console.log('person ate some ' + food); }); -sendEvent(person, 'didEat', ['brocolli']); +person.emitter.emit('didEat', 'brocolli'); // outputs: person ate some broccoli ``` - -It should be possible to provide a codemod, to assist with this transition. - ## Drawbacks -This RFC introduces churn in existing apps that make use of the Evented Mixin. +This RFC introduces churn in existing apps that make use of the Evented Mixin and Events. + +Due to transitioning away from an Ember package and using a third-party library of the developers choice, this seems like it will be difficult / impossible to codemod and be a very manual process. ## Alternatives -Do not deprecate the Evented Mixin +* Do not deprecate Ember Events +* Deprecate only the `@ember/object/evented` package and Evented Mixin, and keep the `@ember/object/events` package ## Unresolved questions -None +Can this process be somwhat automated by providing a codemod? From 117fc1b3818e2a28107a49054b892708136acac7 Mon Sep 17 00:00:00 2001 From: Gerald Gayowsky Date: Fri, 30 Aug 2019 09:58:58 -0400 Subject: [PATCH 7/9] Update text/0000-deprecate-evented-mixin.md Co-Authored-By: Ricardo Mendes --- text/0000-deprecate-evented-mixin.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0000-deprecate-evented-mixin.md b/text/0000-deprecate-evented-mixin.md index a48efd2ccf..058546c172 100644 --- a/text/0000-deprecate-evented-mixin.md +++ b/text/0000-deprecate-evented-mixin.md @@ -191,4 +191,4 @@ Due to transitioning away from an Ember package and using a third-party library ## Unresolved questions -Can this process be somwhat automated by providing a codemod? +Can this process be somewhat automated by providing a codemod? From 37fa87baf260885da0821fd2ccc17ef1ad17803d Mon Sep 17 00:00:00 2001 From: Gerald Gayowsky Date: Fri, 30 Aug 2019 09:59:05 -0400 Subject: [PATCH 8/9] Update text/0000-deprecate-evented-mixin.md Co-Authored-By: Ricardo Mendes --- text/0000-deprecate-evented-mixin.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0000-deprecate-evented-mixin.md b/text/0000-deprecate-evented-mixin.md index 058546c172..44d59218de 100644 --- a/text/0000-deprecate-evented-mixin.md +++ b/text/0000-deprecate-evented-mixin.md @@ -13,7 +13,7 @@ This includes deprcating the `Evented` Mixin, and methods exposed in the `@ember ## Motivation -Eventing is something that is no longer core to Ember, as eventing is no longer used internally after changes from all the work on Octane. +Eventing is something that is no longer core to Ember, and is no longer used internally after changes from all the work on Octane. One pillar of the Ember 2019-2020 roadmap is to "Continue Simplifying Ember". This deprecation aligns with that pillar as deprecating eventing will reduce the surface area of Ember and ensure that Ember is not maintaining a feature that is available and stable in several other libraries. From 1b49aeba35713d2bab45d3be8492f5919f76eb1f Mon Sep 17 00:00:00 2001 From: Gerald Gayowsky Date: Fri, 30 Aug 2019 09:59:11 -0400 Subject: [PATCH 9/9] Update text/0000-deprecate-evented-mixin.md Co-Authored-By: Ricardo Mendes --- text/0000-deprecate-evented-mixin.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0000-deprecate-evented-mixin.md b/text/0000-deprecate-evented-mixin.md index 44d59218de..0bce479c69 100644 --- a/text/0000-deprecate-evented-mixin.md +++ b/text/0000-deprecate-evented-mixin.md @@ -9,7 +9,7 @@ Deprecation support for Events within Ember. -This includes deprcating the `Evented` Mixin, and methods exposed in the `@ember/object/events` and `@ember/object/evented` packages +This includes deprecating the `Evented` Mixin, and methods exposed in the `@ember/object/events` and `@ember/object/evented` packages. ## Motivation