UNPKG

pusher-js

Version:

Pusher JavaScript library for browser, React Native, NodeJS and web workers

296 lines (274 loc) 7.29 kB
import base64encode from '../base64'; import Util from '../util'; const global = Function("return this")(); /** Merges multiple objects into the target argument. * * For properties that are plain Objects, performs a deep-merge. For the * rest it just copies the value of the property. * * To extend prototypes use it as following: * Pusher.Util.extend(Target.prototype, Base.prototype) * * You can also use it to merge objects without altering them: * Pusher.Util.extend({}, object1, object2) * * @param {Object} target * @return {Object} the target argument */ export function extend<T>(target : any, ...sources: any[]) : T { for (var i = 0; i < sources.length; i++) { var extensions = sources[i]; for (var property in extensions) { if (extensions[property] && extensions[property].constructor && extensions[property].constructor === Object) { target[property] = extend( target[property] || {}, extensions[property] ); } else { target[property] = extensions[property]; } } } return target; } export function stringify() : string { var m = ["Pusher"]; for (var i = 0; i < arguments.length; i++) { if (typeof arguments[i] === "string") { m.push(arguments[i]); } else { m.push(JSON.stringify(arguments[i])); } } return m.join(" : "); } export function arrayIndexOf(array : any[], item : any) : number { // MSIE doesn't have array.indexOf var nativeIndexOf = Array.prototype.indexOf; if (array === null) { return -1; } if (nativeIndexOf && array.indexOf === nativeIndexOf) { return array.indexOf(item); } for (var i = 0, l = array.length; i < l; i++) { if (array[i] === item) { return i; } } return -1; } /** Applies a function f to all properties of an object. * * Function f gets 3 arguments passed: * - element from the object * - key of the element * - reference to the object * * @param {Object} object * @param {Function} f */ export function objectApply(object : any, f : Function) { for (var key in object) { if (Object.prototype.hasOwnProperty.call(object, key)) { f(object[key], key, object); } } } /** Return a list of objects own proerty keys * * @param {Object} object * @returns {Array} */ export function keys(object : any) : string[] { var keys = []; objectApply(object, function(_, key) { keys.push(key); }); return keys; } /** Return a list of object's own property values * * @param {Object} object * @returns {Array} */ export function values(object : any) : any[] { var values = []; objectApply(object, function(value) { values.push(value); }); return values; } /** Applies a function f to all elements of an array. * * Function f gets 3 arguments passed: * - element from the array * - index of the element * - reference to the array * * @param {Array} array * @param {Function} f */ export function apply(array : any[], f : Function, context?: any) { for (var i = 0; i < array.length; i++) { f.call(context || global, array[i], i, array); } } /** Maps all elements of the array and returns the result. * * Function f gets 4 arguments passed: * - element from the array * - index of the element * - reference to the source array * - reference to the destination array * * @param {Array} array * @param {Function} f */ export function map(array : any[], f : Function) : any[] { var result = []; for (var i = 0; i < array.length; i++) { result.push(f(array[i], i, array, result)); } return result; } /** Maps all elements of the object and returns the result. * * Function f gets 4 arguments passed: * - element from the object * - key of the element * - reference to the source object * - reference to the destination object * * @param {Object} object * @param {Function} f */ export function mapObject(object : any, f : Function) : any { var result = {}; objectApply(object, function(value, key) { result[key] = f(value); }); return result; } /** Filters elements of the array using a test function. * * Function test gets 4 arguments passed: * - element from the array * - index of the element * - reference to the source array * - reference to the destination array * * @param {Array} array * @param {Function} f */ export function filter(array : any[], test : Function) : any[] { test = test || function(value) { return !!value; }; var result = []; for (var i = 0; i < array.length; i++) { if (test(array[i], i, array, result)) { result.push(array[i]); } } return result; } /** Filters properties of the object using a test function. * * Function test gets 4 arguments passed: * - element from the object * - key of the element * - reference to the source object * - reference to the destination object * * @param {Object} object * @param {Function} f */ export function filterObject(object : Object, test : Function) { var result = {}; objectApply(object, function(value, key) { if ((test && test(value, key, object, result)) || Boolean(value)) { result[key] = value; } }); return result; } /** Flattens an object into a two-dimensional array. * * @param {Object} object * @return {Array} resulting array of [key, value] pairs */ export function flatten(object : Object) : any[] { var result = []; objectApply(object, function(value, key) { result.push([key, value]); }); return result; } /** Checks whether any element of the array passes the test. * * Function test gets 3 arguments passed: * - element from the array * - index of the element * - reference to the source array * * @param {Array} array * @param {Function} f */ export function any(array : any[], test : Function) : boolean { for (var i = 0; i < array.length; i++) { if (test(array[i], i, array)) { return true; } } return false; } /** Checks whether all elements of the array pass the test. * * Function test gets 3 arguments passed: * - element from the array * - index of the element * - reference to the source array * * @param {Array} array * @param {Function} f */ export function all(array : any[], test : Function) : boolean { for (var i = 0; i < array.length; i++) { if (!test(array[i], i, array)) { return false; } } return true; } export function encodeParamsObject(data) : string { return mapObject(data, function(value) { if (typeof value === "object") { value = JSON.stringify(value); } return encodeURIComponent(base64encode(value.toString())); }); } export function buildQueryString(data : any) : string { var params = filterObject(data, function(value) { return value !== undefined; }); var query = map( flatten(encodeParamsObject(params)), Util.method("join", "=") ).join("&"); return query; } export function safeJSONStringify(source : any) : string { var cache = []; var serialized = JSON.stringify(source, function(key, value) { if (typeof value === 'object' && value !== null) { if (cache.indexOf(value) !== -1) { // Circular reference found, discard key return; } // Store value in our collection cache.push(value); } return value; }); cache = null; // Enable garbage collection return serialized; }