@apia/dom-store 4.0.15 → 4.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-dynamic-delete */\r\n/* eslint-disable no-param-reassign */\r\n/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport {\r\n useEffect,\r\n useRef,\r\n RefObject,\r\n useCallback,\r\n MutableRefObject,\r\n} from 'react';\r\nimport { Draft, produce } from 'immer';\r\nimport cloneDeep from 'lodash-es/cloneDeep';\r\n\r\n/**\r\n * Las acciones reciben este objeto como terecer parámetro.\r\n *\r\n * Sirve para decidir cuáles serán los keys afectados por la ejecución\r\n * exitosa de la acción actual, de esta forma se evita la necesidad de\r\n * iterar sobre cada elemento ejecutando acciones selectoras y\r\n * haciendo comparación entre la selección actual y la anterior.\r\n *\r\n * Si este objeto no es utilizado en una acción, se seguirá el\r\n * comportamiento por defecto que es recorrer todas las keys del\r\n * store.\r\n */\r\nexport type TKeysDefine = {\r\n /**\r\n * Acepta un método que será llamado con el conjunto de todas las\r\n * keys y deberá responder con las keys que deben ser afectadas.\r\n */\r\n filter: (filterCallback: Parameters<string[]['filter']>[0]) => void;\r\n /**\r\n * Agrega keys al array de búsqueda. La primera vez que se llama, se\r\n * agregan sobre un array vacío.\r\n */\r\n push: (...newKeys: string[]) => void;\r\n /**\r\n * Acepta un array de keys que serán las que se recorrerán en\r\n * la propagación del nuevo estado.\r\n */\r\n set: (newKeys: string[]) => void;\r\n};\r\n\r\n/**\r\n * Las operaciones son métodos que alteran el estado de alguna manera.\r\n *\r\n * Idealmente, cada operación indica qué keys afectó, de forma que no\r\n * sea necesario realizar comparaciones para saber qué elementos deben\r\n * ser modificados dentro del store.\r\n *\r\n * Cada operación recibe state que es un drat de Immer, de igual manera\r\n * como lo hacen los reducers de createSlice de Redux-toolkit.\r\n *\r\n * El payload es arbitrario.\r\n *\r\n * defineKeys es un objeto que contiene distintos métodos que permiten\r\n * alterar el listado de keys que serán iteradas para notificar del\r\n * cambio de estado.\r\n */\r\ntype TOperation<State, Payload> = (\r\n state: Draft<State>,\r\n payload: Payload,\r\n defineKeys: TKeysDefine,\r\n) => void;\r\n\r\n/**\r\n * Representa el conjunto de todas las operaciones de un store.\r\n */\r\nexport type TOperations<State> = Record<string, TOperation<State, any>>;\r\n\r\n/**\r\n * Conjunto de elementos que distinguen a cada tipo de elemento del\r\n * store. Se toma a partir de la definición del objeto distinctors\r\n * del método create.\r\n */\r\ntype TDistinctions<\r\n Distinctors extends TDistinctors<any>,\r\n K extends keyof Distinctors,\r\n> = Parameters<Distinctors[K][0]>[0];\r\n\r\n/**\r\n * Es el hook encargado de registrar los callbacks necesarios a los\r\n * eventos que corresponda de forma de garantizar que las propiedades\r\n * se apliquen sobre el elemento que corresponda.\r\n */\r\nexport type TUseProperties<State, Distinctors extends TDistinctors<State>> = <\r\n RefType,\r\n K extends keyof Distinctors = keyof Distinctors,\r\n>(\r\n which: K,\r\n distinctions: TDistinctions<Distinctors, K>,\r\n comparator?: (\r\n prevSelection: TDistinctorProperties,\r\n newSelection: TDistinctorProperties,\r\n ) => boolean,\r\n) => RefObject<RefType>;\r\n\r\nexport type TStateChangeListener<State> = (\r\n state: State,\r\n previousState: State,\r\n) => unknown;\r\n\r\n/**\r\n * Permite obtener una copia del estado local\r\n */\r\nexport type TGetState<State> = () => State;\r\n\r\n/**\r\n * Permite registrar un callback que será llamado con cada actualización del\r\n * estado\r\n */\r\nexport type TRegisterStateChangeListener<State> = (\r\n callback: TStateChangeListener<State>,\r\n) => () => void;\r\n\r\n/**\r\n * Es un método que dadas las distinciones de un elemento particular\r\n * construye un string que lo identifica.\r\n */\r\ntype TKeyMaker<\r\n State,\r\n Distinctors extends TDistinctors<State> = TDistinctors<State>,\r\n Key extends keyof Distinctors = keyof Distinctors,\r\n> = (distinctions: TDistinctions<Distinctors, Key>) => string;\r\n\r\n/**\r\n * Es un mapa que contiene un TKeyMaker por cada tipo de elemento.\r\n */\r\nexport type TKeysMaker<State, Distinctors extends TDistinctors<State>> = {\r\n [key in keyof Distinctors]: TKeyMaker<State, Distinctors, key>;\r\n};\r\n\r\n/**\r\n * Tipo que permite extraer el tipo del payload de una operación.\r\n */\r\ntype TOperationParameter<Operation extends TOperation<any, any>> =\r\n Parameters<Operation>[1];\r\n\r\n/**\r\n * Representa una acción asociada a una operación. Es el método\r\n * que es llamado desde fuera del store para ejecutar una operación\r\n * y actualizar el estado. Como consecuencia de la ejecución de esta\r\n * acción, el estado será actualizado y se harán las notificaciones\r\n * y actualización de propiedades que correspondan en los elementos\r\n * afectados.\r\n */\r\ntype TOperationAction<Payload> = (\r\n props: Payload extends void ? void : Payload,\r\n) => void;\r\n\r\n/**\r\n * Objeto que contiene todas las acciones de un store.\r\n */\r\nexport type TActionsMap<State, Operations extends TOperations<State>> = {\r\n [Key in keyof Operations]: TOperationAction<\r\n TOperationParameter<Operations[Key]>\r\n >;\r\n};\r\n\r\n/**\r\n * Método que es llamado luego de que se actualizan los elementos\r\n * pertenecientes a un tipo del store.\r\n */\r\ntype TAfterActionCallback<State> = (\r\n prevState: State,\r\n nextState: State,\r\n) => unknown;\r\n\r\nexport type TClassListComposer = Partial<{\r\n add: string[];\r\n remove: string[];\r\n toggle: string[];\r\n}>;\r\n\r\nexport type TDatasetComposer = Partial<{\r\n add: Record<string, any>;\r\n remove: string[];\r\n}>;\r\n\r\nexport type TDistinctorProperties = Partial<{\r\n classList: TClassListComposer;\r\n dataset: TDatasetComposer;\r\n etc: Record<string, any>;\r\n styles: CSSStyleDeclaration;\r\n}>;\r\n\r\n/**\r\n * Objeto que representa un tipo de elemento del store.\r\n */\r\ntype TDistinctor<State, Distinctions extends Record<string, any>> =\r\n | [\r\n (distinctions: Distinctions, state: State) => TDistinctorProperties,\r\n TAfterActionCallback<State>,\r\n ]\r\n | [(distinctions: Distinctions, state: State) => TDistinctorProperties];\r\n\r\n/**\r\n * Los distinctors determinan para cada tipo de elemento aceptado,\r\n * si dado un cambio en el estado del store, este elemento debe ser\r\n * actualizado o no\r\n * */\r\nexport type TDistinctors<State> = Record<string, TDistinctor<State, any>>;\r\n\r\nfunction setAriaAttributes(\r\n element: HTMLElement,\r\n attribute: string,\r\n value: any,\r\n) {\r\n element.setAttribute(attribute, value as string);\r\n}\r\n\r\n/**\r\n * Representa los callbacks internos del store utilizados para comunicar\r\n * acerca del cambio de estado a los elementos correspondientes.\r\n */\r\ntype TInnerStateListener<State> = (currentState: State) => void;\r\n\r\nfunction applyProperties(element: HTMLElement, props: TDistinctorProperties) {\r\n if (!element || !(element instanceof HTMLElement)) return;\r\n\r\n (props.classList?.add ?? []).forEach((current) => {\r\n if (current) element.classList.add(current);\r\n });\r\n (props.classList?.remove ?? []).forEach((current) => {\r\n if (current) element.classList.remove(current);\r\n });\r\n (props.classList?.toggle ?? []).forEach((current) => {\r\n if (current) element.classList.toggle(current);\r\n });\r\n\r\n Object.entries(props.dataset?.add ?? {}).forEach(([key, value]) => {\r\n element.dataset[key] = value;\r\n });\r\n (props.dataset?.remove ?? []).forEach(\r\n (current) => delete element.dataset[current],\r\n );\r\n\r\n Object.entries(props.styles ?? {}).forEach(([prop, value]) => {\r\n (element.style[prop as unknown as number] as any) = value;\r\n });\r\n\r\n Object.entries(props.etc ?? {}).forEach(([prop, value]) => {\r\n if (value === undefined) {\r\n delete (element as Record<string, any>)[prop];\r\n return;\r\n }\r\n\r\n const match = prop.match(/^aria-(\\w+)$/);\r\n if (match) {\r\n setAriaAttributes(element, prop, value);\r\n return;\r\n }\r\n (element as Record<string, any>)[prop] = String(value);\r\n });\r\n}\r\n\r\n/**\r\n * Falta documentar, a grandes rasgos:\r\n * \r\n * Este store propone el máximo rendimiento: afectar solamente los registros\r\n * que sean estrictamente necesarios y no renderizar.\r\n * \r\n * Para lograr evitar el renderizado, el estado se guarda en internamente en el\r\n * store, pero también en el elemento asociado a cada registro. De esta manera,\r\n * cuando se actualiza el estado, se procesan los keys afectados, se genera el\r\n * estado para cada uno de ellos de acuerdo a su distintor correspondiente y se\r\n * actualiza el DOM en el momento. Si por algún motivo, el componente afectado\r\n * vuelve a renderizar, el hook devuelve el estado actualizado, de forma de\r\n * evitar pérdida de información.\r\n * \r\n * @returns\r\n * \r\n * Al crear un store se devuelve un array compuesto por 3 elementos en el\r\n * siguiente orden:\r\n * \r\n * - acciones: Un mapa de métodos correspondientes a las operaciones\r\n * definidas. \r\n * - useProperties: Un hook utilizado para obtener las propiedades\r\n * de un elemento, de acuerdo a su distinción.\r\n * - getState: Un método que permite obtener el estado actual del store.\r\n * \r\n * @example\r\n * \r\n * \r\n * const [actions, useProperties, getState, registerStateListener] =\r\n * createFAsomeStore({\r\n // Se puede utilizar un estado con estructura arbitraria\r\n initialState: {\r\n people: [],\r\n // El as ... es necesario para que typescript pueda realizar la inferencia\r\n // correctamente. Siempre que se cree un store se debe seguir la estructura\r\n // propuesta en este ejemplo\r\n } as { people: { name: string }[] },\r\n // Los distinguidores \"distinctors\" establecen qué tipos de elementos existen\r\n // dentro del store y qué estado utiliza cada uno de ellos\r\n distinctors: {\r\n person: [\r\n // El tipado asignado al parámetro distinctions será tomado por el store\r\n // para pasarlo luego al keymaker a la hora de seleccionar un registro del\r\n // store\r\n (distinctions: { name: string }, state) => {\r\n return {\r\n name: state.people.find(\r\n (current) => current.name === distinctions.name,\r\n ),\r\n };\r\n },\r\n ],\r\n },\r\n // Los keymakers se encargan de generar claves únicas para cada elemento del\r\n // store\r\n keysMakers: {\r\n person: (distinctions) => {\r\n // Debe crear una key única dentro del store\r\n return distinctions.name;\r\n },\r\n },\r\n // Los operadores permiten alterar el estado actual\r\n operations: {\r\n addPerson(state, payload: { name: string }, affectedKeys) {\r\n // El estado se altera de cualquier forma que sea conveniente\r\n state.people.push({ name: payload.name });\r\n // Este key debe ser idéntico al generado por el keyMaker de person (Más\r\n // arriba)\r\n affectedKeys.set([payload.name]);\r\n },\r\n },\r\n });\r\n */\r\nexport function createFAsomeStore<\r\n State,\r\n Distinctors extends TDistinctors<State> = TDistinctors<State>,\r\n Operations extends TOperations<State> = TOperations<State>,\r\n>({\r\n initialState,\r\n operations,\r\n distinctors,\r\n keysMakers,\r\n}: {\r\n initialState: State;\r\n operations: Operations;\r\n distinctors: Distinctors;\r\n keysMakers: TKeysMaker<State, Distinctors>;\r\n}): [\r\n TActionsMap<State, Operations>,\r\n TUseProperties<State, Distinctors>,\r\n TGetState<State>,\r\n TRegisterStateChangeListener<State>,\r\n] {\r\n const actions = {} as TActionsMap<State, Operations>;\r\n let state = initialState;\r\n\r\n const callbacks: Record<string, Map<string, TInnerStateListener<State>>> = {};\r\n const keysMap = new Map<string, number>();\r\n\r\n function registerCallback<K extends keyof Distinctors>(\r\n which: K,\r\n distinctions: TDistinctions<Distinctors, K>,\r\n callback: TInnerStateListener<State>,\r\n ) {\r\n if (!callbacks[which as string]) {\r\n callbacks[which as string] = new Map();\r\n }\r\n const key = keysMakers[which](distinctions);\r\n keysMap.set(key, (keysMap.get(key) ?? 0) + 1);\r\n callbacks[which as string].set(key, callback);\r\n\r\n return () => {\r\n callbacks[which as string].delete(key);\r\n keysMap.set(key, (keysMap.get(key) as number) - 1);\r\n if (keysMap.get(key) === 0) keysMap.delete(key);\r\n };\r\n }\r\n\r\n let stateListenersCallbacks: TStateChangeListener<State>[] = [];\r\n\r\n const registerStateListener: TRegisterStateChangeListener<State> = (\r\n callback: TStateChangeListener<State>,\r\n ) => {\r\n stateListenersCallbacks.push(callback);\r\n\r\n return () => {\r\n stateListenersCallbacks = stateListenersCallbacks.filter(\r\n (current) => current !== callback,\r\n );\r\n };\r\n };\r\n\r\n Object.entries(operations).forEach(([name, operation]) => {\r\n const action: TOperationAction<TOperationParameter<typeof operation>> = (\r\n props,\r\n ) => {\r\n let keys = Array.from(keysMap.keys()) as string[];\r\n const pushedKeys: Record<string, any> = {};\r\n let hasPushed = false;\r\n const nextState = produce(state, (state) =>\r\n operations[name](state, props, {\r\n filter(filterCallback) {\r\n if (hasPushed) {\r\n Object.keys(pushedKeys)\r\n .filter((current, ...e) => filterCallback(current, ...e))\r\n .forEach((current) => delete pushedKeys[current]);\r\n } else keys = keys.filter(filterCallback);\r\n },\r\n push(...newKeys) {\r\n if (!hasPushed) {\r\n hasPushed = true;\r\n }\r\n newKeys.forEach((current) => (pushedKeys[current] = true));\r\n },\r\n set(newKeys) {\r\n if (!hasPushed) {\r\n hasPushed = true;\r\n }\r\n newKeys.forEach((current) => (pushedKeys[current] = true));\r\n },\r\n }),\r\n );\r\n\r\n const actualKeys = hasPushed ? Object.keys(pushedKeys) : keys;\r\n hasPushed ? Object.keys(pushedKeys) : keys;\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\r\n if ((window as any).debugDomStore) {\r\n console.clear();\r\n }\r\n if (nextState !== state) {\r\n stateListenersCallbacks.forEach((current) => {\r\n current(nextState, state);\r\n });\r\n Object.keys(callbacks).forEach((which) => {\r\n actualKeys.forEach((key) => {\r\n callbacks[which].get(key)?.(nextState);\r\n });\r\n distinctors[which][1]?.(state, nextState);\r\n });\r\n state = nextState;\r\n }\r\n };\r\n actions[name as keyof TActionsMap<State, Operations>] = action;\r\n });\r\n\r\n /**\r\n * Este hook permite recuperar el estado asociado a un elemento. \r\n * El siguiente ejemplo está tomado del componente Listbox de \r\n * **@apia/components**. En el mismo se puede ver que se toman las \r\n * props devueltas y se hacen spread sobre el elemento destino. \r\n * En este ejemplo, las acciones y el useListbox vienen por \r\n * contexto pero son exactamente los mismos devueltos por \r\n * createFAsomeStore.\r\n * \r\n * @example\r\n * \r\n * export const ListboxItem: FC<TListboxItem> = ({\r\n children,\r\n rowIndex: outerRowIndex,\r\n }) => {\r\n const { listboxActions, useListbox } = useContext(ListboxContext);\r\n const rowIndex = useMemo(() => outerRowIndex ?? -1, [outerRowIndex]);\r\n const props = useListbox<HTMLDivElement>('row', { rowIndex });\r\n\r\n return (\r\n <div\r\n {...props}\r\n onClick={useCallback(() => {\r\n listboxActions.updateSelectedRows({ newSelectedRows: [rowIndex] });\r\n }, [listboxActions, rowIndex])}\r\n >\r\n {children}\r\n </div>\r\n );\r\n };\r\n */\r\n const useProperties: TUseProperties<State, Distinctors> = <\r\n RefType,\r\n K extends keyof Distinctors = keyof Distinctors,\r\n >(\r\n which: K,\r\n distinctions: TDistinctions<Distinctors, K>,\r\n comparator: (\r\n prevSelection: TDistinctorProperties,\r\n newSelection: TDistinctorProperties,\r\n ) => boolean = (a, b) => a === b,\r\n ) => {\r\n const ref = useRef<RefType>(null);\r\n const returnRef = useCallback((el: RefType) => {\r\n if (el) {\r\n applyProperties(\r\n el as unknown as HTMLElement,\r\n previousSelection.current,\r\n );\r\n }\r\n (ref as MutableRefObject<RefType>).current = el;\r\n }, []) as unknown as MutableRefObject<RefType>;\r\n const previousSelection = useRef<TDistinctorProperties>(\r\n null as unknown as TDistinctorProperties,\r\n );\r\n if (previousSelection.current === null) {\r\n previousSelection.current = distinctors[which][0](\r\n distinctions,\r\n state,\r\n ) as TDistinctorProperties;\r\n }\r\n\r\n useEffect(() => {\r\n return registerCallback(which, distinctions, (current) => {\r\n const newState: TDistinctorProperties = distinctors[which][0](\r\n distinctions,\r\n current,\r\n );\r\n if (!comparator(previousSelection.current, newState)) {\r\n previousSelection.current = newState;\r\n applyProperties(ref.current as HTMLElement, newState);\r\n }\r\n });\r\n }, [comparator, distinctions, which]);\r\n\r\n return returnRef;\r\n };\r\n\r\n const getState = () => {\r\n return cloneDeep(state);\r\n };\r\n\r\n return [actions, useProperties, getState, registerStateListener];\r\n}\r\n\r\nexport type { Draft };\r\n"],"names":["state"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-dynamic-delete */\r\n/* eslint-disable no-param-reassign */\r\n/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport {\r\n useEffect,\r\n useRef,\r\n RefObject,\r\n useCallback,\r\n MutableRefObject,\r\n} from 'react';\r\nimport { Draft, produce } from 'immer';\r\nimport cloneDeep from 'lodash-es/cloneDeep';\r\n\r\n/**\r\n * Las acciones reciben este objeto como terecer parámetro.\r\n *\r\n * Sirve para decidir cuáles serán los keys afectados por la ejecución\r\n * exitosa de la acción actual, de esta forma se evita la necesidad de\r\n * iterar sobre cada elemento ejecutando acciones selectoras y\r\n * haciendo comparación entre la selección actual y la anterior.\r\n *\r\n * Si este objeto no es utilizado en una acción, se seguirá el\r\n * comportamiento por defecto que es recorrer todas las keys del\r\n * store.\r\n */\r\nexport type TKeysDefine = {\r\n /**\r\n * Acepta un método que será llamado con el conjunto de todas las\r\n * keys y deberá responder con las keys que deben ser afectadas.\r\n */\r\n filter: (filterCallback: Parameters<string[]['filter']>[0]) => void;\r\n /**\r\n * Agrega keys al array de búsqueda. La primera vez que se llama, se\r\n * agregan sobre un array vacío.\r\n */\r\n push: (...newKeys: string[]) => void;\r\n /**\r\n * Acepta un array de keys que serán las que se recorrerán en\r\n * la propagación del nuevo estado.\r\n */\r\n set: (newKeys: string[]) => void;\r\n};\r\n\r\n/**\r\n * Las operaciones son métodos que alteran el estado de alguna manera.\r\n *\r\n * Idealmente, cada operación indica qué keys afectó, de forma que no\r\n * sea necesario realizar comparaciones para saber qué elementos deben\r\n * ser modificados dentro del store.\r\n *\r\n * Cada operación recibe state que es un drat de Immer, de igual manera\r\n * como lo hacen los reducers de createSlice de Redux-toolkit.\r\n *\r\n * El payload es arbitrario.\r\n *\r\n * defineKeys es un objeto que contiene distintos métodos que permiten\r\n * alterar el listado de keys que serán iteradas para notificar del\r\n * cambio de estado.\r\n */\r\ntype TOperation<State, Payload> = (\r\n state: Draft<State>,\r\n payload: Payload,\r\n defineKeys: TKeysDefine,\r\n) => void;\r\n\r\n/**\r\n * Representa el conjunto de todas las operaciones de un store.\r\n */\r\nexport type TOperations<State> = Record<string, TOperation<State, any>>;\r\n\r\n/**\r\n * Conjunto de elementos que distinguen a cada tipo de elemento del\r\n * store. Se toma a partir de la definición del objeto distinctors\r\n * del método create.\r\n */\r\ntype TDistinctions<\r\n Distinctors extends TDistinctors<any>,\r\n K extends keyof Distinctors,\r\n> = Parameters<Distinctors[K][0]>[0];\r\n\r\n/**\r\n * Es el hook encargado de registrar los callbacks necesarios a los\r\n * eventos que corresponda de forma de garantizar que las propiedades\r\n * se apliquen sobre el elemento que corresponda.\r\n */\r\nexport type TUseProperties<State, Distinctors extends TDistinctors<State>> = <\r\n RefType,\r\n K extends keyof Distinctors = keyof Distinctors,\r\n>(\r\n which: K,\r\n distinctions: TDistinctions<Distinctors, K>,\r\n comparator?: (\r\n prevSelection: TDistinctorProperties,\r\n newSelection: TDistinctorProperties,\r\n ) => boolean,\r\n) => RefObject<RefType>;\r\n\r\nexport type TStateChangeListener<State> = (\r\n state: State,\r\n previousState: State,\r\n) => unknown;\r\n\r\n/**\r\n * Permite obtener una copia del estado local\r\n */\r\nexport type TGetState<State> = () => State;\r\n\r\n/**\r\n * Permite registrar un callback que será llamado con cada actualización del\r\n * estado\r\n */\r\nexport type TRegisterStateChangeListener<State> = (\r\n callback: TStateChangeListener<State>,\r\n) => () => void;\r\n\r\n/**\r\n * Es un método que dadas las distinciones de un elemento particular\r\n * construye un string que lo identifica.\r\n */\r\ntype TKeyMaker<\r\n State,\r\n Distinctors extends TDistinctors<State> = TDistinctors<State>,\r\n Key extends keyof Distinctors = keyof Distinctors,\r\n> = (distinctions: TDistinctions<Distinctors, Key>) => string;\r\n\r\n/**\r\n * Es un mapa que contiene un TKeyMaker por cada tipo de elemento.\r\n */\r\nexport type TKeysMaker<State, Distinctors extends TDistinctors<State>> = {\r\n [key in keyof Distinctors]: TKeyMaker<State, Distinctors, key>;\r\n};\r\n\r\n/**\r\n * Tipo que permite extraer el tipo del payload de una operación.\r\n */\r\ntype TOperationParameter<Operation extends TOperation<any, any>> =\r\n Parameters<Operation>[1];\r\n\r\n/**\r\n * Representa una acción asociada a una operación. Es el método\r\n * que es llamado desde fuera del store para ejecutar una operación\r\n * y actualizar el estado. Como consecuencia de la ejecución de esta\r\n * acción, el estado será actualizado y se harán las notificaciones\r\n * y actualización de propiedades que correspondan en los elementos\r\n * afectados.\r\n */\r\ntype TOperationAction<Payload> = (\r\n props: Payload extends void ? void : Payload,\r\n) => void;\r\n\r\n/**\r\n * Objeto que contiene todas las acciones de un store.\r\n */\r\nexport type TActionsMap<State, Operations extends TOperations<State>> = {\r\n [Key in keyof Operations]: TOperationAction<\r\n TOperationParameter<Operations[Key]>\r\n >;\r\n};\r\n\r\n/**\r\n * Método que es llamado luego de que se actualizan los elementos\r\n * pertenecientes a un tipo del store.\r\n */\r\ntype TAfterActionCallback<State> = (\r\n prevState: State,\r\n nextState: State,\r\n) => unknown;\r\n\r\nexport type TClassListComposer = Partial<{\r\n add: string[];\r\n remove: string[];\r\n toggle: string[];\r\n}>;\r\n\r\nexport type TDatasetComposer = Partial<{\r\n add: Record<string, any>;\r\n remove: string[];\r\n}>;\r\n\r\nexport type TDistinctorProperties = Partial<{\r\n classList: TClassListComposer;\r\n dataset: TDatasetComposer;\r\n etc: Record<string, any>;\r\n styles: CSSStyleDeclaration;\r\n}>;\r\n\r\n/**\r\n * Objeto que representa un tipo de elemento del store.\r\n */\r\ntype TDistinctor<State, Distinctions extends Record<string, any>> =\r\n | [\r\n (distinctions: Distinctions, state: State) => TDistinctorProperties,\r\n TAfterActionCallback<State>,\r\n ]\r\n | [(distinctions: Distinctions, state: State) => TDistinctorProperties];\r\n\r\n/**\r\n * Los distinctors determinan para cada tipo de elemento aceptado,\r\n * si dado un cambio en el estado del store, este elemento debe ser\r\n * actualizado o no\r\n * */\r\nexport type TDistinctors<State> = Record<string, TDistinctor<State, any>>;\r\n\r\nfunction setAriaAttributes(\r\n element: HTMLElement,\r\n attribute: string,\r\n value: any,\r\n) {\r\n element.setAttribute(attribute, value as string);\r\n}\r\n\r\n/**\r\n * Representa los callbacks internos del store utilizados para comunicar\r\n * acerca del cambio de estado a los elementos correspondientes.\r\n */\r\ntype TInnerStateListener<State> = (currentState: State) => void;\r\n\r\nfunction applyProperties(element: HTMLElement, props: TDistinctorProperties) {\r\n if (!element || !(element instanceof HTMLElement)) return;\r\n\r\n (props.classList?.add ?? []).forEach((current) => {\r\n if (current) element.classList.add(current);\r\n });\r\n (props.classList?.remove ?? []).forEach((current) => {\r\n if (current) element.classList.remove(current);\r\n });\r\n (props.classList?.toggle ?? []).forEach((current) => {\r\n if (current) element.classList.toggle(current);\r\n });\r\n\r\n Object.entries(props.dataset?.add ?? {}).forEach(([key, value]) => {\r\n element.dataset[key] = value;\r\n });\r\n (props.dataset?.remove ?? []).forEach(\r\n (current) => delete element.dataset[current],\r\n );\r\n\r\n Object.entries(props.styles ?? {}).forEach(([prop, value]) => {\r\n (element.style[prop as unknown as number] as any) = value;\r\n });\r\n\r\n Object.entries(props.etc ?? {}).forEach(([prop, value]) => {\r\n if (value === undefined) {\r\n delete (element as Record<string, any>)[prop];\r\n return;\r\n }\r\n\r\n const match = prop.match(/^aria-(\\w+)$/);\r\n if (match) {\r\n setAriaAttributes(element, prop, value);\r\n return;\r\n }\r\n (element as Record<string, any>)[prop] = String(value);\r\n });\r\n}\r\n\r\n/**\r\n * Falta documentar, a grandes rasgos:\r\n * \r\n * Este store propone el máximo rendimiento: afectar solamente los registros\r\n * que sean estrictamente necesarios y no renderizar.\r\n * \r\n * Para lograr evitar el renderizado, el estado se guarda en internamente en el\r\n * store, pero también en el elemento asociado a cada registro. De esta manera,\r\n * cuando se actualiza el estado, se procesan los keys afectados, se genera el\r\n * estado para cada uno de ellos de acuerdo a su distintor correspondiente y se\r\n * actualiza el DOM en el momento. Si por algún motivo, el componente afectado\r\n * vuelve a renderizar, el hook devuelve el estado actualizado, de forma de\r\n * evitar pérdida de información.\r\n * \r\n * @returns\r\n * \r\n * Al crear un store se devuelve un array compuesto por 3 elementos en el\r\n * siguiente orden:\r\n * \r\n * - acciones: Un mapa de métodos correspondientes a las operaciones\r\n * definidas. \r\n * - useProperties: Un hook utilizado para obtener las propiedades\r\n * de un elemento, de acuerdo a su distinción.\r\n * - getState: Un método que permite obtener el estado actual del store.\r\n * \r\n * @example\r\n * \r\n * \r\n * const [actions, useProperties, getState, registerStateListener] =\r\n * createFAsomeStore({\r\n // Se puede utilizar un estado con estructura arbitraria\r\n initialState: {\r\n people: [],\r\n // El as ... es necesario para que typescript pueda realizar la inferencia\r\n // correctamente. Siempre que se cree un store se debe seguir la estructura\r\n // propuesta en este ejemplo\r\n } as { people: { name: string }[] },\r\n // Los distinguidores \"distinctors\" establecen qué tipos de elementos existen\r\n // dentro del store y qué estado utiliza cada uno de ellos\r\n distinctors: {\r\n person: [\r\n // El tipado asignado al parámetro distinctions será tomado por el store\r\n // para pasarlo luego al keymaker a la hora de seleccionar un registro del\r\n // store\r\n (distinctions: { name: string }, state) => {\r\n return {\r\n name: state.people.find(\r\n (current) => current.name === distinctions.name,\r\n ),\r\n };\r\n },\r\n ],\r\n },\r\n // Los keymakers se encargan de generar claves únicas para cada elemento del\r\n // store\r\n keysMakers: {\r\n person: (distinctions) => {\r\n // Debe crear una key única dentro del store\r\n return distinctions.name;\r\n },\r\n },\r\n // Los operadores permiten alterar el estado actual\r\n operations: {\r\n addPerson(state, payload: { name: string }, affectedKeys) {\r\n // El estado se altera de cualquier forma que sea conveniente\r\n state.people.push({ name: payload.name });\r\n // Este key debe ser idéntico al generado por el keyMaker de person (Más\r\n // arriba)\r\n affectedKeys.set([payload.name]);\r\n },\r\n },\r\n });\r\n */\r\nexport function createFAsomeStore<\r\n State,\r\n Distinctors extends TDistinctors<State> = TDistinctors<State>,\r\n Operations extends TOperations<State> = TOperations<State>,\r\n>({\r\n initialState,\r\n operations,\r\n distinctors,\r\n keysMakers,\r\n}: {\r\n initialState: State;\r\n operations: Operations;\r\n distinctors: Distinctors;\r\n keysMakers: TKeysMaker<State, Distinctors>;\r\n}): [\r\n TActionsMap<State, Operations>,\r\n TUseProperties<State, Distinctors>,\r\n TGetState<State>,\r\n TRegisterStateChangeListener<State>,\r\n] {\r\n const actions = {} as TActionsMap<State, Operations>;\r\n let state = initialState;\r\n\r\n const callbacks: Record<string, Map<string, TInnerStateListener<State>>> = {};\r\n const keysMap = new Map<string, number>();\r\n\r\n function registerCallback<K extends keyof Distinctors>(\r\n which: K,\r\n distinctions: TDistinctions<Distinctors, K>,\r\n callback: TInnerStateListener<State>,\r\n ) {\r\n if (!callbacks[which as string]) {\r\n callbacks[which as string] = new Map();\r\n }\r\n const key = keysMakers[which](distinctions);\r\n keysMap.set(key, (keysMap.get(key) ?? 0) + 1);\r\n callbacks[which as string].set(key, callback);\r\n\r\n return () => {\r\n callbacks[which as string].delete(key);\r\n keysMap.set(key, (keysMap.get(key) as number) - 1);\r\n if (keysMap.get(key) === 0) keysMap.delete(key);\r\n };\r\n }\r\n\r\n let stateListenersCallbacks: TStateChangeListener<State>[] = [];\r\n\r\n const registerStateListener: TRegisterStateChangeListener<State> = (\r\n callback: TStateChangeListener<State>,\r\n ) => {\r\n stateListenersCallbacks.push(callback);\r\n\r\n return () => {\r\n stateListenersCallbacks = stateListenersCallbacks.filter(\r\n (current) => current !== callback,\r\n );\r\n };\r\n };\r\n\r\n Object.entries(operations).forEach(([name, operation]) => {\r\n const action: TOperationAction<TOperationParameter<typeof operation>> = (\r\n props,\r\n ) => {\r\n let keys = Array.from(keysMap.keys()) as string[];\r\n const pushedKeys: Record<string, any> = {};\r\n let hasPushed = false;\r\n const nextState = produce(state, (state) =>\r\n operations[name](state, props, {\r\n filter(filterCallback) {\r\n if (hasPushed) {\r\n Object.keys(pushedKeys)\r\n .filter((current, ...e) => filterCallback(current, ...e))\r\n .forEach((current) => delete pushedKeys[current]);\r\n } else keys = keys.filter(filterCallback);\r\n },\r\n push(...newKeys) {\r\n if (!hasPushed) {\r\n hasPushed = true;\r\n }\r\n newKeys.forEach((current) => (pushedKeys[current] = true));\r\n },\r\n set(newKeys) {\r\n if (!hasPushed) {\r\n hasPushed = true;\r\n }\r\n newKeys.forEach((current) => (pushedKeys[current] = true));\r\n },\r\n }),\r\n );\r\n\r\n const actualKeys = hasPushed ? Object.keys(pushedKeys) : keys;\r\n hasPushed ? Object.keys(pushedKeys) : keys;\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\r\n if ((window as any).debugDomStore) {\r\n console.clear();\r\n }\r\n if (nextState !== state) {\r\n stateListenersCallbacks.forEach((current) => {\r\n current(nextState, state);\r\n });\r\n Object.keys(callbacks).forEach((which) => {\r\n actualKeys.forEach((key) => {\r\n callbacks[which].get(key)?.(nextState);\r\n });\r\n distinctors[which][1]?.(state, nextState);\r\n });\r\n state = nextState;\r\n }\r\n };\r\n actions[name as keyof TActionsMap<State, Operations>] = action;\r\n });\r\n\r\n /**\r\n * Este hook permite recuperar el estado asociado a un elemento. \r\n * El siguiente ejemplo está tomado del componente Listbox de \r\n * **@apia/components**. En el mismo se puede ver que se toman las \r\n * props devueltas y se hacen spread sobre el elemento destino. \r\n * En este ejemplo, las acciones y el useListbox vienen por \r\n * contexto pero son exactamente los mismos devueltos por \r\n * createFAsomeStore.\r\n * \r\n * @example\r\n * \r\n * export const ListboxItem: FC<TListboxItem> = ({\r\n children,\r\n rowIndex: outerRowIndex,\r\n }) => {\r\n const { listboxActions, useListbox } = useContext(ListboxContext);\r\n const rowIndex = useMemo(() => outerRowIndex ?? -1, [outerRowIndex]);\r\n const props = useListbox<HTMLDivElement>('row', { rowIndex });\r\n\r\n return (\r\n <div\r\n {...props}\r\n onClick={useCallback(() => {\r\n listboxActions.updateSelectedRows({ newSelectedRows: [rowIndex] });\r\n }, [listboxActions, rowIndex])}\r\n >\r\n {children}\r\n </div>\r\n );\r\n };\r\n */\r\n const useProperties: TUseProperties<State, Distinctors> = <\r\n RefType,\r\n K extends keyof Distinctors = keyof Distinctors,\r\n >(\r\n which: K,\r\n distinctions: TDistinctions<Distinctors, K>,\r\n comparator: (\r\n prevSelection: TDistinctorProperties,\r\n newSelection: TDistinctorProperties,\r\n ) => boolean = (a, b) => a === b,\r\n ) => {\r\n const ref = useRef<RefType>(null);\r\n const returnRef = useCallback((el: RefType) => {\r\n if (el) {\r\n applyProperties(\r\n el as unknown as HTMLElement,\r\n previousSelection.current,\r\n );\r\n }\r\n (ref as MutableRefObject<RefType>).current = el;\r\n }, []) as unknown as MutableRefObject<RefType>;\r\n const previousSelection = useRef<TDistinctorProperties>(\r\n null as unknown as TDistinctorProperties,\r\n );\r\n if (previousSelection.current === null) {\r\n previousSelection.current = distinctors[which][0](\r\n distinctions,\r\n state,\r\n ) as TDistinctorProperties;\r\n }\r\n\r\n useEffect(() => {\r\n return registerCallback(which, distinctions, (current) => {\r\n const newState: TDistinctorProperties = distinctors[which][0](\r\n distinctions,\r\n current,\r\n );\r\n if (!comparator(previousSelection.current, newState)) {\r\n previousSelection.current = newState;\r\n applyProperties(ref.current as HTMLElement, newState);\r\n }\r\n });\r\n }, [comparator, distinctions, which]);\r\n\r\n return returnRef;\r\n };\r\n\r\n const getState = () => {\r\n return cloneDeep(state);\r\n };\r\n\r\n return [actions, useProperties, getState, registerStateListener];\r\n}\r\n\r\nexport type { Draft };\r\n"],"names":["state"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apia/dom-store",
3
- "version": "4.0.15",
3
+ "version": "4.0.16",
4
4
  "sideEffects": false,
5
5
  "author": "Alexis Leite <alexisleite@live.com>",
6
6
  "main": "dist/index.js",
@@ -31,5 +31,5 @@
31
31
  "access": "public",
32
32
  "registry": "https://registry.npmjs.org/"
33
33
  },
34
- "gitHead": "893eb39744c85737b54df181b2919a51963fcc81"
34
+ "gitHead": "7c6a8c2281bfd78469eece56b7efaca115734db4"
35
35
  }