Giter Club home page Giter Club logo

ember-deep-tracked's Introduction

ember-deep-tracked

npm version CI

Deep tracking using proxies for complex objects for when you want everything to be reactive, at the cost of performance.

This is not recommended for performance-sensitive situations such as rendering a table from a large data set where updates to that data set are frequent. Even without updates, deeply tracking will increase initial-render time.

Compatibility

  • Ember.js v3.25+
  • TypeScript v4.5+
  • ember-auto-import v2+
  • Proxy support

Installation

npm install ember-deep-tracked
# or
yarn add ember-deep-tracked
# or
pnpm add ember-deep-tracked
# or
ember install ember-deep-tracked

Usage

import { tracked } from 'ember-deep-tracked';

class Foo {
  @tracked obj = { bar: 2 };
}

or in a component:

import { tracked } from 'ember-deep-tracked';
import Component from '@glimmer/component';

export default class Foo extends Component {
  @tracked obj = { bar: 2 };
}
{{this.obj.bar}} <- automatically updates when "obj.bar" changes

using this decorator form will track the reference, like tracked from @glimmer/tracking does, and then also deeply tracks the value.

the entire object and any sub object can be swapped with other objects and they'll be automatically tracked.

import { deepTracked } from 'ember-deep-tracked';

is also available, and is an alias of tracked

Contributing

See the Contributing guide for details.

License

This project is licensed under the MIT License.

ember-deep-tracked's People

Contributors

amk221 avatar gossi avatar jimschofield avatar nullvoxpopuli avatar renovate-bot avatar renovate[bot] avatar semantic-release-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

ember-deep-tracked's Issues

Does it support deduped tracking?

Hey, this looks pretty close to what I need, but I am not sure how it would deal with an immutable object, that is replaced for every change.

To give you an example: a (non-Ember) library is returning an immutable object, that drives the UI state. On every change of the application state, that library is asked to return a new object, which is then assigned to a tracked property, to update the UI. That even works without any "deep" tracking, just plain @tracked, as the whole object is replaced. But this causes all parts of the UI to rerender, even those where the actual value didn't change.

Some pseudo code to illustrate the example:

class GlobalStateService extends Service {
  @tracked globalState = { foo: 0, bar: 0};

  @action
  updateFoo() {
    // instead of mutating the foo property, we simulate the immutable behavior by assigned a new POJO
    this.globalState = { ...this.globalState, foo: this.globalState.foo + 1 };
  }
}

When I consume both globalState.foo and globalState.bar in a template, after calling updateFoo() both would re-render, as the whole globalState has been updated. But what I would like to see is that only the parts depending on globalState.foo re-render, but those depending on globalState.bar don't, as the actual value didn't change.

That's kinda the behavior of @dedupeTracked, but with deep tracking.

I assume that's not what ember-deep-tracked currently does, right? Do you think it would be feasible to support that?

Issues with accessing the store from a deep-tracked object

There is an issue with accessing the ember-data store from an object if that object is being kept in a deep-tracked array. A minimal example to reproduce the behavior can be found here: https://github.com/LeopoldHock/ember-deep-tracked-test

The core issue

Say we have a custom object that can make use of service injection by having its owner set in the constructor method.

export default class Car {
    @service store;

    constructor(owner) {
        setOwner(this, owner);
    }
}

And after instantiation, that object will be put into a nested deep-tracked context.

// e.g. in a service
import { tracked } from 'ember-deep-tracked';
@tracked data = {
    cars = []
}
let car = new Car(this);
data.cars.push(car);

And at some point, that object attempts to access the injected store to find a record.

// in car.js
let someRecord = this.store.peekRecord("my-collection", "some-key");

someRecord will be null, while requesting the same record in a different contect (e.g. a service) will return the record.
The issue does not occur in a non-tracked context (e.g. by simply removing @Tracked).

Feature: allow partial proxying

is there a way to just replace a part of the model with a tracked proxy ?

Like if i have
a.b = { x: "xx", y: "yy" }
and do
a.b = tracked(a.b) to replace instance of the sub-object with a proxy?

Error if object is undefined

With native @Tracked you can defined your tracked properties with no default values.

@tracked foo;
@tracked bar;

Even though as objects ember won't track these, the user is used to write it this way. When you start to use this addon, without adding = {} you get the following error

image

vendor.js:172922 Uncaught (in promise) TypeError: initializer is not a function

