diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts index 920b0c3927..46704fd7ff 100644 --- a/src/compiler/compile/Component.ts +++ b/src/compiler/compile/Component.ts @@ -209,7 +209,7 @@ export default class Component { }); const subscribable_name = name.slice(1); - this.add_reference(subscribable_name); + // this.add_reference(subscribable_name); const variable = this.var_lookup.get(subscribable_name); if (variable) variable.subscribable = true; diff --git a/src/compiler/compile/render_dom/Block.ts b/src/compiler/compile/render_dom/Block.ts index 01359b7c18..b69955abae 100644 --- a/src/compiler/compile/render_dom/Block.ts +++ b/src/compiler/compile/render_dom/Block.ts @@ -34,7 +34,7 @@ export default class Block { key: Identifier; first: Identifier; - dependencies: Set; + dependencies: Set = new Set(); bindings: Map = new Map(); + context: ContextMember[] = []; + context_lookup: Map = new Map(); blocks: Array = []; readonly: Set = new Set(); meta_bindings: Array = []; // initial values for e.g. window.innerWidth, if there's a meta tag @@ -31,22 +40,18 @@ export default class Renderer { this.file_var = options.dev && this.component.get_unique_name('file'); // TODO sort vars, most frequently referenced first? - component.vars - .filter(v => ((v.referenced || v.export_name) && !v.hoistable)) - .forEach(v => this.add_to_context(v.name)); + component.vars.filter(v => !v.hoistable || (v.export_name && !v.module)).forEach(v => this.add_to_context(v.name)); // ensure store values are included in context - component.vars - .filter(v => v.subscribable) - .forEach(v => this.add_to_context(`$${v.name}`)); + component.vars.filter(v => v.subscribable).forEach(v => this.add_to_context(`$${v.name}`)); if (component.var_lookup.has('$$props')) { this.add_to_context('$$props'); } if (component.slots.size > 0) { - this.add_to_context('$$slots'); this.add_to_context('$$scope'); + this.add_to_context('$$slots'); } if (this.binding_groups.length > 0) { @@ -86,25 +91,62 @@ export default class Renderer { this.block.assign_variable_names(); this.fragment.render(this.block, null, x`#nodes` as Identifier); + + this.context.forEach(member => { + const { variable } = member; + if (variable) { + member.priority += 2; + if (variable.mutated || variable.reassigned) member.priority += 4; + + // these determine whether variable is included in initial context + // array, so must have the highest priority + if (variable.export_name) member.priority += 8; + if (variable.referenced) member.priority += 16; + } + + if (!member.is_contextual) { + member.priority += 1; + } + }); + + this.context.sort((a, b) => b.priority - a.priority); + this.context.forEach((member, i) => member.index.value = i); } add_to_context(name: string, contextual = false) { if (!this.context_lookup.has(name)) { - const i = this.context.length; + const member: ContextMember = { + name, + index: { type: 'Literal', value: -1 }, // set later + is_contextual: false, + is_non_contextual: false, // shadowed vars could be contextual and non-contextual + variable: null, + priority: 0 + }; + + this.context_lookup.set(name, member); + this.context.push(member); + } + + const member = this.context_lookup.get(name); - this.context_lookup.set(name, i); - this.context.push(contextual ? null : name); + if (contextual) { + member.is_contextual = true; + } else { + member.is_non_contextual = true; + const variable = this.component.var_lookup.get(name); + member.variable = variable; } - return this.context_lookup.get(name); + return member; } invalidate(name: string, value?) { const variable = this.component.var_lookup.get(name); - const i = this.context_lookup.get(name); + const member = this.context_lookup.get(name); if (variable && (variable.subscribable && (variable.reassigned || variable.export_name))) { - return x`${`$$subscribe_${name}`}($$invalidate(${i}, ${value || name}))`; + return x`${`$$subscribe_${name}`}($$invalidate(${member.index}, ${value || name}))`; } if (name[0] === '$' && name[1] !== '$') { @@ -122,7 +164,7 @@ export default class Renderer { } if (value) { - return x`$$invalidate(${i}, ${value})`; + return x`$$invalidate(${member.index}, ${value})`; } // if this is a reactive declaration, invalidate dependencies recursively @@ -140,15 +182,46 @@ export default class Renderer { }); return Array.from(deps) - .map(n => x`$$invalidate(${this.context_lookup.get(n)}, ${n})`) + .map(n => x`$$invalidate(${this.context_lookup.get(n).index}, ${n})`) .reduce((lhs, rhs) => x`${lhs}, ${rhs}}`); } get_bitmask(names) { - return names.reduce((bits, name) => { - const bit = 1 << this.context_lookup.get(name); - return bits | bit; - }, 0); + const { context_lookup } = this; + + // names.forEach(name => { + // if (!context_lookup.has(name)) { + // console.log({ names }); + // throw new Error(`wut ${name}`); + // } + // }); + + return { + type: 'Literal', + + // we need to use a getter so that bitmasks can be determined + // lazily, once context has fully shaken out. TODO would be nice + // to do everything in a different order so that this isn't necessary + get value() { + return names.reduce((bits, name) => { + const member = context_lookup.get(name); + + if (!member) return bits; + + if (member.index.value === -1) { + throw new Error(`unset index`); + } + + // if (!member) { + // console.log({ names }); + // throw new Error(`wut ${name}`); + // } + + const bit = 1 << (member.index.value as number); + return bits | bit; + }, 0); + } + }; } changed(names, is_reactive_declaration = false) { @@ -165,17 +238,17 @@ export default class Renderer { } const { name, nodes } = flatten_reference(node); - const i = this.context_lookup.get(name); + const member = this.context_lookup.get(name); // TODO is this correct? if (this.component.var_lookup.get(name)) { this.component.add_reference(name); } - if (i !== undefined) { - const replacement = x`#ctx[${i}]` as MemberExpression; + if (member !== undefined) { + const replacement = x`#ctx[${member.index}]` as MemberExpression; - replacement.object.loc = nodes[0].loc; + if (nodes[0].loc) replacement.object.loc = nodes[0].loc; nodes[0] = replacement; return nodes.reduce((lhs, rhs) => x`${lhs}.${rhs}`); diff --git a/src/compiler/compile/render_dom/index.ts b/src/compiler/compile/render_dom/index.ts index d775abca47..f2b203a60b 100644 --- a/src/compiler/compile/render_dom/index.ts +++ b/src/compiler/compile/render_dom/index.ts @@ -104,7 +104,7 @@ export default function dom( kind: 'get', key: { type: 'Identifier', name: prop.export_name }, value: x`function() { - return ${prop.hoistable ? prop.name : x`this.$$.ctx[${renderer.context_lookup.get(prop.name)}]`} + return ${prop.hoistable ? prop.name : x`this.$$.ctx[${renderer.context_lookup.get(prop.name).index}]`} }` }); } else if (component.compile_options.dev) { @@ -222,7 +222,7 @@ export default function dom( component.rewrite_props(({ name, reassigned, export_name }) => { const value = `$${name}`; - const i = renderer.context_lookup.get(`$${name}`); + const i = renderer.context_lookup.get(`$${name}`).index; const insert = (reassigned || export_name) ? b`${`$$subscribe_${name}`}()` @@ -268,12 +268,31 @@ export default function dom( const instance_javascript = component.extract_javascript(component.ast.instance); + let i = renderer.context.length; + while (i--) { + const member = renderer.context[i]; + if (member.variable) { + if (member.variable.referenced || member.variable.export_name) break; + } else if (member.is_non_contextual) { + break; + } + } + const initial_context = renderer.context.slice(0, i + 1); + + // const initial_context = renderer.context.filter(member => { + // // return member.variable + // // ? (member.variable.referenced || member.variable.export_name) + // // : !member.is_contextual; + + // return member.variable || !member.is_contextual; + // }); + const has_definition = ( (instance_javascript && instance_javascript.length > 0) || filtered_props.length > 0 || uses_props || component.partly_hoisted.length > 0 || - renderer.context.length > 0 || + initial_context.length > 0 || component.reactive_declarations.length > 0 ); @@ -288,7 +307,7 @@ export default function dom( }) .map(({ name }) => b` ${component.compile_options.dev && b`@validate_store(${name.slice(1)}, '${name.slice(1)}');`} - @component_subscribe($$self, ${name.slice(1)}, $$value => $$invalidate(${renderer.context_lookup.get(name)}, ${name} = $$value)); + @component_subscribe($$self, ${name.slice(1)}, $$value => $$invalidate(${renderer.context_lookup.get(name).index}, ${name} = $$value)); `); const resubscribable_reactive_store_unsubscribers = reactive_stores @@ -308,7 +327,7 @@ export default function dom( const writable = dependencies.filter(n => { const variable = component.var_lookup.get(n); - return variable && (variable.writable || variable.mutated); + return variable && (variable.export_name || variable.mutated || variable.reassigned); }); const condition = !uses_props && writable.length > 0 && renderer.changed(writable, true); @@ -337,7 +356,7 @@ export default function dom( if (store && (store.reassigned || store.export_name)) { const unsubscribe = `$$unsubscribe_${name}`; const subscribe = `$$subscribe_${name}`; - const i = renderer.context_lookup.get($name); + const i = renderer.context_lookup.get($name).index; return b`let ${$name}, ${unsubscribe} = @noop, ${subscribe} = () => (${unsubscribe}(), ${unsubscribe} = @subscribe(${name}, $$value => $$invalidate(${i}, ${$name} = $$value)), ${name})`; } @@ -357,11 +376,10 @@ export default function dom( const return_value = { type: 'ArrayExpression', - elements: renderer.context - .map(name => name ? ({ - type: 'Identifier', - name - }) as Expression : x`null`) + elements: initial_context.map(member => ({ + type: 'Identifier', + name: member.name + }) as Expression) }; body.push(b` @@ -406,7 +424,7 @@ export default function dom( } const prop_indexes = x`{ - ${props.filter(v => !v.hoistable).map(v => p`${v.export_name}: ${renderer.context_lookup.get(v.name)}`)} + ${props.filter(v => v.export_name && !v.module).map(v => p`${v.export_name}: ${renderer.context_lookup.get(v.name).index}`)} }` as ObjectExpression; if (options.customElement) { diff --git a/src/compiler/compile/render_dom/invalidate.ts b/src/compiler/compile/render_dom/invalidate.ts index d51d7fe787..ba72f9b7f1 100644 --- a/src/compiler/compile/render_dom/invalidate.ts +++ b/src/compiler/compile/render_dom/invalidate.ts @@ -52,7 +52,7 @@ export function invalidate(renderer: Renderer, scope: Scope, node: Node, names: let invalidate = is_store_value ? x`@set_store_value(${head.slice(1)}, ${node}, ${extra_args})` - : x`$$invalidate(${renderer.context_lookup.get(head)}, ${node}, ${extra_args})`; + : x`$$invalidate(${renderer.context_lookup.get(head).index}, ${node}, ${extra_args})`; if (variable.subscribable && variable.reassigned) { const subscribe = `$$subscribe_${head}`; diff --git a/src/compiler/compile/render_dom/wrappers/AwaitBlock.ts b/src/compiler/compile/render_dom/wrappers/AwaitBlock.ts index caf2161746..9e2e657c47 100644 --- a/src/compiler/compile/render_dom/wrappers/AwaitBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/AwaitBlock.ts @@ -118,6 +118,9 @@ export default class AwaitBlockWrapper extends Wrapper { if (has_outros) { block.add_outro(); } + + if (this.node.value) block.renderer.add_to_context(this.node.value, true); + if (this.node.error) block.renderer.add_to_context(this.node.error, true); } render( @@ -137,8 +140,8 @@ export default class AwaitBlockWrapper extends Wrapper { block.maintain_context = true; - const value_index = this.node.value && block.renderer.add_to_context(this.node.value, true); - const error_index = this.node.error && block.renderer.add_to_context(this.node.error, true); + const value_index = this.node.value && block.renderer.context_lookup.get(this.node.value).index; + const error_index = this.node.error && block.renderer.context_lookup.get(this.node.error).index; const info_props: any = x`{ ctx: #ctx, diff --git a/src/compiler/compile/render_dom/wrappers/EachBlock.ts b/src/compiler/compile/render_dom/wrappers/EachBlock.ts index 244e879e81..d1d55b1e5c 100644 --- a/src/compiler/compile/render_dom/wrappers/EachBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/EachBlock.ts @@ -196,10 +196,10 @@ export default class EachBlockWrapper extends Wrapper { ? !this.next.is_dom_node() : !parent_node || !this.parent.is_dom_node(); - this.context_props = this.node.contexts.map(prop => b`child_ctx[${renderer.context_lookup.get(prop.key.name)}] = ${prop.modifier(x`list[i]`)};`); + this.context_props = this.node.contexts.map(prop => b`child_ctx[${renderer.context_lookup.get(prop.key.name).index}] = ${prop.modifier(x`list[i]`)};`); - if (this.node.has_binding) this.context_props.push(b`child_ctx[${renderer.context_lookup.get(this.vars.each_block_value.name)}] = list;`); - if (this.node.has_binding || this.node.index) this.context_props.push(b`child_ctx[${renderer.context_lookup.get(this.index_name.name)}] = i;`); + if (this.node.has_binding) this.context_props.push(b`child_ctx[${renderer.context_lookup.get(this.vars.each_block_value.name).index}] = list;`); + if (this.node.has_binding || this.node.index) this.context_props.push(b`child_ctx[${renderer.context_lookup.get(this.index_name.name).index}] = i;`); const snippet = this.node.expression.manipulate(block); @@ -476,9 +476,8 @@ export default class EachBlockWrapper extends Wrapper { } `); - const all_dependencies = new Set(this.block.dependencies); - const { dependencies } = this.node.expression; - dependencies.forEach((dependency: string) => { + const all_dependencies = new Set(this.block.dependencies); // TODO should be dynamic deps only + this.node.expression.dynamic_dependencies().forEach((dependency: string) => { all_dependencies.add(dependency); }); diff --git a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts index 3417b563e2..315b347ef6 100644 --- a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts +++ b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts @@ -156,6 +156,7 @@ export default class InlineComponentWrapper extends Wrapper { } if (this.fragment) { + this.renderer.add_to_context('$$scope', true); const default_slot = this.slots.get('default'); this.fragment.nodes.forEach((child) => { diff --git a/src/compiler/compile/render_dom/wrappers/Window.ts b/src/compiler/compile/render_dom/wrappers/Window.ts index b13d4dd043..9cd05fa2e8 100644 --- a/src/compiler/compile/render_dom/wrappers/Window.ts +++ b/src/compiler/compile/render_dom/wrappers/Window.ts @@ -124,9 +124,6 @@ export default class WindowWrapper extends Wrapper { `); } - renderer.add_to_context(id.name); - const reference = renderer.reference(id.name); - component.partly_hoisted.push(b` function ${id}() { ${props.map(prop => renderer.invalidate(prop.name, x`${prop.name} = @_window.${prop.value}`))} @@ -134,7 +131,7 @@ export default class WindowWrapper extends Wrapper { `); block.chunks.init.push(b` - @add_render_callback(${reference}); + @add_render_callback(${fn}); `); component.has_reactive_assignments = true; diff --git a/src/compiler/compile/render_dom/wrappers/shared/get_slot_definition.ts b/src/compiler/compile/render_dom/wrappers/shared/get_slot_definition.ts index 170e9d87db..082ac6f841 100644 --- a/src/compiler/compile/render_dom/wrappers/shared/get_slot_definition.ts +++ b/src/compiler/compile/render_dom/wrappers/shared/get_slot_definition.ts @@ -25,13 +25,22 @@ export function get_slot_definition(block: Block, scope: TemplateScope, lets: Le const context = { type: 'ObjectExpression', - properties: Array.from(names).map(name => p`${block.renderer.context_lookup.get(name)}: ${name}`) + properties: Array.from(names).map(name => p`${block.renderer.context_lookup.get(name).index}: ${name}`) }; const changes = Array.from(names) .map(name => { - const i = block.renderer.context_lookup.get(name); - return x`${name} ? ${1 << i} : 0`; + const { context_lookup } = block.renderer; + + const literal = { + type: 'Literal', + get value() { + const i = context_lookup.get(name).index.value; + return 1 << i; + } + }; + + return x`${name} ? ${literal} : 0`; }) .reduce((lhs, rhs) => x`${lhs} | ${rhs}`); diff --git a/src/runtime/internal/Component.ts b/src/runtime/internal/Component.ts index 5333774125..9f9d43fd2d 100644 --- a/src/runtime/internal/Component.ts +++ b/src/runtime/internal/Component.ts @@ -83,7 +83,7 @@ export function destroy_component(component, detaching) { // TODO null out other refs, including component.$$ (but need to // preserve final state?) $$.on_destroy = $$.fragment = null; - $$.ctx = {}; + $$.ctx = []; } } @@ -134,7 +134,7 @@ export function init(component, options, instance, create_fragment, not_equal, p } return ret; }) - : prop_values; + : []; $$.update(); ready = true; diff --git a/test/js/samples/component-store-access-invalidate/expected.js b/test/js/samples/component-store-access-invalidate/expected.js index b31c1e1a6a..36952ab211 100644 --- a/test/js/samples/component-store-access-invalidate/expected.js +++ b/test/js/samples/component-store-access-invalidate/expected.js @@ -22,14 +22,14 @@ function create_fragment(ctx) { return { c() { h1 = element("h1"); - t = text(ctx[1]); + t = text(ctx[0]); }, m(target, anchor) { insert(target, h1, anchor); append(h1, t); }, p(ctx, changed) { - if (changed & 2) set_data(t, ctx[1]); + if (changed & 1) set_data(t, ctx[0]); }, i: noop, o: noop, @@ -42,8 +42,8 @@ function create_fragment(ctx) { function instance($$self, $$props, $$invalidate) { let $foo; const foo = writable(0); - component_subscribe($$self, foo, value => $$invalidate(1, $foo = value)); - return [foo, $foo]; + component_subscribe($$self, foo, value => $$invalidate(0, $foo = value)); + return [$foo]; } class Component extends SvelteComponent { diff --git a/test/js/samples/debug-foo-bar-baz-things/expected.js b/test/js/samples/debug-foo-bar-baz-things/expected.js index ee34ad39aa..11143ba909 100644 --- a/test/js/samples/debug-foo-bar-baz-things/expected.js +++ b/test/js/samples/debug-foo-bar-baz-things/expected.js @@ -194,7 +194,7 @@ function instance($$self, $$props, $$invalidate) { if ("baz" in $$props) $$invalidate(3, baz = $$props.baz); }; - return [things, foo, bar, baz, null, null, null]; + return [things, foo, bar, baz]; } class Component extends SvelteComponentDev { diff --git a/test/js/samples/debug-foo/expected.js b/test/js/samples/debug-foo/expected.js index aae080ffef..87e2927c06 100644 --- a/test/js/samples/debug-foo/expected.js +++ b/test/js/samples/debug-foo/expected.js @@ -182,7 +182,7 @@ function instance($$self, $$props, $$invalidate) { if ("foo" in $$props) $$invalidate(1, foo = $$props.foo); }; - return [things, foo, null, null, null]; + return [things, foo]; } class Component extends SvelteComponentDev { diff --git a/test/js/samples/debug-no-dependencies/expected.js b/test/js/samples/debug-no-dependencies/expected.js index 0de3a53f85..247e3eabdb 100644 --- a/test/js/samples/debug-no-dependencies/expected.js +++ b/test/js/samples/debug-no-dependencies/expected.js @@ -89,7 +89,7 @@ function create_fragment(ctx) { insert_dev(target, each_1_anchor, anchor); }, p: function update(ctx, changed) { - if (changed & 1) { + if (changed & 0) { each_value = things; let i; diff --git a/test/js/samples/deconflict-builtins/expected.js b/test/js/samples/deconflict-builtins/expected.js index 1f13224b30..07295eefbe 100644 --- a/test/js/samples/deconflict-builtins/expected.js +++ b/test/js/samples/deconflict-builtins/expected.js @@ -108,7 +108,7 @@ function instance($$self, $$props, $$invalidate) { if ("createElement" in $$props) $$invalidate(0, createElement = $$props.createElement); }; - return [createElement, null, null, null]; + return [createElement]; } class Component extends SvelteComponent { diff --git a/test/js/samples/each-block-array-literal/expected.js b/test/js/samples/each-block-array-literal/expected.js index 8f6e902c21..16f14910dc 100644 --- a/test/js/samples/each-block-array-literal/expected.js +++ b/test/js/samples/each-block-array-literal/expected.js @@ -114,7 +114,7 @@ function instance($$self, $$props, $$invalidate) { if ("e" in $$props) $$invalidate(4, e = $$props.e); }; - return [a, b, c, d, e, null, null, null]; + return [a, b, c, d, e]; } class Component extends SvelteComponent { diff --git a/test/js/samples/each-block-changed-check/expected.js b/test/js/samples/each-block-changed-check/expected.js index 56c399cdc5..38e8396126 100644 --- a/test/js/samples/each-block-changed-check/expected.js +++ b/test/js/samples/each-block-changed-check/expected.js @@ -159,7 +159,7 @@ function instance($$self, $$props, $$invalidate) { if ("foo" in $$props) $$invalidate(3, foo = $$props.foo); }; - return [comments, elapsed, time, foo, null, null, null]; + return [comments, elapsed, time, foo]; } class Component extends SvelteComponent { diff --git a/test/js/samples/each-block-keyed-animated/expected.js b/test/js/samples/each-block-keyed-animated/expected.js index 780f5c6db2..463a63e88e 100644 --- a/test/js/samples/each-block-keyed-animated/expected.js +++ b/test/js/samples/each-block-keyed-animated/expected.js @@ -130,7 +130,7 @@ function instance($$self, $$props, $$invalidate) { if ("things" in $$props) $$invalidate(0, things = $$props.things); }; - return [things, null, null, null]; + return [things]; } class Component extends SvelteComponent { diff --git a/test/js/samples/each-block-keyed/expected.js b/test/js/samples/each-block-keyed/expected.js index dd72e418c7..80369af9f0 100644 --- a/test/js/samples/each-block-keyed/expected.js +++ b/test/js/samples/each-block-keyed/expected.js @@ -99,7 +99,7 @@ function instance($$self, $$props, $$invalidate) { if ("things" in $$props) $$invalidate(0, things = $$props.things); }; - return [things, null, null, null]; + return [things]; } class Component extends SvelteComponent { diff --git a/test/js/samples/reactive-values-non-topologically-ordered/expected.js b/test/js/samples/reactive-values-non-topologically-ordered/expected.js index e4a4cc6605..a98e81293f 100644 --- a/test/js/samples/reactive-values-non-topologically-ordered/expected.js +++ b/test/js/samples/reactive-values-non-topologically-ordered/expected.js @@ -12,10 +12,10 @@ function instance($$self, $$props, $$invalidate) { $$self.$$.update = () => { if ($$self.$$.dirty & 1) { - $: $$invalidate("b", b = x); + $: $$invalidate(2, b = x); } - if ($$self.$$.dirty & 2) { + if ($$self.$$.dirty & 4) { $: a = b; } }; diff --git a/test/js/samples/setup-method/expected.js b/test/js/samples/setup-method/expected.js index 5ee43a9f1f..8e30a03a7d 100644 --- a/test/js/samples/setup-method/expected.js +++ b/test/js/samples/setup-method/expected.js @@ -7,10 +7,14 @@ function foo(bar) { console.log(bar); } +function instance($$self, $$props, $$invalidate) { + return [foo]; +} + class Component extends SvelteComponent { constructor(options) { super(); - init(this, options, null, null, safe_not_equal, { foo: 0 }); + init(this, options, instance, null, safe_not_equal, { foo: 0 }); } get foo() { diff --git a/test/js/samples/unreferenced-state-not-invalidated/expected.js b/test/js/samples/unreferenced-state-not-invalidated/expected.js index f85026bc9b..0bd2531008 100644 --- a/test/js/samples/unreferenced-state-not-invalidated/expected.js +++ b/test/js/samples/unreferenced-state-not-invalidated/expected.js @@ -39,7 +39,7 @@ function create_fragment(ctx) { } function instance($$self, $$props, $$invalidate) { - let a, b, c; + let a = 1, b = 2, c = 3; onMount(() => { const interval = setInterval( @@ -58,15 +58,12 @@ function instance($$self, $$props, $$invalidate) { let y; $$self.$$.update = () => { - if ($$self.$$.dirty === -1) { - $: x = a * 2; - } - if ($$self.$$.dirty & 2) { $: $$invalidate(0, y = b * 2); } }; + $: x = a * 2; return [y]; } diff --git a/test/js/samples/unreferenced-state-not-invalidated/input.svelte b/test/js/samples/unreferenced-state-not-invalidated/input.svelte index fff60f181d..a453f9a23e 100644 --- a/test/js/samples/unreferenced-state-not-invalidated/input.svelte +++ b/test/js/samples/unreferenced-state-not-invalidated/input.svelte @@ -1,7 +1,7 @@