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: Compiler.aggregate causing binding misbehavior and issues with SSR cache clearing #6650

Closed
nicholasrice opened this issue Feb 24, 2023 · 2 comments
Labels
area:fast-element Pertains to fast-element bug A bug

Comments

@nicholasrice
Copy link
Contributor

🐛 Bug Report

There are two separate issues relating to the way that Compiler.aggregate works, one related to oneTime bindings and the other to SSR OpCode cache-clearing.

Compiler.aggregate stores a reference to the last binding in a set of strings and bindings. It then mutates that binding and uses it as the binding provided to the constructor of a new HTMLBindingDirective.

SSR OpCode Cache Issue:
In SSR, if the ViewTemplate -> OpCode cache is cleared, a template will be re-parsed for op codes. Because Compiler.aggregate mutates the binding reference, this leads to a different output than the first parsing of the template by the Template Parser, causing an inconsistent SSR result.

Attribute binding Issue:
When oneTime is used in conjunction with a regular binding in an element's attribute, there is inconsistent behavior with how the bindings update due to how Compiler.aggregate re-uses the last binding in the set of bindings. If the last binding in the attribute is a oneTime binding, the oneTime binding is used by Compiler.aggregate and changes to observable properties fail to update the attribute value. If the oneTime binding is not last, changes to observable properties update the attribute value, but also re-evaluate the oneTime binding unexpectedly. See https://stackblitz.com/edit/typescript-t71pfv?file=index.ts,index.html for a min-repro.

Proposed Fix

I think two changes need to be made:

  1. Update OneTimeBinding.evaluate to only invoke the binding expression once, during bind(). All other invocations of OneTimeBinding.evaluate would return the previously returned value. Uppon re-binding of the OneTimeBinding, the binding expression would be re-invoked for the provided target. This change is necessary because code created in Compiler.aggregate manually calls the binding expression from dataBinding.evaluate().
  2. Update Compiler.aggregate to provide a new binding to the returned HTMLBindingDirective instead of re-using the last binding. Doing so will prevent the binding from not updating when the last binding is a OneTimeBinding. This prevents mutation of the existing bindings and fixes SSR cache issue, and also prevents OneTimeBinding from preventing updates of other bindings when it is the last binding in the set of bindings.
        // this
        binding.evaluate = expression;
        binding.isVolatile = isVolatile;
        binding.policy = bindingPolicy ?? policy;
        const directive = new HTMLBindingDirective(binding);

        // becomes this
       const directive = new HTMLBindingDirective(bind(expression, bindingPolicy ?? policy, isVolatile ));
@nicholasrice nicholasrice added the status:triage New Issue - needs triage label Feb 24, 2023
@nicholasrice nicholasrice added this to the FAST Element 2.0 milestone Feb 24, 2023
@nicholasrice nicholasrice added bug A bug area:fast-element Pertains to fast-element and removed status:triage New Issue - needs triage labels Feb 24, 2023
@nicholasrice nicholasrice moved this from Triage to Todo in FAST Architecture Roadmap Feb 24, 2023
@nicholasrice
Copy link
Contributor Author

Actually fast-ssr also manually calls dataBinding.evaluate() from the same binding reference, so overriding evaluate() is probably not a good idea. We might need a different solution to fix the oneTime re-evaluation problem.

@janechu
Copy link
Collaborator

janechu commented Jul 5, 2024

I believe this is fixed from #6977

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:fast-element Pertains to fast-element bug A bug
Projects
Archived in project
Development

No branches or pull requests

2 participants