From e619de7e089eb37f3e266e80b2ec17cf536862fa Mon Sep 17 00:00:00 2001 From: Thomas Ghysels Date: Sun, 3 Mar 2019 21:58:48 +0100 Subject: [PATCH 1/3] Throw descriptive error when 'subscribable' of undefined Fix #2139 --- src/compile/nodes/shared/Expression.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/compile/nodes/shared/Expression.ts b/src/compile/nodes/shared/Expression.ts index 0d33988fb3..d52a0d80de 100644 --- a/src/compile/nodes/shared/Expression.ts +++ b/src/compile/nodes/shared/Expression.ts @@ -149,6 +149,13 @@ export default class Expression { dependencies.add(name); } + if (name[0] === '$' && !component.var_lookup.get(name.slice(1)) && name !== '$$props') { + component.error(node, { + code: `missing-store`, + message: `Stores must be declared` + }); + } + component.add_reference(name); component.warn_if_undefined(nodes[0], template_scope, true); } From 6d3e47812d35c2a42eacd23842612d5ca9f67587 Mon Sep 17 00:00:00 2001 From: Richard Harris Date: Sat, 16 Mar 2019 15:32:57 -0400 Subject: [PATCH 2/3] subscribe to global stores (#2139) --- src/compile/Component.ts | 2 +- src/compile/nodes/shared/Expression.ts | 7 ------- src/compile/render-dom/index.ts | 6 +++--- .../samples/store-auto-subscribe-missing-global/_config.js | 3 +++ .../store-auto-subscribe-missing-global/main.svelte | 1 + 5 files changed, 8 insertions(+), 11 deletions(-) create mode 100644 test/runtime/samples/store-auto-subscribe-missing-global/_config.js create mode 100644 test/runtime/samples/store-auto-subscribe-missing-global/main.svelte diff --git a/src/compile/Component.ts b/src/compile/Component.ts index 62c2931f62..037880eff5 100644 --- a/src/compile/Component.ts +++ b/src/compile/Component.ts @@ -168,7 +168,7 @@ export default class Component { this.add_reference(subscribable_name); const variable = this.var_lookup.get(subscribable_name); - variable.subscribable = true; + if (variable) variable.subscribable = true; } else { this.usedNames.add(name); } diff --git a/src/compile/nodes/shared/Expression.ts b/src/compile/nodes/shared/Expression.ts index 87d06b722b..eb6b12143a 100644 --- a/src/compile/nodes/shared/Expression.ts +++ b/src/compile/nodes/shared/Expression.ts @@ -149,13 +149,6 @@ export default class Expression { dependencies.add(name); } - if (name[0] === '$' && !component.var_lookup.get(name.slice(1)) && name !== '$$props') { - component.error(node, { - code: `missing-store`, - message: `Stores must be declared` - }); - } - component.add_reference(name); component.warn_if_undefined(nodes[0], template_scope); } diff --git a/src/compile/render-dom/index.ts b/src/compile/render-dom/index.ts index 9d926d0d37..5def2edd04 100644 --- a/src/compile/render-dom/index.ts +++ b/src/compile/render-dom/index.ts @@ -326,7 +326,7 @@ export default function dom( const reactive_store_subscriptions = reactive_stores .filter(store => { const variable = component.var_lookup.get(store.name.slice(1)); - return variable.hoistable; + return !variable || variable.hoistable; }) .map(({ name }) => deindent` ${component.compileOptions.dev && `@validate_store(${name.slice(1)}, '${name.slice(1)}');`} @@ -336,7 +336,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.reassigned; + return variable && variable.reassigned; }) .map(({ name }) => `$$self.$$.on_destroy.push(() => $$unsubscribe_${name.slice(1)}());`); @@ -370,7 +370,7 @@ export default function dom( const name = $name.slice(1); const store = component.var_lookup.get(name); - if (store.reassigned) { + if (store && store.reassigned) { return `${$name}, $$unsubscribe_${name} = @noop, $$subscribe_${name} = () => { $$unsubscribe_${name}(); $$unsubscribe_${name} = ${name}.subscribe($$value => { ${$name} = $$value; $$invalidate('${$name}', ${$name}); }) }` } diff --git a/test/runtime/samples/store-auto-subscribe-missing-global/_config.js b/test/runtime/samples/store-auto-subscribe-missing-global/_config.js new file mode 100644 index 0000000000..c4eb72b553 --- /dev/null +++ b/test/runtime/samples/store-auto-subscribe-missing-global/_config.js @@ -0,0 +1,3 @@ +export default { + error: 'missingGlobal is not defined' +}; \ No newline at end of file diff --git a/test/runtime/samples/store-auto-subscribe-missing-global/main.svelte b/test/runtime/samples/store-auto-subscribe-missing-global/main.svelte new file mode 100644 index 0000000000..196836edef --- /dev/null +++ b/test/runtime/samples/store-auto-subscribe-missing-global/main.svelte @@ -0,0 +1 @@ +

{$missingGlobal}

\ No newline at end of file From b57c724bede8a37a1005d8b419ef30a87599ae90 Mon Sep 17 00:00:00 2001 From: Richard Harris Date: Sat, 16 Mar 2019 15:41:14 -0400 Subject: [PATCH 3/3] same but for SSR --- src/compile/render-ssr/index.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/compile/render-ssr/index.ts b/src/compile/render-ssr/index.ts index 64846f36cb..9e10733e37 100644 --- a/src/compile/render-ssr/index.ts +++ b/src/compile/render-ssr/index.ts @@ -27,13 +27,14 @@ export default function ssr( const reactive_stores = component.vars.filter(variable => variable.name[0] === '$' && variable.name[1] !== '$'); const reactive_store_values = reactive_stores .map(({ name }) => { - const store = component.var_lookup.get(name.slice(1)); - if (store.hoistable) return; + const store_name = name.slice(1); + const store = component.var_lookup.get(store_name); + if (store && store.hoistable) return; - const assignment = `${name} = @get_store_value(${store.name});`; + const assignment = `${name} = @get_store_value(${store_name});`; return component.compileOptions.dev - ? `@validate_store(${store.name}, '${store.name}'); ${assignment}` + ? `@validate_store(${store_name}, '${store_name}'); ${assignment}` : assignment; }); @@ -95,10 +96,11 @@ export default function ssr( const blocks = [ reactive_stores.length > 0 && `let ${reactive_stores .map(({ name }) => { - const store = component.var_lookup.get(name.slice(1)); - if (store.hoistable) { + const store_name = name.slice(1); + const store = component.var_lookup.get(store_name); + if (store && store.hoistable) { const get_store_value = component.helper('get_store_value'); - return `${name} = ${get_store_value}(${store.name})`; + return `${name} = ${get_store_value}(${store_name})`; } return name; })