reactive declarations

pull/3945/head
Rich Harris 6 years ago
parent 773a78071f
commit a74cc6996e

@ -332,7 +332,7 @@ export default class Expression {
} }
}); });
this.replace(invalidate(block.renderer, scope, node, traced)); this.replace(invalidate(block.renderer, scope, node, traced, false));
} }
} }
}); });

@ -138,13 +138,15 @@ export default class Renderer {
.reduce((lhs, rhs) => x`${lhs}, ${rhs}}`); .reduce((lhs, rhs) => x`${lhs}, ${rhs}}`);
} }
changed(names) { changed(names, needs_update) {
const bitmask = names.reduce((bits, name) => { const bitmask = names.reduce((bits, name) => {
const bit = 1 << this.context_lookup.get(name); const bit = 1 << this.context_lookup.get(name);
return bits | bit; return bits | bit;
}, 0); }, 0);
return x`#changed & ${bitmask}`; return needs_update
? x`(#changed = $$self.$$.dirty) & ${bitmask}`
: x`#changed & ${bitmask}`;
} }
reference(name) { reference(name) {

@ -3,7 +3,6 @@ import Component from '../Component';
import Renderer from './Renderer'; import Renderer from './Renderer';
import { CompileOptions } from '../../interfaces'; import { CompileOptions } from '../../interfaces';
import { walk } from 'estree-walker'; import { walk } from 'estree-walker';
import add_to_set from '../utils/add_to_set';
import { extract_names } from '../utils/scope'; import { extract_names } from '../utils/scope';
import { invalidate } from './invalidate'; import { invalidate } from './invalidate';
import Block from './Block'; import Block from './Block';
@ -282,11 +281,6 @@ export default function dom(
? component.alias('instance') ? component.alias('instance')
: { type: 'Literal', value: null }; : { type: 'Literal', value: null };
const all_reactive_dependencies = new Set();
component.reactive_declarations.forEach(d => {
add_to_set(all_reactive_dependencies, d.dependencies);
});
const reactive_store_subscriptions = reactive_stores const reactive_store_subscriptions = reactive_stores
.filter(store => { .filter(store => {
const variable = component.var_lookup.get(store.name.slice(1)); const variable = component.var_lookup.get(store.name.slice(1));
@ -317,7 +311,7 @@ export default function dom(
return variable && (variable.writable || variable.mutated); return variable && (variable.writable || variable.mutated);
}); });
const condition = !uses_props && writable.length > 0 && renderer.changed(writable); const condition = !uses_props && writable.length > 0 && renderer.changed(writable, true);
let statement = d.node; // TODO remove label (use d.node.body) if it's not referenced let statement = d.node; // TODO remove label (use d.node.body) if it's not referenced
@ -370,18 +364,6 @@ export default function dom(
}) as Expression : x`null`) }) as Expression : x`null`)
}; };
const reactive_dependencies = {
type: 'ObjectPattern',
properties: Array.from(all_reactive_dependencies).map(name => {
return {
type: 'Property',
kind: 'init',
key: { type: 'Identifier', name },
value: { type: 'Literal', value: 1 }
};
})
};
body.push(b` body.push(b`
function ${definition}(${args}) { function ${definition}(${args}) {
${reactive_store_declarations} ${reactive_store_declarations}
@ -409,7 +391,7 @@ export default function dom(
${injected.map(name => b`let ${name};`)} ${injected.map(name => b`let ${name};`)}
${reactive_declarations.length > 0 && b` ${reactive_declarations.length > 0 && b`
$$self.$$.update = (#changed = ${reactive_dependencies}) => { $$self.$$.update = #changed => {
${reactive_declarations} ${reactive_declarations}
}; };
`} `}

@ -186,7 +186,7 @@ export default class SlotWrapper extends Wrapper {
if (${slot} && ${slot}.p && ${renderer.changed(dynamic_dependencies)}) { if (${slot} && ${slot}.p && ${renderer.changed(dynamic_dependencies)}) {
${slot}.p( ${slot}.p(
@get_slot_context(${slot_definition}, #ctx, ${renderer.reference('$$scope')}, ${get_slot_context_fn}), @get_slot_context(${slot_definition}, #ctx, ${renderer.reference('$$scope')}, ${get_slot_context_fn}),
@get_slot_changes(${slot_definition}, #ctx, ${renderer.reference('$$scope')}, #changed, ${get_slot_changes_fn}) @get_slot_changes(${slot_definition}, ${renderer.reference('$$scope')}, #changed, ${get_slot_changes_fn})
); );
} }
`); `);

@ -24,7 +24,7 @@ interface T$$ {
dirty: number; dirty: number;
ctx: null|any; ctx: null|any;
bound: any; bound: any;
update: () => void; update: (n: number) => number;
callbacks: any; callbacks: any;
after_update: any[]; after_update: any[];
props: Record<string, 0 | string>; props: Record<string, 0 | string>;
@ -108,7 +108,7 @@ export function init(component, options, instance, create_fragment, not_equal, p
// state // state
props, props,
update: noop, update: (noop as unknown as (n: number) => number),
not_equal, not_equal,
bound: blank_object(), bound: blank_object(),
@ -136,7 +136,7 @@ export function init(component, options, instance, create_fragment, not_equal, p
}) })
: prop_values; : prop_values;
$$.update(); $$.update(-1);
ready = true; ready = true;
run_all($$.before_update); run_all($$.before_update);

@ -1,4 +1,4 @@
import { assign, is_promise } from './utils'; import { is_promise } from './utils';
import { check_outros, group_outros, transition_in, transition_out } from './transitions'; import { check_outros, group_outros, transition_in, transition_out } from './transitions';
import { flush } from './scheduler'; import { flush } from './scheduler';
import { get_current_component, set_current_component } from './lifecycle'; import { get_current_component, set_current_component } from './lifecycle';

@ -76,7 +76,7 @@ export function get_slot_context(definition, ctx, $$scope, fn) {
: $$scope.ctx; : $$scope.ctx;
} }
export function get_slot_changes(definition, ctx, $$scope, changed, fn) { export function get_slot_changes(definition, $$scope, changed, fn) {
return definition[1] return definition[1]
? assign({}, assign($$scope.changed || {}, definition[1](fn ? fn(changed) : {}))) ? assign({}, assign($$scope.changed || {}, definition[1](fn ? fn(changed) : {})))
: $$scope.changed || {}; : $$scope.changed || {};

Loading…
Cancel
Save