capture local variables in $capture_state

pull/3822/head
rixo 6 years ago
parent 1273f97808
commit cf3fe22e9b

@ -1,7 +1,7 @@
import { b, x, p } from 'code-red';
import Component from '../Component';
import Renderer from './Renderer';
import { CompileOptions } from '../../interfaces';
import { CompileOptions, Var } from '../../interfaces';
import { walk } from 'estree-walker';
import add_to_set from '../utils/add_to_set';
import { extract_names } from '../utils/scope';
@ -167,27 +167,41 @@ export default function dom(
`;
}
capture_state = (uses_props || writable_props.length > 0) ? x`
() => {
return { ${component.vars.filter(prop => prop.writable).map(prop => p`${prop.name}`)} };
}
` : x`
() => {
return {};
}
`;
// we need to filter out store subscriptions ($x) or $inject_state will try to call .set() on them, leading
// to a crash if store is not writable (and probably not intended behaviour to change store value)
const is_not_sub = (variable: Var) => variable.name.substr(0, 1) !== '$';
const writable_vars = component.vars.filter(variable => !variable.module && variable.writable);
inject_state = (uses_props || writable_vars.length > 0) ? x`
${$$props} => {
${uses_props && component.invalidate('$$props', x`$$props = @assign(@assign({}, $$props), $$new_props)`)}
${writable_vars.map(prop => b`
if ('${prop.name}' in $$props) ${component.invalidate(prop.name, x`${prop.name} = ${$$props}.${prop.name}`)};
`)}
}
` : x`
${$$props} => {}
`;
const capturable_vars = component.vars.filter(
variable => !variable.module && variable.writable && is_not_sub(variable)
);
if (uses_props || capturable_vars.length > 0) {
const capturable_props = writable_props.filter(is_not_sub);
const local_vars = capturable_vars.filter(variable => !variable.export_name);
const var_names = (variables: Var[]) => variables.map(prop => p`${prop.name}`);
capture_state = x`
({ props: $props = true, local: $local = true } = {}) => ({
...${x`$props && { ${var_names(capturable_props)} }`},
...${x`$local && { ${var_names(local_vars)} }`}
})
`;
inject_state = x`
${$$props} => {
${uses_props && component.invalidate('$$props', x`$$props = @assign(@assign({}, $$props), $$new_props)`)}
${capturable_vars.map(prop => b`
if ('${prop.name}' in $$props) ${component.invalidate(prop.name, x`${prop.name} = ${$$props}.${prop.name}`)};
`)}
}
`;
} else {
capture_state = x`() => ({})`;
inject_state = x`() => {}`;
}
}
// instrument assignments

@ -78,9 +78,10 @@ function instance($$self, $$props, $$invalidate) {
if ("name" in $$props) $$invalidate("name", name = $$props.name);
};
$$self.$capture_state = () => {
return { name };
};
$$self.$capture_state = ({ props: $props = true, local: $local = true } = {}) => ({
...$props && ({ name }),
...$local && ({})
});
$$self.$inject_state = $$props => {
if ("name" in $$props) $$invalidate("name", name = $$props.name);
@ -118,4 +119,4 @@ class Component extends SvelteComponentDev {
}
}
export default Component;
export default Component;

@ -175,9 +175,10 @@ function instance($$self, $$props, $$invalidate) {
if ("baz" in $$props) $$invalidate("baz", baz = $$props.baz);
};
$$self.$capture_state = () => {
return { things, foo, bar, baz };
};
$$self.$capture_state = ({ props: $props = true, local: $local = true } = {}) => ({
...$props && ({ things, foo, bar, baz }),
...$local && ({})
});
$$self.$inject_state = $$props => {
if ("things" in $$props) $$invalidate("things", things = $$props.things);
@ -254,4 +255,4 @@ class Component extends SvelteComponentDev {
}
}
export default Component;
export default Component;

@ -171,9 +171,10 @@ function instance($$self, $$props, $$invalidate) {
if ("foo" in $$props) $$invalidate("foo", foo = $$props.foo);
};
$$self.$capture_state = () => {
return { things, foo };
};
$$self.$capture_state = ({ props: $props = true, local: $local = true } = {}) => ({
...$props && ({ things, foo }),
...$local && ({})
});
$$self.$inject_state = $$props => {
if ("things" in $$props) $$invalidate("things", things = $$props.things);
@ -224,4 +225,4 @@ class Component extends SvelteComponentDev {
}
}
export default Component;
export default Component;

@ -49,9 +49,10 @@ let kobzol = 5;
function instance($$self) {
let obj = { x: 5 };
$$self.$capture_state = () => {
return {};
};
$$self.$capture_state = ({ props: $props = true, local: $local = true } = {}) => ({
...$props && ({}),
...$local && ({ obj, kobzol })
});
$$self.$inject_state = $$props => {
if ("obj" in $$props) $$invalidate("obj", obj = $$props.obj);
@ -75,4 +76,4 @@ class Component extends SvelteComponentDev {
}
}
export default Component;
export default Component;

@ -75,9 +75,10 @@ function instance($$self, $$props, $$invalidate) {
if ("foo" in $$props) $$invalidate("foo", foo = $$props.foo);
};
$$self.$capture_state = () => {
return { foo, bar };
};
$$self.$capture_state = ({ props: $props = true, local: $local = true } = {}) => ({
...$props && ({ foo }),
...$local && ({ bar })
});
$$self.$inject_state = $$props => {
if ("foo" in $$props) $$invalidate("foo", foo = $$props.foo);
@ -122,4 +123,4 @@ class Component extends SvelteComponentDev {
}
}
export default Component;
export default Component;

Loading…
Cancel
Save