UNPKG

@irrelon/forerunnerdb-core

Version:

ForerunnerDB core utilities for operating on JSON data.

141 lines (117 loc) 3.23 kB
import { get as pathGet, setImmutable as pathSetImmutable, unSetImmutable as pathUnSetImmutable, match as pathMatch } from "@irrelon/path"; export const operatePipeline = (pipeline, data, extraInfo = {"originalUpdate": {}}) => { const opFunc = operationLookup[pipeline.op]; if (!opFunc) { throw new Error(`Unknown operation "${pipeline.op}"`); } return opFunc(data, pipeline.value, {"originalUpdate": extraInfo.originalUpdate, "operation": pipeline}); }; export const $updateReplaceMode = (dataItem, opArr, extraInfo = {"originalQuery": {}}) => { // Run through each operation and return a completely replaced // data item based on data from the original return opArr.reduce((newDataItem, opData) => { const opPath = opData.path; const opValue = opData.value; const opFunc = operationLookup[opData.op]; if (!opFunc) { throw new Error(`Unknown operation "${opData.op}"`); } if (!opFunc.selfControlled) { const currentValue = pathGet(dataItem, opData.path, undefined, {"arrayTraversal": true}); const newData = opFunc(currentValue, opValue, {"originalQuery": extraInfo.originalQuery, "operation": opData}); newDataItem = pathSetImmutable(newDataItem, opPath, newData); } else { newDataItem = opFunc(newDataItem, opPath, opValue, {"originalQuery": extraInfo.originalQuery, "operation": opData}); } if (!opFunc) { throw new Error(`Unknown operation "${opData.op}" in operation ${JSON.stringify(opData)}`); } return newDataItem; }, dataItem); }; const normalise = (data) => { // No normalisation currently needed - change this as required later - ROB return data; }; export const $inc = (data, value, extraInfo = {}) => { return normalise(data) + normalise(value); }; export const $replaceValue = (data, value, extraInfo = {}) => { return value; }; export const $push = (data, value, extraInfo = {}) => { return [...data, value]; }; export const $pull = (data, value, extraInfo = {}) => { let found = false; return data.reduce((newArr, item) => { if (!found && pathMatch(item, value)) { found = true; } else { newArr.push(item); } return newArr; }, []); }; export const $pullAll = (data, value, extraInfo = {}) => { return data.reduce((newArr, item) => { if (!pathMatch(item, value)) { newArr.push(item); } return newArr; }, []); }; export const $pop = (data, value, extraInfo = {}) => { return data.slice(0, data.length - 1); }; export const $shift = (data, value, extraInfo = {}) => { const [, ...newArr] = data; return newArr; }; export const $set = (newDataItem, opPath, opValue, extraInfo = {}) => { return pathSetImmutable(newDataItem, opPath, opValue); }; export const $unset = (newDataItem, opPath, opValue, extraInfo = {}) => { return pathUnSetImmutable(newDataItem, opPath); }; $set.selfControlled = true; $unset.selfControlled = true; export const operationLookup = { $replaceValue, $updateReplaceMode, $inc, $push, $pull, $pullAll, $pop, $shift, $set, $unset }; // TODO: Write /* $addToSet $cast $each $inc - DONE $move $mul $overwrite $push - DONE $pull - DONE $pullAll - DONE $pop - DONE $shift - DONE $rename $replace $splicePush $splicePull $toggle $unset Array Positional in Updates (.$) */