chore: split $.each into $.each_keyed/$.each_indexed (#9422)

* Split $.each into $.each_keyed/$.each_indexed

* Add changeset

* Update .changeset/quiet-camels-mate.md

* Fix typo

---------

Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
pull/9427/head
Dominic Gannaway 1 year ago committed by GitHub
parent 5a6afe5463
commit 8798f3b1e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,5 @@
---
'svelte': patch
---
chore: improve keyblock treeshaking

@ -2227,19 +2227,34 @@ export const template_visitors = {
declarations.push(b.let(node.index, index)); declarations.push(b.let(node.index, index));
} }
context.state.after_update.push( if ((each_type & EACH_KEYED) !== 0) {
b.stmt( context.state.after_update.push(
b.call( b.stmt(
'$.each', b.call(
context.state.node, '$.each_keyed',
each_node_meta.array_name ? each_node_meta.array_name : b.thunk(collection), context.state.node,
b.literal(each_type), each_node_meta.array_name ? each_node_meta.array_name : b.thunk(collection),
key_function, b.literal(each_type),
b.arrow([b.id('$$anchor'), item, index], b.block(declarations.concat(children))), key_function,
else_block b.arrow([b.id('$$anchor'), item, index], b.block(declarations.concat(children))),
else_block
)
) )
) );
); } else {
context.state.after_update.push(
b.stmt(
b.call(
'$.each_indexed',
context.state.node,
each_node_meta.array_name ? each_node_meta.array_name : b.thunk(collection),
b.literal(each_type),
b.arrow([b.id('$$anchor'), item, index], b.block(declarations.concat(children))),
else_block
)
)
);
}
}, },
IfBlock(node, context) { IfBlock(node, context) {
context.state.template.push('<!>'); context.state.template.push('<!>');

@ -260,9 +260,9 @@ export function reconcile_indexed_array(
* @param {Element | Comment | Text} dom * @param {Element | Comment | Text} dom
* @param {boolean} is_controlled * @param {boolean} is_controlled
* @param {(anchor: null, item: V, index: number | import('./types.js').Signal<number>) => void} render_fn * @param {(anchor: null, item: V, index: number | import('./types.js').Signal<number>) => void} render_fn
* @param {Array<string> | null} keys
* @param {number} flags * @param {number} flags
* @param {boolean} apply_transitions * @param {boolean} apply_transitions
* @param {Array<string> | null} keys
* @returns {void} * @returns {void}
*/ */
export function reconcile_tracked_array( export function reconcile_tracked_array(
@ -271,9 +271,9 @@ export function reconcile_tracked_array(
dom, dom,
is_controlled, is_controlled,
render_fn, render_fn,
keys,
flags, flags,
apply_transitions apply_transitions,
keys
) { ) {
var a_blocks = each_block.items; var a_blocks = each_block.items;
const is_computed_key = keys !== null; const is_computed_key = keys !== null;

@ -68,7 +68,7 @@ import {
hydrate_block_anchor, hydrate_block_anchor,
set_current_hydration_fragment set_current_hydration_fragment
} from './hydration.js'; } from './hydration.js';
import { array_from, define_property, get_descriptor, get_descriptors, is_array } from './utils.js'; import { array_from, define_property, get_descriptor, is_array } from './utils.js';
import { is_promise } from '../common.js'; import { is_promise } from '../common.js';
import { bind_transition } from './transitions.js'; import { bind_transition } from './transitions.js';
@ -2262,9 +2262,10 @@ export function each_item_block(item, key, index, render_fn, flags) {
* @param {null | ((item: V) => string)} key_fn * @param {null | ((item: V) => string)} key_fn
* @param {(anchor: null, item: V, index: import('./types.js').MaybeSignal<number>) => void} render_fn * @param {(anchor: null, item: V, index: import('./types.js').MaybeSignal<number>) => void} render_fn
* @param {null | ((anchor: Node) => void)} fallback_fn * @param {null | ((anchor: Node) => void)} fallback_fn
* @param {typeof reconcile_indexed_array | reconcile_tracked_array} reconcile_fn
* @returns {void} * @returns {void}
*/ */
export function each(anchor_node, collection, flags, key_fn, render_fn, fallback_fn) { function each(anchor_node, collection, flags, key_fn, render_fn, fallback_fn, reconcile_fn) {
const is_controlled = (flags & EACH_IS_CONTROLLED) !== 0; const is_controlled = (flags & EACH_IS_CONTROLLED) !== 0;
const block = create_each_block(flags, anchor_node); const block = create_each_block(flags, anchor_node);
@ -2384,20 +2385,7 @@ export function each(anchor_node, collection, flags, key_fn, render_fn, fallback
const flags = block.flags; const flags = block.flags;
const is_controlled = (flags & EACH_IS_CONTROLLED) !== 0; const is_controlled = (flags & EACH_IS_CONTROLLED) !== 0;
const anchor_node = block.anchor; const anchor_node = block.anchor;
if ((flags & EACH_KEYED) !== 0) { reconcile_fn(array, block, anchor_node, is_controlled, render_fn, flags, true, keys);
reconcile_tracked_array(
array,
block,
anchor_node,
is_controlled,
render_fn,
keys,
flags,
true
);
} else {
reconcile_indexed_array(array, block, anchor_node, is_controlled, render_fn, flags, true);
}
}, },
block, block,
true true
@ -2419,12 +2407,39 @@ export function each(anchor_node, collection, flags, key_fn, render_fn, fallback
fallback = fallback.prev; fallback = fallback.prev;
} }
// Clear the array // Clear the array
reconcile_indexed_array([], block, anchor_node, is_controlled, render_fn, flags, false); reconcile_fn([], block, anchor_node, is_controlled, render_fn, flags, false, keys);
destroy_signal(/** @type {import('./types.js').EffectSignal} */ (render)); destroy_signal(/** @type {import('./types.js').EffectSignal} */ (render));
}); });
block.effect = each; block.effect = each;
} }
/**
* @template V
* @param {Element | Comment} anchor_node
* @param {() => V[]} collection
* @param {number} flags
* @param {null | ((item: V) => string)} key_fn
* @param {(anchor: null, item: V, index: import('./types.js').MaybeSignal<number>) => void} render_fn
* @param {null | ((anchor: Node) => void)} fallback_fn
* @returns {void}
*/
export function each_keyed(anchor_node, collection, flags, key_fn, render_fn, fallback_fn) {
each(anchor_node, collection, flags, key_fn, render_fn, fallback_fn, reconcile_tracked_array);
}
/**
* @template V
* @param {Element | Comment} anchor_node
* @param {() => V[]} collection
* @param {number} flags
* @param {(anchor: null, item: V, index: import('./types.js').MaybeSignal<number>) => void} render_fn
* @param {null | ((anchor: Node) => void)} fallback_fn
* @returns {void}
*/
export function each_indexed(anchor_node, collection, flags, render_fn, fallback_fn) {
each(anchor_node, collection, flags, null, render_fn, fallback_fn, reconcile_indexed_array);
}
/** /**
* @param {Element | Text | Comment} anchor * @param {Element | Text | Comment} anchor
* @param {boolean} is_html * @param {boolean} is_html

Loading…
Cancel
Save