this repo has no description
at main 143 lines 3.4 kB view raw
1import { transition_in, transition_out } from './transitions.js'; 2import { run_all } from './utils.js'; 3 4// general each functions: 5 6export function ensure_array_like(array_like_or_iterator) { 7 return array_like_or_iterator?.length !== undefined 8 ? array_like_or_iterator 9 : Array.from(array_like_or_iterator); 10} 11 12// keyed each functions: 13 14/** @returns {void} */ 15export function destroy_block(block, lookup) { 16 block.d(1); 17 lookup.delete(block.key); 18} 19 20/** @returns {void} */ 21export function outro_and_destroy_block(block, lookup) { 22 transition_out(block, 1, 1, () => { 23 lookup.delete(block.key); 24 }); 25} 26 27/** @returns {void} */ 28export function fix_and_destroy_block(block, lookup) { 29 block.f(); 30 destroy_block(block, lookup); 31} 32 33/** @returns {void} */ 34export function fix_and_outro_and_destroy_block(block, lookup) { 35 block.f(); 36 outro_and_destroy_block(block, lookup); 37} 38 39/** @returns {any[]} */ 40export function update_keyed_each( 41 old_blocks, 42 dirty, 43 get_key, 44 dynamic, 45 ctx, 46 list, 47 lookup, 48 node, 49 destroy, 50 create_each_block, 51 next, 52 get_context 53) { 54 let o = old_blocks.length; 55 let n = list.length; 56 let i = o; 57 const old_indexes = {}; 58 while (i--) old_indexes[old_blocks[i].key] = i; 59 const new_blocks = []; 60 const new_lookup = new Map(); 61 const deltas = new Map(); 62 const updates = []; 63 i = n; 64 while (i--) { 65 const child_ctx = get_context(ctx, list, i); 66 const key = get_key(child_ctx); 67 let block = lookup.get(key); 68 if (!block) { 69 block = create_each_block(key, child_ctx); 70 block.c(); 71 } else if (dynamic) { 72 // defer updates until all the DOM shuffling is done 73 updates.push(() => block.p(child_ctx, dirty)); 74 } 75 new_lookup.set(key, (new_blocks[i] = block)); 76 if (key in old_indexes) deltas.set(key, Math.abs(i - old_indexes[key])); 77 } 78 const will_move = new Set(); 79 const did_move = new Set(); 80 /** @returns {void} */ 81 function insert(block) { 82 transition_in(block, 1); 83 block.m(node, next); 84 lookup.set(block.key, block); 85 next = block.first; 86 n--; 87 } 88 while (o && n) { 89 const new_block = new_blocks[n - 1]; 90 const old_block = old_blocks[o - 1]; 91 const new_key = new_block.key; 92 const old_key = old_block.key; 93 if (new_block === old_block) { 94 // do nothing 95 next = new_block.first; 96 o--; 97 n--; 98 } else if (!new_lookup.has(old_key)) { 99 // remove old block 100 destroy(old_block, lookup); 101 o--; 102 } else if (!lookup.has(new_key) || will_move.has(new_key)) { 103 insert(new_block); 104 } else if (did_move.has(old_key)) { 105 o--; 106 } else if (deltas.get(new_key) > deltas.get(old_key)) { 107 did_move.add(new_key); 108 insert(new_block); 109 } else { 110 will_move.add(old_key); 111 o--; 112 } 113 } 114 while (o--) { 115 const old_block = old_blocks[o]; 116 if (!new_lookup.has(old_block.key)) destroy(old_block, lookup); 117 } 118 while (n) insert(new_blocks[n - 1]); 119 run_all(updates); 120 return new_blocks; 121} 122 123/** @returns {void} */ 124export function validate_each_keys(ctx, list, get_context, get_key) { 125 const keys = new Map(); 126 for (let i = 0; i < list.length; i++) { 127 const key = get_key(get_context(ctx, list, i)); 128 if (keys.has(key)) { 129 let value = ''; 130 try { 131 value = `with value '${String(key)}' `; 132 } catch (e) { 133 // can't stringify 134 } 135 throw new Error( 136 `Cannot have duplicate keys in a keyed each: Keys at index ${keys.get( 137 key 138 )} and ${i} ${value}are duplicates` 139 ); 140 } 141 keys.set(key, i); 142 } 143}