UNPKG

optix

Version:

Optix is a data manipulation library that provides optics-like capabilites with a simpler syntax. It features robust Typescript support with minimal type annotations and is smaller and faster than true optics libraries.

163 lines (154 loc) 5.2 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); const _get = (obj, path) => { if (!path.length) { return obj; } const slicedPath = path.slice(1); const resolved = typeof path[0] === "function" ? path[0](obj) : path[0]; return Array.isArray(resolved) ? resolved.map((idx) => obj != null ? _get(obj[idx], slicedPath) : undefined) : obj != null ? _get(obj[resolved], slicedPath) : undefined; }; const _update = (obj, path, updater) => { if (!path.length) { return updater(obj); } const slicedPath = path.slice(1); const resolved = typeof path[0] === "function" ? path[0](obj) : path[0]; const keysToUpdate = typeof resolved === "string" || typeof resolved === "number" ? [resolved] : Array.isArray(resolved) ? resolved : []; // check for invalid path const typeofKey0 = typeof keysToUpdate[0]; if ((typeofKey0 !== "string" && typeofKey0 !== "number") || keysToUpdate[0] < 0) { return obj; } const treatObjAsArray = typeofKey0 === "number"; const newObj = obj && typeof obj === "object" ? treatObjAsArray ? obj.slice(0) : Object.assign({}, obj) : treatObjAsArray ? [] : {}; for (let i = 0; i < keysToUpdate.length; i++) { newObj[keysToUpdate[i]] = _update(newObj[keysToUpdate[i]], slicedPath, updater); } return newObj; }; const _set = (object, path, value) => _update(object, path, () => value); const _remove = (obj, path) => { if (!path.length || !obj || typeof obj !== "object") { return obj; } const resolved = typeof path[0] === "function" ? path[0](obj) : path[0]; const keysToRemove = typeof resolved === "string" || typeof resolved === "number" ? [resolved] : Array.isArray(resolved) ? resolved : []; // check for invalid path const typeofKey0 = typeof keysToRemove[0]; if ((typeofKey0 !== "string" && typeofKey0 !== "number") || keysToRemove[0] < 0) { return obj; } if (path.length === 1) { let newObj; if (Array.isArray(obj)) { const keySet = new Set(keysToRemove); newObj = []; for (let i = 0; i < obj.length; i++) { if (!keySet.has(i)) { newObj.push(obj[i]); } } } else { newObj = Object.assign({}, obj); for (let i = 0; i < keysToRemove.length; i++) { delete newObj[keysToRemove[i]]; } } return newObj; } else { const slicedPath = path.slice(1); const newObj = Array.isArray(obj) ? obj.slice(0) : Object.assign({}, obj); for (let i = 0; i < keysToRemove.length; i++) { const keyToRemove = keysToRemove[i]; if ({}.hasOwnProperty.call(newObj, keyToRemove)) { newObj[keyToRemove] = _remove(newObj[keyToRemove], slicedPath); } } return newObj; } }; const last = (arr) => arr.length - 1; const all = (arr) => arr.map((_, i) => i); const keys = Object.keys; const find = (predicate) => (arr) => { for (let i = 0; i < arr.length; i++) { if (predicate(arr[i])) return i; } return -1; }; const findByKey = (predicate) => (obj) => { for (let i = 0, keys = Object.keys(obj); i < keys.length; i++) { if (predicate(keys[i])) return keys[i]; } }; const findByVal = (predicate) => (obj) => findByKey(key => predicate(obj[key]))(obj); const filter = (predicate) => (arr) => { const filtered = []; for (let i = 0; i < arr.length; i++) { if (predicate(arr[i])) filtered.push(i); } return filtered; }; const filterByKey = (predicate) => (obj) => { const filtered = []; const keys = Object.keys(obj); for (let i = 0; i < keys.length; i++) { if (predicate(keys[i])) filtered.push(keys[i]); } return filtered; }; const filterByVal = (predicate) => (obj) => filterByKey(key => predicate(obj[key]))(obj); const get = (...path) => (obj) => _get(obj, path); const set = (...path) => (value) => (obj) => _set(obj, path, value); const update = (...path) => (updater) => (obj) => _update(obj, path, updater); const remove = (...path) => (obj) => _remove(obj, path); const polySet = set; const polyUpdate = update; const polyRemove = remove; exports._get = _get; exports._remove = _remove; exports._set = _set; exports._update = _update; exports.all = all; exports.filter = filter; exports.filterByKey = filterByKey; exports.filterByVal = filterByVal; exports.find = find; exports.findByKey = findByKey; exports.findByVal = findByVal; exports.get = get; exports.keys = keys; exports.last = last; exports.polyRemove = polyRemove; exports.polySet = polySet; exports.polyUpdate = polyUpdate; exports.remove = remove; exports.set = set; exports.update = update;