/ node_modules / svelte / src / runtime / internal / await_block.js
await_block.js
  1  import { is_promise } from './utils.js';
  2  import { check_outros, group_outros, transition_in, transition_out } from './transitions.js';
  3  import { flush } from './scheduler.js';
  4  import { 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   */
 12  export 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} */
 90  export 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  }