All files / src/internal/client/dom/legacy lifecycle.js

100% Statements 85/85
100% Branches 26/26
100% Functions 4/4
100% Lines 81/81

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 822x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2786x 2786x 2786x 2786x 2149x 2149x 2149x 2786x 8x 8x 8x 8x 8x 20x 20x 20x 38x 18x 18x 18x 38x 20x 20x 8x 8x 8x 8x 2149x 2149x 2784x 2038x 2076x 2076x 2038x 2038x 2149x 2149x 2149x 2149x 2149x 2147x 119x 44x 44x 119x 2149x 2149x 2149x 2149x 2786x 26x 48x 48x 26x 26x 2786x 2x 2x 2x 2x 2x 2x 2x 2124x 2124x 2122x 2122x 2124x 2124x 2124x  
/** @import { ComponentContextLegacy } from '#client' */
import { run, run_all } from '../../../shared/utils.js';
import { derived } from '../../reactivity/deriveds.js';
import { user_pre_effect, user_effect } from '../../reactivity/effects.js';
import { component_context, deep_read_state, get, untrack } from '../../runtime.js';
 
/**
 * Legacy-mode only: Call `onMount` callbacks and set up `beforeUpdate`/`afterUpdate` effects
 * @param {boolean} [immutable]
 */
export function init(immutable = false) {
	const context = /** @type {ComponentContextLegacy} */ (component_context);
 
	const callbacks = context.l.u;
	if (!callbacks) return;
 
	let props = () => deep_read_state(context.s);
 
	if (immutable) {
		let version = 0;
		let prev = /** @type {Record<string, any>} */ ({});
 
		// In legacy immutable mode, before/afterUpdate only fire if the object identity of a prop changes
		const d = derived(() => {
			let changed = false;
			const props = context.s;
			for (const key in props) {
				if (props[key] !== prev[key]) {
					prev[key] = props[key];
					changed = true;
				}
			}
			if (changed) version++;
			return version;
		});
 
		props = () => get(d);
	}
 
	// beforeUpdate
	if (callbacks.b.length) {
		user_pre_effect(() => {
			observe_all(context, props);
			run_all(callbacks.b);
		});
	}
 
	// onMount (must run before afterUpdate)
	user_effect(() => {
		const fns = untrack(() => callbacks.m.map(run));
		return () => {
			for (const fn of fns) {
				if (typeof fn === 'function') {
					fn();
				}
			}
		};
	});
 
	// afterUpdate
	if (callbacks.a.length) {
		user_effect(() => {
			observe_all(context, props);
			run_all(callbacks.a);
		});
	}
}
 
/**
 * Invoke the getter of all signals associated with a component
 * so they can be registered to the effect this function is called in.
 * @param {ComponentContextLegacy} context
 * @param {(() => void)} props
 */
function observe_all(context, props) {
	if (context.l.s) {
		for (const signal of context.l.s) get(signal);
	}
 
	props();
}