@featbit/js-client-sdk 2.0.2 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -201
- package/README.md +160 -152
- package/dist/esm/Configuration.d.ts +35 -0
- package/dist/esm/Configuration.d.ts.map +1 -0
- package/dist/esm/Configuration.js +179 -0
- package/dist/esm/Configuration.js.map +1 -0
- package/dist/esm/Context.d.ts +23 -0
- package/dist/esm/Context.d.ts.map +1 -0
- package/dist/esm/Context.js +49 -0
- package/dist/esm/Context.js.map +1 -0
- package/dist/esm/FbClientBuilder.d.ts +90 -0
- package/dist/esm/FbClientBuilder.d.ts.map +1 -0
- package/dist/esm/FbClientBuilder.js +133 -0
- package/dist/esm/FbClientBuilder.js.map +1 -0
- package/dist/esm/FbClientCore.d.ts +57 -0
- package/dist/esm/FbClientCore.d.ts.map +1 -0
- package/dist/esm/FbClientCore.js +283 -0
- package/dist/esm/FbClientCore.js.map +1 -0
- package/dist/esm/IContextProperty.d.ts +5 -0
- package/dist/esm/IContextProperty.d.ts.map +1 -0
- package/dist/esm/IContextProperty.js +3 -0
- package/dist/esm/IContextProperty.js.map +1 -0
- package/dist/esm/IDataKind.d.ts +12 -0
- package/dist/esm/IDataKind.d.ts.map +1 -0
- package/dist/esm/IDataKind.js +3 -0
- package/dist/esm/IDataKind.js.map +1 -0
- package/dist/esm/IFbClient.d.ts +30 -0
- package/dist/esm/IFbClient.d.ts.map +1 -0
- package/dist/esm/IFbClient.js +3 -0
- package/dist/esm/IFbClient.js.map +1 -0
- package/dist/esm/IFbClientCore.d.ts +240 -0
- package/dist/esm/IFbClientCore.d.ts.map +1 -0
- package/dist/esm/IFbClientCore.js +3 -0
- package/dist/esm/IFbClientCore.js.map +1 -0
- package/dist/esm/IVersionedData.d.ts +18 -0
- package/dist/esm/IVersionedData.d.ts.map +1 -0
- package/dist/esm/IVersionedData.js +3 -0
- package/dist/esm/IVersionedData.js.map +1 -0
- package/dist/esm/bootstrap/IBootstrapProvider.d.ts +5 -0
- package/dist/esm/bootstrap/IBootstrapProvider.d.ts.map +1 -0
- package/dist/esm/bootstrap/IBootstrapProvider.js +3 -0
- package/dist/esm/bootstrap/IBootstrapProvider.js.map +1 -0
- package/dist/esm/bootstrap/JsonBootstrapProvider.d.ts +9 -0
- package/dist/esm/bootstrap/JsonBootstrapProvider.d.ts.map +1 -0
- package/dist/esm/bootstrap/JsonBootstrapProvider.js +29 -0
- package/dist/esm/bootstrap/JsonBootstrapProvider.js.map +1 -0
- package/dist/esm/bootstrap/NullBootstrapProvider.d.ts +8 -0
- package/dist/esm/bootstrap/NullBootstrapProvider.d.ts.map +1 -0
- package/dist/esm/bootstrap/NullBootstrapProvider.js +19 -0
- package/dist/esm/bootstrap/NullBootstrapProvider.js.map +1 -0
- package/dist/esm/bootstrap/index.d.ts +4 -0
- package/dist/esm/bootstrap/index.d.ts.map +1 -0
- package/dist/esm/bootstrap/index.js +20 -0
- package/dist/esm/bootstrap/index.js.map +1 -0
- package/dist/esm/constants.d.ts +3 -0
- package/dist/esm/constants.d.ts.map +1 -0
- package/dist/esm/constants.js +6 -0
- package/dist/esm/constants.js.map +1 -0
- package/dist/esm/data-sources/DataSourceUpdates.d.ts +17 -0
- package/dist/esm/data-sources/DataSourceUpdates.d.ts.map +1 -0
- package/dist/esm/data-sources/DataSourceUpdates.js +89 -0
- package/dist/esm/data-sources/DataSourceUpdates.js.map +1 -0
- package/dist/esm/data-sources/createStreamListeners.d.ts +19 -0
- package/dist/esm/data-sources/createStreamListeners.d.ts.map +1 -0
- package/dist/esm/data-sources/createStreamListeners.js +49 -0
- package/dist/esm/data-sources/createStreamListeners.js.map +1 -0
- package/dist/esm/data-sources/index.d.ts +3 -0
- package/dist/esm/data-sources/index.d.ts.map +1 -0
- package/dist/esm/data-sources/index.js +19 -0
- package/dist/esm/data-sources/index.js.map +1 -0
- package/dist/esm/data-sync/DataSyncMode.d.ts +5 -0
- package/dist/esm/data-sync/DataSyncMode.d.ts.map +1 -0
- package/dist/esm/data-sync/DataSyncMode.js +9 -0
- package/dist/esm/data-sync/DataSyncMode.js.map +1 -0
- package/dist/esm/data-sync/IDataSynchronizer.d.ts +15 -0
- package/dist/esm/data-sync/IDataSynchronizer.d.ts.map +1 -0
- package/dist/esm/data-sync/IDataSynchronizer.js +3 -0
- package/dist/esm/data-sync/IDataSynchronizer.js.map +1 -0
- package/dist/esm/data-sync/IRequestor.d.ts +11 -0
- package/dist/esm/data-sync/IRequestor.d.ts.map +1 -0
- package/dist/esm/data-sync/IRequestor.js +3 -0
- package/dist/esm/data-sync/IRequestor.js.map +1 -0
- package/dist/esm/data-sync/NullDataSynchronizer.d.ts +8 -0
- package/dist/esm/data-sync/NullDataSynchronizer.d.ts.map +1 -0
- package/dist/esm/data-sync/NullDataSynchronizer.js +15 -0
- package/dist/esm/data-sync/NullDataSynchronizer.js.map +1 -0
- package/dist/esm/data-sync/PollingDataSynchronizer.d.ts +23 -0
- package/dist/esm/data-sync/PollingDataSynchronizer.d.ts.map +1 -0
- package/dist/esm/data-sync/PollingDataSynchronizer.js +87 -0
- package/dist/esm/data-sync/PollingDataSynchronizer.js.map +1 -0
- package/dist/esm/data-sync/Requestor.d.ts +20 -0
- package/dist/esm/data-sync/Requestor.d.ts.map +1 -0
- package/dist/esm/data-sync/Requestor.js +56 -0
- package/dist/esm/data-sync/Requestor.js.map +1 -0
- package/dist/esm/data-sync/WebSocketDataSynchronizer.d.ts +20 -0
- package/dist/esm/data-sync/WebSocketDataSynchronizer.d.ts.map +1 -0
- package/dist/esm/data-sync/WebSocketDataSynchronizer.js +55 -0
- package/dist/esm/data-sync/WebSocketDataSynchronizer.js.map +1 -0
- package/dist/esm/data-sync/index.d.ts +10 -0
- package/dist/esm/data-sync/index.d.ts.map +1 -0
- package/dist/esm/data-sync/index.js +26 -0
- package/dist/esm/data-sync/index.js.map +1 -0
- package/dist/esm/data-sync/types.d.ts +17 -0
- package/dist/esm/data-sync/types.d.ts.map +1 -0
- package/dist/esm/data-sync/types.js +9 -0
- package/dist/esm/data-sync/types.js.map +1 -0
- package/dist/esm/data-sync/utils.d.ts +3 -0
- package/dist/esm/data-sync/utils.d.ts.map +1 -0
- package/dist/esm/data-sync/utils.js +33 -0
- package/dist/esm/data-sync/utils.js.map +1 -0
- package/dist/esm/errors.d.ts +16 -0
- package/dist/esm/errors.d.ts.map +1 -0
- package/dist/esm/errors.js +41 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/evaluation/EvalResult.d.ts +20 -0
- package/dist/esm/evaluation/EvalResult.d.ts.map +1 -0
- package/dist/esm/evaluation/EvalResult.js +33 -0
- package/dist/esm/evaluation/EvalResult.js.map +1 -0
- package/dist/esm/evaluation/Evaluator.d.ts +15 -0
- package/dist/esm/evaluation/Evaluator.d.ts.map +1 -0
- package/dist/esm/evaluation/Evaluator.js +28 -0
- package/dist/esm/evaluation/Evaluator.js.map +1 -0
- package/dist/esm/evaluation/IEvalDetail.d.ts +21 -0
- package/dist/esm/evaluation/IEvalDetail.d.ts.map +1 -0
- package/dist/esm/evaluation/IEvalDetail.js +3 -0
- package/dist/esm/evaluation/IEvalDetail.js.map +1 -0
- package/dist/esm/evaluation/ReasonKinds.d.ts +11 -0
- package/dist/esm/evaluation/ReasonKinds.d.ts.map +1 -0
- package/dist/esm/evaluation/ReasonKinds.js +15 -0
- package/dist/esm/evaluation/ReasonKinds.js.map +1 -0
- package/dist/esm/evaluation/data/IFlag.d.ts +26 -0
- package/dist/esm/evaluation/data/IFlag.d.ts.map +1 -0
- package/dist/esm/evaluation/data/IFlag.js +12 -0
- package/dist/esm/evaluation/data/IFlag.js.map +1 -0
- package/dist/esm/evaluation/data/index.d.ts +2 -0
- package/dist/esm/evaluation/data/index.d.ts.map +1 -0
- package/dist/esm/evaluation/data/index.js +18 -0
- package/dist/esm/evaluation/data/index.js.map +1 -0
- package/dist/esm/evaluation/index.d.ts +6 -0
- package/dist/esm/evaluation/index.d.ts.map +1 -0
- package/dist/esm/evaluation/index.js +22 -0
- package/dist/esm/evaluation/index.js.map +1 -0
- package/dist/esm/events/DefaultEventProcessor.d.ts +16 -0
- package/dist/esm/events/DefaultEventProcessor.d.ts.map +1 -0
- package/dist/esm/events/DefaultEventProcessor.js +79 -0
- package/dist/esm/events/DefaultEventProcessor.js.map +1 -0
- package/dist/esm/events/DefaultEventQueue.d.ts +18 -0
- package/dist/esm/events/DefaultEventQueue.d.ts.map +1 -0
- package/dist/esm/events/DefaultEventQueue.js +42 -0
- package/dist/esm/events/DefaultEventQueue.js.map +1 -0
- package/dist/esm/events/DefaultEventSender.d.ts +10 -0
- package/dist/esm/events/DefaultEventSender.d.ts.map +1 -0
- package/dist/esm/events/DefaultEventSender.js +67 -0
- package/dist/esm/events/DefaultEventSender.js.map +1 -0
- package/dist/esm/events/DefaultEventSerializer.d.ts +6 -0
- package/dist/esm/events/DefaultEventSerializer.d.ts.map +1 -0
- package/dist/esm/events/DefaultEventSerializer.js +14 -0
- package/dist/esm/events/DefaultEventSerializer.js.map +1 -0
- package/dist/esm/events/EventDispatcher.d.ts +17 -0
- package/dist/esm/events/EventDispatcher.d.ts.map +1 -0
- package/dist/esm/events/EventDispatcher.js +127 -0
- package/dist/esm/events/EventDispatcher.js.map +1 -0
- package/dist/esm/events/EventSerializer.d.ts +5 -0
- package/dist/esm/events/EventSerializer.d.ts.map +1 -0
- package/dist/esm/events/EventSerializer.js +3 -0
- package/dist/esm/events/EventSerializer.js.map +1 -0
- package/dist/esm/events/IEventProcessor.d.ts +7 -0
- package/dist/esm/events/IEventProcessor.d.ts.map +1 -0
- package/dist/esm/events/IEventProcessor.js +3 -0
- package/dist/esm/events/IEventProcessor.js.map +1 -0
- package/dist/esm/events/IEventQueue.d.ts +11 -0
- package/dist/esm/events/IEventQueue.d.ts.map +1 -0
- package/dist/esm/events/IEventQueue.js +3 -0
- package/dist/esm/events/IEventQueue.js.map +1 -0
- package/dist/esm/events/IEventSender.d.ts +13 -0
- package/dist/esm/events/IEventSender.d.ts.map +1 -0
- package/dist/esm/events/IEventSender.js +10 -0
- package/dist/esm/events/IEventSender.js.map +1 -0
- package/dist/esm/events/NullEventProcessor.d.ts +8 -0
- package/dist/esm/events/NullEventProcessor.d.ts.map +1 -0
- package/dist/esm/events/NullEventProcessor.js +16 -0
- package/dist/esm/events/NullEventProcessor.js.map +1 -0
- package/dist/esm/events/event.d.ts +44 -0
- package/dist/esm/events/event.d.ts.map +1 -0
- package/dist/esm/events/event.js +115 -0
- package/dist/esm/events/event.js.map +1 -0
- package/dist/esm/events/index.d.ts +12 -0
- package/dist/esm/events/index.d.ts.map +1 -0
- package/dist/esm/events/index.js +28 -0
- package/dist/esm/events/index.js.map +1 -0
- package/dist/esm/index.d.ts +21 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +37 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/integrations/TestLogger.d.ts +10 -0
- package/dist/esm/integrations/TestLogger.d.ts.map +1 -0
- package/dist/esm/integrations/TestLogger.js +25 -0
- package/dist/esm/integrations/TestLogger.js.map +1 -0
- package/dist/esm/integrations/index.d.ts +3 -0
- package/dist/esm/integrations/index.d.ts.map +1 -0
- package/dist/esm/integrations/index.js +21 -0
- package/dist/esm/integrations/index.js.map +1 -0
- package/dist/esm/integrations/test_data/FlagBuilder.d.ts +19 -0
- package/dist/esm/integrations/test_data/FlagBuilder.d.ts.map +1 -0
- package/dist/esm/integrations/test_data/FlagBuilder.js +56 -0
- package/dist/esm/integrations/test_data/FlagBuilder.js.map +1 -0
- package/dist/esm/integrations/test_data/TestData.d.ts +18 -0
- package/dist/esm/integrations/test_data/TestData.d.ts.map +1 -0
- package/dist/esm/integrations/test_data/TestData.js +38 -0
- package/dist/esm/integrations/test_data/TestData.js.map +1 -0
- package/dist/esm/integrations/test_data/TestDataSynchronizer.d.ts +21 -0
- package/dist/esm/integrations/test_data/TestDataSynchronizer.d.ts.map +1 -0
- package/dist/esm/integrations/test_data/TestDataSynchronizer.js +50 -0
- package/dist/esm/integrations/test_data/TestDataSynchronizer.js.map +1 -0
- package/dist/esm/integrations/test_data/index.d.ts +5 -0
- package/dist/esm/integrations/test_data/index.d.ts.map +1 -0
- package/dist/esm/integrations/test_data/index.js +13 -0
- package/dist/esm/integrations/test_data/index.js.map +1 -0
- package/dist/esm/logging/BasicLogger.d.ts +34 -0
- package/dist/esm/logging/BasicLogger.d.ts.map +1 -0
- package/dist/esm/logging/BasicLogger.js +101 -0
- package/dist/esm/logging/BasicLogger.js.map +1 -0
- package/dist/esm/logging/IBasicLoggerOptions.d.ts +43 -0
- package/dist/esm/logging/IBasicLoggerOptions.d.ts.map +1 -0
- package/dist/esm/logging/IBasicLoggerOptions.js +3 -0
- package/dist/esm/logging/IBasicLoggerOptions.js.map +1 -0
- package/dist/esm/logging/ILogger.d.ts +47 -0
- package/dist/esm/logging/ILogger.d.ts.map +1 -0
- package/dist/esm/logging/ILogger.js +3 -0
- package/dist/esm/logging/ILogger.js.map +1 -0
- package/dist/esm/logging/LogLevel.d.ts +10 -0
- package/dist/esm/logging/LogLevel.d.ts.map +1 -0
- package/dist/esm/logging/LogLevel.js +3 -0
- package/dist/esm/logging/LogLevel.js.map +1 -0
- package/dist/esm/logging/SafeLogger.d.ts +28 -0
- package/dist/esm/logging/SafeLogger.d.ts.map +1 -0
- package/dist/esm/logging/SafeLogger.js +64 -0
- package/dist/esm/logging/SafeLogger.js.map +1 -0
- package/dist/esm/logging/format.d.ts +12 -0
- package/dist/esm/logging/format.d.ts.map +1 -0
- package/dist/esm/logging/format.js +156 -0
- package/dist/esm/logging/format.js.map +1 -0
- package/dist/esm/logging/index.d.ts +7 -0
- package/dist/esm/logging/index.d.ts.map +1 -0
- package/dist/esm/logging/index.js +23 -0
- package/dist/esm/logging/index.js.map +1 -0
- package/dist/esm/options/ClientContext.d.ts +28 -0
- package/dist/esm/options/ClientContext.d.ts.map +1 -0
- package/dist/esm/options/ClientContext.js +21 -0
- package/dist/esm/options/ClientContext.js.map +1 -0
- package/dist/esm/options/IClientContext.d.ts +45 -0
- package/dist/esm/options/IClientContext.d.ts.map +1 -0
- package/dist/esm/options/IClientContext.js +3 -0
- package/dist/esm/options/IClientContext.js.map +1 -0
- package/dist/esm/options/IOptions.d.ts +101 -0
- package/dist/esm/options/IOptions.d.ts.map +1 -0
- package/dist/esm/options/IOptions.js +3 -0
- package/dist/esm/options/IOptions.js.map +1 -0
- package/dist/esm/options/IUser.d.ts +7 -0
- package/dist/esm/options/IUser.d.ts.map +1 -0
- package/dist/esm/options/IUser.js +3 -0
- package/dist/esm/options/IUser.js.map +1 -0
- package/dist/esm/options/IValidatedOptions.d.ts +27 -0
- package/dist/esm/options/IValidatedOptions.d.ts.map +1 -0
- package/dist/esm/options/IValidatedOptions.js +3 -0
- package/dist/esm/options/IValidatedOptions.js.map +1 -0
- package/dist/esm/options/OptionMessages.d.ts +14 -0
- package/dist/esm/options/OptionMessages.d.ts.map +1 -0
- package/dist/esm/options/OptionMessages.js +33 -0
- package/dist/esm/options/OptionMessages.js.map +1 -0
- package/dist/esm/options/UserBuilder.d.ts +17 -0
- package/dist/esm/options/UserBuilder.d.ts.map +1 -0
- package/dist/esm/options/UserBuilder.js +35 -0
- package/dist/esm/options/UserBuilder.js.map +1 -0
- package/dist/esm/options/Validators.d.ts +111 -0
- package/dist/esm/options/Validators.d.ts.map +1 -0
- package/dist/esm/options/Validators.js +247 -0
- package/dist/esm/options/Validators.js.map +1 -0
- package/dist/esm/options/index.d.ts +9 -0
- package/dist/esm/options/index.d.ts.map +1 -0
- package/dist/esm/options/index.js +25 -0
- package/dist/esm/options/index.js.map +1 -0
- package/dist/esm/platform/IInfo.d.ts +92 -0
- package/dist/esm/platform/IInfo.d.ts.map +1 -0
- package/dist/esm/platform/IInfo.js +3 -0
- package/dist/esm/platform/IInfo.js.map +1 -0
- package/dist/esm/platform/IPlatform.d.ts +19 -0
- package/dist/esm/platform/IPlatform.d.ts.map +1 -0
- package/dist/esm/platform/IPlatform.js +3 -0
- package/dist/esm/platform/IPlatform.js.map +1 -0
- package/dist/esm/platform/IStore.d.ts +104 -0
- package/dist/esm/platform/IStore.d.ts.map +1 -0
- package/dist/esm/platform/IStore.js +3 -0
- package/dist/esm/platform/IStore.js.map +1 -0
- package/dist/esm/platform/IWebSocket.d.ts +21 -0
- package/dist/esm/platform/IWebSocket.d.ts.map +1 -0
- package/dist/esm/platform/IWebSocket.js +3 -0
- package/dist/esm/platform/IWebSocket.js.map +1 -0
- package/dist/esm/platform/browser/BrowserInfo.d.ts +7 -0
- package/dist/esm/platform/browser/BrowserInfo.d.ts.map +1 -0
- package/dist/esm/platform/browser/BrowserInfo.js +24 -0
- package/dist/esm/platform/browser/BrowserInfo.js.map +1 -0
- package/dist/esm/platform/browser/BrowserPlatform.d.ts +12 -0
- package/dist/esm/platform/browser/BrowserPlatform.d.ts.map +1 -0
- package/dist/esm/platform/browser/BrowserPlatform.js +17 -0
- package/dist/esm/platform/browser/BrowserPlatform.js.map +1 -0
- package/dist/esm/platform/browser/BrowserRequests.d.ts +5 -0
- package/dist/esm/platform/browser/BrowserRequests.d.ts.map +1 -0
- package/dist/esm/platform/browser/BrowserRequests.js +10 -0
- package/dist/esm/platform/browser/BrowserRequests.js.map +1 -0
- package/dist/esm/platform/browser/BrowserWebSocket.d.ts +38 -0
- package/dist/esm/platform/browser/BrowserWebSocket.d.ts.map +1 -0
- package/dist/esm/platform/browser/BrowserWebSocket.js +129 -0
- package/dist/esm/platform/browser/BrowserWebSocket.js.map +1 -0
- package/dist/esm/platform/browser/FbClient.d.ts +30 -0
- package/dist/esm/platform/browser/FbClient.d.ts.map +1 -0
- package/dist/esm/platform/browser/FbClient.js +52 -0
- package/dist/esm/platform/browser/FbClient.js.map +1 -0
- package/dist/esm/platform/browser/LocalStorageStore.d.ts +12 -0
- package/dist/esm/platform/browser/LocalStorageStore.d.ts.map +1 -0
- package/dist/esm/platform/browser/LocalStorageStore.js +65 -0
- package/dist/esm/platform/browser/LocalStorageStore.js.map +1 -0
- package/dist/esm/platform/index.d.ts +9 -0
- package/dist/esm/platform/index.d.ts.map +1 -0
- package/dist/esm/platform/index.js +29 -0
- package/dist/esm/platform/index.js.map +1 -0
- package/dist/esm/platform/requests.d.ts +64 -0
- package/dist/esm/platform/requests.d.ts.map +1 -0
- package/dist/esm/platform/requests.js +7 -0
- package/dist/esm/platform/requests.js.map +1 -0
- package/dist/esm/store/BaseStore.d.ts +25 -0
- package/dist/esm/store/BaseStore.d.ts.map +1 -0
- package/dist/esm/store/BaseStore.js +125 -0
- package/dist/esm/store/BaseStore.js.map +1 -0
- package/dist/esm/store/DataKinds.d.ts +5 -0
- package/dist/esm/store/DataKinds.d.ts.map +1 -0
- package/dist/esm/store/DataKinds.js +9 -0
- package/dist/esm/store/DataKinds.js.map +1 -0
- package/dist/esm/store/IDataSourceUpdates.d.ts +48 -0
- package/dist/esm/store/IDataSourceUpdates.d.ts.map +1 -0
- package/dist/esm/store/IDataSourceUpdates.js +3 -0
- package/dist/esm/store/IDataSourceUpdates.js.map +1 -0
- package/dist/esm/store/InMemoryStore.d.ts +11 -0
- package/dist/esm/store/InMemoryStore.d.ts.map +1 -0
- package/dist/esm/store/InMemoryStore.js +46 -0
- package/dist/esm/store/InMemoryStore.js.map +1 -0
- package/dist/esm/store/index.d.ts +7 -0
- package/dist/esm/store/index.d.ts.map +1 -0
- package/dist/esm/store/index.js +23 -0
- package/dist/esm/store/index.js.map +1 -0
- package/dist/esm/store/serialization.d.ts +23 -0
- package/dist/esm/store/serialization.d.ts.map +1 -0
- package/dist/esm/store/serialization.js +37 -0
- package/dist/esm/store/serialization.js.map +1 -0
- package/dist/esm/store/store.d.ts +30 -0
- package/dist/esm/store/store.d.ts.map +1 -0
- package/dist/esm/store/store.js +6 -0
- package/dist/esm/store/store.js.map +1 -0
- package/dist/esm/utils/Emits.d.ts +30 -0
- package/dist/esm/utils/Emits.d.ts.map +1 -0
- package/dist/esm/utils/Emits.js +64 -0
- package/dist/esm/utils/Emits.js.map +1 -0
- package/dist/esm/utils/EventEmitter.d.ts +22 -0
- package/dist/esm/utils/EventEmitter.d.ts.map +1 -0
- package/dist/esm/utils/EventEmitter.js +108 -0
- package/dist/esm/utils/EventEmitter.js.map +1 -0
- package/dist/esm/utils/IEventEmitter.d.ts +16 -0
- package/dist/esm/utils/IEventEmitter.d.ts.map +1 -0
- package/dist/esm/utils/IEventEmitter.js +3 -0
- package/dist/esm/utils/IEventEmitter.js.map +1 -0
- package/dist/esm/utils/Regex.d.ts +7 -0
- package/dist/esm/utils/Regex.d.ts.map +1 -0
- package/dist/esm/utils/Regex.js +22 -0
- package/dist/esm/utils/Regex.js.map +1 -0
- package/dist/esm/utils/ValueConverters.d.ts +13 -0
- package/dist/esm/utils/ValueConverters.d.ts.map +1 -0
- package/dist/esm/utils/ValueConverters.js +46 -0
- package/dist/esm/utils/ValueConverters.js.map +1 -0
- package/dist/esm/utils/VoidFunction.d.ts +2 -0
- package/dist/esm/utils/VoidFunction.d.ts.map +1 -0
- package/dist/esm/utils/VoidFunction.js +3 -0
- package/dist/esm/utils/VoidFunction.js.map +1 -0
- package/dist/esm/utils/canonicalizeUri.d.ts +2 -0
- package/dist/esm/utils/canonicalizeUri.d.ts.map +1 -0
- package/dist/esm/utils/canonicalizeUri.js +9 -0
- package/dist/esm/utils/canonicalizeUri.js.map +1 -0
- package/dist/esm/utils/debounce.d.ts +22 -0
- package/dist/esm/utils/debounce.d.ts.map +1 -0
- package/dist/esm/utils/debounce.js +34 -0
- package/dist/esm/utils/debounce.js.map +1 -0
- package/dist/esm/utils/http.d.ts +12 -0
- package/dist/esm/utils/http.d.ts.map +1 -0
- package/dist/esm/utils/http.js +26 -0
- package/dist/esm/utils/http.js.map +1 -0
- package/dist/esm/utils/index.d.ts +7 -0
- package/dist/esm/utils/index.d.ts.map +1 -0
- package/dist/esm/utils/index.js +23 -0
- package/dist/esm/utils/index.js.map +1 -0
- package/dist/esm/utils/isNullOrUndefined.d.ts +2 -0
- package/dist/esm/utils/isNullOrUndefined.d.ts.map +1 -0
- package/dist/esm/utils/isNullOrUndefined.js +8 -0
- package/dist/esm/utils/isNullOrUndefined.js.map +1 -0
- package/dist/esm/utils/serializeUser.d.ts +3 -0
- package/dist/esm/utils/serializeUser.d.ts.map +1 -0
- package/dist/esm/utils/serializeUser.js +24 -0
- package/dist/esm/utils/serializeUser.js.map +1 -0
- package/dist/esm/utils/sleep.d.ts +3 -0
- package/dist/esm/utils/sleep.d.ts.map +1 -0
- package/dist/esm/utils/sleep.js +18 -0
- package/dist/esm/utils/sleep.js.map +1 -0
- package/dist/esm/version.d.ts +3 -0
- package/dist/esm/version.d.ts.map +1 -0
- package/dist/esm/version.js +6 -0
- package/dist/esm/version.js.map +1 -0
- package/dist/umd/featbit-js-client-sdk-3.0.1.js +2 -0
- package/dist/umd/featbit-js-client-sdk-3.0.1.js.map +1 -0
- package/dist/umd/featbit-js-client-sdk.js +2 -0
- package/dist/umd/featbit-js-client-sdk.js.map +1 -0
- package/package.json +22 -24
- package/src/Configuration.ts +233 -0
- package/src/Context.ts +62 -0
- package/src/FbClientBuilder.ts +161 -0
- package/src/FbClientCore.ts +389 -0
- package/src/IContextProperty.ts +4 -0
- package/src/IDataKind.ts +11 -0
- package/src/IFbClient.ts +30 -0
- package/src/IFbClientCore.ts +291 -0
- package/src/IVersionedData.ts +18 -0
- package/src/bootstrap/IBootstrapProvider.ts +5 -0
- package/src/bootstrap/JsonBootstrapProvider.ts +35 -0
- package/src/bootstrap/NullBootstrapProvider.ts +21 -0
- package/src/bootstrap/index.ts +3 -0
- package/src/constants.ts +2 -6
- package/src/data-sources/DataSourceUpdates.ts +89 -0
- package/src/data-sources/createStreamListeners.ts +66 -0
- package/src/data-sources/index.ts +2 -0
- package/src/data-sync/DataSyncMode.ts +4 -0
- package/src/data-sync/IDataSynchronizer.ts +15 -0
- package/src/data-sync/IRequestor.ts +10 -0
- package/src/data-sync/NullDataSynchronizer.ts +15 -0
- package/src/data-sync/PollingDataSynchronizer.ts +111 -0
- package/src/data-sync/Requestor.ts +61 -0
- package/src/data-sync/WebSocketDataSynchronizer.ts +74 -0
- package/src/data-sync/index.ts +9 -0
- package/src/data-sync/types.ts +20 -0
- package/src/data-sync/utils.ts +32 -0
- package/src/errors.ts +41 -0
- package/src/evaluation/EvalResult.ts +36 -0
- package/src/evaluation/Evaluator.ts +27 -0
- package/src/evaluation/IEvalDetail.ts +24 -0
- package/src/evaluation/ReasonKinds.ts +10 -0
- package/src/evaluation/data/IFlag.ts +29 -0
- package/src/evaluation/data/index.ts +1 -0
- package/src/evaluation/index.ts +5 -0
- package/src/events/DefaultEventProcessor.ts +84 -0
- package/src/events/DefaultEventQueue.ts +50 -0
- package/src/events/DefaultEventSender.ts +75 -0
- package/src/events/DefaultEventSerializer.ts +12 -0
- package/src/events/EventDispatcher.ts +128 -0
- package/src/events/EventSerializer.ts +5 -0
- package/src/events/IEventProcessor.ts +9 -0
- package/src/events/IEventQueue.ts +17 -0
- package/src/events/IEventSender.ts +14 -0
- package/src/events/NullEventProcessor.ts +16 -0
- package/src/events/event.ts +130 -0
- package/src/events/index.ts +11 -0
- package/src/index.ts +20 -4
- package/src/integrations/TestLogger.ts +25 -0
- package/src/integrations/index.ts +2 -0
- package/src/integrations/test_data/FlagBuilder.ts +60 -0
- package/src/integrations/test_data/TestData.ts +58 -0
- package/src/integrations/test_data/TestDataSynchronizer.ts +50 -0
- package/src/integrations/test_data/index.ts +5 -0
- package/src/logging/BasicLogger.ts +108 -0
- package/src/logging/IBasicLoggerOptions.ts +46 -0
- package/src/logging/ILogger.ts +49 -0
- package/src/logging/LogLevel.ts +9 -0
- package/src/logging/SafeLogger.ts +70 -0
- package/src/logging/format.ts +154 -0
- package/src/logging/index.ts +6 -0
- package/src/options/ClientContext.ts +40 -0
- package/src/options/IClientContext.ts +54 -0
- package/src/options/IOptions.ts +124 -0
- package/src/options/IUser.ts +7 -0
- package/src/options/IValidatedOptions.ts +30 -0
- package/src/options/OptionMessages.ts +36 -0
- package/src/options/UserBuilder.ts +36 -0
- package/src/options/Validators.ts +301 -0
- package/src/options/index.ts +8 -0
- package/src/platform/IInfo.ts +103 -0
- package/src/platform/IPlatform.ts +21 -0
- package/src/platform/IStore.ts +113 -0
- package/src/platform/IWebSocket.ts +23 -0
- package/src/platform/browser/BrowserInfo.ts +25 -0
- package/src/platform/browser/BrowserPlatform.ts +20 -0
- package/src/platform/browser/BrowserRequests.ts +7 -0
- package/src/platform/browser/BrowserWebSocket.ts +143 -0
- package/src/platform/browser/FbClient.ts +65 -0
- package/src/platform/browser/LocalStorageStore.ts +60 -0
- package/src/platform/index.ts +12 -0
- package/src/platform/requests.ts +77 -0
- package/src/store/BaseStore.ts +123 -0
- package/src/store/DataKinds.ts +7 -0
- package/src/store/IDataSourceUpdates.ts +49 -0
- package/src/store/InMemoryStore.ts +37 -0
- package/src/store/index.ts +6 -0
- package/src/store/serialization.ts +52 -0
- package/src/store/store.ts +38 -0
- package/src/utils/Emits.ts +76 -0
- package/src/utils/EventEmitter.ts +129 -0
- package/src/utils/IEventEmitter.ts +15 -0
- package/src/utils/Regex.ts +22 -0
- package/src/utils/ValueConverters.ts +56 -0
- package/src/utils/VoidFunction.ts +1 -0
- package/src/utils/canonicalizeUri.ts +4 -0
- package/src/utils/debounce.ts +33 -0
- package/src/utils/http.ts +40 -0
- package/src/utils/index.ts +6 -0
- package/src/utils/isNullOrUndefined.ts +3 -0
- package/src/utils/serializeUser.ts +28 -0
- package/src/utils/sleep.ts +6 -0
- package/src/version.ts +1 -0
- package/esm/constants.d.ts +0 -6
- package/esm/constants.js +0 -7
- package/esm/constants.js.map +0 -1
- package/esm/events.d.ts +0 -14
- package/esm/events.js +0 -27
- package/esm/events.js.map +0 -1
- package/esm/featbit.d.ts +0 -34
- package/esm/featbit.js +0 -382
- package/esm/featbit.js.map +0 -1
- package/esm/index.d.ts +0 -4
- package/esm/index.js +0 -5
- package/esm/index.js.map +0 -1
- package/esm/logger.d.ts +0 -4
- package/esm/logger.js +0 -20
- package/esm/logger.js.map +0 -1
- package/esm/network.service.d.ts +0 -27
- package/esm/network.service.js +0 -288
- package/esm/network.service.js.map +0 -1
- package/esm/optionMessages.d.ts +0 -5
- package/esm/optionMessages.js +0 -16
- package/esm/optionMessages.js.map +0 -1
- package/esm/queue.d.ts +0 -8
- package/esm/queue.js +0 -35
- package/esm/queue.js.map +0 -1
- package/esm/store.d.ts +0 -20
- package/esm/store.js +0 -143
- package/esm/store.js.map +0 -1
- package/esm/throttleutil.d.ts +0 -9
- package/esm/throttleutil.js +0 -133
- package/esm/throttleutil.js.map +0 -1
- package/esm/types.d.ts +0 -94
- package/esm/types.js +0 -24
- package/esm/types.js.map +0 -1
- package/esm/umd.d.ts +0 -2
- package/esm/utils.d.ts +0 -11
- package/esm/utils.js +0 -142
- package/esm/utils.js.map +0 -1
- package/src/events.ts +0 -29
- package/src/featbit.ts +0 -343
- package/src/logger.ts +0 -13
- package/src/network.service.ts +0 -223
- package/src/optionMessages.ts +0 -13
- package/src/queue.ts +0 -23
- package/src/store.ts +0 -169
- package/src/throttleutil.ts +0 -72
- package/src/types.ts +0 -113
- package/src/umd.ts +0 -15
- package/src/utils.ts +0 -173
- package/umd/featbit-js-client-sdk-2.0.2.js +0 -2
- package/umd/featbit-js-client-sdk-2.0.2.js.map +0 -1
- package/umd/featbit-js-client-sdk.js +0 -2
- package/umd/featbit-js-client-sdk.js.map +0 -1
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { IPlatform } from "../IPlatform";
|
|
2
|
+
import { IInfo } from "../IInfo";
|
|
3
|
+
import { IRequests } from "../requests";
|
|
4
|
+
import { IOptions } from "../../options/IOptions";
|
|
5
|
+
import BrowserInfo from "./BrowserInfo";
|
|
6
|
+
import { BrowserRequests } from "./BrowserRequests";
|
|
7
|
+
import { IWebSocketWithEvents } from "../IWebSocket";
|
|
8
|
+
import BrowserWebSocket from "./BrowserWebSocket";
|
|
9
|
+
|
|
10
|
+
export default class BrowserPlatform implements IPlatform {
|
|
11
|
+
info: IInfo = new BrowserInfo();
|
|
12
|
+
|
|
13
|
+
requests: IRequests;
|
|
14
|
+
webSocket: IWebSocketWithEvents;
|
|
15
|
+
|
|
16
|
+
constructor(options: IOptions) {
|
|
17
|
+
this.requests = new BrowserRequests();
|
|
18
|
+
this.webSocket = new BrowserWebSocket();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { IWebSocket, IWebSocketConfig } from "../IWebSocket";
|
|
2
|
+
import { Emits } from "../../utils/Emits";
|
|
3
|
+
import { IEventEmitter } from "../../utils/IEventEmitter";
|
|
4
|
+
import { EventEmitter } from "../../utils/EventEmitter";
|
|
5
|
+
import { generateConnectionToken } from "../../data-sync/utils";
|
|
6
|
+
import { StreamResponseEventType } from "../../data-sync/types";
|
|
7
|
+
import { IUser } from "../../options/IUser";
|
|
8
|
+
|
|
9
|
+
const socketConnectionIntervals = [1000, 3000, 5000, 7000, 11000, 13000, 30000, 60000];
|
|
10
|
+
|
|
11
|
+
class BrowserWebSocket implements IWebSocket {
|
|
12
|
+
emitter: IEventEmitter;
|
|
13
|
+
private ws?: WebSocket;
|
|
14
|
+
private retryCounter = 0;
|
|
15
|
+
private closed: boolean = false;
|
|
16
|
+
|
|
17
|
+
private _config: IWebSocketConfig = {} as IWebSocketConfig;
|
|
18
|
+
|
|
19
|
+
constructor() {
|
|
20
|
+
this.emitter = new EventEmitter();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
identify(user: IUser) {
|
|
24
|
+
this._config.user = user;
|
|
25
|
+
this.doDataSync();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
connect() {
|
|
29
|
+
let that = this;
|
|
30
|
+
const startTime = Date.now();
|
|
31
|
+
const url = this._config.streamingUri.replace(/^http/, 'ws') + `?type=client&token=${ generateConnectionToken(this._config.sdkKey) }`;
|
|
32
|
+
this.ws = new WebSocket(url);
|
|
33
|
+
|
|
34
|
+
// Connection opened
|
|
35
|
+
that.ws?.addEventListener('open', function (this: WebSocket, event) {
|
|
36
|
+
// this is the websocket instance to which the current listener is binded to, it's different from that.socket
|
|
37
|
+
that._config.logger.info(`WebSocket connection succeeded, connection time: ${ Date.now() - startTime } ms`);
|
|
38
|
+
that.doDataSync();
|
|
39
|
+
that.sendPingMessage();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Connection closed
|
|
43
|
+
that.ws?.addEventListener('close', function (event) {
|
|
44
|
+
that._config.logger.warn('WebSocket closed');
|
|
45
|
+
if (event.code === 4003) { // do not reconnect when 4003
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
that.reconnect();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// Connection error
|
|
53
|
+
that.ws?.addEventListener('error', function (event) {
|
|
54
|
+
// reconnect
|
|
55
|
+
that._config.logger.debug('error');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// Listen for messages
|
|
59
|
+
that.ws?.addEventListener('message', function (event) {
|
|
60
|
+
const message = JSON.parse(event.data as string);
|
|
61
|
+
if (message.messageType === 'data-sync') {
|
|
62
|
+
switch (message.data.eventType) {
|
|
63
|
+
case StreamResponseEventType.patch:
|
|
64
|
+
that.emitter.emit('patch', message);
|
|
65
|
+
break;
|
|
66
|
+
case StreamResponseEventType.full:
|
|
67
|
+
that.emitter.emit('put', message);
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
close() {
|
|
75
|
+
this.closed = true;
|
|
76
|
+
this.ws?.close(4003, 'The client is closed by user');
|
|
77
|
+
this.ws = undefined;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
config(param: IWebSocketConfig) {
|
|
81
|
+
if (param.emitter) {
|
|
82
|
+
this.emitter = param.emitter;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
this._config = {...param};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private sendPingMessage() {
|
|
89
|
+
const payload = {
|
|
90
|
+
messageType: 'ping',
|
|
91
|
+
data: null
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
setTimeout(() => {
|
|
95
|
+
try {
|
|
96
|
+
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
97
|
+
this._config.logger.debug('sending ping')
|
|
98
|
+
this.ws.send(JSON.stringify(payload));
|
|
99
|
+
this.sendPingMessage();
|
|
100
|
+
} else {
|
|
101
|
+
this._config.logger.debug(`socket closed at ${ new Date() }`);
|
|
102
|
+
}
|
|
103
|
+
} catch (err) {
|
|
104
|
+
this._config.logger.debug(err);
|
|
105
|
+
}
|
|
106
|
+
}, this._config.pingInterval);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private doDataSync() {
|
|
110
|
+
const payload = {
|
|
111
|
+
messageType: 'data-sync',
|
|
112
|
+
data: {
|
|
113
|
+
timestamp: this._config.getStoreTimestamp(),
|
|
114
|
+
user: this._config.user
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
try {
|
|
119
|
+
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
120
|
+
this._config.logger.debug('requesting data');
|
|
121
|
+
this.ws?.send(JSON.stringify(payload));
|
|
122
|
+
} else {
|
|
123
|
+
this._config.logger.error(`not requesting data because socket not open`);
|
|
124
|
+
}
|
|
125
|
+
} catch (err) {
|
|
126
|
+
this._config.logger.debug(err);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
private reconnect() {
|
|
131
|
+
if (!this.closed) {
|
|
132
|
+
this.ws = undefined;
|
|
133
|
+
const waitTime = socketConnectionIntervals[Math.min(this.retryCounter++, socketConnectionIntervals.length - 1)];
|
|
134
|
+
this._config.logger.info(`The client will try to reconnect in ${ waitTime } milliseconds.`);
|
|
135
|
+
setTimeout(() => {
|
|
136
|
+
this._config.logger.info(`The client is trying to reconnect, flag evaluation results may be stale until reconnected, waited for: ${ waitTime } milliseconds`);
|
|
137
|
+
this.connect();
|
|
138
|
+
}, waitTime);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export default Emits(BrowserWebSocket);
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { FbClientCore } from "../../FbClientCore";
|
|
2
|
+
import { IOptions } from "../../options/IOptions";
|
|
3
|
+
import { BasicLogger } from "../../logging/BasicLogger";
|
|
4
|
+
import { EventEmitter } from "../../utils/EventEmitter";
|
|
5
|
+
import { SafeLogger } from "../../logging/SafeLogger";
|
|
6
|
+
import { Emits } from "../../utils/Emits";
|
|
7
|
+
import { IEventEmitter } from "../../utils/IEventEmitter";
|
|
8
|
+
import BrowserPlatform from "./BrowserPlatform";
|
|
9
|
+
import LocalStorageStore from "./LocalStorageStore";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @ignore
|
|
13
|
+
*/
|
|
14
|
+
class FbClient extends FbClientCore {
|
|
15
|
+
emitter: IEventEmitter;
|
|
16
|
+
|
|
17
|
+
constructor(options: IOptions) {
|
|
18
|
+
const fallbackLogger = new BasicLogger({
|
|
19
|
+
level: 'none',
|
|
20
|
+
destination: console.log
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const logger = options.logger ? new SafeLogger(options.logger, fallbackLogger) : fallbackLogger;
|
|
24
|
+
|
|
25
|
+
const emitter = new EventEmitter(logger);
|
|
26
|
+
|
|
27
|
+
let { store } = options;
|
|
28
|
+
if (!store) {
|
|
29
|
+
store = new LocalStorageStore(options);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
super(
|
|
33
|
+
{...options, logger, store },
|
|
34
|
+
new BrowserPlatform({...options, logger}),
|
|
35
|
+
{
|
|
36
|
+
onError: (err: Error) => {
|
|
37
|
+
if (emitter.listenerCount('error')) {
|
|
38
|
+
emitter.emit('error', err);
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
onFailed: (err: Error) => {
|
|
42
|
+
emitter.emit('failed', err);
|
|
43
|
+
},
|
|
44
|
+
onReady: () => {
|
|
45
|
+
emitter.emit('ready');
|
|
46
|
+
},
|
|
47
|
+
onUpdate: (keys: string[]) => {
|
|
48
|
+
emitter.emit('update', [keys]);
|
|
49
|
+
keys.forEach((key) => emitter.emit(`update:${ key }`, key));
|
|
50
|
+
},
|
|
51
|
+
hasEventListeners: () =>
|
|
52
|
+
emitter
|
|
53
|
+
.eventNames()
|
|
54
|
+
.some(
|
|
55
|
+
(name) =>
|
|
56
|
+
name === 'update' || (typeof name === 'string' && name.startsWith('update:')),
|
|
57
|
+
),
|
|
58
|
+
},
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
this.emitter = emitter;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export default Emits(FbClient);
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import {
|
|
2
|
+
StoreStorageKey,
|
|
3
|
+
IStoreDataStorage, CurrentUserStorageKey
|
|
4
|
+
} from "../../store/store";
|
|
5
|
+
import { IOptions } from "../../options/IOptions";
|
|
6
|
+
import { BaseStore } from "../../store/BaseStore";
|
|
7
|
+
import { ILogger } from "../../logging";
|
|
8
|
+
import { serializeUser } from "../../utils/serializeUser";
|
|
9
|
+
|
|
10
|
+
export default class LocalStorageStore extends BaseStore {
|
|
11
|
+
private logger: ILogger;
|
|
12
|
+
|
|
13
|
+
constructor(options: IOptions) {
|
|
14
|
+
super();
|
|
15
|
+
|
|
16
|
+
this.logger = options.logger!;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/* eslint-disable class-methods-use-this */
|
|
20
|
+
close(): void {
|
|
21
|
+
// For the LocalStorage store this is a no-op.
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
get description(): string {
|
|
25
|
+
return 'local-storage-store'
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// This method needs to be overridden in the child class
|
|
29
|
+
protected async saveUser(): Promise<void> {
|
|
30
|
+
localStorage.setItem(CurrentUserStorageKey, serializeUser(this._user));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
protected override async dumpStoreToStorage() {
|
|
34
|
+
const storageKey = `${StoreStorageKey}-${this._user.keyId}`;
|
|
35
|
+
localStorage.setItem(storageKey, JSON.stringify(this.store));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
protected override async loadStoreFromStorage() {
|
|
39
|
+
const storageKey = `${StoreStorageKey}-${this._user.keyId}`;
|
|
40
|
+
const dataStoreStr = localStorage.getItem(storageKey);
|
|
41
|
+
let store: IStoreDataStorage | null = null;
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
if (dataStoreStr && dataStoreStr.trim().length > 0) {
|
|
45
|
+
store = JSON.parse(dataStoreStr);
|
|
46
|
+
}
|
|
47
|
+
} catch (err) {
|
|
48
|
+
this.logger.error(`error while loading local data store: ${storageKey}`, err);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (!!store) {
|
|
52
|
+
this.store = store;
|
|
53
|
+
} else {
|
|
54
|
+
this.store = {
|
|
55
|
+
flags: {},
|
|
56
|
+
version: 0
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export * from './IInfo';
|
|
2
|
+
export * from './IStore';
|
|
3
|
+
export * from './IPlatform';
|
|
4
|
+
export * from './IWebSocket';
|
|
5
|
+
export * from './requests';
|
|
6
|
+
export * from './browser/BrowserRequests';
|
|
7
|
+
|
|
8
|
+
import BrowserWebSocket from './browser/BrowserWebSocket';
|
|
9
|
+
|
|
10
|
+
export {
|
|
11
|
+
BrowserWebSocket
|
|
12
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// These are not full specifications of the interface, but instead subsets
|
|
2
|
+
// based on the functionality needed by the SDK. Exposure of the full standard
|
|
3
|
+
// would require much more per platform implementation for platforms that do not
|
|
4
|
+
// natively support fetch.
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Interface for headers that are part of a fetch response.
|
|
8
|
+
*/
|
|
9
|
+
export interface IHeaders {
|
|
10
|
+
/**
|
|
11
|
+
* Get a header by name.
|
|
12
|
+
*
|
|
13
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Headers/get
|
|
14
|
+
*
|
|
15
|
+
* @param name The name of the header to get.
|
|
16
|
+
*/
|
|
17
|
+
get(name: string): string | null;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Returns an iterator allowing iteration of all the keys contained
|
|
21
|
+
* in this object.
|
|
22
|
+
*
|
|
23
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Headers/keys
|
|
24
|
+
*
|
|
25
|
+
*/
|
|
26
|
+
keys(): Iterable<string>;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Returns an iterator allowing iteration of all the values contained
|
|
30
|
+
* in this object.
|
|
31
|
+
*
|
|
32
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Headers/values
|
|
33
|
+
*/
|
|
34
|
+
values(): Iterable<string>;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Returns an iterator allowing iteration of all the key-value pairs in
|
|
38
|
+
* the object.
|
|
39
|
+
*
|
|
40
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Headers/entries
|
|
41
|
+
*/
|
|
42
|
+
entries(): Iterable<[string, string]>;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Returns true if the header is present.
|
|
46
|
+
* @param name The name of the header to check.
|
|
47
|
+
*/
|
|
48
|
+
has(name: string): boolean;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Interface for fetch responses.
|
|
53
|
+
*/
|
|
54
|
+
export interface IResponse {
|
|
55
|
+
status: number;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Read the response and provide it as a string.
|
|
59
|
+
*/
|
|
60
|
+
text(): Promise<string>;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Read the response and provide it as decoded json.
|
|
64
|
+
*/
|
|
65
|
+
json(): Promise<any>;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface IRequestOptions {
|
|
69
|
+
headers?: Record<string, string>;
|
|
70
|
+
method?: string;
|
|
71
|
+
body?: string;
|
|
72
|
+
timeout?: number;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface IRequests {
|
|
76
|
+
fetch(url: string, options?: IRequestOptions): Promise<IResponse>;
|
|
77
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { IStore } from "../platform";
|
|
2
|
+
import { IKeyedStoreItem, IStoreDataStorage, IStoreItem, IStoreKindData } from "./store";
|
|
3
|
+
import { IUser } from "../options";
|
|
4
|
+
import { IDataKind } from "../IDataKind";
|
|
5
|
+
|
|
6
|
+
export class BaseStore implements IStore {
|
|
7
|
+
protected store: IStoreDataStorage = {} as IStoreDataStorage;
|
|
8
|
+
|
|
9
|
+
protected initCalled = false;
|
|
10
|
+
|
|
11
|
+
protected _user: IUser = {} as IUser;
|
|
12
|
+
|
|
13
|
+
constructor() {
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async identify(user: IUser) {
|
|
17
|
+
this._user = {...user};
|
|
18
|
+
|
|
19
|
+
await this.saveUser();
|
|
20
|
+
await this.loadStoreFromStorage();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
get user(): IUser {
|
|
24
|
+
return this._user;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
protected async addItem(kind: IDataKind, key: string, item: IStoreItem) {
|
|
28
|
+
let items = this.store[kind.namespace];
|
|
29
|
+
if (!items) {
|
|
30
|
+
items = {};
|
|
31
|
+
this.store[kind.namespace] = items;
|
|
32
|
+
}
|
|
33
|
+
if (Object.hasOwnProperty.call(items, key)) {
|
|
34
|
+
const old = items[key];
|
|
35
|
+
if (!old || old.version < item.version) {
|
|
36
|
+
items[key] = item;
|
|
37
|
+
}
|
|
38
|
+
} else {
|
|
39
|
+
items[key] = item;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (item.version > this.store.version) {
|
|
43
|
+
this.store.version = item.version;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
await this.dumpStoreToStorage();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
get(kind: IDataKind, key: string): IStoreItem | null {
|
|
50
|
+
const items = this.store[kind.namespace];
|
|
51
|
+
if (items) {
|
|
52
|
+
if (Object.prototype.hasOwnProperty.call(items, key)) {
|
|
53
|
+
const item = items[key];
|
|
54
|
+
if (item) {
|
|
55
|
+
return item;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
all(kind: IDataKind): [IStoreKindData, number] {
|
|
63
|
+
const result: IStoreKindData = {};
|
|
64
|
+
const items = this.store[kind.namespace] ?? {};
|
|
65
|
+
Object.entries(items).forEach(([key, item]) => {
|
|
66
|
+
if (item) {
|
|
67
|
+
result[key] = <IStoreItem>item;
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
return [result, this.store.version];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async init(allData: IStoreDataStorage) {
|
|
75
|
+
this.store = allData as IStoreDataStorage;
|
|
76
|
+
|
|
77
|
+
Object.keys(allData).map(namespace => {
|
|
78
|
+
Object.entries(allData[namespace]).forEach(([_, item]) => {
|
|
79
|
+
const ele = item as IStoreItem;
|
|
80
|
+
if (ele.version > this.store.version) {
|
|
81
|
+
this.store.version = ele.version;
|
|
82
|
+
}
|
|
83
|
+
})
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
await this.dumpStoreToStorage();
|
|
87
|
+
this.initCalled = true;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async upsert(kind: IDataKind, data: IKeyedStoreItem) {
|
|
91
|
+
await this.addItem(kind, data.key, data);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
initialized(): boolean {
|
|
95
|
+
return this.initCalled;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* eslint-disable class-methods-use-this */
|
|
99
|
+
close(): void {
|
|
100
|
+
// For the LocalStorage store this is a no-op.
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
get version(): number {
|
|
104
|
+
return this.store.version;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// This getter needs to be overridden in the child class
|
|
108
|
+
get description(): string {
|
|
109
|
+
return '';
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// This method needs to be overridden in the child class
|
|
113
|
+
protected async saveUser(): Promise<void> {
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// This method needs to be overridden in the child class
|
|
117
|
+
protected async loadStoreFromStorage(): Promise<void> {
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// This method needs to be overridden in the child class
|
|
121
|
+
protected async dumpStoreToStorage(): Promise<void> {
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { IDataKind } from "../IDataKind";
|
|
2
|
+
import { IStoreDataStorage, IKeyedStoreItem } from "./store";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Interface that a data source implementation will use to push data into the SDK.
|
|
6
|
+
*
|
|
7
|
+
* The data source interacts with this object, rather than manipulating the data store directly, so
|
|
8
|
+
* that the SDK can perform any other necessary operations that must happen when data is updated.
|
|
9
|
+
*/
|
|
10
|
+
export interface IDataSourceUpdates {
|
|
11
|
+
/**
|
|
12
|
+
* Completely overwrites the current contents of the data store with a set of items for each
|
|
13
|
+
* collection.
|
|
14
|
+
*
|
|
15
|
+
* @param userKeyId
|
|
16
|
+
* The key ID of the user whose data is being updated.
|
|
17
|
+
*
|
|
18
|
+
* @param allData
|
|
19
|
+
* An object in which each key is the "namespace" of a collection (e.g. `"features"`) and
|
|
20
|
+
* the value is an object that maps keys to entities. The actual type of this parameter is
|
|
21
|
+
* `interfaces.FullDataSet<VersionedData>`.
|
|
22
|
+
*
|
|
23
|
+
* @param callback
|
|
24
|
+
* Will be called when the store has been initialized.
|
|
25
|
+
*/
|
|
26
|
+
init(userKeyId: string, allData: IStoreDataStorage, callback?: () => void): void;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Updates or inserts an item in the specified collection. For updates, the object will only be
|
|
30
|
+
* updated if the existing version is less than the new version.
|
|
31
|
+
*
|
|
32
|
+
* @param userKeyId
|
|
33
|
+
* The key ID of the user whose data is being updated.
|
|
34
|
+
*
|
|
35
|
+
* @param kind
|
|
36
|
+
* The type of data to be accessed. The actual type of this parameter is
|
|
37
|
+
* {@link IDataKind}.
|
|
38
|
+
*
|
|
39
|
+
* @param data
|
|
40
|
+
* The contents of the entity, as an object that can be converted to JSON. The store
|
|
41
|
+
* should check the `version` property of this object, and should *not* overwrite any
|
|
42
|
+
* existing data if the existing `version` is greater than or equal to that value.
|
|
43
|
+
* The actual type of this parameter is {@link IKeyedStoreItem}.
|
|
44
|
+
*
|
|
45
|
+
* @param callback
|
|
46
|
+
* Will be called after the upsert operation is complete.
|
|
47
|
+
*/
|
|
48
|
+
upsert(userKeyId: string, kind: IDataKind, data: IKeyedStoreItem, callback: () => void): void;
|
|
49
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {
|
|
2
|
+
StoreStorageKey,
|
|
3
|
+
IStoreDataStorage
|
|
4
|
+
} from "./store";
|
|
5
|
+
import { BaseStore } from "./BaseStore";
|
|
6
|
+
|
|
7
|
+
export default class InMemoryStore extends BaseStore {
|
|
8
|
+
private allStores: { [DataStoreStorageKey: string]: IStoreDataStorage } = {};
|
|
9
|
+
|
|
10
|
+
constructor() {
|
|
11
|
+
super();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* eslint-disable class-methods-use-this */
|
|
15
|
+
close(): void {
|
|
16
|
+
// For the LocalStorage store this is a no-op.
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
get description(): string {
|
|
20
|
+
return 'in-memory-store'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
protected async saveUser(): Promise<void> {
|
|
24
|
+
// For in-memory store, this is a no-op.
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
protected override async dumpStoreToStorage() {
|
|
28
|
+
const storageKey = `${StoreStorageKey}-${this._user.keyId}`;
|
|
29
|
+
this.allStores[storageKey] = {...this.store};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
protected override async loadStoreFromStorage() {
|
|
33
|
+
const storageKey = `${StoreStorageKey}-${this._user.keyId}`;
|
|
34
|
+
|
|
35
|
+
this.store = this.allStores[storageKey] ?? { flags: {}, version: 0 };
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { IFlag } from "../evaluation/data/IFlag";
|
|
2
|
+
import DataKinds from "./DataKinds";
|
|
3
|
+
import { IVersionedData } from "../IVersionedData";
|
|
4
|
+
import { IDataKind } from "../IDataKind";
|
|
5
|
+
|
|
6
|
+
export interface Flags {
|
|
7
|
+
flags: { [name: string]: IFlag };
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
type VersionedFlag = IVersionedData & IFlag;
|
|
11
|
+
|
|
12
|
+
export interface IPatchData {
|
|
13
|
+
data: VersionedFlag;
|
|
14
|
+
kind: IDataKind;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
export function deserializeAll(flags: IFlag[]): Flags {
|
|
21
|
+
const result = {
|
|
22
|
+
[DataKinds.Flags.namespace]: {}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
if (flags?.length) {
|
|
26
|
+
result[DataKinds.Flags.namespace] = flags.reduce((acc: any, cur: any) => {
|
|
27
|
+
acc[cur.id] = {...cur, version: cur.timestamp || 0, key: cur.id, variations: cur.variationOptions};
|
|
28
|
+
return acc;
|
|
29
|
+
}, {});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return result as any as Flags;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @internal
|
|
37
|
+
*/
|
|
38
|
+
export function deserializePatch(flags: IFlag[]): IPatchData[] {
|
|
39
|
+
const result = [
|
|
40
|
+
...flags?.map(item => ({
|
|
41
|
+
data: {
|
|
42
|
+
...item,
|
|
43
|
+
version:item.timestamp,
|
|
44
|
+
key: item.id,
|
|
45
|
+
variations: item.variationOptions
|
|
46
|
+
},
|
|
47
|
+
kind: DataKinds.Flags
|
|
48
|
+
})) || []
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
return result as any as IPatchData[];
|
|
52
|
+
}
|