only invalidate referenced values

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

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

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

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

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

@ -17,26 +17,25 @@ function create_fragment(ctx) {
}; };
} }
let a = 1;
let b = 2;
function instance($$self, $$props, $$invalidate) { 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 }) => { $$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 { class Component extends SvelteComponent {
constructor(options) { constructor(options) {
super(); 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> <script>
let a = 1; export let a = 1;
let b = 2; export let b = 2;
let max; $: console.log('max', Math.max(a, b));
$: max = Math.max(a, b);
</script> </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> <script>
import { beforeUpdate, onMount } from 'svelte'; import { beforeUpdate, onMount } from 'svelte';
let mounted; let mounted = false;
export let count = 0; export let count = 0;
export let foo = { bar: 'baz' }; export let foo = { bar: 'baz' };
@ -14,4 +14,5 @@
}); });
</script> </script>
<h3>Called {count} times.</h3> <h3>Called {count} times.</h3>
<p>{foo.bar} {mounted}</p>

@ -1,16 +1,35 @@
export default { export default {
immutable: true, 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; 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; 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> </script>
<div> <div>
<Nested bind:this={nested} /> <Nested bind:this={nested} />
</div> </div>

Loading…
Cancel
Save