@featbit/react-client-sdk 1.0.0
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 +201 -0
- package/README.md +435 -0
- package/dist/asyncWithFbProvider.d.ts +29 -0
- package/dist/asyncWithFbProvider.js +129 -0
- package/dist/asyncWithFbProvider.js.map +1 -0
- package/dist/context.d.ts +15 -0
- package/dist/context.js +6 -0
- package/dist/context.js.map +1 -0
- package/dist/getFlagsProxy.d.ts +6 -0
- package/dist/getFlagsProxy.js +56 -0
- package/dist/getFlagsProxy.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/initClient.d.ts +12 -0
- package/dist/initClient.js +84 -0
- package/dist/initClient.js.map +1 -0
- package/dist/provider.d.ts +39 -0
- package/dist/provider.js +201 -0
- package/dist/provider.js.map +1 -0
- package/dist/types.d.ts +90 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/useFbClient.d.ts +11 -0
- package/dist/useFbClient.js +18 -0
- package/dist/useFbClient.js.map +1 -0
- package/dist/useFlags.d.ts +11 -0
- package/dist/useFlags.js +16 -0
- package/dist/useFlags.js.map +1 -0
- package/dist/utils.d.ts +27 -0
- package/dist/utils.js +78 -0
- package/dist/utils.js.map +1 -0
- package/dist/withFbConsumer.d.ts +38 -0
- package/dist/withFbConsumer.js +36 -0
- package/dist/withFbConsumer.js.map +1 -0
- package/dist/withFbProvider.d.ts +25 -0
- package/dist/withFbProvider.js +50 -0
- package/dist/withFbProvider.js.map +1 -0
- package/package.json +57 -0
- package/src/asyncWithFbProvider.tsx +72 -0
- package/src/context.ts +24 -0
- package/src/getFlagsProxy.ts +82 -0
- package/src/index.ts +21 -0
- package/src/initClient.ts +26 -0
- package/src/provider.tsx +136 -0
- package/src/types.ts +103 -0
- package/src/useFbClient.ts +21 -0
- package/src/useFlags.ts +19 -0
- package/src/utils.ts +39 -0
- package/src/withFbConsumer.tsx +58 -0
- package/src/withFbProvider.tsx +49 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
13
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
14
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
15
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
16
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
17
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
18
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
22
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
23
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
24
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
25
|
+
function step(op) {
|
|
26
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
27
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
28
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
29
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
30
|
+
switch (op[0]) {
|
|
31
|
+
case 0: case 1: t = op; break;
|
|
32
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
33
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
34
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
35
|
+
default:
|
|
36
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
37
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
38
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
39
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
40
|
+
if (t[2]) _.ops.pop();
|
|
41
|
+
_.trys.pop(); continue;
|
|
42
|
+
}
|
|
43
|
+
op = body.call(thisArg, _);
|
|
44
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
45
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
import React, { useState, useEffect } from 'react';
|
|
49
|
+
import { defaultReactOptions } from './types';
|
|
50
|
+
import { Provider } from './context';
|
|
51
|
+
import { initClient } from './initClient';
|
|
52
|
+
import getFlagsProxy from "./getFlagsProxy";
|
|
53
|
+
/**
|
|
54
|
+
* This is an async function which initializes feature-flags.co's JS SDK (`@featbit/js-client-sdk`)
|
|
55
|
+
* and awaits it so all flags and the fbClient are ready before the consumer app is rendered.
|
|
56
|
+
*
|
|
57
|
+
* The difference between `withFbProvider` and `asyncWithFbProvider` is that `withFbProvider` initializes
|
|
58
|
+
* `@featbit/js-client-sdk` at componentDidMount. This means your flags and the fbClient are only available after
|
|
59
|
+
* your app has mounted. This can result in a flicker due to flag changes at startup time.
|
|
60
|
+
*
|
|
61
|
+
* `asyncWithFbProvider` initializes `@featbit/js-client-sdk` at the entry point of your app prior to render.
|
|
62
|
+
* This means that your flags and the fbClient are ready at the beginning of your app. This ensures your app does not
|
|
63
|
+
* flicker due to flag changes at startup time.
|
|
64
|
+
*
|
|
65
|
+
* `asyncWithFbProvider` accepts a config object which is used to initialize `@featbit/js-client-sdk`.
|
|
66
|
+
*
|
|
67
|
+
* `asyncWithFbProvider` does not support the `deferInitialization` config option because `asyncWithFbProvider` needs
|
|
68
|
+
* to be initialized at the entry point prior to render to ensure your flags and the fbClient are ready at the beginning
|
|
69
|
+
* of your app.
|
|
70
|
+
*
|
|
71
|
+
* It returns a provider which is a React FunctionComponent which:
|
|
72
|
+
* - saves all flags and the ldClient instance in the context API
|
|
73
|
+
* - subscribes to flag changes and propagate them through the context API
|
|
74
|
+
*
|
|
75
|
+
* @param config - The configuration used to initialize FeatBit's JS SDK
|
|
76
|
+
*/
|
|
77
|
+
export default function asyncWithFbProvider(config) {
|
|
78
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
79
|
+
var options, userReactOptions, reactOptions, _a, fetchedFlags, fbClient, bootstrapFlags, FbProvider;
|
|
80
|
+
var _this = this;
|
|
81
|
+
return __generator(this, function (_b) {
|
|
82
|
+
switch (_b.label) {
|
|
83
|
+
case 0:
|
|
84
|
+
options = config.options, userReactOptions = config.reactOptions;
|
|
85
|
+
reactOptions = __assign(__assign({}, defaultReactOptions), userReactOptions);
|
|
86
|
+
return [4 /*yield*/, initClient(reactOptions, options)];
|
|
87
|
+
case 1:
|
|
88
|
+
_a = _b.sent(), fetchedFlags = _a.flags, fbClient = _a.fbClient;
|
|
89
|
+
bootstrapFlags = ((options === null || options === void 0 ? void 0 : options.bootstrap) || []).reduce(function (acc, flag) {
|
|
90
|
+
acc[flag.id] = flag.variation;
|
|
91
|
+
return acc;
|
|
92
|
+
}, {});
|
|
93
|
+
FbProvider = function (_a) {
|
|
94
|
+
var children = _a.children;
|
|
95
|
+
var _b = useState(function () { return (__assign({ unproxiedFlags: fetchedFlags }, getFlagsProxy(fbClient, bootstrapFlags, fetchedFlags, reactOptions))); }), state = _b[0], setState = _b[1];
|
|
96
|
+
useEffect(function () {
|
|
97
|
+
fbClient.on('update', function (changedKeys) {
|
|
98
|
+
var updates = changedKeys.reduce(function (acc, key) { return __awaiter(_this, void 0, void 0, function () {
|
|
99
|
+
var _a, _b;
|
|
100
|
+
return __generator(this, function (_c) {
|
|
101
|
+
switch (_c.label) {
|
|
102
|
+
case 0:
|
|
103
|
+
_a = acc;
|
|
104
|
+
_b = key;
|
|
105
|
+
return [4 /*yield*/, fbClient.variation(key, '')];
|
|
106
|
+
case 1:
|
|
107
|
+
_a[_b] = _c.sent();
|
|
108
|
+
return [2 /*return*/, acc];
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}); }, {});
|
|
112
|
+
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));
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}, []);
|
|
121
|
+
var flags = state.flags, flagKeyMap = state.flagKeyMap;
|
|
122
|
+
return React.createElement(Provider, { value: { flags: flags, flagKeyMap: flagKeyMap, fbClient: fbClient } }, children);
|
|
123
|
+
};
|
|
124
|
+
return [2 /*return*/, FbProvider];
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=asyncWithFbProvider.js.map
|
|
@@ -0,0 +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,GAAoC,MAAM,QAA1C,EAAgB,gBAAgB,GAAI,MAAM,aAAV,CAAW;oBACnD,YAAY,yBAAO,mBAAmB,GAAK,gBAAgB,CAAC,CAAC;oBAC1B,qBAAM,UAAU,CAAC,YAAY,EAAE,OAAO,CAAC,EAAA;;oBAA1E,KAAmC,SAAuC,EAAjE,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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { IFbClient } from '@featbit/js-client-sdk';
|
|
3
|
+
import { FlagKeyMap, IFlagSet } from "./types";
|
|
4
|
+
interface FbContext {
|
|
5
|
+
flags: IFlagSet;
|
|
6
|
+
/**
|
|
7
|
+
* Map of camelized flag keys to their original unmodified form. Empty if useCamelCaseFlagKeys option is false.
|
|
8
|
+
*/
|
|
9
|
+
flagKeyMap: FlagKeyMap;
|
|
10
|
+
fbClient?: IFbClient;
|
|
11
|
+
}
|
|
12
|
+
declare const context: import("react").Context<FbContext>;
|
|
13
|
+
declare const Provider: import("react").Provider<FbContext>, Consumer: import("react").Consumer<FbContext>;
|
|
14
|
+
export { Provider, Consumer, FbContext };
|
|
15
|
+
export default context;
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { createContext } from 'react';
|
|
2
|
+
var context = createContext({ flags: {}, flagKeyMap: {}, fbClient: undefined });
|
|
3
|
+
var Provider = context.Provider, Consumer = context.Consumer;
|
|
4
|
+
export { Provider, Consumer };
|
|
5
|
+
export default context;
|
|
6
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { FbReactOptions, FlagKeyMap, IFlagSet } from "./types";
|
|
2
|
+
import { IFbClient } from "@featbit/js-client-sdk";
|
|
3
|
+
export default function getFlagsProxy(fbClient: IFbClient, bootstrapFlags: IFlagSet, fetchedFlags: IFlagSet, reactOptions?: FbReactOptions): {
|
|
4
|
+
flags: IFlagSet;
|
|
5
|
+
flagKeyMap: FlagKeyMap;
|
|
6
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { defaultReactOptions } from "./types";
|
|
2
|
+
import camelCase from "lodash.camelcase";
|
|
3
|
+
export default function getFlagsProxy(fbClient, bootstrapFlags, fetchedFlags, reactOptions) {
|
|
4
|
+
if (reactOptions === void 0) { reactOptions = defaultReactOptions; }
|
|
5
|
+
var _a = reactOptions.useCamelCaseFlagKeys, useCamelCaseFlagKeys = _a === void 0 ? false : _a, _b = reactOptions.sendEventsOnFlagRead, sendEventsOnFlagRead = _b === void 0 ? true : _b;
|
|
6
|
+
var _c = useCamelCaseFlagKeys ? getCamelizedKeysAndFlagMap(fetchedFlags) : [fetchedFlags], flags = _c[0], _d = _c[1], flagKeyMap = _d === void 0 ? {} : _d;
|
|
7
|
+
return {
|
|
8
|
+
flags: toFlagsProxy(fbClient, bootstrapFlags, flags, flagKeyMap, fetchedFlags, useCamelCaseFlagKeys, sendEventsOnFlagRead),
|
|
9
|
+
flagKeyMap: flagKeyMap,
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function getCamelizedKeysAndFlagMap(rawFlags) {
|
|
13
|
+
var flags = {};
|
|
14
|
+
var flagKeyMap = {};
|
|
15
|
+
for (var rawFlagKey in rawFlags) {
|
|
16
|
+
// Exclude system keys
|
|
17
|
+
if (rawFlagKey.indexOf('$') === 0) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
var camelKey = camelCase(rawFlagKey);
|
|
21
|
+
flags[camelKey] = rawFlags[rawFlagKey];
|
|
22
|
+
flagKeyMap[camelKey] = rawFlagKey;
|
|
23
|
+
}
|
|
24
|
+
return [flags, flagKeyMap];
|
|
25
|
+
}
|
|
26
|
+
function hasFlag(flags, flagKey) {
|
|
27
|
+
return Object.prototype.hasOwnProperty.call(flags, flagKey);
|
|
28
|
+
}
|
|
29
|
+
function toFlagsProxy(fbClient, bootstrapFlags, flags, flagKeyMap, flagsWithRawFlagKeys, useCamelCaseFlagKeys, sendEventsOnFlagRead) {
|
|
30
|
+
return new Proxy(flags, {
|
|
31
|
+
get: function (target, prop, receiver) {
|
|
32
|
+
var currentValue = Reflect.get(target, prop, receiver) || flagsWithRawFlagKeys[prop];
|
|
33
|
+
// check if flag key exists as camelCase or original case
|
|
34
|
+
var validFlagKey = hasFlag(flagKeyMap, prop) || hasFlag(target, prop) || hasFlag(flagsWithRawFlagKeys, prop);
|
|
35
|
+
if (!validFlagKey && hasFlag(bootstrapFlags, prop)) {
|
|
36
|
+
return bootstrapFlags[prop];
|
|
37
|
+
}
|
|
38
|
+
// only process flag keys and ignore symbols and native Object functions
|
|
39
|
+
if (typeof prop === 'symbol' || !validFlagKey) {
|
|
40
|
+
return currentValue;
|
|
41
|
+
}
|
|
42
|
+
if (useCamelCaseFlagKeys && prop !== camelCase(prop)) {
|
|
43
|
+
console.warn("You're attempting to access a flag with its original keyId: ".concat(prop, ", even though useCamelCaseFlagKeys is set to true."));
|
|
44
|
+
}
|
|
45
|
+
if (currentValue === undefined) {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
if (!sendEventsOnFlagRead) {
|
|
49
|
+
return currentValue;
|
|
50
|
+
}
|
|
51
|
+
var pristineFlagKey = useCamelCaseFlagKeys ? (flagKeyMap[prop] || prop) : prop;
|
|
52
|
+
return fbClient.variation(pristineFlagKey, currentValue);
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=getFlagsProxy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getFlagsProxy.js","sourceRoot":"../src/","sources":["getFlagsProxy.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import asyncWithFbProvider from './asyncWithFbProvider';
|
|
2
|
+
import context from './context';
|
|
3
|
+
import FbProvider from './provider';
|
|
4
|
+
import useFlags from './useFlags';
|
|
5
|
+
import useFbClient from './useFbClient';
|
|
6
|
+
import { camelCaseKeys } from './utils';
|
|
7
|
+
import withFbConsumer from './withFbConsumer';
|
|
8
|
+
import withFbProvider from './withFbProvider';
|
|
9
|
+
export * from './types';
|
|
10
|
+
export { FbProvider, context, asyncWithFbProvider, camelCaseKeys, useFlags, useFbClient, withFbProvider, withFbConsumer };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import asyncWithFbProvider from './asyncWithFbProvider';
|
|
2
|
+
import context from './context';
|
|
3
|
+
import FbProvider from './provider';
|
|
4
|
+
import useFlags from './useFlags';
|
|
5
|
+
import useFbClient from './useFbClient';
|
|
6
|
+
import { camelCaseKeys } from './utils';
|
|
7
|
+
import withFbConsumer from './withFbConsumer';
|
|
8
|
+
import withFbProvider from './withFbProvider';
|
|
9
|
+
export * from './types';
|
|
10
|
+
export { FbProvider, context, asyncWithFbProvider, camelCaseKeys, useFlags, useFbClient, withFbProvider, withFbConsumer };
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"../src/","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,MAAM,uBAAuB,CAAC;AACxD,OAAO,OAAO,MAAM,WAAW,CAAC;AAChC,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAC9C,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAE9C,cAAc,SAAS,CAAC;AAExB,OAAO,EACL,UAAU,EACV,OAAO,EACP,mBAAmB,EACnB,aAAa,EACb,QAAQ,EACR,WAAW,EACX,cAAc,EACd,cAAc,EACf,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { AllFlagsFbClient, FbReactOptions } from './types';
|
|
2
|
+
import { IOptions } from '@featbit/js-client-sdk';
|
|
3
|
+
/**
|
|
4
|
+
* Internal function to initialize the `@featbit/js-client-sdk`.
|
|
5
|
+
*
|
|
6
|
+
* @param reactOptions Initialization options for the FeatBit React SDK
|
|
7
|
+
* @param options @featbit/js-client-sdk initialization options
|
|
8
|
+
*
|
|
9
|
+
* @see `ProviderConfig` for more details about the parameters
|
|
10
|
+
* @return An initialized client and flags
|
|
11
|
+
*/
|
|
12
|
+
export declare const initClient: (reactOptions?: FbReactOptions, options?: IOptions) => Promise<AllFlagsFbClient>;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
13
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
14
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
15
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
16
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
17
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
18
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
22
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
23
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
24
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
25
|
+
function step(op) {
|
|
26
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
27
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
28
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
29
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
30
|
+
switch (op[0]) {
|
|
31
|
+
case 0: case 1: t = op; break;
|
|
32
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
33
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
34
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
35
|
+
default:
|
|
36
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
37
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
38
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
39
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
40
|
+
if (t[2]) _.ops.pop();
|
|
41
|
+
_.trys.pop(); continue;
|
|
42
|
+
}
|
|
43
|
+
op = body.call(thisArg, _);
|
|
44
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
45
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
import { defaultReactOptions } from './types';
|
|
49
|
+
import { FbClientBuilder } from '@featbit/js-client-sdk';
|
|
50
|
+
import { fetchFlags } from "./utils";
|
|
51
|
+
/**
|
|
52
|
+
* Internal function to initialize the `@featbit/js-client-sdk`.
|
|
53
|
+
*
|
|
54
|
+
* @param reactOptions Initialization options for the FeatBit React SDK
|
|
55
|
+
* @param options @featbit/js-client-sdk initialization options
|
|
56
|
+
*
|
|
57
|
+
* @see `ProviderConfig` for more details about the parameters
|
|
58
|
+
* @return An initialized client and flags
|
|
59
|
+
*/
|
|
60
|
+
export var initClient = function (reactOptions, options) {
|
|
61
|
+
if (reactOptions === void 0) { reactOptions = defaultReactOptions; }
|
|
62
|
+
if (options === void 0) { options = {}; }
|
|
63
|
+
return __awaiter(void 0, void 0, void 0, function () {
|
|
64
|
+
var fbClient;
|
|
65
|
+
return __generator(this, function (_a) {
|
|
66
|
+
fbClient = new FbClientBuilder(__assign({}, options)).build();
|
|
67
|
+
return [2 /*return*/, new Promise(function (resolve) {
|
|
68
|
+
fbClient.on('ready', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
69
|
+
var flags;
|
|
70
|
+
return __generator(this, function (_a) {
|
|
71
|
+
switch (_a.label) {
|
|
72
|
+
case 0: return [4 /*yield*/, fetchFlags(fbClient)];
|
|
73
|
+
case 1:
|
|
74
|
+
flags = _a.sent();
|
|
75
|
+
resolve({ flags: flags, fbClient: fbClient });
|
|
76
|
+
return [2 /*return*/];
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}); });
|
|
80
|
+
})];
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
//# sourceMappingURL=initClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initClient.js","sourceRoot":"../src/","sources":["initClient.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,EAAoB,mBAAmB,EAAkB,MAAM,SAAS,CAAC;AAChF,OAAO,EAAE,eAAe,EAAY,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC;;;;;;;;GAQG;AACH,MAAM,CAAC,IAAM,UAAU,GAAG,UACxB,YAAkD,EAClD,OAAsB;IADtB,6BAAA,EAAA,kCAAkD;IAClD,wBAAA,EAAA,YAAsB;;;;YAEhB,QAAQ,GAAG,IAAI,eAAe,cAAK,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC;YAE3D,sBAAO,IAAI,OAAO,CAAmB,UAAC,OAAO;oBAC3C,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE;;;;wCACL,qBAAM,UAAU,CAAC,QAAQ,CAAC,EAAA;;oCAAlC,KAAK,GAAG,SAA0B;oCACxC,OAAO,CAAC,EAAC,KAAK,OAAA,EAAE,QAAQ,UAAA,EAAC,CAAC,CAAC;;;;yBAC5B,CAAC,CAAC;gBACL,CAAC,CAAC,EAAC;;;CACJ,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { EnhancedComponent, ProviderConfig, IFlagSet } from './types';
|
|
3
|
+
import { FbContext } from './context';
|
|
4
|
+
import { IFbClient } from '@featbit/js-client-sdk';
|
|
5
|
+
interface FbHocState extends FbContext {
|
|
6
|
+
unproxiedFlags: IFlagSet;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The `FbProvider` is a component which accepts a config object which is used to
|
|
10
|
+
* initialize `@featbit/js-client-sdk`.
|
|
11
|
+
*
|
|
12
|
+
* This Provider does three things:
|
|
13
|
+
* - It initializes the FeatBit instance by calling `@featbit/js-client-sdk` init on `componentDidMount`
|
|
14
|
+
* - It saves all flags and the FeatBit instance in the context API
|
|
15
|
+
* - It subscribes to flag changes and propagate them through the context API
|
|
16
|
+
*
|
|
17
|
+
* Because the `@featbit/js-client-sdk` is only initialized on `componentDidMount`, your flags and the
|
|
18
|
+
* FeatBit are only available after your app has mounted. This can result in a flicker due to flag changes at
|
|
19
|
+
* startup time.
|
|
20
|
+
*
|
|
21
|
+
* This component can be used as a standalone provider. However, be mindful to only include the component once
|
|
22
|
+
* within your application. This provider is used inside the `withFbProviderHOC` and can be used instead to initialize
|
|
23
|
+
* the `@featbit/js-client-sdk`. For async initialization, check out the `asyncWithFbProvider` function
|
|
24
|
+
*/
|
|
25
|
+
declare class FbProvider extends React.Component<ProviderConfig, FbHocState> implements EnhancedComponent {
|
|
26
|
+
readonly state: Readonly<FbHocState>;
|
|
27
|
+
bootstrapFlags: IFlagSet;
|
|
28
|
+
constructor(props: ProviderConfig);
|
|
29
|
+
getReactOptions: () => {
|
|
30
|
+
useCamelCaseFlagKeys: boolean;
|
|
31
|
+
sendEventsOnFlagRead: boolean;
|
|
32
|
+
};
|
|
33
|
+
subscribeToChanges: (fbClient: IFbClient) => void;
|
|
34
|
+
init: () => Promise<void>;
|
|
35
|
+
componentDidMount(): Promise<void>;
|
|
36
|
+
componentDidUpdate(prevProps: ProviderConfig): Promise<void>;
|
|
37
|
+
render(): React.JSX.Element | null;
|
|
38
|
+
}
|
|
39
|
+
export default FbProvider;
|
package/dist/provider.js
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
var __extends = (this && this.__extends) || (function () {
|
|
2
|
+
var extendStatics = function (d, b) {
|
|
3
|
+
extendStatics = Object.setPrototypeOf ||
|
|
4
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
5
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
6
|
+
return extendStatics(d, b);
|
|
7
|
+
};
|
|
8
|
+
return function (d, b) {
|
|
9
|
+
if (typeof b !== "function" && b !== null)
|
|
10
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
11
|
+
extendStatics(d, b);
|
|
12
|
+
function __() { this.constructor = d; }
|
|
13
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
14
|
+
};
|
|
15
|
+
})();
|
|
16
|
+
var __assign = (this && this.__assign) || function () {
|
|
17
|
+
__assign = Object.assign || function(t) {
|
|
18
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
19
|
+
s = arguments[i];
|
|
20
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
21
|
+
t[p] = s[p];
|
|
22
|
+
}
|
|
23
|
+
return t;
|
|
24
|
+
};
|
|
25
|
+
return __assign.apply(this, arguments);
|
|
26
|
+
};
|
|
27
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
28
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
29
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
30
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
31
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
32
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
33
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
37
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
38
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
39
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
40
|
+
function step(op) {
|
|
41
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
42
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
43
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
44
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
45
|
+
switch (op[0]) {
|
|
46
|
+
case 0: case 1: t = op; break;
|
|
47
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
48
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
49
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
50
|
+
default:
|
|
51
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
52
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
53
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
54
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
55
|
+
if (t[2]) _.ops.pop();
|
|
56
|
+
_.trys.pop(); continue;
|
|
57
|
+
}
|
|
58
|
+
op = body.call(thisArg, _);
|
|
59
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
60
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
import React from "react";
|
|
64
|
+
import { defaultReactOptions } from './types';
|
|
65
|
+
import { Provider } from './context';
|
|
66
|
+
import { camelCaseKeys, fetchFlags } from "./utils";
|
|
67
|
+
import { initClient } from './initClient';
|
|
68
|
+
import getFlagsProxy from "./getFlagsProxy";
|
|
69
|
+
/**
|
|
70
|
+
* The `FbProvider` is a component which accepts a config object which is used to
|
|
71
|
+
* initialize `@featbit/js-client-sdk`.
|
|
72
|
+
*
|
|
73
|
+
* This Provider does three things:
|
|
74
|
+
* - It initializes the FeatBit instance by calling `@featbit/js-client-sdk` init on `componentDidMount`
|
|
75
|
+
* - It saves all flags and the FeatBit instance in the context API
|
|
76
|
+
* - It subscribes to flag changes and propagate them through the context API
|
|
77
|
+
*
|
|
78
|
+
* Because the `@featbit/js-client-sdk` is only initialized on `componentDidMount`, your flags and the
|
|
79
|
+
* FeatBit are only available after your app has mounted. This can result in a flicker due to flag changes at
|
|
80
|
+
* startup time.
|
|
81
|
+
*
|
|
82
|
+
* This component can be used as a standalone provider. However, be mindful to only include the component once
|
|
83
|
+
* within your application. This provider is used inside the `withFbProviderHOC` and can be used instead to initialize
|
|
84
|
+
* the `@featbit/js-client-sdk`. For async initialization, check out the `asyncWithFbProvider` function
|
|
85
|
+
*/
|
|
86
|
+
var FbProvider = /** @class */ (function (_super) {
|
|
87
|
+
__extends(FbProvider, _super);
|
|
88
|
+
function FbProvider(props) {
|
|
89
|
+
var _this = _super.call(this, props) || this;
|
|
90
|
+
_this.getReactOptions = function () { return (__assign(__assign({}, defaultReactOptions), _this.props.reactOptions)); };
|
|
91
|
+
_this.subscribeToChanges = function (fbClient) {
|
|
92
|
+
fbClient.on('update', function (changedKeys) {
|
|
93
|
+
var updates = changedKeys.reduce(function (acc, key) {
|
|
94
|
+
acc[key] = fbClient.variation(key, '');
|
|
95
|
+
return acc;
|
|
96
|
+
}, {});
|
|
97
|
+
var unproxiedFlags = __assign(__assign({}, _this.state.unproxiedFlags), updates);
|
|
98
|
+
if (Object.keys(updates).length > 0) {
|
|
99
|
+
_this.setState(__assign({ unproxiedFlags: unproxiedFlags }, getFlagsProxy(fbClient, _this.bootstrapFlags, unproxiedFlags, _this.getReactOptions())));
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
_this.init = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
104
|
+
var options, client, reactOptions, unproxiedFlags, initialisedOutput;
|
|
105
|
+
return __generator(this, function (_a) {
|
|
106
|
+
switch (_a.label) {
|
|
107
|
+
case 0:
|
|
108
|
+
options = this.props.options;
|
|
109
|
+
client = this.props.fbClient;
|
|
110
|
+
reactOptions = this.getReactOptions();
|
|
111
|
+
if (!client) return [3 /*break*/, 2];
|
|
112
|
+
return [4 /*yield*/, fetchFlags(client)];
|
|
113
|
+
case 1:
|
|
114
|
+
unproxiedFlags = _a.sent();
|
|
115
|
+
return [3 /*break*/, 4];
|
|
116
|
+
case 2: return [4 /*yield*/, initClient(reactOptions, options)];
|
|
117
|
+
case 3:
|
|
118
|
+
initialisedOutput = _a.sent();
|
|
119
|
+
unproxiedFlags = initialisedOutput.flags;
|
|
120
|
+
client = initialisedOutput.fbClient;
|
|
121
|
+
_a.label = 4;
|
|
122
|
+
case 4:
|
|
123
|
+
this.setState(__assign(__assign({ unproxiedFlags: unproxiedFlags }, getFlagsProxy(client, this.bootstrapFlags, unproxiedFlags, reactOptions)), { fbClient: client }));
|
|
124
|
+
this.subscribeToChanges(client);
|
|
125
|
+
return [2 /*return*/];
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
}); };
|
|
129
|
+
var options = props.options;
|
|
130
|
+
_this.bootstrapFlags = ((options === null || options === void 0 ? void 0 : options.bootstrap) || []).reduce(function (acc, flag) {
|
|
131
|
+
acc[flag.id] = flag.variation;
|
|
132
|
+
return acc;
|
|
133
|
+
}, {});
|
|
134
|
+
;
|
|
135
|
+
_this.state = {
|
|
136
|
+
flags: {},
|
|
137
|
+
unproxiedFlags: {},
|
|
138
|
+
flagKeyMap: {},
|
|
139
|
+
fbClient: undefined,
|
|
140
|
+
};
|
|
141
|
+
if ((options === null || options === void 0 ? void 0 : options.bootstrap) && (options === null || options === void 0 ? void 0 : options.bootstrap.length) > 0) {
|
|
142
|
+
var useCamelCaseFlagKeys = _this.getReactOptions().useCamelCaseFlagKeys;
|
|
143
|
+
var flags = useCamelCaseFlagKeys ? camelCaseKeys(_this.bootstrapFlags) : _this.bootstrapFlags;
|
|
144
|
+
_this.state = {
|
|
145
|
+
flags: flags,
|
|
146
|
+
unproxiedFlags: flags,
|
|
147
|
+
flagKeyMap: {},
|
|
148
|
+
fbClient: undefined,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
return _this;
|
|
152
|
+
}
|
|
153
|
+
FbProvider.prototype.componentDidMount = function () {
|
|
154
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
155
|
+
var _a, options, deferInitialization;
|
|
156
|
+
return __generator(this, function (_b) {
|
|
157
|
+
switch (_b.label) {
|
|
158
|
+
case 0:
|
|
159
|
+
_a = this.props, options = _a.options, deferInitialization = _a.deferInitialization;
|
|
160
|
+
if (deferInitialization && !options) {
|
|
161
|
+
return [2 /*return*/];
|
|
162
|
+
}
|
|
163
|
+
return [4 /*yield*/, this.init()];
|
|
164
|
+
case 1:
|
|
165
|
+
_b.sent();
|
|
166
|
+
return [2 /*return*/];
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
};
|
|
171
|
+
FbProvider.prototype.componentDidUpdate = function (prevProps) {
|
|
172
|
+
var _a;
|
|
173
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
174
|
+
var _b, options, deferInitialization, userJustLoaded;
|
|
175
|
+
return __generator(this, function (_c) {
|
|
176
|
+
switch (_c.label) {
|
|
177
|
+
case 0:
|
|
178
|
+
_b = this.props, options = _b.options, deferInitialization = _b.deferInitialization;
|
|
179
|
+
userJustLoaded = !((_a = prevProps.options) === null || _a === void 0 ? void 0 : _a.user) && (options === null || options === void 0 ? void 0 : options.user);
|
|
180
|
+
if (!(deferInitialization && userJustLoaded)) return [3 /*break*/, 2];
|
|
181
|
+
return [4 /*yield*/, this.init()];
|
|
182
|
+
case 1:
|
|
183
|
+
_c.sent();
|
|
184
|
+
_c.label = 2;
|
|
185
|
+
case 2: return [2 /*return*/];
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
};
|
|
190
|
+
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);
|
|
197
|
+
};
|
|
198
|
+
return FbProvider;
|
|
199
|
+
}(React.Component));
|
|
200
|
+
export default FbProvider;
|
|
201
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"../src/","sources":["provider.tsx"],"names":[],"mappings":"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"}
|