set-array
Version:
Set array items declaratively
47 lines (33 loc) • 1.23 kB
JavaScript
import{ANY_KEY,PREPEND_CHAR}from"./check.js";
export const normalizeUpdatesObj=(updatesObj,length)=>{
const lengthA=getLength(length,updatesObj);
return Object.entries(updatesObj).map(([updateKey,items])=>
normalizeUpdate(updateKey,items,lengthA)
)
};
const getLength=(length,{[ANY_KEY]:anyItems})=>
Array.isArray(anyItems)?length*anyItems.length:length;
const normalizeUpdate=(updateKey,items,length)=>{
const{index,fullIndex,negation,any}=resolveIndex(updateKey,length);
const itemsA=Array.isArray(items)?items:[items];
return{index,fullIndex,negation,any,items:itemsA}
};
const resolveIndex=(updateKey,length)=>{
const any=updateKey===ANY_KEY;
if(any){
return{negation:2,any}
}
const{updateKey:updateKeyA,prepend}=resolvePrepend(updateKey);
const fullIndex=Number(updateKeyA);
const{index,negation}=resolveNegation(fullIndex,length);
const indexA=index-prepend;
return{index:indexA,fullIndex,negation,any}
};
const resolvePrepend=(updateKey)=>
updateKey.endsWith(PREPEND_CHAR)?
{updateKey:updateKey.slice(0,-1),prepend:0.5}:
{updateKey,prepend:0};
const resolveNegation=(fullIndex,length)=>
fullIndex<=0&&!Object.is(fullIndex,+0)?
{index:Math.max(length+fullIndex,+0),negation:1}:
{index:fullIndex,negation:0};