From 17c0c67747b6b9970f4ada96e622889bf6a648c8 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Mon, 8 May 2023 21:52:24 -0600 Subject: [PATCH] Convert src/runtime/internal/keyed_each.ts to JavaScript --- src/runtime/internal/keyed_each.ts | 237 ++++++++++++++--------------- 1 file changed, 111 insertions(+), 126 deletions(-) diff --git a/src/runtime/internal/keyed_each.ts b/src/runtime/internal/keyed_each.ts index f08a1e063b..52af960bab 100644 --- a/src/runtime/internal/keyed_each.ts +++ b/src/runtime/internal/keyed_each.ts @@ -1,140 +1,125 @@ import { transition_in, transition_out } from './transitions'; import { run_all } from './utils'; - +/** @returns {void} */ export function destroy_block(block, lookup) { - block.d(1); - lookup.delete(block.key); + block.d(1); + lookup.delete(block.key); } - +/** @returns {void} */ export function outro_and_destroy_block(block, lookup) { - transition_out(block, 1, 1, () => { - lookup.delete(block.key); - }); + transition_out(block, 1, 1, () => { + lookup.delete(block.key); + }); } - +/** @returns {void} */ export function fix_and_destroy_block(block, lookup) { - block.f(); - destroy_block(block, lookup); + block.f(); + destroy_block(block, lookup); } - +/** @returns {void} */ export function fix_and_outro_and_destroy_block(block, lookup) { - block.f(); - outro_and_destroy_block(block, lookup); + block.f(); + outro_and_destroy_block(block, lookup); +} +/** @returns {any[]} */ +export function update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list, lookup, node, destroy, create_each_block, next, get_context) { + let o = old_blocks.length; + let n = list.length; + let i = o; + const old_indexes = {}; + while (i--) + old_indexes[old_blocks[i].key] = i; + const new_blocks = []; + const new_lookup = new Map(); + const deltas = new Map(); + const updates = []; + i = n; + while (i--) { + const child_ctx = get_context(ctx, list, i); + const key = get_key(child_ctx); + let block = lookup.get(key); + if (!block) { + block = create_each_block(key, child_ctx); + block.c(); + } + else if (dynamic) { + // defer updates until all the DOM shuffling is done + updates.push(() => block.p(child_ctx, dirty)); + } + new_lookup.set(key, (new_blocks[i] = block)); + if (key in old_indexes) + deltas.set(key, Math.abs(i - old_indexes[key])); + } + const will_move = new Set(); + const did_move = new Set(); + /** @returns {void} */ + function insert(block) { + transition_in(block, 1); + block.m(node, next); + lookup.set(block.key, block); + next = block.first; + n--; + } + while (o && n) { + const new_block = new_blocks[n - 1]; + const old_block = old_blocks[o - 1]; + const new_key = new_block.key; + const old_key = old_block.key; + if (new_block === old_block) { + // do nothing + next = new_block.first; + o--; + n--; + } + else if (!new_lookup.has(old_key)) { + // remove old block + destroy(old_block, lookup); + o--; + } + else if (!lookup.has(new_key) || will_move.has(new_key)) { + insert(new_block); + } + else if (did_move.has(old_key)) { + o--; + } + else if (deltas.get(new_key) > deltas.get(old_key)) { + did_move.add(new_key); + insert(new_block); + } + else { + will_move.add(old_key); + o--; + } + } + while (o--) { + const old_block = old_blocks[o]; + if (!new_lookup.has(old_block.key)) + destroy(old_block, lookup); + } + while (n) + insert(new_blocks[n - 1]); + run_all(updates); + return new_blocks; +} +/** @returns {void} */ +export function validate_each_keys(ctx, list, get_context, get_key) { + const keys = new Map(); + for (let i = 0; i < list.length; i++) { + const key = get_key(get_context(ctx, list, i)); + if (keys.has(key)) { + let value = ''; + try { + value = `with value '${String(key)}' `; + } + catch (e) { + // can't stringify + } + throw new Error(`Cannot have duplicate keys in a keyed each: Keys at index ${keys.get(key)} and ${i} ${value}are duplicates`); + } + keys.set(key, i); + } } -export function update_keyed_each( - old_blocks, - dirty, - get_key, - dynamic, - ctx, - list, - lookup, - node, - destroy, - create_each_block, - next, - get_context -) { - let o = old_blocks.length; - let n = list.length; - - let i = o; - const old_indexes = {}; - while (i--) old_indexes[old_blocks[i].key] = i; - - const new_blocks = []; - const new_lookup = new Map(); - const deltas = new Map(); - const updates = []; - - i = n; - while (i--) { - const child_ctx = get_context(ctx, list, i); - const key = get_key(child_ctx); - let block = lookup.get(key); - - if (!block) { - block = create_each_block(key, child_ctx); - block.c(); - } else if (dynamic) { - // defer updates until all the DOM shuffling is done - updates.push(() => block.p(child_ctx, dirty)); - } - - new_lookup.set(key, (new_blocks[i] = block)); - - if (key in old_indexes) deltas.set(key, Math.abs(i - old_indexes[key])); - } - - const will_move = new Set(); - const did_move = new Set(); - - function insert(block) { - transition_in(block, 1); - block.m(node, next); - lookup.set(block.key, block); - next = block.first; - n--; - } - - while (o && n) { - const new_block = new_blocks[n - 1]; - const old_block = old_blocks[o - 1]; - const new_key = new_block.key; - const old_key = old_block.key; - - if (new_block === old_block) { - // do nothing - next = new_block.first; - o--; - n--; - } else if (!new_lookup.has(old_key)) { - // remove old block - destroy(old_block, lookup); - o--; - } else if (!lookup.has(new_key) || will_move.has(new_key)) { - insert(new_block); - } else if (did_move.has(old_key)) { - o--; - } else if (deltas.get(new_key) > deltas.get(old_key)) { - did_move.add(new_key); - insert(new_block); - } else { - will_move.add(old_key); - o--; - } - } - - while (o--) { - const old_block = old_blocks[o]; - if (!new_lookup.has(old_block.key)) destroy(old_block, lookup); - } - - while (n) insert(new_blocks[n - 1]); - run_all(updates); - return new_blocks; -} -export function validate_each_keys(ctx, list, get_context, get_key) { - const keys = new Map(); - for (let i = 0; i < list.length; i++) { - const key = get_key(get_context(ctx, list, i)); - if (keys.has(key)) { - let value = ''; - try { - value = `with value '${String(key)}' `; - } catch (e) { - // can't stringify - } - throw new Error( - `Cannot have duplicate keys in a keyed each: Keys at index ${keys.get( - key - )} and ${i} ${value}are duplicates` - ); - } - keys.set(key, i); - } -}