Skip to content
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

fix(deps): update dependency ember-resources to v7 #305

Merged
merged 1 commit into from
Jan 12, 2024

Conversation

renovate[bot]
Copy link
Contributor

@renovate renovate bot commented Jan 11, 2024

Mend Renovate

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
ember-resources ^6.0.0 -> ^7.0.0 age adoption passing confidence

Release Notes

NullVoxPopuli/ember-resources (ember-resources)

v6.4.2

Compare Source

Patch Changes
  • #​1019 d63d7b7 Thanks @​wagenet! - The keepLatest utility previously incorrectly had a | undefined type for the return value.
    That's been removed.

    | undefined is still a valid type if the passed value is possibly | undefined.
    This made the | undefined on keepLatest redundant.

v6.4.1

Compare Source

Patch Changes
  • #​1011 606ba4b Thanks @​NullVoxPopuli! - trackedFunction: Fix timing issue where updating tracked data consumed in trackedFunction would not re-cause the isLoading state to become true again.

    Resolves #​1010

v6.4.0

Compare Source

Minor Changes
  • #​975 1a964f1 Thanks @​NullVoxPopuli! - trackedFunction can now be composed just like regular resources.

    The function body still auto-tracks and will update within consuming resource appropriately.

    Example
    const Person = resourceFactory((maybeIdFn) => {
      return resource(({ use }) => {
        let request = use(
          trackedFunction(async () => {
            let id = typeof maybeIdFn === "function" ? maybeIdFn() : maybeIdFn;
            let response = await fetch(`https://api.github.com/users/${id}`);
            return response.json();
          }),
        );
    
        // `use` returns a ReadonlyCell where `.current`
        // is the State of trackedFunction.
        return () => request.current;
      });
    });

    Usage examples:

    <template>
        {{#let (Person 1) as |request|}}
          {{#if request.isLoading}}
             ... loading ...
          {{/if}}
    
          {{#if request.value}}
    
          {{/if}}
        {{/let}}
    </template>
    An async doubler
    const Doubled = resourceFactory((num: number) => {
      return resource(({ use }) => {
        let doubler = use(trackedFunction(async () => num * 2));
    
        // Since current is the "State" of `trackedFunction`,
        // accessing .value on it means that the overall value of
        // `Doubled` is the eventual return value of the `trackedFunction`
        return () => doubler.current.value;
      });
    });
    
    // Actual code from a test
    class State {
      @&#8203;tracked num = 2;
    }
    
    let state = new State();
    
    setOwner(state, this.owner);
    
    await render(<template><out>{{Doubled state.num}}</out></template>);
    Example with arguments

    Imagine you want to compute the hypotenuse of a triangle,
    but all calculations are asynchronous (maybe the measurements exist on external APIs or something).

    // Actual code from a test
    type NumberThunk = () => number;
    
    const Sqrt = resourceFactory((numFn: NumberThunk) =>
      trackedFunction(async () => {
        let num = numFn();
    
        return Math.sqrt(num);
      }),
    );
    
    const Squared = resourceFactory((numFn: NumberThunk) =>
      trackedFunction(async () => {
        let num = numFn();
    
        return Math.pow(num, 2);
      }),
    );
    
    const Hypotenuse = resourceFactory((aFn: NumberThunk, bFn: NumberThunk) => {
      return resource(({ use }) => {
        const aSquared = use(Squared(aFn));
        const bSquared = use(Squared(bFn));
        const c = use(
          Sqrt(() => {
            return (aSquared.current.value ?? 0) + (bSquared.current.value ?? 0);
          }),
        );
    
        // We use the function return because we want this property chain
        // to be what's lazily evaluated -- in this example, since
        // we want to return the hypotenuse, we don't (atm)
        // care about loading / error state, etc.
        // In real apps, you might care about loading state though!
        return () => c.current.value;
    
        // In situations where you care about forwarding other states,
        // you could do this
        return {
          get value() {
            return c.current.value;
          },
          get isLoading() {
            return (
              a.current.isLoading || b.current.isLoading || c.current.isLoading
            );
          },
        };
      });
    });

v6.3.1

Compare Source

Patch Changes

v6.3.0

Compare Source

Minor Changes
  • #​952 1551b33 Thanks @​NullVoxPopuli! - Introduce resources as modifiers.
    This brings alignment with Starbeam's plans for modifiers as a universal primitive.

    In ember-resources, using modifiers as resources looks like this:

    import { resource } from 'ember-resources';
    import { modifier } from 'ember-resources/modifier';
    
    const wiggle = modifier((element, arg1, arg2, namedArgs) => {
        return resource(({ on }) => {
            let animation = element.animate([
                { transform: `translateX(${arg1}px)` },
                { transform: `translateX(-${arg2}px)` },
            ], {
                duration: 100,
                iterations: Infinity,
            });
    
            on.cleanup(() => animation.cancel());
        });
    });
    
    <template>
        <div {{wiggle 2 5 named="hello"}}>hello</div>
    </template>

    The signature for the modifier here is different from ember-modifier, where positional args and named args are grouped together into an array and object respectively.

    This signature for ember-resource's modifier follows the plain function invocation signature.

    in Starbeam
    import { resource } from '@&#8203;starbeam/universal';
    
    function wiggle(element, arg1, arg2, namedArgs) {
        return resource(({ on }) => {
            let animation = element.animate([
                { transform: `translateX(${arg1}px)` },
                { transform: `translateX(-${arg2}px)` },
            ], {
                duration: 100,
                iterations: Infinity,
            });
    
            on.cleanup(() => animation.cancel());
        });
    }
    
    <template>
        <div {{wiggle 2 5 named="hello"}}>hello</div>
    </template>

v6.2.2

Compare Source

Patch Changes

v6.2.1

Compare Source

Patch Changes
  • #​941 bfc432b Thanks @​NullVoxPopuli! - Fix an issue with a new (not yet used feature) where Resources could directly return a Cell, and it would have its .current method automatically called when resolving the value of a Resource.

    import { resource, cell } from 'ember-resources';
    
    export const Now = resource(({ on }) => {
      const now = cell(Date.now());
      const timer = setInterval(() => now.set(Date.now()));
    
      on.cleanup(() => clearInterval(timer));
    
      return now;
    });
    
    <template>
      It is: <time>{{Now}}</time>
    </template>

v6.2.0

Compare Source

Minor Changes
  • #​936 6246a3c Thanks @​NullVoxPopuli! - The use import from ember-resources now supports an alternate style of usage.
    This is partly to provide consistency across the different kinds of resources (and resource builders), whether or not arguments are provided.

    The motivation from this change comes from trying to better align with Starbeam's composition capabilities, and "define something once, use it anywhere" approach to that composition.

    For example, before, only this was possible:

    import { resource, use } from "ember-resources";
    
    const StuckClock = resource(() => 2);
    
    class MyClass {
      @&#8203;use data = StuckClock;
    }
    
    new MyClass().data === 2;

    That looks a little awkward, because it looks like data is set to a constant.
    In TypeScript, this still worked out, and the type of data would be a number,
    but it still didn't look intuitive.

    Now, we can do this:

    import { resource, use } from "ember-resources";
    
    const StuckClock = resource(() => 2);
    
    class MyClass {
      data = use(this, StuckClock);
    }
    
    new MyClass().data.current === 2;

    The key difference here is that data is now a Reactive<number>, which, like a cell, has a .current property.
    This is a readonly value -- however current can still return a mutable data structure.

    This style of use ends up extending nicely to Resources that take arguments:

    import { tracked } from "@&#8203;glimmer/tracking";
    import { resource, use, resourceFactory } from "ember-resources";
    
    const Clock = resourceFactory((locale) => resource(/* ... */));
    
    class MyClass {
      @&#8203;tracked locale = "en-US";
    
      data = use(
        this,
        Clock(() => this.locale),
      );
    }

    Note

    The old way of using @use as a decorator is still supported, and has no plans of being deprecated.

    Another approach

    I can't recommend this approach for general usage, but it is supported under SemVer (for exploration and feedback).

    import { resource, use } from "ember-resources";
    
    const StuckClock = resource(() => 2);
    
    class MyClass {
      @&#8203;use(StuckClock) declare data: number;
    }
    
    new MyClass().data === 2;

    This should feel familiar as it looks like what we're familiar with when it comes to declaring @tracked properties as well as @services.

    However, this has the same problems as @service -- in TypeScript, it requires you to use declare and specify a type, which may or may not match the actual type of StuckClock.

    Additionally, whenever we want to pass arguments to the resource, like this:

    import { tracked } from '@&#8203;glimmer/tracking';
    import { resource, use } from 'ember-resources';
    
    const Clock = resourceFactory((locale) => resource( /* ... */);
    
    class MyClass {
      @&#8203;tracked locale = 'en-US';
    
      @&#8203;use(Clock(() => this.locale) declare data: number;
    }

    The arrow function passed to Clock would not have the correct this.
    This is confusing, because in every other situation where we use classes,
    the arrow function has the same context as the instance of the class.
    But due to how decorators are configured / transpiled, the this is actually the surrounding context around MyClass, because decorators are statically applied.

    class MyClass {
      @&#8203;tracked locale = 'en-US';
    
      @&#8203;use(Clock( static context here, not instance ) declare data: number;
    }

    So... that's why I want to recommend property = use(this, Foo) by default.

    class MyClass {
      @&#8203;tracked locale = 'en-US';
    
      data = use(this, (Clock( instance access ));
    }

v6.1.1

Compare Source

Patch Changes
  • #​925 e320cf8 Thanks @​NullVoxPopuli! - Fix situation where, when composing with blueprint/factory-creted Resources, the owner was not passed to the tusedd resource.

    Example from the added test
    const Now = resourceFactory((ms = 1000) =>
      resource(({ on }) => {
        let now = cell(nowDate);
        let timer = setInterval(() => now.set(Date.now()), ms);
    
        on.cleanup(() => clearInterval(timer));
    
        return () => now.current;
      })
    );
    
    const Stopwatch = resourceFactory((ms = 500) =>
      resource(({ use }) => {
        let time = use(Now(ms));
    
        return () => format(time);
      })
    );
    
    await render(<template><time>{{Stopwatch 250}}</time></template>);

    The owner is part of the hooks API for resource and an error is thrown when it is undefined - regardless if used.

    const Demo = resource(({ on, use, owner }) => {
      // ...
    });

v6.1.0

Compare Source

Minor Changes
  • #​866 e1e4f66 Thanks @​NullVoxPopuli! - Add the ability to compose function resources.
    This is enabled only for function resources as class-based resources could already compose.

    how function resources compose
    let formatter = new Intl.DateTimeFormat("en-US", {
      hour: "numeric",
      minute: "numeric",
      second: "numeric",
      hour12: false,
    });
    
    let format = (time) => formatter.format(time.current);
    
    // representing the current time.
    // This could be rendered directly as {{Now}}
    // but Date does not serialize nicely for humans (Date.now() is a number)
    const Now = resource(({ on }) => {
      let now = cell(Date.now());
      let timer = setInterval(() => now.set(Date.now()), 1000);
    
      on.cleanup(() => clearInterval(timer));
    
      return () => now.current;
    });
    
    const Clock = resource(({ use }) => {
      let time = use(Now);
    
      return () => format(time);
    });
    
    // Rendered, Clock is always the formatted time
    <template>
      <time>{{ Clock }}</time>
    </template>;
Patch Changes

Configuration

📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 Automerge: Enabled.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR has been generated by Mend Renovate. View repository job log here.

Copy link

changeset-bot bot commented Jan 11, 2024

⚠️ No Changeset found

Latest commit: b539425

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Contributor

Preview URLs

Env: preview
Docs: https://366806c1.ember-toucan-core.pages.dev

@renovate renovate bot merged commit 858f006 into main Jan 12, 2024
14 checks passed
@renovate renovate bot deleted the renovate/ember-resources-7.x branch January 12, 2024 00:10
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.

0 participants