|
|
|
|
@ -1,8 +1,6 @@
|
|
|
|
|
import { block, branch, pause_effect, render_effect } from '../../reactivity/effects.js';
|
|
|
|
|
import { remove } from '../reconciler.js';
|
|
|
|
|
import { current_effect } from '../../runtime.js';
|
|
|
|
|
import { block, branch, pause_effect } from '../../reactivity/effects.js';
|
|
|
|
|
|
|
|
|
|
// TODO this is very similar to `key`, can we deduplicate?
|
|
|
|
|
// TODO seems weird that `anchor` is unused here — possible bug?
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @template P
|
|
|
|
|
@ -16,46 +14,19 @@ export function component(anchor, get_component, render_fn) {
|
|
|
|
|
/** @type {C} */
|
|
|
|
|
let component;
|
|
|
|
|
|
|
|
|
|
/** @type {import('#client').Effect} */
|
|
|
|
|
/** @type {import('#client').Effect | null} */
|
|
|
|
|
let effect;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Every time `component` changes, we create a new effect. Old effects are
|
|
|
|
|
* removed from this set when they have fully transitioned out
|
|
|
|
|
* @type {Set<import('#client').Effect>}
|
|
|
|
|
*/
|
|
|
|
|
let effects = new Set();
|
|
|
|
|
|
|
|
|
|
const component_effect = block(() => {
|
|
|
|
|
block(() => {
|
|
|
|
|
if (component === (component = get_component())) return;
|
|
|
|
|
|
|
|
|
|
if (effect) {
|
|
|
|
|
var e = effect;
|
|
|
|
|
pause_effect(e, () => {
|
|
|
|
|
effects.delete(e);
|
|
|
|
|
});
|
|
|
|
|
pause_effect(effect);
|
|
|
|
|
effect = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (component) {
|
|
|
|
|
effect = branch(() => {
|
|
|
|
|
render_fn(component);
|
|
|
|
|
|
|
|
|
|
// `render_fn` doesn't return anything, and we can't reference `effect`
|
|
|
|
|
// yet, so we reference it indirectly as `current_effect`
|
|
|
|
|
const dom = /** @type {import('#client').Effect} */ (current_effect).dom;
|
|
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
if (dom !== null) remove(dom);
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
effects.add(effect);
|
|
|
|
|
effect = branch(() => render_fn(component));
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
component_effect.ondestroy = () => {
|
|
|
|
|
for (const e of effects) {
|
|
|
|
|
if (e.dom) remove(e.dom);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|