Let's assume we have autotracking chain implementation. In general, we could be able to mark "accessed" properties, we could introduce "addToChain" function with 2 arguments,
1.) object (context) 2.) property we trying to access (on object)
like:
const deps: [object, string][] = [];
function addToChain(object, property) {
deps.push([object, property]);
}
addToChain({name: 'hello'}, 'hello');
every @tracked
property has this logic inside it's getter.
Let's introduce startTransaction
and endTransaction
functions to be able to track list of dependencies for exact property.
let deps: [object, string][] = [];
addToChain(object, property) {
deps.push([object, property]);
}
startTransaction() {
deps = [];
}
endTransaction() {
console.log(deps);
}
template:
equals to
{
startTransaction()
valueToRender = this.hello;
endTransaction();
}
if our "hello" property is an getter, depenent of 2 tracked properties, for example this.name
& this.surname
like:
{
@tracked name = 'Rick';
@tracked surname = 'Roll';
get hello() {
return this.name + this.surname;
}
}
equals to
{
get name() {
addToChain(this, 'name');
return 'Rick';
}
get surname() {
addToChain(this, 'surname');
return 'Roll';
}
get hello() {
return this.name + this.surname;
}
}
we will see this order in callstack:
1.) startTransaction()
2.) get hello()
3.) addToChain(object, 'name');
4.) addToChain(object, 'surname')
5.) endTransaction();
6.) log: [ [object, 'name'], [object, 'surname'] ]
and if object.name
or object.surname
is changed, we could recall get hello()
to get actual value to display message
if we return promise in getter, and it's resolved after "endTransaction" we will loose usages in chain