this repo has no description
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}