Skip to main content

Β· 6 min read
Dan Gebhardt

After two years, 28 beta releases, and over 400 commits, Orbit v0.17 is finally ready! πŸŽ‰

Orbit's docs have been updated to reflect all the changes. If you are upgrading from v0.16, the place to start is the "What's new" section.

Some highlights of this release include:

  • New API reference docs β€” At long last, Orbit v0.17 has API docs for all its packages. These docs are generated by TypeDoc from Orbit's typings and code annotations. Although a bit sparse for now, this reference should only improve with time and help from the community.

  • Improved, strict typings throughout β€” By improving the quality of Orbit's TypeScript, we have been able to refactor more confidently, provide better documentation, and make for a better developer experience all around.

  • Extraction of @orbit/records from @orbit/data β€” As part of the push to improve typings, it became clear that @orbit/data contains a number of interfaces and classes that could prove useful for any type of data, not just records. Thus, record-specific types and classes were extracted into a new package: @orbit/records. Apologies for the breaking changes with module imports. We wanted to get this churn out of the way before the semver constraints that will come with v1.0.

  • Multi-expression queries β€” Just as transforms can contain multiple operations, queries can now contain multiple expressions. This allows sources, such as JSONAPISource, to optionally perform these expressions in parallel.

  • Per-expression/operation options β€” Along with the move to multi-expression queries, we've introduced per-expression options. This can be useful if, for instance, you want to specify a different target url per expression. Similarly, transform operations can also each have their own options.

  • Full vs. data-only responses β€” All requests (queries and updates) can now be made with the { fullResponse: true } option to receive responses in the form { data, details, transforms, sources }. data will include the primary data that would be returned without the fullResponse option. details includes response details particular to the source, and sources includes a named map of all the responses from downstream sources that participated in this request. This allows you to access full response documents, inverse operations, etc. from the initial request call point.

  • Deprecation of Pullable and Pushable interfaces β€” Now that responses can include full processing details, everything that was unique to the push and pull methods on source is redundant. The Pullable and Pushable interfaces have been deprecated to focus on the more capable Queryable and Updatable interfaces for making requests.

  • Transform buffers for faster cache processing β€” Record-cache-based sources that interact with browser storage have had performance issues when dealing with large datasets, especially when paired with read/write heavy processors that ensure relationship tracking and correctness. A new paradigm has been developed, the RecordTransformBuffer, that acts as a memory buffer for these operations. For now, using this buffer is opt-in, with the { useBuffer: true } option. You'll be reminded to explicitly set this option to either true or false until you do. Early users are reporting promising results with IndexedDB, such as performance boosts of > 20x with large numbers of operations.

  • New serializers β€” Concepts of serialization have, up until now, been very specific to usage by the JSONAPISource, and particularly the JSONAPISerializer class. This class has been deprecated and replaced with a series of composable serializers all built upon a simple and flexible Serializer interface. This interface, as well as some serializers for primitives (booleans, dates, date-times, etc.) have been published in a new package, @orbit/serializers. And of course, new serializers particular to JSON:API have been added to @orbit/jsonapi.

  • New validators β€” A common source of problems for Orbit developers has been using data that is malformed or doesn't align with a schema's expectations. This can cause confusing errors during processing by a cache or downstream source. To address this problem, we're introducing "validators", which are shipped in a new package @orbit/validators that includes some validators for primitive types. Validators that are record-specific have also been included in @orbit/records. By default, each source will build its own set of validators and use them automatically. You can instead share a common set of validators via the validatorFor settings. And you can opt-out of using validators entirely by configuring your sources with { autoValidate: false }.

  • Record normalizers β€” When building queries and transforms, some scenarios have been more tedious than necessary: identifying records by a key instead of id, for instance, or using a model class from a lib like ember-orbit to reference a record instead of its json identity. A new abstraction has been added to make query and transform builders more flexible: record normalizers. Record normalizers implement the RecordNormalizer interface and convert record identities and/or data into a normalized form. The new base normalizer now allows { type, key, value } to be used anywhere that { type, id } identities can be used, which significantly reduces the annoyance of working with remote keys. Other normalizers,

  • Synchronous change tracking in memory forks β€” Previously, memory source forks behaved precisely like other memory sources: every trackable update applied at the source level (and thus async). Now, the default (but overrideable) behavior is to track changes at the cache level in forks. Thus synchronous changes can be made to a forked cache and then merged back into the base source. This better accomodates the most common use case for forks: editing form data in isolation before merging coalesced changes back to the base.

  • Debug mode β€” A new debug setting has been added to the Orbit global, that toggles between using a more verbose, developer-friendly "debug" mode of Orbit vs. a leaner, more performant production mode. Since debug mode is enabled by default, you'll need to set Orbit.debug = false in order to eliminate deprecation warnings and other debug-friendly messaging.

  • Increased reliance on The Platformβ„’ β€” Orbit's codebase continues to evolve with the web, adopting new ES language and web platform features as they are released. Custom utilities have been gradually deprecated and phased out of the codebase (e.g. isArray -> Array.isArray), new language features such as nullish coalescing and optional chaining have been adopted, and platform features such as crypto.randomUUID have been adopted (with a fallback implementation if unavailable).

These highlights are covered in more depth, including code samples, in the "What's new" section of the main guides.

Thanks for your patience with this release. We expect that v0.18 will not take nearly as long as v0.17 did. In fact, we plan to use this next release primarily to remove deprecated interfaces in preparation for a lean and focused v1.0 release.

Β· One min read
Dan Gebhardt

I'm excited to announce a complete refresh of Orbitjs.com! πŸŽ‰

Our site has been rebuilt using Docusaurus. The source for this site now lives in Orbit's monorepo right alongside the packages that it describes. This will make it easier to update docs along with code, preferably even in the same PRs.

I'm especially excited to announce that we are finally publishing API reference docs, generated with TypeDoc, alongside the Orbit guides. The first API docs available are for the upcoming v0.17, which can be accessed directly here or by choosing from the documentation version selector in the upper right.

While the current API docs are much better than nothing, the prose and examples are pretty thin for most packages. Please be patient as we work to fill out these docs through improved code annotations. Community contributions are encouraged and most welcome! ❀️