Skip to content

Deprecate PromiseProxyMixin, Enumerable, and Observable (mixins, RFC#… - #21588

Open
NullVoxPopuli wants to merge 5 commits into
mainfrom
nvp/deprecate-mixin-followups
Open

NullVoxPopuli wants to merge 5 commits into
mainfrom
nvp/deprecate-mixin-followups

Conversation

@NullVoxPopuli

@NullVoxPopuli NullVoxPopuli commented Aug 31, 2026 •

Copy link
Copy Markdown
Contributor

Supersedes:

Advancement:

RFC:

Guides:

Best viewed with:
image

Note

Because of the strategy of this deprecation (internal + public extends + deprecate), our tests don't have a lot of the testUnless stuff. We still need the tests because many of these mixins are still used internally. This makes this deprecation a bit different from the other ones due to how entangled mixins our in the codebase

Comment thread packages/@ember/-internals/utils/lib/deprecated-mixin.ts Outdated
@github-actions

github-actions Bot commented Aug 31, 2026 •

Copy link
Copy Markdown
Contributor

📊 Size report

Tarball size — 1.2 MB → 1.2 MB

dist/dev   0.6%↑

File Before (Size / Brotli) After (Size / Brotli)
Total (Includes all files) 2.1 MB / 514.1 kB 0.6%↑2.1 MB / 0.8%↑518.2 kB
Show files (33 files)
File Before (Size / Brotli) After (Size / Brotli)
./packages/@ember/-internals/deprecations/index.js 6.7 kB / 1.7 kB 42%↑9.6 kB / 11%↑1.9 kB
./packages/@ember/-internals/runtime/lib/mixins/-proxy-internal.js — 4 kB / 1.3 kB
./packages/@ember/-internals/runtime/lib/mixins/-proxy.js 4 kB / 1.3 kB -76.7%↓935 B / -69.7%↓408 B
./packages/@ember/-internals/runtime/lib/mixins/action_handler-internal.js — 1.6 kB / 596 B
./packages/@ember/-internals/runtime/lib/mixins/action_handler.js 6.2 kB / 1.7 kB -11.3%↓5.5 kB / -14%↓1.5 kB
./packages/@ember/-internals/runtime/lib/mixins/container_proxy-internal.js — 990 B / 358 B
./packages/@ember/-internals/runtime/lib/mixins/container_proxy.js 1.2 kB / 422 B -10%↓1.1 kB / -7.82%↓389 B
./packages/@ember/-internals/runtime/lib/mixins/registry_proxy-internal.js — 1.6 kB / 541 B
./packages/@ember/-internals/runtime/lib/mixins/registry_proxy.js 1.6 kB / 528 B -48.1%↓806 B / -41.1%↓311 B
./packages/@ember/-internals/runtime/lib/mixins/target_action_support-internal.js — 2.8 kB / 831 B
./packages/@ember/-internals/runtime/lib/mixins/target_action_support.js 4.9 kB / 1.3 kB -77.9%↓1.1 kB / -68.4%↓427 B
./packages/@ember/-internals/views/lib/mixins/action_support-internal.js — 1.7 kB / 630 B
./packages/@ember/-internals/views/lib/mixins/action_support.js 1.5 kB / 585 B -56%↓680 B / -47.9%↓305 B
./packages/@ember/array/index-internal.js — 757 B / 262 B
./packages/@ember/array/index.js 755 B / 270 B 458%↑4.2 kB / 386%↑1.3 kB
./packages/@ember/controller/controller-internal.js — 2.9 kB / 1 kB
./packages/@ember/controller/index.js 4.9 kB / 1.6 kB -41.9%↓2.8 kB / -41.5%↓936 B
./packages/@ember/enumerable/-internal.js — 416 B / 207 B
./packages/@ember/enumerable/index.js 570 B / 281 B 65%↑939 B / 43%↑403 B
./packages/@ember/enumerable/mutable-internal.js — 504 B / 230 B
./packages/@ember/enumerable/mutable.js 623 B / 289 B 57%↑981 B / 38%↑399 B
./packages/@ember/object/mixin-internal.js — 17 kB / 4.5 kB
./packages/@ember/object/mixin.js 610 B / 230 B 342%↑2.7 kB / 253%↑813 B
./packages/@ember/object/observable-internal.js — 4.4 kB / 1.1 kB
./packages/@ember/object/observable.js 6.7 kB / 1.8 kB -54%↓3.1 kB / -42.6%↓1 kB
./packages/shared-chunks/api-{hash}.js 10 kB / 2.1 kB 162%↑26.3 kB / 177%↑5.9 kB
./packages/shared-chunks/computed-BHLSC3Cg.js 34.1 kB / 7.9 kB —
./packages/shared-chunks/evented-{hash}.js 3.3 kB / 855 B 6%↑3.5 kB / 0.1%↑856 B
./packages/shared-chunks/index-internal-DWql8dtG.js — 15.8 kB / 3.8 kB
./packages/shared-chunks/mixin-6JjyWNte.js 18.5 kB / 4.8 kB —
./packages/shared-chunks/mutable-BIeaBqYk.js 18.2 kB / 4.6 kB —
./packages/shared-chunks/properties-zkQ-nuns.js — 34.1 kB / 7.9 kB
./packages/shared-chunks/template-{hash}.js 491 B / 203 B 118%↑1.1 kB / 98%↑401 B

dist/prod   0.7%↑

File Before (Size / Brotli) After (Size / Brotli)
Total (Includes all files) 1.9 MB / 471.1 kB 0.7%↑2 MB / 0.9%↑475.2 kB
Show files (32 files)
File Before (Size / Brotli) After (Size / Brotli)
./packages/@ember/-internals/deprecations/index.js 6.4 kB / 1.6 kB 44%↑9.3 kB / 11%↑1.8 kB
./packages/@ember/-internals/runtime/lib/mixins/-proxy-internal.js — 3.1 kB / 1.1 kB
./packages/@ember/-internals/runtime/lib/mixins/-proxy.js 3.1 kB / 1 kB -69.4%↓935 B / -60.6%↓408 B
./packages/@ember/-internals/runtime/lib/mixins/action_handler-internal.js — 1.1 kB / 460 B
./packages/@ember/-internals/runtime/lib/mixins/action_handler.js 5.7 kB / 1.6 kB -4.18%↓5.5 kB / -6.81%↓1.5 kB
./packages/@ember/-internals/runtime/lib/mixins/container_proxy-internal.js — 990 B / 358 B
./packages/@ember/-internals/runtime/lib/mixins/container_proxy.js 1.2 kB / 424 B -10%↓1.1 kB / -8.25%↓389 B
./packages/@ember/-internals/runtime/lib/mixins/registry_proxy-internal.js — 1.4 kB / 508 B
./packages/@ember/-internals/runtime/lib/mixins/registry_proxy.js 1.3 kB / 473 B -38.4%↓806 B / -34.3%↓311 B
./packages/@ember/-internals/runtime/lib/mixins/target_action_support-internal.js — 2.5 kB / 754 B
./packages/@ember/-internals/runtime/lib/mixins/target_action_support.js 4.6 kB / 1.3 kB -77.4%↓1 kB / -68%↓411 B
./packages/@ember/-internals/views/lib/mixins/action_support-internal.js — 1.1 kB / 477 B
./packages/@ember/-internals/views/lib/mixins/action_support.js 923 B / 403 B -26.3%↓680 B / -24.3%↓305 B
./packages/@ember/array/index-internal.js — 696 B / 247 B
./packages/@ember/array/index.js 694 B / 260 B 507%↑4.2 kB / 399%↑1.3 kB
./packages/@ember/controller/controller-internal.js — 2.9 kB / 1 kB
./packages/@ember/controller/index.js 4.9 kB / 1.6 kB -41.9%↓2.8 kB / -41.4%↓938 B
./packages/@ember/enumerable/-internal.js — 416 B / 207 B
./packages/@ember/enumerable/index.js 570 B / 283 B 65%↑939 B / 42%↑403 B
./packages/@ember/enumerable/mutable-internal.js — 504 B / 230 B
./packages/@ember/enumerable/mutable.js 623 B / 296 B 57%↑981 B / 35%↑399 B
./packages/@ember/object/mixin-internal.js — 15.3 kB / 4 kB
./packages/@ember/object/mixin.js 497 B / 205 B 443%↑2.7 kB / 297%↑813 B
./packages/@ember/object/observable-internal.js — 3.9 kB / 1 kB
./packages/@ember/object/observable.js 6.2 kB / 1.7 kB -50.2%↓3.1 kB / -39.1%↓1 kB
./packages/shared-chunks/api-{hash}.js 8.3 kB / 1.8 kB 210%↑25.8 kB / 226%↑5.8 kB
./packages/shared-chunks/computed-CMpy8sQ2.js 28.2 kB / 6.6 kB —
./packages/shared-chunks/evented-{hash}.js 3.3 kB / 852 B 6%↑3.5 kB / 0.2%↑854 B
./packages/shared-chunks/index-internal-CJvIMpSS.js — 13.9 kB / 3.5 kB
./packages/shared-chunks/mixin-Io_m1M_e.js 16.7 kB / 4.4 kB —
./packages/shared-chunks/mutable-Bohp9fQW.js 16.4 kB / 4.3 kB —
./packages/shared-chunks/properties-DCNROVm7.js — 28.2 kB / 6.6 kB

smoke-tests/v2-app-template/dist   1%↑

File Before (Size / Brotli) After (Size / Brotli)
./assets/main-{hash}.js 320.3 kB / 85.8 kB 0.8%↑322.8 kB / 0.3%↑86.1 kB
./assets/modules-{hash}.js 30.5 kB / 9.5 kB 7%↑32.6 kB / 3%↑9.8 kB
Total (Includes all files) 352.7 kB / 96.2 kB 1%↑357.2 kB / 0.6%↑96.8 kB

smoke-tests/v2-app-hello-world-template/dist   1%↑

File Before (Size / Brotli) After (Size / Brotli)
./assets/main-{hash}.js 126 kB / 35 kB 1%↑127.9 kB / 0.4%↑35.1 kB
Total (Includes all files) 126.3 kB / 35.1 kB 1%↑128.2 kB / 0.4%↑35.2 kB

🤖 This report was automatically generated by wyvox/pkg-size

Comment thread packages/@ember/object/index.ts Outdated
Comment thread packages/@ember/-internals/runtime/tests/mixins/array_test.js
Comment thread packages/@ember/-internals/views/lib/mixins/action_support.ts
@NullVoxPopuli
NullVoxPopuli marked this pull request as draft September 2, 2026 17:38
Comment thread rollup.config.mjs

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't want to expose all these new internal files as importable things, so they got filtered out

@NullVoxPopuli
NullVoxPopuli marked this pull request as ready for review September 3, 2026 14:03
Comment thread packages/@ember/-internals/deprecations/index.ts
Comment thread packages/@ember/-internals/deprecations/index.ts
Comment thread packages/@ember/-internals/runtime/lib/mixins/-proxy-internal.ts Outdated
Comment thread packages/@ember/-internals/runtime/lib/mixins/-proxy.ts
Comment thread packages/@ember/-internals/runtime/lib/mixins/action_handler.ts
Comment thread packages/@ember/-internals/runtime/lib/mixins/container_proxy.ts
Comment thread packages/@ember/-internals/runtime/lib/mixins/registry_proxy.ts
Comment thread packages/@ember/array/index-internal.ts Outdated
Comment thread packages/@ember/enumerable/mutable.ts
Comment thread packages/@ember/object/evented.ts
@public
*/
static create<M extends typeof Mixin>(...args: any[]): InstanceType<M> {
static override create<M extends typeof InternalMixin>(...args: any[]): InstanceType<M> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docs above need @deprecated

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't create also get marked @deprecated?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idk, the whole class is deprecated - so it feels redundant.

@NullVoxPopuli
NullVoxPopuli force-pushed the nvp/deprecate-mixin-followups branch 2 times, most recently from 27efb8f to 8ed880e Compare September 29, 2026 19:29
Comment thread packages/@ember/-internals/deprecations/index.ts Outdated
@NullVoxPopuli
NullVoxPopuli force-pushed the nvp/deprecate-mixin-followups branch from 8ed880e to 831dd86 Compare October 1, 2026 15:58
Comment thread packages/@ember/-internals/glimmer/lib/helpers/each-in.ts
Comment thread packages/@ember/-internals/glimmer/lib/component.ts
Comment thread packages/@ember/-internals/glimmer/tests/integration/helpers/tracked-test.js Outdated
Comment thread packages/@ember/-internals/runtime/tests/mixins/array_test.js Outdated
Comment thread packages/@ember/-internals/runtime/tests/mixins/container_proxy_test.js Outdated
@NullVoxPopuli
NullVoxPopuli force-pushed the nvp/deprecate-mixin-followups branch from 56bd561 to a44ff39 Compare October 1, 2026 17:04
import Controller from '@ember/controller';
import Service, { service } from '@ember/service';
import { _ProxyMixin } from '@ember/-internals/runtime';
import _ProxyMixin from '@ember/-internals/runtime/lib/mixins/-proxy-internal';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this use should also go away when the deprecations are removed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

meaning I think it should get a guard

@deprecated Invoke the corresponding method directly instead.
@param {String} actionName The action to trigger
@param {*} args Arguments to pass on with the action
@private

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one (and a couple of others) were private but are currently until: 8 because they share the TARGET_ACTION_SUPPORT deprecation that previously landed for public API

public mixin emits.

@internal
*/

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the point of the empty internal version?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just using InternalMixin, so the Mixin class doesn't cause a deprecation -- needed until we remove EmeberArray

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tho, perhaps it could be removed entirely with no-effect. I need to look in to that.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I don't think it does anything. It doesn't even maintain any inspecting of hierarchy now that it has a different name

@internal
*/
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
interface InternalMutableEnumerable extends InternalEnumerable {}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, empty internal version?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as Enumerable

const Observable = DeprecatedMixin.create(InternalObservable, {
init() {
this._super(...arguments);
deprecateUntil(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there no docs for the Observable mixin that need to be marked @deprecated? Was it even public?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea its public
image

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm wonder why that's @class

but in that case, it needs an @deprecated

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

@kategengler kategengler left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments. I want to generate the docs tomorrow and check out the result.

NullVoxPopuli and others added 5 commits October 11, 2026 12:52
RFC #1116 deprecates applying Ember's mixins, but Ember's own internals are
built on several of them. Those mixins need to exist twice: an internal copy
that applies silently, and a public copy that emits the deprecation.

This is the mechanical half -- the six mixins under @ember/-internals move to
`-internal` filenames with their contents unchanged, and their importers
follow. The public, deprecating copies are added in the next commit.

Add deprecating public mixin wrappers (RFC #1116 follow-up)

Every mixin Ember applies to its own classes now exists twice: the internal
copy applies silently, and the public copy wraps it and emits the deprecation
from `init`. The public copies keep the API documentation; the internal copies
carry the implementation.

`Mixin` itself gets the same treatment -- `InternalMixin` holds the machinery
and `Mixin.create` is the deprecating subclass -- which lets the
`INTERNAL_MIXIN_CREATE` symbol go away entirely.

Because the two copies are distinct objects, `meta.hasMixin` would no longer
match a public mixin against an object that only ever had the internal copy
applied. `DeprecatedMixin` overrides `detect` to look through to the wrapped
copy, so `EmberArray.detect(someArrayProxy)` keeps working while the
deprecation is live.

Ember's own tests that exercise a mixin's behavior now apply the internal copy,
matching what the framework does; tests that specifically cover the deprecation
keep using the public copy. `EmberObject` already applies the internal
`Observable`, so `observable_test` no longer re-applies the public one on top.

The internal copies are kept out of `renamed-modules` so they are not
advertised as importable module paths.

Move deprecations to 7.5

Set deprecate flags, and update untils
Tests imported the silent `-internal` copies of the deprecated mixins.
Such a test stays after the deprecation is removed, and it keeps the
internal copy in use.

These tests now import the public mixin, expect its deprecation, and
use `testUnless(...isRemoved)`. They go away with the deprecation.

- `EmberArray` in `runtime/tests/mixins/array_test.js`
- `MutableArray` in `glimmer/tests/integration/helpers/tracked-test.js`
- `ContainerProxyMixin` in `container_proxy_test.js`
- `TargetActionSupport` in `target_action_support_test.js`
- `_ProxyMixin` in `ember/tests/service_injection_test.js`

`TestArray#init` in `array_test.js` now calls `super.init`. Without
that call, the deprecation of the mixin does not fire.

Three tests in `array_test.js` do not use the mixin. They moved to
their own module, so they still run after the removal.

`mixin/deprecation_test.js` still imports `InternalMixin`. That test
checks that the internal constructor does not fire the deprecation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A production build runs one assertion for all deprecation
expectations of a test. A development build runs one assertion for
each expectation. Two expectations made `assert.expect` fail in the
production build jobs.

Each test now has one expectation. Its pattern matches the mixin
deprecation and the `triggerAction` deprecation. The `assert.expect`
counts are back to their values on the base branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@NullVoxPopuli
NullVoxPopuli force-pushed the nvp/deprecate-mixin-followups branch from 3ba8803 to 44e5959 Compare October 11, 2026 16:52

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants