chore: simplify blocks (#10873)

* reduce some indirection

* update tests

* unify blocks before we kill them

* refactor types, rename some stuff

* simplify

* remove block.e
pull/10874/head
Rich Harris 1 year ago committed by GitHub
parent b91392e5bd
commit 04879c53e9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1282,6 +1282,12 @@ function create_block(parent, name, nodes, context) {
// It's important that close is the last statement in the block, as any previous statements
// could contain element insertions into the template, which the close statement needs to
// know of when constructing the list of current inner elements.
if (context.path.length > 0) {
// this is a block — return DOM so it can be attached directly to the effect
close = b.return(close.expression);
}
body.push(close);
}

@ -2,7 +2,6 @@ import { is_promise } from '../../../common.js';
import { hydrate_block_anchor } from '../hydration.js';
import { remove } from '../reconciler.js';
import {
current_block,
current_component_context,
flushSync,
set_current_component_context,
@ -11,20 +10,7 @@ import {
} from '../../runtime.js';
import { destroy_effect, pause_effect, render_effect } from '../../reactivity/effects.js';
import { DESTROYED, INERT } from '../../constants.js';
/** @returns {import('../../types.js').AwaitBlock} */
export function create_await_block() {
return {
// dom
d: null,
// effect
e: null,
// parent
p: /** @type {import('../../types.js').Block} */ (current_block),
// pending
n: true
};
}
import { create_block } from './utils.js';
/**
* @template V
@ -36,7 +22,7 @@ export function create_await_block() {
* @returns {void}
*/
export function await_block(anchor, get_input, pending_fn, then_fn, catch_fn) {
const block = create_await_block();
const block = create_block();
const component_context = current_component_context;

@ -15,7 +15,7 @@ import {
} from '../hydration.js';
import { empty } from '../operations.js';
import { insert, remove } from '../reconciler.js';
import { current_block, untrack } from '../../runtime.js';
import { untrack } from '../../runtime.js';
import {
destroy_effect,
pause_effect,
@ -26,6 +26,7 @@ import {
import { source, mutable_source, set } from '../../reactivity/sources.js';
import { is_array, is_frozen, map_get, map_set } from '../../utils.js';
import { STATE_SYMBOL } from '../../constants.js';
import { create_block } from './utils.js';
var NEW_BLOCK = -1;
var LIS_BLOCK = -2;
@ -33,11 +34,11 @@ var LIS_BLOCK = -2;
/**
* The row of a keyed each block that is currently updating. We track this
* so that `animate:` directives have something to attach themselves to
* @type {import('#client').EachItemBlock | null}
* @type {import('#client').EachItem | null}
*/
export let current_each_item_block = null;
/** @param {import('#client').EachItemBlock | null} block */
/** @param {import('#client').EachItem | null} block */
export function set_current_each_item_block(block) {
current_each_item_block = block;
}
@ -54,18 +55,10 @@ export function set_current_each_item_block(block) {
* @returns {void}
*/
function each(anchor, get_collection, flags, get_key, render_fn, fallback_fn, reconcile_fn) {
/** @type {import('#client').EachBlock} */
var block = {
// dom
d: null,
// flags
f: flags,
// items
v: [],
// effect
e: null,
p: /** @type {import('#client').Block} */ (current_block)
};
var block = create_block();
/** @type {import('#client').EachState} */
var state = { flags, items: [] };
var is_controlled = (flags & EACH_IS_CONTROLLED) !== 0;
hydrate_block_anchor(is_controlled ? /** @type {Node} */ (anchor.firstChild) : anchor);
@ -94,7 +87,7 @@ function each(anchor, get_collection, flags, get_key, render_fn, fallback_fn, re
// If we are working with an array that isn't proxied or frozen, then remove strict equality and ensure the items
// are treated as reactive, so they get wrapped in a signal.
var flags = block.f;
var flags = state.flags;
if ((flags & EACH_IS_STRICT_EQUALS) !== 0 && !is_frozen(array) && !(STATE_SYMBOL in array)) {
flags ^= EACH_IS_STRICT_EQUALS;
@ -142,7 +135,7 @@ function each(anchor, get_collection, flags, get_key, render_fn, fallback_fn, re
break;
}
b_blocks[i] = create_block(array[i], keys?.[i], i, render_fn, flags);
b_blocks[i] = create_item(array[i], keys?.[i], i, render_fn, flags);
// TODO helperise this
hydrating_node = /** @type {import('#client').TemplateNode} */ (
@ -154,12 +147,12 @@ function each(anchor, get_collection, flags, get_key, render_fn, fallback_fn, re
remove_excess_hydration_nodes(hydration_list, hydrating_node);
block.v = b_blocks;
state.items = b_blocks;
}
if (!hydrating) {
// TODO add 'empty controlled block' optimisation here
reconcile_fn(array, block, anchor, render_fn, flags, keys);
reconcile_fn(array, state, anchor, render_fn, flags, keys);
}
if (fallback_fn !== null) {
@ -200,17 +193,15 @@ function each(anchor, get_collection, flags, get_key, render_fn, fallback_fn, re
);
effect.ondestroy = () => {
for (var b of block.v) {
if (b.d !== null) {
destroy_effect(b.e);
remove(b.d);
for (var item of state.items) {
if (item.d !== null) {
destroy_effect(item.e);
remove(item.d);
}
}
if (fallback) destroy_effect(fallback);
};
block.e = effect;
}
/**
@ -243,55 +234,55 @@ export function each_indexed(anchor, get_collection, flags, render_fn, fallback_
/**
* @template V
* @param {Array<V>} array
* @param {import('#client').EachBlock} each_block
* @param {import('#client').EachState} state
* @param {Element | Comment | Text} anchor
* @param {(anchor: null, item: V, index: number | import('#client').Source<number>) => void} render_fn
* @param {number} flags
* @returns {void}
*/
function reconcile_indexed_array(array, each_block, anchor, render_fn, flags) {
var a_blocks = each_block.v;
function reconcile_indexed_array(array, state, anchor, render_fn, flags) {
var a_items = state.items;
var a = a_blocks.length;
var a = a_items.length;
var b = array.length;
var min = Math.min(a, b);
/** @type {typeof a_blocks} */
var b_blocks = Array(b);
/** @type {typeof a_items} */
var b_items = Array(b);
var block;
var item;
var value;
// update items
for (var i = 0; i < min; i += 1) {
item = array[i];
block = a_blocks[i];
b_blocks[i] = block;
update_block(block, item, i, flags);
resume_effect(block.e);
value = array[i];
item = a_items[i];
b_items[i] = item;
update_item(item, value, i, flags);
resume_effect(item.e);
}
if (b > a) {
// add items
for (; i < b; i += 1) {
item = array[i];
block = create_block(item, null, i, render_fn, flags);
b_blocks[i] = block;
insert_block(block, anchor);
value = array[i];
item = create_item(value, null, i, render_fn, flags);
b_items[i] = item;
insert_item(item, anchor);
}
each_block.v = b_blocks;
state.items = b_items;
} else if (a > b) {
// remove items
var remaining = a - b;
var clear = () => {
for (var i = b; i < a; i += 1) {
var block = a_blocks[i];
var block = a_items[i];
if (block.d) remove(block.d);
}
each_block.v = each_block.v.slice(0, b);
state.items.length = b;
};
var check = () => {
@ -301,7 +292,7 @@ function reconcile_indexed_array(array, each_block, anchor, render_fn, flags) {
};
for (; i < a; i += 1) {
pause_effect(a_blocks[i].e, check);
pause_effect(a_items[i].e, check);
}
}
}
@ -312,20 +303,20 @@ function reconcile_indexed_array(array, each_block, anchor, render_fn, flags) {
* https://github.com/localvoid/ivi/blob/9f1bd0918f487da5b131941228604763c5d8ef56/packages/ivi/src/client/core.ts#L968
* @template V
* @param {Array<V>} array
* @param {import('#client').EachBlock} each_block
* @param {import('#client').EachState} state
* @param {Element | Comment | Text} anchor
* @param {(anchor: null, item: V, index: number | import('#client').Source<number>) => void} render_fn
* @param {number} flags
* @param {any[]} keys
* @returns {void}
*/
function reconcile_tracked_array(array, each_block, anchor, render_fn, flags, keys) {
var a_blocks = each_block.v;
function reconcile_tracked_array(array, state, anchor, render_fn, flags, keys) {
var a_blocks = state.items;
var a = a_blocks.length;
var b = array.length;
/** @type {Array<import('#client').EachItemBlock>} */
/** @type {Array<import('#client').EachItem>} */
var b_blocks = Array(b);
var is_animated = (flags & EACH_IS_ANIMATED) !== 0;
@ -333,7 +324,7 @@ function reconcile_tracked_array(array, each_block, anchor, render_fn, flags, ke
var start = 0;
var block;
/** @type {Array<import('#client').EachItemBlock>} */
/** @type {Array<import('#client').EachItem>} */
var to_destroy = [];
// Step 1 — trim common suffix
@ -344,7 +335,7 @@ function reconcile_tracked_array(array, each_block, anchor, render_fn, flags, ke
resume_effect(block.e);
if (should_update) {
update_block(block, array[b], b, flags);
update_item(block, array[b], b, flags);
}
}
@ -355,7 +346,7 @@ function reconcile_tracked_array(array, each_block, anchor, render_fn, flags, ke
resume_effect(block.e);
if (should_update) {
update_block(block, array[start], start, flags);
update_item(block, array[start], start, flags);
}
start += 1;
@ -365,9 +356,9 @@ function reconcile_tracked_array(array, each_block, anchor, render_fn, flags, ke
if (start === a) {
// add only
while (start < b) {
block = create_block(array[start], keys[start], start, render_fn, flags);
block = create_item(array[start], keys[start], start, render_fn, flags);
b_blocks[start++] = block;
insert_block(block, anchor);
insert_item(block, anchor);
}
} else if (start === b) {
// remove only
@ -390,7 +381,7 @@ function reconcile_tracked_array(array, each_block, anchor, render_fn, flags, ke
map_set(indexes, keys[i], i);
}
/** @type {Array<import('#client').EachItemBlock>} */
/** @type {Array<import('#client').EachItem>} */
var to_animate = [];
if (is_animated) {
// for all blocks that were in both the old and the new list,
@ -439,17 +430,17 @@ function reconcile_tracked_array(array, each_block, anchor, render_fn, flags, ke
var insert = index === NEW_BLOCK;
if (insert) {
block = create_block(array[b], keys[b], b, render_fn, flags);
block = create_item(array[b], keys[b], b, render_fn, flags);
} else {
block = b_blocks[b];
if (should_update) {
update_block(block, array[b], b, flags);
update_item(block, array[b], b, flags);
}
}
if (insert || (moved && index !== LIS_BLOCK)) {
last_sibling = last_block === undefined ? anchor : get_first_child(last_block);
anchor = insert_block(block, last_sibling);
anchor = insert_item(block, last_sibling);
}
last_block = b_blocks[b] = block;
@ -477,7 +468,7 @@ function reconcile_tracked_array(array, each_block, anchor, render_fn, flags, ke
if (block.d) remove(block.d);
}
each_block.v = b_blocks;
state.items = b_blocks;
};
var check = () => {
@ -490,7 +481,7 @@ function reconcile_tracked_array(array, each_block, anchor, render_fn, flags, ke
pause_effect(block.e, check);
}
} else {
each_block.v = b_blocks;
state.items = b_blocks;
}
}
@ -582,17 +573,17 @@ function mark_lis(a) {
}
/**
* @param {import('#client').Block} block
* @param {import('#client').EachItem} block
* @param {Text | Element | Comment} sibling
* @returns {Text | Element | Comment}
*/
function insert_block(block, sibling) {
function insert_item(block, sibling) {
var current = /** @type {import('#client').TemplateNode} */ (block.d);
return insert(current, sibling);
}
/**
* @param {import('#client').Block} block
* @param {import('#client').EachItem} block
* @returns {Text | Element | Comment}
*/
function get_first_child(block) {
@ -606,13 +597,13 @@ function get_first_child(block) {
}
/**
* @param {import('#client').EachItemBlock} block
* @param {import('#client').EachItem} block
* @param {any} item
* @param {number} index
* @param {number} type
* @returns {void}
*/
function update_block(block, item, index, type) {
function update_item(block, item, index, type) {
if ((type & EACH_ITEM_REACTIVE) !== 0) {
set(block.v, item);
}
@ -631,9 +622,9 @@ function update_block(block, item, index, type) {
* @param {number} index
* @param {(anchor: null, item: V, index: number | import('#client').Value<number>) => void} render_fn
* @param {number} flags
* @returns {import('#client').EachItemBlock}
* @returns {import('#client').EachItem}
*/
function create_block(item, key, index, render_fn, flags) {
function create_item(item, key, index, render_fn, flags) {
var each_item_not_reactive = (flags & EACH_ITEM_REACTIVE) === 0;
var item_value = each_item_not_reactive
@ -642,7 +633,7 @@ function create_block(item, key, index, render_fn, flags) {
? source(item)
: mutable_source(item);
/** @type {import('#client').EachItemBlock} */
/** @type {import('#client').EachItem} */
var block = {
a: null,
// dom

@ -6,46 +6,32 @@ import {
set_current_hydration_fragment
} from '../hydration.js';
import { remove } from '../reconciler.js';
import { current_block } from '../../runtime.js';
import {
destroy_effect,
pause_effect,
render_effect,
resume_effect
} from '../../reactivity/effects.js';
/** @returns {import('#client').IfBlock} */
function create_if_block() {
return {
// dom
d: null,
// effect
e: null,
// parent
p: /** @type {import('#client').Block} */ (current_block),
// value
v: false
};
}
import { create_block } from './utils.js';
/**
* @param {Comment} anchor
* @param {() => boolean} get_condition
* @param {(anchor: Node) => void} consequent_fn
* @param {null | ((anchor: Node) => void)} alternate_fn
* @param {(anchor: Node) => import('#client').TemplateNode | import('#client').TemplateNode[]} consequent_fn
* @param {null | ((anchor: Node) => import('#client').TemplateNode | import('#client').TemplateNode[])} alternate_fn
* @param {boolean} [elseif] True if this is an `{:else if ...}` block rather than an `{#if ...}`, as that affects which transitions are considered 'local'
* @returns {void}
*/
export function if_block(anchor, get_condition, consequent_fn, alternate_fn, elseif = false) {
const block = create_if_block();
const block = create_block();
hydrate_block_anchor(anchor);
/** @type {null | import('#client').TemplateNode | Array<import('#client').TemplateNode>} */
let consequent_dom = null;
/** @type {undefined | import('#client').TemplateNode | Array<import('#client').TemplateNode>} */
let consequent_dom;
/** @type {null | import('#client').TemplateNode | Array<import('#client').TemplateNode>} */
let alternate_dom = null;
/** @type {undefined | import('#client').TemplateNode | Array<import('#client').TemplateNode>} */
let alternate_dom;
/** @type {import('#client').Effect | null} */
let consequent_effect = null;
@ -87,15 +73,14 @@ export function if_block(anchor, get_condition, consequent_fn, alternate_fn, els
} else {
consequent_effect = render_effect(
() => {
consequent_fn(anchor);
consequent_dom = block.d;
consequent_dom = consequent_fn(anchor);
return () => {
// TODO make this unnecessary by linking the dom to the effect,
// and removing automatically on teardown
if (consequent_dom !== null) {
if (consequent_dom !== undefined) {
remove(consequent_dom);
consequent_dom = null;
consequent_dom = undefined;
}
};
},
@ -116,15 +101,14 @@ export function if_block(anchor, get_condition, consequent_fn, alternate_fn, els
} else if (alternate_fn) {
alternate_effect = render_effect(
() => {
alternate_fn(anchor);
alternate_dom = block.d;
alternate_dom = alternate_fn(anchor);
return () => {
// TODO make this unnecessary by linking the dom to the effect,
// and removing automatically on teardown
if (alternate_dom !== null) {
if (alternate_dom !== undefined) {
remove(alternate_dom);
alternate_dom = null;
alternate_dom = undefined;
}
};
},
@ -154,21 +138,20 @@ export function if_block(anchor, get_condition, consequent_fn, alternate_fn, els
if_effect.ondestroy = () => {
// TODO make this unnecessary by linking the dom to the effect,
// and removing automatically on teardown
if (consequent_dom !== null) {
if (consequent_dom !== undefined) {
remove(consequent_dom);
}
if (alternate_dom !== null) {
if (alternate_dom !== undefined) {
remove(alternate_dom);
}
if (consequent_effect) {
destroy_effect(consequent_effect);
}
if (alternate_effect) {
destroy_effect(alternate_effect);
}
};
block.e = if_effect;
}

@ -3,6 +3,7 @@ import { hydrate_block_anchor } from '../hydration.js';
import { remove } from '../reconciler.js';
import { pause_effect, render_effect } from '../../reactivity/effects.js';
import { safe_not_equal } from '../../reactivity/equality.js';
import { create_block } from './utils.js';
/**
* @template V
@ -12,7 +13,7 @@ import { safe_not_equal } from '../../reactivity/equality.js';
* @returns {void}
*/
export function key_block(anchor, get_key, render_fn) {
const block = {};
const block = create_block();
hydrate_block_anchor(anchor);
@ -43,7 +44,6 @@ export function key_block(anchor, get_key, render_fn) {
() => {
render_fn(anchor);
// @ts-expect-error TODO this should be unnecessary
const dom = block.d;
return () => {

@ -1,6 +1,7 @@
import { render_effect } from '../../reactivity/effects.js';
import { remove } from '../reconciler.js';
import { current_block, untrack } from '../../runtime.js';
import { untrack } from '../../runtime.js';
import { create_block } from './utils.js';
/**
* @param {() => Function | null | undefined} get_snippet
@ -9,15 +10,7 @@ import { current_block, untrack } from '../../runtime.js';
* @returns {void}
*/
export function snippet(get_snippet, node, ...args) {
/** @type {import('#client').SnippetBlock} */
const block = {
// dom
d: null,
// parent
p: /** @type {import('#client').Block} */ (current_block),
// effect
e: null
};
const block = create_block();
render_effect(() => {
// Only rerender when the snippet function itself changes,

@ -1,6 +1,7 @@
import { hydrate_block_anchor } from '../hydration.js';
import { pause_effect, render_effect } from '../../reactivity/effects.js';
import { remove } from '../reconciler.js';
import { create_block } from './utils.js';
// TODO this is very similar to `key`, can we deduplicate?
@ -13,7 +14,7 @@ import { remove } from '../reconciler.js';
* @returns {void}
*/
export function component(anchor, get_component, render_fn) {
const block = {};
const block = create_block();
hydrate_block_anchor(anchor);
@ -46,7 +47,6 @@ export function component(anchor, get_component, render_fn) {
() => {
render_fn(component);
// @ts-expect-error TODO this should be unnecessary
const dom = block.d;
return () => {

@ -8,10 +8,11 @@ import {
resume_effect
} from '../../reactivity/effects.js';
import { remove } from '../reconciler.js';
import { current_block } from '../../runtime.js';
import { is_array } from '../../utils.js';
import { set_should_intro } from '../../render.js';
import { current_each_item_block, set_current_each_item_block } from './each.js';
import { create_block } from './utils.js';
import { current_block } from '../../runtime.js';
/**
* @param {import('#client').Block} block
@ -41,15 +42,8 @@ function swap_block_dom(block, from, to) {
* @returns {void}
*/
export function element(anchor, get_tag, is_svg, render_fn) {
/** @type {import('#client').DynamicElementBlock} */
const block = {
// dom
d: null,
// effect
e: null,
// parent
p: /** @type {import('#client').Block} */ (current_block)
};
const parent_block = /** @type {import('#client').Block} */ (current_block);
const block = create_block();
hydrate_block_anchor(anchor);
@ -134,7 +128,7 @@ export function element(anchor, get_tag, is_svg, render_fn) {
anchor.before(element);
if (prev_element) {
swap_block_dom(block.p, prev_element, element);
swap_block_dom(parent_block, prev_element, element);
prev_element.remove();
}
},
@ -161,6 +155,4 @@ export function element(anchor, get_tag, is_svg, render_fn) {
destroy_effect(effect);
}
};
block.e = wrapper;
}

@ -7,22 +7,14 @@ import {
import { empty } from '../operations.js';
import { render_effect } from '../../reactivity/effects.js';
import { remove } from '../reconciler.js';
import { current_block } from '../../runtime.js';
import { create_block } from './utils.js';
/**
* @param {(anchor: Node | null) => void} render_fn
* @returns {void}
*/
export function head(render_fn) {
/** @type {import('#client').HeadBlock} */
const block = {
// dom
d: null,
// effect
e: null,
// parent
p: /** @type {import('#client').Block} */ (current_block)
};
const block = create_block();
// The head function may be called after the first hydration pass and ssr comment nodes may still be present,
// therefore we need to skip that when we detect that we're not in hydration mode.
@ -61,8 +53,6 @@ export function head(render_fn) {
remove(current);
}
};
block.e = head_effect;
} finally {
if (is_hydrating) {
set_current_hydration_fragment(previous_hydration_fragment);

@ -0,0 +1,7 @@
/** @returns {import('#client').Block} */
export function create_block() {
return {
// dom
d: null
};
}

@ -77,7 +77,7 @@ const linear = (t) => t;
* @param {(() => P) | null} get_params
*/
export function animation(element, get_fn, get_params) {
var block = /** @type {import('#client').EachItemBlock} */ (current_each_item_block);
var block = /** @type {import('#client').EachItem} */ (current_each_item_block);
/** @type {DOMRect} */
var from;

@ -178,7 +178,7 @@ export function comment(anchor) {
* @param {Element | Text} dom
* @param {boolean} is_fragment
* @param {null | Text | Comment | Element} anchor
* @returns {void}
* @returns {import('#client').TemplateNode | import('#client').TemplateNode[]}
*/
function close_template(dom, is_fragment, anchor) {
/** @type {import('#client').TemplateNode | Array<import('#client').TemplateNode>} */
@ -193,22 +193,22 @@ function close_template(dom, is_fragment, anchor) {
}
/** @type {import('#client').Block} */ (current_block).d = current;
return current;
}
/**
* @param {null | Text | Comment | Element} anchor
* @param {Element | Text} dom
* @returns {void}
*/
export function close(anchor, dom) {
close_template(dom, false, anchor);
return close_template(dom, false, anchor);
}
/**
* @param {null | Text | Comment | Element} anchor
* @param {Element | Text} dom
* @returns {void}
*/
export function close_frag(anchor, dom) {
close_template(dom, true, anchor);
return close_template(dom, true, anchor);
}

@ -211,16 +211,10 @@ function _mount(Component, options) {
should_intro = options.intro ?? false;
/** @type {import('#client').RootBlock} */
/** @type {import('#client').Block} */
const block = {
// dom
d: null,
// effect
e: null,
// intro
i: options.intro || false,
// parent
p: null
d: null
};
/** @type {Exports} */
@ -251,7 +245,7 @@ function _mount(Component, options) {
block,
true
);
block.e = effect;
const bound_event_listener = handle_event_propagation.bind(null, container);
const bound_document_event_listener = handle_event_propagation.bind(null, document);
@ -301,7 +295,7 @@ function _mount(Component, options) {
if (dom !== null) {
remove(dom);
}
destroy_effect(/** @type {import('./types.js').Effect} */ (block.e));
destroy_effect(effect);
});
return component;

@ -49,80 +49,19 @@ export type Equals = (this: Value, value: unknown) => boolean;
export type TemplateNode = Text | Element | Comment;
export type RootBlock = {
export interface Block {
/** dom */
d: null | TemplateNode | Array<TemplateNode>;
/** effect */
e: null | Effect;
/** intro */
i: boolean;
/** parent */
p: null;
};
export type IfBlock = {
/** value */
v: boolean;
/** dom */
d: null | TemplateNode | Array<TemplateNode>;
/** effect */
e: null | Effect;
/** parent */
p: Block;
};
export type HeadBlock = {
/** dom */
d: null | TemplateNode | Array<TemplateNode>;
/** effect */
e: null | Effect;
/** parent */
p: Block;
};
export type DynamicElementBlock = {
/** dom */
d: null | TemplateNode | Array<TemplateNode>;
/** effect */
e: null | Effect;
/** parent */
p: Block;
};
export type DynamicComponentBlock = {
/** dom */
d: null | TemplateNode | Array<TemplateNode>;
/** effect */
e: null | Effect;
/** parent */
p: Block;
};
export type AwaitBlock = {
/** dom */
d: null | TemplateNode | Array<TemplateNode>;
/** effect */
e: null | Effect;
/** parent */
p: Block;
/** pending */
n: boolean;
};
}
export type EachBlock = {
export type EachState = {
/** flags */
f: number;
/** dom */
d: null | TemplateNode | Array<TemplateNode>;
flags: number;
/** items */
v: EachItemBlock[];
/** effewct */
e: null | Effect;
/** parent */
p: Block;
items: EachItem[];
};
export type EachItemBlock = {
export type EachItem = {
/** animation manager */
a: AnimationManager | null;
/** dom */
@ -137,26 +76,6 @@ export type EachItemBlock = {
k: unknown;
};
export type SnippetBlock = {
/** dom */
d: null | TemplateNode | Array<TemplateNode>;
/** parent */
p: Block;
/** effect */
e: null | Effect;
};
export type Block =
| RootBlock
| IfBlock
| AwaitBlock
| DynamicElementBlock
| DynamicComponentBlock
| HeadBlock
| EachBlock
| EachItemBlock
| SnippetBlock;
export interface TransitionManager {
/** Whether the `global` modifier was used (i.e. `transition:fade|global`) */
is_global: boolean;

@ -21,11 +21,11 @@ export default function Each_string_template($$anchor, $$props) {
/* Update */
$.text_effect(text, () => `${$.stringify($.unwrap(thing))}, `);
$.close($$anchor, text);
return $.close($$anchor, text);
},
null
);
$.close_frag($$anchor, fragment);
$.pop();
}
}

@ -27,10 +27,10 @@ export default function Function_prop_no_getter($$anchor, $$props) {
/* Update */
$.text_effect(text, () => `clicks: ${$.stringify($.get(count))}`);
$.close($$anchor, text);
return $.close($$anchor, text);
}
});
$.close_frag($$anchor, fragment);
$.pop();
}
}

Loading…
Cancel
Save