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

95.74% Statements 45/47
91.66% Branches 11/12
100% Functions 1/1
95.34% Lines 41/43

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 442x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 102x 102x 102x 102x 18x 18x 18x 40x 40x 40x 40x 40x 40x 40x 40x 22x 22x 18x 18x 18x 18x     18x 102x 102x 48x 48x 102x 102x  
import { effect, render_effect } from '../../reactivity/effects.js';
import { deep_read_state, untrack } from '../../runtime.js';
import { hydrating } from '../hydration.js';
import { hydrate_event_replay } from './events.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 (hydrating) {
				hydrate_event_replay(/** @type {HTMLElement} */ (dom));
			}
		}
 
		if (payload?.destroy) {
			return () => /** @type {Function} */ (payload.destroy)();
		}
	});
}