Merge pull request #1941 from sveltejs/gh-1889

allow reactive store references anywhere in script
pull/1942/head
Rich Harris 6 years ago committed by GitHub
commit 45d375e15d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

18
package-lock.json generated

@ -1,6 +1,6 @@
{
"name": "svelte",
"version": "3.0.0-alpha12",
"version": "3.0.0-alpha13",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -2806,20 +2806,12 @@
"dev": true
},
"is-reference": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.1.0.tgz",
"integrity": "sha512-h37O/IX4efe56o9k41II1ECMqKwtqHa7/12dLDEzJIFux2x15an4WCDb0/eKdmUgRpLJ3bR0DrzDc7vOrVgRDw==",
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.1.1.tgz",
"integrity": "sha512-URlByVARcyP2E2GC7d3Ur702g3vqW391VKCHuF5Goo/M8IT97k4RU/+56OYImwDdX1J/V/VRxECE/wJqB0I2tg==",
"dev": true,
"requires": {
"@types/estree": "0.0.38"
},
"dependencies": {
"@types/estree": {
"version": "0.0.38",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.38.tgz",
"integrity": "sha512-F/v7t1LwS4vnXuPooJQGBRKRGIoxWUTmA4VHfqjOccFsNDThD5bfUNpITive6s352O7o384wcpEaDV8rHCehDA==",
"dev": true
}
"@types/estree": "0.0.39"
}
},
"is-typedarray": {

@ -63,7 +63,7 @@
"eslint-plugin-html": "^4.0.3",
"eslint-plugin-import": "^2.11.0",
"estree-walker": "^0.6.0",
"is-reference": "^1.1.0",
"is-reference": "^1.1.1",
"jsdom": "^11.8.0",
"kleur": "^3.0.0",
"locate-character": "^2.0.5",

@ -539,9 +539,43 @@ export default class Component {
this.extract_imports_and_exports(script.content, this.imports, this.props);
this.hoist_instance_declarations();
this.extract_reactive_declarations();
this.extract_reactive_store_references();
this.javascript = this.extract_javascript(script);
}
extract_reactive_store_references() {
// TODO this pattern happens a lot... can we abstract it
// (or better still, do fewer AST walks)?
const component = this;
let { instance_scope: scope, instance_scope_map: map } = this;
walk(this.instance_script.content, {
enter(node, parent) {
if (map.has(node)) {
scope = map.get(node);
}
if (isReference(node, parent)) {
const object = getObject(node);
const { name } = object;
if (name[0] === '$' && !scope.has(name)) {
component.warn_if_undefined(object, null);
// cheeky hack
component.template_references.add(name);
}
}
},
leave(node) {
if (map.has(node)) {
scope = scope.parent;
}
}
});
}
rewrite_props() {
const component = this;
const { code, instance_scope, instance_scope_map: map, meta } = this;
@ -735,7 +769,11 @@ export default class Component {
const { name } = flattenReference(node);
const owner = scope.findOwner(name);
if (owner === instance_scope) {
if (name[0] === '$' && !owner) {
hoistable = false;
}
else if (owner === instance_scope) {
if (name === fn_declaration.id.name) return;
if (hoistable_names.has(name)) return;
if (imported_declarations.has(name)) return;
@ -818,13 +856,7 @@ export default class Component {
const object = getObject(node);
const { name } = object;
if (component.declarations.indexOf(name) !== -1) {
dependencies.add(name);
} else if (name[0] === '$') {
component.warn_if_undefined(object, null);
// cheeky hack
component.template_references.add(name);
if (name[0] === '$' || component.declarations.indexOf(name) !== -1) {
dependencies.add(name);
}

@ -0,0 +1,26 @@
import { writable } from '../../../../store.js';
const count = writable(0);
export default {
props: {
count
},
html: `
<button>+1</button>
`,
async test({ assert, component, target, window }) {
assert.equal(component.get_count(), 0);
const button = target.querySelector('button');
const click = new window.MouseEvent('click');
await button.dispatchEvent(click);
assert.equal(component.get_count(), 1);
await count.set(42);
assert.equal(component.get_count(), 42);
}
};

@ -0,0 +1,9 @@
<script>
export let count;
export function get_count() {
return $count;
}
</script>
<button on:click="{() => count.update(n => n + 1)}">+1</button>
Loading…
Cancel
Save