<commit_before>import { options } from 'preact';

/** @type {number} */
let currentIndex;

/** @type {import('./internal').Component} */
let currentComponent;

/** @type {Array<import('./internal').Component>} */
let afterPaintEffects = [];

/** @type {boolean} */
let stateChanged;

let oldBeforeRender = options.beforeRender;
options.beforeRender = vnode => {
	if (oldBeforeRender) oldBeforeRender(vnode);

	currentComponent = vnode._component;
	currentIndex = 0;

	if (!currentComponent.__hooks) return;
	currentComponent.__hooks._pendingEffects.forEach(invokeEffect);
	currentComponent.__hooks._pendingEffects = [];
};


let oldAfterDiff = options.afterDiff;
options.afterDiff = vnode => {
	if (oldAfterDiff) oldAfterDiff(vnode);

	const c = vnode._component;
	if (!c) return;

	const hooks = c.__hooks;
	if (!hooks) return;

	stateChanged = false;

	hooks._pendingLayoutEffects.forEach(invokeEffect);
	hooks._pendingLayoutEffects = [];

	if (stateChanged) c.forceUpdate();
};


let oldBeforeUnmount = options.beforeUnmount;
options.beforeUnmount = vnode => {
	if (oldBeforeUnmount) oldBeforeUnmount(vnode);

	const hooks = vnode._component.__hooks;
	if (!hooks) return;

	hooks._list.forEach(hook => hook._cleanup && hook._cleanup());
};

/**
 * Get a hook's state from the currentComponent
 * @template State
 * @param {number} index The index of the hook to get
 * @param {State} initialState The initial state of the hook
 * @returns {State}
 */
function getHookState(index, initialState) {
	// Largely inspired by:
	// * https://github.com/michael-klein/funcy.js/blob/master/src/hooks/core_hooks.mjs
	// * https://github.com/michael-klein/funcy.js/blob/master/src/lib/renderer.mjs
	// Other implementations to look at:
	// * https://codesandbox.io/s/mnox05qp8

	const hooks = currentComponent.__hooks || (currentComponent.__hooks = { _list: [], _pendingEffects: [], _pendingLayoutEffects: [] });

	// 503 B
	if (index >= hooks._list.length) {
		hooks._list.push(initialState);
	}
	return hooks._list[index];

	// 506 B
	// if (index >= hooks._list.length) {
	// 	hooks._list.push(initialState);
	// 	return initialState;
	// }
	// else {
	// 	return hooks._list[index];
	// }

	// 505 B
	// if (index < hooks._list.length) {
	// 	return hooks._list[index];
	// }
	// else {
	// 	hooks._list.push(initialState);
	// 	return initialState;
	// }
}

export function useState(initialState) {
	return useReducer(invokeOrReturn, initialState);
}

export function useReducer(reducer, initialState, initialAction) {
	// 717 B
	// /** @type {import('./internal').ReducerHookState} */
	// const state = getHookState(currentIndex++, { _component: currentComponent });
	// if (!('_value' in state)) {
	// 	// state._value = typeof initialState === 'function' ? initialState(): initialState;
	// 	// state._value = initialAction ? reducer(invokeOrReturn(null, initialState), initialAction) : invokeOrReturn(null, initialState);
	// 	state._value = invokeOrReturn(null, initialState);
	// 	if (initialAction) {
	// 		state._value = reducer(state._value, initialAction);
	// 	}
	// }
	// return [
	// 	state._value,
	// 	action => {
	// 		state._value = reducer(state._value, action);
	// 		stateChanged = true; // +(15-18) B!!
	// 		state._component.setState({});
	// 	}
	// ];

	// 723 B
	/** @type {import('./internal').ReducerHookState} */
	const hookState = getHookState(currentIndex++, { _component: currentComponent });
	if (!('_value' in hookState)) {
		hookState._value = [
			initialAction
				? reducer(invokeOrReturn(null, initialState), initialAction)
				: invokeOrReturn(null, initialState),
			action => {
				hookState._value[0] = reducer(hookState._value[0], action);
				stateChanged = true;
				hookState._component.setState({});
			}
		];
	}
	return hookState._value;
}

/**
 * @param {import('./internal').Effect} callback
 * @param {any[]} args
 */
