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

Conditional Paths Computed Functions #10

Closed
ghost opened this issue Jun 13, 2019 · 3 comments
Closed

Conditional Paths Computed Functions #10

ghost opened this issue Jun 13, 2019 · 3 comments

Comments

@ghost
Copy link

ghost commented Jun 13, 2019

Very neat little library you have created. I am working on combining this with Lit-Html to build custom web components. It seems like a perfect combination.

I was giving it a few tests using the RunKit sandbox on NPM to see how well it would work with nested observables and conditional logic before I start to integrate into my components.

So the first thing I needed to verify was that you detect data property dependencies each time a computed function is run (not just first time), so it can handle conditional paths in the computed function. This seems to work fine.

The next test was to see if changes to observed object properties that were no longer used in the last computed function run (based on changes to conditional paths), would continue to execute the computed function.

const hyperactiv = require("hyperactiv");
const { observe, computed } = hyperactiv;

const context = observe({
    user: {
        name: "Chris Beckett",
        age: 49,
        verified: false
    }
});

const state = observe({
    ready: false,
    context: context
});

computed(() => {
    console.log('Changed...');
    if (!state.ready) {
        console.log("Not Ready");
    } else {
        if (!state.context.user.verified) {
            console.log(`Not Verified - ${state.context.user.name}`);
        } else {
            console.log(`Verified - Age ${state.context.user.age}`);
        }
    }
});

state.ready = true;
context.user.age = 48;
context.user.verified = true;
context.user.age = 50;
context.user.name = "Janet Kwan";

The behavior exhibited is that when a piece of state is modified that was previously detected in a conditional path, but was not rendered in the last run, the computed function will run again even though nothing needs to be rendered. In the above example, the computed function runs again and prints 'Verified - Age 50' when the 'context.user.name' data is changed even though it is not required based on the last run (and is not used in the result of the next run). In other words, the computed function continues to execute when data is changed it no longer uses.

You will certainly have put a lot of thought and testing into this than I have in my little example. I can't think of a scenario where the computed function would need to run based on a change in data that was not used in the last run?

It might be beneficial to clear and recreate the data dependencies during each run of a computed function so it will only run again if properties actually used in the last run have changed.

@elbywan
Copy link
Owner

elbywan commented Jun 13, 2019

Hello @chrismbeckett,

Very neat little library you have created.

Thanks a lot!

I am working on combining this with Lit-Html to build custom web components. It seems like a perfect combination.

Sounds like a great use case 👍.

I can't think of a scenario where the computed function would need to run based on a change in data that was not used in the last run?

It might be beneficial to clear and recreate the data dependencies during each run of a computed function so it will only run again if properties actually used in the last run have changed.

Absolutely! I think that recomputing on every dependency change is quite unnecessary.

I think, if I recall correctly, that the reason why I left that out when I wrote the library a while ago was because at that point I could not see a way to do that without having cyclic references.

  • objects referencing functions in order to mark them as dependencies and run them when a property changes
  • functions referencing objects in order to clean up unused properties during the last run

Anyway, thinking about it today I found a way to keep weak references and to avoid the issue.

So I just pushed a new branch with the fix (#11) that should solve the problem without causing any memory leak 🎉 .

I don't have access to my own computer for the rest of the week, I'm planning to release a new version of hyperactiv next monday.

In the meantime,if you would like to test the branch you could run npm i elbywan/hyperactiv#recalculate-latest-dependencies and check if everything seems to be working on your end.

@ghost
Copy link
Author

ghost commented Jun 14, 2019

Wow, thank you for the fast response. Looking forward to new release. I will certainly give it a try.

@elbywan
Copy link
Owner

elbywan commented Jun 14, 2019

@chrismbeckett finally I was able to publish version 0.7.3 today a bit ahead of time.

Closing the issue but feel free to reopen if I missed something.

playground link

Capture d’écran 2019-06-14 à 12 37 25

@elbywan elbywan closed this as completed Jun 14, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant