@featbit/js-client-sdk 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/esm/constants.d.ts +0 -1
- package/esm/constants.js +0 -1
- package/esm/constants.js.map +1 -1
- package/esm/logger.js +2 -6
- package/esm/logger.js.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +0 -1
- package/src/logger.ts +2 -7
- package/umd/featbit-js-client-sdk-2.0.2.js +2 -0
- package/umd/featbit-js-client-sdk-2.0.2.js.map +1 -0
- package/umd/featbit-js-client-sdk.js +1 -1
- package/umd/featbit-js-client-sdk.js.map +1 -1
- package/umd/featbit-js-client-sdk-2.0.0.js +0 -2
- package/umd/featbit-js-client-sdk-2.0.0.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
> **Deprecated**
|
|
2
|
+
>
|
|
3
|
+
> We have totally reimplemented the SDK to adapt to NextJs projects, for the new version, please refer to [@featbit/js-client-sdk](https://github.com/featbit/featbit-js-client-sdk)
|
|
4
|
+
|
|
1
5
|
# FeatBit Client-Side SDK for JavaScript
|
|
2
6
|
|
|
3
7
|
## Introduction
|
package/esm/constants.d.ts
CHANGED
|
@@ -2,6 +2,5 @@ export declare const insightsFlushTopic = "insights.flush";
|
|
|
2
2
|
export declare const featureFlagEvaluatedTopic = "featureflag.evaluated.topic";
|
|
3
3
|
export declare const featureFlagEvaluatedBufferTopic = "featureflag.evaluated.buffer.topic";
|
|
4
4
|
export declare const websocketReconnectTopic = "network.websocket.reconnect";
|
|
5
|
-
export declare const debugModeQueryStr = "debugmode";
|
|
6
5
|
export declare const insightsTopic = "insights.topic";
|
|
7
6
|
export declare const currentUserStorageKey = "fb-user";
|
package/esm/constants.js
CHANGED
|
@@ -2,7 +2,6 @@ export var insightsFlushTopic = 'insights.flush';
|
|
|
2
2
|
export var featureFlagEvaluatedTopic = 'featureflag.evaluated.topic';
|
|
3
3
|
export var featureFlagEvaluatedBufferTopic = 'featureflag.evaluated.buffer.topic';
|
|
4
4
|
export var websocketReconnectTopic = 'network.websocket.reconnect';
|
|
5
|
-
export var debugModeQueryStr = 'debugmode'; // will print debug logs if true
|
|
6
5
|
export var insightsTopic = 'insights.topic';
|
|
7
6
|
export var currentUserStorageKey = 'fb-user';
|
|
8
7
|
//# sourceMappingURL=constants.js.map
|
package/esm/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,IAAM,kBAAkB,GAAG,gBAAgB,CAAC;AACnD,MAAM,CAAC,IAAM,yBAAyB,GAAG,6BAA6B,CAAC;AACvE,MAAM,CAAC,IAAM,+BAA+B,GAAG,oCAAoC,CAAC;AACpF,MAAM,CAAC,IAAM,uBAAuB,GAAG,6BAA6B,CAAC;AACrE,MAAM,CAAC,IAAM,
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,IAAM,kBAAkB,GAAG,gBAAgB,CAAC;AACnD,MAAM,CAAC,IAAM,yBAAyB,GAAG,6BAA6B,CAAC;AACvE,MAAM,CAAC,IAAM,+BAA+B,GAAG,oCAAoC,CAAC;AACpF,MAAM,CAAC,IAAM,uBAAuB,GAAG,6BAA6B,CAAC;AACrE,MAAM,CAAC,IAAM,aAAa,GAAG,gBAAgB,CAAC;AAC9C,MAAM,CAAC,IAAM,qBAAqB,GAAG,SAAS,CAAC"}
|
package/esm/logger.js
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
// get debug mode from query string
|
|
3
|
-
var queryString = window.location.search;
|
|
4
|
-
var urlParams = new URLSearchParams(queryString);
|
|
5
|
-
var debugModeParam = urlParams.get(debugModeQueryStr);
|
|
1
|
+
var debug = false;
|
|
6
2
|
export var logger = {
|
|
7
3
|
logDebug: function () {
|
|
8
4
|
var args = [];
|
|
9
5
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
10
6
|
args[_i] = arguments[_i];
|
|
11
7
|
}
|
|
12
|
-
if (
|
|
8
|
+
if (debug) {
|
|
13
9
|
console.log.apply(console, args);
|
|
14
10
|
}
|
|
15
11
|
},
|
package/esm/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,IAAM,KAAK,GAAG,KAAK,CAAC;AAEpB,MAAM,CAAC,IAAM,MAAM,GAAG;IAClB,QAAQ;QAAC,cAAO;aAAP,UAAO,EAAP,qBAAO,EAAP,IAAO;YAAP,yBAAO;;QACZ,IAAI,KAAK,EAAE,CAAC;YACR,OAAO,CAAC,GAAG,OAAX,OAAO,EAAQ,IAAI,EAAE;QACzB,CAAC;IACL,CAAC;IAED,GAAG;QAAC,cAAO;aAAP,UAAO,EAAP,qBAAO,EAAP,IAAO;YAAP,yBAAO;;QACP,OAAO,CAAC,GAAG,OAAX,OAAO,EAAQ,IAAI,EAAE;IACzB,CAAC;CACJ,CAAA"}
|
package/package.json
CHANGED
package/src/constants.ts
CHANGED
|
@@ -2,6 +2,5 @@ export const insightsFlushTopic = 'insights.flush';
|
|
|
2
2
|
export const featureFlagEvaluatedTopic = 'featureflag.evaluated.topic';
|
|
3
3
|
export const featureFlagEvaluatedBufferTopic = 'featureflag.evaluated.buffer.topic';
|
|
4
4
|
export const websocketReconnectTopic = 'network.websocket.reconnect';
|
|
5
|
-
export const debugModeQueryStr = 'debugmode'; // will print debug logs if true
|
|
6
5
|
export const insightsTopic = 'insights.topic';
|
|
7
6
|
export const currentUserStorageKey = 'fb-user';
|
package/src/logger.ts
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// get debug mode from query string
|
|
4
|
-
const queryString = window.location.search;
|
|
5
|
-
const urlParams = new URLSearchParams(queryString);
|
|
6
|
-
const debugModeParam = urlParams.get(debugModeQueryStr);
|
|
1
|
+
const debug = false;
|
|
7
2
|
|
|
8
3
|
export const logger = {
|
|
9
4
|
logDebug(...args) {
|
|
10
|
-
if (
|
|
5
|
+
if (debug) {
|
|
11
6
|
console.log(...args);
|
|
12
7
|
}
|
|
13
8
|
},
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
!function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var n=e();for(var r in n)("object"==typeof exports?exports:t)[r]=n[r]}}(this,(()=>(()=>{"use strict";var t={d:(e,n)=>{for(var r in n)t.o(n,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{fbClient:()=>q});var n,r,i,o,a=new(function(){function t(t){this.events=t||{}}return t.prototype.subscribe=function(t,e){var n=this;return(this.events[t]||(this.events[t]=[])).push(e),{unsubscribe:function(){return n.events[t]&&n.events[t].splice(n.events[t].indexOf(e)>>>0,1)}}},t.prototype.unsubscribe=function(t,e){this.events[t]&&this.events[t].splice(this.events[t].indexOf(e)>>>0,1)},t.prototype.emit=function(t){for(var e=[],n=1;n<arguments.length;n++)e[n-1]=arguments[n];(this.events[t]||[]).forEach((function(t){return t.apply(void 0,e)}))},t}()),u={logDebug:function(){for(var t=[],e=0;e<arguments.length;e++)t[e]=arguments[e]},log:function(){for(var t=[],e=0;e<arguments.length;e++)t[e]=arguments[e];console.log.apply(console,t)}},s="insights.flush",c="featureflag.evaluated.topic",l="featureflag.evaluated.buffer.topic",f="network.websocket.reconnect",p="fb-user";!function(t){t[t.featureFlagUsage=1]="featureFlagUsage",t[t.customEvent=2]="customEvent",t[t.pageView=3]="pageView",t[t.click=4]="click"}(n||(n={})),function(t){t.string="string",t.boolean="boolean",t.number="number",t.json="json"}(r||(r={})),function(t){t.full="full",t.patch="patch"}(i||(i={})),function(t){t.update="update"}(o||(o={}));const d=function(){function t(){}return t.partialEndpoint=function(t){return"You have set custom uris without specifying the ".concat(t," URI; connections may not work properly")},t.invalidParam=function(t){return"The ".concat(t," option is not passed in or its value is invalid")},t.mandatory=function(t){return"".concat(t," is mandatory")},t}();function h(t){var e;if(!t)return"";var n="".concat(t.keyId,",").concat(t.name),r=null===(e=t.customizedProperties)||void 0===e?void 0:e.map((function(t){return"".concat(t.name,":").concat(t.value)})).join(",");return"".concat(n,",").concat(r)}function v(t,e){switch(t){case r.string:return e;case r.boolean:return"true"===e||"false"!==e&&(u.log("expected boolean value, but got ".concat(e)),e);case r.number:return"string"!=typeof(n=e)||isNaN(n)||isNaN(parseFloat(n))?(u.log("expected numeric value, but got ".concat(e)),e):+e;case r.json:try{return JSON.parse(e)}catch(t){return u.log("expected json value, but got ".concat(e)),e}default:return u.log("unexpected variation type ".concat(t," for ").concat(e)),e}var n}function g(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(t){var e=16*Math.random()|0;return("x"==t?e:3&e|8).toString(16)}))}function y(t){if(!t)return d.mandatory("user");var e=t.keyId,n=t.name;return null==e||""===e.trim()?d.mandatory("user.keyId"):null==n||""===n.trim()?d.mandatory("user.name"):null}function m(t){return null==t||""===t.trim()}var b={0:"Q",1:"B",2:"W",3:"S",4:"P",5:"H",6:"D",7:"X",8:"Z",9:"U"};function w(t,e){var n="000000000000"+t;return n.slice(n.length-e).split("").map((function(t){return b[t]})).join("")}var x="fb-datastore",_=function(){function t(){this._userId=null,this._store={featureFlags:{}}}return Object.defineProperty(t.prototype,"userId",{set:function(t){this._userId=t,this._loadFromStorage()},enumerable:!1,configurable:!0}),t.prototype.getFeatureFlag=function(t){return this._store.featureFlags[t]},t.prototype.getVariation=function(t){var e=this._store.featureFlags[t];if(e)return a.emit(c,{insightType:n.featureFlagUsage,id:e.id,timestamp:Date.now(),sendToExperiment:e.sendToExperiment,variation:e.variationOptions.find((function(t){return t.value===e.variation}))}),v(e.variationType,e.variation)},t.prototype.setFullData=function(t){this._store={featureFlags:{}},this._dumpToStorage(this._store),this.updateBulkFromRemote(t)},t.prototype.getFeatureFlags=function(){return this._store.featureFlags},t.prototype.updateStorageBulk=function(t,e,n){var r=localStorage.getItem(e),i=null;try{r&&r.trim().length>0&&(i=JSON.parse(r))}catch(t){u.logDebug("error while loading local data store: ".concat(e)+t)}if(i){var o=t.featureFlags;Object.keys(o).forEach((function(t){var e=o[t];(!i.featureFlags[t]||!n)&&(i.featureFlags[e.id]=Object.assign({},e))})),this._dumpToStorage(i,e)}},t.prototype.updateBulkFromRemote=function(t){var e="".concat(x,"-").concat(this._userId);this.updateStorageBulk(t,e,!1),this._loadFromStorage()},t.prototype._emitUpdateEvents=function(t){t.length>0&&(t.forEach((function(t){t.id;var e=t.operation,n=t.data;return a.emit("ff_".concat(e,":").concat(n.id),n)})),a.emit("ff_".concat(o.update),t.map((function(t){return t.data}))))},t.prototype._dumpToStorage=function(t,e){if(t){var n=e||"".concat(x,"-").concat(this._userId);localStorage.setItem(n,JSON.stringify(t))}else{var r="".concat(x,"-").concat(this._userId);localStorage.setItem(r,JSON.stringify(this._store))}},t.prototype._loadFromStorage=function(){var t=this;try{var e="".concat(x,"-").concat(this._userId),n=localStorage.getItem(e);if(n&&n.trim().length>0){var r=JSON.parse(n),i=Object.keys(r.featureFlags).filter((function(e){var n=r.featureFlags[e],i=t._store.featureFlags[e];return!i||n.variation!==i.variation||n.variationType!==i.variationType})).map((function(e){var n=r.featureFlags[e],i=t._store.featureFlags[e];return{id:e,operation:o.update,sendToExperiment:n.sendToExperiment,data:{id:e,oldValue:i?v(i.variationType,i.variation):void 0,newValue:v(n.variationType,n.variation)}}}));this._store=r,this._emitUpdateEvents(i)}else this._store={featureFlags:{}}}catch(t){u.logDebug("error while loading local data store: "+t)}},t}();const k=new _;var T=function(){return T=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var i in e=arguments[n])Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},T.apply(this,arguments)},S={},F=[];const E=new(function(){function t(){this._key=g()}return t.prototype.setKey=function(t){this._key=t||this._key},t.prototype.throttle=function(t,e){var n=0;return function(){for(var r=[],i=0;i<arguments.length;i++)r[i]=arguments[i];clearTimeout(n),n=setTimeout(t.bind.apply(t,function(t,e,n){if(n||2===arguments.length)for(var r,i=0,o=e.length;i<o;i++)!r&&i in e||(r||(r=Array.prototype.slice.call(e,0,i)),r[i]=e[i]);return t.concat(r||Array.prototype.slice.call(e))}([null],r,!1)),e||0)}},t.prototype.throttleAsync=function(t){var e=this,n=!1;return function(){for(var r=[],i=0;i<arguments.length;i++)r[i]=arguments[i];return o=this,a=void 0,s=function(){var i,o,a,u;return function(t,e){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function u(u){return function(s){return function(u){if(n)throw new TypeError("Generator is already executing.");for(;o&&(o=0,u[0]&&(a=0)),a;)try{if(n=1,r&&(i=2&u[0]?r.return:u[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,u[1])).done)return i;switch(r=0,i&&(u=[2&u[0],i.value]),u[0]){case 0:case 1:i=u;break;case 4:return a.label++,{value:u[1],done:!1};case 5:a.label++,r=u[1],u=[0];continue;case 7:u=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==u[0]&&2!==u[0])){a=0;continue}if(3===u[0]&&(!i||u[1]>i[0]&&u[1]<i[3])){a.label=u[1];break}if(6===u[0]&&a.label<i[1]){a.label=i[1],i=u;break}if(i&&a.label<i[2]){a.label=i[2],a.ops.push(u);break}i[2]&&a.ops.pop(),a.trys.pop();continue}u=e.call(t,a)}catch(t){u=[6,t],r=0}finally{n=i=0}if(5&u[0])throw u[1];return{value:u[0]?u[1]:void 0,done:!0}}([u,s])}}}(this,(function(s){switch(s.label){case 0:return i=function(t){var n=t.map((function(t){return"object"==typeof t&&"function"!=typeof t&&null!==t?Array.isArray(t)?t.map((function(t){return T(T({},t),{timestamp:null})})):T(T({},t),{timestamp:null}):t}));return e._key+JSON.stringify(n)}(r),o=F.findIndex((function(t){return t===i})),n&&-1!==o?[3,2]:(n=!0,-1===o&&F.push(i),a=S,u=i,[4,t.apply(null,r)]);case 1:a[u]=s.sent(),setTimeout((function(){n=!1}),0),s.label=2;case 2:return[2,S[i]]}}))},new((u=void 0)||(u=Promise))((function(t,e){function n(t){try{i(s.next(t))}catch(t){e(t)}}function r(t){try{i(s.throw(t))}catch(t){e(t)}}function i(e){var i;e.done?t(e.value):(i=e.value,i instanceof u?i:new u((function(t){t(i)}))).then(n,r)}i((s=s.apply(o,a||[])).next())}));var o,a,u,s}},t}());var O=function(){return O=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var i in e=arguments[n])Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},O.apply(this,arguments)},D=function(t,e,n,r){return new(n||(n=Promise))((function(i,o){function a(t){try{s(r.next(t))}catch(t){o(t)}}function u(t){try{s(r.throw(t))}catch(t){o(t)}}function s(t){var e;t.done?i(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(a,u)}s((r=r.apply(t,e||[])).next())}))},I=function(t,e){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function u(u){return function(s){return function(u){if(n)throw new TypeError("Generator is already executing.");for(;o&&(o=0,u[0]&&(a=0)),a;)try{if(n=1,r&&(i=2&u[0]?r.return:u[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,u[1])).done)return i;switch(r=0,i&&(u=[2&u[0],i.value]),u[0]){case 0:case 1:i=u;break;case 4:return a.label++,{value:u[1],done:!1};case 5:a.label++,r=u[1],u=[0];continue;case 7:u=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==u[0]&&2!==u[0])){a=0;continue}if(3===u[0]&&(!i||u[1]>i[0]&&u[1]<i[3])){a.label=u[1];break}if(6===u[0]&&a.label<i[1]){a.label=i[1],i=u;break}if(i&&a.label<i[2]){a.label=i[2],a.ops.push(u);break}i[2]&&a.ops.pop(),a.trys.pop();continue}u=e.call(t,a)}catch(t){u=[6,t],r=0}finally{n=i=0}if(5&u[0])throw u[1];return{value:u[0]?u[1]:void 0,done:!0}}([u,s])}}},j=[250,500,1e3,2e3,4e3,8e3],P=new(function(){function t(){var t=this;this.retryCounter=0,this.sendInsights=E.throttleAsync((function(e){return D(t,void 0,void 0,(function(){var t,r,i=this;return I(this,(function(o){switch(o.label){case 0:if(!this.secret||!this.user||!e||0===e.length)return[2];o.label=1;case 1:return o.trys.push([1,3,,4]),t=[{user:this.__getUserInfo(),variations:e.filter((function(t){return t.insightType===n.featureFlagUsage})).map((function(t){return{featureFlagKey:t.id,sendToExperiment:t.sendToExperiment,timestamp:t.timestamp,variation:{id:t.variation.id,value:t.variation.value}}})),metrics:e.filter((function(t){return t.insightType!==n.featureFlagUsage})).map((function(t){return{route:location.pathname,timestamp:t.timestamp,numericValue:null===t.numericValue||void 0===t.numericValue?1:t.numericValue,appType:i.appType,eventName:t.eventName,type:t.type}}))}],[4,U("".concat(this.eventsUri,"/api/public/insight/track"),t,{Authorization:this.secret})];case 2:return o.sent(),[3,4];case 3:return r=o.sent(),u.logDebug(r),[3,4];case 4:return[2]}}))}))}))}return t.prototype.init=function(t,e,n,r){this.streamingUri=t,this.eventsUri=e,this.secret=n,this.appType=r},t.prototype.identify=function(t,e){var n;this.user=O({},t),E.setKey(null===(n=this.user)||void 0===n?void 0:n.keyId),e&&this.socket&&this.sendUserIdentifyMessage(0)},t.prototype.sendUserIdentifyMessage=function(t){var e,n,r=this.user,i={messageType:"data-sync",data:{user:{name:r.name,keyId:r.keyId,customizedProperties:r.customizedProperties},timestamp:t}};try{(null===(e=this.socket)||void 0===e?void 0:e.readyState)===WebSocket.OPEN?(u.logDebug("sending user identify message"),null===(n=this.socket)||void 0===n||n.send(JSON.stringify(i))):u.logDebug("didn't send user identify message because socket not open")}catch(t){u.logDebug(t)}},t.prototype.reconnect=function(){this.socket=null;var t=j[Math.min(this.retryCounter++,j.length-1)];setTimeout((function(){u.logDebug("emit reconnect event"),a.emit(f,{})}),t),u.logDebug(t)},t.prototype.sendPingMessage=function(){var t=this,e={messageType:"ping",data:null};setTimeout((function(){var n;try{(null===(n=t.socket)||void 0===n?void 0:n.readyState)===WebSocket.OPEN?(u.logDebug("sending ping"),t.socket.send(JSON.stringify(e)),t.sendPingMessage()):(u.logDebug("socket closed at ".concat(new Date)),t.reconnect())}catch(t){u.logDebug(t)}}),18e3)},t.prototype.createConnection=function(t,e){var n=this;if(n.socket)e({});else{var r=Date.now(),i="".concat(this.streamingUri,"/streaming?type=client&token=").concat(function(t){t=t.replace(/=*$/,"");var e=Date.now(),n=w(e,e.toString().length),r=Math.max(Math.floor(Math.random()*t.length),2);return"".concat(w(r,3)).concat(w(n.length,2)).concat(t.slice(0,r)).concat(n).concat(t.slice(r))}(this.secret));n.socket=new WebSocket(i),n.socket.addEventListener("open",(function(e){n.retryCounter=0,u.logDebug("Connection time: ".concat(Date.now()-r," ms")),n.sendUserIdentifyMessage(t),n.sendPingMessage()})),n.socket.addEventListener("close",(function(t){u.logDebug("close"),4003!==t.code&&n.reconnect()})),n.socket.addEventListener("error",(function(t){u.logDebug("error")})),n.socket.addEventListener("message",(function(t){var n=JSON.parse(t.data);"data-sync"===n.messageType&&(e(n.data),n.data.featureFlags.length>0&&u.logDebug("socket push update time(ms): ",Date.now()-n.data.featureFlags[0].timestamp))}))}},t.prototype.__getUserInfo=function(){var t=this.user;return{name:t.name,keyId:t.keyId,customizedProperties:t.customizedProperties}},t}());function U(t,e,n){return void 0===t&&(t=""),void 0===e&&(e={}),void 0===n&&(n={}),D(this,void 0,void 0,(function(){var r,i;return I(this,(function(o){switch(o.label){case 0:return o.trys.push([0,2,,3]),[4,fetch(t,{method:"POST",headers:Object.assign({"Content-Type":"application/json"},n),body:JSON.stringify(e)})];case 1:return[2,200===(r=o.sent()).status?r.json():{}];case 2:return i=o.sent(),u.logDebug(i),[2,{}];case 3:return[2]}}))}))}var N=function(){function t(t,e){void 0===t&&(t=0),void 0===e&&(e=""),this.flushLimit=t,this.arriveflushLimitTopic=e,this.queue=[]}return t.prototype.add=function(t){this.queue.push(t),this.flushLimit>0&&this.queue.length>=this.flushLimit&&a.emit(this.arriveflushLimitTopic,{})},t.prototype.flush=function(){var t=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,o=e.length;i<o;i++)!r&&i in e||(r||(r=Array.prototype.slice.call(e,0,i)),r[i]=e[i]);return t.concat(r||Array.prototype.slice.call(e))}([],this.queue,!0);return this.queue=[],t},t}(),M=function(){return M=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var i in e=arguments[n])Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},M.apply(this,arguments)},V=function(t,e,n,r){return new(n||(n=Promise))((function(i,o){function a(t){try{s(r.next(t))}catch(t){o(t)}}function u(t){try{s(r.throw(t))}catch(t){o(t)}}function s(t){var e;t.done?i(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(a,u)}s((r=r.apply(t,e||[])).next())}))},A=function(t,e){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function u(u){return function(s){return function(u){if(n)throw new TypeError("Generator is already executing.");for(;o&&(o=0,u[0]&&(a=0)),a;)try{if(n=1,r&&(i=2&u[0]?r.return:u[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,u[1])).done)return i;switch(r=0,i&&(u=[2&u[0],i.value]),u[0]){case 0:case 1:i=u;break;case 4:return a.label++,{value:u[1],done:!1};case 5:a.label++,r=u[1],u=[0];continue;case 7:u=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==u[0]&&2!==u[0])){a=0;continue}if(3===u[0]&&(!i||u[1]>i[0]&&u[1]<i[3])){a.label=u[1];break}if(6===u[0]&&a.label<i[1]){a.label=i[1],i=u;break}if(i&&a.label<i[2]){a.label=i[2],a.ops.push(u);break}i[2]&&a.ops.pop(),a.trys.pop();continue}u=e.call(t,a)}catch(t){u=[6,t],r=0}finally{n=i=0}if(5&u[0])throw u[1];return{value:u[0]?u[1]:void 0,done:!0}}([u,s])}}},C=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,o=e.length;i<o;i++)!r&&i in e||(r||(r=Array.prototype.slice.call(e,0,i)),r[i]=e[i]);return t.concat(r||Array.prototype.slice.call(e))};function L(){var t=function(){var t=localStorage.getItem("fb-guid");if(t)return t;var e=g();return localStorage.setItem("fb-guid",e),e}();return{name:t,keyId:t}}function z(t){return Object.keys(t).map((function(e){var n=t[e],i=n.id,o=n.variation,a=t[e].variationType||r.string;return{id:i,variation:v(a,o),variationType:a}}))}var J=function(){function t(){var t=this;this._readyEventEmitted=!1,this._insightsQueue=new N(1,s),this._featureFlagEvaluationBuffer=new N,this._option={secret:"",api:"",streamingUri:"",eventsUri:"",enableDataSync:!0,appType:"javascript"},this._readyPromise=new Promise((function(e,r){t.on("ready",(function(){var r=k.getFeatureFlags();if(e(z(r)),t._option.enableDataSync){var i=t._featureFlagEvaluationBuffer.flush().map((function(t){var e=r[t.id];if(!e)return u.log("Called unexisting feature flag: ".concat(t.id)),null;var i=e.variationOptions.find((function(e){return e.value===t.variationValue}));return i?u.logDebug("Sent buffered insight for feature flag: ".concat(t.id," with variation: ").concat(i.value)):u.log("Sent buffered insight for feature flag: ".concat(t.id," with unexisting default variation: ").concat(t.variationValue)),{insightType:n.featureFlagUsage,id:e.id,timestamp:t.timestamp,sendToExperiment:e.sendToExperiment,variation:i||{id:-1,value:t.variationValue}}}));P.sendInsights(i.filter((function(t){return!!t})))}}))})),a.subscribe(f,(function(){return V(t,void 0,void 0,(function(){var t;return A(this,(function(e){switch(e.label){case 0:return e.trys.push([0,2,,3]),u.logDebug("reconnecting"),[4,this.dataSync()];case 1:return e.sent(),this._readyEventEmitted||(this._readyEventEmitted=!0,a.emit("ready",z(k.getFeatureFlags()))),[3,3];case 2:return t=e.sent(),u.log("data sync error",t),[3,3];case 3:return[2]}}))}))})),a.subscribe(l,(function(e){t._featureFlagEvaluationBuffer.add(e)})),a.subscribe(s,(function(){t._option.enableDataSync&&P.sendInsights(t._insightsQueue.flush())})),a.subscribe(c,(function(e){t._insightsQueue.add(e)})),a.subscribe("insights.topic",(function(e){t._insightsQueue.add(e)}))}return t.prototype.on=function(t,e){a.subscribe(t,e)},t.prototype.off=function(t,e){a.unsubscribe(t,e)},t.prototype.waitUntilReady=function(){return this._readyPromise},t.prototype.init=function(t){var e;return V(this,void 0,void 0,(function(){var n;return A(this,(function(r){switch(r.label){case 0:return n=function(t){if(null==t)return d.mandatory("option");var e=t.streamingUri,n=t.eventsUri,r=t.secret,i=t.anonymous,o=t.user,a=t.enableDataSync,u=m(e),s=m(n);if(a&&(u||s)){if(s)return d.partialEndpoint("eventsUri");if(u)return d.partialEndpoint("streamingUri")}return a&&m(r)?d.invalidParam("secret"):0!=!!i||o?o?y(o):null:d.mandatory("user")}(M(M({},this._option),t)),null!==n?(u.log(n),[2]):(this._option=M(M(M({},this._option),t),{api:null===(e=t.api||this._option.api)||void 0===e?void 0:e.replace(/\/$/,"")}),this._option.enableDataSync&&P.init(this._option.streamingUri,this._option.eventsUri,this._option.secret,this._option.appType),[4,this.identify(t.user||L())]);case 1:return r.sent(),[2]}}))}))},t.prototype.identify=function(t){var e;return V(this,void 0,void 0,(function(){var n,r;return A(this,(function(i){switch(i.label){case 0:return null!==(n=y(t))?(u.log(n),[2]):(t.customizedProperties=null===(e=t.customizedProperties)||void 0===e?void 0:e.map((function(t){return{name:t.name,value:"".concat(t.value)}})),r=h(t)!==localStorage.getItem(p),this._option.user=Object.assign({},t),localStorage.setItem(p,h(this._option.user)),k.userId=this._option.user.keyId,P.identify(this._option.user,r),[4,this.bootstrap(this._option.bootstrap,r)]);case 1:return i.sent(),[2]}}))}))},t.prototype.logout=function(){return V(this,void 0,void 0,(function(){var t;return A(this,(function(e){switch(e.label){case 0:return t=L(),[4,this.identify(t)];case 1:return e.sent(),[2,t]}}))}))},t.prototype.bootstrap=function(t,e){return V(this,void 0,void 0,(function(){var n,i;return A(this,(function(o){switch(o.label){case 0:if((t=t||this._option.bootstrap)&&t.length>0&&(n={featureFlags:t.reduce((function(t,e){var n=e.id,i=e.variation,o=e.timestamp,a=e.variationOptions,u=e.sendToExperiment,s=e.variationType;return t[n]={id:n,variation:i,timestamp:o,variationOptions:a||[{id:1,value:i}],sendToExperiment:u,variationType:s||r.string},t}),{})},k.setFullData(n),u.logDebug("bootstrapped with full data")),!this._option.enableDataSync)return[3,4];o.label=1;case 1:return o.trys.push([1,3,,4]),[4,this.dataSync(e)];case 2:return o.sent(),[3,4];case 3:return i=o.sent(),u.log("data sync error",i),[3,4];case 4:return this._readyEventEmitted||(this._readyEventEmitted=!0,a.emit("ready",z(k.getFeatureFlags()))),[2]}}))}))},t.prototype.dataSync=function(t){return V(this,void 0,void 0,(function(){var e=this;return A(this,(function(n){return[2,new Promise((function(n,o){var a=t?0:Math.max.apply(Math,C(C([],Object.values(k.getFeatureFlags()).map((function(t){return t.timestamp})),!1),[0],!1));P.createConnection(a,(function(t){var o;if(t&&t.userKeyId===(null===(o=e._option.user)||void 0===o?void 0:o.keyId)){var a=t.featureFlags;switch(t.eventType){case i.full:case i.patch:var s={featureFlags:a.reduce((function(t,e){var n=e.id,i=e.variation,o=e.timestamp,a=e.variationOptions,u=e.sendToExperiment,s=e.variationType;return t[n]={id:n,variation:i,timestamp:o,variationOptions:a,sendToExperiment:u,variationType:s||r.string},t}),{})};t.eventType===i.full?(k.setFullData(s),u.logDebug("synchonized with full data")):(k.updateBulkFromRemote(s),u.logDebug("synchonized with partial data"));break;default:u.logDebug("invalid stream event type: "+t.eventType)}}n()}))}))]}))}))},t.prototype.variation=function(t,e){var n=B(t,e);return void 0===n?e:n},t.prototype.boolVariation=function(t,e){var n=B(t,e);return void 0===n?e:"true"===(null==n?void 0:n.toLocaleLowerCase())},t.prototype.getUser=function(){return M({},this._option.user)},t.prototype.sendCustomEvent=function(t){var e=this;(t||[]).forEach((function(t){return e._insightsQueue.add(M({insightType:n.customEvent,timestamp:Date.now(),type:"CustomEvent"},t))}))},t.prototype.sendFeatureFlagInsight=function(t,e){this.variation(t,e)},t.prototype.getAllFeatureFlags=function(){var t=k.getFeatureFlags();return Object.values(t).reduce((function(t,e){return t[e.id]=v(e.variationType,e.variation),t}),{})},t}(),B=function(t,e){var n=k.getVariation(t);return void 0===n&&a.emit(l,{id:t,timestamp:Date.now(),variationValue:"".concat(e)}),n};const q=new J;var Q=document.querySelector("html");return Q&&(Q.style.visibility="hidden",setTimeout((function(){return Q.style.visibility="visible"}),500)),u.logDebug("version: 2.0.2"),e})()));
|
|
2
|
+
//# sourceMappingURL=featbit-js-client-sdk-2.0.2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"featbit-js-client-sdk-2.0.2.js","mappings":"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","sources":["webpack://@featbit/js-client-sdk/webpack/universalModuleDefinition","webpack://@featbit/js-client-sdk/webpack/bootstrap","webpack://@featbit/js-client-sdk/webpack/runtime/define property getters","webpack://@featbit/js-client-sdk/webpack/runtime/hasOwnProperty shorthand","webpack://@featbit/js-client-sdk/webpack/runtime/make namespace object","webpack://@featbit/js-client-sdk/./src/events.ts","webpack://@featbit/js-client-sdk/./src/types.ts","webpack://@featbit/js-client-sdk/./src/logger.ts","webpack://@featbit/js-client-sdk/./src/constants.ts","webpack://@featbit/js-client-sdk/./src/optionMessages.ts","webpack://@featbit/js-client-sdk/./src/utils.ts","webpack://@featbit/js-client-sdk/./src/store.ts","webpack://@featbit/js-client-sdk/./src/throttleutil.ts","webpack://@featbit/js-client-sdk/./src/network.service.ts","webpack://@featbit/js-client-sdk/./src/queue.ts","webpack://@featbit/js-client-sdk/./src/featbit.ts","webpack://@featbit/js-client-sdk/./src/umd.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse {\n\t\tvar a = factory();\n\t\tfor(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n\t}\n})(this, () => {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","interface Events {\n [key: string]: Function[];\n}\n\nclass EventEmitter {\n public events: Events;\n constructor(events?: Events) {\n this.events = events || {};\n }\n\n public subscribe(name: string, cb: Function) {\n (this.events[name] || (this.events[name] = [])).push(cb);\n\n return {\n unsubscribe: () =>\n this.events[name] && this.events[name].splice(this.events[name].indexOf(cb) >>> 0, 1)\n };\n }\n\n public unsubscribe(name: string, cb: Function) {\n this.events[name] && this.events[name].splice(this.events[name].indexOf(cb) >>> 0, 1);\n }\n\n public emit(name: string, ...args: any[]): void {\n (this.events[name] || []).forEach(fn => fn(...args));\n }\n}\n\nexport const eventHub = new EventEmitter();","export type FeatureFlagValue = any;\n\nexport interface IFeatureFlagSet {\n [key: string]: FeatureFlagValue;\n}\n\nexport interface IFeatureFlagChange {\n id: string,\n oldValue: FeatureFlagValue,\n newValue: FeatureFlagValue\n}\n\nexport interface IOption {\n secret: string,\n anonymous?: boolean,\n bootstrap?: IFeatureFlag[],\n streamingUri?: string,\n eventsUri?: string,\n\n // deprecated, this option will be removed in the future, please use streamingUri and eventsUri instead\n api?: string,\n\n appType?: string,\n user?: IUser,\n enableDataSync?: boolean\n}\n\nexport interface IUser {\n name: string,\n keyId: string,\n customizedProperties?: ICustomizedProperty[]\n}\n\nexport interface ICustomizedProperty {\n name: string,\n value: string | number | boolean\n}\n\nexport interface IVariationOption {\n id: number,\n value: FeatureFlagValue\n}\n\nexport interface IFeatureFlagVariation {\n id?: string,\n sendToExperiment?: boolean\n timestamp?: number,\n variation?: {\n id: number,\n value: FeatureFlagValue,\n }\n}\n\nexport interface IFeatureFlagVariationBuffer {\n id: string,\n timestamp: number,\n variationValue: FeatureFlagValue\n}\n\nexport enum InsightType {\n featureFlagUsage = 1,\n customEvent = 2,\n pageView = 3,\n click = 4\n}\n\nexport enum VariationDataType {\n string = 'string',\n boolean = 'boolean',\n number = 'number',\n json = 'json',\n}\n\nexport interface IInsight extends IFeatureFlagVariation, ICustomEvent {\n insightType: InsightType\n}\n\nexport interface IFeatureFlagBase {\n id: string, // the keyname\n variation: FeatureFlagValue,\n variationType: VariationDataType\n}\n\nexport interface IFeatureFlag extends IFeatureFlagBase{\n sendToExperiment: boolean,\n timestamp: number,\n variationOptions: IVariationOption[]\n}\n\nexport interface IDataStore {\n featureFlags: { [key: string]: IFeatureFlag }\n}\n\nexport enum StreamResponseEventType {\n full = 'full',\n patch = 'patch'\n}\n\nexport enum FeatureFlagUpdateOperation {\n update = 'update'\n}\n\nexport interface IStreamResponse {\n eventType: StreamResponseEventType,\n userKeyId: string,\n featureFlags: IFeatureFlag[]\n}\n\nexport interface ICustomEvent {\n type?: string,\n eventName: string,\n numericValue?: number\n}","const debug = false;\n\nexport const logger = {\n logDebug(...args) {\n if (debug) {\n console.log(...args);\n }\n },\n\n log(...args) {\n console.log(...args);\n }\n}","export const insightsFlushTopic = 'insights.flush';\nexport const featureFlagEvaluatedTopic = 'featureflag.evaluated.topic';\nexport const featureFlagEvaluatedBufferTopic = 'featureflag.evaluated.buffer.topic';\nexport const websocketReconnectTopic = 'network.websocket.reconnect';\nexport const insightsTopic = 'insights.topic';\nexport const currentUserStorageKey = 'fb-user';\n","export default class OptionMessages {\n static partialEndpoint(name: string): string {\n return `You have set custom uris without specifying the ${ name } URI; connections may not work properly`;\n }\n\n static invalidParam(name: string): string {\n return `The ${ name } option is not passed in or its value is invalid`;\n }\n\n static mandatory(name: string): string {\n return `${ name } is mandatory`;\n }\n}","import {FeatureFlagValue, IOption, IUser, VariationDataType} from \"./types\";\nimport {logger} from \"./logger\";\nimport OptionMessages from \"./optionMessages\";\n\n\n// generate default user info\nexport function generateorGetGuid(): string {\n let guid = localStorage.getItem(\"fb-guid\");\n if (guid) {\n return guid;\n }\n else {\n const id = uuid();\n localStorage.setItem(\"fb-guid\", id);\n return id;\n }\n}\n\nexport function serializeUser(user: IUser | undefined): string {\n if (!user) {\n return '';\n }\n\n const builtInProperties = `${user.keyId},${user.name}`;\n\n const customizedProperties = user.customizedProperties?.map(p => `${p.name}:${p.value}`).join(',');\n\n return `${builtInProperties},${customizedProperties}`;\n}\n\nexport function isNumeric(str: string) {\n if (typeof str != \"string\") return false // we only process strings!\n // @ts-ignore\n return !isNaN(str) && // use type coercion to parse the _entirety_ of the string (`parseFloat` alone does not do this)...\n !isNaN(parseFloat(str)) // ...and ensure strings of whitespace fail\n}\n\nexport function parseVariation(type: VariationDataType, value: string): FeatureFlagValue {\n switch (type) {\n case VariationDataType.string:\n return value;\n case VariationDataType.boolean:\n if (value === 'true') {\n return true;\n }\n\n if (value === 'false') {\n return false;\n }\n\n logger.log(`expected boolean value, but got ${value}`);\n return value;\n case VariationDataType.number:\n if (isNumeric(value)) {\n return +value;\n }\n\n logger.log(`expected numeric value, but got ${value}`);\n return value;\n case VariationDataType.json:\n try {\n return JSON.parse(value);\n }\n catch (e) {\n logger.log(`expected json value, but got ${value}`);\n return value;\n }\n default:\n logger.log(`unexpected variation type ${type} for ${value}`);\n return value;\n }\n}\n\nexport function uuid(): string {\n let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\n var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n\n return uuid;\n}\n\nexport function validateUser(user: IUser): string | null {\n if (!user) {\n return OptionMessages.mandatory('user')\n }\n\n const { keyId, name } = user;\n\n if (keyId === undefined || keyId === null || keyId.trim() === '') {\n return OptionMessages.mandatory('user.keyId');\n }\n\n if (name === undefined || name === null || name.trim() === '') {\n return OptionMessages.mandatory('user.name');\n }\n\n return null;\n}\n\nexport function isNullOrUndefinedOrWhiteSpace(value?: string): boolean {\n return value === null || value === undefined || value.trim() === '';\n}\n\nexport function validateOption(option: IOption): string | null {\n if (option === undefined || option === null) {\n return OptionMessages.mandatory('option')\n }\n\n const { streamingUri, eventsUri, secret, anonymous, user, enableDataSync } = option;\n\n const streamingUriMissing = isNullOrUndefinedOrWhiteSpace(streamingUri);\n const eventsUriMissing = isNullOrUndefinedOrWhiteSpace(eventsUri);\n\n if (enableDataSync && (streamingUriMissing || eventsUriMissing))\n {\n if (eventsUriMissing) {\n return OptionMessages.partialEndpoint('eventsUri');\n }\n\n if (streamingUriMissing) {\n return OptionMessages.partialEndpoint('streamingUri');\n }\n }\n\n if (enableDataSync && isNullOrUndefinedOrWhiteSpace(secret)) {\n return OptionMessages.invalidParam('secret');\n }\n\n // validate user\n if (!!anonymous === false && !user) {\n return OptionMessages.mandatory('user');\n }\n\n if (user) {\n return validateUser(user);\n }\n\n return null;\n}\n\n/********************** encode text begin *****************************/\nconst alphabet = {\n \"0\": \"Q\",\n \"1\": \"B\",\n \"2\": \"W\",\n \"3\": \"S\",\n \"4\": \"P\",\n \"5\": \"H\",\n \"6\": \"D\",\n \"7\": \"X\",\n \"8\": \"Z\",\n \"9\": \"U\",\n}\n\nfunction encodeNumber(param: number, length: number): string {\n var s = \"000000000000\" + param;\n const numberWithLeadingZeros = s.slice(s.length - length);\n return numberWithLeadingZeros.split('').map(n => alphabet[n]).join('');\n}\n\n// generate connection token\nexport function generateConnectionToken(text: string): string {\n text = text.replace(/=*$/, '');\n const timestamp = Date.now();\n const timestampCode = encodeNumber(timestamp, timestamp.toString().length);\n // get random number less than the length of the text as the start point, and it must be greater or equal to 2\n const start = Math.max(Math.floor(Math.random() * text.length), 2);\n\n return `${encodeNumber(start, 3)}${encodeNumber(timestampCode.length, 2)}${text.slice(0, start)}${timestampCode}${text.slice(start)}`;\n}\n\n/********************** encode text end *****************************/\n","import {featureFlagEvaluatedTopic} from \"./constants\";\nimport {eventHub} from \"./events\";\nimport {logger} from \"./logger\";\nimport {\n FeatureFlagUpdateOperation, FeatureFlagValue,\n IDataStore,\n IFeatureFlag,\n IFeatureFlagChange,\n InsightType\n} from \"./types\";\nimport {parseVariation} from \"./utils\";\n\nconst DataStoreStorageKey = 'fb-datastore';\n\nclass Store {\n private _userId: string | null = null;\n\n private _store: IDataStore = {\n featureFlags: {} as { [key: string]: IFeatureFlag }\n }\n\n constructor() { }\n\n set userId(id: string) {\n this._userId = id;\n this._loadFromStorage();\n }\n\n getFeatureFlag(key: string): IFeatureFlag {\n return this._store.featureFlags[key];\n }\n\n getVariation(key: string): FeatureFlagValue {\n const featureFlag = this._store.featureFlags[key];\n\n if (!featureFlag) {\n return undefined;\n }\n\n eventHub.emit(featureFlagEvaluatedTopic, {\n insightType: InsightType.featureFlagUsage,\n id: featureFlag.id,\n timestamp: Date.now(),\n sendToExperiment: featureFlag.sendToExperiment,\n variation: featureFlag.variationOptions.find(o => o.value === featureFlag.variation)\n });\n\n const { variationType, variation } = featureFlag;\n\n return parseVariation(variationType, variation);\n }\n\n setFullData(data: IDataStore) {\n this._store = {\n featureFlags: {} as { [key: string]: IFeatureFlag }\n };\n\n this._dumpToStorage(this._store);\n this.updateBulkFromRemote(data);\n }\n\n getFeatureFlags(): { [key: string]: IFeatureFlag } {\n return this._store.featureFlags;\n }\n\n updateStorageBulk(data: IDataStore, storageKey: string, onlyInsertNewElement: boolean) {\n let dataStoreStr = localStorage.getItem(storageKey);\n let store: IDataStore | null = null;\n\n try {\n if (dataStoreStr && dataStoreStr.trim().length > 0) {\n store = JSON.parse(dataStoreStr);\n }\n } catch (err) {\n logger.logDebug(`error while loading local data store: ${storageKey}` + err);\n }\n\n if (!!store) {\n const { featureFlags } = data;\n\n Object.keys(featureFlags).forEach(id => {\n const remoteFf = featureFlags[id];\n const localFf = store!.featureFlags[id];\n\n const predicate = !localFf || !onlyInsertNewElement;\n if (predicate) {\n store!.featureFlags[remoteFf.id] = Object.assign({}, remoteFf);\n }\n });\n\n this._dumpToStorage(store, storageKey);\n }\n }\n\n updateBulkFromRemote(data: IDataStore) {\n const storageKey = `${DataStoreStorageKey}-${this._userId}`;\n\n this.updateStorageBulk(data, storageKey, false);\n\n this._loadFromStorage();\n }\n\n private _emitUpdateEvents(updatedFeatureFlags: any[]): void {\n if (updatedFeatureFlags.length > 0) {\n updatedFeatureFlags.forEach(({ id, operation, data }) => eventHub.emit(`ff_${operation}:${data.id}`, data));\n eventHub.emit(`ff_${FeatureFlagUpdateOperation.update}`, updatedFeatureFlags.map(item => item.data));\n }\n }\n\n private _dumpToStorage(store?: IDataStore, localStorageKey?: string): void {\n if (store) {\n const storageKey = localStorageKey || `${DataStoreStorageKey}-${this._userId}`;\n localStorage.setItem(storageKey, JSON.stringify(store));\n return;\n }\n const storageKey = `${DataStoreStorageKey}-${this._userId}`;\n localStorage.setItem(storageKey, JSON.stringify(this._store));\n }\n\n private _loadFromStorage(): void {\n try {\n const storageKey = `${DataStoreStorageKey}-${this._userId}`;\n let dataStoreStr = localStorage.getItem(storageKey);\n\n let shouldDumpToStorage = false;\n\n if (dataStoreStr && dataStoreStr.trim().length > 0) {\n // compare _store and dataStoreStr data and send notification if different\n const storageData: IDataStore = JSON.parse(dataStoreStr);\n\n const updatedFeatureFlags = Object.keys(storageData.featureFlags).filter(key => {\n const storageFf = storageData.featureFlags[key];\n const ff = this._store.featureFlags[key];\n return !ff || storageFf.variation !== ff.variation || storageFf.variationType !== ff.variationType;\n }).map(key => {\n const storageFf = storageData.featureFlags[key];\n const ff = this._store.featureFlags[key];\n\n return {\n id: key,\n operation: FeatureFlagUpdateOperation.update,\n sendToExperiment: storageFf.sendToExperiment,\n data: {\n id: key,\n oldValue: ff ? parseVariation(ff.variationType, ff.variation): undefined,\n newValue: parseVariation(storageFf.variationType, storageFf.variation)\n } as IFeatureFlagChange\n }\n });\n\n this._store = storageData;\n this._emitUpdateEvents(updatedFeatureFlags);\n } else {\n this._store = {\n featureFlags: {} as { [key: string]: IFeatureFlag }\n };\n }\n\n if (shouldDumpToStorage) {\n this._dumpToStorage();\n }\n\n } catch (err) {\n logger.logDebug('error while loading local data store: ' + err);\n }\n }\n}\n\nexport default new Store();","import { uuid } from \"./utils\";\n\nconst API_CALL_RESULTS : {[key: string]: string} = {};\nconst FOOT_PRINTS: string[] = [];\nlet _throttleWait: number = 0; // send immediately\n\nclass ThrottleUtil {\n private _key: string;\n\n constructor(){\n this._key = uuid();\n }\n\n setKey(key: string) {\n this._key = key || this._key;\n }\n\n throttle(fn: Function, ms: number) {\n let timer:any = 0\n return function(...args) {\n clearTimeout(timer)\n timer = setTimeout(fn.bind(null, ...args), ms || 0)\n }\n }\n\n throttleAsync (callback: any): any {\n let waiting = false; \n \n let getFootprint = (args: any): string => {\n const params = args.map(arg => {\n if (\n typeof arg === 'object' &&\n typeof arg !== \"function\" &&\n arg !== null\n ) {\n if (Array.isArray(arg)) {\n return arg.map(a => ({...a, ...{timestamp: null}}))\n } else {\n return {...arg, ...{timestamp: null}};\n }\n }\n \n return arg;\n });\n \n return this._key + JSON.stringify(params);\n };\n \n return async function (...args) {\n const footprint = getFootprint(args);\n const idx = FOOT_PRINTS.findIndex(f => f === footprint);\n if (!waiting || idx === -1) {\n waiting = true;\n if (idx === -1) {\n FOOT_PRINTS.push(footprint);\n }\n \n API_CALL_RESULTS[footprint] = await callback.apply(null, args);\n \n setTimeout(function () {\n waiting = false;\n }, _throttleWait);\n }\n \n return API_CALL_RESULTS[footprint];\n }\n }\n}\n\nexport default new ThrottleUtil();\n\n\n","import { websocketReconnectTopic } from \"./constants\";\nimport { eventHub } from \"./events\";\nimport { logger } from \"./logger\";\nimport { IInsight, InsightType, IStreamResponse, IUser } from \"./types\";\nimport { generateConnectionToken } from \"./utils\";\nimport throttleUtil from \"./throttleutil\";\n\nconst socketConnectionIntervals = [250, 500, 1000, 2000, 4000, 8000];\n\nclass NetworkService {\n private user: IUser | undefined;\n private streamingUri: string | undefined;\n private eventsUri: string | undefined;\n private secret: string | undefined;\n private appType: string | undefined;\n\n private retryCounter = 0;\n\n constructor(){}\n\n init(streamingUri: string, eventsUri: string, secret: string, appType: string) {\n this.streamingUri = streamingUri;\n this.eventsUri = eventsUri;\n this.secret = secret;\n this.appType = appType;\n }\n\n identify(user: IUser, sendIdentifyMessage: boolean) {\n this.user = { ...user };\n throttleUtil.setKey(this.user?.keyId);\n\n if (sendIdentifyMessage && this.socket) {\n this.sendUserIdentifyMessage(0);\n }\n }\n\n private sendUserIdentifyMessage(timestamp: number) {\n const { name, keyId, customizedProperties } = this.user!;\n const payload = {\n messageType: 'data-sync',\n data: {\n user: {\n name,\n keyId,\n customizedProperties,\n },\n timestamp\n }\n };\n\n try {\n if (this.socket?.readyState === WebSocket.OPEN) {\n logger.logDebug('sending user identify message');\n this.socket?.send(JSON.stringify(payload));\n } else {\n logger.logDebug(`didn't send user identify message because socket not open`);\n }\n } catch (err) {\n logger.logDebug(err);\n }\n }\n\n private socket: WebSocket | undefined | any;\n\n private reconnect() {\n this.socket = null;\n const waitTime = socketConnectionIntervals[Math.min(this.retryCounter++, socketConnectionIntervals.length - 1)];\n setTimeout(() => {\n logger.logDebug('emit reconnect event');\n eventHub.emit(websocketReconnectTopic, {});\n }, waitTime);\n logger.logDebug(waitTime);\n }\n\n private sendPingMessage() {\n const payload = {\n messageType: 'ping',\n data: null\n };\n\n setTimeout(() => {\n try {\n if (this.socket?.readyState === WebSocket.OPEN) {\n logger.logDebug('sending ping')\n this.socket.send(JSON.stringify(payload));\n this.sendPingMessage();\n } else {\n logger.logDebug(`socket closed at ${new Date()}`);\n this.reconnect();\n }\n } catch (err) {\n logger.logDebug(err);\n }\n }, 18000);\n }\n\n createConnection(timestamp: number, onMessage: (response: IStreamResponse) => any) {\n const that = this;\n if (that.socket) {\n onMessage({} as IStreamResponse);\n return;\n }\n\n const startTime = Date.now();\n // Create WebSocket connection.\n const url = `${this.streamingUri}/streaming?type=client&token=${generateConnectionToken(this.secret!)}`;\n that.socket = new WebSocket(url);\n\n // Connection opened\n that.socket.addEventListener('open', function (this: WebSocket, event) {\n that.retryCounter = 0;\n // this is the websocket instance to which the current listener is binded to, it's different from that.socket\n logger.logDebug(`Connection time: ${Date.now() - startTime} ms`);\n that.sendUserIdentifyMessage(timestamp);\n that.sendPingMessage();\n });\n \n // Connection closed\n that.socket.addEventListener('close', function (event) {\n logger.logDebug('close');\n if (event.code === 4003) { // do not reconnect when 4003\n return;\n }\n\n that.reconnect();\n });\n \n // Connection error\n that.socket!.addEventListener('error', function (event) {\n // reconnect\n logger.logDebug('error');\n });\n \n // Listen for messages\n that.socket.addEventListener('message', function (event) {\n const message = JSON.parse(event.data);\n if (message.messageType === 'data-sync') {\n onMessage(message.data);\n if (message.data.featureFlags.length > 0) {\n logger.logDebug('socket push update time(ms): ', Date.now() - message.data.featureFlags[0].timestamp);\n }\n }\n });\n }\n\n private __getUserInfo(): any {\n const { name, keyId, customizedProperties } = this.user!;\n return {\n name: name,\n keyId: keyId,\n customizedProperties: customizedProperties,\n }\n }\n\n sendInsights = throttleUtil.throttleAsync(async (data: IInsight[]): Promise<void> => {\n if (!this.secret || !this.user || !data || data.length === 0) {\n return;\n }\n \n try {\n const payload = [{\n user: this.__getUserInfo(),\n variations: data.filter(d => d.insightType === InsightType.featureFlagUsage).map(v => ({\n featureFlagKey: v.id,\n sendToExperiment: v.sendToExperiment,\n timestamp: v.timestamp,\n variation: {\n id: v.variation!.id,\n value: v.variation!.value\n }\n })),\n metrics: data.filter(d => d.insightType !== InsightType.featureFlagUsage).map(d => ({\n route: location.pathname,\n timestamp: d.timestamp,\n numericValue: d.numericValue === null || d.numericValue === undefined? 1 : d.numericValue,\n appType: this.appType,\n eventName: d.eventName,\n type: d.type\n }))\n }];\n \n await post(`${this.eventsUri}/api/public/insight/track`, payload, { Authorization: this.secret });\n } catch (err) {\n logger.logDebug(err);\n }\n })\n}\n\nexport const networkService = new NetworkService();\n\nexport async function post(url: string = '', data: any = {}, headers: { [key: string]: string } = {}) {\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: Object.assign({\n 'Content-Type': 'application/json'\n }, headers),\n body: JSON.stringify(data) // body data type must match \"Content-Type\" header\n });\n\n return response.status === 200 ? response.json() : {};\n } catch (err) {\n logger.logDebug(err);\n return {};\n }\n}\n\nexport async function get(url: string = '', headers: { [key: string]: string } = {}) {\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: Object.assign({\n 'Accept': 'application/json',\n 'Content-Type': 'application/json'\n }, headers)\n });\n\n return response.status === 200 ? response.json() : {};\n } catch (err) {\n logger.logDebug(err);\n return null;\n }\n}\n","import { eventHub } from \"./events\";\n\nexport class Queue<T> {\n private queue: T[];\n // flushLimit === 0 means no limit\n // and \n constructor(private flushLimit: number = 0, private arriveflushLimitTopic: string = '') {\n this.queue = [];\n }\n\n add(element: T): void {\n this.queue.push(element);\n if (this.flushLimit > 0 && this.queue.length >= this.flushLimit) {\n eventHub.emit(this.arriveflushLimitTopic, {});\n }\n }\n\n flush(): T[] {\n const allElements = [...this.queue];\n this.queue = [];\n return allElements;\n }\n}","import { eventHub } from \"./events\";\nimport { logger } from \"./logger\";\nimport store from \"./store\";\nimport { networkService } from \"./network.service\";\nimport {\n FeatureFlagValue,\n ICustomEvent,\n IFeatureFlag,\n IFeatureFlagBase,\n IFeatureFlagSet,\n IFeatureFlagVariationBuffer,\n IInsight,\n InsightType,\n IOption,\n IStreamResponse,\n IUser,\n StreamResponseEventType,\n VariationDataType\n} from \"./types\";\nimport {\n generateorGetGuid,\n isNullOrUndefinedOrWhiteSpace,\n parseVariation,\n serializeUser,\n validateOption,\n validateUser\n} from \"./utils\";\nimport { Queue } from \"./queue\";\nimport {\n currentUserStorageKey,\n featureFlagEvaluatedBufferTopic,\n featureFlagEvaluatedTopic,\n insightsFlushTopic,\n insightsTopic,\n websocketReconnectTopic\n} from \"./constants\";\n\n\nfunction createOrGetAnonymousUser(): IUser {\n const sessionId = generateorGetGuid();\n\n return {\n name: sessionId,\n keyId: sessionId\n };\n}\n\nfunction mapFeatureFlagsToFeatureFlagBaseList(featureFlags: { [key: string]: IFeatureFlag }): IFeatureFlagBase[] {\n return Object.keys(featureFlags).map((cur) => {\n const {id, variation} = featureFlags[cur];\n const variationType = featureFlags[cur].variationType || VariationDataType.string;\n return {id, variation: parseVariation(variationType, variation), variationType};\n });\n}\n\nexport class FB {\n private _readyEventEmitted: boolean = false;\n private _readyPromise: Promise<IFeatureFlagBase[]>;\n\n private _insightsQueue: Queue<IInsight> = new Queue<IInsight>(1, insightsFlushTopic);\n private _featureFlagEvaluationBuffer: Queue<IFeatureFlagVariationBuffer> = new Queue<IFeatureFlagVariationBuffer>();\n private _option: IOption = {\n secret: '',\n api: '',\n streamingUri: '',\n eventsUri: '',\n enableDataSync: true,\n appType: 'javascript'\n };\n\n constructor() {\n this._readyPromise = new Promise<IFeatureFlagBase[]>((resolve, reject) => {\n this.on('ready', () => {\n const featureFlags = store.getFeatureFlags();\n resolve(mapFeatureFlagsToFeatureFlagBaseList(featureFlags));\n if (this._option.enableDataSync) {\n const buffered = this._featureFlagEvaluationBuffer.flush().map(f => {\n const featureFlag = featureFlags[f.id];\n if (!featureFlag) {\n logger.log(`Called unexisting feature flag: ${ f.id }`);\n return null;\n }\n\n const variation = featureFlag.variationOptions.find(o => o.value === f.variationValue);\n if (!variation) {\n logger.log(`Sent buffered insight for feature flag: ${ f.id } with unexisting default variation: ${ f.variationValue }`);\n } else {\n logger.logDebug(`Sent buffered insight for feature flag: ${ f.id } with variation: ${ variation.value }`);\n }\n\n return {\n insightType: InsightType.featureFlagUsage,\n id: featureFlag.id,\n timestamp: f.timestamp,\n sendToExperiment: featureFlag.sendToExperiment,\n variation: variation || {id: -1, value: f.variationValue}\n }\n });\n\n networkService.sendInsights(buffered.filter(x => !!x));\n }\n });\n });\n\n // reconnect to websocket\n eventHub.subscribe(websocketReconnectTopic, async () => {\n try {\n logger.logDebug('reconnecting');\n await this.dataSync();\n if (!this._readyEventEmitted) {\n this._readyEventEmitted = true;\n eventHub.emit('ready', mapFeatureFlagsToFeatureFlagBaseList(store.getFeatureFlags()));\n }\n } catch (err) {\n logger.log('data sync error', err);\n }\n });\n\n eventHub.subscribe(featureFlagEvaluatedBufferTopic, (data: IFeatureFlagVariationBuffer) => {\n this._featureFlagEvaluationBuffer.add(data);\n });\n\n // track feature flag usage data\n eventHub.subscribe(insightsFlushTopic, () => {\n if (this._option.enableDataSync) {\n networkService.sendInsights(this._insightsQueue.flush());\n }\n });\n\n eventHub.subscribe(featureFlagEvaluatedTopic, (data: IInsight) => {\n this._insightsQueue.add(data);\n });\n\n eventHub.subscribe(insightsTopic, (data: IInsight) => {\n this._insightsQueue.add(data);\n });\n }\n\n on(name: string, cb: Function) {\n eventHub.subscribe(name, cb);\n }\n\n off(name: string, cb: Function) {\n eventHub.unsubscribe(name, cb);\n }\n\n waitUntilReady(): Promise<IFeatureFlagBase[]> {\n return this._readyPromise;\n }\n\n async init(option: IOption) {\n const validateOptionResult = validateOption({...this._option, ...option});\n if (validateOptionResult !== null) {\n logger.log(validateOptionResult);\n return;\n }\n\n this._option = {\n ...this._option,\n ...option,\n ...{\n api: (option.api || this._option.api)?.replace(/\\/$/, '')\n }\n };\n\n if (this._option.enableDataSync) {\n networkService.init(this._option.streamingUri!, this._option.eventsUri!, this._option.secret, this._option.appType!);\n }\n\n await this.identify(option.user || createOrGetAnonymousUser());\n }\n\n async identify(user: IUser): Promise<void> {\n const validateUserResult = validateUser(user);\n if (validateUserResult !== null) {\n logger.log(validateUserResult);\n return;\n }\n\n user.customizedProperties = user.customizedProperties?.map(p => ({name: p.name, value: `${ p.value }`}));\n\n const isUserChanged = serializeUser(user) !== localStorage.getItem(currentUserStorageKey);\n this._option.user = Object.assign({}, user);\n localStorage.setItem(currentUserStorageKey, serializeUser(this._option.user));\n\n store.userId = this._option.user.keyId;\n networkService.identify(this._option.user, isUserChanged);\n\n await this.bootstrap(this._option.bootstrap, isUserChanged);\n }\n\n async logout(): Promise<IUser> {\n const anonymousUser = createOrGetAnonymousUser();\n await this.identify(anonymousUser);\n return anonymousUser;\n }\n\n /**\n * bootstrap with predefined feature flags.\n * @param {array} featureFlags the predefined feature flags.\n * @param {boolean} forceFullFetch if a forced full fetch should be made.\n * @return {Promise<void>} nothing.\n */\n async bootstrap(featureFlags?: IFeatureFlag[], forceFullFetch?: boolean): Promise<void> {\n featureFlags = featureFlags || this._option.bootstrap;\n if (featureFlags && featureFlags.length > 0) {\n const data = {\n featureFlags: featureFlags.reduce((res, curr) => {\n const {id, variation, timestamp, variationOptions, sendToExperiment, variationType} = curr;\n res[id] = {\n id,\n variation,\n timestamp,\n variationOptions: variationOptions || [{id: 1, value: variation}],\n sendToExperiment,\n variationType: variationType || VariationDataType.string\n };\n\n return res;\n }, {} as { [key: string]: IFeatureFlag })\n };\n\n store.setFullData(data);\n logger.logDebug('bootstrapped with full data');\n }\n\n if (this._option.enableDataSync) {\n // start data sync\n try {\n await this.dataSync(forceFullFetch);\n } catch (err) {\n logger.log('data sync error', err);\n }\n }\n\n if (!this._readyEventEmitted) {\n this._readyEventEmitted = true;\n eventHub.emit('ready', mapFeatureFlagsToFeatureFlagBaseList(store.getFeatureFlags()));\n }\n }\n\n private async dataSync(forceFullFetch?: boolean): Promise<any> {\n return new Promise<void>((resolve, reject) => {\n const timestamp = forceFullFetch ? 0 : Math.max(...Object.values(store.getFeatureFlags()).map(ff => ff.timestamp), 0);\n\n networkService.createConnection(timestamp, (message: IStreamResponse) => {\n if (message && message.userKeyId === this._option.user?.keyId) {\n const {featureFlags} = message;\n\n switch (message.eventType) {\n case StreamResponseEventType.full: // full data\n case StreamResponseEventType.patch: // partial data\n const data = {\n featureFlags: featureFlags.reduce((res, curr) => {\n const {id, variation, timestamp, variationOptions, sendToExperiment, variationType} = curr;\n res[id] = {\n id,\n variation,\n timestamp,\n variationOptions,\n sendToExperiment,\n variationType: variationType || VariationDataType.string\n };\n\n return res;\n }, {} as { [key: string]: IFeatureFlag })\n };\n\n if (message.eventType === StreamResponseEventType.full) {\n store.setFullData(data);\n logger.logDebug('synchonized with full data');\n } else {\n store.updateBulkFromRemote(data);\n logger.logDebug('synchonized with partial data');\n }\n\n break;\n default:\n logger.logDebug('invalid stream event type: ' + message.eventType);\n break;\n }\n }\n\n resolve();\n });\n });\n }\n\n variation(key: string, defaultResult: FeatureFlagValue): FeatureFlagValue {\n const variation = variationWithInsightBuffer(key, defaultResult);\n return variation === undefined ? defaultResult : variation;\n }\n\n /**\n * deprecated, you should use variation method directly\n */\n boolVariation(key: string, defaultResult: boolean): boolean {\n const variation = variationWithInsightBuffer(key, defaultResult);\n return variation === undefined ? defaultResult : variation?.toLocaleLowerCase() === 'true';\n }\n\n getUser(): IUser {\n return {...this._option.user!};\n }\n\n sendCustomEvent(data: ICustomEvent[]): void {\n (data || []).forEach(d => this._insightsQueue.add({\n insightType: InsightType.customEvent,\n timestamp: Date.now(),\n type: 'CustomEvent',\n ...d\n }))\n }\n\n sendFeatureFlagInsight(key: string, variation: string) {\n this.variation(key, variation);\n }\n\n getAllFeatureFlags(): IFeatureFlagSet {\n const flags = store.getFeatureFlags();\n\n return Object.values(flags).reduce((acc, curr) => {\n acc[curr.id] = parseVariation(curr.variationType, curr.variation);\n return acc;\n }, {});\n }\n}\n\nconst variationWithInsightBuffer = (key: string, defaultResult: string | boolean) => {\n const variation = store.getVariation(key);\n if (variation === undefined) {\n eventHub.emit(featureFlagEvaluatedBufferTopic, {\n id: key,\n timestamp: Date.now(),\n variationValue: `${ defaultResult }`\n } as IFeatureFlagVariationBuffer);\n }\n\n return variation;\n}\n\nexport default new FB();\n\n","// This file is only for umd version\n\nconst html = document.querySelector('html');\nconst waittime = 500;\nif (html) {\n html.style.visibility = 'hidden';\n setTimeout(() => html.style.visibility = 'visible', waittime);\n}\n\nimport fbClient from './featbit';\nimport { logger } from './logger';\n\nlogger.logDebug(`version: 2.0.2`);\n\nexport { fbClient }\n"],"names":["root","factory","exports","module","define","amd","a","i","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","InsightType","VariationDataType","StreamResponseEventType","FeatureFlagUpdateOperation","eventHub","events","subscribe","name","cb","push","unsubscribe","splice","indexOf","emit","forEach","fn","args","logDebug","log","console","insightsFlushTopic","featureFlagEvaluatedTopic","featureFlagEvaluatedBufferTopic","websocketReconnectTopic","currentUserStorageKey","partialEndpoint","invalidParam","mandatory","serializeUser","user","builtInProperties","keyId","customizedProperties","map","p","join","parseVariation","type","string","boolean","number","str","isNaN","parseFloat","json","JSON","parse","e","uuid","replace","c","r","Math","random","toString","validateUser","trim","isNullOrUndefinedOrWhiteSpace","alphabet","encodeNumber","param","length","s","slice","split","n","DataStoreStorageKey","_userId","_store","featureFlags","id","_loadFromStorage","getFeatureFlag","getVariation","featureFlag","insightType","featureFlagUsage","timestamp","Date","now","sendToExperiment","variation","variationOptions","find","setFullData","data","_dumpToStorage","updateBulkFromRemote","getFeatureFlags","updateStorageBulk","storageKey","onlyInsertNewElement","dataStoreStr","localStorage","getItem","store","err","keys","remoteFf","assign","_emitUpdateEvents","updatedFeatureFlags","operation","update","item","localStorageKey","setItem","stringify","filter","storageFf","ff","variationType","oldValue","undefined","newValue","Store","API_CALL_RESULTS","FOOT_PRINTS","_key","setKey","throttle","ms","timer","clearTimeout","setTimeout","bind","throttleAsync","callback","waiting","footprint","params","arg","Array","isArray","getFootprint","idx","findIndex","f","apply","socketConnectionIntervals","networkService","retryCounter","sendInsights","secret","payload","__getUserInfo","variations","d","v","featureFlagKey","metrics","route","location","pathname","numericValue","appType","eventName","post","eventsUri","Authorization","init","streamingUri","identify","sendIdentifyMessage","socket","sendUserIdentifyMessage","messageType","readyState","WebSocket","OPEN","send","reconnect","waitTime","min","sendPingMessage","createConnection","onMessage","that","startTime","url","text","timestampCode","start","max","floor","generateConnectionToken","addEventListener","event","code","message","headers","fetch","method","body","response","status","flushLimit","arriveflushLimitTopic","queue","add","element","flush","allElements","createOrGetAnonymousUser","sessionId","guid","generateorGetGuid","mapFeatureFlagsToFeatureFlagBaseList","cur","_readyEventEmitted","_insightsQueue","Queue","_featureFlagEvaluationBuffer","_option","api","enableDataSync","_readyPromise","Promise","resolve","reject","on","buffered","variationValue","x","dataSync","off","waitUntilReady","option","validateOptionResult","anonymous","streamingUriMissing","eventsUriMissing","validateOption","validateUserResult","isUserChanged","userId","bootstrap","logout","anonymousUser","forceFullFetch","reduce","res","curr","values","userKeyId","eventType","full","patch","defaultResult","variationWithInsightBuffer","boolVariation","toLocaleLowerCase","getUser","sendCustomEvent","customEvent","sendFeatureFlagInsight","getAllFeatureFlags","flags","acc","FB","html","document","querySelector","style","visibility"],"sourceRoot":""}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var n=e();for(var r in n)("object"==typeof exports?exports:t)[r]=n[r]}}(this,(()=>(()=>{"use strict";var t={d:(e,n)=>{for(var r in n)t.o(n,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{fbClient:()=>R});var n,r,i,o,a=new(function(){function t(t){this.events=t||{}}return t.prototype.subscribe=function(t,e){var n=this;return(this.events[t]||(this.events[t]=[])).push(e),{unsubscribe:function(){return n.events[t]&&n.events[t].splice(n.events[t].indexOf(e)>>>0,1)}}},t.prototype.unsubscribe=function(t,e){this.events[t]&&this.events[t].splice(this.events[t].indexOf(e)>>>0,1)},t.prototype.emit=function(t){for(var e=[],n=1;n<arguments.length;n++)e[n-1]=arguments[n];(this.events[t]||[]).forEach((function(t){return t.apply(void 0,e)}))},t}()),u="insights.flush",s="featureflag.evaluated.topic",c="featureflag.evaluated.buffer.topic",l="network.websocket.reconnect",f="fb-user",p=window.location.search,d=new URLSearchParams(p).get("debugmode"),h={logDebug:function(){for(var t=[],e=0;e<arguments.length;e++)t[e]=arguments[e];"true"===d&&console.log.apply(console,t)},log:function(){for(var t=[],e=0;e<arguments.length;e++)t[e]=arguments[e];console.log.apply(console,t)}};!function(t){t[t.featureFlagUsage=1]="featureFlagUsage",t[t.customEvent=2]="customEvent",t[t.pageView=3]="pageView",t[t.click=4]="click"}(n||(n={})),function(t){t.string="string",t.boolean="boolean",t.number="number",t.json="json"}(r||(r={})),function(t){t.full="full",t.patch="patch"}(i||(i={})),function(t){t.update="update"}(o||(o={}));const v=function(){function t(){}return t.partialEndpoint=function(t){return"You have set custom uris without specifying the ".concat(t," URI; connections may not work properly")},t.invalidParam=function(t){return"The ".concat(t," option is not passed in or its value is invalid")},t.mandatory=function(t){return"".concat(t," is mandatory")},t}();function g(t){var e;if(!t)return"";var n="".concat(t.keyId,",").concat(t.name),r=null===(e=t.customizedProperties)||void 0===e?void 0:e.map((function(t){return"".concat(t.name,":").concat(t.value)})).join(",");return"".concat(n,",").concat(r)}function y(t,e){switch(t){case r.string:return e;case r.boolean:return"true"===e||"false"!==e&&(h.log("expected boolean value, but got ".concat(e)),e);case r.number:return"string"!=typeof(n=e)||isNaN(n)||isNaN(parseFloat(n))?(h.log("expected numeric value, but got ".concat(e)),e):+e;case r.json:try{return JSON.parse(e)}catch(t){return h.log("expected json value, but got ".concat(e)),e}default:return h.log("unexpected variation type ".concat(t," for ").concat(e)),e}var n}function m(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(t){var e=16*Math.random()|0;return("x"==t?e:3&e|8).toString(16)}))}function b(t){if(!t)return v.mandatory("user");var e=t.keyId,n=t.name;return null==e||""===e.trim()?v.mandatory("user.keyId"):null==n||""===n.trim()?v.mandatory("user.name"):null}function w(t){return null==t||""===t.trim()}var x={0:"Q",1:"B",2:"W",3:"S",4:"P",5:"H",6:"D",7:"X",8:"Z",9:"U"};function _(t,e){var n="000000000000"+t;return n.slice(n.length-e).split("").map((function(t){return x[t]})).join("")}var k="fb-datastore",S=function(){function t(){this._userId=null,this._store={featureFlags:{}}}return Object.defineProperty(t.prototype,"userId",{set:function(t){this._userId=t,this._loadFromStorage()},enumerable:!1,configurable:!0}),t.prototype.getFeatureFlag=function(t){return this._store.featureFlags[t]},t.prototype.getVariation=function(t){var e=this._store.featureFlags[t];if(e)return a.emit(s,{insightType:n.featureFlagUsage,id:e.id,timestamp:Date.now(),sendToExperiment:e.sendToExperiment,variation:e.variationOptions.find((function(t){return t.value===e.variation}))}),y(e.variationType,e.variation)},t.prototype.setFullData=function(t){this._store={featureFlags:{}},this._dumpToStorage(this._store),this.updateBulkFromRemote(t)},t.prototype.getFeatureFlags=function(){return this._store.featureFlags},t.prototype.updateStorageBulk=function(t,e,n){var r=localStorage.getItem(e),i=null;try{r&&r.trim().length>0&&(i=JSON.parse(r))}catch(t){h.logDebug("error while loading local data store: ".concat(e)+t)}if(i){var o=t.featureFlags;Object.keys(o).forEach((function(t){var e=o[t];(!i.featureFlags[t]||!n)&&(i.featureFlags[e.id]=Object.assign({},e))})),this._dumpToStorage(i,e)}},t.prototype.updateBulkFromRemote=function(t){var e="".concat(k,"-").concat(this._userId);this.updateStorageBulk(t,e,!1),this._loadFromStorage()},t.prototype._emitUpdateEvents=function(t){t.length>0&&(t.forEach((function(t){t.id;var e=t.operation,n=t.data;return a.emit("ff_".concat(e,":").concat(n.id),n)})),a.emit("ff_".concat(o.update),t.map((function(t){return t.data}))))},t.prototype._dumpToStorage=function(t,e){if(t){var n=e||"".concat(k,"-").concat(this._userId);localStorage.setItem(n,JSON.stringify(t))}else{var r="".concat(k,"-").concat(this._userId);localStorage.setItem(r,JSON.stringify(this._store))}},t.prototype._loadFromStorage=function(){var t=this;try{var e="".concat(k,"-").concat(this._userId),n=localStorage.getItem(e);if(n&&n.trim().length>0){var r=JSON.parse(n),i=Object.keys(r.featureFlags).filter((function(e){var n=r.featureFlags[e],i=t._store.featureFlags[e];return!i||n.variation!==i.variation||n.variationType!==i.variationType})).map((function(e){var n=r.featureFlags[e],i=t._store.featureFlags[e];return{id:e,operation:o.update,sendToExperiment:n.sendToExperiment,data:{id:e,oldValue:i?y(i.variationType,i.variation):void 0,newValue:y(n.variationType,n.variation)}}}));this._store=r,this._emitUpdateEvents(i)}else this._store={featureFlags:{}}}catch(t){h.logDebug("error while loading local data store: "+t)}},t}();const T=new S;var F=function(){return F=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var i in e=arguments[n])Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},F.apply(this,arguments)},E={},O=[];const D=new(function(){function t(){this._key=m()}return t.prototype.setKey=function(t){this._key=t||this._key},t.prototype.throttle=function(t,e){var n=0;return function(){for(var r=[],i=0;i<arguments.length;i++)r[i]=arguments[i];clearTimeout(n),n=setTimeout(t.bind.apply(t,function(t,e,n){if(n||2===arguments.length)for(var r,i=0,o=e.length;i<o;i++)!r&&i in e||(r||(r=Array.prototype.slice.call(e,0,i)),r[i]=e[i]);return t.concat(r||Array.prototype.slice.call(e))}([null],r,!1)),e||0)}},t.prototype.throttleAsync=function(t){var e=this,n=!1;return function(){for(var r=[],i=0;i<arguments.length;i++)r[i]=arguments[i];return o=this,a=void 0,s=function(){var i,o,a,u;return function(t,e){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function u(u){return function(s){return function(u){if(n)throw new TypeError("Generator is already executing.");for(;o&&(o=0,u[0]&&(a=0)),a;)try{if(n=1,r&&(i=2&u[0]?r.return:u[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,u[1])).done)return i;switch(r=0,i&&(u=[2&u[0],i.value]),u[0]){case 0:case 1:i=u;break;case 4:return a.label++,{value:u[1],done:!1};case 5:a.label++,r=u[1],u=[0];continue;case 7:u=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==u[0]&&2!==u[0])){a=0;continue}if(3===u[0]&&(!i||u[1]>i[0]&&u[1]<i[3])){a.label=u[1];break}if(6===u[0]&&a.label<i[1]){a.label=i[1],i=u;break}if(i&&a.label<i[2]){a.label=i[2],a.ops.push(u);break}i[2]&&a.ops.pop(),a.trys.pop();continue}u=e.call(t,a)}catch(t){u=[6,t],r=0}finally{n=i=0}if(5&u[0])throw u[1];return{value:u[0]?u[1]:void 0,done:!0}}([u,s])}}}(this,(function(s){switch(s.label){case 0:return i=function(t){var n=t.map((function(t){return"object"==typeof t&&"function"!=typeof t&&null!==t?Array.isArray(t)?t.map((function(t){return F(F({},t),{timestamp:null})})):F(F({},t),{timestamp:null}):t}));return e._key+JSON.stringify(n)}(r),o=O.findIndex((function(t){return t===i})),n&&-1!==o?[3,2]:(n=!0,-1===o&&O.push(i),a=E,u=i,[4,t.apply(null,r)]);case 1:a[u]=s.sent(),setTimeout((function(){n=!1}),0),s.label=2;case 2:return[2,E[i]]}}))},new((u=void 0)||(u=Promise))((function(t,e){function n(t){try{i(s.next(t))}catch(t){e(t)}}function r(t){try{i(s.throw(t))}catch(t){e(t)}}function i(e){var i;e.done?t(e.value):(i=e.value,i instanceof u?i:new u((function(t){t(i)}))).then(n,r)}i((s=s.apply(o,a||[])).next())}));var o,a,u,s}},t}());var I=function(){return I=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var i in e=arguments[n])Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},I.apply(this,arguments)},j=function(t,e,n,r){return new(n||(n=Promise))((function(i,o){function a(t){try{s(r.next(t))}catch(t){o(t)}}function u(t){try{s(r.throw(t))}catch(t){o(t)}}function s(t){var e;t.done?i(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(a,u)}s((r=r.apply(t,e||[])).next())}))},P=function(t,e){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function u(u){return function(s){return function(u){if(n)throw new TypeError("Generator is already executing.");for(;o&&(o=0,u[0]&&(a=0)),a;)try{if(n=1,r&&(i=2&u[0]?r.return:u[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,u[1])).done)return i;switch(r=0,i&&(u=[2&u[0],i.value]),u[0]){case 0:case 1:i=u;break;case 4:return a.label++,{value:u[1],done:!1};case 5:a.label++,r=u[1],u=[0];continue;case 7:u=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==u[0]&&2!==u[0])){a=0;continue}if(3===u[0]&&(!i||u[1]>i[0]&&u[1]<i[3])){a.label=u[1];break}if(6===u[0]&&a.label<i[1]){a.label=i[1],i=u;break}if(i&&a.label<i[2]){a.label=i[2],a.ops.push(u);break}i[2]&&a.ops.pop(),a.trys.pop();continue}u=e.call(t,a)}catch(t){u=[6,t],r=0}finally{n=i=0}if(5&u[0])throw u[1];return{value:u[0]?u[1]:void 0,done:!0}}([u,s])}}},U=[250,500,1e3,2e3,4e3,8e3],N=new(function(){function t(){var t=this;this.retryCounter=0,this.sendInsights=D.throttleAsync((function(e){return j(t,void 0,void 0,(function(){var t,r,i=this;return P(this,(function(o){switch(o.label){case 0:if(!this.secret||!this.user||!e||0===e.length)return[2];o.label=1;case 1:return o.trys.push([1,3,,4]),t=[{user:this.__getUserInfo(),variations:e.filter((function(t){return t.insightType===n.featureFlagUsage})).map((function(t){return{featureFlagKey:t.id,sendToExperiment:t.sendToExperiment,timestamp:t.timestamp,variation:{id:t.variation.id,value:t.variation.value}}})),metrics:e.filter((function(t){return t.insightType!==n.featureFlagUsage})).map((function(t){return{route:location.pathname,timestamp:t.timestamp,numericValue:null===t.numericValue||void 0===t.numericValue?1:t.numericValue,appType:i.appType,eventName:t.eventName,type:t.type}}))}],[4,M("".concat(this.eventsUri,"/api/public/insight/track"),t,{Authorization:this.secret})];case 2:return o.sent(),[3,4];case 3:return r=o.sent(),h.logDebug(r),[3,4];case 4:return[2]}}))}))}))}return t.prototype.init=function(t,e,n,r){this.streamingUri=t,this.eventsUri=e,this.secret=n,this.appType=r},t.prototype.identify=function(t,e){var n;this.user=I({},t),D.setKey(null===(n=this.user)||void 0===n?void 0:n.keyId),e&&this.socket&&this.sendUserIdentifyMessage(0)},t.prototype.sendUserIdentifyMessage=function(t){var e,n,r=this.user,i={messageType:"data-sync",data:{user:{name:r.name,keyId:r.keyId,customizedProperties:r.customizedProperties},timestamp:t}};try{(null===(e=this.socket)||void 0===e?void 0:e.readyState)===WebSocket.OPEN?(h.logDebug("sending user identify message"),null===(n=this.socket)||void 0===n||n.send(JSON.stringify(i))):h.logDebug("didn't send user identify message because socket not open")}catch(t){h.logDebug(t)}},t.prototype.reconnect=function(){this.socket=null;var t=U[Math.min(this.retryCounter++,U.length-1)];setTimeout((function(){h.logDebug("emit reconnect event"),a.emit(l,{})}),t),h.logDebug(t)},t.prototype.sendPingMessage=function(){var t=this,e={messageType:"ping",data:null};setTimeout((function(){var n;try{(null===(n=t.socket)||void 0===n?void 0:n.readyState)===WebSocket.OPEN?(h.logDebug("sending ping"),t.socket.send(JSON.stringify(e)),t.sendPingMessage()):(h.logDebug("socket closed at ".concat(new Date)),t.reconnect())}catch(t){h.logDebug(t)}}),18e3)},t.prototype.createConnection=function(t,e){var n=this;if(n.socket)e({});else{var r=Date.now(),i="".concat(this.streamingUri,"/streaming?type=client&token=").concat(function(t){t=t.replace(/=*$/,"");var e=Date.now(),n=_(e,e.toString().length),r=Math.max(Math.floor(Math.random()*t.length),2);return"".concat(_(r,3)).concat(_(n.length,2)).concat(t.slice(0,r)).concat(n).concat(t.slice(r))}(this.secret));n.socket=new WebSocket(i),n.socket.addEventListener("open",(function(e){n.retryCounter=0,h.logDebug("Connection time: ".concat(Date.now()-r," ms")),n.sendUserIdentifyMessage(t),n.sendPingMessage()})),n.socket.addEventListener("close",(function(t){h.logDebug("close"),4003!==t.code&&n.reconnect()})),n.socket.addEventListener("error",(function(t){h.logDebug("error")})),n.socket.addEventListener("message",(function(t){var n=JSON.parse(t.data);"data-sync"===n.messageType&&(e(n.data),n.data.featureFlags.length>0&&h.logDebug("socket push update time(ms): ",Date.now()-n.data.featureFlags[0].timestamp))}))}},t.prototype.__getUserInfo=function(){var t=this.user;return{name:t.name,keyId:t.keyId,customizedProperties:t.customizedProperties}},t}());function M(t,e,n){return void 0===t&&(t=""),void 0===e&&(e={}),void 0===n&&(n={}),j(this,void 0,void 0,(function(){var r,i;return P(this,(function(o){switch(o.label){case 0:return o.trys.push([0,2,,3]),[4,fetch(t,{method:"POST",headers:Object.assign({"Content-Type":"application/json"},n),body:JSON.stringify(e)})];case 1:return[2,200===(r=o.sent()).status?r.json():{}];case 2:return i=o.sent(),h.logDebug(i),[2,{}];case 3:return[2]}}))}))}var V=function(){function t(t,e){void 0===t&&(t=0),void 0===e&&(e=""),this.flushLimit=t,this.arriveflushLimitTopic=e,this.queue=[]}return t.prototype.add=function(t){this.queue.push(t),this.flushLimit>0&&this.queue.length>=this.flushLimit&&a.emit(this.arriveflushLimitTopic,{})},t.prototype.flush=function(){var t=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,o=e.length;i<o;i++)!r&&i in e||(r||(r=Array.prototype.slice.call(e,0,i)),r[i]=e[i]);return t.concat(r||Array.prototype.slice.call(e))}([],this.queue,!0);return this.queue=[],t},t}(),A=function(){return A=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var i in e=arguments[n])Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},A.apply(this,arguments)},C=function(t,e,n,r){return new(n||(n=Promise))((function(i,o){function a(t){try{s(r.next(t))}catch(t){o(t)}}function u(t){try{s(r.throw(t))}catch(t){o(t)}}function s(t){var e;t.done?i(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(a,u)}s((r=r.apply(t,e||[])).next())}))},L=function(t,e){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function u(u){return function(s){return function(u){if(n)throw new TypeError("Generator is already executing.");for(;o&&(o=0,u[0]&&(a=0)),a;)try{if(n=1,r&&(i=2&u[0]?r.return:u[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,u[1])).done)return i;switch(r=0,i&&(u=[2&u[0],i.value]),u[0]){case 0:case 1:i=u;break;case 4:return a.label++,{value:u[1],done:!1};case 5:a.label++,r=u[1],u=[0];continue;case 7:u=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==u[0]&&2!==u[0])){a=0;continue}if(3===u[0]&&(!i||u[1]>i[0]&&u[1]<i[3])){a.label=u[1];break}if(6===u[0]&&a.label<i[1]){a.label=i[1],i=u;break}if(i&&a.label<i[2]){a.label=i[2],a.ops.push(u);break}i[2]&&a.ops.pop(),a.trys.pop();continue}u=e.call(t,a)}catch(t){u=[6,t],r=0}finally{n=i=0}if(5&u[0])throw u[1];return{value:u[0]?u[1]:void 0,done:!0}}([u,s])}}},z=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,o=e.length;i<o;i++)!r&&i in e||(r||(r=Array.prototype.slice.call(e,0,i)),r[i]=e[i]);return t.concat(r||Array.prototype.slice.call(e))};function J(){var t=function(){var t=localStorage.getItem("fb-guid");if(t)return t;var e=m();return localStorage.setItem("fb-guid",e),e}();return{name:t,keyId:t}}function B(t){return Object.keys(t).map((function(e){var n=t[e],i=n.id,o=n.variation,a=t[e].variationType||r.string;return{id:i,variation:y(a,o),variationType:a}}))}var q=function(){function t(){var t=this;this._readyEventEmitted=!1,this._insightsQueue=new V(1,u),this._featureFlagEvaluationBuffer=new V,this._option={secret:"",api:"",streamingUri:"",eventsUri:"",enableDataSync:!0,appType:"javascript"},this._readyPromise=new Promise((function(e,r){t.on("ready",(function(){var r=T.getFeatureFlags();if(e(B(r)),t._option.enableDataSync){var i=t._featureFlagEvaluationBuffer.flush().map((function(t){var e=r[t.id];if(!e)return h.log("Called unexisting feature flag: ".concat(t.id)),null;var i=e.variationOptions.find((function(e){return e.value===t.variationValue}));return i?h.logDebug("Sent buffered insight for feature flag: ".concat(t.id," with variation: ").concat(i.value)):h.log("Sent buffered insight for feature flag: ".concat(t.id," with unexisting default variation: ").concat(t.variationValue)),{insightType:n.featureFlagUsage,id:e.id,timestamp:t.timestamp,sendToExperiment:e.sendToExperiment,variation:i||{id:-1,value:t.variationValue}}}));N.sendInsights(i.filter((function(t){return!!t})))}}))})),a.subscribe(l,(function(){return C(t,void 0,void 0,(function(){var t;return L(this,(function(e){switch(e.label){case 0:return e.trys.push([0,2,,3]),h.logDebug("reconnecting"),[4,this.dataSync()];case 1:return e.sent(),this._readyEventEmitted||(this._readyEventEmitted=!0,a.emit("ready",B(T.getFeatureFlags()))),[3,3];case 2:return t=e.sent(),h.log("data sync error",t),[3,3];case 3:return[2]}}))}))})),a.subscribe(c,(function(e){t._featureFlagEvaluationBuffer.add(e)})),a.subscribe(u,(function(){t._option.enableDataSync&&N.sendInsights(t._insightsQueue.flush())})),a.subscribe(s,(function(e){t._insightsQueue.add(e)})),a.subscribe("insights.topic",(function(e){t._insightsQueue.add(e)}))}return t.prototype.on=function(t,e){a.subscribe(t,e)},t.prototype.off=function(t,e){a.unsubscribe(t,e)},t.prototype.waitUntilReady=function(){return this._readyPromise},t.prototype.init=function(t){var e;return C(this,void 0,void 0,(function(){var n;return L(this,(function(r){switch(r.label){case 0:return n=function(t){if(null==t)return v.mandatory("option");var e=t.streamingUri,n=t.eventsUri,r=t.secret,i=t.anonymous,o=t.user,a=t.enableDataSync,u=w(e),s=w(n);if(a&&(u||s)){if(s)return v.partialEndpoint("eventsUri");if(u)return v.partialEndpoint("streamingUri")}return a&&w(r)?v.invalidParam("secret"):0!=!!i||o?o?b(o):null:v.mandatory("user")}(A(A({},this._option),t)),null!==n?(h.log(n),[2]):(this._option=A(A(A({},this._option),t),{api:null===(e=t.api||this._option.api)||void 0===e?void 0:e.replace(/\/$/,"")}),this._option.enableDataSync&&N.init(this._option.streamingUri,this._option.eventsUri,this._option.secret,this._option.appType),[4,this.identify(t.user||J())]);case 1:return r.sent(),[2]}}))}))},t.prototype.identify=function(t){var e;return C(this,void 0,void 0,(function(){var n,r;return L(this,(function(i){switch(i.label){case 0:return null!==(n=b(t))?(h.log(n),[2]):(t.customizedProperties=null===(e=t.customizedProperties)||void 0===e?void 0:e.map((function(t){return{name:t.name,value:"".concat(t.value)}})),r=g(t)!==localStorage.getItem(f),this._option.user=Object.assign({},t),localStorage.setItem(f,g(this._option.user)),T.userId=this._option.user.keyId,N.identify(this._option.user,r),[4,this.bootstrap(this._option.bootstrap,r)]);case 1:return i.sent(),[2]}}))}))},t.prototype.logout=function(){return C(this,void 0,void 0,(function(){var t;return L(this,(function(e){switch(e.label){case 0:return t=J(),[4,this.identify(t)];case 1:return e.sent(),[2,t]}}))}))},t.prototype.bootstrap=function(t,e){return C(this,void 0,void 0,(function(){var n,i;return L(this,(function(o){switch(o.label){case 0:if((t=t||this._option.bootstrap)&&t.length>0&&(n={featureFlags:t.reduce((function(t,e){var n=e.id,i=e.variation,o=e.timestamp,a=e.variationOptions,u=e.sendToExperiment,s=e.variationType;return t[n]={id:n,variation:i,timestamp:o,variationOptions:a||[{id:1,value:i}],sendToExperiment:u,variationType:s||r.string},t}),{})},T.setFullData(n),h.logDebug("bootstrapped with full data")),!this._option.enableDataSync)return[3,4];o.label=1;case 1:return o.trys.push([1,3,,4]),[4,this.dataSync(e)];case 2:return o.sent(),[3,4];case 3:return i=o.sent(),h.log("data sync error",i),[3,4];case 4:return this._readyEventEmitted||(this._readyEventEmitted=!0,a.emit("ready",B(T.getFeatureFlags()))),[2]}}))}))},t.prototype.dataSync=function(t){return C(this,void 0,void 0,(function(){var e=this;return L(this,(function(n){return[2,new Promise((function(n,o){var a=t?0:Math.max.apply(Math,z(z([],Object.values(T.getFeatureFlags()).map((function(t){return t.timestamp})),!1),[0],!1));N.createConnection(a,(function(t){var o;if(t&&t.userKeyId===(null===(o=e._option.user)||void 0===o?void 0:o.keyId)){var a=t.featureFlags;switch(t.eventType){case i.full:case i.patch:var u={featureFlags:a.reduce((function(t,e){var n=e.id,i=e.variation,o=e.timestamp,a=e.variationOptions,u=e.sendToExperiment,s=e.variationType;return t[n]={id:n,variation:i,timestamp:o,variationOptions:a,sendToExperiment:u,variationType:s||r.string},t}),{})};t.eventType===i.full?(T.setFullData(u),h.logDebug("synchonized with full data")):(T.updateBulkFromRemote(u),h.logDebug("synchonized with partial data"));break;default:h.logDebug("invalid stream event type: "+t.eventType)}}n()}))}))]}))}))},t.prototype.variation=function(t,e){var n=Q(t,e);return void 0===n?e:n},t.prototype.boolVariation=function(t,e){var n=Q(t,e);return void 0===n?e:"true"===(null==n?void 0:n.toLocaleLowerCase())},t.prototype.getUser=function(){return A({},this._option.user)},t.prototype.sendCustomEvent=function(t){var e=this;(t||[]).forEach((function(t){return e._insightsQueue.add(A({insightType:n.customEvent,timestamp:Date.now(),type:"CustomEvent"},t))}))},t.prototype.sendFeatureFlagInsight=function(t,e){this.variation(t,e)},t.prototype.getAllFeatureFlags=function(){var t=T.getFeatureFlags();return Object.values(t).reduce((function(t,e){return t[e.id]=y(e.variationType,e.variation),t}),{})},t}(),Q=function(t,e){var n=T.getVariation(t);return void 0===n&&a.emit(c,{id:t,timestamp:Date.now(),variationValue:"".concat(e)}),n};const R=new q;var K=document.querySelector("html");return K&&(K.style.visibility="hidden",setTimeout((function(){return K.style.visibility="visible"}),500)),h.logDebug("version: 2.0.0"),e})()));
|
|
1
|
+
!function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var n=e();for(var r in n)("object"==typeof exports?exports:t)[r]=n[r]}}(this,(()=>(()=>{"use strict";var t={d:(e,n)=>{for(var r in n)t.o(n,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{fbClient:()=>q});var n,r,i,o,a=new(function(){function t(t){this.events=t||{}}return t.prototype.subscribe=function(t,e){var n=this;return(this.events[t]||(this.events[t]=[])).push(e),{unsubscribe:function(){return n.events[t]&&n.events[t].splice(n.events[t].indexOf(e)>>>0,1)}}},t.prototype.unsubscribe=function(t,e){this.events[t]&&this.events[t].splice(this.events[t].indexOf(e)>>>0,1)},t.prototype.emit=function(t){for(var e=[],n=1;n<arguments.length;n++)e[n-1]=arguments[n];(this.events[t]||[]).forEach((function(t){return t.apply(void 0,e)}))},t}()),u={logDebug:function(){for(var t=[],e=0;e<arguments.length;e++)t[e]=arguments[e]},log:function(){for(var t=[],e=0;e<arguments.length;e++)t[e]=arguments[e];console.log.apply(console,t)}},s="insights.flush",c="featureflag.evaluated.topic",l="featureflag.evaluated.buffer.topic",f="network.websocket.reconnect",p="fb-user";!function(t){t[t.featureFlagUsage=1]="featureFlagUsage",t[t.customEvent=2]="customEvent",t[t.pageView=3]="pageView",t[t.click=4]="click"}(n||(n={})),function(t){t.string="string",t.boolean="boolean",t.number="number",t.json="json"}(r||(r={})),function(t){t.full="full",t.patch="patch"}(i||(i={})),function(t){t.update="update"}(o||(o={}));const d=function(){function t(){}return t.partialEndpoint=function(t){return"You have set custom uris without specifying the ".concat(t," URI; connections may not work properly")},t.invalidParam=function(t){return"The ".concat(t," option is not passed in or its value is invalid")},t.mandatory=function(t){return"".concat(t," is mandatory")},t}();function h(t){var e;if(!t)return"";var n="".concat(t.keyId,",").concat(t.name),r=null===(e=t.customizedProperties)||void 0===e?void 0:e.map((function(t){return"".concat(t.name,":").concat(t.value)})).join(",");return"".concat(n,",").concat(r)}function v(t,e){switch(t){case r.string:return e;case r.boolean:return"true"===e||"false"!==e&&(u.log("expected boolean value, but got ".concat(e)),e);case r.number:return"string"!=typeof(n=e)||isNaN(n)||isNaN(parseFloat(n))?(u.log("expected numeric value, but got ".concat(e)),e):+e;case r.json:try{return JSON.parse(e)}catch(t){return u.log("expected json value, but got ".concat(e)),e}default:return u.log("unexpected variation type ".concat(t," for ").concat(e)),e}var n}function g(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(t){var e=16*Math.random()|0;return("x"==t?e:3&e|8).toString(16)}))}function y(t){if(!t)return d.mandatory("user");var e=t.keyId,n=t.name;return null==e||""===e.trim()?d.mandatory("user.keyId"):null==n||""===n.trim()?d.mandatory("user.name"):null}function m(t){return null==t||""===t.trim()}var b={0:"Q",1:"B",2:"W",3:"S",4:"P",5:"H",6:"D",7:"X",8:"Z",9:"U"};function w(t,e){var n="000000000000"+t;return n.slice(n.length-e).split("").map((function(t){return b[t]})).join("")}var x="fb-datastore",_=function(){function t(){this._userId=null,this._store={featureFlags:{}}}return Object.defineProperty(t.prototype,"userId",{set:function(t){this._userId=t,this._loadFromStorage()},enumerable:!1,configurable:!0}),t.prototype.getFeatureFlag=function(t){return this._store.featureFlags[t]},t.prototype.getVariation=function(t){var e=this._store.featureFlags[t];if(e)return a.emit(c,{insightType:n.featureFlagUsage,id:e.id,timestamp:Date.now(),sendToExperiment:e.sendToExperiment,variation:e.variationOptions.find((function(t){return t.value===e.variation}))}),v(e.variationType,e.variation)},t.prototype.setFullData=function(t){this._store={featureFlags:{}},this._dumpToStorage(this._store),this.updateBulkFromRemote(t)},t.prototype.getFeatureFlags=function(){return this._store.featureFlags},t.prototype.updateStorageBulk=function(t,e,n){var r=localStorage.getItem(e),i=null;try{r&&r.trim().length>0&&(i=JSON.parse(r))}catch(t){u.logDebug("error while loading local data store: ".concat(e)+t)}if(i){var o=t.featureFlags;Object.keys(o).forEach((function(t){var e=o[t];(!i.featureFlags[t]||!n)&&(i.featureFlags[e.id]=Object.assign({},e))})),this._dumpToStorage(i,e)}},t.prototype.updateBulkFromRemote=function(t){var e="".concat(x,"-").concat(this._userId);this.updateStorageBulk(t,e,!1),this._loadFromStorage()},t.prototype._emitUpdateEvents=function(t){t.length>0&&(t.forEach((function(t){t.id;var e=t.operation,n=t.data;return a.emit("ff_".concat(e,":").concat(n.id),n)})),a.emit("ff_".concat(o.update),t.map((function(t){return t.data}))))},t.prototype._dumpToStorage=function(t,e){if(t){var n=e||"".concat(x,"-").concat(this._userId);localStorage.setItem(n,JSON.stringify(t))}else{var r="".concat(x,"-").concat(this._userId);localStorage.setItem(r,JSON.stringify(this._store))}},t.prototype._loadFromStorage=function(){var t=this;try{var e="".concat(x,"-").concat(this._userId),n=localStorage.getItem(e);if(n&&n.trim().length>0){var r=JSON.parse(n),i=Object.keys(r.featureFlags).filter((function(e){var n=r.featureFlags[e],i=t._store.featureFlags[e];return!i||n.variation!==i.variation||n.variationType!==i.variationType})).map((function(e){var n=r.featureFlags[e],i=t._store.featureFlags[e];return{id:e,operation:o.update,sendToExperiment:n.sendToExperiment,data:{id:e,oldValue:i?v(i.variationType,i.variation):void 0,newValue:v(n.variationType,n.variation)}}}));this._store=r,this._emitUpdateEvents(i)}else this._store={featureFlags:{}}}catch(t){u.logDebug("error while loading local data store: "+t)}},t}();const k=new _;var T=function(){return T=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var i in e=arguments[n])Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},T.apply(this,arguments)},S={},F=[];const E=new(function(){function t(){this._key=g()}return t.prototype.setKey=function(t){this._key=t||this._key},t.prototype.throttle=function(t,e){var n=0;return function(){for(var r=[],i=0;i<arguments.length;i++)r[i]=arguments[i];clearTimeout(n),n=setTimeout(t.bind.apply(t,function(t,e,n){if(n||2===arguments.length)for(var r,i=0,o=e.length;i<o;i++)!r&&i in e||(r||(r=Array.prototype.slice.call(e,0,i)),r[i]=e[i]);return t.concat(r||Array.prototype.slice.call(e))}([null],r,!1)),e||0)}},t.prototype.throttleAsync=function(t){var e=this,n=!1;return function(){for(var r=[],i=0;i<arguments.length;i++)r[i]=arguments[i];return o=this,a=void 0,s=function(){var i,o,a,u;return function(t,e){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function u(u){return function(s){return function(u){if(n)throw new TypeError("Generator is already executing.");for(;o&&(o=0,u[0]&&(a=0)),a;)try{if(n=1,r&&(i=2&u[0]?r.return:u[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,u[1])).done)return i;switch(r=0,i&&(u=[2&u[0],i.value]),u[0]){case 0:case 1:i=u;break;case 4:return a.label++,{value:u[1],done:!1};case 5:a.label++,r=u[1],u=[0];continue;case 7:u=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==u[0]&&2!==u[0])){a=0;continue}if(3===u[0]&&(!i||u[1]>i[0]&&u[1]<i[3])){a.label=u[1];break}if(6===u[0]&&a.label<i[1]){a.label=i[1],i=u;break}if(i&&a.label<i[2]){a.label=i[2],a.ops.push(u);break}i[2]&&a.ops.pop(),a.trys.pop();continue}u=e.call(t,a)}catch(t){u=[6,t],r=0}finally{n=i=0}if(5&u[0])throw u[1];return{value:u[0]?u[1]:void 0,done:!0}}([u,s])}}}(this,(function(s){switch(s.label){case 0:return i=function(t){var n=t.map((function(t){return"object"==typeof t&&"function"!=typeof t&&null!==t?Array.isArray(t)?t.map((function(t){return T(T({},t),{timestamp:null})})):T(T({},t),{timestamp:null}):t}));return e._key+JSON.stringify(n)}(r),o=F.findIndex((function(t){return t===i})),n&&-1!==o?[3,2]:(n=!0,-1===o&&F.push(i),a=S,u=i,[4,t.apply(null,r)]);case 1:a[u]=s.sent(),setTimeout((function(){n=!1}),0),s.label=2;case 2:return[2,S[i]]}}))},new((u=void 0)||(u=Promise))((function(t,e){function n(t){try{i(s.next(t))}catch(t){e(t)}}function r(t){try{i(s.throw(t))}catch(t){e(t)}}function i(e){var i;e.done?t(e.value):(i=e.value,i instanceof u?i:new u((function(t){t(i)}))).then(n,r)}i((s=s.apply(o,a||[])).next())}));var o,a,u,s}},t}());var O=function(){return O=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var i in e=arguments[n])Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},O.apply(this,arguments)},D=function(t,e,n,r){return new(n||(n=Promise))((function(i,o){function a(t){try{s(r.next(t))}catch(t){o(t)}}function u(t){try{s(r.throw(t))}catch(t){o(t)}}function s(t){var e;t.done?i(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(a,u)}s((r=r.apply(t,e||[])).next())}))},I=function(t,e){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function u(u){return function(s){return function(u){if(n)throw new TypeError("Generator is already executing.");for(;o&&(o=0,u[0]&&(a=0)),a;)try{if(n=1,r&&(i=2&u[0]?r.return:u[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,u[1])).done)return i;switch(r=0,i&&(u=[2&u[0],i.value]),u[0]){case 0:case 1:i=u;break;case 4:return a.label++,{value:u[1],done:!1};case 5:a.label++,r=u[1],u=[0];continue;case 7:u=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==u[0]&&2!==u[0])){a=0;continue}if(3===u[0]&&(!i||u[1]>i[0]&&u[1]<i[3])){a.label=u[1];break}if(6===u[0]&&a.label<i[1]){a.label=i[1],i=u;break}if(i&&a.label<i[2]){a.label=i[2],a.ops.push(u);break}i[2]&&a.ops.pop(),a.trys.pop();continue}u=e.call(t,a)}catch(t){u=[6,t],r=0}finally{n=i=0}if(5&u[0])throw u[1];return{value:u[0]?u[1]:void 0,done:!0}}([u,s])}}},j=[250,500,1e3,2e3,4e3,8e3],P=new(function(){function t(){var t=this;this.retryCounter=0,this.sendInsights=E.throttleAsync((function(e){return D(t,void 0,void 0,(function(){var t,r,i=this;return I(this,(function(o){switch(o.label){case 0:if(!this.secret||!this.user||!e||0===e.length)return[2];o.label=1;case 1:return o.trys.push([1,3,,4]),t=[{user:this.__getUserInfo(),variations:e.filter((function(t){return t.insightType===n.featureFlagUsage})).map((function(t){return{featureFlagKey:t.id,sendToExperiment:t.sendToExperiment,timestamp:t.timestamp,variation:{id:t.variation.id,value:t.variation.value}}})),metrics:e.filter((function(t){return t.insightType!==n.featureFlagUsage})).map((function(t){return{route:location.pathname,timestamp:t.timestamp,numericValue:null===t.numericValue||void 0===t.numericValue?1:t.numericValue,appType:i.appType,eventName:t.eventName,type:t.type}}))}],[4,U("".concat(this.eventsUri,"/api/public/insight/track"),t,{Authorization:this.secret})];case 2:return o.sent(),[3,4];case 3:return r=o.sent(),u.logDebug(r),[3,4];case 4:return[2]}}))}))}))}return t.prototype.init=function(t,e,n,r){this.streamingUri=t,this.eventsUri=e,this.secret=n,this.appType=r},t.prototype.identify=function(t,e){var n;this.user=O({},t),E.setKey(null===(n=this.user)||void 0===n?void 0:n.keyId),e&&this.socket&&this.sendUserIdentifyMessage(0)},t.prototype.sendUserIdentifyMessage=function(t){var e,n,r=this.user,i={messageType:"data-sync",data:{user:{name:r.name,keyId:r.keyId,customizedProperties:r.customizedProperties},timestamp:t}};try{(null===(e=this.socket)||void 0===e?void 0:e.readyState)===WebSocket.OPEN?(u.logDebug("sending user identify message"),null===(n=this.socket)||void 0===n||n.send(JSON.stringify(i))):u.logDebug("didn't send user identify message because socket not open")}catch(t){u.logDebug(t)}},t.prototype.reconnect=function(){this.socket=null;var t=j[Math.min(this.retryCounter++,j.length-1)];setTimeout((function(){u.logDebug("emit reconnect event"),a.emit(f,{})}),t),u.logDebug(t)},t.prototype.sendPingMessage=function(){var t=this,e={messageType:"ping",data:null};setTimeout((function(){var n;try{(null===(n=t.socket)||void 0===n?void 0:n.readyState)===WebSocket.OPEN?(u.logDebug("sending ping"),t.socket.send(JSON.stringify(e)),t.sendPingMessage()):(u.logDebug("socket closed at ".concat(new Date)),t.reconnect())}catch(t){u.logDebug(t)}}),18e3)},t.prototype.createConnection=function(t,e){var n=this;if(n.socket)e({});else{var r=Date.now(),i="".concat(this.streamingUri,"/streaming?type=client&token=").concat(function(t){t=t.replace(/=*$/,"");var e=Date.now(),n=w(e,e.toString().length),r=Math.max(Math.floor(Math.random()*t.length),2);return"".concat(w(r,3)).concat(w(n.length,2)).concat(t.slice(0,r)).concat(n).concat(t.slice(r))}(this.secret));n.socket=new WebSocket(i),n.socket.addEventListener("open",(function(e){n.retryCounter=0,u.logDebug("Connection time: ".concat(Date.now()-r," ms")),n.sendUserIdentifyMessage(t),n.sendPingMessage()})),n.socket.addEventListener("close",(function(t){u.logDebug("close"),4003!==t.code&&n.reconnect()})),n.socket.addEventListener("error",(function(t){u.logDebug("error")})),n.socket.addEventListener("message",(function(t){var n=JSON.parse(t.data);"data-sync"===n.messageType&&(e(n.data),n.data.featureFlags.length>0&&u.logDebug("socket push update time(ms): ",Date.now()-n.data.featureFlags[0].timestamp))}))}},t.prototype.__getUserInfo=function(){var t=this.user;return{name:t.name,keyId:t.keyId,customizedProperties:t.customizedProperties}},t}());function U(t,e,n){return void 0===t&&(t=""),void 0===e&&(e={}),void 0===n&&(n={}),D(this,void 0,void 0,(function(){var r,i;return I(this,(function(o){switch(o.label){case 0:return o.trys.push([0,2,,3]),[4,fetch(t,{method:"POST",headers:Object.assign({"Content-Type":"application/json"},n),body:JSON.stringify(e)})];case 1:return[2,200===(r=o.sent()).status?r.json():{}];case 2:return i=o.sent(),u.logDebug(i),[2,{}];case 3:return[2]}}))}))}var N=function(){function t(t,e){void 0===t&&(t=0),void 0===e&&(e=""),this.flushLimit=t,this.arriveflushLimitTopic=e,this.queue=[]}return t.prototype.add=function(t){this.queue.push(t),this.flushLimit>0&&this.queue.length>=this.flushLimit&&a.emit(this.arriveflushLimitTopic,{})},t.prototype.flush=function(){var t=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,o=e.length;i<o;i++)!r&&i in e||(r||(r=Array.prototype.slice.call(e,0,i)),r[i]=e[i]);return t.concat(r||Array.prototype.slice.call(e))}([],this.queue,!0);return this.queue=[],t},t}(),M=function(){return M=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var i in e=arguments[n])Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},M.apply(this,arguments)},V=function(t,e,n,r){return new(n||(n=Promise))((function(i,o){function a(t){try{s(r.next(t))}catch(t){o(t)}}function u(t){try{s(r.throw(t))}catch(t){o(t)}}function s(t){var e;t.done?i(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(a,u)}s((r=r.apply(t,e||[])).next())}))},A=function(t,e){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function u(u){return function(s){return function(u){if(n)throw new TypeError("Generator is already executing.");for(;o&&(o=0,u[0]&&(a=0)),a;)try{if(n=1,r&&(i=2&u[0]?r.return:u[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,u[1])).done)return i;switch(r=0,i&&(u=[2&u[0],i.value]),u[0]){case 0:case 1:i=u;break;case 4:return a.label++,{value:u[1],done:!1};case 5:a.label++,r=u[1],u=[0];continue;case 7:u=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==u[0]&&2!==u[0])){a=0;continue}if(3===u[0]&&(!i||u[1]>i[0]&&u[1]<i[3])){a.label=u[1];break}if(6===u[0]&&a.label<i[1]){a.label=i[1],i=u;break}if(i&&a.label<i[2]){a.label=i[2],a.ops.push(u);break}i[2]&&a.ops.pop(),a.trys.pop();continue}u=e.call(t,a)}catch(t){u=[6,t],r=0}finally{n=i=0}if(5&u[0])throw u[1];return{value:u[0]?u[1]:void 0,done:!0}}([u,s])}}},C=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,o=e.length;i<o;i++)!r&&i in e||(r||(r=Array.prototype.slice.call(e,0,i)),r[i]=e[i]);return t.concat(r||Array.prototype.slice.call(e))};function L(){var t=function(){var t=localStorage.getItem("fb-guid");if(t)return t;var e=g();return localStorage.setItem("fb-guid",e),e}();return{name:t,keyId:t}}function z(t){return Object.keys(t).map((function(e){var n=t[e],i=n.id,o=n.variation,a=t[e].variationType||r.string;return{id:i,variation:v(a,o),variationType:a}}))}var J=function(){function t(){var t=this;this._readyEventEmitted=!1,this._insightsQueue=new N(1,s),this._featureFlagEvaluationBuffer=new N,this._option={secret:"",api:"",streamingUri:"",eventsUri:"",enableDataSync:!0,appType:"javascript"},this._readyPromise=new Promise((function(e,r){t.on("ready",(function(){var r=k.getFeatureFlags();if(e(z(r)),t._option.enableDataSync){var i=t._featureFlagEvaluationBuffer.flush().map((function(t){var e=r[t.id];if(!e)return u.log("Called unexisting feature flag: ".concat(t.id)),null;var i=e.variationOptions.find((function(e){return e.value===t.variationValue}));return i?u.logDebug("Sent buffered insight for feature flag: ".concat(t.id," with variation: ").concat(i.value)):u.log("Sent buffered insight for feature flag: ".concat(t.id," with unexisting default variation: ").concat(t.variationValue)),{insightType:n.featureFlagUsage,id:e.id,timestamp:t.timestamp,sendToExperiment:e.sendToExperiment,variation:i||{id:-1,value:t.variationValue}}}));P.sendInsights(i.filter((function(t){return!!t})))}}))})),a.subscribe(f,(function(){return V(t,void 0,void 0,(function(){var t;return A(this,(function(e){switch(e.label){case 0:return e.trys.push([0,2,,3]),u.logDebug("reconnecting"),[4,this.dataSync()];case 1:return e.sent(),this._readyEventEmitted||(this._readyEventEmitted=!0,a.emit("ready",z(k.getFeatureFlags()))),[3,3];case 2:return t=e.sent(),u.log("data sync error",t),[3,3];case 3:return[2]}}))}))})),a.subscribe(l,(function(e){t._featureFlagEvaluationBuffer.add(e)})),a.subscribe(s,(function(){t._option.enableDataSync&&P.sendInsights(t._insightsQueue.flush())})),a.subscribe(c,(function(e){t._insightsQueue.add(e)})),a.subscribe("insights.topic",(function(e){t._insightsQueue.add(e)}))}return t.prototype.on=function(t,e){a.subscribe(t,e)},t.prototype.off=function(t,e){a.unsubscribe(t,e)},t.prototype.waitUntilReady=function(){return this._readyPromise},t.prototype.init=function(t){var e;return V(this,void 0,void 0,(function(){var n;return A(this,(function(r){switch(r.label){case 0:return n=function(t){if(null==t)return d.mandatory("option");var e=t.streamingUri,n=t.eventsUri,r=t.secret,i=t.anonymous,o=t.user,a=t.enableDataSync,u=m(e),s=m(n);if(a&&(u||s)){if(s)return d.partialEndpoint("eventsUri");if(u)return d.partialEndpoint("streamingUri")}return a&&m(r)?d.invalidParam("secret"):0!=!!i||o?o?y(o):null:d.mandatory("user")}(M(M({},this._option),t)),null!==n?(u.log(n),[2]):(this._option=M(M(M({},this._option),t),{api:null===(e=t.api||this._option.api)||void 0===e?void 0:e.replace(/\/$/,"")}),this._option.enableDataSync&&P.init(this._option.streamingUri,this._option.eventsUri,this._option.secret,this._option.appType),[4,this.identify(t.user||L())]);case 1:return r.sent(),[2]}}))}))},t.prototype.identify=function(t){var e;return V(this,void 0,void 0,(function(){var n,r;return A(this,(function(i){switch(i.label){case 0:return null!==(n=y(t))?(u.log(n),[2]):(t.customizedProperties=null===(e=t.customizedProperties)||void 0===e?void 0:e.map((function(t){return{name:t.name,value:"".concat(t.value)}})),r=h(t)!==localStorage.getItem(p),this._option.user=Object.assign({},t),localStorage.setItem(p,h(this._option.user)),k.userId=this._option.user.keyId,P.identify(this._option.user,r),[4,this.bootstrap(this._option.bootstrap,r)]);case 1:return i.sent(),[2]}}))}))},t.prototype.logout=function(){return V(this,void 0,void 0,(function(){var t;return A(this,(function(e){switch(e.label){case 0:return t=L(),[4,this.identify(t)];case 1:return e.sent(),[2,t]}}))}))},t.prototype.bootstrap=function(t,e){return V(this,void 0,void 0,(function(){var n,i;return A(this,(function(o){switch(o.label){case 0:if((t=t||this._option.bootstrap)&&t.length>0&&(n={featureFlags:t.reduce((function(t,e){var n=e.id,i=e.variation,o=e.timestamp,a=e.variationOptions,u=e.sendToExperiment,s=e.variationType;return t[n]={id:n,variation:i,timestamp:o,variationOptions:a||[{id:1,value:i}],sendToExperiment:u,variationType:s||r.string},t}),{})},k.setFullData(n),u.logDebug("bootstrapped with full data")),!this._option.enableDataSync)return[3,4];o.label=1;case 1:return o.trys.push([1,3,,4]),[4,this.dataSync(e)];case 2:return o.sent(),[3,4];case 3:return i=o.sent(),u.log("data sync error",i),[3,4];case 4:return this._readyEventEmitted||(this._readyEventEmitted=!0,a.emit("ready",z(k.getFeatureFlags()))),[2]}}))}))},t.prototype.dataSync=function(t){return V(this,void 0,void 0,(function(){var e=this;return A(this,(function(n){return[2,new Promise((function(n,o){var a=t?0:Math.max.apply(Math,C(C([],Object.values(k.getFeatureFlags()).map((function(t){return t.timestamp})),!1),[0],!1));P.createConnection(a,(function(t){var o;if(t&&t.userKeyId===(null===(o=e._option.user)||void 0===o?void 0:o.keyId)){var a=t.featureFlags;switch(t.eventType){case i.full:case i.patch:var s={featureFlags:a.reduce((function(t,e){var n=e.id,i=e.variation,o=e.timestamp,a=e.variationOptions,u=e.sendToExperiment,s=e.variationType;return t[n]={id:n,variation:i,timestamp:o,variationOptions:a,sendToExperiment:u,variationType:s||r.string},t}),{})};t.eventType===i.full?(k.setFullData(s),u.logDebug("synchonized with full data")):(k.updateBulkFromRemote(s),u.logDebug("synchonized with partial data"));break;default:u.logDebug("invalid stream event type: "+t.eventType)}}n()}))}))]}))}))},t.prototype.variation=function(t,e){var n=B(t,e);return void 0===n?e:n},t.prototype.boolVariation=function(t,e){var n=B(t,e);return void 0===n?e:"true"===(null==n?void 0:n.toLocaleLowerCase())},t.prototype.getUser=function(){return M({},this._option.user)},t.prototype.sendCustomEvent=function(t){var e=this;(t||[]).forEach((function(t){return e._insightsQueue.add(M({insightType:n.customEvent,timestamp:Date.now(),type:"CustomEvent"},t))}))},t.prototype.sendFeatureFlagInsight=function(t,e){this.variation(t,e)},t.prototype.getAllFeatureFlags=function(){var t=k.getFeatureFlags();return Object.values(t).reduce((function(t,e){return t[e.id]=v(e.variationType,e.variation),t}),{})},t}(),B=function(t,e){var n=k.getVariation(t);return void 0===n&&a.emit(l,{id:t,timestamp:Date.now(),variationValue:"".concat(e)}),n};const q=new J;var Q=document.querySelector("html");return Q&&(Q.style.visibility="hidden",setTimeout((function(){return Q.style.visibility="visible"}),500)),u.logDebug("version: 2.0.2"),e})()));
|
|
2
2
|
//# sourceMappingURL=featbit-js-client-sdk.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"featbit-js-client-sdk.js","mappings":"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","sources":["webpack://@featbit/js-client-sdk/webpack/universalModuleDefinition","webpack://@featbit/js-client-sdk/webpack/bootstrap","webpack://@featbit/js-client-sdk/webpack/runtime/define property getters","webpack://@featbit/js-client-sdk/webpack/runtime/hasOwnProperty shorthand","webpack://@featbit/js-client-sdk/webpack/runtime/make namespace object","webpack://@featbit/js-client-sdk/./src/events.ts","webpack://@featbit/js-client-sdk/./src/types.ts","webpack://@featbit/js-client-sdk/./src/constants.ts","webpack://@featbit/js-client-sdk/./src/logger.ts","webpack://@featbit/js-client-sdk/./src/optionMessages.ts","webpack://@featbit/js-client-sdk/./src/utils.ts","webpack://@featbit/js-client-sdk/./src/store.ts","webpack://@featbit/js-client-sdk/./src/throttleutil.ts","webpack://@featbit/js-client-sdk/./src/network.service.ts","webpack://@featbit/js-client-sdk/./src/queue.ts","webpack://@featbit/js-client-sdk/./src/featbit.ts","webpack://@featbit/js-client-sdk/./src/umd.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse {\n\t\tvar a = factory();\n\t\tfor(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n\t}\n})(this, () => {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","interface Events {\n [key: string]: Function[];\n}\n\nclass EventEmitter {\n public events: Events;\n constructor(events?: Events) {\n this.events = events || {};\n }\n\n public subscribe(name: string, cb: Function) {\n (this.events[name] || (this.events[name] = [])).push(cb);\n\n return {\n unsubscribe: () =>\n this.events[name] && this.events[name].splice(this.events[name].indexOf(cb) >>> 0, 1)\n };\n }\n\n public unsubscribe(name: string, cb: Function) {\n this.events[name] && this.events[name].splice(this.events[name].indexOf(cb) >>> 0, 1);\n }\n\n public emit(name: string, ...args: any[]): void {\n (this.events[name] || []).forEach(fn => fn(...args));\n }\n}\n\nexport const eventHub = new EventEmitter();","export type FeatureFlagValue = any;\n\nexport interface IFeatureFlagSet {\n [key: string]: FeatureFlagValue;\n}\n\nexport interface IFeatureFlagChange {\n id: string,\n oldValue: FeatureFlagValue,\n newValue: FeatureFlagValue\n}\n\nexport interface IOption {\n secret: string,\n anonymous?: boolean,\n bootstrap?: IFeatureFlag[],\n streamingUri?: string,\n eventsUri?: string,\n\n // deprecated, this option will be removed in the future, please use streamingUri and eventsUri instead\n api?: string,\n\n appType?: string,\n user?: IUser,\n enableDataSync?: boolean\n}\n\nexport interface IUser {\n name: string,\n keyId: string,\n customizedProperties?: ICustomizedProperty[]\n}\n\nexport interface ICustomizedProperty {\n name: string,\n value: string | number | boolean\n}\n\nexport interface IVariationOption {\n id: number,\n value: FeatureFlagValue\n}\n\nexport interface IFeatureFlagVariation {\n id?: string,\n sendToExperiment?: boolean\n timestamp?: number,\n variation?: {\n id: number,\n value: FeatureFlagValue,\n }\n}\n\nexport interface IFeatureFlagVariationBuffer {\n id: string,\n timestamp: number,\n variationValue: FeatureFlagValue\n}\n\nexport enum InsightType {\n featureFlagUsage = 1,\n customEvent = 2,\n pageView = 3,\n click = 4\n}\n\nexport enum VariationDataType {\n string = 'string',\n boolean = 'boolean',\n number = 'number',\n json = 'json',\n}\n\nexport interface IInsight extends IFeatureFlagVariation, ICustomEvent {\n insightType: InsightType\n}\n\nexport interface IFeatureFlagBase {\n id: string, // the keyname\n variation: FeatureFlagValue,\n variationType: VariationDataType\n}\n\nexport interface IFeatureFlag extends IFeatureFlagBase{\n sendToExperiment: boolean,\n timestamp: number,\n variationOptions: IVariationOption[]\n}\n\nexport interface IDataStore {\n featureFlags: { [key: string]: IFeatureFlag }\n}\n\nexport enum StreamResponseEventType {\n full = 'full',\n patch = 'patch'\n}\n\nexport enum FeatureFlagUpdateOperation {\n update = 'update'\n}\n\nexport interface IStreamResponse {\n eventType: StreamResponseEventType,\n userKeyId: string,\n featureFlags: IFeatureFlag[]\n}\n\nexport interface ICustomEvent {\n type?: string,\n eventName: string,\n numericValue?: number\n}","export const insightsFlushTopic = 'insights.flush';\nexport const featureFlagEvaluatedTopic = 'featureflag.evaluated.topic';\nexport const featureFlagEvaluatedBufferTopic = 'featureflag.evaluated.buffer.topic';\nexport const websocketReconnectTopic = 'network.websocket.reconnect';\nexport const debugModeQueryStr = 'debugmode'; // will print debug logs if true\nexport const insightsTopic = 'insights.topic';\nexport const currentUserStorageKey = 'fb-user';\n","import { debugModeQueryStr } from \"./constants\";\n\n// get debug mode from query string\nconst queryString = window.location.search;\nconst urlParams = new URLSearchParams(queryString);\nconst debugModeParam = urlParams.get(debugModeQueryStr);\n\nexport const logger = {\n logDebug(...args) {\n if (debugModeParam === 'true') {\n console.log(...args);\n }\n },\n\n log(...args) {\n console.log(...args);\n }\n}","export default class OptionMessages {\n static partialEndpoint(name: string): string {\n return `You have set custom uris without specifying the ${ name } URI; connections may not work properly`;\n }\n\n static invalidParam(name: string): string {\n return `The ${ name } option is not passed in or its value is invalid`;\n }\n\n static mandatory(name: string): string {\n return `${ name } is mandatory`;\n }\n}","import {FeatureFlagValue, IOption, IUser, VariationDataType} from \"./types\";\nimport {logger} from \"./logger\";\nimport OptionMessages from \"./optionMessages\";\n\n\n// generate default user info\nexport function generateorGetGuid(): string {\n let guid = localStorage.getItem(\"fb-guid\");\n if (guid) {\n return guid;\n }\n else {\n const id = uuid();\n localStorage.setItem(\"fb-guid\", id);\n return id;\n }\n}\n\nexport function serializeUser(user: IUser | undefined): string {\n if (!user) {\n return '';\n }\n\n const builtInProperties = `${user.keyId},${user.name}`;\n\n const customizedProperties = user.customizedProperties?.map(p => `${p.name}:${p.value}`).join(',');\n\n return `${builtInProperties},${customizedProperties}`;\n}\n\nexport function isNumeric(str: string) {\n if (typeof str != \"string\") return false // we only process strings!\n // @ts-ignore\n return !isNaN(str) && // use type coercion to parse the _entirety_ of the string (`parseFloat` alone does not do this)...\n !isNaN(parseFloat(str)) // ...and ensure strings of whitespace fail\n}\n\nexport function parseVariation(type: VariationDataType, value: string): FeatureFlagValue {\n switch (type) {\n case VariationDataType.string:\n return value;\n case VariationDataType.boolean:\n if (value === 'true') {\n return true;\n }\n\n if (value === 'false') {\n return false;\n }\n\n logger.log(`expected boolean value, but got ${value}`);\n return value;\n case VariationDataType.number:\n if (isNumeric(value)) {\n return +value;\n }\n\n logger.log(`expected numeric value, but got ${value}`);\n return value;\n case VariationDataType.json:\n try {\n return JSON.parse(value);\n }\n catch (e) {\n logger.log(`expected json value, but got ${value}`);\n return value;\n }\n default:\n logger.log(`unexpected variation type ${type} for ${value}`);\n return value;\n }\n}\n\nexport function uuid(): string {\n let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\n var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n\n return uuid;\n}\n\nexport function validateUser(user: IUser): string | null {\n if (!user) {\n return OptionMessages.mandatory('user')\n }\n\n const { keyId, name } = user;\n\n if (keyId === undefined || keyId === null || keyId.trim() === '') {\n return OptionMessages.mandatory('user.keyId');\n }\n\n if (name === undefined || name === null || name.trim() === '') {\n return OptionMessages.mandatory('user.name');\n }\n\n return null;\n}\n\nexport function isNullOrUndefinedOrWhiteSpace(value?: string): boolean {\n return value === null || value === undefined || value.trim() === '';\n}\n\nexport function validateOption(option: IOption): string | null {\n if (option === undefined || option === null) {\n return OptionMessages.mandatory('option')\n }\n\n const { streamingUri, eventsUri, secret, anonymous, user, enableDataSync } = option;\n\n const streamingUriMissing = isNullOrUndefinedOrWhiteSpace(streamingUri);\n const eventsUriMissing = isNullOrUndefinedOrWhiteSpace(eventsUri);\n\n if (enableDataSync && (streamingUriMissing || eventsUriMissing))\n {\n if (eventsUriMissing) {\n return OptionMessages.partialEndpoint('eventsUri');\n }\n\n if (streamingUriMissing) {\n return OptionMessages.partialEndpoint('streamingUri');\n }\n }\n\n if (enableDataSync && isNullOrUndefinedOrWhiteSpace(secret)) {\n return OptionMessages.invalidParam('secret');\n }\n\n // validate user\n if (!!anonymous === false && !user) {\n return OptionMessages.mandatory('user');\n }\n\n if (user) {\n return validateUser(user);\n }\n\n return null;\n}\n\n/********************** encode text begin *****************************/\nconst alphabet = {\n \"0\": \"Q\",\n \"1\": \"B\",\n \"2\": \"W\",\n \"3\": \"S\",\n \"4\": \"P\",\n \"5\": \"H\",\n \"6\": \"D\",\n \"7\": \"X\",\n \"8\": \"Z\",\n \"9\": \"U\",\n}\n\nfunction encodeNumber(param: number, length: number): string {\n var s = \"000000000000\" + param;\n const numberWithLeadingZeros = s.slice(s.length - length);\n return numberWithLeadingZeros.split('').map(n => alphabet[n]).join('');\n}\n\n// generate connection token\nexport function generateConnectionToken(text: string): string {\n text = text.replace(/=*$/, '');\n const timestamp = Date.now();\n const timestampCode = encodeNumber(timestamp, timestamp.toString().length);\n // get random number less than the length of the text as the start point, and it must be greater or equal to 2\n const start = Math.max(Math.floor(Math.random() * text.length), 2);\n\n return `${encodeNumber(start, 3)}${encodeNumber(timestampCode.length, 2)}${text.slice(0, start)}${timestampCode}${text.slice(start)}`;\n}\n\n/********************** encode text end *****************************/\n","import {featureFlagEvaluatedTopic} from \"./constants\";\nimport {eventHub} from \"./events\";\nimport {logger} from \"./logger\";\nimport {\n FeatureFlagUpdateOperation, FeatureFlagValue,\n IDataStore,\n IFeatureFlag,\n IFeatureFlagChange,\n InsightType\n} from \"./types\";\nimport {parseVariation} from \"./utils\";\n\nconst DataStoreStorageKey = 'fb-datastore';\n\nclass Store {\n private _userId: string | null = null;\n\n private _store: IDataStore = {\n featureFlags: {} as { [key: string]: IFeatureFlag }\n }\n\n constructor() { }\n\n set userId(id: string) {\n this._userId = id;\n this._loadFromStorage();\n }\n\n getFeatureFlag(key: string): IFeatureFlag {\n return this._store.featureFlags[key];\n }\n\n getVariation(key: string): FeatureFlagValue {\n const featureFlag = this._store.featureFlags[key];\n\n if (!featureFlag) {\n return undefined;\n }\n\n eventHub.emit(featureFlagEvaluatedTopic, {\n insightType: InsightType.featureFlagUsage,\n id: featureFlag.id,\n timestamp: Date.now(),\n sendToExperiment: featureFlag.sendToExperiment,\n variation: featureFlag.variationOptions.find(o => o.value === featureFlag.variation)\n });\n\n const { variationType, variation } = featureFlag;\n\n return parseVariation(variationType, variation);\n }\n\n setFullData(data: IDataStore) {\n this._store = {\n featureFlags: {} as { [key: string]: IFeatureFlag }\n };\n\n this._dumpToStorage(this._store);\n this.updateBulkFromRemote(data);\n }\n\n getFeatureFlags(): { [key: string]: IFeatureFlag } {\n return this._store.featureFlags;\n }\n\n updateStorageBulk(data: IDataStore, storageKey: string, onlyInsertNewElement: boolean) {\n let dataStoreStr = localStorage.getItem(storageKey);\n let store: IDataStore | null = null;\n\n try {\n if (dataStoreStr && dataStoreStr.trim().length > 0) {\n store = JSON.parse(dataStoreStr);\n }\n } catch (err) {\n logger.logDebug(`error while loading local data store: ${storageKey}` + err);\n }\n\n if (!!store) {\n const { featureFlags } = data;\n\n Object.keys(featureFlags).forEach(id => {\n const remoteFf = featureFlags[id];\n const localFf = store!.featureFlags[id];\n\n const predicate = !localFf || !onlyInsertNewElement;\n if (predicate) {\n store!.featureFlags[remoteFf.id] = Object.assign({}, remoteFf);\n }\n });\n\n this._dumpToStorage(store, storageKey);\n }\n }\n\n updateBulkFromRemote(data: IDataStore) {\n const storageKey = `${DataStoreStorageKey}-${this._userId}`;\n\n this.updateStorageBulk(data, storageKey, false);\n\n this._loadFromStorage();\n }\n\n private _emitUpdateEvents(updatedFeatureFlags: any[]): void {\n if (updatedFeatureFlags.length > 0) {\n updatedFeatureFlags.forEach(({ id, operation, data }) => eventHub.emit(`ff_${operation}:${data.id}`, data));\n eventHub.emit(`ff_${FeatureFlagUpdateOperation.update}`, updatedFeatureFlags.map(item => item.data));\n }\n }\n\n private _dumpToStorage(store?: IDataStore, localStorageKey?: string): void {\n if (store) {\n const storageKey = localStorageKey || `${DataStoreStorageKey}-${this._userId}`;\n localStorage.setItem(storageKey, JSON.stringify(store));\n return;\n }\n const storageKey = `${DataStoreStorageKey}-${this._userId}`;\n localStorage.setItem(storageKey, JSON.stringify(this._store));\n }\n\n private _loadFromStorage(): void {\n try {\n const storageKey = `${DataStoreStorageKey}-${this._userId}`;\n let dataStoreStr = localStorage.getItem(storageKey);\n\n let shouldDumpToStorage = false;\n\n if (dataStoreStr && dataStoreStr.trim().length > 0) {\n // compare _store and dataStoreStr data and send notification if different\n const storageData: IDataStore = JSON.parse(dataStoreStr);\n\n const updatedFeatureFlags = Object.keys(storageData.featureFlags).filter(key => {\n const storageFf = storageData.featureFlags[key];\n const ff = this._store.featureFlags[key];\n return !ff || storageFf.variation !== ff.variation || storageFf.variationType !== ff.variationType;\n }).map(key => {\n const storageFf = storageData.featureFlags[key];\n const ff = this._store.featureFlags[key];\n\n return {\n id: key,\n operation: FeatureFlagUpdateOperation.update,\n sendToExperiment: storageFf.sendToExperiment,\n data: {\n id: key,\n oldValue: ff ? parseVariation(ff.variationType, ff.variation): undefined,\n newValue: parseVariation(storageFf.variationType, storageFf.variation)\n } as IFeatureFlagChange\n }\n });\n\n this._store = storageData;\n this._emitUpdateEvents(updatedFeatureFlags);\n } else {\n this._store = {\n featureFlags: {} as { [key: string]: IFeatureFlag }\n };\n }\n\n if (shouldDumpToStorage) {\n this._dumpToStorage();\n }\n\n } catch (err) {\n logger.logDebug('error while loading local data store: ' + err);\n }\n }\n}\n\nexport default new Store();","import { uuid } from \"./utils\";\n\nconst API_CALL_RESULTS : {[key: string]: string} = {};\nconst FOOT_PRINTS: string[] = [];\nlet _throttleWait: number = 0; // send immediately\n\nclass ThrottleUtil {\n private _key: string;\n\n constructor(){\n this._key = uuid();\n }\n\n setKey(key: string) {\n this._key = key || this._key;\n }\n\n throttle(fn: Function, ms: number) {\n let timer:any = 0\n return function(...args) {\n clearTimeout(timer)\n timer = setTimeout(fn.bind(null, ...args), ms || 0)\n }\n }\n\n throttleAsync (callback: any): any {\n let waiting = false; \n \n let getFootprint = (args: any): string => {\n const params = args.map(arg => {\n if (\n typeof arg === 'object' &&\n typeof arg !== \"function\" &&\n arg !== null\n ) {\n if (Array.isArray(arg)) {\n return arg.map(a => ({...a, ...{timestamp: null}}))\n } else {\n return {...arg, ...{timestamp: null}};\n }\n }\n \n return arg;\n });\n \n return this._key + JSON.stringify(params);\n };\n \n return async function (...args) {\n const footprint = getFootprint(args);\n const idx = FOOT_PRINTS.findIndex(f => f === footprint);\n if (!waiting || idx === -1) {\n waiting = true;\n if (idx === -1) {\n FOOT_PRINTS.push(footprint);\n }\n \n API_CALL_RESULTS[footprint] = await callback.apply(null, args);\n \n setTimeout(function () {\n waiting = false;\n }, _throttleWait);\n }\n \n return API_CALL_RESULTS[footprint];\n }\n }\n}\n\nexport default new ThrottleUtil();\n\n\n","import { websocketReconnectTopic } from \"./constants\";\nimport { eventHub } from \"./events\";\nimport { logger } from \"./logger\";\nimport { IInsight, InsightType, IStreamResponse, IUser } from \"./types\";\nimport { generateConnectionToken } from \"./utils\";\nimport throttleUtil from \"./throttleutil\";\n\nconst socketConnectionIntervals = [250, 500, 1000, 2000, 4000, 8000];\n\nclass NetworkService {\n private user: IUser | undefined;\n private streamingUri: string | undefined;\n private eventsUri: string | undefined;\n private secret: string | undefined;\n private appType: string | undefined;\n\n private retryCounter = 0;\n\n constructor(){}\n\n init(streamingUri: string, eventsUri: string, secret: string, appType: string) {\n this.streamingUri = streamingUri;\n this.eventsUri = eventsUri;\n this.secret = secret;\n this.appType = appType;\n }\n\n identify(user: IUser, sendIdentifyMessage: boolean) {\n this.user = { ...user };\n throttleUtil.setKey(this.user?.keyId);\n\n if (sendIdentifyMessage && this.socket) {\n this.sendUserIdentifyMessage(0);\n }\n }\n\n private sendUserIdentifyMessage(timestamp: number) {\n const { name, keyId, customizedProperties } = this.user!;\n const payload = {\n messageType: 'data-sync',\n data: {\n user: {\n name,\n keyId,\n customizedProperties,\n },\n timestamp\n }\n };\n\n try {\n if (this.socket?.readyState === WebSocket.OPEN) {\n logger.logDebug('sending user identify message');\n this.socket?.send(JSON.stringify(payload));\n } else {\n logger.logDebug(`didn't send user identify message because socket not open`);\n }\n } catch (err) {\n logger.logDebug(err);\n }\n }\n\n private socket: WebSocket | undefined | any;\n\n private reconnect() {\n this.socket = null;\n const waitTime = socketConnectionIntervals[Math.min(this.retryCounter++, socketConnectionIntervals.length - 1)];\n setTimeout(() => {\n logger.logDebug('emit reconnect event');\n eventHub.emit(websocketReconnectTopic, {});\n }, waitTime);\n logger.logDebug(waitTime);\n }\n\n private sendPingMessage() {\n const payload = {\n messageType: 'ping',\n data: null\n };\n\n setTimeout(() => {\n try {\n if (this.socket?.readyState === WebSocket.OPEN) {\n logger.logDebug('sending ping')\n this.socket.send(JSON.stringify(payload));\n this.sendPingMessage();\n } else {\n logger.logDebug(`socket closed at ${new Date()}`);\n this.reconnect();\n }\n } catch (err) {\n logger.logDebug(err);\n }\n }, 18000);\n }\n\n createConnection(timestamp: number, onMessage: (response: IStreamResponse) => any) {\n const that = this;\n if (that.socket) {\n onMessage({} as IStreamResponse);\n return;\n }\n\n const startTime = Date.now();\n // Create WebSocket connection.\n const url = `${this.streamingUri}/streaming?type=client&token=${generateConnectionToken(this.secret!)}`;\n that.socket = new WebSocket(url);\n\n // Connection opened\n that.socket.addEventListener('open', function (this: WebSocket, event) {\n that.retryCounter = 0;\n // this is the websocket instance to which the current listener is binded to, it's different from that.socket\n logger.logDebug(`Connection time: ${Date.now() - startTime} ms`);\n that.sendUserIdentifyMessage(timestamp);\n that.sendPingMessage();\n });\n \n // Connection closed\n that.socket.addEventListener('close', function (event) {\n logger.logDebug('close');\n if (event.code === 4003) { // do not reconnect when 4003\n return;\n }\n\n that.reconnect();\n });\n \n // Connection error\n that.socket!.addEventListener('error', function (event) {\n // reconnect\n logger.logDebug('error');\n });\n \n // Listen for messages\n that.socket.addEventListener('message', function (event) {\n const message = JSON.parse(event.data);\n if (message.messageType === 'data-sync') {\n onMessage(message.data);\n if (message.data.featureFlags.length > 0) {\n logger.logDebug('socket push update time(ms): ', Date.now() - message.data.featureFlags[0].timestamp);\n }\n }\n });\n }\n\n private __getUserInfo(): any {\n const { name, keyId, customizedProperties } = this.user!;\n return {\n name: name,\n keyId: keyId,\n customizedProperties: customizedProperties,\n }\n }\n\n sendInsights = throttleUtil.throttleAsync(async (data: IInsight[]): Promise<void> => {\n if (!this.secret || !this.user || !data || data.length === 0) {\n return;\n }\n \n try {\n const payload = [{\n user: this.__getUserInfo(),\n variations: data.filter(d => d.insightType === InsightType.featureFlagUsage).map(v => ({\n featureFlagKey: v.id,\n sendToExperiment: v.sendToExperiment,\n timestamp: v.timestamp,\n variation: {\n id: v.variation!.id,\n value: v.variation!.value\n }\n })),\n metrics: data.filter(d => d.insightType !== InsightType.featureFlagUsage).map(d => ({\n route: location.pathname,\n timestamp: d.timestamp,\n numericValue: d.numericValue === null || d.numericValue === undefined? 1 : d.numericValue,\n appType: this.appType,\n eventName: d.eventName,\n type: d.type\n }))\n }];\n \n await post(`${this.eventsUri}/api/public/insight/track`, payload, { Authorization: this.secret });\n } catch (err) {\n logger.logDebug(err);\n }\n })\n}\n\nexport const networkService = new NetworkService();\n\nexport async function post(url: string = '', data: any = {}, headers: { [key: string]: string } = {}) {\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: Object.assign({\n 'Content-Type': 'application/json'\n }, headers),\n body: JSON.stringify(data) // body data type must match \"Content-Type\" header\n });\n\n return response.status === 200 ? response.json() : {};\n } catch (err) {\n logger.logDebug(err);\n return {};\n }\n}\n\nexport async function get(url: string = '', headers: { [key: string]: string } = {}) {\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: Object.assign({\n 'Accept': 'application/json',\n 'Content-Type': 'application/json'\n }, headers)\n });\n\n return response.status === 200 ? response.json() : {};\n } catch (err) {\n logger.logDebug(err);\n return null;\n }\n}\n","import { eventHub } from \"./events\";\n\nexport class Queue<T> {\n private queue: T[];\n // flushLimit === 0 means no limit\n // and \n constructor(private flushLimit: number = 0, private arriveflushLimitTopic: string = '') {\n this.queue = [];\n }\n\n add(element: T): void {\n this.queue.push(element);\n if (this.flushLimit > 0 && this.queue.length >= this.flushLimit) {\n eventHub.emit(this.arriveflushLimitTopic, {});\n }\n }\n\n flush(): T[] {\n const allElements = [...this.queue];\n this.queue = [];\n return allElements;\n }\n}","import { eventHub } from \"./events\";\nimport { logger } from \"./logger\";\nimport store from \"./store\";\nimport { networkService } from \"./network.service\";\nimport {\n FeatureFlagValue,\n ICustomEvent,\n IFeatureFlag,\n IFeatureFlagBase,\n IFeatureFlagSet,\n IFeatureFlagVariationBuffer,\n IInsight,\n InsightType,\n IOption,\n IStreamResponse,\n IUser,\n StreamResponseEventType,\n VariationDataType\n} from \"./types\";\nimport {\n generateorGetGuid,\n isNullOrUndefinedOrWhiteSpace,\n parseVariation,\n serializeUser,\n validateOption,\n validateUser\n} from \"./utils\";\nimport { Queue } from \"./queue\";\nimport {\n currentUserStorageKey,\n featureFlagEvaluatedBufferTopic,\n featureFlagEvaluatedTopic,\n insightsFlushTopic,\n insightsTopic,\n websocketReconnectTopic\n} from \"./constants\";\n\n\nfunction createOrGetAnonymousUser(): IUser {\n const sessionId = generateorGetGuid();\n\n return {\n name: sessionId,\n keyId: sessionId\n };\n}\n\nfunction mapFeatureFlagsToFeatureFlagBaseList(featureFlags: { [key: string]: IFeatureFlag }): IFeatureFlagBase[] {\n return Object.keys(featureFlags).map((cur) => {\n const {id, variation} = featureFlags[cur];\n const variationType = featureFlags[cur].variationType || VariationDataType.string;\n return {id, variation: parseVariation(variationType, variation), variationType};\n });\n}\n\nexport class FB {\n private _readyEventEmitted: boolean = false;\n private _readyPromise: Promise<IFeatureFlagBase[]>;\n\n private _insightsQueue: Queue<IInsight> = new Queue<IInsight>(1, insightsFlushTopic);\n private _featureFlagEvaluationBuffer: Queue<IFeatureFlagVariationBuffer> = new Queue<IFeatureFlagVariationBuffer>();\n private _option: IOption = {\n secret: '',\n api: '',\n streamingUri: '',\n eventsUri: '',\n enableDataSync: true,\n appType: 'javascript'\n };\n\n constructor() {\n this._readyPromise = new Promise<IFeatureFlagBase[]>((resolve, reject) => {\n this.on('ready', () => {\n const featureFlags = store.getFeatureFlags();\n resolve(mapFeatureFlagsToFeatureFlagBaseList(featureFlags));\n if (this._option.enableDataSync) {\n const buffered = this._featureFlagEvaluationBuffer.flush().map(f => {\n const featureFlag = featureFlags[f.id];\n if (!featureFlag) {\n logger.log(`Called unexisting feature flag: ${ f.id }`);\n return null;\n }\n\n const variation = featureFlag.variationOptions.find(o => o.value === f.variationValue);\n if (!variation) {\n logger.log(`Sent buffered insight for feature flag: ${ f.id } with unexisting default variation: ${ f.variationValue }`);\n } else {\n logger.logDebug(`Sent buffered insight for feature flag: ${ f.id } with variation: ${ variation.value }`);\n }\n\n return {\n insightType: InsightType.featureFlagUsage,\n id: featureFlag.id,\n timestamp: f.timestamp,\n sendToExperiment: featureFlag.sendToExperiment,\n variation: variation || {id: -1, value: f.variationValue}\n }\n });\n\n networkService.sendInsights(buffered.filter(x => !!x));\n }\n });\n });\n\n // reconnect to websocket\n eventHub.subscribe(websocketReconnectTopic, async () => {\n try {\n logger.logDebug('reconnecting');\n await this.dataSync();\n if (!this._readyEventEmitted) {\n this._readyEventEmitted = true;\n eventHub.emit('ready', mapFeatureFlagsToFeatureFlagBaseList(store.getFeatureFlags()));\n }\n } catch (err) {\n logger.log('data sync error', err);\n }\n });\n\n eventHub.subscribe(featureFlagEvaluatedBufferTopic, (data: IFeatureFlagVariationBuffer) => {\n this._featureFlagEvaluationBuffer.add(data);\n });\n\n // track feature flag usage data\n eventHub.subscribe(insightsFlushTopic, () => {\n if (this._option.enableDataSync) {\n networkService.sendInsights(this._insightsQueue.flush());\n }\n });\n\n eventHub.subscribe(featureFlagEvaluatedTopic, (data: IInsight) => {\n this._insightsQueue.add(data);\n });\n\n eventHub.subscribe(insightsTopic, (data: IInsight) => {\n this._insightsQueue.add(data);\n });\n }\n\n on(name: string, cb: Function) {\n eventHub.subscribe(name, cb);\n }\n\n off(name: string, cb: Function) {\n eventHub.unsubscribe(name, cb);\n }\n\n waitUntilReady(): Promise<IFeatureFlagBase[]> {\n return this._readyPromise;\n }\n\n async init(option: IOption) {\n const validateOptionResult = validateOption({...this._option, ...option});\n if (validateOptionResult !== null) {\n logger.log(validateOptionResult);\n return;\n }\n\n this._option = {\n ...this._option,\n ...option,\n ...{\n api: (option.api || this._option.api)?.replace(/\\/$/, '')\n }\n };\n\n if (this._option.enableDataSync) {\n networkService.init(this._option.streamingUri!, this._option.eventsUri!, this._option.secret, this._option.appType!);\n }\n\n await this.identify(option.user || createOrGetAnonymousUser());\n }\n\n async identify(user: IUser): Promise<void> {\n const validateUserResult = validateUser(user);\n if (validateUserResult !== null) {\n logger.log(validateUserResult);\n return;\n }\n\n user.customizedProperties = user.customizedProperties?.map(p => ({name: p.name, value: `${ p.value }`}));\n\n const isUserChanged = serializeUser(user) !== localStorage.getItem(currentUserStorageKey);\n this._option.user = Object.assign({}, user);\n localStorage.setItem(currentUserStorageKey, serializeUser(this._option.user));\n\n store.userId = this._option.user.keyId;\n networkService.identify(this._option.user, isUserChanged);\n\n await this.bootstrap(this._option.bootstrap, isUserChanged);\n }\n\n async logout(): Promise<IUser> {\n const anonymousUser = createOrGetAnonymousUser();\n await this.identify(anonymousUser);\n return anonymousUser;\n }\n\n /**\n * bootstrap with predefined feature flags.\n * @param {array} featureFlags the predefined feature flags.\n * @param {boolean} forceFullFetch if a forced full fetch should be made.\n * @return {Promise<void>} nothing.\n */\n async bootstrap(featureFlags?: IFeatureFlag[], forceFullFetch?: boolean): Promise<void> {\n featureFlags = featureFlags || this._option.bootstrap;\n if (featureFlags && featureFlags.length > 0) {\n const data = {\n featureFlags: featureFlags.reduce((res, curr) => {\n const {id, variation, timestamp, variationOptions, sendToExperiment, variationType} = curr;\n res[id] = {\n id,\n variation,\n timestamp,\n variationOptions: variationOptions || [{id: 1, value: variation}],\n sendToExperiment,\n variationType: variationType || VariationDataType.string\n };\n\n return res;\n }, {} as { [key: string]: IFeatureFlag })\n };\n\n store.setFullData(data);\n logger.logDebug('bootstrapped with full data');\n }\n\n if (this._option.enableDataSync) {\n // start data sync\n try {\n await this.dataSync(forceFullFetch);\n } catch (err) {\n logger.log('data sync error', err);\n }\n }\n\n if (!this._readyEventEmitted) {\n this._readyEventEmitted = true;\n eventHub.emit('ready', mapFeatureFlagsToFeatureFlagBaseList(store.getFeatureFlags()));\n }\n }\n\n private async dataSync(forceFullFetch?: boolean): Promise<any> {\n return new Promise<void>((resolve, reject) => {\n const timestamp = forceFullFetch ? 0 : Math.max(...Object.values(store.getFeatureFlags()).map(ff => ff.timestamp), 0);\n\n networkService.createConnection(timestamp, (message: IStreamResponse) => {\n if (message && message.userKeyId === this._option.user?.keyId) {\n const {featureFlags} = message;\n\n switch (message.eventType) {\n case StreamResponseEventType.full: // full data\n case StreamResponseEventType.patch: // partial data\n const data = {\n featureFlags: featureFlags.reduce((res, curr) => {\n const {id, variation, timestamp, variationOptions, sendToExperiment, variationType} = curr;\n res[id] = {\n id,\n variation,\n timestamp,\n variationOptions,\n sendToExperiment,\n variationType: variationType || VariationDataType.string\n };\n\n return res;\n }, {} as { [key: string]: IFeatureFlag })\n };\n\n if (message.eventType === StreamResponseEventType.full) {\n store.setFullData(data);\n logger.logDebug('synchonized with full data');\n } else {\n store.updateBulkFromRemote(data);\n logger.logDebug('synchonized with partial data');\n }\n\n break;\n default:\n logger.logDebug('invalid stream event type: ' + message.eventType);\n break;\n }\n }\n\n resolve();\n });\n });\n }\n\n variation(key: string, defaultResult: FeatureFlagValue): FeatureFlagValue {\n const variation = variationWithInsightBuffer(key, defaultResult);\n return variation === undefined ? defaultResult : variation;\n }\n\n /**\n * deprecated, you should use variation method directly\n */\n boolVariation(key: string, defaultResult: boolean): boolean {\n const variation = variationWithInsightBuffer(key, defaultResult);\n return variation === undefined ? defaultResult : variation?.toLocaleLowerCase() === 'true';\n }\n\n getUser(): IUser {\n return {...this._option.user!};\n }\n\n sendCustomEvent(data: ICustomEvent[]): void {\n (data || []).forEach(d => this._insightsQueue.add({\n insightType: InsightType.customEvent,\n timestamp: Date.now(),\n type: 'CustomEvent',\n ...d\n }))\n }\n\n sendFeatureFlagInsight(key: string, variation: string) {\n this.variation(key, variation);\n }\n\n getAllFeatureFlags(): IFeatureFlagSet {\n const flags = store.getFeatureFlags();\n\n return Object.values(flags).reduce((acc, curr) => {\n acc[curr.id] = parseVariation(curr.variationType, curr.variation);\n return acc;\n }, {});\n }\n}\n\nconst variationWithInsightBuffer = (key: string, defaultResult: string | boolean) => {\n const variation = store.getVariation(key);\n if (variation === undefined) {\n eventHub.emit(featureFlagEvaluatedBufferTopic, {\n id: key,\n timestamp: Date.now(),\n variationValue: `${ defaultResult }`\n } as IFeatureFlagVariationBuffer);\n }\n\n return variation;\n}\n\nexport default new FB();\n\n","// This file is only for umd version\n\nconst html = document.querySelector('html');\nconst waittime = 500;\nif (html) {\n html.style.visibility = 'hidden';\n setTimeout(() => html.style.visibility = 'visible', waittime);\n}\n\nimport fbClient from './featbit';\nimport { logger } from './logger';\n\nlogger.logDebug(`version: 2.0.0`);\n\nexport { fbClient }\n"],"names":["root","factory","exports","module","define","amd","a","i","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","InsightType","VariationDataType","StreamResponseEventType","FeatureFlagUpdateOperation","eventHub","events","subscribe","name","cb","push","unsubscribe","splice","indexOf","emit","forEach","fn","args","insightsFlushTopic","featureFlagEvaluatedTopic","featureFlagEvaluatedBufferTopic","websocketReconnectTopic","currentUserStorageKey","queryString","window","location","search","debugModeParam","URLSearchParams","logDebug","console","log","partialEndpoint","invalidParam","mandatory","serializeUser","user","builtInProperties","keyId","customizedProperties","map","p","join","parseVariation","type","string","boolean","number","str","isNaN","parseFloat","json","JSON","parse","e","uuid","replace","c","r","Math","random","toString","validateUser","trim","isNullOrUndefinedOrWhiteSpace","alphabet","encodeNumber","param","length","s","slice","split","n","DataStoreStorageKey","_userId","_store","featureFlags","id","_loadFromStorage","getFeatureFlag","getVariation","featureFlag","insightType","featureFlagUsage","timestamp","Date","now","sendToExperiment","variation","variationOptions","find","setFullData","data","_dumpToStorage","updateBulkFromRemote","getFeatureFlags","updateStorageBulk","storageKey","onlyInsertNewElement","dataStoreStr","localStorage","getItem","store","err","keys","remoteFf","assign","_emitUpdateEvents","updatedFeatureFlags","operation","update","item","localStorageKey","setItem","stringify","filter","storageFf","ff","variationType","oldValue","undefined","newValue","Store","API_CALL_RESULTS","FOOT_PRINTS","_key","setKey","throttle","ms","timer","clearTimeout","setTimeout","bind","throttleAsync","callback","waiting","footprint","params","arg","Array","isArray","getFootprint","idx","findIndex","f","apply","socketConnectionIntervals","networkService","retryCounter","sendInsights","secret","payload","__getUserInfo","variations","d","v","featureFlagKey","metrics","route","pathname","numericValue","appType","eventName","post","eventsUri","Authorization","init","streamingUri","identify","sendIdentifyMessage","socket","sendUserIdentifyMessage","messageType","readyState","WebSocket","OPEN","send","reconnect","waitTime","min","sendPingMessage","createConnection","onMessage","that","startTime","url","text","timestampCode","start","max","floor","generateConnectionToken","addEventListener","event","code","message","headers","fetch","method","body","response","status","flushLimit","arriveflushLimitTopic","queue","add","element","flush","allElements","createOrGetAnonymousUser","sessionId","guid","generateorGetGuid","mapFeatureFlagsToFeatureFlagBaseList","cur","_readyEventEmitted","_insightsQueue","Queue","_featureFlagEvaluationBuffer","_option","api","enableDataSync","_readyPromise","Promise","resolve","reject","on","buffered","variationValue","x","dataSync","off","waitUntilReady","option","validateOptionResult","anonymous","streamingUriMissing","eventsUriMissing","validateOption","validateUserResult","isUserChanged","userId","bootstrap","logout","anonymousUser","forceFullFetch","reduce","res","curr","values","userKeyId","eventType","full","patch","defaultResult","variationWithInsightBuffer","boolVariation","toLocaleLowerCase","getUser","sendCustomEvent","customEvent","sendFeatureFlagInsight","getAllFeatureFlags","flags","acc","FB","html","document","querySelector","style","visibility"],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"featbit-js-client-sdk.js","mappings":"CAAA,SAA2CA,EAAMC,GAChD,GAAsB,iBAAZC,SAA0C,iBAAXC,OACxCA,OAAOD,QAAUD,SACb,GAAqB,mBAAXG,QAAyBA,OAAOC,IAC9CD,OAAO,GAAIH,OACP,CACJ,IAAIK,EAAIL,IACR,IAAI,IAAIM,KAAKD,GAAuB,iBAAZJ,QAAuBA,QAAUF,GAAMO,GAAKD,EAAEC,EACvE,CACA,CATD,CASGC,MAAM,I,mBCRT,IAAIC,EAAsB,CCA1BA,EAAwB,CAACP,EAASQ,KACjC,IAAI,IAAIC,KAAOD,EACXD,EAAoBG,EAAEF,EAAYC,KAASF,EAAoBG,EAAEV,EAASS,IAC5EE,OAAOC,eAAeZ,EAASS,EAAK,CAAEI,YAAY,EAAMC,IAAKN,EAAWC,IAE1E,ECNDF,EAAwB,CAACQ,EAAKC,IAAUL,OAAOM,UAAUC,eAAeC,KAAKJ,EAAKC,GCClFT,EAAyBP,IACH,oBAAXoB,QAA0BA,OAAOC,aAC1CV,OAAOC,eAAeZ,EAASoB,OAAOC,YAAa,CAAEC,MAAO,WAE7DX,OAAOC,eAAeZ,EAAS,aAAc,CAAEsB,OAAO,GAAO,G,oCCD9D,ICuDYC,EAOAC,EA2BAC,EAKAC,EDtECC,EAAW,IAxBxB,WAEE,WAAYC,GACVtB,KAAKsB,OAASA,GAAU,CAAC,CAC3B,CAkBF,OAhBS,YAAAC,UAAP,SAAiBC,EAAcC,GAA/B,WAGE,OAFCzB,KAAKsB,OAAOE,KAAUxB,KAAKsB,OAAOE,GAAQ,KAAKE,KAAKD,GAE9C,CACLE,YAAa,WACX,SAAKL,OAAOE,IAAS,EAAKF,OAAOE,GAAMI,OAAO,EAAKN,OAAOE,GAAMK,QAAQJ,KAAQ,EAAG,EAAnF,EAEN,EAEO,YAAAE,YAAP,SAAmBH,EAAcC,GAC/BzB,KAAKsB,OAAOE,IAASxB,KAAKsB,OAAOE,GAAMI,OAAO5B,KAAKsB,OAAOE,GAAMK,QAAQJ,KAAQ,EAAG,EACrF,EAEO,YAAAK,KAAP,SAAYN,G,IAAc,yDACvBxB,KAAKsB,OAAOE,IAAS,IAAIO,SAAQ,SAAAC,GAAM,OAAAA,EAAE,aAAIC,EAAN,GAC1C,EACF,EAtBA,IEFa,EAAS,CAClBC,SAAQ,W,IAAC,qDAIT,EAEAC,IAAG,W,IAAC,sDACAC,QAAQD,IAAG,MAAXC,QAAeH,EACnB,GCXSI,EAAqB,iBACrBC,EAA4B,8BAC5BC,EAAkC,qCAClCC,EAA0B,8BAE1BC,EAAwB,WFsDrC,SAAYxB,GACV,2CACA,iCACA,2BACA,oBACD,CALD,CAAYA,IAAAA,EAAW,KAOvB,SAAYC,GACV,kBACA,oBACA,kBACA,aACD,CALD,CAAYA,IAAAA,EAAiB,KA2B7B,SAAYC,GACV,cACA,eACD,CAHD,CAAYA,IAAAA,EAAuB,KAKnC,SAAYC,GACV,iBACD,CAFD,CAAYA,IAAAA,EAA0B,K,QGlGtC,wBAYA,QAXS,EAAAsB,gBAAP,SAAuBlB,GACrB,MAAO,0DAAoDA,EAAI,0CACjE,EAEO,EAAAmB,aAAP,SAAoBnB,GAClB,MAAO,cAAQA,EAAI,mDACrB,EAEO,EAAAoB,UAAP,SAAiBpB,GACf,MAAO,UAAIA,EAAI,gBACjB,EACF,EAZA,GCkBO,SAASqB,EAAcC,G,MAC5B,IAAKA,EACH,MAAO,GAGT,IAAMC,EAAoB,UAAGD,EAAKE,MAAK,YAAIF,EAAKtB,MAE1CyB,EAAgD,QAAzB,EAAAH,EAAKG,4BAAoB,eAAEC,KAAI,SAAAC,GAAK,gBAAGA,EAAE3B,KAAI,YAAI2B,EAAEnC,MAAf,IAAwBoC,KAAK,KAE9F,MAAO,UAAGL,EAAiB,YAAIE,EACjC,CASO,SAASI,EAAeC,EAAyBtC,GACtD,OAAQsC,GACN,KAAKpC,EAAkBqC,OACrB,OAAOvC,EACT,KAAKE,EAAkBsC,QACrB,MAAc,SAAVxC,GAIU,UAAVA,IAIJ,EAAOmB,IAAI,0CAAmCnB,IACvCA,GACT,KAAKE,EAAkBuC,OACrB,MAtBc,iBADMC,EAuBN1C,IApBV2C,MAAMD,IACTC,MAAMC,WAAWF,KAuBlB,EAAOvB,IAAI,0CAAmCnB,IACvCA,IAJGA,EAKZ,KAAKE,EAAkB2C,KACrB,IACE,OAAOC,KAAKC,MAAM/C,EACpB,CACA,MAAOgD,GAEL,OADA,EAAO7B,IAAI,uCAAgCnB,IACpCA,CACT,CACF,QAEE,OADA,EAAOmB,IAAI,oCAA6BmB,EAAI,gBAAQtC,IAC7CA,EAvCN,IAAmB0C,CAyC1B,CAEO,SAASO,IAMd,MALW,uCAAuCC,QAAQ,SAAS,SAAUC,GAC3E,IAAIC,EAAoB,GAAhBC,KAAKC,SAAgB,EAC7B,OADyC,KAALH,EAAWC,EAAS,EAAJA,EAAU,GACrDG,SAAS,GACpB,GAGF,CAEO,SAASC,EAAa1B,GAC3B,IAAKA,EACH,OAAO,EAAeF,UAAU,QAG1B,IAAAI,EAAgBF,EAAI,MAAbtB,EAASsB,EAAI,KAE5B,OAAIE,SAA0D,KAAjBA,EAAMyB,OAC1C,EAAe7B,UAAU,cAG9BpB,SAAuD,KAAhBA,EAAKiD,OACvC,EAAe7B,UAAU,aAG3B,IACT,CAEO,SAAS8B,EAA8B1D,GAC5C,OAAOA,SAA0D,KAAjBA,EAAMyD,MACxD,CAwCA,IAAME,EAAW,CACf,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,IACL,EAAK,KAGP,SAASC,EAAaC,EAAeC,GACnC,IAAIC,EAAI,eAAiBF,EAEzB,OAD+BE,EAAEC,MAAMD,EAAED,OAASA,GACpBG,MAAM,IAAI/B,KAAI,SAAAgC,GAAK,OAAAP,EAASO,EAAT,IAAa9B,KAAK,GACrE,CCnJA,IAAM+B,EAAsB,eAE5B,aAOE,aANQ,KAAAC,QAAyB,KAEzB,KAAAC,OAAqB,CAC3BC,aAAc,CAAC,EAGD,CAiJlB,OA/IE,sBAAI,qBAAM,C,IAAV,SAAWC,GACTvF,KAAKoF,QAAUG,EACfvF,KAAKwF,kBACP,E,gCAEA,YAAAC,eAAA,SAAetF,GACb,OAAOH,KAAKqF,OAAOC,aAAanF,EAClC,EAEA,YAAAuF,aAAA,SAAavF,GACX,IAAMwF,EAAc3F,KAAKqF,OAAOC,aAAanF,GAE7C,GAAKwF,EAcL,OAVAtE,EAASS,KAAKQ,EAA2B,CACvCsD,YAAa3E,EAAY4E,iBACzBN,GAAII,EAAYJ,GAChBO,UAAWC,KAAKC,MAChBC,iBAAkBN,EAAYM,iBAC9BC,UAAWP,EAAYQ,iBAAiBC,MAAK,SAAAhG,GAAK,OAAAA,EAAEY,QAAU2E,EAAYO,SAAxB,MAK7C7C,EAF8BsC,EAAW,cAAXA,EAAW,UAGlD,EAEA,YAAAU,YAAA,SAAYC,GACVtG,KAAKqF,OAAS,CACZC,aAAc,CAAC,GAGjBtF,KAAKuG,eAAevG,KAAKqF,QACzBrF,KAAKwG,qBAAqBF,EAC5B,EAEA,YAAAG,gBAAA,WACE,OAAOzG,KAAKqF,OAAOC,YACrB,EAEA,YAAAoB,kBAAA,SAAkBJ,EAAkBK,EAAoBC,GACtD,IAAIC,EAAeC,aAAaC,QAAQJ,GACpCK,EAA2B,KAE/B,IACMH,GAAgBA,EAAapC,OAAOK,OAAS,IAC/CkC,EAAQlD,KAAKC,MAAM8C,GAEvB,CAAE,MAAOI,GACP,EAAO/E,SAAS,gDAAyCyE,GAAeM,EAC1E,CAEA,GAAMD,EAAO,CACH,MAAiBV,EAAI,aAE7BjG,OAAO6G,KAAK,GAAcnF,SAAQ,SAAAwD,GAChC,IAAM4B,EAAW,EAAa5B,KACdyB,EAAO1B,aAAaC,KAELqB,KAE7BI,EAAO1B,aAAa6B,EAAS5B,IAAMlF,OAAO+G,OAAO,CAAC,EAAGD,GAEzD,IAEAnH,KAAKuG,eAAeS,EAAOL,EAC7B,CACF,EAEA,YAAAH,qBAAA,SAAqBF,GACnB,IAAMK,EAAa,UAAGxB,EAAmB,YAAInF,KAAKoF,SAElDpF,KAAK0G,kBAAkBJ,EAAMK,GAAY,GAEzC3G,KAAKwF,kBACP,EAEQ,YAAA6B,kBAAR,SAA0BC,GACpBA,EAAoBxC,OAAS,IAC/BwC,EAAoBvF,SAAQ,SAAC,GAAI,K,IAAEwF,EAAS,YAAEjB,EAAI,OAAO,OAAAjF,EAASS,KAAK,aAAMyF,EAAS,YAAIjB,EAAKf,IAAMe,EAA5C,IACzDjF,EAASS,KAAK,aAAMV,EAA2BoG,QAAUF,EAAoBpE,KAAI,SAAAuE,GAAQ,OAAAA,EAAKnB,IAAL,KAE7F,EAEQ,YAAAC,eAAR,SAAuBS,EAAoBU,GACzC,GAAIV,EAAJ,CACE,IAAM,EAAaU,GAAmB,UAAGvC,EAAmB,YAAInF,KAAKoF,SACrE0B,aAAaa,QAAQ,EAAY7D,KAAK8D,UAAUZ,GAElD,KAJA,CAKA,IAAML,EAAa,UAAGxB,EAAmB,YAAInF,KAAKoF,SAClD0B,aAAaa,QAAQhB,EAAY7C,KAAK8D,UAAU5H,KAAKqF,QAFrD,CAGF,EAEQ,YAAAG,iBAAR,sBACE,IACE,IAAMmB,EAAa,UAAGxB,EAAmB,YAAInF,KAAKoF,SAC9CyB,EAAeC,aAAaC,QAAQJ,GAIxC,GAAIE,GAAgBA,EAAapC,OAAOK,OAAS,EAAG,CAElD,IAAM,EAA0BhB,KAAKC,MAAM8C,GAErCS,EAAsBjH,OAAO6G,KAAK,EAAY5B,cAAcuC,QAAO,SAAA1H,GACvE,IAAM2H,EAAY,EAAYxC,aAAanF,GACrC4H,EAAK,EAAK1C,OAAOC,aAAanF,GACpC,OAAQ4H,GAAMD,EAAU5B,YAAc6B,EAAG7B,WAAa4B,EAAUE,gBAAkBD,EAAGC,aACvF,IAAG9E,KAAI,SAAA/C,GACL,IAAM2H,EAAY,EAAYxC,aAAanF,GACrC4H,EAAK,EAAK1C,OAAOC,aAAanF,GAEpC,MAAO,CACLoF,GAAIpF,EACJoH,UAAWnG,EAA2BoG,OACtCvB,iBAAkB6B,EAAU7B,iBAC5BK,KAAM,CACJf,GAAIpF,EACJ8H,SAAUF,EAAK1E,EAAe0E,EAAGC,cAAeD,EAAG7B,gBAAYgC,EAC/DC,SAAU9E,EAAeyE,EAAUE,cAAeF,EAAU5B,YAGlE,IAEAlG,KAAKqF,OAAS,EACdrF,KAAKqH,kBAAkBC,EACzB,MACEtH,KAAKqF,OAAS,CACZC,aAAc,CAAC,EAQrB,CAAE,MAAO2B,GACP,EAAO/E,SAAS,yCAA2C+E,EAC7D,CACF,EACF,EAxJA,GA0JA,YAAmBmB,E,oNCtKbC,EAA6C,CAAC,EAC9CC,EAAwB,GAkE9B,YA/DA,WAGI,aACItI,KAAKuI,KAAOtE,GAChB,CAwDJ,OAtDI,YAAAuE,OAAA,SAAOrI,GACHH,KAAKuI,KAAOpI,GAAOH,KAAKuI,IAC5B,EAEA,YAAAE,SAAA,SAASzG,EAAc0G,GACrB,IAAIC,EAAY,EAChB,OAAO,W,IAAS,sDACdC,aAAaD,GACbA,EAAQE,WAAW7G,EAAG8G,KAAI,MAAP9G,E,+LAAE,EAAM,MAASC,GAAI,IAAGyG,GAAM,EACnD,CACF,EAEA,YAAAK,cAAA,SAAeC,GAAf,WACMC,GAAU,EAsBd,OAAO,W,IAAgB,sD,iqCACfC,EArBW,SAACjH,GAClB,IAAMkH,EAASlH,EAAKiB,KAAI,SAAAkG,GACtB,MACiB,iBAARA,GACQ,mBAARA,GACC,OAARA,EAEIC,MAAMC,QAAQF,GACTA,EAAIlG,KAAI,SAAApD,GAAK,cAAKA,GAAM,CAACgG,UAAW,MAAvB,IAEb,EAAP,KAAWsD,GAAQ,CAACtD,UAAW,OAI5BsD,CACT,IAEA,OAAO,EAAKb,KAAOzE,KAAK8D,UAAUuB,EACpC,CAGoBI,CAAatH,GACzBuH,EAAMlB,EAAYmB,WAAU,SAAAC,GAAK,OAAAA,IAAMR,CAAN,IAClCD,IAAoB,IAATO,EAAZ,OACFP,GAAU,GACG,IAATO,GACFlB,EAAY5G,KAAKwH,GAGnB,EAAAb,EAAiB,EAAAa,EAAa,GAAMF,EAASW,MAAM,KAAM1H,K,OAAzD,KAA8B,SAE9B4G,YAAW,WACPI,GAAU,CACd,GAzDmB,G,iBA4DrB,MAAO,CAAP,EAAOZ,EAAiBa,I,oSAE5B,EACJ,EA7DA,I,sjDCCMU,EAA4B,CAAC,IAAK,IAAK,IAAM,IAAM,IAAM,KAqLlDC,EAAiB,IAnL9B,WASE,wBAFQ,KAAAC,aAAe,EA0IvB,KAAAC,aAAe,EAAahB,eAAc,SAAOzC,GAAgB,qC,iEAC/D,IAAKtG,KAAKgK,SAAWhK,KAAK8C,OAASwD,GAAwB,IAAhBA,EAAKxB,OAC9C,U,iBAyBA,O,sBArBMmF,EAAU,CAAC,CACfnH,KAAM9C,KAAKkK,gBACXC,WAAY7D,EAAKuB,QAAO,SAAAuC,GAAK,OAAAA,EAAExE,cAAgB3E,EAAY4E,gBAA9B,IAAgD3C,KAAI,SAAAmH,GAAK,OACpFC,eAAgBD,EAAE9E,GAClBU,iBAAkBoE,EAAEpE,iBACpBH,UAAWuE,EAAEvE,UACbI,UAAW,CACTX,GAAI8E,EAAEnE,UAAWX,GACjBvE,MAAOqJ,EAAEnE,UAAWlF,OAN8D,IAStFuJ,QAASjE,EAAKuB,QAAO,SAAAuC,GAAK,OAAAA,EAAExE,cAAgB3E,EAAY4E,gBAA9B,IAAgD3C,KAAI,SAAAkH,GAAK,OACjFI,MAAOC,SAASC,SAChB5E,UAAWsE,EAAEtE,UACb6E,aAAiC,OAAnBP,EAAEO,mBAA4CzC,IAAnBkC,EAAEO,aAA4B,EAAIP,EAAEO,aAC7EC,QAAS,EAAKA,QACdC,UAAWT,EAAES,UACbvH,KAAM8G,EAAE9G,KANyE,MAUrF,GAAMwH,EAAK,UAAG9K,KAAK+K,UAAS,6BAA6Bd,EAAS,CAAEe,cAAehL,KAAKgK,U,cAAxF,S,+BAEA,EAAO9H,SAAS,G,gCArKN,CAwKhB,OAtKE,YAAA+I,KAAA,SAAKC,EAAsBH,EAAmBf,EAAgBY,GAC5D5K,KAAKkL,aAAeA,EACpBlL,KAAK+K,UAAYA,EACjB/K,KAAKgK,OAASA,EACdhK,KAAK4K,QAAUA,CACjB,EAEA,YAAAO,SAAA,SAASrI,EAAasI,G,MACpBpL,KAAK8C,KAAO,KAAKA,GACjB,EAAa0F,OAAgB,QAAT,EAAAxI,KAAK8C,YAAI,eAAEE,OAE3BoI,GAAuBpL,KAAKqL,QAC9BrL,KAAKsL,wBAAwB,EAEjC,EAEQ,YAAAA,wBAAR,SAAgCxF,G,QACxB,EAAwC9F,KAAK8C,KAC7CmH,EAAU,CACdsB,YAAa,YACbjF,KAAM,CACJxD,KAAM,CACJtB,KALM,OAMNwB,MANa,QAObC,qBAPmC,wBASrC6C,UAAS,IAIb,KACiB,QAAX,EAAA9F,KAAKqL,cAAM,eAAEG,cAAeC,UAAUC,MACxC,EAAOxJ,SAAS,iCACL,QAAX,EAAAlC,KAAKqL,cAAM,SAAEM,KAAK7H,KAAK8D,UAAUqC,KAEjC,EAAO/H,SAAS,4DAEpB,CAAE,MAAO+E,GACP,EAAO/E,SAAS+E,EAClB,CACF,EAIQ,YAAA2E,UAAR,WACE5L,KAAKqL,OAAS,KACd,IAAMQ,EAAWjC,EAA0BvF,KAAKyH,IAAI9L,KAAK8J,eAAgBF,EAA0B9E,OAAS,IAC5G+D,YAAW,WACT,EAAO3G,SAAS,wBAChBb,EAASS,KAAKU,EAAyB,CAAC,EAC1C,GAAGqJ,GACH,EAAO3J,SAAS2J,EAClB,EAEQ,YAAAE,gBAAR,sBACQ9B,EAAU,CACdsB,YAAa,OACbjF,KAAM,MAGRuC,YAAW,W,MACT,KACiB,QAAX,IAAKwC,cAAM,eAAEG,cAAeC,UAAUC,MACxC,EAAOxJ,SAAS,gBAChB,EAAKmJ,OAAOM,KAAK7H,KAAK8D,UAAUqC,IAChC,EAAK8B,oBAEL,EAAO7J,SAAS,2BAAoB,IAAI6D,OACxC,EAAK6F,YAET,CAAE,MAAO3E,GACP,EAAO/E,SAAS+E,EAClB,CACF,GAAG,KACL,EAEA,YAAA+E,iBAAA,SAAiBlG,EAAmBmG,GAClC,IAAMC,EAAOlM,KACb,GAAIkM,EAAKb,OACPY,EAAU,CAAC,OADb,CAKA,IAAME,EAAYpG,KAAKC,MAEjBoG,EAAM,UAAGpM,KAAKkL,aAAY,wCHyD7B,SAAiCmB,GACtCA,EAAOA,EAAKnI,QAAQ,MAAO,IAC3B,IAAM4B,EAAYC,KAAKC,MACjBsG,EAAgB1H,EAAakB,EAAWA,EAAUvB,WAAWO,QAE7DyH,EAAQlI,KAAKmI,IAAInI,KAAKoI,MAAMpI,KAAKC,SAAW+H,EAAKvH,QAAS,GAEhE,MAAO,UAAGF,EAAa2H,EAAO,IAAE,OAAG3H,EAAa0H,EAAcxH,OAAQ,IAAE,OAAGuH,EAAKrH,MAAM,EAAGuH,IAAM,OAAGD,GAAa,OAAGD,EAAKrH,MAAMuH,GAC/H,CGjEoEG,CAAwB1M,KAAKgK,SAC7FkC,EAAKb,OAAS,IAAII,UAAUW,GAG5BF,EAAKb,OAAOsB,iBAAiB,QAAQ,SAA2BC,GAC9DV,EAAKpC,aAAe,EAEpB,EAAO5H,SAAS,2BAAoB6D,KAAKC,MAAQmG,EAAS,QAC1DD,EAAKZ,wBAAwBxF,GAC7BoG,EAAKH,iBACP,IAGAG,EAAKb,OAAOsB,iBAAiB,SAAS,SAAUC,GAC9C,EAAO1K,SAAS,SACG,OAAf0K,EAAMC,MAIVX,EAAKN,WACP,IAGAM,EAAKb,OAAQsB,iBAAiB,SAAS,SAAUC,GAE/C,EAAO1K,SAAS,QAClB,IAGAgK,EAAKb,OAAOsB,iBAAiB,WAAW,SAAUC,GAChD,IAAME,EAAUhJ,KAAKC,MAAM6I,EAAMtG,MACL,cAAxBwG,EAAQvB,cACVU,EAAUa,EAAQxG,MACdwG,EAAQxG,KAAKhB,aAAaR,OAAS,GACrC,EAAO5C,SAAS,gCAAiC6D,KAAKC,MAAQ8G,EAAQxG,KAAKhB,aAAa,GAAGQ,WAGjG,GAzCA,CA0CF,EAEQ,YAAAoE,cAAR,WACQ,MAAwClK,KAAK8C,KACnD,MAAO,CACLtB,KAFU,OAGVwB,MAHiB,QAIjBC,qBAJuC,uBAM3C,EAkCF,EAjLA,IAqLO,SAAe6H,EAAKsB,EAAkB9F,EAAgByG,G,YAAlC,IAAAX,IAAAA,EAAA,SAAkB,IAAA9F,IAAAA,EAAA,SAAgB,IAAAyG,IAAAA,EAAA,I,2FAExC,O,sBAAA,GAAMC,MAAMZ,EAAK,CAChCa,OAAQ,OACRF,QAAS1M,OAAO+G,OAAO,CACrB,eAAgB,oBACf2F,GACHG,KAAMpJ,KAAK8D,UAAUtB,M,OAGvB,MAAO,CAAP,EAA2B,OARrB6G,EAAW,UAQDC,OAAiBD,EAAStJ,OAAS,CAAC,G,OAGpD,O,WADA,EAAO3B,SAAS,GACT,CAAP,EAAO,CAAC,G,4BCzMZ,aAII,WAAoBmL,EAAgCC,QAAhC,IAAAD,IAAAA,EAAA,QAAgC,IAAAC,IAAAA,EAAA,IAAhC,KAAAD,WAAAA,EAAgC,KAAAC,sBAAAA,EAChDtN,KAAKuN,MAAQ,EACjB,CAcJ,OAZI,YAAAC,IAAA,SAAIC,GACAzN,KAAKuN,MAAM7L,KAAK+L,GACZzN,KAAKqN,WAAa,GAAKrN,KAAKuN,MAAMzI,QAAU9E,KAAKqN,YACjDhM,EAASS,KAAK9B,KAAKsN,sBAAuB,CAAC,EAEnD,EAEA,YAAAI,MAAA,WACI,IAAMC,E,+LAAc,IAAI3N,KAAKuN,OAAK,GAElC,OADAvN,KAAKuN,MAAQ,GACNI,CACX,EACJ,EApBA,G,ovDCoCA,SAASC,IACP,IAAMC,ELjCD,WACL,IAAIC,EAAOhH,aAAaC,QAAQ,WAChC,GAAI+G,EACF,OAAOA,EAGP,IAAMvI,EAAKtB,IAEX,OADA6C,aAAaa,QAAQ,UAAWpC,GACzBA,CAEX,CKuBoBwI,GAElB,MAAO,CACLvM,KAAMqM,EACN7K,MAAO6K,EAEX,CAEA,SAASG,EAAqC1I,GAC5C,OAAOjF,OAAO6G,KAAK5B,GAAcpC,KAAI,SAAC+K,GAC9B,MAAkB3I,EAAa2I,GAA9B1I,EAAE,KAAEW,EAAS,YACd8B,EAAgB1C,EAAa2I,GAAKjG,eAAiB9G,EAAkBqC,OAC3E,MAAO,CAACgC,GAAE,EAAEW,UAAW7C,EAAe2E,EAAe9B,GAAY8B,cAAa,EAChF,GACF,CAEA,iBAeE,wBAdQ,KAAAkG,oBAA8B,EAG9B,KAAAC,eAAkC,IAAIC,EAAgB,EAAG/L,GACzD,KAAAgM,6BAAmE,IAAID,EACvE,KAAAE,QAAmB,CACzBtE,OAAQ,GACRuE,IAAK,GACLrD,aAAc,GACdH,UAAW,GACXyD,gBAAgB,EAChB5D,QAAS,cAIT5K,KAAKyO,cAAgB,IAAIC,SAA4B,SAACC,EAASC,GAC7D,EAAKC,GAAG,SAAS,WACf,IAAMvJ,EAAe0B,EAAMP,kBAE3B,GADAkI,EAAQX,EAAqC1I,IACzC,EAAKgJ,QAAQE,eAAgB,CAC/B,IAAMM,EAAW,EAAKT,6BAA6BX,QAAQxK,KAAI,SAAAwG,GAC7D,IAAM/D,EAAcL,EAAaoE,EAAEnE,IACnC,IAAKI,EAEH,OADA,EAAOxD,IAAI,0CAAoCuH,EAAEnE,KAC1C,KAGT,IAAMW,EAAYP,EAAYQ,iBAAiBC,MAAK,SAAAhG,GAAK,OAAAA,EAAEY,QAAU0I,EAAEqF,cAAd,IAOzD,OANK7I,EAGH,EAAOhE,SAAS,kDAA4CwH,EAAEnE,GAAE,4BAAsBW,EAAUlF,QAFhG,EAAOmB,IAAI,kDAA4CuH,EAAEnE,GAAE,+CAAyCmE,EAAEqF,iBAKjG,CACLnJ,YAAa3E,EAAY4E,iBACzBN,GAAII,EAAYJ,GAChBO,UAAW4D,EAAE5D,UACbG,iBAAkBN,EAAYM,iBAC9BC,UAAWA,GAAa,CAACX,IAAK,EAAGvE,MAAO0I,EAAEqF,gBAE9C,IAEAlF,EAAeE,aAAa+E,EAASjH,QAAO,SAAAmH,GAAK,QAAEA,CAAF,IACnD,CACF,GACF,IAGA3N,EAASE,UAAUiB,GAAyB,gD,wDAGxC,O,sBADA,EAAON,SAAS,gBAChB,GAAMlC,KAAKiP,Y,cAAX,SACKjP,KAAKkO,qBACRlO,KAAKkO,oBAAqB,EAC1B7M,EAASS,KAAK,QAASkM,EAAqChH,EAAMP,qB,+BAGpE,EAAOtE,IAAI,kBAAmB,G,iCAIlCd,EAASE,UAAUgB,GAAiC,SAAC+D,GACnD,EAAK+H,6BAA6Bb,IAAIlH,EACxC,IAGAjF,EAASE,UAAUc,GAAoB,WACjC,EAAKiM,QAAQE,gBACf3E,EAAeE,aAAa,EAAKoE,eAAeT,QAEpD,IAEArM,EAASE,UAAUe,GAA2B,SAACgE,GAC7C,EAAK6H,eAAeX,IAAIlH,EAC1B,IAEAjF,EAASE,UPjIgB,kBOiIS,SAAC+E,GACjC,EAAK6H,eAAeX,IAAIlH,EAC1B,GACF,CA8LF,OA5LE,YAAAuI,GAAA,SAAGrN,EAAcC,GACfJ,EAASE,UAAUC,EAAMC,EAC3B,EAEA,YAAAyN,IAAA,SAAI1N,EAAcC,GAChBJ,EAASM,YAAYH,EAAMC,EAC7B,EAEA,YAAA0N,eAAA,WACE,OAAOnP,KAAKyO,aACd,EAEM,YAAAxD,KAAN,SAAWmE,G,sGAET,OADMC,EL/CH,SAAwBD,GAC7B,GAAIA,QACF,OAAO,EAAexM,UAAU,UAG1B,IAAAsI,EAAqEkE,EAAM,aAA7DrE,EAAuDqE,EAAM,UAAlDpF,EAA4CoF,EAAM,OAA1CE,EAAoCF,EAAM,UAA/BtM,EAAyBsM,EAAM,KAAzBZ,EAAmBY,EAAM,eAE7EG,EAAsB7K,EAA8BwG,GACpDsE,EAAmB9K,EAA8BqG,GAEvD,GAAIyD,IAAmBe,GAAuBC,GAC9C,CACI,GAAIA,EACF,OAAO,EAAe9M,gBAAgB,aAGxC,GAAI6M,EACF,OAAO,EAAe7M,gBAAgB,eAE5C,CAEA,OAAI8L,GAAkB9J,EAA8BsF,GAC3C,EAAerH,aAAa,UAIjB,KAAd2M,GAAwBxM,EAI1BA,EACK0B,EAAa1B,GAGf,KAPE,EAAeF,UAAU,OAQpC,CKYiC6M,CAAe,OAAIzP,KAAKsO,SAAYc,IACpC,OAAzBC,GACF,EAAOlN,IAAIkN,GACX,MAGFrP,KAAKsO,QAAU,SACVtO,KAAKsO,SACLc,GACA,CACDb,IAAqC,QAA/B,EAAAa,EAAOb,KAAOvO,KAAKsO,QAAQC,WAAI,eAAErK,QAAQ,MAAO,MAItDlE,KAAKsO,QAAQE,gBACf3E,EAAeoB,KAAKjL,KAAKsO,QAAQpD,aAAelL,KAAKsO,QAAQvD,UAAY/K,KAAKsO,QAAQtE,OAAQhK,KAAKsO,QAAQ1D,SAG7G,GAAM5K,KAAKmL,SAASiE,EAAOtM,MAAQ8K,O,cAAnC,S,YAGI,YAAAzC,SAAN,SAAerI,G,wGAEb,OAA2B,QADrB4M,EAAqBlL,EAAa1B,KAEtC,EAAOX,IAAIuN,GACX,MAGF5M,EAAKG,qBAAgD,QAAzB,EAAAH,EAAKG,4BAAoB,eAAEC,KAAI,SAAAC,GAAK,OAAE3B,KAAM2B,EAAE3B,KAAMR,MAAO,UAAImC,EAAEnC,OAA7B,IAE1D2O,EAAgB9M,EAAcC,KAAUgE,aAAaC,QAAQtE,GACnEzC,KAAKsO,QAAQxL,KAAOzC,OAAO+G,OAAO,CAAC,EAAGtE,GACtCgE,aAAaa,QAAQlF,EAAuBI,EAAc7C,KAAKsO,QAAQxL,OAEvEkE,EAAM4I,OAAS5P,KAAKsO,QAAQxL,KAAKE,MACjC6G,EAAesB,SAASnL,KAAKsO,QAAQxL,KAAM6M,GAE3C,GAAM3P,KAAK6P,UAAU7P,KAAKsO,QAAQuB,UAAWF,K,cAA7C,S,YAGI,YAAAG,OAAN,W,gGAEE,OADMC,EAAgBnC,IACtB,GAAM5N,KAAKmL,SAAS4E,I,OACpB,OADA,SACO,CAAP,EAAOA,G,QASH,YAAAF,UAAN,SAAgBvK,EAA+B0K,G,sGAC7C1K,EAAeA,GAAgBtF,KAAKsO,QAAQuB,YACxBvK,EAAaR,OAAS,IAClCwB,EAAO,CACXhB,aAAcA,EAAa2K,QAAO,SAACC,EAAKC,GAC/B,IAAA5K,EAA+E4K,EAAI,GAA/EjK,EAA2EiK,EAAI,UAApErK,EAAgEqK,EAAI,UAAzDhK,EAAqDgK,EAAI,iBAAvClK,EAAmCkK,EAAI,iBAArBnI,EAAiBmI,EAAI,cAU1F,OATAD,EAAI3K,GAAM,CACRA,GAAE,EACFW,UAAS,EACTJ,UAAS,EACTK,iBAAkBA,GAAoB,CAAC,CAACZ,GAAI,EAAGvE,MAAOkF,IACtDD,iBAAgB,EAChB+B,cAAeA,GAAiB9G,EAAkBqC,QAG7C2M,CACT,GAAG,CAAC,IAGNlJ,EAAMX,YAAYC,GAClB,EAAOpE,SAAS,iCAGdlC,KAAKsO,QAAQE,eAAb,Y,iBAGA,O,sBAAA,GAAMxO,KAAKiP,SAASe,I,cAApB,S,+BAEA,EAAO7N,IAAI,kBAAmB,G,oBAI7BnC,KAAKkO,qBACRlO,KAAKkO,oBAAqB,EAC1B7M,EAASS,KAAK,QAASkM,EAAqChH,EAAMP,qB,YAIxD,YAAAwI,SAAd,SAAuBe,G,8EACrB,MAAO,CAAP,EAAO,IAAItB,SAAc,SAACC,EAASC,GACjC,IAAM9I,EAAYkK,EAAiB,EAAI3L,KAAKmI,IAAG,MAARnI,KAAI,OAAQhE,OAAO+P,OAAOpJ,EAAMP,mBAAmBvD,KAAI,SAAA6E,GAAM,OAAAA,EAAGjC,SAAH,KAAe,GAAF,CAAE,IAAC,IAEpH+D,EAAemC,iBAAiBlG,GAAW,SAACgH,G,MAC1C,GAAIA,GAAWA,EAAQuD,aAA+B,QAAjB,IAAK/B,QAAQxL,YAAI,eAAEE,OAAO,CACtD,IAAAsC,EAAgBwH,EAAO,aAE9B,OAAQA,EAAQwD,WACd,KAAKnP,EAAwBoP,KAC7B,KAAKpP,EAAwBqP,MAC3B,IAAMlK,EAAO,CACXhB,aAAcA,EAAa2K,QAAO,SAACC,EAAKC,GAC/B,IAAA5K,EAA+E4K,EAAI,GAA/EjK,EAA2EiK,EAAI,UAApErK,EAAgEqK,EAAI,UAAzDhK,EAAqDgK,EAAI,iBAAvClK,EAAmCkK,EAAI,iBAArBnI,EAAiBmI,EAAI,cAU1F,OATAD,EAAI3K,GAAM,CACRA,GAAE,EACFW,UAAS,EACTJ,UAAS,EACTK,iBAAgB,EAChBF,iBAAgB,EAChB+B,cAAeA,GAAiB9G,EAAkBqC,QAG7C2M,CACT,GAAG,CAAC,IAGFpD,EAAQwD,YAAcnP,EAAwBoP,MAChDvJ,EAAMX,YAAYC,GAClB,EAAOpE,SAAS,gCAEhB8E,EAAMR,qBAAqBF,GAC3B,EAAOpE,SAAS,kCAGlB,MACF,QACE,EAAOA,SAAS,8BAAgC4K,EAAQwD,WAG9D,CAEA3B,GACF,GACF,I,QAGF,YAAAzI,UAAA,SAAU/F,EAAasQ,GACrB,IAAMvK,EAAYwK,EAA2BvQ,EAAKsQ,GAClD,YAAqBvI,IAAdhC,EAA0BuK,EAAgBvK,CACnD,EAKA,YAAAyK,cAAA,SAAcxQ,EAAasQ,GACzB,IAAMvK,EAAYwK,EAA2BvQ,EAAKsQ,GAClD,YAAqBvI,IAAdhC,EAA0BuK,EAAmD,UAAnCvK,aAAS,EAATA,EAAW0K,oBAC9D,EAEA,YAAAC,QAAA,WACE,OAAO,KAAI7Q,KAAKsO,QAAQxL,KAC1B,EAEA,YAAAgO,gBAAA,SAAgBxK,GAAhB,YACGA,GAAQ,IAAIvE,SAAQ,SAAAqI,GAAK,SAAK+D,eAAeX,IAAI,GAChD5H,YAAa3E,EAAY8P,YACzBjL,UAAWC,KAAKC,MAChB1C,KAAM,eACH8G,GAJqB,GAM5B,EAEA,YAAA4G,uBAAA,SAAuB7Q,EAAa+F,GAClClG,KAAKkG,UAAU/F,EAAK+F,EACtB,EAEA,YAAA+K,mBAAA,WACE,IAAMC,EAAQlK,EAAMP,kBAEpB,OAAOpG,OAAO+P,OAAOc,GAAOjB,QAAO,SAACkB,EAAKhB,GAEvC,OADAgB,EAAIhB,EAAK5K,IAAMlC,EAAe8M,EAAKnI,cAAemI,EAAKjK,WAChDiL,CACT,GAAG,CAAC,EACN,EACF,EA/QA,GAiRMT,EAA6B,SAACvQ,EAAasQ,GAC/C,IAAMvK,EAAYc,EAAMtB,aAAavF,GASrC,YARkB+H,IAAdhC,GACF7E,EAASS,KAAKS,EAAiC,CAC7CgD,GAAIpF,EACJ2F,UAAWC,KAAKC,MAChB+I,eAAgB,UAAI0B,KAIjBvK,CACT,EAEA,YAAmBkL,ECnVnB,IAAMC,EAAOC,SAASC,cAAc,Q,OAEhCF,IACFA,EAAKG,MAAMC,WAAa,SACxB5I,YAAW,WAAM,OAAAwI,EAAKG,MAAMC,WAAa,SAAxB,GAHF,MASjB,EAAOvP,SAAS,kB","sources":["webpack://@featbit/js-client-sdk/webpack/universalModuleDefinition","webpack://@featbit/js-client-sdk/webpack/bootstrap","webpack://@featbit/js-client-sdk/webpack/runtime/define property getters","webpack://@featbit/js-client-sdk/webpack/runtime/hasOwnProperty shorthand","webpack://@featbit/js-client-sdk/webpack/runtime/make namespace object","webpack://@featbit/js-client-sdk/./src/events.ts","webpack://@featbit/js-client-sdk/./src/types.ts","webpack://@featbit/js-client-sdk/./src/logger.ts","webpack://@featbit/js-client-sdk/./src/constants.ts","webpack://@featbit/js-client-sdk/./src/optionMessages.ts","webpack://@featbit/js-client-sdk/./src/utils.ts","webpack://@featbit/js-client-sdk/./src/store.ts","webpack://@featbit/js-client-sdk/./src/throttleutil.ts","webpack://@featbit/js-client-sdk/./src/network.service.ts","webpack://@featbit/js-client-sdk/./src/queue.ts","webpack://@featbit/js-client-sdk/./src/featbit.ts","webpack://@featbit/js-client-sdk/./src/umd.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse {\n\t\tvar a = factory();\n\t\tfor(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n\t}\n})(this, () => {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","interface Events {\n [key: string]: Function[];\n}\n\nclass EventEmitter {\n public events: Events;\n constructor(events?: Events) {\n this.events = events || {};\n }\n\n public subscribe(name: string, cb: Function) {\n (this.events[name] || (this.events[name] = [])).push(cb);\n\n return {\n unsubscribe: () =>\n this.events[name] && this.events[name].splice(this.events[name].indexOf(cb) >>> 0, 1)\n };\n }\n\n public unsubscribe(name: string, cb: Function) {\n this.events[name] && this.events[name].splice(this.events[name].indexOf(cb) >>> 0, 1);\n }\n\n public emit(name: string, ...args: any[]): void {\n (this.events[name] || []).forEach(fn => fn(...args));\n }\n}\n\nexport const eventHub = new EventEmitter();","export type FeatureFlagValue = any;\n\nexport interface IFeatureFlagSet {\n [key: string]: FeatureFlagValue;\n}\n\nexport interface IFeatureFlagChange {\n id: string,\n oldValue: FeatureFlagValue,\n newValue: FeatureFlagValue\n}\n\nexport interface IOption {\n secret: string,\n anonymous?: boolean,\n bootstrap?: IFeatureFlag[],\n streamingUri?: string,\n eventsUri?: string,\n\n // deprecated, this option will be removed in the future, please use streamingUri and eventsUri instead\n api?: string,\n\n appType?: string,\n user?: IUser,\n enableDataSync?: boolean\n}\n\nexport interface IUser {\n name: string,\n keyId: string,\n customizedProperties?: ICustomizedProperty[]\n}\n\nexport interface ICustomizedProperty {\n name: string,\n value: string | number | boolean\n}\n\nexport interface IVariationOption {\n id: number,\n value: FeatureFlagValue\n}\n\nexport interface IFeatureFlagVariation {\n id?: string,\n sendToExperiment?: boolean\n timestamp?: number,\n variation?: {\n id: number,\n value: FeatureFlagValue,\n }\n}\n\nexport interface IFeatureFlagVariationBuffer {\n id: string,\n timestamp: number,\n variationValue: FeatureFlagValue\n}\n\nexport enum InsightType {\n featureFlagUsage = 1,\n customEvent = 2,\n pageView = 3,\n click = 4\n}\n\nexport enum VariationDataType {\n string = 'string',\n boolean = 'boolean',\n number = 'number',\n json = 'json',\n}\n\nexport interface IInsight extends IFeatureFlagVariation, ICustomEvent {\n insightType: InsightType\n}\n\nexport interface IFeatureFlagBase {\n id: string, // the keyname\n variation: FeatureFlagValue,\n variationType: VariationDataType\n}\n\nexport interface IFeatureFlag extends IFeatureFlagBase{\n sendToExperiment: boolean,\n timestamp: number,\n variationOptions: IVariationOption[]\n}\n\nexport interface IDataStore {\n featureFlags: { [key: string]: IFeatureFlag }\n}\n\nexport enum StreamResponseEventType {\n full = 'full',\n patch = 'patch'\n}\n\nexport enum FeatureFlagUpdateOperation {\n update = 'update'\n}\n\nexport interface IStreamResponse {\n eventType: StreamResponseEventType,\n userKeyId: string,\n featureFlags: IFeatureFlag[]\n}\n\nexport interface ICustomEvent {\n type?: string,\n eventName: string,\n numericValue?: number\n}","const debug = false;\n\nexport const logger = {\n logDebug(...args) {\n if (debug) {\n console.log(...args);\n }\n },\n\n log(...args) {\n console.log(...args);\n }\n}","export const insightsFlushTopic = 'insights.flush';\nexport const featureFlagEvaluatedTopic = 'featureflag.evaluated.topic';\nexport const featureFlagEvaluatedBufferTopic = 'featureflag.evaluated.buffer.topic';\nexport const websocketReconnectTopic = 'network.websocket.reconnect';\nexport const insightsTopic = 'insights.topic';\nexport const currentUserStorageKey = 'fb-user';\n","export default class OptionMessages {\n static partialEndpoint(name: string): string {\n return `You have set custom uris without specifying the ${ name } URI; connections may not work properly`;\n }\n\n static invalidParam(name: string): string {\n return `The ${ name } option is not passed in or its value is invalid`;\n }\n\n static mandatory(name: string): string {\n return `${ name } is mandatory`;\n }\n}","import {FeatureFlagValue, IOption, IUser, VariationDataType} from \"./types\";\nimport {logger} from \"./logger\";\nimport OptionMessages from \"./optionMessages\";\n\n\n// generate default user info\nexport function generateorGetGuid(): string {\n let guid = localStorage.getItem(\"fb-guid\");\n if (guid) {\n return guid;\n }\n else {\n const id = uuid();\n localStorage.setItem(\"fb-guid\", id);\n return id;\n }\n}\n\nexport function serializeUser(user: IUser | undefined): string {\n if (!user) {\n return '';\n }\n\n const builtInProperties = `${user.keyId},${user.name}`;\n\n const customizedProperties = user.customizedProperties?.map(p => `${p.name}:${p.value}`).join(',');\n\n return `${builtInProperties},${customizedProperties}`;\n}\n\nexport function isNumeric(str: string) {\n if (typeof str != \"string\") return false // we only process strings!\n // @ts-ignore\n return !isNaN(str) && // use type coercion to parse the _entirety_ of the string (`parseFloat` alone does not do this)...\n !isNaN(parseFloat(str)) // ...and ensure strings of whitespace fail\n}\n\nexport function parseVariation(type: VariationDataType, value: string): FeatureFlagValue {\n switch (type) {\n case VariationDataType.string:\n return value;\n case VariationDataType.boolean:\n if (value === 'true') {\n return true;\n }\n\n if (value === 'false') {\n return false;\n }\n\n logger.log(`expected boolean value, but got ${value}`);\n return value;\n case VariationDataType.number:\n if (isNumeric(value)) {\n return +value;\n }\n\n logger.log(`expected numeric value, but got ${value}`);\n return value;\n case VariationDataType.json:\n try {\n return JSON.parse(value);\n }\n catch (e) {\n logger.log(`expected json value, but got ${value}`);\n return value;\n }\n default:\n logger.log(`unexpected variation type ${type} for ${value}`);\n return value;\n }\n}\n\nexport function uuid(): string {\n let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\n var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n\n return uuid;\n}\n\nexport function validateUser(user: IUser): string | null {\n if (!user) {\n return OptionMessages.mandatory('user')\n }\n\n const { keyId, name } = user;\n\n if (keyId === undefined || keyId === null || keyId.trim() === '') {\n return OptionMessages.mandatory('user.keyId');\n }\n\n if (name === undefined || name === null || name.trim() === '') {\n return OptionMessages.mandatory('user.name');\n }\n\n return null;\n}\n\nexport function isNullOrUndefinedOrWhiteSpace(value?: string): boolean {\n return value === null || value === undefined || value.trim() === '';\n}\n\nexport function validateOption(option: IOption): string | null {\n if (option === undefined || option === null) {\n return OptionMessages.mandatory('option')\n }\n\n const { streamingUri, eventsUri, secret, anonymous, user, enableDataSync } = option;\n\n const streamingUriMissing = isNullOrUndefinedOrWhiteSpace(streamingUri);\n const eventsUriMissing = isNullOrUndefinedOrWhiteSpace(eventsUri);\n\n if (enableDataSync && (streamingUriMissing || eventsUriMissing))\n {\n if (eventsUriMissing) {\n return OptionMessages.partialEndpoint('eventsUri');\n }\n\n if (streamingUriMissing) {\n return OptionMessages.partialEndpoint('streamingUri');\n }\n }\n\n if (enableDataSync && isNullOrUndefinedOrWhiteSpace(secret)) {\n return OptionMessages.invalidParam('secret');\n }\n\n // validate user\n if (!!anonymous === false && !user) {\n return OptionMessages.mandatory('user');\n }\n\n if (user) {\n return validateUser(user);\n }\n\n return null;\n}\n\n/********************** encode text begin *****************************/\nconst alphabet = {\n \"0\": \"Q\",\n \"1\": \"B\",\n \"2\": \"W\",\n \"3\": \"S\",\n \"4\": \"P\",\n \"5\": \"H\",\n \"6\": \"D\",\n \"7\": \"X\",\n \"8\": \"Z\",\n \"9\": \"U\",\n}\n\nfunction encodeNumber(param: number, length: number): string {\n var s = \"000000000000\" + param;\n const numberWithLeadingZeros = s.slice(s.length - length);\n return numberWithLeadingZeros.split('').map(n => alphabet[n]).join('');\n}\n\n// generate connection token\nexport function generateConnectionToken(text: string): string {\n text = text.replace(/=*$/, '');\n const timestamp = Date.now();\n const timestampCode = encodeNumber(timestamp, timestamp.toString().length);\n // get random number less than the length of the text as the start point, and it must be greater or equal to 2\n const start = Math.max(Math.floor(Math.random() * text.length), 2);\n\n return `${encodeNumber(start, 3)}${encodeNumber(timestampCode.length, 2)}${text.slice(0, start)}${timestampCode}${text.slice(start)}`;\n}\n\n/********************** encode text end *****************************/\n","import {featureFlagEvaluatedTopic} from \"./constants\";\nimport {eventHub} from \"./events\";\nimport {logger} from \"./logger\";\nimport {\n FeatureFlagUpdateOperation, FeatureFlagValue,\n IDataStore,\n IFeatureFlag,\n IFeatureFlagChange,\n InsightType\n} from \"./types\";\nimport {parseVariation} from \"./utils\";\n\nconst DataStoreStorageKey = 'fb-datastore';\n\nclass Store {\n private _userId: string | null = null;\n\n private _store: IDataStore = {\n featureFlags: {} as { [key: string]: IFeatureFlag }\n }\n\n constructor() { }\n\n set userId(id: string) {\n this._userId = id;\n this._loadFromStorage();\n }\n\n getFeatureFlag(key: string): IFeatureFlag {\n return this._store.featureFlags[key];\n }\n\n getVariation(key: string): FeatureFlagValue {\n const featureFlag = this._store.featureFlags[key];\n\n if (!featureFlag) {\n return undefined;\n }\n\n eventHub.emit(featureFlagEvaluatedTopic, {\n insightType: InsightType.featureFlagUsage,\n id: featureFlag.id,\n timestamp: Date.now(),\n sendToExperiment: featureFlag.sendToExperiment,\n variation: featureFlag.variationOptions.find(o => o.value === featureFlag.variation)\n });\n\n const { variationType, variation } = featureFlag;\n\n return parseVariation(variationType, variation);\n }\n\n setFullData(data: IDataStore) {\n this._store = {\n featureFlags: {} as { [key: string]: IFeatureFlag }\n };\n\n this._dumpToStorage(this._store);\n this.updateBulkFromRemote(data);\n }\n\n getFeatureFlags(): { [key: string]: IFeatureFlag } {\n return this._store.featureFlags;\n }\n\n updateStorageBulk(data: IDataStore, storageKey: string, onlyInsertNewElement: boolean) {\n let dataStoreStr = localStorage.getItem(storageKey);\n let store: IDataStore | null = null;\n\n try {\n if (dataStoreStr && dataStoreStr.trim().length > 0) {\n store = JSON.parse(dataStoreStr);\n }\n } catch (err) {\n logger.logDebug(`error while loading local data store: ${storageKey}` + err);\n }\n\n if (!!store) {\n const { featureFlags } = data;\n\n Object.keys(featureFlags).forEach(id => {\n const remoteFf = featureFlags[id];\n const localFf = store!.featureFlags[id];\n\n const predicate = !localFf || !onlyInsertNewElement;\n if (predicate) {\n store!.featureFlags[remoteFf.id] = Object.assign({}, remoteFf);\n }\n });\n\n this._dumpToStorage(store, storageKey);\n }\n }\n\n updateBulkFromRemote(data: IDataStore) {\n const storageKey = `${DataStoreStorageKey}-${this._userId}`;\n\n this.updateStorageBulk(data, storageKey, false);\n\n this._loadFromStorage();\n }\n\n private _emitUpdateEvents(updatedFeatureFlags: any[]): void {\n if (updatedFeatureFlags.length > 0) {\n updatedFeatureFlags.forEach(({ id, operation, data }) => eventHub.emit(`ff_${operation}:${data.id}`, data));\n eventHub.emit(`ff_${FeatureFlagUpdateOperation.update}`, updatedFeatureFlags.map(item => item.data));\n }\n }\n\n private _dumpToStorage(store?: IDataStore, localStorageKey?: string): void {\n if (store) {\n const storageKey = localStorageKey || `${DataStoreStorageKey}-${this._userId}`;\n localStorage.setItem(storageKey, JSON.stringify(store));\n return;\n }\n const storageKey = `${DataStoreStorageKey}-${this._userId}`;\n localStorage.setItem(storageKey, JSON.stringify(this._store));\n }\n\n private _loadFromStorage(): void {\n try {\n const storageKey = `${DataStoreStorageKey}-${this._userId}`;\n let dataStoreStr = localStorage.getItem(storageKey);\n\n let shouldDumpToStorage = false;\n\n if (dataStoreStr && dataStoreStr.trim().length > 0) {\n // compare _store and dataStoreStr data and send notification if different\n const storageData: IDataStore = JSON.parse(dataStoreStr);\n\n const updatedFeatureFlags = Object.keys(storageData.featureFlags).filter(key => {\n const storageFf = storageData.featureFlags[key];\n const ff = this._store.featureFlags[key];\n return !ff || storageFf.variation !== ff.variation || storageFf.variationType !== ff.variationType;\n }).map(key => {\n const storageFf = storageData.featureFlags[key];\n const ff = this._store.featureFlags[key];\n\n return {\n id: key,\n operation: FeatureFlagUpdateOperation.update,\n sendToExperiment: storageFf.sendToExperiment,\n data: {\n id: key,\n oldValue: ff ? parseVariation(ff.variationType, ff.variation): undefined,\n newValue: parseVariation(storageFf.variationType, storageFf.variation)\n } as IFeatureFlagChange\n }\n });\n\n this._store = storageData;\n this._emitUpdateEvents(updatedFeatureFlags);\n } else {\n this._store = {\n featureFlags: {} as { [key: string]: IFeatureFlag }\n };\n }\n\n if (shouldDumpToStorage) {\n this._dumpToStorage();\n }\n\n } catch (err) {\n logger.logDebug('error while loading local data store: ' + err);\n }\n }\n}\n\nexport default new Store();","import { uuid } from \"./utils\";\n\nconst API_CALL_RESULTS : {[key: string]: string} = {};\nconst FOOT_PRINTS: string[] = [];\nlet _throttleWait: number = 0; // send immediately\n\nclass ThrottleUtil {\n private _key: string;\n\n constructor(){\n this._key = uuid();\n }\n\n setKey(key: string) {\n this._key = key || this._key;\n }\n\n throttle(fn: Function, ms: number) {\n let timer:any = 0\n return function(...args) {\n clearTimeout(timer)\n timer = setTimeout(fn.bind(null, ...args), ms || 0)\n }\n }\n\n throttleAsync (callback: any): any {\n let waiting = false; \n \n let getFootprint = (args: any): string => {\n const params = args.map(arg => {\n if (\n typeof arg === 'object' &&\n typeof arg !== \"function\" &&\n arg !== null\n ) {\n if (Array.isArray(arg)) {\n return arg.map(a => ({...a, ...{timestamp: null}}))\n } else {\n return {...arg, ...{timestamp: null}};\n }\n }\n \n return arg;\n });\n \n return this._key + JSON.stringify(params);\n };\n \n return async function (...args) {\n const footprint = getFootprint(args);\n const idx = FOOT_PRINTS.findIndex(f => f === footprint);\n if (!waiting || idx === -1) {\n waiting = true;\n if (idx === -1) {\n FOOT_PRINTS.push(footprint);\n }\n \n API_CALL_RESULTS[footprint] = await callback.apply(null, args);\n \n setTimeout(function () {\n waiting = false;\n }, _throttleWait);\n }\n \n return API_CALL_RESULTS[footprint];\n }\n }\n}\n\nexport default new ThrottleUtil();\n\n\n","import { websocketReconnectTopic } from \"./constants\";\nimport { eventHub } from \"./events\";\nimport { logger } from \"./logger\";\nimport { IInsight, InsightType, IStreamResponse, IUser } from \"./types\";\nimport { generateConnectionToken } from \"./utils\";\nimport throttleUtil from \"./throttleutil\";\n\nconst socketConnectionIntervals = [250, 500, 1000, 2000, 4000, 8000];\n\nclass NetworkService {\n private user: IUser | undefined;\n private streamingUri: string | undefined;\n private eventsUri: string | undefined;\n private secret: string | undefined;\n private appType: string | undefined;\n\n private retryCounter = 0;\n\n constructor(){}\n\n init(streamingUri: string, eventsUri: string, secret: string, appType: string) {\n this.streamingUri = streamingUri;\n this.eventsUri = eventsUri;\n this.secret = secret;\n this.appType = appType;\n }\n\n identify(user: IUser, sendIdentifyMessage: boolean) {\n this.user = { ...user };\n throttleUtil.setKey(this.user?.keyId);\n\n if (sendIdentifyMessage && this.socket) {\n this.sendUserIdentifyMessage(0);\n }\n }\n\n private sendUserIdentifyMessage(timestamp: number) {\n const { name, keyId, customizedProperties } = this.user!;\n const payload = {\n messageType: 'data-sync',\n data: {\n user: {\n name,\n keyId,\n customizedProperties,\n },\n timestamp\n }\n };\n\n try {\n if (this.socket?.readyState === WebSocket.OPEN) {\n logger.logDebug('sending user identify message');\n this.socket?.send(JSON.stringify(payload));\n } else {\n logger.logDebug(`didn't send user identify message because socket not open`);\n }\n } catch (err) {\n logger.logDebug(err);\n }\n }\n\n private socket: WebSocket | undefined | any;\n\n private reconnect() {\n this.socket = null;\n const waitTime = socketConnectionIntervals[Math.min(this.retryCounter++, socketConnectionIntervals.length - 1)];\n setTimeout(() => {\n logger.logDebug('emit reconnect event');\n eventHub.emit(websocketReconnectTopic, {});\n }, waitTime);\n logger.logDebug(waitTime);\n }\n\n private sendPingMessage() {\n const payload = {\n messageType: 'ping',\n data: null\n };\n\n setTimeout(() => {\n try {\n if (this.socket?.readyState === WebSocket.OPEN) {\n logger.logDebug('sending ping')\n this.socket.send(JSON.stringify(payload));\n this.sendPingMessage();\n } else {\n logger.logDebug(`socket closed at ${new Date()}`);\n this.reconnect();\n }\n } catch (err) {\n logger.logDebug(err);\n }\n }, 18000);\n }\n\n createConnection(timestamp: number, onMessage: (response: IStreamResponse) => any) {\n const that = this;\n if (that.socket) {\n onMessage({} as IStreamResponse);\n return;\n }\n\n const startTime = Date.now();\n // Create WebSocket connection.\n const url = `${this.streamingUri}/streaming?type=client&token=${generateConnectionToken(this.secret!)}`;\n that.socket = new WebSocket(url);\n\n // Connection opened\n that.socket.addEventListener('open', function (this: WebSocket, event) {\n that.retryCounter = 0;\n // this is the websocket instance to which the current listener is binded to, it's different from that.socket\n logger.logDebug(`Connection time: ${Date.now() - startTime} ms`);\n that.sendUserIdentifyMessage(timestamp);\n that.sendPingMessage();\n });\n \n // Connection closed\n that.socket.addEventListener('close', function (event) {\n logger.logDebug('close');\n if (event.code === 4003) { // do not reconnect when 4003\n return;\n }\n\n that.reconnect();\n });\n \n // Connection error\n that.socket!.addEventListener('error', function (event) {\n // reconnect\n logger.logDebug('error');\n });\n \n // Listen for messages\n that.socket.addEventListener('message', function (event) {\n const message = JSON.parse(event.data);\n if (message.messageType === 'data-sync') {\n onMessage(message.data);\n if (message.data.featureFlags.length > 0) {\n logger.logDebug('socket push update time(ms): ', Date.now() - message.data.featureFlags[0].timestamp);\n }\n }\n });\n }\n\n private __getUserInfo(): any {\n const { name, keyId, customizedProperties } = this.user!;\n return {\n name: name,\n keyId: keyId,\n customizedProperties: customizedProperties,\n }\n }\n\n sendInsights = throttleUtil.throttleAsync(async (data: IInsight[]): Promise<void> => {\n if (!this.secret || !this.user || !data || data.length === 0) {\n return;\n }\n \n try {\n const payload = [{\n user: this.__getUserInfo(),\n variations: data.filter(d => d.insightType === InsightType.featureFlagUsage).map(v => ({\n featureFlagKey: v.id,\n sendToExperiment: v.sendToExperiment,\n timestamp: v.timestamp,\n variation: {\n id: v.variation!.id,\n value: v.variation!.value\n }\n })),\n metrics: data.filter(d => d.insightType !== InsightType.featureFlagUsage).map(d => ({\n route: location.pathname,\n timestamp: d.timestamp,\n numericValue: d.numericValue === null || d.numericValue === undefined? 1 : d.numericValue,\n appType: this.appType,\n eventName: d.eventName,\n type: d.type\n }))\n }];\n \n await post(`${this.eventsUri}/api/public/insight/track`, payload, { Authorization: this.secret });\n } catch (err) {\n logger.logDebug(err);\n }\n })\n}\n\nexport const networkService = new NetworkService();\n\nexport async function post(url: string = '', data: any = {}, headers: { [key: string]: string } = {}) {\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: Object.assign({\n 'Content-Type': 'application/json'\n }, headers),\n body: JSON.stringify(data) // body data type must match \"Content-Type\" header\n });\n\n return response.status === 200 ? response.json() : {};\n } catch (err) {\n logger.logDebug(err);\n return {};\n }\n}\n\nexport async function get(url: string = '', headers: { [key: string]: string } = {}) {\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: Object.assign({\n 'Accept': 'application/json',\n 'Content-Type': 'application/json'\n }, headers)\n });\n\n return response.status === 200 ? response.json() : {};\n } catch (err) {\n logger.logDebug(err);\n return null;\n }\n}\n","import { eventHub } from \"./events\";\n\nexport class Queue<T> {\n private queue: T[];\n // flushLimit === 0 means no limit\n // and \n constructor(private flushLimit: number = 0, private arriveflushLimitTopic: string = '') {\n this.queue = [];\n }\n\n add(element: T): void {\n this.queue.push(element);\n if (this.flushLimit > 0 && this.queue.length >= this.flushLimit) {\n eventHub.emit(this.arriveflushLimitTopic, {});\n }\n }\n\n flush(): T[] {\n const allElements = [...this.queue];\n this.queue = [];\n return allElements;\n }\n}","import { eventHub } from \"./events\";\nimport { logger } from \"./logger\";\nimport store from \"./store\";\nimport { networkService } from \"./network.service\";\nimport {\n FeatureFlagValue,\n ICustomEvent,\n IFeatureFlag,\n IFeatureFlagBase,\n IFeatureFlagSet,\n IFeatureFlagVariationBuffer,\n IInsight,\n InsightType,\n IOption,\n IStreamResponse,\n IUser,\n StreamResponseEventType,\n VariationDataType\n} from \"./types\";\nimport {\n generateorGetGuid,\n isNullOrUndefinedOrWhiteSpace,\n parseVariation,\n serializeUser,\n validateOption,\n validateUser\n} from \"./utils\";\nimport { Queue } from \"./queue\";\nimport {\n currentUserStorageKey,\n featureFlagEvaluatedBufferTopic,\n featureFlagEvaluatedTopic,\n insightsFlushTopic,\n insightsTopic,\n websocketReconnectTopic\n} from \"./constants\";\n\n\nfunction createOrGetAnonymousUser(): IUser {\n const sessionId = generateorGetGuid();\n\n return {\n name: sessionId,\n keyId: sessionId\n };\n}\n\nfunction mapFeatureFlagsToFeatureFlagBaseList(featureFlags: { [key: string]: IFeatureFlag }): IFeatureFlagBase[] {\n return Object.keys(featureFlags).map((cur) => {\n const {id, variation} = featureFlags[cur];\n const variationType = featureFlags[cur].variationType || VariationDataType.string;\n return {id, variation: parseVariation(variationType, variation), variationType};\n });\n}\n\nexport class FB {\n private _readyEventEmitted: boolean = false;\n private _readyPromise: Promise<IFeatureFlagBase[]>;\n\n private _insightsQueue: Queue<IInsight> = new Queue<IInsight>(1, insightsFlushTopic);\n private _featureFlagEvaluationBuffer: Queue<IFeatureFlagVariationBuffer> = new Queue<IFeatureFlagVariationBuffer>();\n private _option: IOption = {\n secret: '',\n api: '',\n streamingUri: '',\n eventsUri: '',\n enableDataSync: true,\n appType: 'javascript'\n };\n\n constructor() {\n this._readyPromise = new Promise<IFeatureFlagBase[]>((resolve, reject) => {\n this.on('ready', () => {\n const featureFlags = store.getFeatureFlags();\n resolve(mapFeatureFlagsToFeatureFlagBaseList(featureFlags));\n if (this._option.enableDataSync) {\n const buffered = this._featureFlagEvaluationBuffer.flush().map(f => {\n const featureFlag = featureFlags[f.id];\n if (!featureFlag) {\n logger.log(`Called unexisting feature flag: ${ f.id }`);\n return null;\n }\n\n const variation = featureFlag.variationOptions.find(o => o.value === f.variationValue);\n if (!variation) {\n logger.log(`Sent buffered insight for feature flag: ${ f.id } with unexisting default variation: ${ f.variationValue }`);\n } else {\n logger.logDebug(`Sent buffered insight for feature flag: ${ f.id } with variation: ${ variation.value }`);\n }\n\n return {\n insightType: InsightType.featureFlagUsage,\n id: featureFlag.id,\n timestamp: f.timestamp,\n sendToExperiment: featureFlag.sendToExperiment,\n variation: variation || {id: -1, value: f.variationValue}\n }\n });\n\n networkService.sendInsights(buffered.filter(x => !!x));\n }\n });\n });\n\n // reconnect to websocket\n eventHub.subscribe(websocketReconnectTopic, async () => {\n try {\n logger.logDebug('reconnecting');\n await this.dataSync();\n if (!this._readyEventEmitted) {\n this._readyEventEmitted = true;\n eventHub.emit('ready', mapFeatureFlagsToFeatureFlagBaseList(store.getFeatureFlags()));\n }\n } catch (err) {\n logger.log('data sync error', err);\n }\n });\n\n eventHub.subscribe(featureFlagEvaluatedBufferTopic, (data: IFeatureFlagVariationBuffer) => {\n this._featureFlagEvaluationBuffer.add(data);\n });\n\n // track feature flag usage data\n eventHub.subscribe(insightsFlushTopic, () => {\n if (this._option.enableDataSync) {\n networkService.sendInsights(this._insightsQueue.flush());\n }\n });\n\n eventHub.subscribe(featureFlagEvaluatedTopic, (data: IInsight) => {\n this._insightsQueue.add(data);\n });\n\n eventHub.subscribe(insightsTopic, (data: IInsight) => {\n this._insightsQueue.add(data);\n });\n }\n\n on(name: string, cb: Function) {\n eventHub.subscribe(name, cb);\n }\n\n off(name: string, cb: Function) {\n eventHub.unsubscribe(name, cb);\n }\n\n waitUntilReady(): Promise<IFeatureFlagBase[]> {\n return this._readyPromise;\n }\n\n async init(option: IOption) {\n const validateOptionResult = validateOption({...this._option, ...option});\n if (validateOptionResult !== null) {\n logger.log(validateOptionResult);\n return;\n }\n\n this._option = {\n ...this._option,\n ...option,\n ...{\n api: (option.api || this._option.api)?.replace(/\\/$/, '')\n }\n };\n\n if (this._option.enableDataSync) {\n networkService.init(this._option.streamingUri!, this._option.eventsUri!, this._option.secret, this._option.appType!);\n }\n\n await this.identify(option.user || createOrGetAnonymousUser());\n }\n\n async identify(user: IUser): Promise<void> {\n const validateUserResult = validateUser(user);\n if (validateUserResult !== null) {\n logger.log(validateUserResult);\n return;\n }\n\n user.customizedProperties = user.customizedProperties?.map(p => ({name: p.name, value: `${ p.value }`}));\n\n const isUserChanged = serializeUser(user) !== localStorage.getItem(currentUserStorageKey);\n this._option.user = Object.assign({}, user);\n localStorage.setItem(currentUserStorageKey, serializeUser(this._option.user));\n\n store.userId = this._option.user.keyId;\n networkService.identify(this._option.user, isUserChanged);\n\n await this.bootstrap(this._option.bootstrap, isUserChanged);\n }\n\n async logout(): Promise<IUser> {\n const anonymousUser = createOrGetAnonymousUser();\n await this.identify(anonymousUser);\n return anonymousUser;\n }\n\n /**\n * bootstrap with predefined feature flags.\n * @param {array} featureFlags the predefined feature flags.\n * @param {boolean} forceFullFetch if a forced full fetch should be made.\n * @return {Promise<void>} nothing.\n */\n async bootstrap(featureFlags?: IFeatureFlag[], forceFullFetch?: boolean): Promise<void> {\n featureFlags = featureFlags || this._option.bootstrap;\n if (featureFlags && featureFlags.length > 0) {\n const data = {\n featureFlags: featureFlags.reduce((res, curr) => {\n const {id, variation, timestamp, variationOptions, sendToExperiment, variationType} = curr;\n res[id] = {\n id,\n variation,\n timestamp,\n variationOptions: variationOptions || [{id: 1, value: variation}],\n sendToExperiment,\n variationType: variationType || VariationDataType.string\n };\n\n return res;\n }, {} as { [key: string]: IFeatureFlag })\n };\n\n store.setFullData(data);\n logger.logDebug('bootstrapped with full data');\n }\n\n if (this._option.enableDataSync) {\n // start data sync\n try {\n await this.dataSync(forceFullFetch);\n } catch (err) {\n logger.log('data sync error', err);\n }\n }\n\n if (!this._readyEventEmitted) {\n this._readyEventEmitted = true;\n eventHub.emit('ready', mapFeatureFlagsToFeatureFlagBaseList(store.getFeatureFlags()));\n }\n }\n\n private async dataSync(forceFullFetch?: boolean): Promise<any> {\n return new Promise<void>((resolve, reject) => {\n const timestamp = forceFullFetch ? 0 : Math.max(...Object.values(store.getFeatureFlags()).map(ff => ff.timestamp), 0);\n\n networkService.createConnection(timestamp, (message: IStreamResponse) => {\n if (message && message.userKeyId === this._option.user?.keyId) {\n const {featureFlags} = message;\n\n switch (message.eventType) {\n case StreamResponseEventType.full: // full data\n case StreamResponseEventType.patch: // partial data\n const data = {\n featureFlags: featureFlags.reduce((res, curr) => {\n const {id, variation, timestamp, variationOptions, sendToExperiment, variationType} = curr;\n res[id] = {\n id,\n variation,\n timestamp,\n variationOptions,\n sendToExperiment,\n variationType: variationType || VariationDataType.string\n };\n\n return res;\n }, {} as { [key: string]: IFeatureFlag })\n };\n\n if (message.eventType === StreamResponseEventType.full) {\n store.setFullData(data);\n logger.logDebug('synchonized with full data');\n } else {\n store.updateBulkFromRemote(data);\n logger.logDebug('synchonized with partial data');\n }\n\n break;\n default:\n logger.logDebug('invalid stream event type: ' + message.eventType);\n break;\n }\n }\n\n resolve();\n });\n });\n }\n\n variation(key: string, defaultResult: FeatureFlagValue): FeatureFlagValue {\n const variation = variationWithInsightBuffer(key, defaultResult);\n return variation === undefined ? defaultResult : variation;\n }\n\n /**\n * deprecated, you should use variation method directly\n */\n boolVariation(key: string, defaultResult: boolean): boolean {\n const variation = variationWithInsightBuffer(key, defaultResult);\n return variation === undefined ? defaultResult : variation?.toLocaleLowerCase() === 'true';\n }\n\n getUser(): IUser {\n return {...this._option.user!};\n }\n\n sendCustomEvent(data: ICustomEvent[]): void {\n (data || []).forEach(d => this._insightsQueue.add({\n insightType: InsightType.customEvent,\n timestamp: Date.now(),\n type: 'CustomEvent',\n ...d\n }))\n }\n\n sendFeatureFlagInsight(key: string, variation: string) {\n this.variation(key, variation);\n }\n\n getAllFeatureFlags(): IFeatureFlagSet {\n const flags = store.getFeatureFlags();\n\n return Object.values(flags).reduce((acc, curr) => {\n acc[curr.id] = parseVariation(curr.variationType, curr.variation);\n return acc;\n }, {});\n }\n}\n\nconst variationWithInsightBuffer = (key: string, defaultResult: string | boolean) => {\n const variation = store.getVariation(key);\n if (variation === undefined) {\n eventHub.emit(featureFlagEvaluatedBufferTopic, {\n id: key,\n timestamp: Date.now(),\n variationValue: `${ defaultResult }`\n } as IFeatureFlagVariationBuffer);\n }\n\n return variation;\n}\n\nexport default new FB();\n\n","// This file is only for umd version\n\nconst html = document.querySelector('html');\nconst waittime = 500;\nif (html) {\n html.style.visibility = 'hidden';\n setTimeout(() => html.style.visibility = 'visible', waittime);\n}\n\nimport fbClient from './featbit';\nimport { logger } from './logger';\n\nlogger.logDebug(`version: 2.0.2`);\n\nexport { fbClient }\n"],"names":["root","factory","exports","module","define","amd","a","i","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","InsightType","VariationDataType","StreamResponseEventType","FeatureFlagUpdateOperation","eventHub","events","subscribe","name","cb","push","unsubscribe","splice","indexOf","emit","forEach","fn","args","logDebug","log","console","insightsFlushTopic","featureFlagEvaluatedTopic","featureFlagEvaluatedBufferTopic","websocketReconnectTopic","currentUserStorageKey","partialEndpoint","invalidParam","mandatory","serializeUser","user","builtInProperties","keyId","customizedProperties","map","p","join","parseVariation","type","string","boolean","number","str","isNaN","parseFloat","json","JSON","parse","e","uuid","replace","c","r","Math","random","toString","validateUser","trim","isNullOrUndefinedOrWhiteSpace","alphabet","encodeNumber","param","length","s","slice","split","n","DataStoreStorageKey","_userId","_store","featureFlags","id","_loadFromStorage","getFeatureFlag","getVariation","featureFlag","insightType","featureFlagUsage","timestamp","Date","now","sendToExperiment","variation","variationOptions","find","setFullData","data","_dumpToStorage","updateBulkFromRemote","getFeatureFlags","updateStorageBulk","storageKey","onlyInsertNewElement","dataStoreStr","localStorage","getItem","store","err","keys","remoteFf","assign","_emitUpdateEvents","updatedFeatureFlags","operation","update","item","localStorageKey","setItem","stringify","filter","storageFf","ff","variationType","oldValue","undefined","newValue","Store","API_CALL_RESULTS","FOOT_PRINTS","_key","setKey","throttle","ms","timer","clearTimeout","setTimeout","bind","throttleAsync","callback","waiting","footprint","params","arg","Array","isArray","getFootprint","idx","findIndex","f","apply","socketConnectionIntervals","networkService","retryCounter","sendInsights","secret","payload","__getUserInfo","variations","d","v","featureFlagKey","metrics","route","location","pathname","numericValue","appType","eventName","post","eventsUri","Authorization","init","streamingUri","identify","sendIdentifyMessage","socket","sendUserIdentifyMessage","messageType","readyState","WebSocket","OPEN","send","reconnect","waitTime","min","sendPingMessage","createConnection","onMessage","that","startTime","url","text","timestampCode","start","max","floor","generateConnectionToken","addEventListener","event","code","message","headers","fetch","method","body","response","status","flushLimit","arriveflushLimitTopic","queue","add","element","flush","allElements","createOrGetAnonymousUser","sessionId","guid","generateorGetGuid","mapFeatureFlagsToFeatureFlagBaseList","cur","_readyEventEmitted","_insightsQueue","Queue","_featureFlagEvaluationBuffer","_option","api","enableDataSync","_readyPromise","Promise","resolve","reject","on","buffered","variationValue","x","dataSync","off","waitUntilReady","option","validateOptionResult","anonymous","streamingUriMissing","eventsUriMissing","validateOption","validateUserResult","isUserChanged","userId","bootstrap","logout","anonymousUser","forceFullFetch","reduce","res","curr","values","userKeyId","eventType","full","patch","defaultResult","variationWithInsightBuffer","boolVariation","toLocaleLowerCase","getUser","sendCustomEvent","customEvent","sendFeatureFlagInsight","getAllFeatureFlags","flags","acc","FB","html","document","querySelector","style","visibility"],"sourceRoot":""}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
!function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var n=e();for(var r in n)("object"==typeof exports?exports:t)[r]=n[r]}}(this,(()=>(()=>{"use strict";var t={d:(e,n)=>{for(var r in n)t.o(n,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{fbClient:()=>R});var n,r,i,o,a=new(function(){function t(t){this.events=t||{}}return t.prototype.subscribe=function(t,e){var n=this;return(this.events[t]||(this.events[t]=[])).push(e),{unsubscribe:function(){return n.events[t]&&n.events[t].splice(n.events[t].indexOf(e)>>>0,1)}}},t.prototype.unsubscribe=function(t,e){this.events[t]&&this.events[t].splice(this.events[t].indexOf(e)>>>0,1)},t.prototype.emit=function(t){for(var e=[],n=1;n<arguments.length;n++)e[n-1]=arguments[n];(this.events[t]||[]).forEach((function(t){return t.apply(void 0,e)}))},t}()),u="insights.flush",s="featureflag.evaluated.topic",c="featureflag.evaluated.buffer.topic",l="network.websocket.reconnect",f="fb-user",p=window.location.search,d=new URLSearchParams(p).get("debugmode"),h={logDebug:function(){for(var t=[],e=0;e<arguments.length;e++)t[e]=arguments[e];"true"===d&&console.log.apply(console,t)},log:function(){for(var t=[],e=0;e<arguments.length;e++)t[e]=arguments[e];console.log.apply(console,t)}};!function(t){t[t.featureFlagUsage=1]="featureFlagUsage",t[t.customEvent=2]="customEvent",t[t.pageView=3]="pageView",t[t.click=4]="click"}(n||(n={})),function(t){t.string="string",t.boolean="boolean",t.number="number",t.json="json"}(r||(r={})),function(t){t.full="full",t.patch="patch"}(i||(i={})),function(t){t.update="update"}(o||(o={}));const v=function(){function t(){}return t.partialEndpoint=function(t){return"You have set custom uris without specifying the ".concat(t," URI; connections may not work properly")},t.invalidParam=function(t){return"The ".concat(t," option is not passed in or its value is invalid")},t.mandatory=function(t){return"".concat(t," is mandatory")},t}();function g(t){var e;if(!t)return"";var n="".concat(t.keyId,",").concat(t.name),r=null===(e=t.customizedProperties)||void 0===e?void 0:e.map((function(t){return"".concat(t.name,":").concat(t.value)})).join(",");return"".concat(n,",").concat(r)}function y(t,e){switch(t){case r.string:return e;case r.boolean:return"true"===e||"false"!==e&&(h.log("expected boolean value, but got ".concat(e)),e);case r.number:return"string"!=typeof(n=e)||isNaN(n)||isNaN(parseFloat(n))?(h.log("expected numeric value, but got ".concat(e)),e):+e;case r.json:try{return JSON.parse(e)}catch(t){return h.log("expected json value, but got ".concat(e)),e}default:return h.log("unexpected variation type ".concat(t," for ").concat(e)),e}var n}function m(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(t){var e=16*Math.random()|0;return("x"==t?e:3&e|8).toString(16)}))}function b(t){if(!t)return v.mandatory("user");var e=t.keyId,n=t.name;return null==e||""===e.trim()?v.mandatory("user.keyId"):null==n||""===n.trim()?v.mandatory("user.name"):null}function w(t){return null==t||""===t.trim()}var x={0:"Q",1:"B",2:"W",3:"S",4:"P",5:"H",6:"D",7:"X",8:"Z",9:"U"};function _(t,e){var n="000000000000"+t;return n.slice(n.length-e).split("").map((function(t){return x[t]})).join("")}var k="fb-datastore",S=function(){function t(){this._userId=null,this._store={featureFlags:{}}}return Object.defineProperty(t.prototype,"userId",{set:function(t){this._userId=t,this._loadFromStorage()},enumerable:!1,configurable:!0}),t.prototype.getFeatureFlag=function(t){return this._store.featureFlags[t]},t.prototype.getVariation=function(t){var e=this._store.featureFlags[t];if(e)return a.emit(s,{insightType:n.featureFlagUsage,id:e.id,timestamp:Date.now(),sendToExperiment:e.sendToExperiment,variation:e.variationOptions.find((function(t){return t.value===e.variation}))}),y(e.variationType,e.variation)},t.prototype.setFullData=function(t){this._store={featureFlags:{}},this._dumpToStorage(this._store),this.updateBulkFromRemote(t)},t.prototype.getFeatureFlags=function(){return this._store.featureFlags},t.prototype.updateStorageBulk=function(t,e,n){var r=localStorage.getItem(e),i=null;try{r&&r.trim().length>0&&(i=JSON.parse(r))}catch(t){h.logDebug("error while loading local data store: ".concat(e)+t)}if(i){var o=t.featureFlags;Object.keys(o).forEach((function(t){var e=o[t];(!i.featureFlags[t]||!n)&&(i.featureFlags[e.id]=Object.assign({},e))})),this._dumpToStorage(i,e)}},t.prototype.updateBulkFromRemote=function(t){var e="".concat(k,"-").concat(this._userId);this.updateStorageBulk(t,e,!1),this._loadFromStorage()},t.prototype._emitUpdateEvents=function(t){t.length>0&&(t.forEach((function(t){t.id;var e=t.operation,n=t.data;return a.emit("ff_".concat(e,":").concat(n.id),n)})),a.emit("ff_".concat(o.update),t.map((function(t){return t.data}))))},t.prototype._dumpToStorage=function(t,e){if(t){var n=e||"".concat(k,"-").concat(this._userId);localStorage.setItem(n,JSON.stringify(t))}else{var r="".concat(k,"-").concat(this._userId);localStorage.setItem(r,JSON.stringify(this._store))}},t.prototype._loadFromStorage=function(){var t=this;try{var e="".concat(k,"-").concat(this._userId),n=localStorage.getItem(e);if(n&&n.trim().length>0){var r=JSON.parse(n),i=Object.keys(r.featureFlags).filter((function(e){var n=r.featureFlags[e],i=t._store.featureFlags[e];return!i||n.variation!==i.variation||n.variationType!==i.variationType})).map((function(e){var n=r.featureFlags[e],i=t._store.featureFlags[e];return{id:e,operation:o.update,sendToExperiment:n.sendToExperiment,data:{id:e,oldValue:i?y(i.variationType,i.variation):void 0,newValue:y(n.variationType,n.variation)}}}));this._store=r,this._emitUpdateEvents(i)}else this._store={featureFlags:{}}}catch(t){h.logDebug("error while loading local data store: "+t)}},t}();const T=new S;var F=function(){return F=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var i in e=arguments[n])Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},F.apply(this,arguments)},E={},O=[];const D=new(function(){function t(){this._key=m()}return t.prototype.setKey=function(t){this._key=t||this._key},t.prototype.throttle=function(t,e){var n=0;return function(){for(var r=[],i=0;i<arguments.length;i++)r[i]=arguments[i];clearTimeout(n),n=setTimeout(t.bind.apply(t,function(t,e,n){if(n||2===arguments.length)for(var r,i=0,o=e.length;i<o;i++)!r&&i in e||(r||(r=Array.prototype.slice.call(e,0,i)),r[i]=e[i]);return t.concat(r||Array.prototype.slice.call(e))}([null],r,!1)),e||0)}},t.prototype.throttleAsync=function(t){var e=this,n=!1;return function(){for(var r=[],i=0;i<arguments.length;i++)r[i]=arguments[i];return o=this,a=void 0,s=function(){var i,o,a,u;return function(t,e){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function u(u){return function(s){return function(u){if(n)throw new TypeError("Generator is already executing.");for(;o&&(o=0,u[0]&&(a=0)),a;)try{if(n=1,r&&(i=2&u[0]?r.return:u[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,u[1])).done)return i;switch(r=0,i&&(u=[2&u[0],i.value]),u[0]){case 0:case 1:i=u;break;case 4:return a.label++,{value:u[1],done:!1};case 5:a.label++,r=u[1],u=[0];continue;case 7:u=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==u[0]&&2!==u[0])){a=0;continue}if(3===u[0]&&(!i||u[1]>i[0]&&u[1]<i[3])){a.label=u[1];break}if(6===u[0]&&a.label<i[1]){a.label=i[1],i=u;break}if(i&&a.label<i[2]){a.label=i[2],a.ops.push(u);break}i[2]&&a.ops.pop(),a.trys.pop();continue}u=e.call(t,a)}catch(t){u=[6,t],r=0}finally{n=i=0}if(5&u[0])throw u[1];return{value:u[0]?u[1]:void 0,done:!0}}([u,s])}}}(this,(function(s){switch(s.label){case 0:return i=function(t){var n=t.map((function(t){return"object"==typeof t&&"function"!=typeof t&&null!==t?Array.isArray(t)?t.map((function(t){return F(F({},t),{timestamp:null})})):F(F({},t),{timestamp:null}):t}));return e._key+JSON.stringify(n)}(r),o=O.findIndex((function(t){return t===i})),n&&-1!==o?[3,2]:(n=!0,-1===o&&O.push(i),a=E,u=i,[4,t.apply(null,r)]);case 1:a[u]=s.sent(),setTimeout((function(){n=!1}),0),s.label=2;case 2:return[2,E[i]]}}))},new((u=void 0)||(u=Promise))((function(t,e){function n(t){try{i(s.next(t))}catch(t){e(t)}}function r(t){try{i(s.throw(t))}catch(t){e(t)}}function i(e){var i;e.done?t(e.value):(i=e.value,i instanceof u?i:new u((function(t){t(i)}))).then(n,r)}i((s=s.apply(o,a||[])).next())}));var o,a,u,s}},t}());var I=function(){return I=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var i in e=arguments[n])Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},I.apply(this,arguments)},j=function(t,e,n,r){return new(n||(n=Promise))((function(i,o){function a(t){try{s(r.next(t))}catch(t){o(t)}}function u(t){try{s(r.throw(t))}catch(t){o(t)}}function s(t){var e;t.done?i(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(a,u)}s((r=r.apply(t,e||[])).next())}))},P=function(t,e){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function u(u){return function(s){return function(u){if(n)throw new TypeError("Generator is already executing.");for(;o&&(o=0,u[0]&&(a=0)),a;)try{if(n=1,r&&(i=2&u[0]?r.return:u[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,u[1])).done)return i;switch(r=0,i&&(u=[2&u[0],i.value]),u[0]){case 0:case 1:i=u;break;case 4:return a.label++,{value:u[1],done:!1};case 5:a.label++,r=u[1],u=[0];continue;case 7:u=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==u[0]&&2!==u[0])){a=0;continue}if(3===u[0]&&(!i||u[1]>i[0]&&u[1]<i[3])){a.label=u[1];break}if(6===u[0]&&a.label<i[1]){a.label=i[1],i=u;break}if(i&&a.label<i[2]){a.label=i[2],a.ops.push(u);break}i[2]&&a.ops.pop(),a.trys.pop();continue}u=e.call(t,a)}catch(t){u=[6,t],r=0}finally{n=i=0}if(5&u[0])throw u[1];return{value:u[0]?u[1]:void 0,done:!0}}([u,s])}}},U=[250,500,1e3,2e3,4e3,8e3],N=new(function(){function t(){var t=this;this.retryCounter=0,this.sendInsights=D.throttleAsync((function(e){return j(t,void 0,void 0,(function(){var t,r,i=this;return P(this,(function(o){switch(o.label){case 0:if(!this.secret||!this.user||!e||0===e.length)return[2];o.label=1;case 1:return o.trys.push([1,3,,4]),t=[{user:this.__getUserInfo(),variations:e.filter((function(t){return t.insightType===n.featureFlagUsage})).map((function(t){return{featureFlagKey:t.id,sendToExperiment:t.sendToExperiment,timestamp:t.timestamp,variation:{id:t.variation.id,value:t.variation.value}}})),metrics:e.filter((function(t){return t.insightType!==n.featureFlagUsage})).map((function(t){return{route:location.pathname,timestamp:t.timestamp,numericValue:null===t.numericValue||void 0===t.numericValue?1:t.numericValue,appType:i.appType,eventName:t.eventName,type:t.type}}))}],[4,M("".concat(this.eventsUri,"/api/public/insight/track"),t,{Authorization:this.secret})];case 2:return o.sent(),[3,4];case 3:return r=o.sent(),h.logDebug(r),[3,4];case 4:return[2]}}))}))}))}return t.prototype.init=function(t,e,n,r){this.streamingUri=t,this.eventsUri=e,this.secret=n,this.appType=r},t.prototype.identify=function(t,e){var n;this.user=I({},t),D.setKey(null===(n=this.user)||void 0===n?void 0:n.keyId),e&&this.socket&&this.sendUserIdentifyMessage(0)},t.prototype.sendUserIdentifyMessage=function(t){var e,n,r=this.user,i={messageType:"data-sync",data:{user:{name:r.name,keyId:r.keyId,customizedProperties:r.customizedProperties},timestamp:t}};try{(null===(e=this.socket)||void 0===e?void 0:e.readyState)===WebSocket.OPEN?(h.logDebug("sending user identify message"),null===(n=this.socket)||void 0===n||n.send(JSON.stringify(i))):h.logDebug("didn't send user identify message because socket not open")}catch(t){h.logDebug(t)}},t.prototype.reconnect=function(){this.socket=null;var t=U[Math.min(this.retryCounter++,U.length-1)];setTimeout((function(){h.logDebug("emit reconnect event"),a.emit(l,{})}),t),h.logDebug(t)},t.prototype.sendPingMessage=function(){var t=this,e={messageType:"ping",data:null};setTimeout((function(){var n;try{(null===(n=t.socket)||void 0===n?void 0:n.readyState)===WebSocket.OPEN?(h.logDebug("sending ping"),t.socket.send(JSON.stringify(e)),t.sendPingMessage()):(h.logDebug("socket closed at ".concat(new Date)),t.reconnect())}catch(t){h.logDebug(t)}}),18e3)},t.prototype.createConnection=function(t,e){var n=this;if(n.socket)e({});else{var r=Date.now(),i="".concat(this.streamingUri,"/streaming?type=client&token=").concat(function(t){t=t.replace(/=*$/,"");var e=Date.now(),n=_(e,e.toString().length),r=Math.max(Math.floor(Math.random()*t.length),2);return"".concat(_(r,3)).concat(_(n.length,2)).concat(t.slice(0,r)).concat(n).concat(t.slice(r))}(this.secret));n.socket=new WebSocket(i),n.socket.addEventListener("open",(function(e){n.retryCounter=0,h.logDebug("Connection time: ".concat(Date.now()-r," ms")),n.sendUserIdentifyMessage(t),n.sendPingMessage()})),n.socket.addEventListener("close",(function(t){h.logDebug("close"),4003!==t.code&&n.reconnect()})),n.socket.addEventListener("error",(function(t){h.logDebug("error")})),n.socket.addEventListener("message",(function(t){var n=JSON.parse(t.data);"data-sync"===n.messageType&&(e(n.data),n.data.featureFlags.length>0&&h.logDebug("socket push update time(ms): ",Date.now()-n.data.featureFlags[0].timestamp))}))}},t.prototype.__getUserInfo=function(){var t=this.user;return{name:t.name,keyId:t.keyId,customizedProperties:t.customizedProperties}},t}());function M(t,e,n){return void 0===t&&(t=""),void 0===e&&(e={}),void 0===n&&(n={}),j(this,void 0,void 0,(function(){var r,i;return P(this,(function(o){switch(o.label){case 0:return o.trys.push([0,2,,3]),[4,fetch(t,{method:"POST",headers:Object.assign({"Content-Type":"application/json"},n),body:JSON.stringify(e)})];case 1:return[2,200===(r=o.sent()).status?r.json():{}];case 2:return i=o.sent(),h.logDebug(i),[2,{}];case 3:return[2]}}))}))}var V=function(){function t(t,e){void 0===t&&(t=0),void 0===e&&(e=""),this.flushLimit=t,this.arriveflushLimitTopic=e,this.queue=[]}return t.prototype.add=function(t){this.queue.push(t),this.flushLimit>0&&this.queue.length>=this.flushLimit&&a.emit(this.arriveflushLimitTopic,{})},t.prototype.flush=function(){var t=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,o=e.length;i<o;i++)!r&&i in e||(r||(r=Array.prototype.slice.call(e,0,i)),r[i]=e[i]);return t.concat(r||Array.prototype.slice.call(e))}([],this.queue,!0);return this.queue=[],t},t}(),A=function(){return A=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var i in e=arguments[n])Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},A.apply(this,arguments)},C=function(t,e,n,r){return new(n||(n=Promise))((function(i,o){function a(t){try{s(r.next(t))}catch(t){o(t)}}function u(t){try{s(r.throw(t))}catch(t){o(t)}}function s(t){var e;t.done?i(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(a,u)}s((r=r.apply(t,e||[])).next())}))},L=function(t,e){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function u(u){return function(s){return function(u){if(n)throw new TypeError("Generator is already executing.");for(;o&&(o=0,u[0]&&(a=0)),a;)try{if(n=1,r&&(i=2&u[0]?r.return:u[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,u[1])).done)return i;switch(r=0,i&&(u=[2&u[0],i.value]),u[0]){case 0:case 1:i=u;break;case 4:return a.label++,{value:u[1],done:!1};case 5:a.label++,r=u[1],u=[0];continue;case 7:u=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==u[0]&&2!==u[0])){a=0;continue}if(3===u[0]&&(!i||u[1]>i[0]&&u[1]<i[3])){a.label=u[1];break}if(6===u[0]&&a.label<i[1]){a.label=i[1],i=u;break}if(i&&a.label<i[2]){a.label=i[2],a.ops.push(u);break}i[2]&&a.ops.pop(),a.trys.pop();continue}u=e.call(t,a)}catch(t){u=[6,t],r=0}finally{n=i=0}if(5&u[0])throw u[1];return{value:u[0]?u[1]:void 0,done:!0}}([u,s])}}},z=function(t,e,n){if(n||2===arguments.length)for(var r,i=0,o=e.length;i<o;i++)!r&&i in e||(r||(r=Array.prototype.slice.call(e,0,i)),r[i]=e[i]);return t.concat(r||Array.prototype.slice.call(e))};function J(){var t=function(){var t=localStorage.getItem("fb-guid");if(t)return t;var e=m();return localStorage.setItem("fb-guid",e),e}();return{name:t,keyId:t}}function B(t){return Object.keys(t).map((function(e){var n=t[e],i=n.id,o=n.variation,a=t[e].variationType||r.string;return{id:i,variation:y(a,o),variationType:a}}))}var q=function(){function t(){var t=this;this._readyEventEmitted=!1,this._insightsQueue=new V(1,u),this._featureFlagEvaluationBuffer=new V,this._option={secret:"",api:"",streamingUri:"",eventsUri:"",enableDataSync:!0,appType:"javascript"},this._readyPromise=new Promise((function(e,r){t.on("ready",(function(){var r=T.getFeatureFlags();if(e(B(r)),t._option.enableDataSync){var i=t._featureFlagEvaluationBuffer.flush().map((function(t){var e=r[t.id];if(!e)return h.log("Called unexisting feature flag: ".concat(t.id)),null;var i=e.variationOptions.find((function(e){return e.value===t.variationValue}));return i?h.logDebug("Sent buffered insight for feature flag: ".concat(t.id," with variation: ").concat(i.value)):h.log("Sent buffered insight for feature flag: ".concat(t.id," with unexisting default variation: ").concat(t.variationValue)),{insightType:n.featureFlagUsage,id:e.id,timestamp:t.timestamp,sendToExperiment:e.sendToExperiment,variation:i||{id:-1,value:t.variationValue}}}));N.sendInsights(i.filter((function(t){return!!t})))}}))})),a.subscribe(l,(function(){return C(t,void 0,void 0,(function(){var t;return L(this,(function(e){switch(e.label){case 0:return e.trys.push([0,2,,3]),h.logDebug("reconnecting"),[4,this.dataSync()];case 1:return e.sent(),this._readyEventEmitted||(this._readyEventEmitted=!0,a.emit("ready",B(T.getFeatureFlags()))),[3,3];case 2:return t=e.sent(),h.log("data sync error",t),[3,3];case 3:return[2]}}))}))})),a.subscribe(c,(function(e){t._featureFlagEvaluationBuffer.add(e)})),a.subscribe(u,(function(){t._option.enableDataSync&&N.sendInsights(t._insightsQueue.flush())})),a.subscribe(s,(function(e){t._insightsQueue.add(e)})),a.subscribe("insights.topic",(function(e){t._insightsQueue.add(e)}))}return t.prototype.on=function(t,e){a.subscribe(t,e)},t.prototype.off=function(t,e){a.unsubscribe(t,e)},t.prototype.waitUntilReady=function(){return this._readyPromise},t.prototype.init=function(t){var e;return C(this,void 0,void 0,(function(){var n;return L(this,(function(r){switch(r.label){case 0:return n=function(t){if(null==t)return v.mandatory("option");var e=t.streamingUri,n=t.eventsUri,r=t.secret,i=t.anonymous,o=t.user,a=t.enableDataSync,u=w(e),s=w(n);if(a&&(u||s)){if(s)return v.partialEndpoint("eventsUri");if(u)return v.partialEndpoint("streamingUri")}return a&&w(r)?v.invalidParam("secret"):0!=!!i||o?o?b(o):null:v.mandatory("user")}(A(A({},this._option),t)),null!==n?(h.log(n),[2]):(this._option=A(A(A({},this._option),t),{api:null===(e=t.api||this._option.api)||void 0===e?void 0:e.replace(/\/$/,"")}),this._option.enableDataSync&&N.init(this._option.streamingUri,this._option.eventsUri,this._option.secret,this._option.appType),[4,this.identify(t.user||J())]);case 1:return r.sent(),[2]}}))}))},t.prototype.identify=function(t){var e;return C(this,void 0,void 0,(function(){var n,r;return L(this,(function(i){switch(i.label){case 0:return null!==(n=b(t))?(h.log(n),[2]):(t.customizedProperties=null===(e=t.customizedProperties)||void 0===e?void 0:e.map((function(t){return{name:t.name,value:"".concat(t.value)}})),r=g(t)!==localStorage.getItem(f),this._option.user=Object.assign({},t),localStorage.setItem(f,g(this._option.user)),T.userId=this._option.user.keyId,N.identify(this._option.user,r),[4,this.bootstrap(this._option.bootstrap,r)]);case 1:return i.sent(),[2]}}))}))},t.prototype.logout=function(){return C(this,void 0,void 0,(function(){var t;return L(this,(function(e){switch(e.label){case 0:return t=J(),[4,this.identify(t)];case 1:return e.sent(),[2,t]}}))}))},t.prototype.bootstrap=function(t,e){return C(this,void 0,void 0,(function(){var n,i;return L(this,(function(o){switch(o.label){case 0:if((t=t||this._option.bootstrap)&&t.length>0&&(n={featureFlags:t.reduce((function(t,e){var n=e.id,i=e.variation,o=e.timestamp,a=e.variationOptions,u=e.sendToExperiment,s=e.variationType;return t[n]={id:n,variation:i,timestamp:o,variationOptions:a||[{id:1,value:i}],sendToExperiment:u,variationType:s||r.string},t}),{})},T.setFullData(n),h.logDebug("bootstrapped with full data")),!this._option.enableDataSync)return[3,4];o.label=1;case 1:return o.trys.push([1,3,,4]),[4,this.dataSync(e)];case 2:return o.sent(),[3,4];case 3:return i=o.sent(),h.log("data sync error",i),[3,4];case 4:return this._readyEventEmitted||(this._readyEventEmitted=!0,a.emit("ready",B(T.getFeatureFlags()))),[2]}}))}))},t.prototype.dataSync=function(t){return C(this,void 0,void 0,(function(){var e=this;return L(this,(function(n){return[2,new Promise((function(n,o){var a=t?0:Math.max.apply(Math,z(z([],Object.values(T.getFeatureFlags()).map((function(t){return t.timestamp})),!1),[0],!1));N.createConnection(a,(function(t){var o;if(t&&t.userKeyId===(null===(o=e._option.user)||void 0===o?void 0:o.keyId)){var a=t.featureFlags;switch(t.eventType){case i.full:case i.patch:var u={featureFlags:a.reduce((function(t,e){var n=e.id,i=e.variation,o=e.timestamp,a=e.variationOptions,u=e.sendToExperiment,s=e.variationType;return t[n]={id:n,variation:i,timestamp:o,variationOptions:a,sendToExperiment:u,variationType:s||r.string},t}),{})};t.eventType===i.full?(T.setFullData(u),h.logDebug("synchonized with full data")):(T.updateBulkFromRemote(u),h.logDebug("synchonized with partial data"));break;default:h.logDebug("invalid stream event type: "+t.eventType)}}n()}))}))]}))}))},t.prototype.variation=function(t,e){var n=Q(t,e);return void 0===n?e:n},t.prototype.boolVariation=function(t,e){var n=Q(t,e);return void 0===n?e:"true"===(null==n?void 0:n.toLocaleLowerCase())},t.prototype.getUser=function(){return A({},this._option.user)},t.prototype.sendCustomEvent=function(t){var e=this;(t||[]).forEach((function(t){return e._insightsQueue.add(A({insightType:n.customEvent,timestamp:Date.now(),type:"CustomEvent"},t))}))},t.prototype.sendFeatureFlagInsight=function(t,e){this.variation(t,e)},t.prototype.getAllFeatureFlags=function(){var t=T.getFeatureFlags();return Object.values(t).reduce((function(t,e){return t[e.id]=y(e.variationType,e.variation),t}),{})},t}(),Q=function(t,e){var n=T.getVariation(t);return void 0===n&&a.emit(c,{id:t,timestamp:Date.now(),variationValue:"".concat(e)}),n};const R=new q;var K=document.querySelector("html");return K&&(K.style.visibility="hidden",setTimeout((function(){return K.style.visibility="visible"}),500)),h.logDebug("version: 2.0.0"),e})()));
|
|
2
|
-
//# sourceMappingURL=featbit-js-client-sdk-2.0.0.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"featbit-js-client-sdk-2.0.0.js","mappings":"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","sources":["webpack://@featbit/js-client-sdk/webpack/universalModuleDefinition","webpack://@featbit/js-client-sdk/webpack/bootstrap","webpack://@featbit/js-client-sdk/webpack/runtime/define property getters","webpack://@featbit/js-client-sdk/webpack/runtime/hasOwnProperty shorthand","webpack://@featbit/js-client-sdk/webpack/runtime/make namespace object","webpack://@featbit/js-client-sdk/./src/events.ts","webpack://@featbit/js-client-sdk/./src/types.ts","webpack://@featbit/js-client-sdk/./src/constants.ts","webpack://@featbit/js-client-sdk/./src/logger.ts","webpack://@featbit/js-client-sdk/./src/optionMessages.ts","webpack://@featbit/js-client-sdk/./src/utils.ts","webpack://@featbit/js-client-sdk/./src/store.ts","webpack://@featbit/js-client-sdk/./src/throttleutil.ts","webpack://@featbit/js-client-sdk/./src/network.service.ts","webpack://@featbit/js-client-sdk/./src/queue.ts","webpack://@featbit/js-client-sdk/./src/featbit.ts","webpack://@featbit/js-client-sdk/./src/umd.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse {\n\t\tvar a = factory();\n\t\tfor(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n\t}\n})(this, () => {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","interface Events {\n [key: string]: Function[];\n}\n\nclass EventEmitter {\n public events: Events;\n constructor(events?: Events) {\n this.events = events || {};\n }\n\n public subscribe(name: string, cb: Function) {\n (this.events[name] || (this.events[name] = [])).push(cb);\n\n return {\n unsubscribe: () =>\n this.events[name] && this.events[name].splice(this.events[name].indexOf(cb) >>> 0, 1)\n };\n }\n\n public unsubscribe(name: string, cb: Function) {\n this.events[name] && this.events[name].splice(this.events[name].indexOf(cb) >>> 0, 1);\n }\n\n public emit(name: string, ...args: any[]): void {\n (this.events[name] || []).forEach(fn => fn(...args));\n }\n}\n\nexport const eventHub = new EventEmitter();","export type FeatureFlagValue = any;\n\nexport interface IFeatureFlagSet {\n [key: string]: FeatureFlagValue;\n}\n\nexport interface IFeatureFlagChange {\n id: string,\n oldValue: FeatureFlagValue,\n newValue: FeatureFlagValue\n}\n\nexport interface IOption {\n secret: string,\n anonymous?: boolean,\n bootstrap?: IFeatureFlag[],\n streamingUri?: string,\n eventsUri?: string,\n\n // deprecated, this option will be removed in the future, please use streamingUri and eventsUri instead\n api?: string,\n\n appType?: string,\n user?: IUser,\n enableDataSync?: boolean\n}\n\nexport interface IUser {\n name: string,\n keyId: string,\n customizedProperties?: ICustomizedProperty[]\n}\n\nexport interface ICustomizedProperty {\n name: string,\n value: string | number | boolean\n}\n\nexport interface IVariationOption {\n id: number,\n value: FeatureFlagValue\n}\n\nexport interface IFeatureFlagVariation {\n id?: string,\n sendToExperiment?: boolean\n timestamp?: number,\n variation?: {\n id: number,\n value: FeatureFlagValue,\n }\n}\n\nexport interface IFeatureFlagVariationBuffer {\n id: string,\n timestamp: number,\n variationValue: FeatureFlagValue\n}\n\nexport enum InsightType {\n featureFlagUsage = 1,\n customEvent = 2,\n pageView = 3,\n click = 4\n}\n\nexport enum VariationDataType {\n string = 'string',\n boolean = 'boolean',\n number = 'number',\n json = 'json',\n}\n\nexport interface IInsight extends IFeatureFlagVariation, ICustomEvent {\n insightType: InsightType\n}\n\nexport interface IFeatureFlagBase {\n id: string, // the keyname\n variation: FeatureFlagValue,\n variationType: VariationDataType\n}\n\nexport interface IFeatureFlag extends IFeatureFlagBase{\n sendToExperiment: boolean,\n timestamp: number,\n variationOptions: IVariationOption[]\n}\n\nexport interface IDataStore {\n featureFlags: { [key: string]: IFeatureFlag }\n}\n\nexport enum StreamResponseEventType {\n full = 'full',\n patch = 'patch'\n}\n\nexport enum FeatureFlagUpdateOperation {\n update = 'update'\n}\n\nexport interface IStreamResponse {\n eventType: StreamResponseEventType,\n userKeyId: string,\n featureFlags: IFeatureFlag[]\n}\n\nexport interface ICustomEvent {\n type?: string,\n eventName: string,\n numericValue?: number\n}","export const insightsFlushTopic = 'insights.flush';\nexport const featureFlagEvaluatedTopic = 'featureflag.evaluated.topic';\nexport const featureFlagEvaluatedBufferTopic = 'featureflag.evaluated.buffer.topic';\nexport const websocketReconnectTopic = 'network.websocket.reconnect';\nexport const debugModeQueryStr = 'debugmode'; // will print debug logs if true\nexport const insightsTopic = 'insights.topic';\nexport const currentUserStorageKey = 'fb-user';\n","import { debugModeQueryStr } from \"./constants\";\n\n// get debug mode from query string\nconst queryString = window.location.search;\nconst urlParams = new URLSearchParams(queryString);\nconst debugModeParam = urlParams.get(debugModeQueryStr);\n\nexport const logger = {\n logDebug(...args) {\n if (debugModeParam === 'true') {\n console.log(...args);\n }\n },\n\n log(...args) {\n console.log(...args);\n }\n}","export default class OptionMessages {\n static partialEndpoint(name: string): string {\n return `You have set custom uris without specifying the ${ name } URI; connections may not work properly`;\n }\n\n static invalidParam(name: string): string {\n return `The ${ name } option is not passed in or its value is invalid`;\n }\n\n static mandatory(name: string): string {\n return `${ name } is mandatory`;\n }\n}","import {FeatureFlagValue, IOption, IUser, VariationDataType} from \"./types\";\nimport {logger} from \"./logger\";\nimport OptionMessages from \"./optionMessages\";\n\n\n// generate default user info\nexport function generateorGetGuid(): string {\n let guid = localStorage.getItem(\"fb-guid\");\n if (guid) {\n return guid;\n }\n else {\n const id = uuid();\n localStorage.setItem(\"fb-guid\", id);\n return id;\n }\n}\n\nexport function serializeUser(user: IUser | undefined): string {\n if (!user) {\n return '';\n }\n\n const builtInProperties = `${user.keyId},${user.name}`;\n\n const customizedProperties = user.customizedProperties?.map(p => `${p.name}:${p.value}`).join(',');\n\n return `${builtInProperties},${customizedProperties}`;\n}\n\nexport function isNumeric(str: string) {\n if (typeof str != \"string\") return false // we only process strings!\n // @ts-ignore\n return !isNaN(str) && // use type coercion to parse the _entirety_ of the string (`parseFloat` alone does not do this)...\n !isNaN(parseFloat(str)) // ...and ensure strings of whitespace fail\n}\n\nexport function parseVariation(type: VariationDataType, value: string): FeatureFlagValue {\n switch (type) {\n case VariationDataType.string:\n return value;\n case VariationDataType.boolean:\n if (value === 'true') {\n return true;\n }\n\n if (value === 'false') {\n return false;\n }\n\n logger.log(`expected boolean value, but got ${value}`);\n return value;\n case VariationDataType.number:\n if (isNumeric(value)) {\n return +value;\n }\n\n logger.log(`expected numeric value, but got ${value}`);\n return value;\n case VariationDataType.json:\n try {\n return JSON.parse(value);\n }\n catch (e) {\n logger.log(`expected json value, but got ${value}`);\n return value;\n }\n default:\n logger.log(`unexpected variation type ${type} for ${value}`);\n return value;\n }\n}\n\nexport function uuid(): string {\n let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\n var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n\n return uuid;\n}\n\nexport function validateUser(user: IUser): string | null {\n if (!user) {\n return OptionMessages.mandatory('user')\n }\n\n const { keyId, name } = user;\n\n if (keyId === undefined || keyId === null || keyId.trim() === '') {\n return OptionMessages.mandatory('user.keyId');\n }\n\n if (name === undefined || name === null || name.trim() === '') {\n return OptionMessages.mandatory('user.name');\n }\n\n return null;\n}\n\nexport function isNullOrUndefinedOrWhiteSpace(value?: string): boolean {\n return value === null || value === undefined || value.trim() === '';\n}\n\nexport function validateOption(option: IOption): string | null {\n if (option === undefined || option === null) {\n return OptionMessages.mandatory('option')\n }\n\n const { streamingUri, eventsUri, secret, anonymous, user, enableDataSync } = option;\n\n const streamingUriMissing = isNullOrUndefinedOrWhiteSpace(streamingUri);\n const eventsUriMissing = isNullOrUndefinedOrWhiteSpace(eventsUri);\n\n if (enableDataSync && (streamingUriMissing || eventsUriMissing))\n {\n if (eventsUriMissing) {\n return OptionMessages.partialEndpoint('eventsUri');\n }\n\n if (streamingUriMissing) {\n return OptionMessages.partialEndpoint('streamingUri');\n }\n }\n\n if (enableDataSync && isNullOrUndefinedOrWhiteSpace(secret)) {\n return OptionMessages.invalidParam('secret');\n }\n\n // validate user\n if (!!anonymous === false && !user) {\n return OptionMessages.mandatory('user');\n }\n\n if (user) {\n return validateUser(user);\n }\n\n return null;\n}\n\n/********************** encode text begin *****************************/\nconst alphabet = {\n \"0\": \"Q\",\n \"1\": \"B\",\n \"2\": \"W\",\n \"3\": \"S\",\n \"4\": \"P\",\n \"5\": \"H\",\n \"6\": \"D\",\n \"7\": \"X\",\n \"8\": \"Z\",\n \"9\": \"U\",\n}\n\nfunction encodeNumber(param: number, length: number): string {\n var s = \"000000000000\" + param;\n const numberWithLeadingZeros = s.slice(s.length - length);\n return numberWithLeadingZeros.split('').map(n => alphabet[n]).join('');\n}\n\n// generate connection token\nexport function generateConnectionToken(text: string): string {\n text = text.replace(/=*$/, '');\n const timestamp = Date.now();\n const timestampCode = encodeNumber(timestamp, timestamp.toString().length);\n // get random number less than the length of the text as the start point, and it must be greater or equal to 2\n const start = Math.max(Math.floor(Math.random() * text.length), 2);\n\n return `${encodeNumber(start, 3)}${encodeNumber(timestampCode.length, 2)}${text.slice(0, start)}${timestampCode}${text.slice(start)}`;\n}\n\n/********************** encode text end *****************************/\n","import {featureFlagEvaluatedTopic} from \"./constants\";\nimport {eventHub} from \"./events\";\nimport {logger} from \"./logger\";\nimport {\n FeatureFlagUpdateOperation, FeatureFlagValue,\n IDataStore,\n IFeatureFlag,\n IFeatureFlagChange,\n InsightType\n} from \"./types\";\nimport {parseVariation} from \"./utils\";\n\nconst DataStoreStorageKey = 'fb-datastore';\n\nclass Store {\n private _userId: string | null = null;\n\n private _store: IDataStore = {\n featureFlags: {} as { [key: string]: IFeatureFlag }\n }\n\n constructor() { }\n\n set userId(id: string) {\n this._userId = id;\n this._loadFromStorage();\n }\n\n getFeatureFlag(key: string): IFeatureFlag {\n return this._store.featureFlags[key];\n }\n\n getVariation(key: string): FeatureFlagValue {\n const featureFlag = this._store.featureFlags[key];\n\n if (!featureFlag) {\n return undefined;\n }\n\n eventHub.emit(featureFlagEvaluatedTopic, {\n insightType: InsightType.featureFlagUsage,\n id: featureFlag.id,\n timestamp: Date.now(),\n sendToExperiment: featureFlag.sendToExperiment,\n variation: featureFlag.variationOptions.find(o => o.value === featureFlag.variation)\n });\n\n const { variationType, variation } = featureFlag;\n\n return parseVariation(variationType, variation);\n }\n\n setFullData(data: IDataStore) {\n this._store = {\n featureFlags: {} as { [key: string]: IFeatureFlag }\n };\n\n this._dumpToStorage(this._store);\n this.updateBulkFromRemote(data);\n }\n\n getFeatureFlags(): { [key: string]: IFeatureFlag } {\n return this._store.featureFlags;\n }\n\n updateStorageBulk(data: IDataStore, storageKey: string, onlyInsertNewElement: boolean) {\n let dataStoreStr = localStorage.getItem(storageKey);\n let store: IDataStore | null = null;\n\n try {\n if (dataStoreStr && dataStoreStr.trim().length > 0) {\n store = JSON.parse(dataStoreStr);\n }\n } catch (err) {\n logger.logDebug(`error while loading local data store: ${storageKey}` + err);\n }\n\n if (!!store) {\n const { featureFlags } = data;\n\n Object.keys(featureFlags).forEach(id => {\n const remoteFf = featureFlags[id];\n const localFf = store!.featureFlags[id];\n\n const predicate = !localFf || !onlyInsertNewElement;\n if (predicate) {\n store!.featureFlags[remoteFf.id] = Object.assign({}, remoteFf);\n }\n });\n\n this._dumpToStorage(store, storageKey);\n }\n }\n\n updateBulkFromRemote(data: IDataStore) {\n const storageKey = `${DataStoreStorageKey}-${this._userId}`;\n\n this.updateStorageBulk(data, storageKey, false);\n\n this._loadFromStorage();\n }\n\n private _emitUpdateEvents(updatedFeatureFlags: any[]): void {\n if (updatedFeatureFlags.length > 0) {\n updatedFeatureFlags.forEach(({ id, operation, data }) => eventHub.emit(`ff_${operation}:${data.id}`, data));\n eventHub.emit(`ff_${FeatureFlagUpdateOperation.update}`, updatedFeatureFlags.map(item => item.data));\n }\n }\n\n private _dumpToStorage(store?: IDataStore, localStorageKey?: string): void {\n if (store) {\n const storageKey = localStorageKey || `${DataStoreStorageKey}-${this._userId}`;\n localStorage.setItem(storageKey, JSON.stringify(store));\n return;\n }\n const storageKey = `${DataStoreStorageKey}-${this._userId}`;\n localStorage.setItem(storageKey, JSON.stringify(this._store));\n }\n\n private _loadFromStorage(): void {\n try {\n const storageKey = `${DataStoreStorageKey}-${this._userId}`;\n let dataStoreStr = localStorage.getItem(storageKey);\n\n let shouldDumpToStorage = false;\n\n if (dataStoreStr && dataStoreStr.trim().length > 0) {\n // compare _store and dataStoreStr data and send notification if different\n const storageData: IDataStore = JSON.parse(dataStoreStr);\n\n const updatedFeatureFlags = Object.keys(storageData.featureFlags).filter(key => {\n const storageFf = storageData.featureFlags[key];\n const ff = this._store.featureFlags[key];\n return !ff || storageFf.variation !== ff.variation || storageFf.variationType !== ff.variationType;\n }).map(key => {\n const storageFf = storageData.featureFlags[key];\n const ff = this._store.featureFlags[key];\n\n return {\n id: key,\n operation: FeatureFlagUpdateOperation.update,\n sendToExperiment: storageFf.sendToExperiment,\n data: {\n id: key,\n oldValue: ff ? parseVariation(ff.variationType, ff.variation): undefined,\n newValue: parseVariation(storageFf.variationType, storageFf.variation)\n } as IFeatureFlagChange\n }\n });\n\n this._store = storageData;\n this._emitUpdateEvents(updatedFeatureFlags);\n } else {\n this._store = {\n featureFlags: {} as { [key: string]: IFeatureFlag }\n };\n }\n\n if (shouldDumpToStorage) {\n this._dumpToStorage();\n }\n\n } catch (err) {\n logger.logDebug('error while loading local data store: ' + err);\n }\n }\n}\n\nexport default new Store();","import { uuid } from \"./utils\";\n\nconst API_CALL_RESULTS : {[key: string]: string} = {};\nconst FOOT_PRINTS: string[] = [];\nlet _throttleWait: number = 0; // send immediately\n\nclass ThrottleUtil {\n private _key: string;\n\n constructor(){\n this._key = uuid();\n }\n\n setKey(key: string) {\n this._key = key || this._key;\n }\n\n throttle(fn: Function, ms: number) {\n let timer:any = 0\n return function(...args) {\n clearTimeout(timer)\n timer = setTimeout(fn.bind(null, ...args), ms || 0)\n }\n }\n\n throttleAsync (callback: any): any {\n let waiting = false; \n \n let getFootprint = (args: any): string => {\n const params = args.map(arg => {\n if (\n typeof arg === 'object' &&\n typeof arg !== \"function\" &&\n arg !== null\n ) {\n if (Array.isArray(arg)) {\n return arg.map(a => ({...a, ...{timestamp: null}}))\n } else {\n return {...arg, ...{timestamp: null}};\n }\n }\n \n return arg;\n });\n \n return this._key + JSON.stringify(params);\n };\n \n return async function (...args) {\n const footprint = getFootprint(args);\n const idx = FOOT_PRINTS.findIndex(f => f === footprint);\n if (!waiting || idx === -1) {\n waiting = true;\n if (idx === -1) {\n FOOT_PRINTS.push(footprint);\n }\n \n API_CALL_RESULTS[footprint] = await callback.apply(null, args);\n \n setTimeout(function () {\n waiting = false;\n }, _throttleWait);\n }\n \n return API_CALL_RESULTS[footprint];\n }\n }\n}\n\nexport default new ThrottleUtil();\n\n\n","import { websocketReconnectTopic } from \"./constants\";\nimport { eventHub } from \"./events\";\nimport { logger } from \"./logger\";\nimport { IInsight, InsightType, IStreamResponse, IUser } from \"./types\";\nimport { generateConnectionToken } from \"./utils\";\nimport throttleUtil from \"./throttleutil\";\n\nconst socketConnectionIntervals = [250, 500, 1000, 2000, 4000, 8000];\n\nclass NetworkService {\n private user: IUser | undefined;\n private streamingUri: string | undefined;\n private eventsUri: string | undefined;\n private secret: string | undefined;\n private appType: string | undefined;\n\n private retryCounter = 0;\n\n constructor(){}\n\n init(streamingUri: string, eventsUri: string, secret: string, appType: string) {\n this.streamingUri = streamingUri;\n this.eventsUri = eventsUri;\n this.secret = secret;\n this.appType = appType;\n }\n\n identify(user: IUser, sendIdentifyMessage: boolean) {\n this.user = { ...user };\n throttleUtil.setKey(this.user?.keyId);\n\n if (sendIdentifyMessage && this.socket) {\n this.sendUserIdentifyMessage(0);\n }\n }\n\n private sendUserIdentifyMessage(timestamp: number) {\n const { name, keyId, customizedProperties } = this.user!;\n const payload = {\n messageType: 'data-sync',\n data: {\n user: {\n name,\n keyId,\n customizedProperties,\n },\n timestamp\n }\n };\n\n try {\n if (this.socket?.readyState === WebSocket.OPEN) {\n logger.logDebug('sending user identify message');\n this.socket?.send(JSON.stringify(payload));\n } else {\n logger.logDebug(`didn't send user identify message because socket not open`);\n }\n } catch (err) {\n logger.logDebug(err);\n }\n }\n\n private socket: WebSocket | undefined | any;\n\n private reconnect() {\n this.socket = null;\n const waitTime = socketConnectionIntervals[Math.min(this.retryCounter++, socketConnectionIntervals.length - 1)];\n setTimeout(() => {\n logger.logDebug('emit reconnect event');\n eventHub.emit(websocketReconnectTopic, {});\n }, waitTime);\n logger.logDebug(waitTime);\n }\n\n private sendPingMessage() {\n const payload = {\n messageType: 'ping',\n data: null\n };\n\n setTimeout(() => {\n try {\n if (this.socket?.readyState === WebSocket.OPEN) {\n logger.logDebug('sending ping')\n this.socket.send(JSON.stringify(payload));\n this.sendPingMessage();\n } else {\n logger.logDebug(`socket closed at ${new Date()}`);\n this.reconnect();\n }\n } catch (err) {\n logger.logDebug(err);\n }\n }, 18000);\n }\n\n createConnection(timestamp: number, onMessage: (response: IStreamResponse) => any) {\n const that = this;\n if (that.socket) {\n onMessage({} as IStreamResponse);\n return;\n }\n\n const startTime = Date.now();\n // Create WebSocket connection.\n const url = `${this.streamingUri}/streaming?type=client&token=${generateConnectionToken(this.secret!)}`;\n that.socket = new WebSocket(url);\n\n // Connection opened\n that.socket.addEventListener('open', function (this: WebSocket, event) {\n that.retryCounter = 0;\n // this is the websocket instance to which the current listener is binded to, it's different from that.socket\n logger.logDebug(`Connection time: ${Date.now() - startTime} ms`);\n that.sendUserIdentifyMessage(timestamp);\n that.sendPingMessage();\n });\n \n // Connection closed\n that.socket.addEventListener('close', function (event) {\n logger.logDebug('close');\n if (event.code === 4003) { // do not reconnect when 4003\n return;\n }\n\n that.reconnect();\n });\n \n // Connection error\n that.socket!.addEventListener('error', function (event) {\n // reconnect\n logger.logDebug('error');\n });\n \n // Listen for messages\n that.socket.addEventListener('message', function (event) {\n const message = JSON.parse(event.data);\n if (message.messageType === 'data-sync') {\n onMessage(message.data);\n if (message.data.featureFlags.length > 0) {\n logger.logDebug('socket push update time(ms): ', Date.now() - message.data.featureFlags[0].timestamp);\n }\n }\n });\n }\n\n private __getUserInfo(): any {\n const { name, keyId, customizedProperties } = this.user!;\n return {\n name: name,\n keyId: keyId,\n customizedProperties: customizedProperties,\n }\n }\n\n sendInsights = throttleUtil.throttleAsync(async (data: IInsight[]): Promise<void> => {\n if (!this.secret || !this.user || !data || data.length === 0) {\n return;\n }\n \n try {\n const payload = [{\n user: this.__getUserInfo(),\n variations: data.filter(d => d.insightType === InsightType.featureFlagUsage).map(v => ({\n featureFlagKey: v.id,\n sendToExperiment: v.sendToExperiment,\n timestamp: v.timestamp,\n variation: {\n id: v.variation!.id,\n value: v.variation!.value\n }\n })),\n metrics: data.filter(d => d.insightType !== InsightType.featureFlagUsage).map(d => ({\n route: location.pathname,\n timestamp: d.timestamp,\n numericValue: d.numericValue === null || d.numericValue === undefined? 1 : d.numericValue,\n appType: this.appType,\n eventName: d.eventName,\n type: d.type\n }))\n }];\n \n await post(`${this.eventsUri}/api/public/insight/track`, payload, { Authorization: this.secret });\n } catch (err) {\n logger.logDebug(err);\n }\n })\n}\n\nexport const networkService = new NetworkService();\n\nexport async function post(url: string = '', data: any = {}, headers: { [key: string]: string } = {}) {\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: Object.assign({\n 'Content-Type': 'application/json'\n }, headers),\n body: JSON.stringify(data) // body data type must match \"Content-Type\" header\n });\n\n return response.status === 200 ? response.json() : {};\n } catch (err) {\n logger.logDebug(err);\n return {};\n }\n}\n\nexport async function get(url: string = '', headers: { [key: string]: string } = {}) {\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: Object.assign({\n 'Accept': 'application/json',\n 'Content-Type': 'application/json'\n }, headers)\n });\n\n return response.status === 200 ? response.json() : {};\n } catch (err) {\n logger.logDebug(err);\n return null;\n }\n}\n","import { eventHub } from \"./events\";\n\nexport class Queue<T> {\n private queue: T[];\n // flushLimit === 0 means no limit\n // and \n constructor(private flushLimit: number = 0, private arriveflushLimitTopic: string = '') {\n this.queue = [];\n }\n\n add(element: T): void {\n this.queue.push(element);\n if (this.flushLimit > 0 && this.queue.length >= this.flushLimit) {\n eventHub.emit(this.arriveflushLimitTopic, {});\n }\n }\n\n flush(): T[] {\n const allElements = [...this.queue];\n this.queue = [];\n return allElements;\n }\n}","import { eventHub } from \"./events\";\nimport { logger } from \"./logger\";\nimport store from \"./store\";\nimport { networkService } from \"./network.service\";\nimport {\n FeatureFlagValue,\n ICustomEvent,\n IFeatureFlag,\n IFeatureFlagBase,\n IFeatureFlagSet,\n IFeatureFlagVariationBuffer,\n IInsight,\n InsightType,\n IOption,\n IStreamResponse,\n IUser,\n StreamResponseEventType,\n VariationDataType\n} from \"./types\";\nimport {\n generateorGetGuid,\n isNullOrUndefinedOrWhiteSpace,\n parseVariation,\n serializeUser,\n validateOption,\n validateUser\n} from \"./utils\";\nimport { Queue } from \"./queue\";\nimport {\n currentUserStorageKey,\n featureFlagEvaluatedBufferTopic,\n featureFlagEvaluatedTopic,\n insightsFlushTopic,\n insightsTopic,\n websocketReconnectTopic\n} from \"./constants\";\n\n\nfunction createOrGetAnonymousUser(): IUser {\n const sessionId = generateorGetGuid();\n\n return {\n name: sessionId,\n keyId: sessionId\n };\n}\n\nfunction mapFeatureFlagsToFeatureFlagBaseList(featureFlags: { [key: string]: IFeatureFlag }): IFeatureFlagBase[] {\n return Object.keys(featureFlags).map((cur) => {\n const {id, variation} = featureFlags[cur];\n const variationType = featureFlags[cur].variationType || VariationDataType.string;\n return {id, variation: parseVariation(variationType, variation), variationType};\n });\n}\n\nexport class FB {\n private _readyEventEmitted: boolean = false;\n private _readyPromise: Promise<IFeatureFlagBase[]>;\n\n private _insightsQueue: Queue<IInsight> = new Queue<IInsight>(1, insightsFlushTopic);\n private _featureFlagEvaluationBuffer: Queue<IFeatureFlagVariationBuffer> = new Queue<IFeatureFlagVariationBuffer>();\n private _option: IOption = {\n secret: '',\n api: '',\n streamingUri: '',\n eventsUri: '',\n enableDataSync: true,\n appType: 'javascript'\n };\n\n constructor() {\n this._readyPromise = new Promise<IFeatureFlagBase[]>((resolve, reject) => {\n this.on('ready', () => {\n const featureFlags = store.getFeatureFlags();\n resolve(mapFeatureFlagsToFeatureFlagBaseList(featureFlags));\n if (this._option.enableDataSync) {\n const buffered = this._featureFlagEvaluationBuffer.flush().map(f => {\n const featureFlag = featureFlags[f.id];\n if (!featureFlag) {\n logger.log(`Called unexisting feature flag: ${ f.id }`);\n return null;\n }\n\n const variation = featureFlag.variationOptions.find(o => o.value === f.variationValue);\n if (!variation) {\n logger.log(`Sent buffered insight for feature flag: ${ f.id } with unexisting default variation: ${ f.variationValue }`);\n } else {\n logger.logDebug(`Sent buffered insight for feature flag: ${ f.id } with variation: ${ variation.value }`);\n }\n\n return {\n insightType: InsightType.featureFlagUsage,\n id: featureFlag.id,\n timestamp: f.timestamp,\n sendToExperiment: featureFlag.sendToExperiment,\n variation: variation || {id: -1, value: f.variationValue}\n }\n });\n\n networkService.sendInsights(buffered.filter(x => !!x));\n }\n });\n });\n\n // reconnect to websocket\n eventHub.subscribe(websocketReconnectTopic, async () => {\n try {\n logger.logDebug('reconnecting');\n await this.dataSync();\n if (!this._readyEventEmitted) {\n this._readyEventEmitted = true;\n eventHub.emit('ready', mapFeatureFlagsToFeatureFlagBaseList(store.getFeatureFlags()));\n }\n } catch (err) {\n logger.log('data sync error', err);\n }\n });\n\n eventHub.subscribe(featureFlagEvaluatedBufferTopic, (data: IFeatureFlagVariationBuffer) => {\n this._featureFlagEvaluationBuffer.add(data);\n });\n\n // track feature flag usage data\n eventHub.subscribe(insightsFlushTopic, () => {\n if (this._option.enableDataSync) {\n networkService.sendInsights(this._insightsQueue.flush());\n }\n });\n\n eventHub.subscribe(featureFlagEvaluatedTopic, (data: IInsight) => {\n this._insightsQueue.add(data);\n });\n\n eventHub.subscribe(insightsTopic, (data: IInsight) => {\n this._insightsQueue.add(data);\n });\n }\n\n on(name: string, cb: Function) {\n eventHub.subscribe(name, cb);\n }\n\n off(name: string, cb: Function) {\n eventHub.unsubscribe(name, cb);\n }\n\n waitUntilReady(): Promise<IFeatureFlagBase[]> {\n return this._readyPromise;\n }\n\n async init(option: IOption) {\n const validateOptionResult = validateOption({...this._option, ...option});\n if (validateOptionResult !== null) {\n logger.log(validateOptionResult);\n return;\n }\n\n this._option = {\n ...this._option,\n ...option,\n ...{\n api: (option.api || this._option.api)?.replace(/\\/$/, '')\n }\n };\n\n if (this._option.enableDataSync) {\n networkService.init(this._option.streamingUri!, this._option.eventsUri!, this._option.secret, this._option.appType!);\n }\n\n await this.identify(option.user || createOrGetAnonymousUser());\n }\n\n async identify(user: IUser): Promise<void> {\n const validateUserResult = validateUser(user);\n if (validateUserResult !== null) {\n logger.log(validateUserResult);\n return;\n }\n\n user.customizedProperties = user.customizedProperties?.map(p => ({name: p.name, value: `${ p.value }`}));\n\n const isUserChanged = serializeUser(user) !== localStorage.getItem(currentUserStorageKey);\n this._option.user = Object.assign({}, user);\n localStorage.setItem(currentUserStorageKey, serializeUser(this._option.user));\n\n store.userId = this._option.user.keyId;\n networkService.identify(this._option.user, isUserChanged);\n\n await this.bootstrap(this._option.bootstrap, isUserChanged);\n }\n\n async logout(): Promise<IUser> {\n const anonymousUser = createOrGetAnonymousUser();\n await this.identify(anonymousUser);\n return anonymousUser;\n }\n\n /**\n * bootstrap with predefined feature flags.\n * @param {array} featureFlags the predefined feature flags.\n * @param {boolean} forceFullFetch if a forced full fetch should be made.\n * @return {Promise<void>} nothing.\n */\n async bootstrap(featureFlags?: IFeatureFlag[], forceFullFetch?: boolean): Promise<void> {\n featureFlags = featureFlags || this._option.bootstrap;\n if (featureFlags && featureFlags.length > 0) {\n const data = {\n featureFlags: featureFlags.reduce((res, curr) => {\n const {id, variation, timestamp, variationOptions, sendToExperiment, variationType} = curr;\n res[id] = {\n id,\n variation,\n timestamp,\n variationOptions: variationOptions || [{id: 1, value: variation}],\n sendToExperiment,\n variationType: variationType || VariationDataType.string\n };\n\n return res;\n }, {} as { [key: string]: IFeatureFlag })\n };\n\n store.setFullData(data);\n logger.logDebug('bootstrapped with full data');\n }\n\n if (this._option.enableDataSync) {\n // start data sync\n try {\n await this.dataSync(forceFullFetch);\n } catch (err) {\n logger.log('data sync error', err);\n }\n }\n\n if (!this._readyEventEmitted) {\n this._readyEventEmitted = true;\n eventHub.emit('ready', mapFeatureFlagsToFeatureFlagBaseList(store.getFeatureFlags()));\n }\n }\n\n private async dataSync(forceFullFetch?: boolean): Promise<any> {\n return new Promise<void>((resolve, reject) => {\n const timestamp = forceFullFetch ? 0 : Math.max(...Object.values(store.getFeatureFlags()).map(ff => ff.timestamp), 0);\n\n networkService.createConnection(timestamp, (message: IStreamResponse) => {\n if (message && message.userKeyId === this._option.user?.keyId) {\n const {featureFlags} = message;\n\n switch (message.eventType) {\n case StreamResponseEventType.full: // full data\n case StreamResponseEventType.patch: // partial data\n const data = {\n featureFlags: featureFlags.reduce((res, curr) => {\n const {id, variation, timestamp, variationOptions, sendToExperiment, variationType} = curr;\n res[id] = {\n id,\n variation,\n timestamp,\n variationOptions,\n sendToExperiment,\n variationType: variationType || VariationDataType.string\n };\n\n return res;\n }, {} as { [key: string]: IFeatureFlag })\n };\n\n if (message.eventType === StreamResponseEventType.full) {\n store.setFullData(data);\n logger.logDebug('synchonized with full data');\n } else {\n store.updateBulkFromRemote(data);\n logger.logDebug('synchonized with partial data');\n }\n\n break;\n default:\n logger.logDebug('invalid stream event type: ' + message.eventType);\n break;\n }\n }\n\n resolve();\n });\n });\n }\n\n variation(key: string, defaultResult: FeatureFlagValue): FeatureFlagValue {\n const variation = variationWithInsightBuffer(key, defaultResult);\n return variation === undefined ? defaultResult : variation;\n }\n\n /**\n * deprecated, you should use variation method directly\n */\n boolVariation(key: string, defaultResult: boolean): boolean {\n const variation = variationWithInsightBuffer(key, defaultResult);\n return variation === undefined ? defaultResult : variation?.toLocaleLowerCase() === 'true';\n }\n\n getUser(): IUser {\n return {...this._option.user!};\n }\n\n sendCustomEvent(data: ICustomEvent[]): void {\n (data || []).forEach(d => this._insightsQueue.add({\n insightType: InsightType.customEvent,\n timestamp: Date.now(),\n type: 'CustomEvent',\n ...d\n }))\n }\n\n sendFeatureFlagInsight(key: string, variation: string) {\n this.variation(key, variation);\n }\n\n getAllFeatureFlags(): IFeatureFlagSet {\n const flags = store.getFeatureFlags();\n\n return Object.values(flags).reduce((acc, curr) => {\n acc[curr.id] = parseVariation(curr.variationType, curr.variation);\n return acc;\n }, {});\n }\n}\n\nconst variationWithInsightBuffer = (key: string, defaultResult: string | boolean) => {\n const variation = store.getVariation(key);\n if (variation === undefined) {\n eventHub.emit(featureFlagEvaluatedBufferTopic, {\n id: key,\n timestamp: Date.now(),\n variationValue: `${ defaultResult }`\n } as IFeatureFlagVariationBuffer);\n }\n\n return variation;\n}\n\nexport default new FB();\n\n","// This file is only for umd version\n\nconst html = document.querySelector('html');\nconst waittime = 500;\nif (html) {\n html.style.visibility = 'hidden';\n setTimeout(() => html.style.visibility = 'visible', waittime);\n}\n\nimport fbClient from './featbit';\nimport { logger } from './logger';\n\nlogger.logDebug(`version: 2.0.0`);\n\nexport { fbClient }\n"],"names":["root","factory","exports","module","define","amd","a","i","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","InsightType","VariationDataType","StreamResponseEventType","FeatureFlagUpdateOperation","eventHub","events","subscribe","name","cb","push","unsubscribe","splice","indexOf","emit","forEach","fn","args","insightsFlushTopic","featureFlagEvaluatedTopic","featureFlagEvaluatedBufferTopic","websocketReconnectTopic","currentUserStorageKey","queryString","window","location","search","debugModeParam","URLSearchParams","logDebug","console","log","partialEndpoint","invalidParam","mandatory","serializeUser","user","builtInProperties","keyId","customizedProperties","map","p","join","parseVariation","type","string","boolean","number","str","isNaN","parseFloat","json","JSON","parse","e","uuid","replace","c","r","Math","random","toString","validateUser","trim","isNullOrUndefinedOrWhiteSpace","alphabet","encodeNumber","param","length","s","slice","split","n","DataStoreStorageKey","_userId","_store","featureFlags","id","_loadFromStorage","getFeatureFlag","getVariation","featureFlag","insightType","featureFlagUsage","timestamp","Date","now","sendToExperiment","variation","variationOptions","find","setFullData","data","_dumpToStorage","updateBulkFromRemote","getFeatureFlags","updateStorageBulk","storageKey","onlyInsertNewElement","dataStoreStr","localStorage","getItem","store","err","keys","remoteFf","assign","_emitUpdateEvents","updatedFeatureFlags","operation","update","item","localStorageKey","setItem","stringify","filter","storageFf","ff","variationType","oldValue","undefined","newValue","Store","API_CALL_RESULTS","FOOT_PRINTS","_key","setKey","throttle","ms","timer","clearTimeout","setTimeout","bind","throttleAsync","callback","waiting","footprint","params","arg","Array","isArray","getFootprint","idx","findIndex","f","apply","socketConnectionIntervals","networkService","retryCounter","sendInsights","secret","payload","__getUserInfo","variations","d","v","featureFlagKey","metrics","route","pathname","numericValue","appType","eventName","post","eventsUri","Authorization","init","streamingUri","identify","sendIdentifyMessage","socket","sendUserIdentifyMessage","messageType","readyState","WebSocket","OPEN","send","reconnect","waitTime","min","sendPingMessage","createConnection","onMessage","that","startTime","url","text","timestampCode","start","max","floor","generateConnectionToken","addEventListener","event","code","message","headers","fetch","method","body","response","status","flushLimit","arriveflushLimitTopic","queue","add","element","flush","allElements","createOrGetAnonymousUser","sessionId","guid","generateorGetGuid","mapFeatureFlagsToFeatureFlagBaseList","cur","_readyEventEmitted","_insightsQueue","Queue","_featureFlagEvaluationBuffer","_option","api","enableDataSync","_readyPromise","Promise","resolve","reject","on","buffered","variationValue","x","dataSync","off","waitUntilReady","option","validateOptionResult","anonymous","streamingUriMissing","eventsUriMissing","validateOption","validateUserResult","isUserChanged","userId","bootstrap","logout","anonymousUser","forceFullFetch","reduce","res","curr","values","userKeyId","eventType","full","patch","defaultResult","variationWithInsightBuffer","boolVariation","toLocaleLowerCase","getUser","sendCustomEvent","customEvent","sendFeatureFlagInsight","getAllFeatureFlags","flags","acc","FB","html","document","querySelector","style","visibility"],"sourceRoot":""}
|