-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EmberData | 5.0 Roadmap #8086
Comments
A potential thing here is to deprecate unstable identifier API signatures. As we've worked through actual implementations this overhead has turned out to be largely unnecessary, at times it even introduces potential error situations (caches doing operations in an unsupported order), and the ergonomics of working with the stable identifier are far better for both caches and the store anyway: especially with typescript. |
Great roadmap! 🏅 Removing EmberObject, observers, etc. sound like a very good idea. Snapshots and/or forks of Ember Data modelsI don't want to pile on additional things to the roadmap. Just mentioning this as more of a background feedback and general thought, rather than something that I think should necessarily be in 5.0. But having this use-case in mind early in the planning, may make it easier to add them in the future, even if it isn't in 5.0. The ability to make snapshots (or forks) of model state (attributes + relationships) and then roll back is something that would make working with forms easier. Basically, a lot of forms have an edit/cancel button, and if you attach a model to the form, make some changes and then press cancel it's nice to have an easy way of rolling it all back. I know there are snapshots internally, exposed to serializers. But they aren't accessible "from the outside". There are also some prior addons:
Today we are using Ember Changeset to handle forms, and are using a bunch of workarounds to buffer changes to relationships. I've also discussed this with @snewcomer in adopted-ember-addons/ember-changeset#551, as something that could also potentially be handled by that addon. Would the ideal place for this be Ember Data or Ember Changeset? I don't know. But maybe it's a primitive that should reside in Ember Data, so I'm mentioning it here. Happy to clarify and explain more about our use-case. There is also a small code example in the aforementioned issue. |
@sandstrom internally it's actually possible at this point to rollback relationships. This capability is not exposed to users because historically rollback did not include that. With the V2 Cache, store-forking becomes something we can (relatively easily) add. Store forking is our intended route for handling all the various encapsulation scenarios where you want to be able to group a set of changes and/or quickly discard a set of records and/or a set of changes. |
Sounds awesome @runspired! |
Added unloadRecord(identifier: StableRecordIdentifier): void {
const cached = this.#peek(identifier);
const storeWrapper = this.#storeWrapper;
graphFor(storeWrapper).unload(identifier);
// effectively clearing these is ensuring that
// we report as `isEmpty` during teardown.
cached.localAttrs = null;
cached.remoteAttrs = null;
cached.inflightAttrs = null;
let relatedIdentifiers = _allRelatedRecordDatas(storeWrapper, identifier);
if (areAllModelsUnloaded(storeWrapper, relatedIdentifiers)) {
for (let i = 0; i < relatedIdentifiers.length; ++i) {
let identifier = relatedIdentifiers[i];
storeWrapper.disconnectRecord(identifier);
}
}
this.#cache.delete(identifier);
this.#destroyedCache.set(identifier, cached);
/*
* The destroy cache is a hack to prevent applications
* from blowing up during teardown. Accessing state
* on a destroyed record is not safe, but historically
* was possible due to a combination of teardown timing
* and retention of a RecordData instance directly on the
* record itself.
*
* Once we have deprecated accessing state on a destroyed
* instance we may remove this.
*/
if (this.#destroyedCache.size === 1) {
schedule('destroy', () => {
setTimeout(() => {
this.#destroyedCache.clear();
});
});
}
} |
And we're done 🥳 |
@runspired Awesome! 💯 Happy Easter! 🐰🥚 |
5.0 Roadmap
Target Date: Nov/Dec 2022
Overview
The EmberData Team intends to release a major version of the library around/during the fall of 2022. This issue tracks the work to be done to prepare for that major. It's a non-comprehensive list and some things will likely be added to it as unknowns are discovered over time.
5.0 will ship with an
ember-data
optimized for Embroider out of the box. This should significantly improve build times for all apps (even traditional ember-cli builds), allow ember-data to be chunked, and bring all of the asset compilation optimizations that ember-cli users currently receive to embroider users. Today embroider users ship 2-3x more compressed ember-data code to production than users of traditional ember-cli. This effort is tracked in #8103This major version will focus on four critical points of evolving the data story for Ember applications: many of these will be items that will need to be individually RFC'd.
There's a lot to unpack in those four work items. Let’s dig in:
Some features can only work in classic mode if we build them using classic APIs. This includes features like decorators which must be built over computed, and base classes (such as Model) which must be built upon EmberObject. Building these APIs in this way introduces unintentional complications that limit what EmberData can do and prevent us from offering better solutions. For instance, the nature of
reopen
andreopenClass
andMixins
are such that even if we were to deprecate classic class syntax, any custom decorators we write for schema information may fall victim to what these methods can do to a Model.Historically, significant portions of internal code, typically the densest and most complex portions, were developed to defend against and manage the consequences of observers, computed chains and "mandatory setter" wreaking havoc by accessing store state before it was finalized. This did not become simpler with Octane, but harder, because EmberData now has to juggle two fundamentally opposed forms of change notification. Bug reports around change notification are the most common reports we receive. Removing support for observers and chains will significantly simplify some portions of the codebase allowing us to offer more advanced feature sets at lower performance costs and with more reliable change notification semantics. It would even allow for some portions of the library to be reimagined to use
tracked
properties directly, something we have to this point been unable to do due to the consequences of observers. While the observer problem was made significantly better with the deprecation and removal of sync-observers in ember 4.x, there's still much more for us to achieve.While Ember is intending to deprecate support for classic, we feel EmberData should make the first move here due to the simple fact that we cannot support classic without building with classic APIs, and were we to not remove this support in advance then the resulting Ember deprecations would be unresolvable for our users.
What does this mean in practice?
A()
on any array or iterable returned by EmberData would be a "no-op" operation.Several RFCs have already begun this work. All promise proxies would be eliminated in favor of awaiting the async value before usage. Promise state flags would be provided via a utility such as the awesome
ember-promise-helpers
library by @fivetanley. We feel such a utility should be given a home core to the ecosystem in a way that all libraries could utilize it, and would likely bring it in as an official package. Promise proxies currently make it nearly impossible to useasync await
within the ember-data codebase when also using typescript and properly typing a method. While we could eventually decide to sometimes provide a custom async value, simply returning promises as the default for async is better for tooling, typescript, and expectations.Adapters and Serializers got us far, but simpler approaches with greater flexibility, maintainability, and customizability have been proved out. Watch for a RequestManager RFC. 5.0 would not itself remove support for adapters and serializers, as we can easily support them as a custom plugin for the new system for some time, but it would move their usage into a "legacy" mode and remove them from the default story.
ember-m3, ember-data-model-fragments, ember-data-changetracker, ember-data-storefront and so many other libraries along the way have each tried to solve how to model more complex data and interactions than what
@ember-data/model
has provided out of the box. ember-m3 was a proving ground that we can do better by default, and it's learnings have led to internal refactoring, new public APIs, and new RFCs to allow us to present data in a whole new approach that fits a larger number of APIs more naturally, is more adept at adapting to new situations, and scales more naturally as applications and teams grow. Critically, these new APIs offer us the chance to offer GraphQL as a default option for users of EmberData. While we are not pivoting away from a strong story for JSON:API users, we want both stories to be equally strong (and even encourage mixing the two, they complement each other well).Action Items
This is a non-comprehensive list that we expect to grow over the next several months as we determine the exact mechanics of achieving the above.
Deprecations
sync
relationships should not be consideredempty
#8816Refactoring
Documentation
Features
remove
operations rfcs#355 [DATA] RecordData Operations rfcs#458ember-data
auto-configures RequestManagerRequest Manager Support
Collection
mode to properly reflectResourceDocument
data
changesCollectionResourceDocument
context.request
in RequestManager before calling nextDeprecation Guides
Other Notes:
lifetimes.isSoftExpired/isHardExpired
data
=>content
Moved to 6.0
The text was updated successfully, but these errors were encountered: