rox-browser
Version:
Rollout.io ROX JS SDK Client
1,409 lines (1,232 loc) • 343 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("axios"));
else if(typeof define === 'function' && define.amd)
define(["axios"], factory);
else if(typeof exports === 'object')
exports["Rox"] = factory(require("axios"));
else
root["Rox"] = factory(root["axios"]);
})(globalThis, (__WEBPACK_EXTERNAL_MODULE__85__) => {
return /******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ([
/* 0 */,
/* 1 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _RoxClient__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
/* harmony import */ var _FreezeOptions__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(51);
/* harmony import */ var rox_base__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(54);
/* harmony import */ var rox_base__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(16);
/* harmony import */ var rox_base__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(39);
/* harmony import */ var rox_base__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(30);
/* harmony import */ var _RoxStringBrowser__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(46);
/* harmony import */ var _RoxNumberBrowser__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(55);
/* harmony import */ var _RoxFlagBrowser__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(56);
/* harmony import */ var _DebuggerUI__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(91);
/* harmony import */ var _Overrider__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(52);
class Rox {
constructor() {
this.RoxString = _RoxStringBrowser__WEBPACK_IMPORTED_MODULE_2__["default"];
this.RoxNumber = _RoxNumberBrowser__WEBPACK_IMPORTED_MODULE_3__["default"];
this.setContext = rox_base__WEBPACK_IMPORTED_MODULE_7__.setContext;
this.Flag = _RoxFlagBrowser__WEBPACK_IMPORTED_MODULE_4__["default"];
this.showOverrides = _DebuggerUI__WEBPACK_IMPORTED_MODULE_5__.open;
this.overrides = _Overrider__WEBPACK_IMPORTED_MODULE_6__;
}
/**
* Initiate connection with ROX servers for the application identified by the application key. The registered containers will be synced and Rox entities will get the appropriate values.
* @param {String} appKey application key as appears in ROX dashboard
* @param {Object} options optional configuration object
*/
setup(appKey, options = {}) {
rox_base__WEBPACK_IMPORTED_MODULE_8__["default"].setVerboseMode(options.debugLevel);
if (options.proxy) {
rox_base__WEBPACK_IMPORTED_MODULE_9__["default"].setProxy(options.proxy);
}
if (options.freeze) {
(0,_FreezeOptions__WEBPACK_IMPORTED_MODULE_1__.setDefaultFreezeOption)(options.freeze);
}
_RoxClient__WEBPACK_IMPORTED_MODULE_0__["default"].setKey(appKey, options);
if (options.configuration) {
rox_base__WEBPACK_IMPORTED_MODULE_9__["default"].setActive(options.configuration);
}
else if (options.hosting) {
rox_base__WEBPACK_IMPORTED_MODULE_9__["default"].setHosting(options.hosting);
}
_RoxClient__WEBPACK_IMPORTED_MODULE_0__["default"].setup(options);
_RoxClient__WEBPACK_IMPORTED_MODULE_0__["default"].sendState();
if (options.disableNetworkFetch) {
return _RoxClient__WEBPACK_IMPORTED_MODULE_0__["default"].fetchCacheOnly();
}
else {
return _RoxClient__WEBPACK_IMPORTED_MODULE_0__["default"].fetchWithCacheAndProceed();
}
}
fetch() {
_RoxClient__WEBPACK_IMPORTED_MODULE_0__["default"] && _RoxClient__WEBPACK_IMPORTED_MODULE_0__["default"].fetch();
}
setCustomStringProperty(key, value) {
_RoxClient__WEBPACK_IMPORTED_MODULE_0__["default"].setCustomProperty(key, String, value);
}
setCustomDateProperty(key, value) {
_RoxClient__WEBPACK_IMPORTED_MODULE_0__["default"].setCustomProperty(key, Date, value);
}
setCustomNumberProperty(key, value) {
_RoxClient__WEBPACK_IMPORTED_MODULE_0__["default"].setCustomProperty(key, Number, value);
}
setCustomBooleanProperty(key, value) {
_RoxClient__WEBPACK_IMPORTED_MODULE_0__["default"].setCustomProperty(key, Boolean, value);
}
setCustomSemverProperty(key, value) {
_RoxClient__WEBPACK_IMPORTED_MODULE_0__["default"].setSemverCustomProperty(key, value);
}
/**
* Register a container of Rox entities by specifying a namespace.
* @param {String} name Container name
* @param {Object} container Object literal whose properties are Rox entities
*/
register(name, container) {
_RoxClient__WEBPACK_IMPORTED_MODULE_0__["default"].register(name, container);
}
unfreeze(namespace) {
_RoxClient__WEBPACK_IMPORTED_MODULE_0__["default"].unfreeze(namespace);
}
get flags() {
return rox_base__WEBPACK_IMPORTED_MODULE_10__["default"].flags;
}
get dynamicApi() {
return _RoxClient__WEBPACK_IMPORTED_MODULE_0__["default"].dynamicApi;
}
setUserspaceUnhandledErrorHandler(handler) {
_RoxClient__WEBPACK_IMPORTED_MODULE_0__["default"].setUserspaceUnhandledErrorHandler(handler);
}
}
const instance = new Rox();
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (instance);
/***/ }),
/* 2 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var rox_base__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(57);
/* harmony import */ var _DeviceProperties__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3);
/* harmony import */ var _DefaultSetupOptions__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11);
/* harmony import */ var _DefaultProperties__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(12);
/* harmony import */ var _RoxCache__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5);
/* harmony import */ var _RoxCrypto__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(41);
/* harmony import */ var _EntitiesProvider__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(45);
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ((0,rox_base__WEBPACK_IMPORTED_MODULE_6__.createRoxClient)({
DeviceProperties: _DeviceProperties__WEBPACK_IMPORTED_MODULE_0__["default"],
getDefaultCustomProperties: _DefaultProperties__WEBPACK_IMPORTED_MODULE_2__.getDefaultCustomProperties,
DefaultSetupOptions: _DefaultSetupOptions__WEBPACK_IMPORTED_MODULE_1__.defaultSetupOptions,
RoxCache: _RoxCache__WEBPACK_IMPORTED_MODULE_3__["default"],
RoxCrypto: _RoxCrypto__WEBPACK_IMPORTED_MODULE_4__["default"],
EntitiesProvider: _EntitiesProvider__WEBPACK_IMPORTED_MODULE_5__["default"]
}));
/***/ }),
/* 3 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var rox_base__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(10);
/* harmony import */ var _manifest__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4);
/* harmony import */ var _RoxCache__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5);
/* harmony import */ var uuid_browser_v4__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7);
/* harmony import */ var uuid_browser_v4__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(uuid_browser_v4__WEBPACK_IMPORTED_MODULE_2__);
const { api_version, lib_version } = _manifest__WEBPACK_IMPORTED_MODULE_0__["default"];
class DeviceProperties extends rox_base__WEBPACK_IMPORTED_MODULE_3__["default"] {
getProperties() {
const { distinct_id, app_release, platform, realPlatform } = this;
return Object.assign({ app_release,
api_version,
lib_version,
distinct_id,
platform,
realPlatform, customSigningCertificate: '5659eb0ca47811395ef85f0b09be63b7', language: navigator.language, anticache: +Date.now() }, (typeof window === 'undefined'
? {}
: {
screen_width: window.screen.width,
screen_height: window.screen.height,
}));
}
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (new DeviceProperties(_RoxCache__WEBPACK_IMPORTED_MODULE_1__["default"], (uuid_browser_v4__WEBPACK_IMPORTED_MODULE_2___default())));
/***/ }),
/* 4 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
api_version: '1.9.0',
lib_version: '6.0.3'
});
/***/ }),
/* 5 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var lscache__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6);
/* harmony import */ var lscache__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lscache__WEBPACK_IMPORTED_MODULE_0__);
class RoxCache {
set(key, value, ttl) {
lscache__WEBPACK_IMPORTED_MODULE_0___default().set(key, value, ttl);
}
get(key) {
return lscache__WEBPACK_IMPORTED_MODULE_0___default().get(key);
}
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (new RoxCache());
/***/ }),
/* 6 */
/***/ (function(module, exports) {
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
* lscache library
* Copyright (c) 2011, Pamela Fox
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* jshint undef:true, browser:true, node:true */
/* global define */
(function (root, factory) {
if (true) {
// AMD. Register as an anonymous module.
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
} else {}
}(this, function () {
// Prefix for all lscache keys
var CACHE_PREFIX = 'lscache-';
// Suffix for the key name on the expiration items in localStorage
var CACHE_SUFFIX = '-cacheexpiration';
// expiration date radix (set to Base-36 for most space savings)
var EXPIRY_RADIX = 10;
// time resolution in milliseconds
var expiryMilliseconds = 60 * 1000;
// ECMAScript max Date (epoch + 1e8 days)
var maxDate = calculateMaxDate(expiryMilliseconds);
var cachedStorage;
var cachedJSON;
var cacheBucket = '';
var warnings = false;
// Determines if localStorage is supported in the browser;
// result is cached for better performance instead of being run each time.
// Feature detection is based on how Modernizr does it;
// it's not straightforward due to FF4 issues.
// It's not run at parse-time as it takes 200ms in Android.
function supportsStorage() {
var key = '__lscachetest__';
var value = key;
if (cachedStorage !== undefined) {
return cachedStorage;
}
// some browsers will throw an error if you try to access local storage (e.g. brave browser)
// hence check is inside a try/catch
try {
if (!localStorage) {
return false;
}
} catch (ex) {
return false;
}
try {
setItem(key, value);
removeItem(key);
cachedStorage = true;
} catch (e) {
// If we hit the limit, and we don't have an empty localStorage then it means we have support
if (isOutOfSpace(e) && localStorage.length) {
cachedStorage = true; // just maxed it out and even the set test failed.
} else {
cachedStorage = false;
}
}
return cachedStorage;
}
// Check to set if the error is us dealing with being out of space
function isOutOfSpace(e) {
return e && (
e.name === 'QUOTA_EXCEEDED_ERR' ||
e.name === 'NS_ERROR_DOM_QUOTA_REACHED' ||
e.name === 'QuotaExceededError'
);
}
// Determines if native JSON (de-)serialization is supported in the browser.
function supportsJSON() {
/*jshint eqnull:true */
if (cachedJSON === undefined) {
cachedJSON = (window.JSON != null);
}
return cachedJSON;
}
/**
* Returns a string where all RegExp special characters are escaped with a \.
* @param {String} text
* @return {string}
*/
function escapeRegExpSpecialCharacters(text) {
return text.replace(/[[\]{}()*+?.\\^$|]/g, '\\$&');
}
/**
* Returns the full string for the localStorage expiration item.
* @param {String} key
* @return {string}
*/
function expirationKey(key) {
return key + CACHE_SUFFIX;
}
/**
* Returns the number of minutes since the epoch.
* @return {number}
*/
function currentTime() {
return Math.floor((new Date().getTime())/expiryMilliseconds);
}
/**
* Wrapper functions for localStorage methods
*/
function getItem(key) {
return localStorage.getItem(CACHE_PREFIX + cacheBucket + key);
}
function setItem(key, value) {
// Fix for iPad issue - sometimes throws QUOTA_EXCEEDED_ERR on setItem.
localStorage.removeItem(CACHE_PREFIX + cacheBucket + key);
localStorage.setItem(CACHE_PREFIX + cacheBucket + key, value);
}
function removeItem(key) {
localStorage.removeItem(CACHE_PREFIX + cacheBucket + key);
}
function eachKey(fn) {
var prefixRegExp = new RegExp('^' + CACHE_PREFIX + escapeRegExpSpecialCharacters(cacheBucket) + '(.*)');
// We first identify which keys to process
var keysToProcess = [];
var key, i;
for (i = 0; i < localStorage.length; i++) {
key = localStorage.key(i);
key = key && key.match(prefixRegExp);
key = key && key[1];
if (key && key.indexOf(CACHE_SUFFIX) < 0) {
keysToProcess.push(key);
}
}
// Then we apply the processing function to each key
for (i = 0; i < keysToProcess.length; i++) {
fn(keysToProcess[i], expirationKey(keysToProcess[i]));
}
}
function flushItem(key) {
var exprKey = expirationKey(key);
removeItem(key);
removeItem(exprKey);
}
function flushExpiredItem(key) {
var exprKey = expirationKey(key);
var expr = getItem(exprKey);
if (expr) {
var expirationTime = parseInt(expr, EXPIRY_RADIX);
// Check if we should actually kick item out of storage
if (currentTime() >= expirationTime) {
removeItem(key);
removeItem(exprKey);
return true;
}
}
}
function warn(message, err) {
if (!warnings) return;
if (!('console' in window) || typeof window.console.warn !== 'function') return;
window.console.warn("lscache - " + message);
if (err) window.console.warn("lscache - The error was: " + err.message);
}
function calculateMaxDate(expiryMilliseconds) {
return Math.floor(8.64e15/expiryMilliseconds);
}
var lscache = {
/**
* Stores the value in localStorage. Expires after specified number of minutes.
* @param {string} key
* @param {Object|string} value
* @param {number} time
* @return {boolean} whether the value was inserted successfully
*/
set: function(key, value, time) {
if (!supportsStorage()) return false;
// If we don't get a string value, try to stringify
// In future, localStorage may properly support storing non-strings
// and this can be removed.
if (!supportsJSON()) return false;
try {
value = JSON.stringify(value);
} catch (e) {
// Sometimes we can't stringify due to circular refs
// in complex objects, so we won't bother storing then.
return false;
}
try {
setItem(key, value);
} catch (e) {
if (isOutOfSpace(e)) {
// If we exceeded the quota, then we will sort
// by the expire time, and then remove the N oldest
var storedKeys = [];
var storedKey;
eachKey(function(key, exprKey) {
var expiration = getItem(exprKey);
if (expiration) {
expiration = parseInt(expiration, EXPIRY_RADIX);
} else {
// TODO: Store date added for non-expiring items for smarter removal
expiration = maxDate;
}
storedKeys.push({
key: key,
size: (getItem(key) || '').length,
expiration: expiration
});
});
// Sorts the keys with oldest expiration time last
storedKeys.sort(function(a, b) { return (b.expiration-a.expiration); });
var targetSize = (value||'').length;
while (storedKeys.length && targetSize > 0) {
storedKey = storedKeys.pop();
warn("Cache is full, removing item with key '" + storedKey.key + "'");
flushItem(storedKey.key);
targetSize -= storedKey.size;
}
try {
setItem(key, value);
} catch (e) {
// value may be larger than total quota
warn("Could not add item with key '" + key + "', perhaps it's too big?", e);
return false;
}
} else {
// If it was some other error, just give up.
warn("Could not add item with key '" + key + "'", e);
return false;
}
}
// If a time is specified, store expiration info in localStorage
if (time) {
setItem(expirationKey(key), (currentTime() + time).toString(EXPIRY_RADIX));
} else {
// In case they previously set a time, remove that info from localStorage.
removeItem(expirationKey(key));
}
return true;
},
/**
* Retrieves specified value from localStorage, if not expired.
* @param {string} key
* @return {string|Object}
*/
get: function(key) {
if (!supportsStorage()) return null;
// Return the de-serialized item if not expired
if (flushExpiredItem(key)) { return null; }
// Tries to de-serialize stored value if its an object, and returns the normal value otherwise.
var value = getItem(key);
if (!value || !supportsJSON()) {
return value;
}
try {
// We can't tell if its JSON or a string, so we try to parse
return JSON.parse(value);
} catch (e) {
// If we can't parse, it's probably because it isn't an object
return value;
}
},
/**
* Removes a value from localStorage.
* Equivalent to 'delete' in memcache, but that's a keyword in JS.
* @param {string} key
*/
remove: function(key) {
if (!supportsStorage()) return;
flushItem(key);
},
/**
* Returns whether local storage is supported.
* Currently exposed for testing purposes.
* @return {boolean}
*/
supported: function() {
return supportsStorage();
},
/**
* Flushes all lscache items and expiry markers without affecting rest of localStorage
*/
flush: function() {
if (!supportsStorage()) return;
eachKey(function(key) {
flushItem(key);
});
},
/**
* Flushes expired lscache items and expiry markers without affecting rest of localStorage
*/
flushExpired: function() {
if (!supportsStorage()) return;
eachKey(function(key) {
flushExpiredItem(key);
});
},
/**
* Appends CACHE_PREFIX so lscache will partition data in to different buckets.
* @param {string} bucket
*/
setBucket: function(bucket) {
cacheBucket = bucket;
},
/**
* Resets the string being appended to CACHE_PREFIX so lscache will use the default storage behavior.
*/
resetBucket: function() {
cacheBucket = '';
},
/**
* @returns {number} The currently set number of milliseconds each time unit represents in
* the set() function's "time" argument.
*/
getExpiryMilliseconds: function() {
return expiryMilliseconds;
},
/**
* Sets the number of milliseconds each time unit represents in the set() function's
* "time" argument.
* Sample values:
* 1: each time unit = 1 millisecond
* 1000: each time unit = 1 second
* 60000: each time unit = 1 minute (Default value)
* 360000: each time unit = 1 hour
* @param {number} milliseconds
*/
setExpiryMilliseconds: function(milliseconds) {
expiryMilliseconds = milliseconds;
maxDate = calculateMaxDate(expiryMilliseconds);
},
/**
* Sets whether to display warnings when an item is removed from the cache or not.
*/
enableWarnings: function(enabled) {
warnings = enabled;
}
};
// Return the module
return lscache;
}));
/***/ }),
/* 7 */
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
var rng = __webpack_require__(8);
var bytesToUuid = __webpack_require__(9);
function v4(options, buf, offset) {
var i = buf && offset || 0;
if (typeof(options) == 'string') {
buf = options == 'binary' ? new Array(16) : null;
options = null;
}
options = options || {};
var rnds = options.random || (options.rng || rng)();
// Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
rnds[6] = (rnds[6] & 0x0f) | 0x40;
rnds[8] = (rnds[8] & 0x3f) | 0x80;
// Copy bytes to buffer, if provided
if (buf) {
for (var ii = 0; ii < 16; ++ii) {
buf[i + ii] = rnds[ii];
}
}
return buf || bytesToUuid(rnds);
}
module.exports = v4;
/***/ }),
/* 8 */
/***/ ((module) => {
// Unique ID creation requires a high quality random # generator. In the
// browser this is a little complicated due to unknown quality of Math.random()
// and inconsistent support for the `crypto` API. We do the best we can via
// feature-detection
var rng;
var crypto = typeof window !== 'undefined' && (window.crypto || window.msCrypto); // for IE 11
if (crypto && crypto.getRandomValues) {
// WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto
var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef
rng = function whatwgRNG() {
crypto.getRandomValues(rnds8);
return rnds8;
};
}
if (!rng) {
// Math.random()-based (RNG)
//
// If all else fails, use Math.random(). It's fast, but is of unspecified
// quality.
var rnds = new Array(16);
rng = function() {
for (var i = 0, r; i < 16; i++) {
if ((i & 0x03) === 0) r = Math.random() * 0x100000000;
rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
}
return rnds;
};
}
module.exports = rng;
/***/ }),
/* 9 */
/***/ ((module) => {
/**
* Convert array of 16 byte values to UUID string format of the form:
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
*/
var byteToHex = [];
for (var i = 0; i < 256; ++i) {
byteToHex[i] = (i + 0x100).toString(16).substr(1);
}
function bytesToUuid(buf, offset) {
var i = offset || 0;
var bth = byteToHex;
return bth[buf[i++]] + bth[buf[i++]] +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] +
bth[buf[i++]] + bth[buf[i++]] +
bth[buf[i++]] + bth[buf[i++]];
}
module.exports = bytesToUuid;
/***/ }),
/* 10 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (/* binding */ DeviceProperties)
/* harmony export */ });
class DeviceProperties {
constructor(cache, uuid) {
this.cache = cache;
this._uuid = uuid;
this.distinct_id = this.generateDistinctId();
this.app_release = '0.0';
this.distinctIdSetExplicitly = false;
}
setPlatform(platform) {
this.platform = platform;
}
setRealPlatform(realPlatform) {
this.realPlatform = realPlatform;
}
setDistinctId(id) {
this.distinctIdSetExplicitly = true;
this.distinct_id = id;
}
setAppRelease(appRelease) {
this.app_release = appRelease;
}
uuid() {
return this._uuid();
}
generateDistinctId() {
let distinct_id = this.cache.get('distinctId');
if (!distinct_id) {
distinct_id = this.uuid();
this.cache.set('distinctId', distinct_id);
}
return distinct_id;
}
}
/***/ }),
/* 11 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ defaultSetupOptions: () => (/* binding */ defaultSetupOptions)
/* harmony export */ });
const defaultSetupOptions = {
distinctId: null,
version: '0',
configurationFetchedHandler: function () { },
impressionHandler: null,
devModeSecret: null,
platform: 'Browser',
analytics: {
flushAt: 20,
flushInterval: 1000
}
};
/***/ }),
/* 12 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ getDefaultCustomProperties: () => (/* binding */ getDefaultCustomProperties)
/* harmony export */ });
/* harmony import */ var rox_base__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(13);
const { CustomProperty } = rox_base__WEBPACK_IMPORTED_MODULE_0__;
function getDefaultCustomProperties(deviceProps, appKey) {
const _props = deviceProps.getProperties();
return [
new CustomProperty('rox.app_release', CustomProperty.semverTypeName, _props.app_release),
new CustomProperty('rox.platform', String, _props.platform),
new CustomProperty('rox.screen_width', Number, _props.screen_width),
new CustomProperty('rox.screen_height', Number, _props.screen_height),
new CustomProperty('rox.language', String, _props.language),
new CustomProperty('rox.distinct_id', String, _props.distinct_id),
new CustomProperty('rox.internal.realPlatform', String, 'Browser'),
new CustomProperty('rox.internal.customPlatform', String, _props.platform),
new CustomProperty('rox.internal.appKey', String, appKey),
new CustomProperty('rox.internal.distinct_id', String, _props.distinct_id),
new CustomProperty('rox.now', Date, () => new Date()),
];
}
/***/ }),
/* 13 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ CallContextTypes: () => (/* reexport safe */ _RoxStringBase__WEBPACK_IMPORTED_MODULE_5__.callContextTypes),
/* harmony export */ CustomProperty: () => (/* reexport safe */ _CustomProperty__WEBPACK_IMPORTED_MODULE_0__["default"]),
/* harmony export */ DeploymentConfiguration: () => (/* reexport safe */ _DeploymentConfiguration__WEBPACK_IMPORTED_MODULE_2__["default"]),
/* harmony export */ DeviceProperty: () => (/* reexport safe */ _DeviceProperty__WEBPACK_IMPORTED_MODULE_1__["default"]),
/* harmony export */ Experiment: () => (/* reexport safe */ _Experiment__WEBPACK_IMPORTED_MODULE_3__["default"]),
/* harmony export */ FlagTypes: () => (/* reexport safe */ _RoxStringBase__WEBPACK_IMPORTED_MODULE_5__.FlagTypes),
/* harmony export */ RoxStringBase: () => (/* reexport safe */ _RoxStringBase__WEBPACK_IMPORTED_MODULE_5__["default"]),
/* harmony export */ TargetGroup: () => (/* reexport safe */ _TargetGroup__WEBPACK_IMPORTED_MODULE_4__["default"])
/* harmony export */ });
/* harmony import */ var _CustomProperty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(14);
/* harmony import */ var _DeviceProperty__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17);
/* harmony import */ var _DeploymentConfiguration__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(18);
/* harmony import */ var _Experiment__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(19);
/* harmony import */ var _TargetGroup__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(20);
/* harmony import */ var _RoxStringBase__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(21);
/***/ }),
/* 14 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (/* binding */ CustomProperty)
/* harmony export */ });
/* harmony import */ var _lib_UserspaceUnhandledErrorInvoker__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(15);
const SEM_VER_TYPE = 'Semver';
const _validateName = function (name) {
if (typeof name === 'undefined' || name === '') {
throw new Error('Custom property must be initialized with a name.');
}
};
const _validateExplicitValue = function (type, value) {
if (value && value.constructor !== type && value.constructor !== Function) {
// add here a condition with a return if we want to validate semver (we usually don't, it's just a string)
throw new Error(`Custom property initialized with an invalid type / value combination. (Type: ${type}, Value: ${value})`);
}
};
const _validateDynamicValue = function (value) {
const argsExpected = value.length;
if (argsExpected > 1) {
throw new Error('Dynamic value of a custom property should be a function with maximum 1 argument');
}
};
class CustomProperty {
constructor(name, type, value) {
if (type === SEM_VER_TYPE) {
this._isSemver = true;
type = String;
}
_validateName(name);
this._name = name;
if (typeof value === 'function') {
_validateDynamicValue(value);
value.isDynamic = true;
this._value = value;
}
else {
_validateExplicitValue(type, value);
this._value = () => value;
}
this._type = type;
}
get type() {
return this.externalType;
}
get externalType() {
if (this._isSemver) {
return SEM_VER_TYPE;
}
if (this._type.name == Date.name) {
return CustomProperty.dateTypeName;
}
return this._type.name;
}
get name() {
return this._name;
}
getValue(context = {}) {
if (this._value && this._value.isDynamic) {
try {
return this._value(context);
}
catch (err) {
err.isUserError = true;
err.trigger = _lib_UserspaceUnhandledErrorInvoker__WEBPACK_IMPORTED_MODULE_0__.ExceptionTrigger.CUSTOM_PROPERTY_GENERATOR;
throw err;
}
}
return this._value(context);
}
static get dateTypeName() {
return 'DateTime';
}
static get semverTypeName() {
return SEM_VER_TYPE;
}
get value() {
return this._value();
}
}
/***/ }),
/* 15 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ ExceptionTrigger: () => (/* binding */ ExceptionTrigger),
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _RoxLogger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(16);
const ExceptionTrigger = {
DYNAMIC_PROPERTIES_RULE: 'DYNAMIC_PROPERTIES_RULE',
CONFIGURATION_FETCHED_HANDLER: 'CONFIGURATION_FETCHED_HANDLER',
IMPRESSION_HANDLER: 'IMPRESSION_HANDLER',
CUSTOM_PROPERTY_GENERATOR: 'CUSTOM_PROPERTY_GENERATOR'
};
class UserspaceUnhandledErrorInvoker {
invoke(exceptionTrigger, error) {
if (!this.userUnhandledErrorHandler) {
_RoxLogger__WEBPACK_IMPORTED_MODULE_0__["default"].error('User Unhandled Error Occured, no fallback handler was set, exception ignored.', error);
return;
}
try {
this.userUnhandledErrorHandler(exceptionTrigger, error);
}
catch (err) {
_RoxLogger__WEBPACK_IMPORTED_MODULE_0__["default"].error('User Unhandled Error Handler itself threw an exception. original exception:' + error, err);
}
}
setHandler(handler) {
if (!(handler instanceof Function)) {
_RoxLogger__WEBPACK_IMPORTED_MODULE_0__["default"].warn('UserspaceUnhandledErrorHandler must be a function. default will be used.');
return;
}
this.userUnhandledErrorHandler = handler;
}
}
// wanted to create with new on client.js and pass it as an object, but 'new RoxParser()' appears in too many places :(
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (new UserspaceUnhandledErrorInvoker());
/***/ }),
/* 16 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
const levels = {
debug: 0,
info: 1,
warn: 2,
error: 3
};
let level = 'error';
class Logger {
constructor() {
this.debug = (data, ...args) => {
if (levels[level] <= levels.debug && console /* console not present on old IEs */) {
console.log(data, ...args); // eslint-disable-line no-console
}
};
this.info = (data, ...args) => {
if (levels[level] <= levels.info && console /* console not present on old IEs */) {
console.info(data, ...args); // eslint-disable-line no-console
}
};
this.warn = (data, ...args) => {
if (levels[level] <= levels.warn && console /* console not present on old IEs */) {
console.warn(data, ...args); // eslint-disable-line no-console
}
};
this.error = (data, ...args) => {
if (console /* console not present on old IEs */) {
console.error(data, ...args); // eslint-disable-line no-console
}
};
this.setVerboseMode = debugLevel => {
if (debugLevel === 'verbose') {
level = 'debug';
this.debug('Active verbose mode');
}
else {
level = 'error';
}
};
this.setLogger = (newLogger) => {
logger = newLogger;
};
}
}
let logger = new Logger();
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (logger);
/***/ }),
/* 17 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (/* binding */ DeviceProperty)
/* harmony export */ });
/* harmony import */ var _CustomProperty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(14);
class DeviceProperty extends _CustomProperty__WEBPACK_IMPORTED_MODULE_0__["default"] {
get name() {
return `rox.${super.name}`;
}
}
/***/ }),
/* 18 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (/* binding */ DeploymentConfiguration)
/* harmony export */ });
class DeploymentConfiguration {
constructor(condition) {
this.condition = condition;
}
}
/***/ }),
/* 19 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (/* binding */ Experiment)
/* harmony export */ });
class Experiment {
constructor(identifier, name, archived, sticky, deploymentConfiguration, flags, labels, stickinessProperty) {
this.identifier = identifier;
this.name = name;
this.archived = archived;
this.sticky = sticky;
this.deploymentConfiguration = deploymentConfiguration;
this.flags = flags;
this.labels = labels;
this.stickinessProperty = stickinessProperty;
}
}
/***/ }),
/* 20 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (/* binding */ TargetGroup)
/* harmony export */ });
class TargetGroup {
constructor(identifier, condition) {
this.identifier = identifier;
this.condition = condition;
}
}
/***/ }),
/* 21 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ FlagTypes: () => (/* binding */ FlagTypes),
/* harmony export */ callContextTypes: () => (/* binding */ callContextTypes),
/* harmony export */ "default": () => (/* binding */ RoxStringBase)
/* harmony export */ });
/* harmony import */ var _lib_ImpressionHandler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(22);
const callContextTypes = {
frozenOrCalc: 'frozenValueOrOneTimeEval',
oneTimeCalc: 'oneTimeEval',
default: 'useFrozen',
};
const FlagTypes = {
boolean: 'boolean',
number: 'number',
string: 'string',
};
class RoxStringBase {
constructor(defaultValue, variations, type) {
this._type = type;
const stringDefault = this._validateDefault(defaultValue);
if (Array.isArray(variations)) {
this._validateOptions(variations);
this._options = variations.map((v) => v.toString());
}
else if (variations === null || variations === undefined) {
this._options = [];
}
else {
throw new Error(`RoxStringBase wrong variations type`);
}
if (this._options.indexOf(stringDefault) === -1) {
this._options.push(stringDefault);
}
this._value = this._defaultValue = stringDefault;
this._frozen = false;
this._freezable = true;
}
_validateDefault(defaultValue) {
if (typeof defaultValue !== this._type) {
throw new Error(`RoxStringBase default value must be of ${this._type} type. Received '${defaultValue}'`);
}
return defaultValue.toString();
}
_validateOptions(variations) {
const optionsError = new Error(`RoxStringBase options must be a non-empty array of ${this._type}. Received '${variations}'`);
if (!variations.every((option) => typeof option === this._type)) {
throw optionsError;
}
}
get defaultValue() {
return this._defaultValue;
}
get overridenValue() {
if (this.overrider.hasOverride(this.name)) {
return this.overrider.getOverride(this.name);
}
}
get overrider() {
throw new Error('Not implemented');
}
/* abstract */
// eslint-disable-next-line no-unused-vars
getInternalValue(_, __) {
throw Error('not implemented');
}
get externalType() {
switch (this._type) {
case FlagTypes.boolean:
return Boolean.name;
case FlagTypes.number:
return Number.name;
case FlagTypes.string:
return String.name;
default:
return String.name;
}
}
set name(name) {
this._name = name;
}
get name() {
return this._name;
}
_getNameDetails() {
if (!this.name)
return;
const els = this.name.split('.');
return {
name: els.pop(),
namespace: els.join('.') || 'default',
};
}
dump() {
const currentValueCall = { type: callContextTypes.frozenOrCalc };
this.getInternalValue(currentValueCall);
return {
name: this.name,
type: this._type,
nameDetails: this._getNameDetails(),
options: [...this._options],
defaultValue: this.defaultValue,
originalValue: this._originalValue(),
overridingValue: this.overridenValue,
value: currentValueCall.result.value,
};
}
// eslint-disable-next-line no-unused-vars
getActiveValue(_, __) {
throw new Error('Not implemented');
}
_originalValue() {
const callContext = { type: callContextTypes.frozenOrCalc };
this.getActiveValue(callContext);
return callContext.result.value;
}
_flagImpression(value, context) {
(0,_lib_ImpressionHandler__WEBPACK_IMPORTED_MODULE_0__.invokeImpression)(value, this, context);
}
static _normalizeString(stringValue) {
return stringValue;
}
static _normalizeNumber(stringValue) {
return Number(stringValue);
}
static _normalizeBoolean(stringValue) {
if (typeof stringValue === 'boolean')
return stringValue;
return stringValue === 'true';
}
}
/***/ }),
/* 22 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ invokeImpression: () => (/* binding */ invokeImpression),
/* harmony export */ setAnalytics: () => (/* binding */ setAnalytics),
/* harmony export */ setHandler: () => (/* binding */ setHandler)
/* harmony export */ });
/* harmony import */ var _RoxLogger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(16);
/* harmony import */ var _InternalFlags__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(23);
/* harmony import */ var _repositories_ExperimentsRepository__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(31);
/* harmony import */ var _repositories_CustomPropertyRepository__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(29);
/* harmony import */ var _UserspaceUnhandledErrorInvoker__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(15);
let impressionHandler = null;
let analytics = null;
function invokeImpression(value, flag, context) {
const originExperiment = _repositories_ExperimentsRepository__WEBPACK_IMPORTED_MODULE_0__["default"].experimentForFlag(flag);
try {
if (analytics && (0,_InternalFlags__WEBPACK_IMPORTED_MODULE_1__.isEnabled)('rox.internal.analytics')) {
const originalExperimentStickinessPropName = originExperiment && originExperiment.stickinessProperty;
let distinctIdProp = originalExperimentStickinessPropName && _repositories_CustomPropertyRepository__WEBPACK_IMPORTED_MODULE_2__["default"].get(originalExperimentStickinessPropName);
distinctIdProp = distinctIdProp || _repositories_CustomPropertyRepository__WEBPACK_IMPORTED_MODULE_2__["default"].get(`rox.distinct_id`);
const distinctId = distinctIdProp ? distinctIdProp.getValue(context) : '';
analytics.track({
flag: flag.name,
value,
distinctId,
type: 'IMPRESSION',
time: new Date().getTime()
});
}
}
catch (err) {
_RoxLogger__WEBPACK_IMPORTED_MODULE_3__["default"].error('Failed to send analytics', err);
}
if (typeof impressionHandler !== 'function')
return;
const targeting = !!originExperiment;
try {
impressionHandler({ name: flag.name, value, targeting }, context);
}
catch (error) {
_UserspaceUnhandledErrorInvoker__WEBPACK_IMPORTED_MODULE_4__["default"].invoke(_UserspaceUnhandledErrorInvoker__WEBPACK_IMPORTED_MODULE_4__.ExceptionTrigger.IMPRESSION_HANDLER, error);
}
}
function setHandler(handler) {
impressionHandler = handler;
}
function setAnalytics(a) {
analytics = a;
}
/***/ }),
/* 23 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ getNumber: () => (/* binding */ getNumber),
/* harmony export */ isEnabled: () => (/* binding */ isEnabled),
/* harmony export */ setDefaultsMode: () => (/* binding */ setDefaultsMode),
/* harmony export */ value: () => (/* binding */ value)
/* harmony export */ });
/* harmony import */ var _parsers_RoxxParser__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(24);
/* harmony import */ var _repositories_ExperimentsRepository__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(31);
let isDefaultsMode = false;
const DEFAULTS = {
'rox.internal.pushUpdates': 'true',
'rox.internal.considerThrottleInPush': 'false',
'rox.internal.throttleFetchInSeconds': '0',
'rox.internal.analytics': 'true',
};
function isEnabled(flagName) {
const val = value(flagName);
if (typeof val === 'boolean')
return val;
return val === 'true';
}
function value(flagName) {
if (isDefaultsMode && Object.prototype.hasOwnProperty.call(DEFAULTS, flagName)) {
return DEFAULTS[flagName];
}
const internalExperiment = _repositories_ExperimentsRepository__WEBPACK_IMPORTED_MODULE_0__["default"].experimentForFlagName(flagName);
if (!internalExperiment || !internalExperiment.deploymentConfiguration)
return '';
const value = new _parsers_RoxxParser__WEBPACK_IMPORTED_MODULE_1__["default"]().evaluateExpression(internalExperiment.deploymentConfiguration.condition);
return value;
}
function getNumber(flagName) {
const val = value(flagName);
return parseInt(val) || 0;
}
function setDefaultsMode(mode) {
isDefaultsMode = mode;
}
/***/ }),
/* 24 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (/* binding */ RoxxParser)
/* harmony export */ });
/* harmony import */ var _RoxxTokenizer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(25);
/* harmony import */ var _lib_RoxLogger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(16);
/* harmony import */ var _lib_RoxxOperators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27);
/* harmony import */ var _lib_UserspaceUnhandledErrorInvoker__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(15);
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(39);
class RoxxParser {
/**
* A parser for Roxx expressions.
* Roxx expression are polish notation expressions {@link https://en.wikipedia.org/wiki/Polish_notation}
* @class
* @module RoxxParser
* @param {*} cache - Optional token cache object. A default cache object is used if none specified.
*/
constructor(cache) {
this._tokenizer = new _RoxxTokenizer__WEBPACK_IMPORTED_MODULE_0__.RoxxTokenizer();
this._cache = cache || {};
}
/**
* Given an operator function and stack, return an array of arguments for the operator.
* @param {Function} operator
* @param {Array} s