diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts index ee24fc700c..456a3ee022 100644 --- a/src/compiler/compile/Component.ts +++ b/src/compiler/compile/Component.ts @@ -772,7 +772,7 @@ export default class Component { invalidate(name, value?) { const variable = this.var_lookup.get(name); - if (variable && (variable.subscribable && variable.reassigned)) { + if (variable && (variable.subscribable && (variable.reassigned || variable.export_name))) { return x`${`$$subscribe_${name}`}($$invalidate('${name}', ${value || name}))`; } diff --git a/src/compiler/compile/render_dom/index.ts b/src/compiler/compile/render_dom/index.ts index bd7b99bd8f..83b0c6ef0a 100644 --- a/src/compiler/compile/render_dom/index.ts +++ b/src/compiler/compile/render_dom/index.ts @@ -221,16 +221,18 @@ export default function dom( } }); - component.rewrite_props(({ name, reassigned }) => { + component.rewrite_props(({ name, reassigned, export_name }) => { const value = `$${name}`; + + let insert: string; + if (reassigned || export_name) { + insert = b`${`$$subscribe_${name}`}()`; + } else { + const callback = x`$$value => $$invalidate('${value}', ${value} = $$value)`; - if (reassigned) { - return b`${`$$subscribe_${name}`}()`; + insert = b`@component_subscribe($$self, ${name}, $${callback})`; } - const callback = x`$$value => $$invalidate('${value}', ${value} = $$value)`; - - let insert = b`@component_subscribe($$self, ${name}, $${callback})`; if (component.compile_options.dev) { insert = b`@validate_store(${name}, '${name}'); ${insert}`; } @@ -311,7 +313,7 @@ export default function dom( const resubscribable_reactive_store_unsubscribers = reactive_stores .filter(store => { const variable = component.var_lookup.get(store.name.slice(1)); - return variable && variable.reassigned; + return variable && (variable.reassigned || variable.export_name); }) .map(({ name }) => b`$$self.$$.on_destroy.push(() => ${`$$unsubscribe_${name.slice(1)}`}());`); @@ -353,7 +355,7 @@ export default function dom( const name = $name.slice(1); const store = component.var_lookup.get(name); - if (store && store.reassigned) { + if (store && (store.reassigned || store.export_name)) { const unsubscribe = `$$unsubscribe_${name}`; const subscribe = `$$subscribe_${name}`; return b`let ${$name}, ${unsubscribe} = @noop, ${subscribe} = () => (${unsubscribe}(), ${unsubscribe} = @subscribe(${name}, $$value => $$invalidate('${$name}', ${$name} = $$value)), ${name})`; diff --git a/test/runtime/samples/store-resubscribe-export/_config.js b/test/runtime/samples/store-resubscribe-export/_config.js new file mode 100644 index 0000000000..b6e6f11344 --- /dev/null +++ b/test/runtime/samples/store-resubscribe-export/_config.js @@ -0,0 +1,27 @@ +let subscribeCalled = false; + +const fakeStore = val => ({ + subscribe: cb => { + cb(val); + return { + unsubscribe: () => { + subscribeCalled = true; + }, + }; + }, +}); + +export default { + props: { + foo: fakeStore(1), + }, + html: ` +

1

+ `, + + async test({ assert, component, target }) { + component.foo = fakeStore(5); + + return assert.htmlEqual(target.innerHTML, `

5

`); + }, +}; diff --git a/test/runtime/samples/store-resubscribe-export/main.svelte b/test/runtime/samples/store-resubscribe-export/main.svelte new file mode 100644 index 0000000000..44b00544b7 --- /dev/null +++ b/test/runtime/samples/store-resubscribe-export/main.svelte @@ -0,0 +1,6 @@ + + +

{$foo}