only invalidate referenced values

pull/2865/head
Richard Harris 5 years ago
parent 2f80667f20
commit db938a4559

@ -787,6 +787,10 @@ export default class Component {
return `${name.slice(1)}.set(${name})`
}
if (variable && !variable.referenced && !variable.is_reactive_dependency && !variable.export_name && !name.startsWith('$$')) {
return value || name;
}
if (value) {
return `$$invalidate('${name}', ${value})`;
}
@ -1118,8 +1122,9 @@ export default class Component {
if (!assignee_nodes.has(identifier)) {
const { name } = identifier;
const owner = scope.find_owner(name);
const component_var = component.var_lookup.get(name);
const is_writable_or_mutated = component_var && (component_var.writable || component_var.mutated);
const variable = component.var_lookup.get(name);
if (variable) variable.is_reactive_dependency = true;
const is_writable_or_mutated = variable && (variable.writable || variable.mutated);
if (
(!owner || owner === component.instance_scope) &&
(name[0] === '$' || is_writable_or_mutated)

@ -204,8 +204,10 @@ export default function dom(
if (variable && (variable.hoistable || variable.global || variable.module)) return;
if (single && !(variable.subscribable && variable.reassigned)) {
code.prependRight(node.start, `$$invalidate('${name}', `);
code.appendLeft(node.end, `)`);
if (variable.referenced || variable.is_reactive_dependency || variable.export_name) {
code.prependRight(node.start, `$$invalidate('${name}', `);
code.appendLeft(node.end, `)`);
}
} else {
pending_assignments.add(name);
}

@ -92,4 +92,5 @@ export interface Var {
initialised?: boolean;
hoistable?: boolean;
subscribable?: boolean;
is_reactive_dependency: boolean;
}

@ -29,7 +29,7 @@ function instance($$self, $$props, $$invalidate) {
$$self.$$.update = ($$dirty = { x: 1, b: 1 }) => {
if ($$dirty.x) { $$invalidate('b', b = x); }
if ($$dirty.b) { $$invalidate('a', a = b); }
if ($$dirty.b) { a = b; }
};
return { x };

@ -17,26 +17,25 @@ function create_fragment(ctx) {
};
}
let a = 1;
let b = 2;
function instance($$self, $$props, $$invalidate) {
let { a = 1, b = 2 } = $$props;
let max;
$$self.$set = $$props => {
if ('a' in $$props) $$invalidate('a', a = $$props.a);
if ('b' in $$props) $$invalidate('b', b = $$props.b);
};
$$self.$$.update = ($$dirty = { a: 1, b: 1 }) => {
if ($$dirty.a || $$dirty.b) { $$invalidate('max', max = Math.max(a, b)); }
if ($$dirty.a || $$dirty.b) { console.log('max', Math.max(a, b)); }
};
return {};
return { a, b };
}
class Component extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance, create_fragment, safe_not_equal, []);
init(this, options, instance, create_fragment, safe_not_equal, ["a", "b"]);
}
}

@ -1,7 +1,6 @@
<script>
let a = 1;
let b = 2;
export let a = 1;
export let b = 2;
let max;
$: max = Math.max(a, b);
$: console.log('max', Math.max(a, b));
</script>

@ -0,0 +1,78 @@
/* generated by Svelte vX.Y.Z */
import {
SvelteComponent,
append,
detach,
element,
init,
insert,
noop,
safe_not_equal,
set_data,
text
} from "svelte/internal";
import { onMount } from "svelte";
function create_fragment(ctx) {
var p, t;
return {
c() {
p = element("p");
t = text(ctx.y);
},
m(target, anchor) {
insert(target, p, anchor);
append(p, t);
},
p(changed, ctx) {
if (changed.y) {
set_data(t, ctx.y);
}
},
i: noop,
o: noop,
d(detaching) {
if (detaching) {
detach(p);
}
}
};
}
function instance($$self, $$props, $$invalidate) {
let a, b, c;
onMount(() => {
const interval = setInterval(() => {
$$invalidate('b', b += 1);
c += 1;
console.log(b, c);
}, 1000);
return () => clearInterval(interval);
});
let x, y;
$$self.$$.update = ($$dirty = { a: 1, b: 1 }) => {
if ($$dirty.a) { x = a * 2; }
if ($$dirty.b) { $$invalidate('y', y = b * 2); }
};
return { y };
}
class Component extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance, create_fragment, safe_not_equal, []);
}
}
export default Component;

@ -0,0 +1,21 @@
<script>
import { onMount } from 'svelte';
let a, b, c;
onMount(() => {
const interval = setInterval(() => {
b += 1;
c += 1;
console.log(b, c);
}, 1000);
return () => clearInterval(interval);
});
$: x = a * 2;
$: y = b * 2;
</script>
<p>{y}</p>

@ -1,7 +1,7 @@
<script>
import { beforeUpdate, onMount } from 'svelte';
let mounted;
let mounted = false;
export let count = 0;
export let foo = { bar: 'baz' };
@ -14,4 +14,5 @@
});
</script>
<h3>Called {count} times.</h3>
<h3>Called {count} times.</h3>
<p>{foo.bar} {mounted}</p>

@ -1,16 +1,35 @@
export default {
immutable: true,
html: `<div><h3>Called 1 times.</h3></div>`,
html: `
<div>
<h3>Called 1 times.</h3>
<p>baz true</p>
</div>
`,
ssrHtml: `<div><h3>Called 0 times.</h3></div>`,
ssrHtml: `
<div>
<h3>Called 0 times.</h3>
<p>baz false</p>
</div>`,
test({ assert, component, target, window }) {
test({ assert, component, target }) {
var nested = component.nested;
assert.htmlEqual(target.innerHTML, `<div><h3>Called 1 times.</h3></div>`);
assert.htmlEqual(target.innerHTML, `
<div>
<h3>Called 1 times.</h3>
<p>baz true</p>
</div>
`);
nested.foo = nested.foo;
assert.htmlEqual(target.innerHTML, `<div><h3>Called 1 times.</h3></div>`);
assert.htmlEqual(target.innerHTML, `
<div>
<h3>Called 1 times.</h3>
<p>baz true</p>
</div>
`);
}
};

@ -5,5 +5,5 @@
</script>
<div>
<Nested bind:this={nested} />
<Nested bind:this={nested} />
</div>

Loading…
Cancel
Save