All files / src/internal/client/dom/elements actions.js

100% Statements 40/40
100% Branches 11/11
100% Functions 1/1
100% Lines 38/38

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 392x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 76x 76x 76x 76x 14x 14x 14x 30x 30x 30x 30x 30x 30x 30x 30x 16x 16x 14x 14x 14x 14x 76x 76x 44x 44x 76x 76x  
import { effect, render_effect } from '../../reactivity/effects.js';
import { deep_read_state, untrack } from '../../runtime.js';
 
/**
 * @template P
 * @param {Element} dom
 * @param {(dom: Element, value?: P) => import('#client').ActionPayload<P>} action
 * @param {() => P} [get_value]
 * @returns {void}
 */
export function action(dom, action, get_value) {
	effect(() => {
		var payload = untrack(() => action(dom, get_value?.()) || {});
 
		if (get_value && payload?.update) {
			var inited = false;
 
			render_effect(() => {
				var value = get_value();
 
				// Action's update method is coarse-grained, i.e. when anything in the passed value changes, update.
				// This works in legacy mode because of mutable_source being updated as a whole, but when using $state
				// together with actions and mutation, it wouldn't notice the change without a deep read.
				deep_read_state(value);
 
				if (inited) {
					/** @type {Function} */ (payload.update)(value);
				}
			});
 
			inited = true;
		}
 
		if (payload?.destroy) {
			return () => /** @type {Function} */ (payload.destroy)();
		}
	});
}