diff --git a/docs/assets/search.js b/docs/assets/search.js index c4e2012..0d6bd80 100644 --- a/docs/assets/search.js +++ b/docs/assets/search.js @@ -1 +1 @@ -window.searchData = JSON.parse("{\"kinds\":{\"64\":\"Function\",\"128\":\"Class\",\"256\":\"Interface\",\"512\":\"Constructor\",\"1024\":\"Property\",\"2048\":\"Method\",\"65536\":\"Type literal\"},\"rows\":[{\"kind\":64,\"name\":\"initializePlatform\",\"url\":\"functions/initializePlatform.html\",\"classes\":\"tsd-kind-function\"},{\"kind\":128,\"name\":\"FPUser\",\"url\":\"classes/FPUser.html\",\"classes\":\"tsd-kind-class\"},{\"kind\":512,\"name\":\"constructor\",\"url\":\"classes/FPUser.html#constructor\",\"classes\":\"tsd-kind-constructor tsd-parent-kind-class\",\"parent\":\"FPUser\"},{\"kind\":1024,\"name\":\"key\",\"url\":\"classes/FPUser.html#key\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FPUser\"},{\"kind\":1024,\"name\":\"attrs\",\"url\":\"classes/FPUser.html#attrs\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FPUser\"},{\"kind\":65536,\"name\":\"__type\",\"url\":\"classes/FPUser.html#__type\",\"classes\":\"tsd-kind-type-literal tsd-parent-kind-class\",\"parent\":\"FPUser\"},{\"kind\":2048,\"name\":\"with\",\"url\":\"classes/FPUser.html#with\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FPUser\"},{\"kind\":2048,\"name\":\"getKey\",\"url\":\"classes/FPUser.html#getKey\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FPUser\"},{\"kind\":2048,\"name\":\"getAttrs\",\"url\":\"classes/FPUser.html#getAttrs\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FPUser\"},{\"kind\":65536,\"name\":\"__type\",\"url\":\"classes/FPUser.html#getAttrs.getAttrs-1.__type-1\",\"classes\":\"tsd-kind-type-literal\",\"parent\":\"FPUser.getAttrs.getAttrs\"},{\"kind\":2048,\"name\":\"extendAttrs\",\"url\":\"classes/FPUser.html#extendAttrs\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FPUser\"},{\"kind\":2048,\"name\":\"get\",\"url\":\"classes/FPUser.html#get\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FPUser\"},{\"kind\":2048,\"name\":\"stableRollout\",\"url\":\"classes/FPUser.html#stableRollout\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FPUser\"},{\"kind\":128,\"name\":\"FeatureProbe\",\"url\":\"classes/FeatureProbe.html\",\"classes\":\"tsd-kind-class\"},{\"kind\":2048,\"name\":\"newForTest\",\"url\":\"classes/FeatureProbe.html#newForTest\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":512,\"name\":\"constructor\",\"url\":\"classes/FeatureProbe.html#constructor\",\"classes\":\"tsd-kind-constructor tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"togglesUrl\",\"url\":\"classes/FeatureProbe.html#togglesUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"eventsUrl\",\"url\":\"classes/FeatureProbe.html#eventsUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"realtimeUrl\",\"url\":\"classes/FeatureProbe.html#realtimeUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"realtimePath\",\"url\":\"classes/FeatureProbe.html#realtimePath\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"refreshInterval\",\"url\":\"classes/FeatureProbe.html#refreshInterval\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"clientSdkKey\",\"url\":\"classes/FeatureProbe.html#clientSdkKey\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"user\",\"url\":\"classes/FeatureProbe.html#user\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"toggles\",\"url\":\"classes/FeatureProbe.html#toggles\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"timer\",\"url\":\"classes/FeatureProbe.html#timer\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"timeoutTimer\",\"url\":\"classes/FeatureProbe.html#timeoutTimer\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"readyPromise\",\"url\":\"classes/FeatureProbe.html#readyPromise\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"status\",\"url\":\"classes/FeatureProbe.html#status\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"timeoutInterval\",\"url\":\"classes/FeatureProbe.html#timeoutInterval\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"storage\",\"url\":\"classes/FeatureProbe.html#storage\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"socket\",\"url\":\"classes/FeatureProbe.html#socket\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"start\",\"url\":\"classes/FeatureProbe.html#start\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"stop\",\"url\":\"classes/FeatureProbe.html#stop\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"waitUntilReady\",\"url\":\"classes/FeatureProbe.html#waitUntilReady\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"boolValue\",\"url\":\"classes/FeatureProbe.html#boolValue\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"numberValue\",\"url\":\"classes/FeatureProbe.html#numberValue\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"stringValue\",\"url\":\"classes/FeatureProbe.html#stringValue\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"jsonValue\",\"url\":\"classes/FeatureProbe.html#jsonValue\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"boolDetail\",\"url\":\"classes/FeatureProbe.html#boolDetail\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"numberDetail\",\"url\":\"classes/FeatureProbe.html#numberDetail\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"stringDetail\",\"url\":\"classes/FeatureProbe.html#stringDetail\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"jsonDetail\",\"url\":\"classes/FeatureProbe.html#jsonDetail\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"allToggles\",\"url\":\"classes/FeatureProbe.html#allToggles\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"getUser\",\"url\":\"classes/FeatureProbe.html#getUser\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"identifyUser\",\"url\":\"classes/FeatureProbe.html#identifyUser\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"logout\",\"url\":\"classes/FeatureProbe.html#logout\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"connectSocket\",\"url\":\"classes/FeatureProbe.html#connectSocket\",\"classes\":\"tsd-kind-method tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"toggleValue\",\"url\":\"classes/FeatureProbe.html#toggleValue\",\"classes\":\"tsd-kind-method tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"toggleDetail\",\"url\":\"classes/FeatureProbe.html#toggleDetail\",\"classes\":\"tsd-kind-method tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"fetchToggles\",\"url\":\"classes/FeatureProbe.html#fetchToggles\",\"classes\":\"tsd-kind-method tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"sendEvents\",\"url\":\"classes/FeatureProbe.html#sendEvents\",\"classes\":\"tsd-kind-method tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"successInitialized\",\"url\":\"classes/FeatureProbe.html#successInitialized\",\"classes\":\"tsd-kind-method tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"errorInitialized\",\"url\":\"classes/FeatureProbe.html#errorInitialized\",\"classes\":\"tsd-kind-method tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":256,\"name\":\"FPDetail\",\"url\":\"interfaces/FPDetail.html\",\"classes\":\"tsd-kind-interface\"},{\"kind\":1024,\"name\":\"value\",\"url\":\"interfaces/FPDetail.html#value\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPDetail\"},{\"kind\":1024,\"name\":\"ruleIndex\",\"url\":\"interfaces/FPDetail.html#ruleIndex\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPDetail\"},{\"kind\":1024,\"name\":\"variationIndex\",\"url\":\"interfaces/FPDetail.html#variationIndex\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPDetail\"},{\"kind\":1024,\"name\":\"version\",\"url\":\"interfaces/FPDetail.html#version\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPDetail\"},{\"kind\":1024,\"name\":\"reason\",\"url\":\"interfaces/FPDetail.html#reason\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPDetail\"},{\"kind\":256,\"name\":\"FPConfig\",\"url\":\"interfaces/FPConfig.html\",\"classes\":\"tsd-kind-interface\"},{\"kind\":1024,\"name\":\"remoteUrl\",\"url\":\"interfaces/FPConfig.html#remoteUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPConfig\"},{\"kind\":1024,\"name\":\"togglesUrl\",\"url\":\"interfaces/FPConfig.html#togglesUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPConfig\"},{\"kind\":1024,\"name\":\"eventsUrl\",\"url\":\"interfaces/FPConfig.html#eventsUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPConfig\"},{\"kind\":1024,\"name\":\"realtimeUrl\",\"url\":\"interfaces/FPConfig.html#realtimeUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPConfig\"},{\"kind\":1024,\"name\":\"realtimePath\",\"url\":\"interfaces/FPConfig.html#realtimePath\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPConfig\"},{\"kind\":1024,\"name\":\"clientSdkKey\",\"url\":\"interfaces/FPConfig.html#clientSdkKey\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPConfig\"},{\"kind\":1024,\"name\":\"user\",\"url\":\"interfaces/FPConfig.html#user\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPConfig\"},{\"kind\":1024,\"name\":\"refreshInterval\",\"url\":\"interfaces/FPConfig.html#refreshInterval\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPConfig\"},{\"kind\":1024,\"name\":\"timeoutInterval\",\"url\":\"interfaces/FPConfig.html#timeoutInterval\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPConfig\"},{\"kind\":256,\"name\":\"FPStorageProvider\",\"url\":\"interfaces/FPStorageProvider.html\",\"classes\":\"tsd-kind-interface\"},{\"kind\":1024,\"name\":\"setItem\",\"url\":\"interfaces/FPStorageProvider.html#setItem\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPStorageProvider\"},{\"kind\":65536,\"name\":\"__type\",\"url\":\"interfaces/FPStorageProvider.html#__type-2\",\"classes\":\"tsd-kind-type-literal tsd-parent-kind-interface\",\"parent\":\"FPStorageProvider\"},{\"kind\":1024,\"name\":\"getItem\",\"url\":\"interfaces/FPStorageProvider.html#getItem\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPStorageProvider\"},{\"kind\":65536,\"name\":\"__type\",\"url\":\"interfaces/FPStorageProvider.html#__type\",\"classes\":\"tsd-kind-type-literal tsd-parent-kind-interface\",\"parent\":\"FPStorageProvider\"},{\"kind\":256,\"name\":\"IHttpRequest\",\"url\":\"interfaces/IHttpRequest.html\",\"classes\":\"tsd-kind-interface\"},{\"kind\":1024,\"name\":\"get\",\"url\":\"interfaces/IHttpRequest.html#get\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"IHttpRequest\"},{\"kind\":65536,\"name\":\"__type\",\"url\":\"interfaces/IHttpRequest.html#__type\",\"classes\":\"tsd-kind-type-literal tsd-parent-kind-interface\",\"parent\":\"IHttpRequest\"},{\"kind\":1024,\"name\":\"post\",\"url\":\"interfaces/IHttpRequest.html#post\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"IHttpRequest\"},{\"kind\":65536,\"name\":\"__type\",\"url\":\"interfaces/IHttpRequest.html#__type-2\",\"classes\":\"tsd-kind-type-literal tsd-parent-kind-interface\",\"parent\":\"IHttpRequest\"}],\"index\":{\"version\":\"2.3.9\",\"fields\":[\"name\",\"comment\"],\"fieldVectors\":[[\"name/0\",[0,39.766]],[\"comment/0\",[]],[\"name/1\",[1,39.766]],[\"comment/1\",[]],[\"name/2\",[2,34.657]],[\"comment/2\",[]],[\"name/3\",[3,39.766]],[\"comment/3\",[]],[\"name/4\",[4,39.766]],[\"comment/4\",[]],[\"name/5\",[5,25.102]],[\"comment/5\",[]],[\"name/6\",[6,39.766]],[\"comment/6\",[]],[\"name/7\",[7,39.766]],[\"comment/7\",[]],[\"name/8\",[8,39.766]],[\"comment/8\",[]],[\"name/9\",[5,25.102]],[\"comment/9\",[]],[\"name/10\",[9,39.766]],[\"comment/10\",[]],[\"name/11\",[10,34.657]],[\"comment/11\",[]],[\"name/12\",[11,39.766]],[\"comment/12\",[]],[\"name/13\",[12,39.766]],[\"comment/13\",[]],[\"name/14\",[13,39.766]],[\"comment/14\",[]],[\"name/15\",[2,34.657]],[\"comment/15\",[]],[\"name/16\",[14,34.657]],[\"comment/16\",[]],[\"name/17\",[15,34.657]],[\"comment/17\",[]],[\"name/18\",[16,34.657]],[\"comment/18\",[]],[\"name/19\",[17,34.657]],[\"comment/19\",[]],[\"name/20\",[18,34.657]],[\"comment/20\",[]],[\"name/21\",[19,34.657]],[\"comment/21\",[]],[\"name/22\",[20,34.657]],[\"comment/22\",[]],[\"name/23\",[21,39.766]],[\"comment/23\",[]],[\"name/24\",[22,39.766]],[\"comment/24\",[]],[\"name/25\",[23,39.766]],[\"comment/25\",[]],[\"name/26\",[24,39.766]],[\"comment/26\",[]],[\"name/27\",[25,39.766]],[\"comment/27\",[]],[\"name/28\",[26,34.657]],[\"comment/28\",[]],[\"name/29\",[27,39.766]],[\"comment/29\",[]],[\"name/30\",[28,39.766]],[\"comment/30\",[]],[\"name/31\",[29,39.766]],[\"comment/31\",[]],[\"name/32\",[30,39.766]],[\"comment/32\",[]],[\"name/33\",[31,39.766]],[\"comment/33\",[]],[\"name/34\",[32,39.766]],[\"comment/34\",[]],[\"name/35\",[33,39.766]],[\"comment/35\",[]],[\"name/36\",[34,39.766]],[\"comment/36\",[]],[\"name/37\",[35,39.766]],[\"comment/37\",[]],[\"name/38\",[36,39.766]],[\"comment/38\",[]],[\"name/39\",[37,39.766]],[\"comment/39\",[]],[\"name/40\",[38,39.766]],[\"comment/40\",[]],[\"name/41\",[39,39.766]],[\"comment/41\",[]],[\"name/42\",[40,39.766]],[\"comment/42\",[]],[\"name/43\",[41,39.766]],[\"comment/43\",[]],[\"name/44\",[42,39.766]],[\"comment/44\",[]],[\"name/45\",[43,39.766]],[\"comment/45\",[]],[\"name/46\",[44,39.766]],[\"comment/46\",[]],[\"name/47\",[45,39.766]],[\"comment/47\",[]],[\"name/48\",[46,39.766]],[\"comment/48\",[]],[\"name/49\",[47,39.766]],[\"comment/49\",[]],[\"name/50\",[48,39.766]],[\"comment/50\",[]],[\"name/51\",[49,39.766]],[\"comment/51\",[]],[\"name/52\",[50,39.766]],[\"comment/52\",[]],[\"name/53\",[51,39.766]],[\"comment/53\",[]],[\"name/54\",[52,39.766]],[\"comment/54\",[]],[\"name/55\",[53,39.766]],[\"comment/55\",[]],[\"name/56\",[54,39.766]],[\"comment/56\",[]],[\"name/57\",[55,39.766]],[\"comment/57\",[]],[\"name/58\",[56,39.766]],[\"comment/58\",[]],[\"name/59\",[57,39.766]],[\"comment/59\",[]],[\"name/60\",[58,39.766]],[\"comment/60\",[]],[\"name/61\",[14,34.657]],[\"comment/61\",[]],[\"name/62\",[15,34.657]],[\"comment/62\",[]],[\"name/63\",[16,34.657]],[\"comment/63\",[]],[\"name/64\",[17,34.657]],[\"comment/64\",[]],[\"name/65\",[19,34.657]],[\"comment/65\",[]],[\"name/66\",[20,34.657]],[\"comment/66\",[]],[\"name/67\",[18,34.657]],[\"comment/67\",[]],[\"name/68\",[26,34.657]],[\"comment/68\",[]],[\"name/69\",[59,39.766]],[\"comment/69\",[]],[\"name/70\",[60,39.766]],[\"comment/70\",[]],[\"name/71\",[5,25.102]],[\"comment/71\",[]],[\"name/72\",[61,39.766]],[\"comment/72\",[]],[\"name/73\",[5,25.102]],[\"comment/73\",[]],[\"name/74\",[62,39.766]],[\"comment/74\",[]],[\"name/75\",[10,34.657]],[\"comment/75\",[]],[\"name/76\",[5,25.102]],[\"comment/76\",[]],[\"name/77\",[63,39.766]],[\"comment/77\",[]],[\"name/78\",[5,25.102]],[\"comment/78\",[]]],\"invertedIndex\":[[\"__type\",{\"_index\":5,\"name\":{\"5\":{},\"9\":{},\"71\":{},\"73\":{},\"76\":{},\"78\":{}},\"comment\":{}}],[\"alltoggles\",{\"_index\":40,\"name\":{\"42\":{}},\"comment\":{}}],[\"attrs\",{\"_index\":4,\"name\":{\"4\":{}},\"comment\":{}}],[\"booldetail\",{\"_index\":36,\"name\":{\"38\":{}},\"comment\":{}}],[\"boolvalue\",{\"_index\":32,\"name\":{\"34\":{}},\"comment\":{}}],[\"clientsdkkey\",{\"_index\":19,\"name\":{\"21\":{},\"65\":{}},\"comment\":{}}],[\"connectsocket\",{\"_index\":44,\"name\":{\"46\":{}},\"comment\":{}}],[\"constructor\",{\"_index\":2,\"name\":{\"2\":{},\"15\":{}},\"comment\":{}}],[\"errorinitialized\",{\"_index\":50,\"name\":{\"52\":{}},\"comment\":{}}],[\"eventsurl\",{\"_index\":15,\"name\":{\"17\":{},\"62\":{}},\"comment\":{}}],[\"extendattrs\",{\"_index\":9,\"name\":{\"10\":{}},\"comment\":{}}],[\"featureprobe\",{\"_index\":12,\"name\":{\"13\":{}},\"comment\":{}}],[\"fetchtoggles\",{\"_index\":47,\"name\":{\"49\":{}},\"comment\":{}}],[\"fpconfig\",{\"_index\":57,\"name\":{\"59\":{}},\"comment\":{}}],[\"fpdetail\",{\"_index\":51,\"name\":{\"53\":{}},\"comment\":{}}],[\"fpstorageprovider\",{\"_index\":59,\"name\":{\"69\":{}},\"comment\":{}}],[\"fpuser\",{\"_index\":1,\"name\":{\"1\":{}},\"comment\":{}}],[\"get\",{\"_index\":10,\"name\":{\"11\":{},\"75\":{}},\"comment\":{}}],[\"getattrs\",{\"_index\":8,\"name\":{\"8\":{}},\"comment\":{}}],[\"getitem\",{\"_index\":61,\"name\":{\"72\":{}},\"comment\":{}}],[\"getkey\",{\"_index\":7,\"name\":{\"7\":{}},\"comment\":{}}],[\"getuser\",{\"_index\":41,\"name\":{\"43\":{}},\"comment\":{}}],[\"identifyuser\",{\"_index\":42,\"name\":{\"44\":{}},\"comment\":{}}],[\"ihttprequest\",{\"_index\":62,\"name\":{\"74\":{}},\"comment\":{}}],[\"initializeplatform\",{\"_index\":0,\"name\":{\"0\":{}},\"comment\":{}}],[\"jsondetail\",{\"_index\":39,\"name\":{\"41\":{}},\"comment\":{}}],[\"jsonvalue\",{\"_index\":35,\"name\":{\"37\":{}},\"comment\":{}}],[\"key\",{\"_index\":3,\"name\":{\"3\":{}},\"comment\":{}}],[\"logout\",{\"_index\":43,\"name\":{\"45\":{}},\"comment\":{}}],[\"newfortest\",{\"_index\":13,\"name\":{\"14\":{}},\"comment\":{}}],[\"numberdetail\",{\"_index\":37,\"name\":{\"39\":{}},\"comment\":{}}],[\"numbervalue\",{\"_index\":33,\"name\":{\"35\":{}},\"comment\":{}}],[\"post\",{\"_index\":63,\"name\":{\"77\":{}},\"comment\":{}}],[\"readypromise\",{\"_index\":24,\"name\":{\"26\":{}},\"comment\":{}}],[\"realtimepath\",{\"_index\":17,\"name\":{\"19\":{},\"64\":{}},\"comment\":{}}],[\"realtimeurl\",{\"_index\":16,\"name\":{\"18\":{},\"63\":{}},\"comment\":{}}],[\"reason\",{\"_index\":56,\"name\":{\"58\":{}},\"comment\":{}}],[\"refreshinterval\",{\"_index\":18,\"name\":{\"20\":{},\"67\":{}},\"comment\":{}}],[\"remoteurl\",{\"_index\":58,\"name\":{\"60\":{}},\"comment\":{}}],[\"ruleindex\",{\"_index\":53,\"name\":{\"55\":{}},\"comment\":{}}],[\"sendevents\",{\"_index\":48,\"name\":{\"50\":{}},\"comment\":{}}],[\"setitem\",{\"_index\":60,\"name\":{\"70\":{}},\"comment\":{}}],[\"socket\",{\"_index\":28,\"name\":{\"30\":{}},\"comment\":{}}],[\"stablerollout\",{\"_index\":11,\"name\":{\"12\":{}},\"comment\":{}}],[\"start\",{\"_index\":29,\"name\":{\"31\":{}},\"comment\":{}}],[\"status\",{\"_index\":25,\"name\":{\"27\":{}},\"comment\":{}}],[\"stop\",{\"_index\":30,\"name\":{\"32\":{}},\"comment\":{}}],[\"storage\",{\"_index\":27,\"name\":{\"29\":{}},\"comment\":{}}],[\"stringdetail\",{\"_index\":38,\"name\":{\"40\":{}},\"comment\":{}}],[\"stringvalue\",{\"_index\":34,\"name\":{\"36\":{}},\"comment\":{}}],[\"successinitialized\",{\"_index\":49,\"name\":{\"51\":{}},\"comment\":{}}],[\"timeoutinterval\",{\"_index\":26,\"name\":{\"28\":{},\"68\":{}},\"comment\":{}}],[\"timeouttimer\",{\"_index\":23,\"name\":{\"25\":{}},\"comment\":{}}],[\"timer\",{\"_index\":22,\"name\":{\"24\":{}},\"comment\":{}}],[\"toggledetail\",{\"_index\":46,\"name\":{\"48\":{}},\"comment\":{}}],[\"toggles\",{\"_index\":21,\"name\":{\"23\":{}},\"comment\":{}}],[\"togglesurl\",{\"_index\":14,\"name\":{\"16\":{},\"61\":{}},\"comment\":{}}],[\"togglevalue\",{\"_index\":45,\"name\":{\"47\":{}},\"comment\":{}}],[\"user\",{\"_index\":20,\"name\":{\"22\":{},\"66\":{}},\"comment\":{}}],[\"value\",{\"_index\":52,\"name\":{\"54\":{}},\"comment\":{}}],[\"variationindex\",{\"_index\":54,\"name\":{\"56\":{}},\"comment\":{}}],[\"version\",{\"_index\":55,\"name\":{\"57\":{}},\"comment\":{}}],[\"waituntilready\",{\"_index\":31,\"name\":{\"33\":{}},\"comment\":{}}],[\"with\",{\"_index\":6,\"name\":{\"6\":{}},\"comment\":{}}]],\"pipeline\":[]}}"); \ No newline at end of file +window.searchData = JSON.parse("{\"kinds\":{\"64\":\"Function\",\"128\":\"Class\",\"256\":\"Interface\",\"512\":\"Constructor\",\"1024\":\"Property\",\"2048\":\"Method\",\"65536\":\"Type literal\",\"4194304\":\"Type alias\"},\"rows\":[{\"kind\":64,\"name\":\"initializePlatform\",\"url\":\"functions/initializePlatform.html\",\"classes\":\"tsd-kind-function\"},{\"kind\":128,\"name\":\"FPUser\",\"url\":\"classes/FPUser.html\",\"classes\":\"tsd-kind-class\"},{\"kind\":512,\"name\":\"constructor\",\"url\":\"classes/FPUser.html#constructor\",\"classes\":\"tsd-kind-constructor tsd-parent-kind-class\",\"parent\":\"FPUser\"},{\"kind\":1024,\"name\":\"key\",\"url\":\"classes/FPUser.html#key\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FPUser\"},{\"kind\":1024,\"name\":\"attrs\",\"url\":\"classes/FPUser.html#attrs\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FPUser\"},{\"kind\":65536,\"name\":\"__type\",\"url\":\"classes/FPUser.html#__type\",\"classes\":\"tsd-kind-type-literal tsd-parent-kind-class\",\"parent\":\"FPUser\"},{\"kind\":2048,\"name\":\"with\",\"url\":\"classes/FPUser.html#with\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FPUser\"},{\"kind\":2048,\"name\":\"getKey\",\"url\":\"classes/FPUser.html#getKey\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FPUser\"},{\"kind\":2048,\"name\":\"getAttrs\",\"url\":\"classes/FPUser.html#getAttrs\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FPUser\"},{\"kind\":65536,\"name\":\"__type\",\"url\":\"classes/FPUser.html#getAttrs.getAttrs-1.__type-1\",\"classes\":\"tsd-kind-type-literal\",\"parent\":\"FPUser.getAttrs.getAttrs\"},{\"kind\":2048,\"name\":\"extendAttrs\",\"url\":\"classes/FPUser.html#extendAttrs\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FPUser\"},{\"kind\":2048,\"name\":\"get\",\"url\":\"classes/FPUser.html#get\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FPUser\"},{\"kind\":2048,\"name\":\"stableRollout\",\"url\":\"classes/FPUser.html#stableRollout\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FPUser\"},{\"kind\":128,\"name\":\"FeatureProbe\",\"url\":\"classes/FeatureProbe.html\",\"classes\":\"tsd-kind-class\"},{\"kind\":2048,\"name\":\"newForTest\",\"url\":\"classes/FeatureProbe.html#newForTest\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":512,\"name\":\"constructor\",\"url\":\"classes/FeatureProbe.html#constructor\",\"classes\":\"tsd-kind-constructor tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"togglesUrl\",\"url\":\"classes/FeatureProbe.html#togglesUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"eventsUrl\",\"url\":\"classes/FeatureProbe.html#eventsUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"getEventsUrl\",\"url\":\"classes/FeatureProbe.html#getEventsUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"realtimeUrl\",\"url\":\"classes/FeatureProbe.html#realtimeUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"realtimePath\",\"url\":\"classes/FeatureProbe.html#realtimePath\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"refreshInterval\",\"url\":\"classes/FeatureProbe.html#refreshInterval\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"clientSdkKey\",\"url\":\"classes/FeatureProbe.html#clientSdkKey\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"user\",\"url\":\"classes/FeatureProbe.html#user\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"toggles\",\"url\":\"classes/FeatureProbe.html#toggles\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"timer\",\"url\":\"classes/FeatureProbe.html#timer\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"timeoutTimer\",\"url\":\"classes/FeatureProbe.html#timeoutTimer\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"readyPromise\",\"url\":\"classes/FeatureProbe.html#readyPromise\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"status\",\"url\":\"classes/FeatureProbe.html#status\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"timeoutInterval\",\"url\":\"classes/FeatureProbe.html#timeoutInterval\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"storage\",\"url\":\"classes/FeatureProbe.html#storage\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"socket\",\"url\":\"classes/FeatureProbe.html#socket\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":1024,\"name\":\"eventRecorder\",\"url\":\"classes/FeatureProbe.html#eventRecorder\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"start\",\"url\":\"classes/FeatureProbe.html#start\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"stop\",\"url\":\"classes/FeatureProbe.html#stop\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"waitUntilReady\",\"url\":\"classes/FeatureProbe.html#waitUntilReady\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"boolValue\",\"url\":\"classes/FeatureProbe.html#boolValue\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"numberValue\",\"url\":\"classes/FeatureProbe.html#numberValue\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"stringValue\",\"url\":\"classes/FeatureProbe.html#stringValue\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"jsonValue\",\"url\":\"classes/FeatureProbe.html#jsonValue\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"boolDetail\",\"url\":\"classes/FeatureProbe.html#boolDetail\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"numberDetail\",\"url\":\"classes/FeatureProbe.html#numberDetail\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"stringDetail\",\"url\":\"classes/FeatureProbe.html#stringDetail\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"jsonDetail\",\"url\":\"classes/FeatureProbe.html#jsonDetail\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"allToggles\",\"url\":\"classes/FeatureProbe.html#allToggles\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"getUser\",\"url\":\"classes/FeatureProbe.html#getUser\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"identifyUser\",\"url\":\"classes/FeatureProbe.html#identifyUser\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"logout\",\"url\":\"classes/FeatureProbe.html#logout\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"flush\",\"url\":\"classes/FeatureProbe.html#flush\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"track\",\"url\":\"classes/FeatureProbe.html#track\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"connectSocket\",\"url\":\"classes/FeatureProbe.html#connectSocket\",\"classes\":\"tsd-kind-method tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"toggleValue\",\"url\":\"classes/FeatureProbe.html#toggleValue\",\"classes\":\"tsd-kind-method tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"toggleDetail\",\"url\":\"classes/FeatureProbe.html#toggleDetail\",\"classes\":\"tsd-kind-method tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"fetchToggles\",\"url\":\"classes/FeatureProbe.html#fetchToggles\",\"classes\":\"tsd-kind-method tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"successInitialized\",\"url\":\"classes/FeatureProbe.html#successInitialized\",\"classes\":\"tsd-kind-method tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":2048,\"name\":\"errorInitialized\",\"url\":\"classes/FeatureProbe.html#errorInitialized\",\"classes\":\"tsd-kind-method tsd-parent-kind-class tsd-is-private\",\"parent\":\"FeatureProbe\"},{\"kind\":256,\"name\":\"FPDetail\",\"url\":\"interfaces/FPDetail.html\",\"classes\":\"tsd-kind-interface\"},{\"kind\":1024,\"name\":\"value\",\"url\":\"interfaces/FPDetail.html#value\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPDetail\"},{\"kind\":1024,\"name\":\"ruleIndex\",\"url\":\"interfaces/FPDetail.html#ruleIndex\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPDetail\"},{\"kind\":1024,\"name\":\"variationIndex\",\"url\":\"interfaces/FPDetail.html#variationIndex\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPDetail\"},{\"kind\":1024,\"name\":\"version\",\"url\":\"interfaces/FPDetail.html#version\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPDetail\"},{\"kind\":1024,\"name\":\"reason\",\"url\":\"interfaces/FPDetail.html#reason\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPDetail\"},{\"kind\":1024,\"name\":\"trackAccessEvents\",\"url\":\"interfaces/FPDetail.html#trackAccessEvents\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPDetail\"},{\"kind\":1024,\"name\":\"lastModified\",\"url\":\"interfaces/FPDetail.html#lastModified\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPDetail\"},{\"kind\":256,\"name\":\"FPConfig\",\"url\":\"interfaces/FPConfig.html\",\"classes\":\"tsd-kind-interface\"},{\"kind\":1024,\"name\":\"remoteUrl\",\"url\":\"interfaces/FPConfig.html#remoteUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPConfig\"},{\"kind\":1024,\"name\":\"togglesUrl\",\"url\":\"interfaces/FPConfig.html#togglesUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPConfig\"},{\"kind\":1024,\"name\":\"eventsUrl\",\"url\":\"interfaces/FPConfig.html#eventsUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPConfig\"},{\"kind\":1024,\"name\":\"realtimeUrl\",\"url\":\"interfaces/FPConfig.html#realtimeUrl\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPConfig\"},{\"kind\":1024,\"name\":\"realtimePath\",\"url\":\"interfaces/FPConfig.html#realtimePath\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPConfig\"},{\"kind\":1024,\"name\":\"clientSdkKey\",\"url\":\"interfaces/FPConfig.html#clientSdkKey\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPConfig\"},{\"kind\":1024,\"name\":\"user\",\"url\":\"interfaces/FPConfig.html#user\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPConfig\"},{\"kind\":1024,\"name\":\"refreshInterval\",\"url\":\"interfaces/FPConfig.html#refreshInterval\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPConfig\"},{\"kind\":1024,\"name\":\"timeoutInterval\",\"url\":\"interfaces/FPConfig.html#timeoutInterval\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPConfig\"},{\"kind\":1024,\"name\":\"enableAutoReporting\",\"url\":\"interfaces/FPConfig.html#enableAutoReporting\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPConfig\"},{\"kind\":256,\"name\":\"FPStorageProvider\",\"url\":\"interfaces/FPStorageProvider.html\",\"classes\":\"tsd-kind-interface\"},{\"kind\":1024,\"name\":\"setItem\",\"url\":\"interfaces/FPStorageProvider.html#setItem\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPStorageProvider\"},{\"kind\":65536,\"name\":\"__type\",\"url\":\"interfaces/FPStorageProvider.html#__type-2\",\"classes\":\"tsd-kind-type-literal tsd-parent-kind-interface\",\"parent\":\"FPStorageProvider\"},{\"kind\":1024,\"name\":\"getItem\",\"url\":\"interfaces/FPStorageProvider.html#getItem\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"FPStorageProvider\"},{\"kind\":65536,\"name\":\"__type\",\"url\":\"interfaces/FPStorageProvider.html#__type\",\"classes\":\"tsd-kind-type-literal tsd-parent-kind-interface\",\"parent\":\"FPStorageProvider\"},{\"kind\":256,\"name\":\"IHttpRequest\",\"url\":\"interfaces/IHttpRequest.html\",\"classes\":\"tsd-kind-interface\"},{\"kind\":1024,\"name\":\"get\",\"url\":\"interfaces/IHttpRequest.html#get\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"IHttpRequest\"},{\"kind\":65536,\"name\":\"__type\",\"url\":\"interfaces/IHttpRequest.html#__type\",\"classes\":\"tsd-kind-type-literal tsd-parent-kind-interface\",\"parent\":\"IHttpRequest\"},{\"kind\":1024,\"name\":\"post\",\"url\":\"interfaces/IHttpRequest.html#post\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"IHttpRequest\"},{\"kind\":65536,\"name\":\"__type\",\"url\":\"interfaces/IHttpRequest.html#__type-2\",\"classes\":\"tsd-kind-type-literal tsd-parent-kind-interface\",\"parent\":\"IHttpRequest\"},{\"kind\":4194304,\"name\":\"IReturnValue\",\"url\":\"types/IReturnValue.html\",\"classes\":\"tsd-kind-type-alias\"},{\"kind\":256,\"name\":\"IOption\",\"url\":\"interfaces/IOption.html\",\"classes\":\"tsd-kind-interface\"},{\"kind\":1024,\"name\":\"platform\",\"url\":\"interfaces/IOption.html#platform\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"IOption\"},{\"kind\":256,\"name\":\"IPlatForm\",\"url\":\"interfaces/IPlatForm.html\",\"classes\":\"tsd-kind-interface\"},{\"kind\":1024,\"name\":\"localStorage\",\"url\":\"interfaces/IPlatForm.html#localStorage\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"IPlatForm\"},{\"kind\":1024,\"name\":\"UA\",\"url\":\"interfaces/IPlatForm.html#UA\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"IPlatForm\"},{\"kind\":1024,\"name\":\"httpRequest\",\"url\":\"interfaces/IPlatForm.html#httpRequest\",\"classes\":\"tsd-kind-property tsd-parent-kind-interface\",\"parent\":\"IPlatForm\"}],\"index\":{\"version\":\"2.3.9\",\"fields\":[\"name\",\"comment\"],\"fieldVectors\":[[\"name/0\",[0,41.271]],[\"comment/0\",[]],[\"name/1\",[1,41.271]],[\"comment/1\",[]],[\"name/2\",[2,36.163]],[\"comment/2\",[]],[\"name/3\",[3,41.271]],[\"comment/3\",[]],[\"name/4\",[4,41.271]],[\"comment/4\",[]],[\"name/5\",[5,26.608]],[\"comment/5\",[]],[\"name/6\",[6,41.271]],[\"comment/6\",[]],[\"name/7\",[7,41.271]],[\"comment/7\",[]],[\"name/8\",[8,41.271]],[\"comment/8\",[]],[\"name/9\",[5,26.608]],[\"comment/9\",[]],[\"name/10\",[9,41.271]],[\"comment/10\",[]],[\"name/11\",[10,36.163]],[\"comment/11\",[]],[\"name/12\",[11,41.271]],[\"comment/12\",[]],[\"name/13\",[12,41.271]],[\"comment/13\",[]],[\"name/14\",[13,41.271]],[\"comment/14\",[]],[\"name/15\",[2,36.163]],[\"comment/15\",[]],[\"name/16\",[14,36.163]],[\"comment/16\",[]],[\"name/17\",[15,36.163]],[\"comment/17\",[]],[\"name/18\",[16,41.271]],[\"comment/18\",[]],[\"name/19\",[17,36.163]],[\"comment/19\",[]],[\"name/20\",[18,36.163]],[\"comment/20\",[]],[\"name/21\",[19,36.163]],[\"comment/21\",[]],[\"name/22\",[20,36.163]],[\"comment/22\",[]],[\"name/23\",[21,36.163]],[\"comment/23\",[]],[\"name/24\",[22,41.271]],[\"comment/24\",[]],[\"name/25\",[23,41.271]],[\"comment/25\",[]],[\"name/26\",[24,41.271]],[\"comment/26\",[]],[\"name/27\",[25,41.271]],[\"comment/27\",[]],[\"name/28\",[26,41.271]],[\"comment/28\",[]],[\"name/29\",[27,36.163]],[\"comment/29\",[]],[\"name/30\",[28,41.271]],[\"comment/30\",[]],[\"name/31\",[29,41.271]],[\"comment/31\",[]],[\"name/32\",[30,41.271]],[\"comment/32\",[]],[\"name/33\",[31,41.271]],[\"comment/33\",[]],[\"name/34\",[32,41.271]],[\"comment/34\",[]],[\"name/35\",[33,41.271]],[\"comment/35\",[]],[\"name/36\",[34,41.271]],[\"comment/36\",[]],[\"name/37\",[35,41.271]],[\"comment/37\",[]],[\"name/38\",[36,41.271]],[\"comment/38\",[]],[\"name/39\",[37,41.271]],[\"comment/39\",[]],[\"name/40\",[38,41.271]],[\"comment/40\",[]],[\"name/41\",[39,41.271]],[\"comment/41\",[]],[\"name/42\",[40,41.271]],[\"comment/42\",[]],[\"name/43\",[41,41.271]],[\"comment/43\",[]],[\"name/44\",[42,41.271]],[\"comment/44\",[]],[\"name/45\",[43,41.271]],[\"comment/45\",[]],[\"name/46\",[44,41.271]],[\"comment/46\",[]],[\"name/47\",[45,41.271]],[\"comment/47\",[]],[\"name/48\",[46,41.271]],[\"comment/48\",[]],[\"name/49\",[47,41.271]],[\"comment/49\",[]],[\"name/50\",[48,41.271]],[\"comment/50\",[]],[\"name/51\",[49,41.271]],[\"comment/51\",[]],[\"name/52\",[50,41.271]],[\"comment/52\",[]],[\"name/53\",[51,41.271]],[\"comment/53\",[]],[\"name/54\",[52,41.271]],[\"comment/54\",[]],[\"name/55\",[53,41.271]],[\"comment/55\",[]],[\"name/56\",[54,41.271]],[\"comment/56\",[]],[\"name/57\",[55,41.271]],[\"comment/57\",[]],[\"name/58\",[56,41.271]],[\"comment/58\",[]],[\"name/59\",[57,41.271]],[\"comment/59\",[]],[\"name/60\",[58,41.271]],[\"comment/60\",[]],[\"name/61\",[59,41.271]],[\"comment/61\",[]],[\"name/62\",[60,41.271]],[\"comment/62\",[]],[\"name/63\",[61,41.271]],[\"comment/63\",[]],[\"name/64\",[62,41.271]],[\"comment/64\",[]],[\"name/65\",[63,41.271]],[\"comment/65\",[]],[\"name/66\",[14,36.163]],[\"comment/66\",[]],[\"name/67\",[15,36.163]],[\"comment/67\",[]],[\"name/68\",[17,36.163]],[\"comment/68\",[]],[\"name/69\",[18,36.163]],[\"comment/69\",[]],[\"name/70\",[20,36.163]],[\"comment/70\",[]],[\"name/71\",[21,36.163]],[\"comment/71\",[]],[\"name/72\",[19,36.163]],[\"comment/72\",[]],[\"name/73\",[27,36.163]],[\"comment/73\",[]],[\"name/74\",[64,41.271]],[\"comment/74\",[]],[\"name/75\",[65,41.271]],[\"comment/75\",[]],[\"name/76\",[66,41.271]],[\"comment/76\",[]],[\"name/77\",[5,26.608]],[\"comment/77\",[]],[\"name/78\",[67,41.271]],[\"comment/78\",[]],[\"name/79\",[5,26.608]],[\"comment/79\",[]],[\"name/80\",[68,41.271]],[\"comment/80\",[]],[\"name/81\",[10,36.163]],[\"comment/81\",[]],[\"name/82\",[5,26.608]],[\"comment/82\",[]],[\"name/83\",[69,41.271]],[\"comment/83\",[]],[\"name/84\",[5,26.608]],[\"comment/84\",[]],[\"name/85\",[70,41.271]],[\"comment/85\",[]],[\"name/86\",[71,41.271]],[\"comment/86\",[]],[\"name/87\",[72,41.271]],[\"comment/87\",[]],[\"name/88\",[73,41.271]],[\"comment/88\",[]],[\"name/89\",[74,41.271]],[\"comment/89\",[]],[\"name/90\",[75,41.271]],[\"comment/90\",[]],[\"name/91\",[76,41.271]],[\"comment/91\",[]]],\"invertedIndex\":[[\"__type\",{\"_index\":5,\"name\":{\"5\":{},\"9\":{},\"77\":{},\"79\":{},\"82\":{},\"84\":{}},\"comment\":{}}],[\"alltoggles\",{\"_index\":42,\"name\":{\"44\":{}},\"comment\":{}}],[\"attrs\",{\"_index\":4,\"name\":{\"4\":{}},\"comment\":{}}],[\"booldetail\",{\"_index\":38,\"name\":{\"40\":{}},\"comment\":{}}],[\"boolvalue\",{\"_index\":34,\"name\":{\"36\":{}},\"comment\":{}}],[\"clientsdkkey\",{\"_index\":20,\"name\":{\"22\":{},\"70\":{}},\"comment\":{}}],[\"connectsocket\",{\"_index\":48,\"name\":{\"50\":{}},\"comment\":{}}],[\"constructor\",{\"_index\":2,\"name\":{\"2\":{},\"15\":{}},\"comment\":{}}],[\"enableautoreporting\",{\"_index\":64,\"name\":{\"74\":{}},\"comment\":{}}],[\"errorinitialized\",{\"_index\":53,\"name\":{\"55\":{}},\"comment\":{}}],[\"eventrecorder\",{\"_index\":30,\"name\":{\"32\":{}},\"comment\":{}}],[\"eventsurl\",{\"_index\":15,\"name\":{\"17\":{},\"67\":{}},\"comment\":{}}],[\"extendattrs\",{\"_index\":9,\"name\":{\"10\":{}},\"comment\":{}}],[\"featureprobe\",{\"_index\":12,\"name\":{\"13\":{}},\"comment\":{}}],[\"fetchtoggles\",{\"_index\":51,\"name\":{\"53\":{}},\"comment\":{}}],[\"flush\",{\"_index\":46,\"name\":{\"48\":{}},\"comment\":{}}],[\"fpconfig\",{\"_index\":62,\"name\":{\"64\":{}},\"comment\":{}}],[\"fpdetail\",{\"_index\":54,\"name\":{\"56\":{}},\"comment\":{}}],[\"fpstorageprovider\",{\"_index\":65,\"name\":{\"75\":{}},\"comment\":{}}],[\"fpuser\",{\"_index\":1,\"name\":{\"1\":{}},\"comment\":{}}],[\"get\",{\"_index\":10,\"name\":{\"11\":{},\"81\":{}},\"comment\":{}}],[\"getattrs\",{\"_index\":8,\"name\":{\"8\":{}},\"comment\":{}}],[\"geteventsurl\",{\"_index\":16,\"name\":{\"18\":{}},\"comment\":{}}],[\"getitem\",{\"_index\":67,\"name\":{\"78\":{}},\"comment\":{}}],[\"getkey\",{\"_index\":7,\"name\":{\"7\":{}},\"comment\":{}}],[\"getuser\",{\"_index\":43,\"name\":{\"45\":{}},\"comment\":{}}],[\"httprequest\",{\"_index\":76,\"name\":{\"91\":{}},\"comment\":{}}],[\"identifyuser\",{\"_index\":44,\"name\":{\"46\":{}},\"comment\":{}}],[\"ihttprequest\",{\"_index\":68,\"name\":{\"80\":{}},\"comment\":{}}],[\"initializeplatform\",{\"_index\":0,\"name\":{\"0\":{}},\"comment\":{}}],[\"ioption\",{\"_index\":71,\"name\":{\"86\":{}},\"comment\":{}}],[\"iplatform\",{\"_index\":73,\"name\":{\"88\":{}},\"comment\":{}}],[\"ireturnvalue\",{\"_index\":70,\"name\":{\"85\":{}},\"comment\":{}}],[\"jsondetail\",{\"_index\":41,\"name\":{\"43\":{}},\"comment\":{}}],[\"jsonvalue\",{\"_index\":37,\"name\":{\"39\":{}},\"comment\":{}}],[\"key\",{\"_index\":3,\"name\":{\"3\":{}},\"comment\":{}}],[\"lastmodified\",{\"_index\":61,\"name\":{\"63\":{}},\"comment\":{}}],[\"localstorage\",{\"_index\":74,\"name\":{\"89\":{}},\"comment\":{}}],[\"logout\",{\"_index\":45,\"name\":{\"47\":{}},\"comment\":{}}],[\"newfortest\",{\"_index\":13,\"name\":{\"14\":{}},\"comment\":{}}],[\"numberdetail\",{\"_index\":39,\"name\":{\"41\":{}},\"comment\":{}}],[\"numbervalue\",{\"_index\":35,\"name\":{\"37\":{}},\"comment\":{}}],[\"platform\",{\"_index\":72,\"name\":{\"87\":{}},\"comment\":{}}],[\"post\",{\"_index\":69,\"name\":{\"83\":{}},\"comment\":{}}],[\"readypromise\",{\"_index\":25,\"name\":{\"27\":{}},\"comment\":{}}],[\"realtimepath\",{\"_index\":18,\"name\":{\"20\":{},\"69\":{}},\"comment\":{}}],[\"realtimeurl\",{\"_index\":17,\"name\":{\"19\":{},\"68\":{}},\"comment\":{}}],[\"reason\",{\"_index\":59,\"name\":{\"61\":{}},\"comment\":{}}],[\"refreshinterval\",{\"_index\":19,\"name\":{\"21\":{},\"72\":{}},\"comment\":{}}],[\"remoteurl\",{\"_index\":63,\"name\":{\"65\":{}},\"comment\":{}}],[\"ruleindex\",{\"_index\":56,\"name\":{\"58\":{}},\"comment\":{}}],[\"setitem\",{\"_index\":66,\"name\":{\"76\":{}},\"comment\":{}}],[\"socket\",{\"_index\":29,\"name\":{\"31\":{}},\"comment\":{}}],[\"stablerollout\",{\"_index\":11,\"name\":{\"12\":{}},\"comment\":{}}],[\"start\",{\"_index\":31,\"name\":{\"33\":{}},\"comment\":{}}],[\"status\",{\"_index\":26,\"name\":{\"28\":{}},\"comment\":{}}],[\"stop\",{\"_index\":32,\"name\":{\"34\":{}},\"comment\":{}}],[\"storage\",{\"_index\":28,\"name\":{\"30\":{}},\"comment\":{}}],[\"stringdetail\",{\"_index\":40,\"name\":{\"42\":{}},\"comment\":{}}],[\"stringvalue\",{\"_index\":36,\"name\":{\"38\":{}},\"comment\":{}}],[\"successinitialized\",{\"_index\":52,\"name\":{\"54\":{}},\"comment\":{}}],[\"timeoutinterval\",{\"_index\":27,\"name\":{\"29\":{},\"73\":{}},\"comment\":{}}],[\"timeouttimer\",{\"_index\":24,\"name\":{\"26\":{}},\"comment\":{}}],[\"timer\",{\"_index\":23,\"name\":{\"25\":{}},\"comment\":{}}],[\"toggledetail\",{\"_index\":50,\"name\":{\"52\":{}},\"comment\":{}}],[\"toggles\",{\"_index\":22,\"name\":{\"24\":{}},\"comment\":{}}],[\"togglesurl\",{\"_index\":14,\"name\":{\"16\":{},\"66\":{}},\"comment\":{}}],[\"togglevalue\",{\"_index\":49,\"name\":{\"51\":{}},\"comment\":{}}],[\"track\",{\"_index\":47,\"name\":{\"49\":{}},\"comment\":{}}],[\"trackaccessevents\",{\"_index\":60,\"name\":{\"62\":{}},\"comment\":{}}],[\"ua\",{\"_index\":75,\"name\":{\"90\":{}},\"comment\":{}}],[\"user\",{\"_index\":21,\"name\":{\"23\":{},\"71\":{}},\"comment\":{}}],[\"value\",{\"_index\":55,\"name\":{\"57\":{}},\"comment\":{}}],[\"variationindex\",{\"_index\":57,\"name\":{\"59\":{}},\"comment\":{}}],[\"version\",{\"_index\":58,\"name\":{\"60\":{}},\"comment\":{}}],[\"waituntilready\",{\"_index\":33,\"name\":{\"35\":{}},\"comment\":{}}],[\"with\",{\"_index\":6,\"name\":{\"6\":{}},\"comment\":{}}]],\"pipeline\":[]}}"); \ No newline at end of file diff --git a/docs/classes/FPUser.html b/docs/classes/FPUser.html index 3edb882..306921a 100644 --- a/docs/classes/FPUser.html +++ b/docs/classes/FPUser.html @@ -1,16 +1,16 @@ -FPUser | FeatureProbe Client Side SDK for JavaScript (1.2.1)
+FPUser | FeatureProbe Client Side SDK for JavaScript (2.0.1)
+
  • The search index is not available
  • FeatureProbe Client Side SDK for JavaScript (2.0.1)
    @@ -22,7 +22,7 @@

    Hierarchy

    • FPUser
    +
  • Defined in src/FPUser.ts:5
  • @@ -60,7 +60,7 @@

    Parameters

    Optional key: string

    Returns FPUser

    +
  • Defined in src/FPUser.ts:9
  • Properties

    @@ -72,12 +72,12 @@

    Type declaration

  • [key: string]: string
  • +
  • Defined in src/FPUser.ts:7
  • key: string
    +
  • Defined in src/FPUser.ts:6
  • Methods

    @@ -99,7 +99,7 @@
    attrs: { [key: [key: string]: string

    Returns FPUser

    +
  • Defined in src/FPUser.ts:53
  • Returns undefined | string

    +
  • Defined in src/FPUser.ts:67
  • +
  • Defined in src/FPUser.ts:42
  • +
  • Defined in src/FPUser.ts:31
  • Returns FPUser

    +
  • Defined in src/FPUser.ts:78
  • Returns FPUser

    +
  • Defined in src/FPUser.ts:23
  • +
  • The search index is not available
  • FeatureProbe Client Side SDK for JavaScript (2.0.1)
    @@ -24,7 +24,7 @@

    Hierarchy

    • FeatureProbe
    +
  • Defined in src/FeatureProbe.ts:30
  • @@ -37,7 +37,9 @@

    Constructors

    Properties

    @@ -97,84 +100,94 @@
    __namedParameters: Returns FeatureProbe
    +
  • Defined in src/FeatureProbe.ts:49
  • Properties

    clientSdkKey: string
    +
  • Defined in src/FeatureProbe.ts:37
  • +
    + +
    eventRecorder?: EventRecorder
    eventsUrl: string
    +
  • Defined in src/FeatureProbe.ts:32
  • +
    + +
    getEventsUrl: string
    readyPromise: null | Promise<void>
    +
  • Defined in src/FeatureProbe.ts:42
  • realtimePath: string
    +
  • Defined in src/FeatureProbe.ts:35
  • realtimeUrl: string
    +
  • Defined in src/FeatureProbe.ts:34
  • refreshInterval: number
    +
  • Defined in src/FeatureProbe.ts:36
  • socket?: Socket<DefaultEventsMap, DefaultEventsMap>
    +
  • Defined in src/FeatureProbe.ts:46
  • status: string
    +
  • Defined in src/FeatureProbe.ts:43
  • +
  • Defined in src/FeatureProbe.ts:45
  • timeoutInterval: number
    +
  • Defined in src/FeatureProbe.ts:44
  • -
    timeoutTimer?: any
    +
  • Defined in src/FeatureProbe.ts:41
  • -
    timer?: any
    +
  • Defined in src/FeatureProbe.ts:40
  • toggles: undefined | { [key: string]: FPDetail }
    +
  • Defined in src/FeatureProbe.ts:39
  • togglesUrl: string
    +
  • Defined in src/FeatureProbe.ts:31
  • user: FPUser
    +
  • Defined in src/FeatureProbe.ts:38
  • Methods

    @@ -186,7 +199,7 @@
    +
  • Defined in src/FeatureProbe.ts:288
  • Returns FPDetail

    +
  • Defined in src/FeatureProbe.ts:242
  • Returns boolean

    +
  • Defined in src/FeatureProbe.ts:190
  • +
  • Defined in src/FeatureProbe.ts:365
  • +
  • Defined in src/FeatureProbe.ts:529
  • +
  • Defined in src/FeatureProbe.ts:487
  • +
    + +
    +
  • Defined in src/FeatureProbe.ts:298
  • Returns void

    +
  • Defined in src/FeatureProbe.ts:308
  • +
  • Defined in src/FeatureProbe.ts:281
  • +
  • Defined in src/FeatureProbe.ts:229
  • +
  • Defined in src/FeatureProbe.ts:317
  • Returns FPDetail

    +
  • Defined in src/FeatureProbe.ts:255
  • Returns number

    +
  • Defined in src/FeatureProbe.ts:203
  • +
  • Defined in src/FeatureProbe.ts:104
  • +
  • Defined in src/FeatureProbe.ts:137
  • Returns FPDetail

    +
  • Defined in src/FeatureProbe.ts:268
  • Returns string

    +
  • Defined in src/FeatureProbe.ts:216
  • +
  • Defined in src/FeatureProbe.ts:516
  • Returns FPDetail

    +
  • Defined in src/FeatureProbe.ts:426
  • -

    Returns any

    +
    + +
    +
  • Defined in src/FeatureProbe.ts:332
  • +
  • Defined in src/FeatureProbe.ts:150
  • Returns FeatureProbe

    +
  • Defined in src/FeatureProbe.ts:342
  • +
  • The search index is not available
  • FeatureProbe Client Side SDK for JavaScript (2.0.1)
      - +
    • Initialize SDK with platform

      @@ -23,12 +23,12 @@

      Function initializePlatform

    Parameters

    Returns void

    +
  • Defined in src/index.ts:12
  • +
  • The search index is not available
  • FeatureProbe Client Side SDK for JavaScript (2.0.1)
    -

    FeatureProbe Client Side SDK for JavaScript (1.2.1)

    +

    FeatureProbe Client Side SDK for JavaScript (2.0.1)

    Index

    @@ -24,6 +24,12 @@

    Interfaces

    FPDetail FPStorageProvider IHttpRequest +IOption +IPlatForm +
    +
    +

    Type Aliases

    +
    IReturnValue

    Functions

    @@ -48,7 +54,7 @@

    Theme

    FeatureProbe Client Side SDK for JavaScript (1.2.1) +
  • The search index is not available
  • FeatureProbe Client Side SDK for JavaScript (2.0.1)
    @@ -18,7 +18,7 @@

    Hierarchy

    • FPConfig
    +
  • Defined in src/types.ts:64
  • @@ -27,6 +27,7 @@

    Properties

    +
  • Defined in src/types.ts:93
  • +
    + +
    enableAutoReporting?: boolean
    +

    Whether SDK should report pageview and click event automatically. Default value is true.

    +
    eventsUrl?: string

    The specific URL to post events, if not set, will generate from remoteUrl.

    +
  • Defined in src/types.ts:78
  • realtimePath?: string

    The specific path to receive realtime events, if not set, default value will be used.

    +
  • Defined in src/types.ts:88
  • realtimeUrl?: string

    The specific URL to receive realtime events, if not set, will generate from remoteUrl.

    +
  • Defined in src/types.ts:83
  • refreshInterval?: number

    Milliseconds for SDK to check for update.

    +
  • Defined in src/types.ts:103
  • remoteUrl?: string

    The unified URL to connect FeatureProbe Server.

    +
  • Defined in src/types.ts:68
  • timeoutInterval?: number

    Milliseconds for SDK to initialize, SDK will emit an error event when milliseconds reach.

    +
  • Defined in src/types.ts:108
  • togglesUrl?: string

    The specific URL to get toggles, if not set, will generate from remoteUrl.

    +
  • Defined in src/types.ts:73
  • user: FPUser

    The User with attributes like name, age is used when toggle evaluation.

    +
  • Defined in src/types.ts:98
  • +
  • The search index is not available
  • FeatureProbe Client Side SDK for JavaScript (2.0.1)
    @@ -18,7 +18,7 @@

    Hierarchy

    • FPDetail
    +
  • Defined in src/types.ts:27
  • @@ -26,49 +26,65 @@

    Properties

    +
    + +
    lastModified?: number
    +

    Toggle last modified timestamp

    +
    - +
    reason: string

    Why return this value, like disabled, default, not exist and so on.

    +
  • Defined in src/types.ts:51
  • ruleIndex: null | number

    The sequence number of the rule in the UI configuration that hit the rule.

    +
  • Defined in src/types.ts:36
  • +
    + +
    trackAccessEvents?: boolean
    +

    Whether to report access events.

    +
    value: string | number | boolean | Record<string, unknown>

    The value corresponding to the rule in the UI platform.

    +
  • Defined in src/types.ts:31
  • variationIndex: null | number

    The sequence number of the variation in the UI platform.

    +
  • Defined in src/types.ts:41
  • version: null | number

    The version of the toggle.

    +
  • Defined in src/types.ts:46
  • +
  • The search index is not available
  • FeatureProbe Client Side SDK for JavaScript (2.0.1)
    @@ -18,7 +18,7 @@

    Hierarchy

    • FPStorageProvider
    +
  • Defined in src/types.ts:116
  • @@ -33,13 +33,13 @@

    Properties

    Properties

    -
    getItem: ((key: string) => Promise<any>)
    +
    getItem: ((key: string) => Promise<string>)

    Type declaration

      • -
      • (key: string): Promise<any>
      • +
      • (key: string): Promise<string>
      • Get data from storage.

        @@ -50,18 +50,18 @@

        Parameters

        key: string

        The key of the storage item.

    -

    Returns Promise<any>

    +
  • Defined in src/types.ts:134
  • -
    setItem: ((key: string, data: any) => Promise<void>)
    +
    setItem: ((key: string, data: string) => Promise<void>)

    Type declaration

    Returns Promise<void>

    +
  • Defined in src/types.ts:126
  • +
  • The search index is not available
  • FeatureProbe Client Side SDK for JavaScript (2.0.1)
    @@ -18,7 +18,7 @@

    Hierarchy

    • IHttpRequest
    +
  • Defined in src/types.ts:137
  • @@ -78,7 +78,7 @@
    e: string

    Returns void

    Returns void

    +
  • Defined in src/types.ts:138
  • post: ((url: string, headers: Record<string, string>, data: string, successCb: (() => void), errorCb: ((e: string) => void)) => void)
    @@ -121,7 +121,7 @@
    e: string

    Returns void

    Returns void

    +
  • Defined in src/types.ts:145
  • +
    +
    +
    + +
    +

    Hierarchy

    +
      +
    • IOption
    +
    +
    +
    + +
    +
    +

    Properties

    +
    +
    +

    Properties

    +
    + +
    platform: IPlatForm
    +
    +
    +

    Generated using TypeDoc

    +
    \ No newline at end of file diff --git a/docs/interfaces/IPlatForm.html b/docs/interfaces/IPlatForm.html new file mode 100644 index 0000000..9d08aee --- /dev/null +++ b/docs/interfaces/IPlatForm.html @@ -0,0 +1,80 @@ +IPlatForm | FeatureProbe Client Side SDK for JavaScript (2.0.1)
    +
    + +
    +
    +
    + +
    +

    Hierarchy

    +
      +
    • IPlatForm
    +
    +
    +
    + +
    +
    +

    Properties

    +
    +
    +

    Properties

    +
    + +
    UA: string
    +
    + +
    httpRequest: IHttpRequest
    +
    + +
    localStorage: FPStorageProvider
    +
    +
    +

    Generated using TypeDoc

    +
    \ No newline at end of file diff --git a/docs/types/IReturnValue.html b/docs/types/IReturnValue.html new file mode 100644 index 0000000..ac6248b --- /dev/null +++ b/docs/types/IReturnValue.html @@ -0,0 +1,54 @@ +IReturnValue | FeatureProbe Client Side SDK for JavaScript (2.0.1)
    +
    + +
    +
    +
    + +
    IReturnValue: string | number | boolean | Record<string, unknown>
    +
    +
    +

    Generated using TypeDoc

    +
    \ No newline at end of file diff --git a/example/index.html b/example/index.html index 846d51f..2fde091 100644 --- a/example/index.html +++ b/example/index.html @@ -14,8 +14,8 @@ color: #556ee6; } - - + + @@ -57,6 +57,14 @@

    boolean type

    document.getElementById("boolean-result").innerText = boolValue; const boolDetail = fpClient.boolDetail("campaign_allow_list", false); document.getElementById("boolean-detail").innerText = JSON.stringify(boolDetail); + + setTimeout(() => { + const boolValue = fpClient.boolValue("campaign_allow_list", false); + }, 1000); + + setTimeout(() => { + const boolValue = fpClient.boolValue("campaign_allow_list", false); + }, 10000); }); fpClient.on("update", function() { diff --git a/package-lock.json b/package-lock.json index 75b0a1e..a99fc19 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "featureprobe-client-sdk-js", - "version": "1.2.0", + "version": "2.0.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "featureprobe-client-sdk-js", - "version": "1.2.0", + "version": "2.0.1", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { @@ -1590,29 +1590,6 @@ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true }, - "node_modules/@rollup/plugin-typescript": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.5.0.tgz", - "integrity": "sha512-wMv1/scv0m/rXx21wD2IsBbJFba8wGF3ErJIr6IKRfRj49S85Lszbxb4DCo8iILpluTjk2GAAu9CoZt4G3ppgQ==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "resolve": "^1.17.0" - }, - "engines": { - "node": ">=8.0.0" - }, - "peerDependencies": { - "rollup": "^2.14.0", - "tslib": "*", - "typescript": ">=3.7.0" - }, - "peerDependenciesMeta": { - "tslib": { - "optional": true - } - } - }, "node_modules/@rollup/pluginutils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", @@ -1814,15 +1791,6 @@ "integrity": "sha512-fOwvpvQYStpb/zHMx0Cauwywu9yLDmzWiiQBC7gJyq5tYLUXFZvDG7VK1B7WBxxjBJNKFOZ0zLoOQn8vmATbhw==", "dev": true }, - "node_modules/@types/resolve": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", - "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", @@ -3515,18 +3483,6 @@ "node": ">=6" } }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/escodegen": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", @@ -3739,6 +3695,18 @@ "node": ">=10" } }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint/node_modules/eslint-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", @@ -6802,29 +6770,6 @@ "rollup": ">=1.6.0" } }, - "node_modules/rollup-plugin-commonjs": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz", - "integrity": "sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==", - "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-commonjs.", - "dev": true, - "dependencies": { - "estree-walker": "^0.6.1", - "is-reference": "^1.1.2", - "magic-string": "^0.25.2", - "resolve": "^1.11.0", - "rollup-pluginutils": "^2.8.1" - }, - "peerDependencies": { - "rollup": ">=1.12.0" - } - }, - "node_modules/rollup-plugin-commonjs/node_modules/estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", - "dev": true - }, "node_modules/rollup-plugin-inject": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rollup-plugin-inject/-/rollup-plugin-inject-3.0.2.tgz", @@ -6852,23 +6797,6 @@ "rollup-plugin-inject": "^3.0.0" } }, - "node_modules/rollup-plugin-node-resolve": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz", - "integrity": "sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==", - "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-node-resolve.", - "dev": true, - "dependencies": { - "@types/resolve": "0.0.8", - "builtin-modules": "^3.1.0", - "is-module": "^1.0.0", - "resolve": "^1.11.1", - "rollup-pluginutils": "^2.8.1" - }, - "peerDependencies": { - "rollup": ">=1.11.0" - } - }, "node_modules/rollup-plugin-typescript2": { "version": "0.31.2", "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.31.2.tgz", @@ -9550,15 +9478,6 @@ } } }, - "@rollup/plugin-typescript": { - "version": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.5.0.tgz", - "integrity": "sha512-wMv1/scv0m/rXx21wD2IsBbJFba8wGF3ErJIr6IKRfRj49S85Lszbxb4DCo8iILpluTjk2GAAu9CoZt4G3ppgQ==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^3.1.0", - "resolve": "^1.17.0" - } - }, "@rollup/pluginutils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", @@ -9753,15 +9672,6 @@ "integrity": "sha512-fOwvpvQYStpb/zHMx0Cauwywu9yLDmzWiiQBC7gJyq5tYLUXFZvDG7VK1B7WBxxjBJNKFOZ0zLoOQn8vmATbhw==", "dev": true }, - "@types/resolve": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", - "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", @@ -11108,12 +11018,6 @@ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, "escodegen": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", @@ -11222,6 +11126,12 @@ "v8-compile-cache": "^2.0.3" }, "dependencies": { + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, "eslint-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", @@ -13557,26 +13467,6 @@ "sourcemap-codec": "^1.4.8" } }, - "rollup-plugin-commonjs": { - "version": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz", - "integrity": "sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==", - "dev": true, - "requires": { - "estree-walker": "^0.6.1", - "is-reference": "^1.1.2", - "magic-string": "^0.25.2", - "resolve": "^1.11.0", - "rollup-pluginutils": "^2.8.1" - }, - "dependencies": { - "estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", - "dev": true - } - } - }, "rollup-plugin-inject": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rollup-plugin-inject/-/rollup-plugin-inject-3.0.2.tgz", @@ -13605,18 +13495,6 @@ "rollup-plugin-inject": "^3.0.0" } }, - "rollup-plugin-node-resolve": { - "version": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz", - "integrity": "sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==", - "dev": true, - "requires": { - "@types/resolve": "0.0.8", - "builtin-modules": "^3.1.0", - "is-module": "^1.0.0", - "resolve": "^1.11.1", - "rollup-pluginutils": "^2.8.1" - } - }, "rollup-plugin-typescript2": { "version": "0.31.2", "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.31.2.tgz", diff --git a/package.json b/package.json index 2cf38d0..16526e9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "featureprobe-client-sdk-js", - "version": "1.2.1", + "version": "2.0.1", "description": "FeatureProbe Client Side SDK for JavaScript", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", diff --git a/src/EventRecorder.ts b/src/EventRecorder.ts new file mode 100644 index 0000000..7c30500 --- /dev/null +++ b/src/EventRecorder.ts @@ -0,0 +1,184 @@ +import { getPlatform } from "./platform"; +import { IAccessEvent, IAccess, IToggleCounter, ClickEvent, PageViewEvent, AccessEvent, CustomEvent } from "./types"; + +export class EventRecorder { + private clientSdkKey: string; + private eventsUrl: string; + private closed: boolean; + private sendAccessQueue: IAccessEvent[]; + private sendEventQueue: (AccessEvent | CustomEvent | ClickEvent | PageViewEvent)[]; + private taskQueue: AsyncBlockingQueue>; + private timer: NodeJS.Timer; + private readonly dispatch: Promise; + + set flushInterval(value: number) { + clearInterval(this.timer); + this.timer = setInterval(() => this.flush(), value); + } + + get accessQueue(): IAccessEvent[] { + return this.sendAccessQueue; + } + + get eventQueue(): (AccessEvent | CustomEvent | ClickEvent | PageViewEvent)[] { + return this.sendEventQueue; + } + + constructor( + clientSdkKey: string, + eventsUrl: string, + flushInterval: number, + ) { + this.clientSdkKey = clientSdkKey; + this.eventsUrl = eventsUrl; + this.closed = false; + this.sendAccessQueue = []; + this.sendEventQueue = []; + this.taskQueue = new AsyncBlockingQueue>(); + this.timer = setInterval(() => this.flush(), flushInterval); + this.dispatch = this.startDispatch(); + } + + public recordAccessEvent(accessEvent: IAccessEvent): void { + if (this.closed) { + console.warn("Trying to push access record to a closed EventProcessor, omitted"); + return; + } + this.sendAccessQueue.push(accessEvent); + } + + public recordTrackEvent(trackEvents: ClickEvent | PageViewEvent | AccessEvent | CustomEvent): void { + if (this.closed) { + console.warn("Trying to push access record to a closed EventProcessor, omitted"); + return; + } + this.sendEventQueue.push(trackEvents); + } + + public flush(): void { + if (this.closed) { + console.warn("Trying to flush a closed EventProcessor, omitted"); + return; + } + this.taskQueue.enqueue(this.doFlush()); + } + + public async stop(): Promise { + if (this.closed) { + console.warn("EventProcessor is already closed"); + return; + } + clearInterval(this.timer); + this.closed = true; + this.taskQueue.enqueue(this.doFlush()); + await this.dispatch; + } + + private async startDispatch(): Promise { + while (!this.closed || !this.taskQueue.isEmpty()) { + await this.taskQueue.dequeue(); + } + } + + private prepareSendData(events: IAccessEvent[]): IAccess { + let start = -1, end = -1; + const counters: { [key: string]: IToggleCounter[] } = {}; + for (const event of events) { + if (start < 0 || start < event.time) { + start = event.time; + } + if (end < 0 || end > event.time) { + end = event.time; + } + + if (counters[event.key] === undefined) { + counters[event.key] = []; + } + let added = false; + for (const counter of counters[event.key]) { + if (counter.index === event.index + && counter.version === event.version + && counter.value === event.value) { + counter.count++; + added = true; + break; + } + } + if (!added) { + counters[event.key].push({ + index: event.index, + version: event.version, + value: event.value, + count: 1, + } as IToggleCounter); + } + } + return { + startTime: start, + endTime: end, + counters: counters, + } as IAccess; + } + + private async doFlush(): Promise { + if (this.sendAccessQueue.length === 0 && this.sendEventQueue.length === 0) { + return; + } + const accessEvents = Object.assign([], this.sendAccessQueue); + const trackEvents = Object.assign([], this.sendEventQueue); + + this.sendAccessQueue = []; + this.sendEventQueue = []; + + const eventRepos = [{ + events: trackEvents, + access: accessEvents.length === 0 ? null : this.prepareSendData(accessEvents), + }]; + + getPlatform().httpRequest.post(this.eventsUrl, { + "Authorization": this.clientSdkKey, + "Content-Type": "application/json", + "UA": getPlatform()?.UA, + }, JSON.stringify(eventRepos), () => { + // Do nothing + }, (error: string) => { + console.error("FeatureProbe JS SDK: Error reporting events: ", error); + }); + + } +} + +// Reference: https://stackoverflow.com/questions/47157428/how-to-implement-a-pseudo-blocking-async-queue-in-js-ts +class AsyncBlockingQueue { + private promises: Promise[]; + private resolvers: ((t: T) => void)[]; + + constructor() { + this.resolvers = []; + this.promises = []; + } + + private add() { + this.promises.push(new Promise(resolve => { + this.resolvers.push(resolve); + })); + } + + enqueue(t: T) { + if (!this.resolvers.length) { + this.add(); + } + this.resolvers.shift()?.(t); + } + + dequeue(): Promise | undefined { + if (!this.promises.length) { + this.add(); + } + return this.promises.shift(); + } + + isEmpty() { + return !this.promises.length; + } +} diff --git a/src/FeatureProbe.ts b/src/FeatureProbe.ts index fc2883f..7d51ae1 100644 --- a/src/FeatureProbe.ts +++ b/src/FeatureProbe.ts @@ -1,10 +1,12 @@ import { TinyEmitter } from "tiny-emitter"; import { Base64 } from "js-base64"; import { FPUser } from "./FPUser"; -import { FPDetail, FPStorageProvider, FPConfig, IParams } from "./types"; +import { FPDetail, FPStorageProvider, FPConfig, IReturnValue } from "./types"; import { io, Socket } from "socket.io-client"; import { DefaultEventsMap } from "@socket.io/component-emitter"; import { getPlatform } from "./platform"; +import { EventRecorder } from "./EventRecorder"; +import reportEvents from "./autoReportEvents"; const KEY = "repository"; const EVENTS = { @@ -28,19 +30,21 @@ const STATUS = { class FeatureProbe extends TinyEmitter { private togglesUrl: string; private eventsUrl: string; + private getEventsUrl: string; private realtimeUrl: string; private realtimePath: string; private refreshInterval: number; private clientSdkKey: string; private user: FPUser; private toggles: { [key: string]: FPDetail } | undefined; - private timer?: any; - private timeoutTimer?: any; + private timer?: NodeJS.Timer; + private timeoutTimer?: NodeJS.Timer; private readyPromise: null | Promise; private status: string; private timeoutInterval: number; private storage: FPStorageProvider; private socket?: Socket; + private eventRecorder?: EventRecorder; constructor({ remoteUrl, @@ -51,7 +55,8 @@ class FeatureProbe extends TinyEmitter { clientSdkKey, user, refreshInterval = 1000, - timeoutInterval = 10000 + timeoutInterval = 10000, + enableAutoReporting = true, }: FPConfig) { super(); if (!clientSdkKey) { @@ -76,6 +81,7 @@ class FeatureProbe extends TinyEmitter { this.toggles = undefined; this.togglesUrl = togglesUrl ?? remoteUrl + "/api/client-sdk/toggles"; this.eventsUrl = eventsUrl ?? remoteUrl + "/api/events"; + this.getEventsUrl = eventsUrl ?? remoteUrl + "/api/client-sdk/events"; this.realtimeUrl = realtimeUrl ?? remoteUrl + "/realtime"; this.realtimePath = realtimePath ?? "/server/realtime"; this.user = user; @@ -85,6 +91,11 @@ class FeatureProbe extends TinyEmitter { this.status = STATUS.START; this.storage = getPlatform().localStorage; this.readyPromise = null; + this.eventRecorder = new EventRecorder(this.clientSdkKey, this.eventsUrl, this.refreshInterval); + + if (enableAutoReporting) { + reportEvents(this.clientSdkKey, user, this.getEventsUrl, this.eventRecorder); + } } /** @@ -92,9 +103,11 @@ class FeatureProbe extends TinyEmitter { */ public async start(): Promise { this.connectSocket(); + if (this.status !== STATUS.START) { return; } + this.status = STATUS.PENDING; this.timeoutTimer = setTimeout(() => { @@ -104,7 +117,7 @@ class FeatureProbe extends TinyEmitter { }, this.timeoutInterval); try { - // Emit `cache_ready` event if toggles exist in LocalStorage + // Emit `cache_ready` event if toggles exist in localStorage const toggles = await this.storage.getItem(KEY); if (toggles) { this.toggles = JSON.parse(toggles); @@ -124,8 +137,8 @@ class FeatureProbe extends TinyEmitter { public stop(): void { clearInterval(this.timer); clearTimeout(this.timeoutTimer); - this.timeoutTimer = null; - this.timer = null; + this.timeoutTimer = undefined; + this.timer = undefined; } /** @@ -306,7 +319,27 @@ class FeatureProbe extends TinyEmitter { this.identifyUser(user); } - static newForTest(toggles: { [key: string]: any }): FeatureProbe { + /** + * Manually push events. + */ + public flush(): void { + this.eventRecorder?.flush(); + } + + /** + * Record custom events, value is optional. + */ + public track(name: string, user: string, value?: unknown): void { + this.eventRecorder?.recordTrackEvent({ + kind: "custom", + name, + time: Date.now(), + user, + value, + }); + } + + static newForTest(toggles: { [key: string]: boolean }): FeatureProbe { const fp = new FeatureProbe({ remoteUrl: "http://127.0.0.1:4000", clientSdkKey: "_", @@ -348,9 +381,7 @@ class FeatureProbe extends TinyEmitter { this.socket = socket; } - private toggleValue(key: string, defaultValue: any, valueType: string): any { - this.sendEvents(key); - + private toggleValue(key: string, defaultValue: IReturnValue, valueType: string): IReturnValue { if (this.toggles == undefined) { return defaultValue; } @@ -362,6 +393,30 @@ class FeatureProbe extends TinyEmitter { const v = detail.value; if (typeof v == valueType) { + const timestamp = Date.now(); + + this.eventRecorder?.recordAccessEvent({ + time: timestamp, + key: key, + value: detail.value, + index: detail.variationIndex ?? -1, + version: detail.version ?? 0, + reason: detail.reason + }); + + if (detail.trackAccessEvents) { + this.eventRecorder?.recordTrackEvent({ + kind: "access", + time: timestamp, + user: this.getUser().getKey(), + key: key, + value: detail.value, + variationIndex: detail.variationIndex ?? -1, + ruleIndex: detail.ruleIndex ?? null, + version: detail.version ?? 0, + }); + } + return v; } else { return defaultValue; @@ -370,11 +425,9 @@ class FeatureProbe extends TinyEmitter { private toggleDetail( key: string, - defaultValue: any, + defaultValue: IReturnValue, valueType: string ): FPDetail { - this.sendEvents(key); - if (this.toggles == undefined) { return { value: defaultValue, @@ -395,6 +448,30 @@ class FeatureProbe extends TinyEmitter { reason: "Toggle: [" + key + "] not found", }; } else if (typeof detail.value === valueType) { + const timestamp = Date.now(); + + this.eventRecorder?.recordAccessEvent({ + time: timestamp, + key: key, + value: detail.value, + index: detail.variationIndex ?? -1, + version: detail.version ?? 0, + reason: detail.reason + }); + + if (detail.trackAccessEvents) { + this.eventRecorder?.recordTrackEvent({ + kind: "access", + time: timestamp, + user: this.getUser().getKey(), + key: key, + value: detail.value, + variationIndex: detail.variationIndex ?? -1, + ruleIndex: detail.ruleIndex ?? null, + version: detail.version ?? 0, + }); + } + return detail; } else { return { @@ -435,40 +512,6 @@ class FeatureProbe extends TinyEmitter { }) } - private async sendEvents(key: string): Promise { - if (this.toggles && this.toggles[key]) { - const timestamp = Date.now(); - const payload: IParams[] = [ - { - access: { - startTime: timestamp, - endTime: timestamp, - counters: { - [key]: [ - { - count: 1, - value: this.toggles[key].value, - index: this.toggles[key].variationIndex, - version: this.toggles[key].version, - }, - ], - }, - }, - }, - ]; - - getPlatform().httpRequest.post(this.eventsUrl, { - Authorization: this.clientSdkKey, - "Content-Type": "application/json", - UA: getPlatform()?.UA, - }, JSON.stringify(payload), () => { - // - }, (error: string) => { - console.error("FeatureProbe JS SDK: Error reporting events: ", error); - }) - } - } - // Emit `ready` event if toggles are successfully returned from server private successInitialized() { this.status = STATUS.READY; @@ -478,7 +521,7 @@ class FeatureProbe extends TinyEmitter { if (this.timeoutTimer) { clearTimeout(this.timeoutTimer); - this.timeoutTimer = null; + this.timeoutTimer = undefined; } } @@ -491,7 +534,7 @@ class FeatureProbe extends TinyEmitter { if (this.timer) { clearInterval(this.timer); - this.timer = null; + this.timer = undefined; } } } diff --git a/src/autoReportEvents.ts b/src/autoReportEvents.ts new file mode 100644 index 0000000..a29ec6e --- /dev/null +++ b/src/autoReportEvents.ts @@ -0,0 +1,216 @@ +import { getPlatform } from "./platform"; +import { FPUser } from "."; +import { EventRecorder } from "./EventRecorder"; +import { ClickEvent, IEvent, IEventValue, PageViewEvent } from "./types"; + +// Reference: https://github.com/sindresorhus/escape-string-regexp +function escapeStringRegexp(string: string): string { + if (typeof string !== 'string') { + throw new TypeError('Expected a string'); + } + + return string + .replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') + .replace(/-/g, '\\x2d'); +} + +/** + * + * Validate whether current page url matches the rule set by event.matcher + * + * @param event + * Event detail + */ +function matchUrl(event: IEventValue): boolean { + const { href, hash, search } = window.location; + let regex; + let testUrl; + + switch (event.matcher) { + case 'EXACT': + testUrl = href; + regex = new RegExp('^' + escapeStringRegexp(event.url) + '/?$'); + break; + case 'SIMPLE': + testUrl = href.replace(hash, '').replace(search, ''); + regex = new RegExp('^' + escapeStringRegexp(event.url) + '/?$'); + break; + case 'SUBSTRING': + testUrl = href.replace(search, ''); + regex = new RegExp('.*' + escapeStringRegexp(event.url) + '.*$'); + break; + case 'REGULAR': + testUrl = href.replace(search, ''); + regex = new RegExp(event.url); + break; + default: + return false; + } + + return regex.test(testUrl); +} + +export default function reportEvents( + clientSdkKey: string, + user: FPUser, + getEventsUrl: string, + eventRecorder: EventRecorder +): void { + let previousUrl: string = window.location.href; + let currentUrl; + let cb: (event: MouseEvent) => void; + let totalEvents: IEvent; + + /** + * + * Report different events to Server API + * + * @param kind + * Event type, like click, pageview, etc. + * @param event + * Event detail + */ + function sendEvents(kind: string, event: IEventValue) { + const sendEvent: PageViewEvent = { + kind: kind, + name: event.name, + time: Date.now(), + user: user.getKey(), + url: window.location.href, + }; + + if (kind === 'click' && event.selector) { + (sendEvent as ClickEvent).selector = event.selector; + } + + eventRecorder?.recordTrackEvent(sendEvent); + } + + /** + * + * Find the element that was clicked by event bubbling + * + * @param event + * Mouse event + * @param clickEvents + * All click events + * @returns + * Match click events + */ + function getClickEvents(event: MouseEvent, clickEvents: IEventValue[]) { + const matchedEvents = []; + + for (let i = 0; i < clickEvents.length; i++) { + let target = event.target; + const clickEvent = clickEvents[i]; + const selector = clickEvent.selector; + + const elements = selector && document.querySelectorAll(selector); + + while (target && elements && elements.length > 0) { + for (let j = 0; j < elements.length; j++) { + if (target === elements[j]) { + matchedEvents.push(clickEvent); + } + } + target = ((target).parentNode); + } + } + + return matchedEvents; + } + + /** + * + * First, find all events URLs, if current page url matches one of them, + * send pageview events automatically. + * + * Second, register document click event, if an element is clicked, + * and it's CSS selector matches the event's selector, + * send click event automatically. + * + * + * @param data + * + */ + function distinguishEvents(data: IEvent) { + const clickEvents: IEventValue[] = []; + + for (const key in data) { + const event: IEventValue = data[key]; + + if (matchUrl(event)) { + if (event.type === 'PAGE_VIEW') { + sendEvents('pageview', event); + } else if (event.type === 'CLICK') { + sendEvents('pageview', event); + clickEvents.push(event); + } + } + } + + if (clickEvents.length > 0) { + cb = function(event: MouseEvent) { + const result = getClickEvents(event, clickEvents); + for (let i = 0; i < result.length; i++) { + sendEvents('click', result[i]); + } + }; + + document.addEventListener('click', cb); + } + } + + /** + * + * Watch the change of the page url. + * If it changes, register the pageview events and click events again. + * + */ + function watchUrlChange() { + currentUrl = window.location.href; + + if (currentUrl !== previousUrl) { + previousUrl = currentUrl; + document.removeEventListener('click', cb); + cb = function() { + // do nothing + } + + distinguishEvents(totalEvents); + } + } + + /** + * Register popstate event when using history router + */ + window.addEventListener('popstate', watchUrlChange); + + /** + * Register hashchange event when using hash router + */ + window.addEventListener('hashchange', watchUrlChange); + + /** + * If popstate or hashchange events are not supported + */ + setInterval(() => { + watchUrlChange(); + }, 300); + + /** + * Get events data from Server API + */ + getPlatform().httpRequest.get(getEventsUrl, { + 'Authorization': clientSdkKey, + "Content-Type": "application/json", + 'UA': getPlatform()?.UA, + }, {}, res => { + if (res) { + distinguishEvents(res as IEvent); + totalEvents = res as IEvent; + } + }, (error: string) => { + console.error('FeatureProbe JS SDK: Error getting events: ', error); + }) +} diff --git a/src/index.ts b/src/index.ts index c58b5c3..8742b0f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ import { FPUser } from './FPUser'; import { FeatureProbe } from './FeatureProbe'; -import { FPConfig, FPStorageProvider, IOption, FPDetail, IHttpRequest } from './types'; +import { FPConfig, FPStorageProvider, IOption, FPDetail, IHttpRequest, IReturnValue, IPlatForm } from './types'; import { setPlatform } from './platform'; /** @@ -15,4 +15,15 @@ function initializePlatform(options: IOption): void { } } -export { FPUser, FeatureProbe, FPDetail, FPConfig, FPStorageProvider, IHttpRequest, initializePlatform }; +export { + FPUser, + FeatureProbe, + FPDetail, + FPConfig, + FPStorageProvider, + IHttpRequest, + IReturnValue, + IOption, + IPlatForm, + initializePlatform, +}; diff --git a/src/types.ts b/src/types.ts index 6f93b4e..a7a9e3c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,25 +1,28 @@ import { FPUser } from "./FPUser"; -interface IValue { - count: number; +export interface IAccessEvent { + time: number; + key: string; value: boolean | string | number | Record; - index: number | null; - version: number | null; + index: number; + version: number; + reason: string | null; } -interface ICounter { - [key: string]: IValue[]; +export interface IToggleCounter { + value: boolean | string | number | Record; + version: number; + index: number; + count: number; } -interface IAccess { +export interface IAccess { startTime: number; endTime: number; - counters: ICounter; + counters: { [key: string]: IToggleCounter[] }; } -export interface IParams { - access: IAccess; -} +export type IReturnValue = string | number | boolean | Record; export interface FPDetail { /** @@ -46,6 +49,16 @@ export interface FPDetail { * Why return this value, like disabled, default, not exist and so on. */ reason: string; + + /** + * Whether to report access events. + */ + trackAccessEvents?: boolean; + + /** + * Toggle last modified timestamp + */ + lastModified?: number; } export interface FPConfig { @@ -92,7 +105,12 @@ export interface FPConfig { /** * Milliseconds for SDK to initialize, SDK will emit an `error` event when milliseconds reach. */ - timeoutInterval?: number + timeoutInterval?: number; + + /** + * Whether SDK should report pageview and click event automatically. Default value is true. + */ + enableAutoReporting?: boolean; } export interface FPStorageProvider { @@ -105,8 +123,7 @@ export interface FPStorageProvider { * @param data * The data of the storage item. */ - - setItem: (key: string, data: any) => Promise; + setItem: (key: string, data: string) => Promise; /** * Get data from storage. @@ -114,7 +131,7 @@ export interface FPStorageProvider { * @param key * The key of the storage item. */ - getItem: (key: string) => Promise; + getItem: (key: string) => Promise; } export interface IHttpRequest { @@ -143,3 +160,51 @@ export interface IPlatForm { export interface IOption { platform: IPlatForm } + +export interface AccessEvent { + kind: string; + time: number; + user: string; + key: string; + value: boolean | string | number | Record; + variationIndex: number; + ruleIndex: number | null; + version: number; +} + +export interface CustomEvent { + kind: string; + name: string; + time: number; + user: string; + value: unknown; +} + +export interface ClickEvent { + kind: string; + name: string; + time: number; + user: string; + url: string; + selector: string; +} + +export interface PageViewEvent { + kind: string; + name: string; + time: number; + user: string; + url: string; +} + +export interface IEventValue { + matcher: string; + name: string; + type: string; + url: string; + selector?: string; +} + +export interface IEvent { + [key: string]: IEventValue +} diff --git a/test/FeatureProbe.test.ts b/test/FeatureProbe.test.ts index de2b774..0fe8983 100644 --- a/test/FeatureProbe.test.ts +++ b/test/FeatureProbe.test.ts @@ -15,6 +15,7 @@ test("FeatureProbe init with invalid param", () => { new FeatureProbe({ clientSdkKey: "client-sdk-key1", user: new FPUser(), + enableAutoReporting: false, }); }).toThrow(); @@ -23,6 +24,7 @@ test("FeatureProbe init with invalid param", () => { remoteUrl: "invalid url", clientSdkKey: "", user: new FPUser(), + enableAutoReporting: false, }); }).toThrow(); @@ -32,6 +34,7 @@ test("FeatureProbe init with invalid param", () => { clientSdkKey: "client-sdk-key1", user: new FPUser(), refreshInterval: -1, + enableAutoReporting: false, }); }).toThrow(); @@ -39,6 +42,7 @@ test("FeatureProbe init with invalid param", () => { new FeatureProbe({ clientSdkKey: "client-sdk-key1", user: new FPUser(), + enableAutoReporting: false, }); }).toThrow(); @@ -47,6 +51,7 @@ test("FeatureProbe init with invalid param", () => { togglesUrl: "http://127.0.0.1:4007", clientSdkKey: "client-sdk-key1", user: new FPUser(), + enableAutoReporting: false, }); }).toThrow(); @@ -55,6 +60,7 @@ test("FeatureProbe init with invalid param", () => { eventsUrl: "http://127.0.0.1:4007", clientSdkKey: "client-sdk-key1", user: new FPUser(), + enableAutoReporting: false, }); }).toThrow(); }); @@ -65,6 +71,7 @@ test("FeatureProbe init", () => { remoteUrl: "http://127.0.0.1:4007", clientSdkKey: "client-sdk-key1", user: new FPUser(), + enableAutoReporting: false, }) ).not.toBeNull(); }); @@ -76,6 +83,7 @@ test("FeatureProbe request", (done) => { remoteUrl: "http://127.0.0.1:4007", clientSdkKey: "client-sdk-key1", user: user, + enableAutoReporting: false, }); fp.start(); fp.on("ready", function () { @@ -92,6 +100,7 @@ test("FeatureProbe bool toggle", (done) => { remoteUrl: "http://127.0.0.1:4007", clientSdkKey: "client-sdk-key1", user: user, + enableAutoReporting: false, }); fp.start(); fp.on("ready", function () { @@ -117,6 +126,7 @@ test("FeatureProbe number toggle", (done) => { remoteUrl: "http://127.0.0.1:4007", clientSdkKey: "client-sdk-key1", user: user, + enableAutoReporting: false, }); fp.start(); @@ -143,6 +153,7 @@ test("FeatureProbe string toggle", (done) => { remoteUrl: "http://127.0.0.1:4007", clientSdkKey: "client-sdk-key1", user: user, + enableAutoReporting: false, }); fp.start(); fp.on("ready", function () { @@ -169,6 +180,7 @@ test("FeatureProbe json toggle", (done) => { remoteUrl: "http://127.0.0.1:4007", clientSdkKey: "client-sdk-key1", user: user, + enableAutoReporting: false, }); fp.start(); @@ -198,6 +210,7 @@ test("FeatureProbe all toggle", (done) => { remoteUrl: "http://127.0.0.1:4007", clientSdkKey: "client-sdk-key1", user: user, + enableAutoReporting: false, }); fp.start(); @@ -224,6 +237,7 @@ test("FeatureProbe used toggle value before ready", (done) => { remoteUrl: "http://127.0.0.1:4007", clientSdkKey: "client-sdk-key1", user: user, + enableAutoReporting: false, }); fp.start(); @@ -245,6 +259,7 @@ test("FeatureProbe used toggle value with error key", (done) => { remoteUrl: "http://127.0.0.1:4007", clientSdkKey: "client-sdk-key1", user: user, + enableAutoReporting: false, }); fp.start(); @@ -269,6 +284,7 @@ test("FeatureProbe logout", (done) => { remoteUrl: "http://127.0.0.1:4007", clientSdkKey: "client-sdk-key1", user: user, + enableAutoReporting: false, }); fp.logout(); expect(fp.getUser().get('city')).toBe(undefined); @@ -281,6 +297,7 @@ test("feature promise api", (done) => { remoteUrl: "http://127.0.0.1:4007", clientSdkKey: "client-sdk-key1", user: new FPUser(), + enableAutoReporting: false, }); fp.waitUntilReady().then(() => { @@ -300,6 +317,7 @@ test("FeatureProbe fetch error", (done) => { clientSdkKey: "client-sdk-key1", user: new FPUser(), refreshInterval: 10000, + enableAutoReporting: false, }); fp.start(); @@ -315,6 +333,7 @@ test("FeatureProbe fetch error trigger error event", (done) => { user: new FPUser(), refreshInterval: 10000, timeoutInterval: 1000, + enableAutoReporting: false, }); fp.on('error', () =>{ diff --git a/test/autoReportEvents.test.ts b/test/autoReportEvents.test.ts new file mode 100644 index 0000000..d88c4b7 --- /dev/null +++ b/test/autoReportEvents.test.ts @@ -0,0 +1,35 @@ +import reportEvents from "../src/autoReportEvents"; +import { EventRecorder } from "../src/EventRecorder"; +import { FPUser } from "../src/FPUser"; + +import { FetchMock } from "jest-fetch-mock"; +import * as data from "./fixtures/events.json"; + +const _fetch = fetch as FetchMock; + +beforeEach(() => {}); + +afterEach(() => { + _fetch.resetMocks(); +}); + +test("report events", (done) => { + _fetch.mockResponseOnce(JSON.stringify(data)); + const clientSdkKey = 'clientSdkKey'; + const eventsUrl = 'http://featureprobe.io/server/event'; + const recorder = new EventRecorder(clientSdkKey, eventsUrl, 10000); + const user = new FPUser('11111').with("city", "2"); + + reportEvents(clientSdkKey, user, eventsUrl, recorder); + + + setTimeout(() => { + document.body.click(); + expect(recorder.eventQueue.length).toBe(3); + expect(recorder.eventQueue[0].kind).toBe('pageview'); + expect(recorder.eventQueue[1].kind).toBe('pageview'); + expect(recorder.eventQueue[2].kind).toBe('click'); + done(); + }, 100); +}); + diff --git a/test/fixtures/events.json b/test/fixtures/events.json new file mode 100644 index 0000000..4abbadc --- /dev/null +++ b/test/fixtures/events.json @@ -0,0 +1,15 @@ +{ + "5d3ff41f68f14c6c5fccf06487444218": { + "matcher": "SIMPLE", + "name": "5d3ff41f68f14c6c5fccf06487444218", + "type": "PAGE_VIEW", + "url": "http://localhost" + }, + "723fe44736793b2d64ad028e7103e0e5": { + "matcher": "EXACT", + "name": "723fe44736793b2d64ad028e7103e0e5", + "type": "CLICK", + "url": "http://localhost", + "selector": "body" + } +} \ No newline at end of file