@featbit/react-client-sdk 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,10 +1,11 @@
1
- # Featbit Client-Side SDK for ReactJS
1
+ # FeatBit Client-Side SDK for ReactJS
2
2
 
3
3
  ## Introduction
4
4
 
5
5
  This is the React client side SDK for the feature management platform [FeatBit](https://www.featbit.co).
6
6
 
7
- Be aware, this is a client side SDK, it is intended for use in a single-user context, which can be mobile, desktop or embeded applications. This SDK can only be ran in a browser environment, it is not suitable for React Native projects, React Native SDK will be available in our other repo.
7
+ Be aware, this is a client side SDK, it is intended for use in a single-user context, which can be mobile, desktop or embeded applications. This SDK can only be ran in a browser environment, it is not suitable for React Native projects.
8
+ If you are looking for React Native SDK, please check this [React Native SDK](https://github.com/featbit/featbit-react-native-sdk).
8
9
 
9
10
  > The React SDK is based on the JavaScript SDK
10
11
  The React SDK builds on FeatBit's JavaScript SDK to provide a better integration for use in React applications. As a result, much of the JavaScript SDK functionality is also available for the React SDK to use.
@@ -45,11 +45,23 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
45
45
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46
46
  }
47
47
  };
48
+ var __rest = (this && this.__rest) || function (s, e) {
49
+ var t = {};
50
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
51
+ t[p] = s[p];
52
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
53
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
54
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
55
+ t[p[i]] = s[p[i]];
56
+ }
57
+ return t;
58
+ };
48
59
  import React, { useState, useEffect } from 'react';
49
60
  import { defaultReactOptions } from './types';
50
61
  import { Provider } from './context';
51
- import { initClient } from './initClient';
52
62
  import getFlagsProxy from "./getFlagsProxy";
63
+ import { FbClientBuilder } from "@featbit/js-client-sdk";
64
+ import { fetchFlags } from "./utils";
53
65
  /**
54
66
  * This is an async function which initializes feature-flags.co's JS SDK (`@featbit/js-client-sdk`)
55
67
  * and awaits it so all flags and the fbClient are ready before the consumer app is rendered.
@@ -76,25 +88,58 @@ import getFlagsProxy from "./getFlagsProxy";
76
88
  */
