this repo has no description
at main 100 lines 2.6 kB view raw
1import { is_promise } from './utils.js'; 2import { check_outros, group_outros, transition_in, transition_out } from './transitions.js'; 3import { flush } from './scheduler.js'; 4import { get_current_component, set_current_component } from './lifecycle.js'; 5 6/** 7 * @template T 8 * @param {Promise<T>} promise 9 * @param {import('./private.js').PromiseInfo<T>} info 10 * @returns {boolean} 11 */ 12export function handle_promise(promise, info) { 13 const token = (info.token = {}); 14 /** 15 * @param {import('./private.js').FragmentFactory} type 16 * @param {0 | 1 | 2} index 17 * @param {number} [key] 18 * @param {any} [value] 19 * @returns {void} 20 */ 21 function update(type, index, key, value) { 22 if (info.token !== token) return; 23 info.resolved = value; 24 let child_ctx = info.ctx; 25 if (key !== undefined) { 26 child_ctx = child_ctx.slice(); 27 child_ctx[key] = value; 28 } 29 const block = type && (info.current = type)(child_ctx); 30 let needs_flush = false; 31 if (info.block) { 32 if (info.blocks) { 33 info.blocks.forEach((block, i) => { 34 if (i !== index && block) { 35 group_outros(); 36 transition_out(block, 1, 1, () => { 37 if (info.blocks[i] === block) { 38 info.blocks[i] = null; 39 } 40 }); 41 check_outros(); 42 } 43 }); 44 } else { 45 info.block.d(1); 46 } 47 block.c(); 48 transition_in(block, 1); 49 block.m(info.mount(), info.anchor); 50 needs_flush = true; 51 } 52 info.block = block; 53 if (info.blocks) info.blocks[index] = block; 54 if (needs_flush) { 55 flush(); 56 } 57 } 58 if (is_promise(promise)) { 59 const current_component = get_current_component(); 60 promise.then( 61 (value) => { 62 set_current_component(current_component); 63 update(info.then, 1, info.value, value); 64 set_current_component(null); 65 }, 66 (error) => { 67 set_current_component(current_component); 68 update(info.catch, 2, info.error, error); 69 set_current_component(null); 70 if (!info.hasCatch) { 71 throw error; 72 } 73 } 74 ); 75 // if we previously had a then/catch block, destroy it 76 if (info.current !== info.pending) { 77 update(info.pending, 0); 78 return true; 79 } 80 } else { 81 if (info.current !== info.then) { 82 update(info.then, 1, info.value, promise); 83 return true; 84 } 85 info.resolved = /** @type {T} */ (promise); 86 } 87} 88 89/** @returns {void} */ 90export function update_await_block_branch(info, ctx, dirty) { 91 const child_ctx = ctx.slice(); 92 const { resolved } = info; 93 if (info.current === info.then) { 94 child_ctx[info.value] = resolved; 95 } 96 if (info.current === info.catch) { 97 child_ctx[info.error] = resolved; 98 } 99 info.block.p(child_ctx, dirty); 100}