diff --git a/src/compiler/compile/render_dom/Renderer.ts b/src/compiler/compile/render_dom/Renderer.ts index 046a90b68400..5cd50e8e0b9b 100644 --- a/src/compiler/compile/render_dom/Renderer.ts +++ b/src/compiler/compile/render_dom/Renderer.ts @@ -153,7 +153,7 @@ export default class Renderer { const member = this.context_lookup.get(name); if (variable && (variable.subscribable && (variable.reassigned || variable.export_name))) { - return x`${`$$subscribe_${name}`}($$invalidate(${member.index}, ${value || name}))`; + return x`${`$$subscribe_${name}`}($$invalidate({ i: ${member.index}, ret: ${value || name} }))`; } if (name[0] === '$' && name[1] !== '$') { @@ -171,7 +171,7 @@ export default class Renderer { } if (value) { - return x`$$invalidate(${member.index}, ${value})`; + return x`$$invalidate({ i: ${member.index}, ret: ${value} })`; } // if this is a reactive declaration, invalidate dependencies recursively @@ -193,7 +193,7 @@ export default class Renderer { if (!filtered.length) return null; return filtered - .map(n => x`$$invalidate(${this.context_lookup.get(n).index}, ${n})`) + .map(n => x`$$invalidate({ i: ${this.context_lookup.get(n).index}, ret: ${n} })`) .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 26fa4a70f81f..4b204d195605 100644 --- a/src/compiler/compile/render_dom/index.ts +++ b/src/compiler/compile/render_dom/index.ts @@ -235,7 +235,7 @@ export default function dom( const insert = (reassigned || export_name) ? b`${`$$subscribe_${name}`}()` - : b`@component_subscribe($$self, ${name}, #value => $$invalidate(${i}, ${value} = #value))`; + : b`@component_subscribe($$self, ${name}, #value => $$invalidate({ i: ${i}, ret: ${value} = #value }))`; if (component.compile_options.dev) { return b`@validate_store(${name}, '${name}'); ${insert}`; @@ -308,7 +308,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).index}, ${name} = $$value)); + @component_subscribe($$self, ${name.slice(1)}, $$value => $$invalidate({ i: ${renderer.context_lookup.get(name).index}, ret: ${name} = $$value })); `); const resubscribable_reactive_store_unsubscribers = reactive_stores @@ -359,7 +359,7 @@ export default function dom( const subscribe = `$$subscribe_${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})`; + return b`let ${$name}, ${unsubscribe} = @noop, ${subscribe} = () => (${unsubscribe}(), ${unsubscribe} = @subscribe(${name}, $$value => $$invalidate({ i: ${i}, ret: ${$name} = $$value })), ${name})`; } return b`let ${$name};`; diff --git a/src/compiler/compile/render_dom/invalidate.ts b/src/compiler/compile/render_dom/invalidate.ts index 65fb73afc3b1..7c4500b674b6 100644 --- a/src/compiler/compile/render_dom/invalidate.ts +++ b/src/compiler/compile/render_dom/invalidate.ts @@ -62,7 +62,11 @@ export function invalidate(renderer: Renderer, scope: Scope, node: Node, names: let invalidate = is_store_value ? x`@set_store_value(${head.name.slice(1)}, ${node}, ${extra_args})` : !main_execution_context - ? x`$$invalidate(${renderer.context_lookup.get(head.name).index}, ${node}, ${extra_args})` + ? x`$$invalidate({ + i: ${renderer.context_lookup.get(head.name).index}, + ret: ${node}, + value: ${extra_args[0]} + }, ${extra_args.slice(1)})` : node; if (head.subscribable && head.reassigned) { diff --git a/src/runtime/internal/Component.ts b/src/runtime/internal/Component.ts index c1d2f80101b1..d0b4a3aef2b9 100644 --- a/src/runtime/internal/Component.ts +++ b/src/runtime/internal/Component.ts @@ -127,12 +127,29 @@ export function init(component, options, instance, create_fragment, not_equal, p let ready = false; $$.ctx = instance - ? instance(component, prop_values, (i, ret, value = ret) => { - if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) { - if ($$.bound[i]) $$.bound[i](value); - if (ready) make_dirty(component, i); + ? instance(component, prop_values, (args) => { + let { i, ret, value } = args; + const isValuePassed = !!Object.keys(args).find(e => e === 'value'); + + const assign = () => { + if (not_equal($$.ctx[i], ($$.ctx[i] = value))) { + if ($$.bound[i]) $$.bound[i](value); + if (ready) make_dirty(component, i); + } + }; + + if ($$.ctx) { + if (!isValuePassed && typeof $$.ctx[i] === 'undefined') { + assign(); + return ret; + } + + value = isValuePassed ? value : (value || ret); + assign(); } + return ret; + }) : [];