77
89
  export default function asyncWithFbProvider(config) {
78
90
  return __awaiter(this, void 0, void 0, function () {
79
- var options, userReactOptions, platform, reactOptions, _a, fetchedFlags, fbClient, bootstrapFlags, FbProvider;
80
- var _this = this;
81
- return __generator(this, function (_b) {
82
- switch (_b.label) {
91
+ var options, userReactOptions, platform, reactOptions, error, fetchedFlags, fbClient, e_1, bootstrapFlags, FbProvider;
92
+ return __generator(this, function (_a) {
93
+ switch (_a.label) {
83
94
  case 0:
84
95
  options = config.options, userReactOptions = config.reactOptions, platform = config.platform;
85
96
  reactOptions = __assign(__assign({}, defaultReactOptions), userReactOptions);
86
- return [4 /*yield*/, initClient(reactOptions, options, platform)];
97
+ fetchedFlags = {};
98
+ fbClient = new FbClientBuilder(__assign({}, options))
99
+ .platform(platform)
100
+ .build();
101
+ _a.label = 1;
87
102
  case 1:
88
- _a = _b.sent(), fetchedFlags = _a.flags, fbClient = _a.fbClient;
103
+ _a.trys.push([1, 4, , 5]);
104
+ return [4 /*yield*/, fbClient.waitForInitialization()];
105
+ case 2:
106
+ _a.sent();
107
+ return [4 /*yield*/, fetchFlags(fbClient)];
108
+ case 3:
109
+ fetchedFlags = _a.sent();
110
+ return [3 /*break*/, 5];
111
+ case 4:
112
+ e_1 = _a.sent();
113
+ error = e_1;
114
+ return [3 /*break*/, 5];
115
+ case 5:
89
116
  bootstrapFlags = ((options === null || options === void 0 ? void 0 : options.bootstrap) || []).reduce(function (acc, flag) {
90
117
  acc[flag.id] = flag.variation;
91
118
  return acc;
92
119
  }, {});
93
120
  FbProvider = function (_a) {
94
121
  var children = _a.children;
95
- var _b = useState(function () { return (__assign({ unproxiedFlags: fetchedFlags }, getFlagsProxy(fbClient, bootstrapFlags, fetchedFlags, reactOptions))); }), state = _b[0], setState = _b[1];
122
+ var _b = useState(function () { return (__assign(__assign({ unproxiedFlags: fetchedFlags }, getFlagsProxy(fbClient, bootstrapFlags, fetchedFlags, reactOptions)), { fbClient: fbClient, error: error })); }), state = _b[0], setState = _b[1];
96
123
  useEffect(function () {
97
- fbClient.on('update', function (changedKeys) {
124
+ function onReady() {
125
+ return __awaiter(this, void 0, void 0, function () {
126
+ var unproxiedFlags;
127
+ return __generator(this, function (_a) {
128
+ switch (_a.label) {
129
+ case 0: return [4 /*yield*/, fetchFlags(fbClient)];
130
+ case 1:
131
+ unproxiedFlags = _a.sent();
132
+ setState(function (prevState) { return (__assign(__assign(__assign({}, prevState), { unproxiedFlags: unproxiedFlags }), getFlagsProxy(fbClient, bootstrapFlags, unproxiedFlags, reactOptions))); });
133
+ return [2 /*return*/];
134
+ }
135
+ });
136
+ });
137
+ }
138
+ function onFailed(e) {
139
+ setState(function (prevState) { return (__assign(__assign({}, prevState), { error: e })); });
140
+ }
141
+ function onUpdate(changedKeys) {
142
+ var _this = this;
98
143
  var updates = changedKeys.reduce(function (acc, key) { return __awaiter(_this, void 0, void 0, function () {
99
144
  var _a, _b;
100
145
  return __generator(this, function (_c) {
@@ -110,16 +155,28 @@ export default function asyncWithFbProvider(config) {
110
155
  });
111
156
  }); }, {});
112
157
  if (Object.keys(updates).length > 0) {
113
- setState(function (_a) {
114
- var unproxiedFlags = _a.unproxiedFlags;
115
- var updatedUnproxiedFlags = __assign(__assign({}, unproxiedFlags), updates);
116
- return __assign({ unproxiedFlags: updatedUnproxiedFlags }, getFlagsProxy(fbClient, bootstrapFlags, updatedUnproxiedFlags, reactOptions));
158
+ setState(function (prevState) {
159
+ var updatedUnproxiedFlags = __assign(__assign({}, prevState.unproxiedFlags), updates);
160
+ return __assign(__assign(__assign({}, prevState), { unproxiedFlags: updatedUnproxiedFlags }), getFlagsProxy(fbClient, bootstrapFlags, updatedUnproxiedFlags, reactOptions));
117
161
  });
118
162
  }
119
- });
163
+ }
164
+ fbClient.on('update', onUpdate);
165
+ // Only subscribe to ready and failed if waitForInitialization timed out
166
+ // because we want the introduction of init timeout to be as minimal and backwards
167
+ // compatible as possible.
168
+ if (error === null || error === void 0 ? void 0 : error.name.toLowerCase().includes('timeout')) {
169
+ fbClient.on('failed', onFailed);
170
+ fbClient.on('ready', onReady);
171
+ }
172
+ return function cleanup() {
173
+ fbClient.off('update', onUpdate);
174
+ fbClient.off('failed', onFailed);
175
+ fbClient.off('ready', onReady);
176
+ };
120
177
  }, []);
121
- var flags = state.flags, flagKeyMap = state.flagKeyMap;
122
- return React.createElement(Provider, { value: { flags: flags, flagKeyMap: flagKeyMap, fbClient: fbClient } }, children);
178
+ var _ = state.unproxiedFlags, rest = __rest(state, ["unproxiedFlags"]);
179
+ return React.createElement(Provider, { value: rest }, children);
123
180
  };
124
181
  return [2 /*return*/, FbProvider];
125
182
  }
@@ -1 +1 @@
1
- {"version":3,"file":"asyncWithFbProvider.js","sourceRoot":"../src/","sources":["asyncWithFbProvider.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAa,MAAM,OAAO,CAAC;AAC9D,OAAO,EAAkB,mBAAmB,EAAY,MAAM,SAAS,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,OAAO,UAAgB,mBAAmB,CAAC,MAAsB;;;;;;;oBAC/D,OAAO,GAA8C,MAAM,QAApD,EAAgB,gBAAgB,GAAc,MAAM,aAApB,EAAE,QAAQ,GAAI,MAAM,SAAV,CAAW;oBAC7D,YAAY,yBAAO,mBAAmB,GAAK,gBAAgB,CAAC,CAAC;oBAC1B,qBAAM,UAAU,CAAC,YAAY,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAA;;oBAApF,KAAmC,SAAiD,EAA3E,YAAY,WAAA,EAAE,QAAQ,cAAA;oBAE/B,cAAc,GAAG,CAAC,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,KAAI,EAAE,CAAC,CAAC,MAAM,CAAC,UAAC,GAA4B,EAAE,IAAS;wBAC/F,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC;wBAC9B,OAAO,GAAG,CAAC;oBACb,CAAC,EAAE,EAA6B,CAAC,CAAC;oBAE5B,UAAU,GAAG,UAAC,EAAmC;4BAAlC,QAAQ,cAAA;wBACrB,IAAA,KAAoB,QAAQ,CAAC,cAAM,OAAA,YACvC,cAAc,EAAE,YAAY,IACzB,aAAa,CAAC,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,CAAC,EACtE,EAHuC,CAGvC,CAAC,EAHI,KAAK,QAAA,EAAE,QAAQ,QAGnB,CAAC;wBAEJ,SAAS,CAAC;4BACR,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAC,WAAqB;gCAC1C,IAAM,OAAO,GAAa,WAAW,CAAC,MAAM,CAAC,UAAO,GAAG,EAAE,GAAG;;;;;gDAC1D,KAAA,GAAG,CAAA;gDAAC,KAAA,GAAG,CAAA;gDAAI,qBAAM,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,CAAC,EAAA;;gDAA5C,MAAQ,GAAG,SAAiC,CAAC;gDAC7C,sBAAO,GAAG,EAAC;;;qCACZ,EAAE,EAAc,CAAC,CAAC;gCAEnB,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;oCACnC,QAAQ,CAAC,UAAC,EAAkB;4CAAhB,cAAc,oBAAA;wCACxB,IAAM,qBAAqB,yBAAQ,cAAc,GAAK,OAAO,CAAE,CAAC;wCAEhE,kBACE,cAAc,EAAE,qBAAqB,IAClC,aAAa,CAAC,QAAQ,EAAE,cAAc,EAAE,qBAAqB,EAAE,YAAY,CAAC,EAC/E;oCACJ,CAAC,CAAC,CAAC;iCACJ;4BACH,CAAC,CAAC,CAAC;wBACL,CAAC,EAAE,EAAE,CAAC,CAAC;wBAEC,IAAA,KAAK,GAAiB,KAAK,MAAtB,EAAE,UAAU,GAAK,KAAK,WAAV,CAAW;wBACpC,OAAO,oBAAC,QAAQ,IAAC,KAAK,EAAE,EAAE,KAAK,OAAA,EAAE,UAAU,YAAA,EAAE,QAAQ,UAAA,EAAE,IAAI,QAAQ,CAAa,CAAC;oBACnF,CAAC,CAAC;oBAEF,sBAAO,UAAU,EAAC;;;;CACnB"}
1
+ {"version":3,"file":"asyncWithFbProvider.js","sourceRoot":"../src/","sources":["asyncWithFbProvider.tsx"],"names":[],"mappings":"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"}
package/dist/context.d.ts CHANGED
@@ -8,6 +8,10 @@ interface FbContext {
8
8
  */
9
9
  flagKeyMap: FlagKeyMap;
10
10
  fbClient?: IFbClient;
11
+ /**
12
+ * FeatBit client initialization error, if there was one.
13
+ */
14
+ error?: Error;
11
15
  }
12
16
  declare const context: import("react").Context<FbContext>;
13
17
  declare const Provider: import("react").Provider<FbContext>, Consumer: import("react").Consumer<FbContext>;
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"../src/","sources":["context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AActC,IAAM,OAAO,GAAG,aAAa,CAAY,EAAC,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAC,CAAC,CAAC;AAGzF,IAAA,QAAQ,GAEN,OAAO,SAFD,EACR,QAAQ,GACN,OAAO,SADD,CACE;AAEZ,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAa,CAAC;AACzC,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"context.js","sourceRoot":"../src/","sources":["context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAmBtC,IAAM,OAAO,GAAG,aAAa,CAAY,EAAC,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAC,CAAC,CAAC;AAGzF,IAAA,QAAQ,GAEN,OAAO,SAFD,EACR,QAAQ,GACN,OAAO,SADD,CACE;AAEZ,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAa,CAAC;AACzC,eAAe,OAAO,CAAC"}
@@ -1,10 +1,7 @@
1
- import React from "react";
1
+ import React, { Component, PropsWithChildren } from "react";
2
2
  import { EnhancedComponent, ProviderConfig, IFlagSet } from './types';
3
- import { FbContext } from './context';
4
3
  import { IFbClient } from '@featbit/js-client-sdk';
5
- interface FbHocState extends FbContext {
6
- unproxiedFlags: IFlagSet;
7
- }
4
+ import { ProviderState } from "./providerState";
8
5
  /**
9
6
  * The `FbProvider` is a component which accepts a config object which is used to
10
7
  * initialize `@featbit/js-client-sdk`.
@@ -22,8 +19,8 @@ interface FbHocState extends FbContext {
22
19
  * within your application. This provider is used inside the `withFbProviderHOC` and can be used instead to initialize
23
20
  * the `@featbit/js-client-sdk`. For async initialization, check out the `asyncWithFbProvider` function
24
21
  */
25
- declare class FbProvider extends React.Component<ProviderConfig, FbHocState> implements EnhancedComponent {
26
- readonly state: Readonly<FbHocState>;
22
+ declare class FbProvider extends Component<PropsWithChildren<ProviderConfig>, ProviderState> implements EnhancedComponent {
23
+ readonly state: Readonly<ProviderState>;
27
24
  bootstrapFlags: IFlagSet;
28
25
  constructor(props: ProviderConfig);
29
26
  getReactOptions: () => {
@@ -31,9 +28,11 @@ declare class FbProvider extends React.Component<ProviderConfig, FbHocState> imp
31
28
  sendEventsOnFlagRead: boolean;
32
29
  };
33
30
  subscribeToChanges: (fbClient: IFbClient) => void;
34
- init: () => Promise<void>;
31
+ onFailed: (fbClient: IFbClient, e: Error) => void;
32
+ onReady: (fbClient: IFbClient, reactOptions: any) => Promise<void>;
33
+ prepareFbClient: () => Promise<void>;
35
34
  componentDidMount(): Promise<void>;
36
35
  componentDidUpdate(prevProps: ProviderConfig): Promise<void>;
37
- render(): React.JSX.Element | null;
36
+ render(): React.JSX.Element;
38
37
  }
39
38
  export default FbProvider;
package/dist/provider.js CHANGED
@@ -60,11 +60,11 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
60
60
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
61
61
  }
62
62
  };
63
- import React from "react";
63
+ import React, { Component } from "react";
64
64
  import { defaultReactOptions } from './types';
65
65
  import { Provider } from './context';
66
66
  import { camelCaseKeys, fetchFlags } from "./utils";
67
- import { initClient } from './initClient';
67
+ import { FbClientBuilder } from '@featbit/js-client-sdk';
68
68
  import getFlagsProxy from "./getFlagsProxy";
69
69
  /**
70
70
  * The `FbProvider` is a component which accepts a config object which is used to
@@ -96,31 +96,67 @@ var FbProvider = /** @class */ (function (_super) {
96
96
  }, {});
97
97
  var unproxiedFlags = __assign(__assign({}, _this.state.unproxiedFlags), updates);
98
98
  if (Object.keys(updates).length > 0) {
99
- _this.setState(__assign({ unproxiedFlags: unproxiedFlags }, getFlagsProxy(fbClient, _this.bootstrapFlags, unproxiedFlags, _this.getReactOptions())));
99
+ _this.setState(function (prevState) { return (__assign(__assign(__assign({}, prevState), { unproxiedFlags: unproxiedFlags }), getFlagsProxy(fbClient, _this.bootstrapFlags, unproxiedFlags, _this.getReactOptions()))); });
100
100
  }
101
101
  });
102
102
  };
103
- _this.init = function () { return __awaiter(_this, void 0, void 0, function () {
104
- var _a, options, platform, client, reactOptions, unproxiedFlags, initialisedOutput;
103
+ _this.onFailed = function (fbClient, e) {
104
+ _this.setState(function (prevState) { return (__assign(__assign({}, prevState), { error: e })); });
105
+ };
106
+ _this.onReady = function (fbClient, reactOptions) { return __awaiter(_this, void 0, void 0, function () {
107
+ var unproxiedFlags;
108
+ var _this = this;
109
+ return __generator(this, function (_a) {
110
+ switch (_a.label) {
111
+ case 0: return [4 /*yield*/, fetchFlags(fbClient)];
112
+ case 1:
113
+ unproxiedFlags = _a.sent();
114
+ this.setState(function (prevState) { return (__assign(__assign(__assign({}, prevState), { unproxiedFlags: unproxiedFlags }), getFlagsProxy(fbClient, _this.bootstrapFlags, unproxiedFlags, reactOptions))); });
115
+ return [2 /*return*/];
116
+ }
117
+ });
118
+ }); };
119
+ _this.prepareFbClient = function () { return __awaiter(_this, void 0, void 0, function () {
120
+ var _a, options, platform, client, reactOptions, unproxiedFlags, error, e_1;
121
+ var _this = this;
105
122
  return __generator(this, function (_b) {
106
123
  switch (_b.label) {
107
124
  case 0:
108
125
  _a = this.props, options = _a.options, platform = _a.platform;
109
126
  client = this.props.fbClient;
110
127
  reactOptions = this.getReactOptions();
128
+ unproxiedFlags = this.state.unproxiedFlags;
111
129
  if (!client) return [3 /*break*/, 2];
112
130
  return [4 /*yield*/, fetchFlags(client)];
113
131
  case 1:
114
132
  unproxiedFlags = _b.sent();
115
- return [3 /*break*/, 4];
116
- case 2: return [4 /*yield*/, initClient(reactOptions, options, platform)];
133
+ return [3 /*break*/, 7];
134
+ case 2:
135
+ client = new FbClientBuilder(__assign({}, options))
136
+ .platform(platform)
137
+ .build();
138
+ _b.label = 3;
117
139
  case 3:
118
- initialisedOutput = _b.sent();
119
- unproxiedFlags = initialisedOutput.flags;
120
- client = initialisedOutput.fbClient;
121
- _b.label = 4;
140
+ _b.trys.push([3, 6, , 7]);
141
+ return [4 /*yield*/, client.waitForInitialization()];
122
142
  case 4:
123
- this.setState(__assign(__assign({ unproxiedFlags: unproxiedFlags }, getFlagsProxy(client, this.bootstrapFlags, unproxiedFlags, reactOptions)), { fbClient: client }));
143
+ _b.sent();
144
+ return [4 /*yield*/, fetchFlags(client)];
145
+ case 5:
146
+ unproxiedFlags = _b.sent();
147
+ return [3 /*break*/, 7];
148
+ case 6:
149
+ e_1 = _b.sent();
150
+ error = e_1;
151
+ if (error === null || error === void 0 ? void 0 : error.name.toLowerCase().includes('timeout')) {
152
+ client.on('failed', this.onFailed);
153
+ client.on('ready', function () {
154
+ _this.onReady(client, reactOptions);
155
+ });
156
+ }
157
+ return [3 /*break*/, 7];
158
+ case 7:
159
+ this.setState(function (previousState) { return (__assign(__assign(__assign(__assign({}, previousState), { unproxiedFlags: unproxiedFlags }), getFlagsProxy(client, _this.bootstrapFlags, unproxiedFlags, reactOptions)), { fbClient: client, error: error })); });
124
160
  this.subscribeToChanges(client);
125
161
  return [2 /*return*/];
126
162
  }
@@ -131,7 +167,6 @@ var FbProvider = /** @class */ (function (_super) {
131
167
  acc[flag.id] = flag.variation;
132
168
  return acc;
133
169
  }, {});
134
- ;
135
170
  _this.state = {
136
171
  flags: {},
137
172
  unproxiedFlags: {},
@@ -160,7 +195,7 @@ var FbProvider = /** @class */ (function (_super) {
160
195
  if (deferInitialization && !options) {
161
196
  return [2 /*return*/];
162
197
  }
163
- return [4 /*yield*/, this.init()];
198
+ return [4 /*yield*/, this.prepareFbClient()];
164
199
  case 1:
165
200
  _b.sent();
166
201
  return [2 /*return*/];
@@ -178,7 +213,7 @@ var FbProvider = /** @class */ (function (_super) {
178
213
  _b = this.props, options = _b.options, deferInitialization = _b.deferInitialization;
179
214
  userJustLoaded = !((_a = prevProps.options) === null || _a === void 0 ? void 0 : _a.user) && (options === null || options === void 0 ? void 0 : options.user);
180
215
  if (!(deferInitialization && userJustLoaded)) return [3 /*break*/, 2];
181
- return [4 /*yield*/, this.init()];
216
+ return [4 /*yield*/, this.prepareFbClient()];
182
217
  case 1:
183
218
  _c.sent();
184
219
  _c.label = 2;
@@ -188,14 +223,10 @@ var FbProvider = /** @class */ (function (_super) {
188
223
  });
189
224
  };
190
225
  FbProvider.prototype.render = function () {
191
- var _a = this.state, flags = _a.flags, flagKeyMap = _a.flagKeyMap, fbClient = _a.fbClient;
192
- // Conditional rendering when fbClient is null
193
- if (fbClient === undefined) {
194
- return null; // or Loading Indicator or any other placeholder
195
- }
196
- return React.createElement(Provider, { value: { flags: flags, flagKeyMap: flagKeyMap, fbClient: fbClient } }, this.props.children);
226
+ var _a = this.state, flags = _a.flags, flagKeyMap = _a.flagKeyMap, fbClient = _a.fbClient, error = _a.error;
227
+ return React.createElement(Provider, { value: { flags: flags, flagKeyMap: flagKeyMap, fbClient: fbClient, error: error } }, this.props.children);
197
228
  };
198
229
  return FbProvider;
199
- }(React.Component));
230
+ }(Component));
200
231
  export default FbProvider;
201
232
  //# sourceMappingURL=provider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider.js","sourceRoot":"../src/","sources":["provider.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"provider.js","sourceRoot":"../src/","sources":["provider.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { FlagKeyMap, IFlagSet } from "./types";
2
+ import { IFbClient } from "@featbit/js-client-sdk";
3
+ export interface ProviderState {
4
+ error?: Error;
5
+ flagKeyMap: FlagKeyMap;
6
+ flags: IFlagSet;
7
+ fbClient?: IFbClient;
8
+ unproxiedFlags: IFlagSet;
9
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=providerState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providerState.js","sourceRoot":"../src/","sources":["providerState.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@featbit/react-client-sdk",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "FeatBit client SDK for React",
5
5
  "keywords": [
6
6
  "FeatBit",
@@ -47,7 +47,7 @@
47
47
  "typescript": "^4.5.3"
48
48
  },
49
49
  "dependencies": {
50
- "@featbit/js-client-sdk": "^3.0.4",
50
+ "@featbit/js-client-sdk": "^3.0.6",
51
51
  "hoist-non-react-statics": "^3.3.2",
52
52
  "lodash.camelcase": "^4.3.0"
53
53
  },
@@ -3,6 +3,8 @@ import { ProviderConfig, defaultReactOptions, IFlagSet } from './types';
3
3
  import { Provider } from './context';
4
4
  import { initClient } from './initClient';
5
5
  import getFlagsProxy from "./getFlagsProxy";
6
+ import { FbClientBuilder } from "@featbit/js-client-sdk";
7
+ import { fetchFlags } from "./utils";
6
8
 
7
9
  /**
8
10
  * This is an async function which initializes feature-flags.co's JS SDK (`@featbit/js-client-sdk`)
@@ -31,7 +33,19 @@ import getFlagsProxy from "./getFlagsProxy";
31
33
  export default async function asyncWithFbProvider(config: ProviderConfig) {
32
34
  const {options, reactOptions: userReactOptions, platform} = config;
33
35
  const reactOptions = {...defaultReactOptions, ...userReactOptions};
34
- const { flags: fetchedFlags, fbClient} = await initClient(reactOptions, options, platform);
36
+ let error: Error;
37
+ let fetchedFlags: IFlagSet = {};
38
+
39
+ const fbClient = new FbClientBuilder({...options})
40
+ .platform(platform)
41
+ .build();
42
+
43
+ try {
44
+ await fbClient.waitForInitialization();
45
+ fetchedFlags = await fetchFlags(fbClient);
46
+ } catch (e) {
47
+ error = e as Error;
48
+ }
35
49
 
36
50
  const bootstrapFlags = (options?.bootstrap || []).reduce((acc: {[key: string]: string}, flag: any) => {
37
51
  acc[flag.id] = flag.variation;
@@ -41,31 +55,63 @@ export default async function asyncWithFbProvider(config: ProviderConfig) {
41
55
  const FbProvider = ({children}: { children: ReactNode }) => {
42
56
  const [state, setState] = useState(() => ({
43
57
  unproxiedFlags: fetchedFlags,
44
- ...getFlagsProxy(fbClient, bootstrapFlags, fetchedFlags, reactOptions)
58
+ ...getFlagsProxy(fbClient, bootstrapFlags, fetchedFlags, reactOptions),
59
+ fbClient,
60
+ error,
45
61
  }));
46
62
 
47
63
  useEffect(() => {
48
- fbClient.on('update', (changedKeys: string[]) => {
64
+ async function onReady() {
65
+ const unproxiedFlags = await fetchFlags(fbClient);
66
+ setState((prevState) => ({
67
+ ...prevState,
68
+ unproxiedFlags,
69
+ ...getFlagsProxy(fbClient, bootstrapFlags, unproxiedFlags, reactOptions)}));
70
+ }
71
+
72
+ function onFailed(e: Error) {
73
+ setState((prevState) => ({ ...prevState, error: e }));
74
+ }
75
+
76
+ function onUpdate(changedKeys: string[]) {
49
77
  const updates: IFlagSet = changedKeys.reduce(async (acc, key) => {
50
78
  acc[key] = await fbClient.variation(key, '');
51
79
  return acc;
52
80
  }, {} as IFlagSet);
53
81
 
54
82
  if (Object.keys(updates).length > 0) {
55
- setState(({ unproxiedFlags }) => {
56
- const updatedUnproxiedFlags = { ...unproxiedFlags, ...updates };
83
+ setState((prevState) => {
84
+ const updatedUnproxiedFlags = { ...prevState.unproxiedFlags, ...updates };
57
85
 
58
86
  return {
87
+ ...prevState,
59
88
  unproxiedFlags: updatedUnproxiedFlags,
60
89
  ...getFlagsProxy(fbClient, bootstrapFlags, updatedUnproxiedFlags, reactOptions),
61
90
  };
62
91
  });
63
92
  }
64
- });
93
+ }
94
+
95
+ fbClient.on('update', onUpdate);
96
+
97
+ // Only subscribe to ready and failed if waitForInitialization timed out
98
+ // because we want the introduction of init timeout to be as minimal and backwards
99
+ // compatible as possible.
100
+ if (error?.name.toLowerCase().includes('timeout')) {
101
+ fbClient.on('failed', onFailed);
102
+ fbClient.on('ready', onReady);
103
+ }
104
+
105
+ return function cleanup() {
106
+ fbClient.off('update', onUpdate);
107
+ fbClient.off('failed', onFailed);
108
+ fbClient.off('ready', onReady);
109
+ };
110
+
65
111
  }, []);
66
112
 
67
- const { flags, flagKeyMap } = state;
68
- return <Provider value={{ flags, flagKeyMap, fbClient }}>{ children }</Provider>;
113
+ const { unproxiedFlags: _, ...rest } = state;
114
+ return <Provider value={rest}>{ children }</Provider>;
69
115
  };
70
116
 
71
117
  return FbProvider;
package/src/context.ts CHANGED
@@ -10,7 +10,12 @@ interface FbContext {
10
10
  */
11
11
  flagKeyMap: FlagKeyMap;
12
12
 
13
- fbClient?: IFbClient
13
+ fbClient?: IFbClient,
14
+
15
+ /**
16
+ * FeatBit client initialization error, if there was one.
17
+ */
18
+ error?: Error,
14
19
  }
15
20
 
16
21
  const context = createContext<FbContext>({flags: {}, flagKeyMap: {}, fbClient: undefined});
package/src/provider.tsx CHANGED
@@ -1,14 +1,11 @@
1
- import React from "react";
1
+ import React, { Component, PropsWithChildren } from "react";
2
2
  import { EnhancedComponent, ProviderConfig, defaultReactOptions, IFlagSet } from './types';
3
- import { Provider, FbContext } from './context';
3
+ import { Provider } from './context';
4
4
  import { camelCaseKeys, fetchFlags } from "./utils";
5
- import { initClient } from './initClient';
6
- import { IFbClient } from '@featbit/js-client-sdk';
5
+ import { FbClientBuilder, IFbClient } from '@featbit/js-client-sdk';
7
6
  import getFlagsProxy from "./getFlagsProxy";
7
+ import { ProviderState } from "./providerState";
8
8
 
9
- interface FbHocState extends FbContext {
10
- unproxiedFlags: IFlagSet;
11
- }
12
9
 
13
10
  /**
14
11
  * The `FbProvider` is a component which accepts a config object which is used to
@@ -27,8 +24,8 @@ interface FbHocState extends FbContext {
27
24
  * within your application. This provider is used inside the `withFbProviderHOC` and can be used instead to initialize
28
25
  * the `@featbit/js-client-sdk`. For async initialization, check out the `asyncWithFbProvider` function
29
26
  */
30
- class FbProvider extends React.Component<ProviderConfig, FbHocState> implements EnhancedComponent {
31
- readonly state: Readonly<FbHocState>;
27
+ class FbProvider extends Component<PropsWithChildren<ProviderConfig>, ProviderState> implements EnhancedComponent {
28
+ readonly state: Readonly<ProviderState>;
32
29
  bootstrapFlags: IFlagSet;
33
30
 
34
31
  constructor(props: ProviderConfig) {
@@ -38,7 +35,7 @@ class FbProvider extends React.Component<ProviderConfig, FbHocState> implements
38
35
  this.bootstrapFlags = (options?.bootstrap || []).reduce((acc: {[key: string]: string}, flag: any) => {
39
36
  acc[flag.id] = flag.variation;
40
37
  return acc;
41
- }, {} as {[key: string]: string});;
38
+ }, {} as {[key: string]: string});
42
39
 
43
40
  this.state = {
44
41
  flags: {},
@@ -74,32 +71,63 @@ class FbProvider extends React.Component<ProviderConfig, FbHocState> implements
74
71
  };
75
72
 
76
73
  if (Object.keys(updates).length > 0) {
77
- this.setState({
74
+ this.setState((prevState) =>({
75
+ ...prevState,
78
76
  unproxiedFlags,
79
77
  ...getFlagsProxy(fbClient, this.bootstrapFlags, unproxiedFlags, this.getReactOptions())
80
- })
78
+ }))
81
79
  }
82
80
  });
83
81
  };
84
82
 
85
- init = async () => {
83
+ onFailed = (fbClient: IFbClient, e: Error) => {
84
+ this.setState((prevState) => ({ ...prevState, error: e }));
85
+ };
86
+
87
+ onReady = async (fbClient: IFbClient, reactOptions: any) => {
88
+ const unproxiedFlags = await fetchFlags(fbClient);
89
+ this.setState((prevState) => ({
90
+ ...prevState,
91
+ unproxiedFlags,
92
+ ...getFlagsProxy(fbClient, this.bootstrapFlags, unproxiedFlags, reactOptions)}));
93
+ };
94
+
95
+ prepareFbClient = async () => {
86
96
  const {options, platform} = this.props;
87
97
  let client: IFbClient = this.props.fbClient!;
88
98
  const reactOptions = this.getReactOptions();
89
- let unproxiedFlags;
99
+ let unproxiedFlags = this.state.unproxiedFlags;
100
+ let error: Error;
101
+
90
102
  if (client) {
91
103
  unproxiedFlags = await fetchFlags(client);
92
104
  } else {
93
- const initialisedOutput = await initClient(reactOptions, options, platform);
94
- unproxiedFlags = initialisedOutput.flags;
95
- client = initialisedOutput.fbClient!;
105
+ client = new FbClientBuilder({...options})
106
+ .platform(platform)
107
+ .build();
108
+
109
+ try {
110
+ await client.waitForInitialization();
111
+ unproxiedFlags = await fetchFlags(client);
112
+ } catch (e) {
113
+ error = e as Error;
114
+
115
+ if (error?.name.toLowerCase().includes('timeout')) {
116
+ client.on('failed', this.onFailed);
117
+ client.on('ready', () => {
118
+ this.onReady(client, reactOptions);
119
+ });
120
+ }
121
+ }
96
122
  }
97
123
 
98
- this.setState({
124
+ this.setState((previousState) => ({
125
+ ...previousState,
99
126
  unproxiedFlags,
100
127
  ...getFlagsProxy(client, this.bootstrapFlags, unproxiedFlags, reactOptions),
101
- fbClient: client
102
- });
128
+ fbClient: client,
129
+ error,
130
+ }));
103
131
 
104
132
  this.subscribeToChanges(client);
105
133
  };
@@ -110,26 +138,21 @@ class FbProvider extends React.Component<ProviderConfig, FbHocState> implements
110
138
  return;
111
139
  }
112
140
 
113
- await this.init();
141
+ await this.prepareFbClient();
114
142
  }
115
143
 
116
144
  async componentDidUpdate(prevProps: ProviderConfig) {
117
145
  const {options, deferInitialization} = this.props;
118
146
  const userJustLoaded = !prevProps.options?.user && options?.user;
119
147
  if (deferInitialization && userJustLoaded) {
120
- await this.init();
148
+ await this.prepareFbClient();
121
149
  }
122
150
  }
123
151
 
124
152
  render() {
125
- const {flags, flagKeyMap, fbClient} = this.state;
126
-
127
- // Conditional rendering when fbClient is null
128
- if (fbClient === undefined) {
129
- return null; // or Loading Indicator or any other placeholder
130
- }
153
+ const {flags, flagKeyMap, fbClient, error} = this.state;
131
154
 
132
- return <Provider value={{ flags, flagKeyMap, fbClient }}>{ this.props.children }</Provider>;
155
+ return <Provider value={{ flags, flagKeyMap, fbClient, error }}>{ this.props.children }</Provider>;
133
156
  }
134
157
  }
135
158
 
@@ -0,0 +1,10 @@
1
+ import { FlagKeyMap, IFlagSet } from "./types";
2
+ import { IFbClient } from "@featbit/js-client-sdk";
3
+
4
+ export interface ProviderState {
5
+ error?: Error;
6
+ flagKeyMap: FlagKeyMap;
7
+ flags: IFlagSet;
8
+ fbClient?: IFbClient;
9
+ unproxiedFlags: IFlagSet;
10
+ }