Releases: NullVoxPopuli/ember-resources
ember-resources@6.0.0-beta.5
Patch Changes
-
#828
24b540e
Thanks @NullVoxPopuli! - ember-async-data@v1 is out, so since we're just now using it, that can be the minimum version.
NOTE:ember-async-data
's minimum ember-source is 4.8, so while things might work with earlier ember-source's it's not guaranteed. -
#826
50ad1ba
Thanks @NullVoxPopuli! - When using RemoteData, isError should be true when the http status code is >= 400. Resolves #825".
Previously, when you had a JSON response with 404 status code,isError
would be false instead of true. -
#830
0767c08
Thanks @NullVoxPopuli! - Support TS 5.0
ember-resources@6.0.0-beta.4
Minor Changes
- #818
feeb2db
Thanks @NullVoxPopuli! - RemoteData now checks the response's Content-Type header to decide whether to convert to JSON or Text
ember-resources@6.0.0-beta.3
Major Changes
-
#815
54e2b50
Thanks @NullVoxPopuli! - TheRemoteData
resource now has the same state changes and semantics astrackedFunction
.Breaking Changes:
isResolved
is only true when the request succeeds. During migration, you may useisFinished
for previous behavior.
ember-resources@6.0.0-beta.2
Minor Changes
-
#797
18adb86
Thanks @NullVoxPopuli! - Add link() and @link, importable fromember-resources/link
.NOTE: for existing users of
ember-resources
, this addition has no impact on your bundle.Example property usage
import { link } from 'ember-resources/link'; class MyClass { ... } export default class Demo extends Component { // This usage does now allow passing args to `MyClass` @link(MyClass) myInstance; }
Example inline usage
import Component from "@glimmer/component"; import { cached } from "@glimmer/tracking"; import { link } from "ember-resources/link"; export default class Demo extends Component { // To pass args to `MyClass`, you must use this form // NOTE though, that `instance` is linked to the `Demo`s lifecycle. // So if @foo is changing frequently, memory pressure will increase rapidly // until the `Demo` instance is destroyed. // // Resources are a better fit for this use case, as they won't add to memory pressure. @cached get myFunction() { let instance = new MyClass(this.args.foo); return link(instance, this); } }
This abstracts away the following boilerplate:
import { getOwner, setOwner } from "@ember/owner"; import { associateDestroyableChild } from "@ember/destroyable"; class MyClass { /* ... */ } export default class Demo extends Component { @cached get myInstance() { let instance = new MyClass(); associateDestroyableChild(this, instance); let owner = getOwner(this); if (owner) { setOwner(instance, owner); } return instance; } }
ember-resources@5.6.3
Patch Changes
-
#808
34884c2
Thanks @NullVoxPopuli! -trackedTask
must return correct last value.Fixes the issue described at #793
If the task was called multiple times and the last returned value was null or undefined,
then trackedTask will return the previous value instead of the current one.
ember-resources@6.0.0-beta.1
Major Changes
- #785
66cee0e
Thanks @NullVoxPopuli! - The import pathember-resources/util/function-resource
has been removed,
as all the relevent exports have been available fromember-resources
since v5.
Minor Changes
-
#794
8989bbb
Thanks @NullVoxPopuli! - New Utils: UpdateFrequency and FrameRateNOTE: for existing users of
ember-resources
, this addition has no impact on your bundle.FrameRate
Utility that uses requestAnimationFrame to report
how many frames per second the current monitor is
rendering at.The result is rounded to two decimal places.
import { FramRate } from "ember-resources/util/fps"; <template>{{ FrameRate }}</template>;
UpdateFrequency
Utility that will report the frequency of updates to tracked data.
import { UpdateFrequency } from 'ember-resources/util/fps'; export default class Demo extends Component { @tracked someProp; @use updateFrequency = UpdateFrequency(() => this.someProp); <template> {{this.updateFrequency}} </template> }
NOTE: the function passed to UpdateFrequency may not set tracked data.
Patch Changes
-
#806
00e8f2f
Thanks @sergey-zhidkov! -trackedTask
must return correct last value.Fixes the issue described at #793
If the task was called multiple times and the last returned value was null or undefined,
then trackedTask will return the previous value instead of the current one.
ember-resources@6.0.0-beta.0
Major Changes
-
#715
e8155b2
Thanks @NullVoxPopuli! - Drop support for TypeScript < 4.8 in order to support Glint. -
#778
901ae9a
Thanks @NullVoxPopuli! - Themap
utility resource has changed its first type-argument for better inference.The utility already supported inference, so this change should not impact too many folks.
When explicit type-arguments were specified,
class Demo { // previously a = map<Element>(this, { data: () => [ /* ... list of Element(s) ... */ ], map: (element) => { /* some transform */ }, }); // now a = map<Element[]>(this, { data: () => [ /* ... list of Element(s) ... */ ], map: (element) => { /* some transform */ }, }); }
This is advantageous, because with
@tsconfig/ember
, the optionnoUncheckedIndexedAccess
is enabled by default. This is a great strictness / quality option to have enabled,
as arrays in javascript are mutable, and we can't guarantee that they don't change between
index-accesses.However the
map
utility resource explicitly disallows the indicies to get out of sync
with the sourcedata
.But!, with
noUncheckedIndexedAccess
, you can only infer so much before TS goes the safe route,
and makes the returned typeX | undefined
.For example, in these type-tests:
import { map } from "ember-resources/util/map"; import { expectType } from "ts-expect"; const constArray = [1, 2, 3]; b = map(this, { data: () => constArray, map: (element) => { expectType<number>(element); return element; }, }); // index-access here is *safely* `| undefined`, due to `constArray` being mutable. expectType<number | undefined>(b[0]); expectType<number | undefined>(b.values()[0]); // but when we use a const as const array, we define a tuple, // and can correctly infer and return real values via index access const tupleArray = [1, 2, 3] as const; c = map(this, { data: () => tupleArray, map: (element) => { expectType<number>(element); return element; }, }); // No `| undefined` here expectType<number>(c[0]); expectType<number>(c.values()[0]);
-
#779
a471d9b
Thanks @NullVoxPopuli! -trackedFunction
has a new API and thus a major version release is required.Work by @lolmaus
tl;dr: the breaking changes:
- no more manual initial value
isResolved
is only true on successisError
has been renamed toisRejected
isLoading
has been removed as it was redundant
other changes:
trackedFunction
is a wrapper aroundember-async-data
'sTrackedAsyncData
- behavior is otherwise the same
NOTE:
trackedFunction
is an example utility of how to use auto-tracking with function invocation,
and abstract away the various states involved with async behavior. Now that the heavy lifting is done byember-async-data
,
trackedFunction
is now more of an example of how to integrated existing tracked utilities in to resources.
Migration
Previously,
trackedFunction
could take an initial value for its second argument.class Demo { foo = trackedFunction(this, "initial value", async () => { /* ... */ }); }
This has been removed, as initial value can be better maintained and made more explicit
in user-space. For example:class Demo { foo = trackedFunction(this, async () => { /* ... */ }); get value() { return this.foo.value ?? "initial value"; } }
Or, in a template:
Or, in gjs/strict mode:
const withDefault = (value) => value ?? 'initial value'; class Demo extends Component { foo = trackedFunction(this, async () => { /* ... */ }); <template> {{withDefault this.foo.value}} </template> }
Previously, the
isResolved
property wastrue
for succesful and error statesNow,
isResolved
is only true when the function passed totrackedFunction
has succesfully
completed.To have behavior similar to the old behavior, you may want to implement your own
isFinished
getter:class Demo { foo = trackedFunction(this, async () => { /* ... */ }); get isFinished() { return this.foo.isResolved || this.foo.isRejected; } }
Minor Changes
-
#778
f841a98
Thanks @NullVoxPopuli! - Use strictest possible settings with TypeScript so that consumers can't be stricter than this library -
#776
a99793e
Thanks @NullVoxPopuli! - Glint is now supported starting with 1.0.0-beta.3
Patch Changes
- #769
abaad4a
Thanks @GreatWizard! - fix typo in map error message when checking if every datum is an object
ember-resources@5.6.2
Patch Changes
-
#742
dd7234a
Thanks @NullVoxPopuli! - When using theresourceFactory
(blueprint in Starbeam terms),
there was an issue where a returnedresource
would not get torn down when the
surrounding context of theresourceFactory
would get torn down.For example, in this situation,
which has been added as the second example on this blog post,const poll = resourceFactory((fn, interval) => { return resource(({ on }) => { let x = setInterval(fn, interval); on.cleanup(() => clearInterval(x)); }); });
usage would be:
So, when this was in an
if
statement, or in a component or route, or any content that could be torn down,
theon.cleanup
callback would not be called.This fix addresses the issue and the
on.cleanup
callback is now called.NOTE: this approach to using resources is equivelent to this 0-dependency solution to polling:
import Component from "@glimmer/component"; import Helper from "@ember/component/helper"; import type RouterService from "@ember/routing/router-service"; import { service } from "@ember/service"; class Poll extends Helper { compute([fn, interval]: [(...args: unknown[]) => unknown, number]) { let x = setInterval(fn, interval); registerDestructor(this, () => clearInterval(x)); } } export default class Demo extends Component { @service declare router: RouterService; poll = Poll; refreshData = () => this.router.refresh(); }
ember-resources@5.6.1
Patch Changes
-
#684
bd723d1
Thanks @NullVoxPopuli! - Improve contribution resistance by removing semantic-release/commits and switching to
Changesets for managing automatic release.The release automation and human intervention is just the right mix of both
to make everything painless for all parties.This means:
- contributors don't need to "adhere to the commit convention" - which was linted for and had no autofix
- a preview PR will be created so folks can see what all is going in to a release
- releases can be bundled, meaning not every commit going in to
main
needs to be releasable- this allows for simultaneous batches of breaking changes, and would have prevented some early churn in this package's history
- and most importantly, changelogs are meant for humans (not machines), and Changeset allows for human-focused changelogs
I'll be moving all of my addons to Changesets and away from semantic-release.
-
b137837
Thanks @NullVoxPopuli! - TypeScript 4.8 and 4.9 Support added
5.6.0 (2022-11-02)
Features
- trackedFunction: add a retry method (8244049)
5.5.0 (2022-10-27)
Features
- cell: add update method to Cell class (b0ce96c)
5.4.0 (2022-09-10)
Features
- owner is now available to function-based resources (410bbf4)