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
JavaScript
;
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;
}
}