UNPKG

deleight

Version:

A library with 9 modules for writing more expressive web applications with traditional HTML, CSS and JavaScript.

264 lines (263 loc) 6.32 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.delAsync = exports.del = exports.callAsync = exports.call = exports.setAsync = exports.set = exports.getAsync = exports.get = exports.destructureAsync = exports.destructure = exports.dk = exports.deepKey = void 0; const own_js_1 = require("../own/own.js"); /** * A proxy for creating deep keys using member access syntax * * @example * */ exports.deepKey = new Proxy((...args) => { const dk = Object.assign(() => { }, { key: [args] }); return dk.proxy = new Proxy(dk, deepKeyHandler); }, { get(target, p) { p = (0, own_js_1.realKey)(p); const dk = Object.assign(() => { }, { key: [p] }); return dk.proxy = new Proxy(dk, deepKeyHandler); } }); /** * Alias for {@link deepKey} */ exports.dk = exports.deepKey; const deepKeyHandler = { get(target, p) { p = (0, own_js_1.realKey)(p); target.key.push(p); return target.proxy; }, apply(target, thisArg, args) { if (args.length) { target.key.push(args); return target.proxy; } else { return target.key; } } }; /** * Given an object and a key or deepkey, returns the object that directly * holds the member being referred to (.parent) and the member key in * it (.member). * * @example * * * @param object * @param key * @returns */ function destructure(object, key) { const keys = (key instanceof Array) ? key : [key]; if (!keys.length) throw new Error(`No keys to destructure`); let parent = object, member; let prevParent = parent; for (let i = 0; i < keys.length - 1; i++) { member = keys[i]; if (member instanceof Array) parent = parent(...member); else parent = parent[member]; if (parent instanceof Function && prevParent) parent = parent.bind(prevParent); prevParent = parent; } member = keys[keys.length - 1]; return { parent, member }; } exports.destructure = destructure; /** * Async equivalent of {@link destructure}. This will resolve * any promises in the member path, so it returns a Promise that resolves * to the same type of object as the one returned by {@link destructure}. * * @example * * * @param object * @param key * @returns */ async function destructureAsync(object, key) { const keys = (key instanceof Array) ? key : [key]; if (!keys.length) throw new Error(`No keys to destructure`); let parent = object, member; let prevParent = parent; for (let i = 0; i < keys.length - 1; i++) { member = keys[i]; if (member instanceof Array) parent = parent(...member); else parent = parent[member]; if (parent instanceof Promise) parent = await parent; if (parent instanceof Function && prevParent) parent = parent.bind(prevParent); prevParent = parent; } member = keys[keys.length - 1]; return { parent, member }; } exports.destructureAsync = destructureAsync; /** * Gets the member referred to by the object and key/deepkey * * @example * * * @param object * @param key * @returns */ function get(object, key) { const { parent, member } = destructure(object, key); if (member instanceof Array) return parent(...member); else return parent[member]; } exports.get = get; /** * Async equivalent of {@link get} * * @example * * * @param object * @param key * @returns */ async function getAsync(object, key) { const { parent, member } = await destructureAsync(object, key); if (member instanceof Array) return parent(...member); else return parent[member]; } exports.getAsync = getAsync; /** * Sets the member referred to by the object and key/deepkey * * @example * * * @param object * @param key * @param value * @returns */ function set(object, key, value) { const { parent, member } = destructure(object, key); return finishSet(parent, member, value); } exports.set = set; /** * Async equivalent of {@link set} * * @example * * @param object * @param key * @param value * @returns */ async function setAsync(object, key, value) { const { parent, member } = await destructureAsync(object, key); return finishSet(parent, member, value); } exports.setAsync = setAsync; function finishSet(parent, member, value) { if (member instanceof Array) { for (let item of member) set(parent, item, value); } else parent[member] = value; return value; } /** * Calls the method referred to by the object and key/deepkey * * @example * * * @param object * @param key * @param args * @returns */ function call(object, key, ...args) { const { parent, member } = destructure(object, key); if (member instanceof Array) return parent(member)(...args); else return parent[member](...args); } exports.call = call; /** * Async equivalent of {@link call} * * @example * * * @param object * @param key * @param args * @returns */ async function callAsync(object, key, ...args) { const { parent, member } = await destructureAsync(object, key); if (member instanceof Array) return parent(member)(...args); else return parent[member](...args); } exports.callAsync = callAsync; /** * Deletes the member referred to by the object and key/deepkey * * @example * * * @param object * @param key * @returns */ function del(object, key) { const { parent, member } = destructure(object, key); finishDel(parent, member); } exports.del = del; /** * Async equivalent of {@link del} * * @example * * * @param object * @param key */ async function delAsync(object, key) { const { parent, member } = await destructureAsync(object, key); finishDel(parent, member); } exports.delAsync = delAsync; function finishDel(parent, member) { if (member instanceof Array) { const result = []; for (let item of member) { result.push(del(parent, item)); } return result; } else { const result = parent[member]; delete parent[member]; return result; } }