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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | 1x 1x 3x 3x 3x 1x 12x 12x 12x 20x 20x 6x 1x 12x 12x 12x 19x 19x 19x 12x 12x 1x 30x 15x 15x 1x 30x 11x 11x 19x 19x | import { BATCH_MUTATION_KEYS, type BatchMutations, type KeyLike, type State, type StateChange } from '@anchorlib/core';
import type { AnchoredProps, Bindable } from './types.js';
/**
* `cleanProps` is a utility function designed to remove the internal
* `_state_version` prop from a component's props object.
*
* When a component is wrapped by the `observed` HOC, it receives an
* additional `_state_version` prop. This prop is used internally by the
* `observed` HOC to force re-renders and should typically not be passed
* down to native DOM elements or other components that don't expect it.
*
* Use this function to filter out `_state_version` before spreading props
* onto child components or DOM elements.
*
* @template T The type of the props object, which must extend `Bindable`.
* @param props The props object that might contain `_state_version`.
* @returns A new object containing all original props except `_state_version`.
*/
export function cleanProps<T extends Bindable>(props: T) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { _state_version, ...rest } = props as T & AnchoredProps;
return rest;
}
/**
* Compares two arrays for shallow equality, ignoring the order of elements.
*
* This function checks if two arrays contain the same elements by comparing:
* 1. Their lengths
* 2. Whether all elements in one array exist in the other array
*
* It's used to determine if the dependencies of an observer have changed,
* where the position of elements doesn't matter but their presence does.
*
* @param prev - The previous array of dependencies
* @param next - The next array of dependencies
* @returns true if the arrays are different, false if they contain the same elements
*/
export function depsChanged(prev: Set<unknown>, next: unknown[]): Set<unknown> | void {
const nextSet = new Set(next);
if (nextSet.size !== prev.size) return nextSet;
for (const item of nextSet) {
if (!prev.has(item)) return nextSet;
}
}
/**
* Helper function that extracts specific properties from a reactive state object.
* It returns a tuple containing:
* 1. An object with the picked properties and their values
* 2. An array of the values corresponding to the picked keys
*
* @template T - The type of the reactive state object
* @param {T} state - The reactive state object to pick values from
* @param {(keyof T)[]} keys - An array of keys to pick from the state object
* @returns {[T, T[keyof T][]]} A tuple containing the picked object and values array
*/
export function pickValues<T extends State>(state: T, keys: (keyof T)[]): [T, T[keyof T][]] {
const values = [] as T[keyof T][];
const result = {} as T;
for (const key of keys) {
values.push(state[key]);
result[key] = state[key];
}
return [result, values] as const;
}
/**
* Checks if a state change event is a mutation of a specific key.
*
* @param event - The state change event.
* @param key - The key to check for mutation.
*/
export function isMutationOf(event: StateChange, key: KeyLike) {
if (event.type === 'init') return false;
return mutationKeys(event).includes(key as string);
}
/**
* Extracts the keys that were mutated in a state change event.
*
* @param event - The state change event.
* @returns An array of keys that were mutated.
*/
export function mutationKeys(event: StateChange) {
if (BATCH_MUTATION_KEYS.has(event.type as BatchMutations)) {
return Object.keys(event.prev ?? {});
}
// Only expect one key (single level) for non-batch mutations.
return event.keys.slice(0, 1);
}
|