@flagship.io/react-sdk 3.0.4 → 3.0.6

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,14 +1,27 @@
1
- <p align="center">
2
- <img src="https://mk0abtastybwtpirqi5t.kinstacdn.com/wp-content/uploads/picture-solutions-persona-product-flagship.jpg" width="211" height="182" alt="flagship-java" />
3
- </p>
4
- <h3 align="center">Bring your features to life</h3>
1
+ [![Code coverage](https://github.com/flagship-io/flagship-react-sdk/actions/workflows/workflow.yml/badge.svg)](https://github.com/flagship-io/flagship-react-sdk/actions/workflows/workflow.yml) [![npm version](https://badge.fury.io/js/@flagship.io%2Freact-sdk.svg)](https://badge.fury.io/js/@flagship.io%2Freact-sdk)
5
2
 
6
- **Visit [https://developers.flagship.io/](https://developers.flagship.io/) to get started with Flagship.**
3
+ ## About Flagship
7
4
 
8
- ## Docs
5
+
6
+ <img src="https://www.flagship.io/wp-content/uploads/Flagship-horizontal-black-wake-AB.png" alt="drawing" width="150"/>
7
+
8
+ [Flagship by AB Tasty](https://www.flagship.io/) is a feature flagging platform for modern engineering and product teams. It eliminates the risks of future releases by separating code deployments from these releases :bulb: With Flagship, you have full control over the release process. You can:
9
+
9
10
 
10
- - [docs](https://docs.developers.flagship.io/docs/react-v3-0-x)
11
-
12
- ## Licence
13
-
14
- [Apache License.](https://github.com/flagship-io/flagship-react-sdk/blob/master/LICENSE)
11
+ - Switch features on or off through remote config.
12
+ - Automatically roll-out your features gradually to monitor performance and gather feedback from your most relevant users.
13
+ - Roll back any feature should any issues arise while testing in production.
14
+ - Segment users by granting access to a feature based on certain user attributes.
15
+ - Carry out A/B tests by easily assigning feature variations to groups of users.
16
+
17
+ <img src="https://www.flagship.io/wp-content/uploads/demo-setup.png" alt="drawing" width="600"/>
18
+
19
+ Flagship also allows you to choose whatever implementation method works for you from our many available SDKs or directly through a REST API. Additionally, our architecture is based on multi-cloud providers that offer high performance and highly-scalable managed services.
20
+
21
+ **To learn more:**
22
+
23
+ - [Solution overview](https://www.flagship.io/#showvideo) - A 5mn video demo :movie_camera:
24
+ - [Documentation](https://docs.developers.flagship.io/) - Our dev portal with guides, how tos, API and SDK references
25
+ - [Sign up for a free trial](https://www.flagship.io/sign-up/) - Create your free account
26
+ - [Guide to feature flagging](https://www.flagship.io/feature-flags/) - Everyhting you need to know about feature flag related use cases
27
+ - [Blog](https://www.flagship.io/blog/) - Additional resources about release management
File without changes
package/dist/Flag.js ADDED
@@ -0,0 +1,66 @@
1
+ import Flagship, { FlagMetadata } from '@flagship.io/js-sdk';
2
+ import { GET_FLAG_CAST_ERROR, GET_METADATA_CAST_ERROR, noVisitorMessage } from './constants';
3
+ import { hasSameType, logInfo, logWarn, sprintf } from './utils';
4
+ var Flag = /** @class */ (function () {
5
+ function Flag(defaultValue, key, flagsData) {
6
+ if (!flagsData) {
7
+ logWarn(Flagship.getConfig(), noVisitorMessage, 'GetFlag');
8
+ }
9
+ this.defaultValue = defaultValue;
10
+ this.key = key;
11
+ this.flag = flagsData === null || flagsData === void 0 ? void 0 : flagsData.get(key);
12
+ }
13
+ Flag.prototype.NotSameType = function () {
14
+ var _a;
15
+ return this.defaultValue !== null && this.defaultValue !== undefined && !hasSameType((_a = this.flag) === null || _a === void 0 ? void 0 : _a.value, this.defaultValue);
16
+ };
17
+ Flag.prototype.getValue = function () {
18
+ if (!this.flag) {
19
+ logWarn(Flagship.getConfig(), noVisitorMessage, 'getValue');
20
+ return this.defaultValue;
21
+ }
22
+ if (this.NotSameType()) {
23
+ logInfo(Flagship.getConfig(), sprintf(GET_FLAG_CAST_ERROR, this.key), "getValue");
24
+ return this.defaultValue;
25
+ }
26
+ return this.flag.value;
27
+ };
28
+ Flag.prototype.exists = function () {
29
+ if (!this.flag) {
30
+ logWarn(Flagship.getConfig(), noVisitorMessage, 'exists');
31
+ return false;
32
+ }
33
+ return !!(this.flag.campaignId && this.flag.variationId && this.flag.variationGroupId);
34
+ };
35
+ Flag.prototype.userExposed = function () {
36
+ if (!this.flag) {
37
+ logWarn(Flagship.getConfig(), noVisitorMessage, 'userExposed');
38
+ }
39
+ return Promise.resolve();
40
+ };
41
+ Object.defineProperty(Flag.prototype, "metadata", {
42
+ get: function () {
43
+ var functionName = 'metadata';
44
+ if (!this.flag) {
45
+ logWarn(Flagship.getConfig(), noVisitorMessage, functionName);
46
+ return FlagMetadata.Empty();
47
+ }
48
+ if (this.NotSameType()) {
49
+ logInfo(Flagship.getConfig(), sprintf(GET_METADATA_CAST_ERROR, this.key), functionName);
50
+ return FlagMetadata.Empty();
51
+ }
52
+ return new FlagMetadata({
53
+ campaignId: this.flag.campaignId,
54
+ variationGroupId: this.flag.variationGroupId,
55
+ variationId: this.flag.variationId,
56
+ isReference: !!this.flag.isReference,
57
+ campaignType: this.flag.campaignType,
58
+ slug: this.flag.slug
59
+ });
60
+ },
61
+ enumerable: false,
62
+ configurable: true
63
+ });
64
+ return Flag;
65
+ }());
66
+ export { Flag };
@@ -0,0 +1,181 @@
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
+ // eslint-disable-next-line no-use-before-define
13
+ import React, { useState, useEffect, createContext, useRef, } from "react";
14
+ import { Flagship, FlagshipStatus, } from "@flagship.io/js-sdk";
15
+ import { getModificationsFromCampaigns, logError, useNonInitialEffect, } from "./utils";
16
+ var initStat = {
17
+ status: { isLoading: true, isSdkReady: false },
18
+ };
19
+ export var FlagshipContext = createContext({
20
+ state: __assign({}, initStat),
21
+ });
22
+ export var FlagshipProvider = function (_a) {
23
+ var children = _a.children, fetchNow = _a.fetchNow, envId = _a.envId, apiKey = _a.apiKey, decisionMode = _a.decisionMode, decisionApiUrl = _a.decisionApiUrl, timeout = _a.timeout, logLevel = _a.logLevel, statusChangedCallback = _a.statusChangedCallback, logManager = _a.logManager, pollingInterval = _a.pollingInterval, visitorData = _a.visitorData, onInitStart = _a.onInitStart, onInitDone = _a.onInitDone, onBucketingSuccess = _a.onBucketingSuccess, onBucketingFail = _a.onBucketingFail, loadingComponent = _a.loadingComponent, onBucketingUpdated = _a.onBucketingUpdated, onUpdate = _a.onUpdate, enableClientCache = _a.enableClientCache, initialBucketing = _a.initialBucketing, initialCampaigns = _a.initialCampaigns, initialModifications = _a.initialModifications, initialFlagsData = _a.initialFlagsData, fetchFlagsOnBucketingUpdated = _a.fetchFlagsOnBucketingUpdated, activateDeduplicationTime = _a.activateDeduplicationTime, hitDeduplicationTime = _a.hitDeduplicationTime, visitorCacheImplementation = _a.visitorCacheImplementation, hitCacheImplementation = _a.hitCacheImplementation, disableCache = _a.disableCache, language = _a.language;
24
+ var modifications = new Map();
25
+ if (initialFlagsData && initialFlagsData.forEach) {
26
+ initialFlagsData.forEach(function (flag) {
27
+ modifications.set(flag.key, flag);
28
+ });
29
+ }
30
+ else if (initialModifications && initialModifications.forEach) {
31
+ initialModifications.forEach(function (modification) {
32
+ modifications.set(modification.key, modification);
33
+ });
34
+ }
35
+ else if (initialCampaigns) {
36
+ modifications = getModificationsFromCampaigns(initialCampaigns);
37
+ }
38
+ var _b = useState(__assign(__assign({}, initStat), { modifications: modifications })), state = _b[0], setState = _b[1];
39
+ var _c = useState(), lastModified = _c[0], setLastModified = _c[1];
40
+ var stateRef = useRef();
41
+ stateRef.current = state;
42
+ useNonInitialEffect(function () {
43
+ var _a;
44
+ if (fetchFlagsOnBucketingUpdated) {
45
+ (_a = state.visitor) === null || _a === void 0 ? void 0 : _a.fetchFlags();
46
+ }
47
+ }, [lastModified]);
48
+ useNonInitialEffect(function () {
49
+ createVisitor(true);
50
+ }, [JSON.stringify(visitorData)]);
51
+ useEffect(function () {
52
+ initSdk();
53
+ }, [envId, apiKey, decisionMode]);
54
+ function initializeState(param) {
55
+ var newStatus = {
56
+ isSdkReady: param.isSdkReady,
57
+ isLoading: param.isLoading,
58
+ isVisitorDefined: !!param.fsVisitor,
59
+ lastRefresh: new Date().toISOString(),
60
+ };
61
+ setState(function (currentState) {
62
+ if (!currentState.status.firstInitSuccess) {
63
+ newStatus.firstInitSuccess = new Date().toISOString();
64
+ }
65
+ return __assign(__assign({}, currentState), { visitor: param.fsVisitor, modifications: param.fsVisitor.modifications, config: Flagship.getConfig(), status: __assign(__assign({}, currentState.status), newStatus) });
66
+ });
67
+ return newStatus;
68
+ }
69
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
70
+ var onVisitorReady = function (fsVisitor, error) {
71
+ if (error) {
72
+ logError(Flagship.getConfig(), error.message || error, "onReady");
73
+ return;
74
+ }
75
+ var newStatus = initializeState({
76
+ fsVisitor: fsVisitor,
77
+ isSdkReady: true,
78
+ isLoading: false,
79
+ });
80
+ if (onUpdate) {
81
+ onUpdate({
82
+ fsModifications: fsVisitor.modifications,
83
+ config: Flagship.getConfig(),
84
+ status: newStatus,
85
+ });
86
+ }
87
+ };
88
+ var createVisitor = function (fetchFlags) {
89
+ if (fetchFlags === void 0) { fetchFlags = false; }
90
+ if (!visitorData) {
91
+ return;
92
+ }
93
+ var fsVisitor = Flagship.newVisitor({
94
+ visitorId: visitorData.id,
95
+ context: visitorData.context,
96
+ isAuthenticated: visitorData.isAuthenticated,
97
+ hasConsented: visitorData.hasConsented,
98
+ initialCampaigns: initialCampaigns,
99
+ initialModifications: initialModifications,
100
+ initialFlagsData: initialFlagsData,
101
+ });
102
+ fsVisitor === null || fsVisitor === void 0 ? void 0 : fsVisitor.on("ready", function (error) {
103
+ onVisitorReady(fsVisitor, error);
104
+ });
105
+ if (!fetchNow && fsVisitor && !fetchFlags) {
106
+ initializeState({
107
+ fsVisitor: fsVisitor,
108
+ isSdkReady: true,
109
+ isLoading: false,
110
+ });
111
+ }
112
+ if (fetchFlags && !fetchNow) {
113
+ fsVisitor === null || fsVisitor === void 0 ? void 0 : fsVisitor.fetchFlags();
114
+ }
115
+ };
116
+ var statusChanged = function (status) {
117
+ if (statusChangedCallback) {
118
+ statusChangedCallback(status);
119
+ }
120
+ switch (status) {
121
+ case FlagshipStatus.STARTING:
122
+ if (status === FlagshipStatus.STARTING && onInitStart) {
123
+ onInitStart();
124
+ }
125
+ break;
126
+ case FlagshipStatus.READY_PANIC_ON:
127
+ case FlagshipStatus.READY:
128
+ if (onInitDone) {
129
+ onInitDone();
130
+ }
131
+ createVisitor();
132
+ break;
133
+ case FlagshipStatus.NOT_INITIALIZED:
134
+ setState(function (prev) { return (__assign(__assign({}, prev), { config: Flagship.getConfig() })); });
135
+ break;
136
+ }
137
+ };
138
+ var onBucketingLastModified = function (lastUpdate) {
139
+ if (onBucketingUpdated) {
140
+ onBucketingUpdated(lastUpdate);
141
+ }
142
+ setLastModified(lastUpdate);
143
+ };
144
+ var initSdk = function () {
145
+ Flagship.start(envId, apiKey, {
146
+ decisionMode: decisionMode,
147
+ fetchNow: fetchNow,
148
+ timeout: timeout,
149
+ logLevel: logLevel,
150
+ statusChangedCallback: statusChanged,
151
+ logManager: logManager,
152
+ pollingInterval: pollingInterval,
153
+ onBucketingFail: onBucketingFail,
154
+ onBucketingSuccess: onBucketingSuccess,
155
+ enableClientCache: enableClientCache,
156
+ decisionApiUrl: decisionApiUrl,
157
+ onBucketingUpdated: onBucketingLastModified,
158
+ initialBucketing: initialBucketing,
159
+ activateDeduplicationTime: activateDeduplicationTime,
160
+ hitDeduplicationTime: hitDeduplicationTime,
161
+ visitorCacheImplementation: visitorCacheImplementation,
162
+ hitCacheImplementation: hitCacheImplementation,
163
+ disableCache: disableCache,
164
+ language: language,
165
+ });
166
+ };
167
+ var handleDisplay = function () {
168
+ var isFirstInit = !state.visitor;
169
+ if (state.status.isLoading && loadingComponent && isFirstInit && fetchNow) {
170
+ return React.createElement(React.Fragment, null, loadingComponent);
171
+ }
172
+ return React.createElement(React.Fragment, null, children);
173
+ };
174
+ return (React.createElement(FlagshipContext.Provider, { value: { state: state, setState: setState } }, handleDisplay()));
175
+ };
176
+ FlagshipProvider.defaultProps = {
177
+ activateDeduplicationTime: 2,
178
+ hitDeduplicationTime: 2,
179
+ fetchNow: true,
180
+ language: 1,
181
+ };
@@ -2,12 +2,12 @@ import { FlagDTO, HitAbstract, HitShape, IFlag, IHit, Modification, modification
2
2
  import { FsStatus } from './FlagshipContext';
3
3
  /**
4
4
  * Retrieve a modification value by its key. If no modification match the given key or if the stored value type and default value type do not match, default value will be returned.
5
- * @deprecated use useFsGetFlag instead
5
+ * @deprecated use useFsFlag instead
6
6
  */
7
7
  export declare const useFsModifications: <T extends unknown>(params: modificationsRequested<T>[], activateAll?: boolean | undefined) => Record<string, T>;
8
8
  /**
9
9
  * Retrieve a modification value by its key. If no modification match the given key or if the stored value type and default value type do not match, default value will be returned.
10
- * @deprecated use useFsGetFlag instead
10
+ * @deprecated use useFsFlag instead
11
11
  */
12
12
  export declare const useFsModification: {
13
13
  <T>(params: modificationsRequested<T>): T;
@@ -15,7 +15,7 @@ export declare const useFsModification: {
15
15
  /**
16
16
  * Get the campaign modification information value matching the given key.
17
17
  * @param {string} key key which identify the modification.
18
- * @deprecated use useFsGetFlag instead
18
+ * @deprecated use useFsFlag instead
19
19
  */
20
20
  export declare const useFsModificationInfo: {
21
21
  (key: string): Modification | null;
@@ -30,7 +30,7 @@ export declare const useFsFlag: <T extends unknown>(key: string, defaultValue: T
30
30
  /**
31
31
  * Report this user has seen this modification. Report this user has seen these modifications.
32
32
  * @param params
33
- * @deprecated use useFsGetFlag instead
33
+ * @deprecated use useFsFlag instead
34
34
  * @returns
35
35
  */
36
36
  export declare const useFsActivate: {
@@ -56,27 +56,27 @@ export declare type UseFlagshipOutput = {
56
56
  */
57
57
  setConsent: (hasConsented: boolean) => void;
58
58
  modifications: Modification[];
59
- FlagsData: FlagDTO[];
59
+ flagsData: FlagDTO[];
60
60
  status: FsStatus;
61
61
  /**
62
62
  *
63
63
  * @param params
64
64
  * @param activateAll
65
- * @deprecated use useFsGetFlag instead
65
+ * @deprecated use getFlag instead
66
66
  */
67
67
  getModifications<T>(params: modificationsRequested<T>[], activateAll?: boolean): Record<string, T>;
68
68
  /**
69
69
  *
70
70
  * @param key
71
- * @deprecated use useFsGetFlag instead
71
+ * @deprecated use getFlag instead
72
72
  */
73
73
  getModificationInfo(key: string): Modification | null;
74
74
  /**
75
- * @deprecated use useFsFetchFlags instead
75
+ * @deprecated use fetchFlags instead
76
76
  */
77
77
  synchronizeModifications(): Promise<void>;
78
78
  /**
79
- * @deprecated use useFsGetFlag instead
79
+ * @deprecated use getFlag instead
80
80
  */
81
81
  activateModification: {
82
82
  (keys: {