export function useEffect(callback, args) {

	/** @type {import('./internal').EffectHookState} */
	const state = getHookState(currentIndex++, {});
	// const state = getHookState(currentIndex++, { _value: callback, _args: null, _cleanup: null }); // +11 B
	// if (args == null || state._args == null || args.some((prop, index) => prop !== state._args[index])) { // -1 B
	if (argsChanged(state._args, args)) {
		state._value = callback;
		state._args = args;
<commit_msg>Golf useReducer initialization (716 B)<commit_after>import { options } from 'preact';

/** @type {number} */
let currentIndex;

/** @type {import('./internal').Component} */
let currentComponent;

/** @type {Array<import('./internal').Component>} */
let afterPaintEffects = [];

/** @type {boolean} */
let stateChanged;

let oldBeforeRender = options.beforeRender;
options.beforeRender = vnode => {
	if (oldBeforeRender) oldBeforeRender(vnode);

	currentComponent = vnode._component;
	currentIndex = 0;

	if (!currentComponent.__hooks) return;
	currentComponent.__hooks._pendingEffects.forEach(invokeEffect);
	currentComponent.__hooks._pendingEffects = [];
};


let oldAfterDiff = options.afterDiff;
options.afterDiff = vnode => {
	if (oldAfterDiff) oldAfterDiff(vnode);

	const c = vnode._component;
	if (!c) return;

	const hooks = c.__hooks;
	if (!hooks) return;

	stateChanged = false;

	hooks._pendingLayoutEffects.forEach(invokeEffect);
	hooks._pendingLayoutEffects = [];

	if (stateChanged) c.forceUpdate();
};


let oldBeforeUnmount = options.beforeUnmount;
options.beforeUnmount = vnode => {
	if (oldBeforeUnmount) oldBeforeUnmount(vnode);

	const hooks = vnode._component.__hooks;
	if (!hooks) return;

	hooks._list.forEach(hook => hook._cleanup && hook._cleanup());
};

/**
 * Get a hook's state from the currentComponent
 * @template State
 * @param {number} index The index of the hook to get
 * @param {State} initialState The initial state of the hook
 * @returns {State}
 */
function getHookState(index, initialState) {
	// Largely inspired by:
	// * https://github.com/michael-klein/funcy.js/blob/master/src/hooks/core_hooks.mjs
	// * https://github.com/michael-klein/funcy.js/blob/master/src/lib/renderer.mjs
	// Other implementations to look at:
	// * https://codesandbox.io/s/mnox05qp8

	const hooks = currentComponent.__hooks || (currentComponent.__hooks = { _list: [], _pendingEffects: [], _pendingLayoutEffects: [] });

	// 503 B
	if (index >= hooks._list.length) {
		hooks._list.push(initialState);
	}
	return hooks._list[index];

	// 506 B
	// if (index >= hooks._list.length) {
	// 	hooks._list.push(initialState);
	// 	return initialState;
	// }
	// else {
	// 	return hooks._list[index];
	// }

	// 505 B
	// if (index < hooks._list.length) {
	// 	return hooks._list[index];
	// }
	// else {
	// 	hooks._list.push(initialState);
	// 	return initialState;
	// }
}

export function useState(initialState) {
	return useReducer(invokeOrReturn, initialState);
}

export function useReducer(reducer, initialState, initialAction) {
	// 710 B
	// /** @type {import('./internal').ReducerHookState} */
	// const state = getHookState(currentIndex++, {});
	// if (state._component == null) {
	// 	state._component = currentComponent;
	// 	// state._value = typeof initialState === 'function' ? initialState(): initialState;
	// 	// state._value = initialAction ? reducer(invokeOrReturn(null, initialState), initialAction) : invokeOrReturn(null, initialState);
	// 	state._value = invokeOrReturn(null, initialState);
	// 	if (initialAction) {
	// 		state._value = reducer(state._value, initialAction);
	// 	}
	// }
	// return [
	// 	state._value,
	// 	action => {
	// 		state._value = reducer(state._value, action);
	// 		stateChanged = true; // +(15-18) B!!
	// 		state._component.setState({});
	// 	}
	// ];

	// 716 B
	/** @type {import('./internal').ReducerHookState} */
	const hookState = getHookState(currentIndex++, {});
	if (hookState._component == null) {
		hookState._component = currentComponent
		hookState._value = [
			initialAction
				? reducer(invokeOrReturn(null, initialState), initialAction)
				: invokeOrReturn(null, initialState),
			action => {
				hookState._value[0] = reducer(hookState._value[0], action);
				stateChanged = true;
				hookState._component.setState({});
			}
		];
	}
	return hookState._value;
}

/**
 * @param {import('./internal').Effect} callback
 * @param {any[]} args
 */
export function useEffect(callback, args) {

	/** @type {import('./internal').EffectHookState} */
	const state = getHookState(currentIndex++, {});
	// const state = getHookState(currentIndex++, { _value: callback, _args: null, _cleanup: null }); // +11 B
	// if (args == null || state._args == null || args.some((prop, index) => prop !== state._args[index])) { // -1 B
	if (argsChanged(state._args, args)) {
		state._value = callback;
		state._args = args;

{'fraction_non_alphanumeric': 0.16722063037249282, 'fraction_numerical': 0.0067621776504298, 'mean_word_length': 3.8912556053811658, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 23, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '305812', 'n_tokens_mistral': 2951, 'n_tokens_neox': 2836, 'n_words': 584}