desc.get = function get() {
      if (!value) {
        value = deepTracked(initializer());
      }

is where the error is.

I think if you're using this addon, and you're trying to track the properties of an object, perhaps it could default to empty object? Or fail with a warning instead.

Breaks when used with `array.includes`

Demo repo:

amk221/-ember-deep-tracked-include-issue@b31a087

Error output:

Uncaught TypeError: Cannot use 'in' operator to search for 'Symbol(TARGET)' in 2
    at unwrap (index.js:14:1060)
    at Array.map (<anonymous>)
    at Proxy.fn (index.js:11:474)
    at get hasFoo2 [as hasFoo2] (application.js:22:1)
    at getPossibleMandatoryProxyValue (index.js:1699:1)
    at _getProp (index.js:1723:1)
    at reference.js:175:1
    at reference.js:136:1
    at track (validator.js:635:1)
    at valueForRef (reference.js:135:1)
unwrap @ index.js:14
fn @ index.js:11
get hasFoo2 @ application.js:22
getPossibleMandatoryProxyValue @ index.js:1699
_getProp @ index.js:1723
(anonymous) @ reference.js:175
(anonymous) @ reference.js:136
track @ validator.js:635
valueForRef @ reference.js:135
(anonymous) @ runtime.js:3269
evaluate @ runtime.js:1052
evaluateSyscall @ runtime.js:4214
evaluateInner @ runtime.js:4185
evaluateOuter @ runtime.js:4178
next @ runtime.js:5009
_execute @ runtime.js:4996
execute @ runtime.js:4971
(anonymous) @ runtime.js:5054
runInTrackingTransaction @ validator.js:138
sync @ runtime.js:5054
(anonymous) @ index.js:4726
(anonymous) @ index.js:4695
(anonymous) @ index.js:4988
inTransaction @ runtime.js:4090
_renderRoots @ index.js:4970
_renderRootsTransaction @ index.js:5014
_renderRoot @ index.js:4959
_appendDefinition @ index.js:4884
appendOutletView @ index.js:4874
invoke @ backburner.js:284
flush @ backburner.js:197
flush @ backburner.js:360
_end @ backburner.js:801
end @ backburner.js:592
_run @ backburner.js:845
run @ backburner.js:627
run @ index.js:74
callback @ index.js:355

The automated release is failing 🚨

🚨 The automated release from the main branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you can benefit from your bug fixes and new features again.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can fix this πŸ’ͺ.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the main branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here are some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Good luck with your project ✨

Your semantic-release bot πŸ“¦πŸš€

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Error type: Cannot find preset's package (github>whitesource/merge-confidence:beta)

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Rate-Limited

These updates are currently rate-limited. Click on a checkbox below to force their creation now.

  • chore(deps): update devdependencies (major) (@commitlint/cli, @commitlint/config-conventional, @ember/test-helpers, @embroider/addon-dev, @embroider/test-setup, @nullvoxpopuli/eslint-configs, @rollup/plugin-babel, @tsconfig/ember, @typescript-eslint/eslint-plugin, @typescript-eslint/parser, concurrently, ember-cached-decorator-polyfill, ember-cli, ember-cli-app-version, ember-cli-babel, ember-data, ember-page-title, ember-qunit, ember-resolver, ember-source, ember-template-lint, ember-try, ember-welcome-page, eslint, eslint-config-prettier, eslint-plugin-ember, eslint-plugin-prettier, eslint-plugin-qunit, eslint-plugin-simple-import-sort, prettier, qunit-dom, rollup, semantic-release, typescript)
  • chore(deps): update github artifact actions to v4 (major) (actions/download-artifact, actions/upload-artifact)
  • chore(deps): update node.js to v20
  • chore(deps): update pnpm/action-setup action to v3
  • πŸ” Create all rate-limited PRs at once πŸ”

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/ci.yml
  • actions/checkout v3
  • volta-cli/action v3
  • actions/cache v3
  • pnpm/action-setup v2.2.4
  • actions/checkout v3
  • volta-cli/action v3
  • actions/cache v3
  • pnpm/action-setup v2.2.4
  • actions/checkout v3
  • volta-cli/action v3
  • wagoid/commitlint-github-action v5.0.2
  • actions/checkout v3
  • volta-cli/action v3
  • actions/cache v3
  • pnpm/action-setup v2.2.4
  • actions/upload-artifact v3
  • actions/checkout v3
  • volta-cli/action v3
  • actions/cache v3
  • pnpm/action-setup v2.2.4
  • actions/download-artifact v3
  • actions/checkout v3
  • volta-cli/action v3
  • actions/cache v3
  • pnpm/action-setup v2.2.4
  • actions/download-artifact v3
  • actions/checkout v3
  • volta-cli/action v3
  • actions/cache v3
  • pnpm/action-setup v2.2.4
  • actions/download-artifact v3
  • actions/checkout v3
  • volta-cli/action v3
  • actions/cache v3
  • pnpm/action-setup v2.2.4
  • actions/download-artifact v3
  • actions/checkout v3
  • volta-cli/action v3
  • actions/cache v3
  • pnpm/action-setup v2.2.4
  • actions/download-artifact v3
npm
ember-deep-tracked/package.json
  • @babel/core ^7.17.0
  • @babel/eslint-parser ^7.18.2
  • @babel/plugin-proposal-class-properties ^7.16.7
  • @babel/plugin-proposal-decorators ^7.17.0
  • @babel/plugin-syntax-decorators ^7.17.0
  • @babel/plugin-transform-typescript 7.20.2
  • @babel/preset-typescript 7.18.6
  • @embroider/addon-dev ^1.0.0
  • @nullvoxpopuli/eslint-configs ^2.2.40
  • @rollup/plugin-babel ^5.3.0
  • @semantic-release/changelog ^6.0.1
  • @semantic-release/git ^10.0.1
  • @tsconfig/ember ^1.0.1
  • ember-template-lint ^4.0.0
  • eslint ^8.0.0
  • eslint-config-prettier ^8.3.0
  • eslint-plugin-ember ^11.0.0
  • eslint-plugin-node ^11.1.0
  • eslint-plugin-prettier ^4.0.0
  • npm-run-all ^4.1.5
  • prettier ^2.7.1
  • rollup ^3.0.0
  • rollup-plugin-ts 3.0.2
  • semantic-release ^19.0.2
  • typescript 4.8.4
package.json
  • concurrently ^7.2.1
  • prettier ^2.5.1
  • node 16.18.1
  • yarn 1.22.19
  • npm 8.19.4
test-app/package.json
  • @babel/core ^7.17.0
  • @commitlint/cli ^17.0.3
  • @commitlint/config-conventional ^17.0.3
  • @ember/optional-features ^2.0.0
  • @ember/test-helpers ^2.8.1
  • @embroider/test-setup 1.8.3
  • @glimmer/component ^1.1.2
  • @glimmer/tracking ^1.1.2
  • @nullvoxpopuli/eslint-configs ^2.2.49
  • @semantic-release/changelog ^6.0.1
  • @semantic-release/git ^10.0.1
  • @types/ember ^4.0.1
  • @types/ember-data ^4.4.0
  • @types/ember-data__adapter ^4.0.0
  • @types/ember-data__model ^4.0.0
  • @types/ember-data__serializer ^4.0.0
  • @types/ember-data__store ^4.0.0
  • @types/ember-qunit ^5.0.0
  • @types/ember-resolver ^5.0.11
  • @types/ember__application ^4.0.1
  • @types/ember__array ^4.0.1
  • @types/ember__component ^4.0.8
  • @types/ember__controller ^4.0.0
  • @types/ember__debug ^4.0.1
  • @types/ember__engine ^4.0.1
  • @types/ember__error ^4.0.0
  • @types/ember__object ^4.0.3
  • @types/ember__polyfills ^4.0.0
  • @types/ember__routing ^4.0.9
  • @types/ember__runloop ^4.0.1
  • @types/ember__service ^4.0.0
  • @types/ember__string ^3.0.9
  • @types/ember__template ^4.0.0
  • @types/ember__test ^4.0.0
  • @types/ember__test-helpers ^2.8.1
  • @types/ember__utils ^4.0.0
  • @types/htmlbars-inline-precompile ^3.0.0
  • @types/qunit ^2.19.2
  • @types/rsvp ^4.0.4
  • @typescript-eslint/eslint-plugin ^5.30.7
  • @typescript-eslint/parser ^5.30.7
  • babel-eslint ^10.1.0
  • broccoli-asset-rev ^3.0.0
  • ember-auto-import ^2.4.2
  • ember-cached-decorator-polyfill ^0.1.4
  • ember-cli ~4.6.0
  • ember-cli-app-version ^5.0.0
  • ember-cli-babel ^7.26.11
  • ember-cli-dependency-checker ^3.3.1
  • ember-cli-htmlbars ^6.1.0
  • ember-cli-inject-live-reload ^2.1.0
  • ember-cli-sri ^2.1.1
  • ember-cli-terser ^4.0.2
  • ember-cli-typescript ^5.1.0
  • ember-cli-typescript-blueprints ^3.0.0
  • ember-data ~4.4.0
  • ember-disable-prototype-extensions ^1.1.3
  • ember-export-application-global ^2.0.1
  • ember-fetch ^8.1.1
  • ember-load-initializers ^2.1.2
  • ember-maybe-import-regenerator ^1.0.0
  • ember-page-title ^7.0.0
  • ember-qunit ^5.1.5
  • ember-resolver ^8.0.3
  • ember-source ~4.6.0
  • ember-source-channel-url ^3.0.0
  • ember-template-lint ^4.10.1
  • ember-try ^2.0.0
  • ember-welcome-page ^6.1.0
  • eslint ^7.32.0
  • eslint-config-prettier ^8.5.0
  • eslint-plugin-decorator-position ^5.0.1
  • eslint-plugin-ember ^11.0.2
  • eslint-plugin-import ^2.25.4
  • eslint-plugin-json ^3.1.0
  • eslint-plugin-node ^11.1.0
  • eslint-plugin-prettier ^4.2.1
  • eslint-plugin-qunit ^7.3.1
  • eslint-plugin-simple-import-sort ^7.0.0
  • loader.js ^4.7.0
  • npm-run-all ^4.1.5
  • prettier ^2.7.1
  • qunit ^2.19.1
  • qunit-dom ^2.0.0
  • semantic-release ^19.0.3
  • typescript ^4.7.4
  • webpack ^5.74.0

  • Check this box to trigger a request for Renovate to run again on this repository

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.