UNPKG

penpal

Version:

A promise-based library for communicating with iframes via postMessage.

68 lines (67 loc) 2.54 kB
const KEY_PATH_DELIMITER = '.'; const keyPathToSegments = (keyPath) => keyPath ? keyPath.split(KEY_PATH_DELIMITER) : []; const segmentsToKeyPath = (segments) => segments.join(KEY_PATH_DELIMITER); const createKeyPath = (key, prefix) => { const segments = keyPathToSegments(prefix || ''); segments.push(key); return segmentsToKeyPath(segments); }; /** * Given a `keyPath`, set it to be `value` on `subject`, creating any intermediate * objects along the way. * * @param {Object} subject The object on which to set value. * @param {string} keyPath The key path at which to set value. * @param {Object} value The value to store at the given key path. * @returns {Object} Updated subject. */ export const setAtKeyPath = (subject, keyPath, value) => { const segments = keyPathToSegments(keyPath); segments.reduce((prevSubject, key, idx) => { if (typeof prevSubject[key] === 'undefined') { prevSubject[key] = {}; } if (idx === segments.length - 1) { prevSubject[key] = value; } return prevSubject[key]; }, subject); return subject; }; /** * Given a dictionary of (nested) keys to function, flatten them to a map * from key path to function. * * @param {Object} methods The (potentially nested) object to serialize. * @param {string} prefix A string with which to prefix entries. Typically not intended to be used by consumers. * @returns {Object} An map from key path in `methods` to functions. */ export const serializeMethods = (methods, prefix) => { const flattenedMethods = {}; Object.keys(methods).forEach((key) => { const value = methods[key]; const keyPath = createKeyPath(key, prefix); if (typeof value === 'object') { // Recurse into any nested children. Object.assign(flattenedMethods, serializeMethods(value, keyPath)); } if (typeof value === 'function') { // If we've found a method, expose it. flattenedMethods[keyPath] = value; } }); return flattenedMethods; }; /** * Given a map of key paths to functions, unpack the key paths to an object. * * @param {Object} flattenedMethods A map of key paths to functions to unpack. * @returns {Object} A (potentially nested) map of functions. */ export const deserializeMethods = (flattenedMethods) => { const methods = {}; for (const keyPath in flattenedMethods) { setAtKeyPath(methods, keyPath, flattenedMethods[keyPath]); } return methods; };