|
|
|
@ -42,6 +42,9 @@ import { active_effect, get } from '../../runtime.js';
|
|
|
|
|
import { DEV } from 'esm-env';
|
|
|
|
|
import { derived_safe_equal } from '../../reactivity/deriveds.js';
|
|
|
|
|
import { current_batch } from '../../reactivity/batch.js';
|
|
|
|
|
import { each_key_duplicate } from '../../errors.js';
|
|
|
|
|
import { validate_each_keys } from '../../validate.js';
|
|
|
|
|
import { invoke_error_boundary } from '../../error-handling.js';
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The row of a keyed each block that is currently updating. We track this
|
|
|
|
@ -201,6 +204,11 @@ export function each(node, flags, get_collection, get_key, render_fn, fallback_f
|
|
|
|
|
}
|
|
|
|
|
was_empty = length === 0;
|
|
|
|
|
|
|
|
|
|
// skip if #each block isn't keyed
|
|
|
|
|
if (DEV && get_key !== index) {
|
|
|
|
|
validate_each_keys(array, get_key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** `true` if there was a hydration mismatch. Needs to be a `let` or else it isn't treeshaken out */
|
|
|
|
|
let mismatch = false;
|
|
|
|
|
|
|
|
|
@ -266,6 +274,8 @@ export function each(node, flags, get_collection, get_key, render_fn, fallback_f
|
|
|
|
|
if (hydrating) {
|
|
|
|
|
if (length === 0 && fallback_fn) {
|
|
|
|
|
fallback = branch(() => fallback_fn(anchor));
|
|
|
|
|
} else if (length > state.items.size) {
|
|
|
|
|
each_key_duplicate('', '', '');
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (should_defer_append()) {
|
|
|
|
@ -363,6 +373,7 @@ function reconcile(
|
|
|
|
|
var is_animated = (flags & EACH_IS_ANIMATED) !== 0;
|
|
|
|
|
var should_update = (flags & (EACH_ITEM_REACTIVE | EACH_INDEX_REACTIVE)) !== 0;
|
|
|
|
|
|
|
|
|
|
var count = 0;
|
|
|
|
|
var length = array.length;
|
|
|
|
|
var items = state.items;
|
|
|
|
|
var first = state.first;
|
|
|
|
@ -451,6 +462,7 @@ function reconcile(
|
|
|
|
|
stashed = [];
|
|
|
|
|
|
|
|
|
|
current = prev.next;
|
|
|
|
|
count += 1;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -473,6 +485,19 @@ function reconcile(
|
|
|
|
|
var start = stashed[0];
|
|
|
|
|
var j;
|
|
|
|
|
|
|
|
|
|
// full key uniqueness check is dev-only,
|
|
|
|
|
// key duplicates cause crash only due to `matched` being empty
|
|
|
|
|
if (matched.length === 0) {
|
|
|
|
|
// reconcile can be called in the batch's callbacks which are
|
|
|
|
|
// executed outside of the effect tree, so error are not caught
|
|
|
|
|
try {
|
|
|
|
|
each_key_duplicate('', '', '');
|
|
|
|
|
} catch (error) {
|
|
|
|
|
invoke_error_boundary(error, each_effect);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
prev = start.prev;
|
|
|
|
|
|
|
|
|
|
var a = matched[0];
|
|
|
|
@ -506,6 +531,7 @@ function reconcile(
|
|
|
|
|
link(state, prev, item);
|
|
|
|
|
|
|
|
|
|
prev = item;
|
|
|
|
|
count += 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
continue;
|
|
|
|
@ -534,6 +560,20 @@ function reconcile(
|
|
|
|
|
matched.push(item);
|
|
|
|
|
prev = item;
|
|
|
|
|
current = item.next;
|
|
|
|
|
count += 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Full key uniqueness check is dev-only. If keys duplication didn't cause a crash,
|
|
|
|
|
// the rendered list will be shorter then the source array
|
|
|
|
|
if (count !== length) {
|
|
|
|
|
// reconcile can be called in the batch's callbacks which are
|
|
|
|
|
// executed outside of the effect tree, so error are not caught
|
|
|
|
|
try {
|
|
|
|
|
each_key_duplicate('', '', '');
|
|
|
|
|
} catch (error) {
|
|
|
|
|
invoke_error_boundary(error, each_effect);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (current !== null || seen !== undefined) {
|
|
|
|
|