@flagship.io/react-sdk 3.0.5 → 3.0.7-alpha.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/README.md +27 -25
- package/dist/{types/Flag.d.ts → Flag.d.ts} +0 -0
- package/dist/Flag.js +60 -0
- package/dist/{types/FlagshipContext.d.ts → FlagshipContext.d.ts} +2 -2
- package/dist/FlagshipContext.js +168 -0
- package/dist/{types/FlagshipHooks.d.ts → FlagshipHooks.d.ts} +0 -0
- package/dist/FlagshipHooks.js +278 -0
- package/dist/{types/constants.d.ts → constants.d.ts} +0 -0
- package/dist/constants.js +4 -0
- package/dist/index.browser.js +18878 -1
- package/dist/index.browser.js.map +1 -1
- package/dist/{types/index.d.ts → index.d.ts} +0 -0
- package/dist/index.js +3 -2
- package/dist/index.node.js +1532 -0
- package/dist/index.node.js.map +1 -0
- package/dist/{types/utils.d.ts → utils.d.ts} +0 -0
- package/dist/utils.js +91 -0
- package/package.json +100 -98
- package/dist/esm/Flag.js +0 -105
- package/dist/esm/FlagshipContext.js +0 -269
- package/dist/esm/FlagshipHooks.js +0 -474
- package/dist/esm/constants.js +0 -4
- package/dist/esm/index.js +0 -3
- package/dist/esm/utils.js +0 -90
- package/dist/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,25 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- [
|
|
24
|
-
- [
|
|
25
|
-
- [
|
|
1
|
+
[](https://github.com/flagship-io/flagship-react-sdk/actions/workflows/workflow.yml) [](https://badge.fury.io/js/@flagship.io%2Freact-sdk)
|
|
2
|
+
|
|
3
|
+
## About Flagship
|
|
4
|
+
|
|
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
|
+
|
|
10
|
+
|
|
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,60 @@
|
|
|
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
|
+
export class Flag {
|
|
5
|
+
constructor(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
|
+
NotSameType() {
|
|
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
|
+
getValue() {
|
|
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
|
+
exists() {
|
|
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
|
+
userExposed() {
|
|
36
|
+
if (!this.flag) {
|
|
37
|
+
logWarn(Flagship.getConfig(), noVisitorMessage, 'userExposed');
|
|
38
|
+
}
|
|
39
|
+
return Promise.resolve();
|
|
40
|
+
}
|
|
41
|
+
get metadata() {
|
|
42
|
+
const functionName = 'metadata';
|
|
43
|
+
if (!this.flag) {
|
|
44
|
+
logWarn(Flagship.getConfig(), noVisitorMessage, functionName);
|
|
45
|
+
return FlagMetadata.Empty();
|
|
46
|
+
}
|
|
47
|
+
if (this.NotSameType()) {
|
|
48
|
+
logInfo(Flagship.getConfig(), sprintf(GET_METADATA_CAST_ERROR, this.key), functionName);
|
|
49
|
+
return FlagMetadata.Empty();
|
|
50
|
+
}
|
|
51
|
+
return new FlagMetadata({
|
|
52
|
+
campaignId: this.flag.campaignId,
|
|
53
|
+
variationGroupId: this.flag.variationGroupId,
|
|
54
|
+
variationId: this.flag.variationId,
|
|
55
|
+
isReference: !!this.flag.isReference,
|
|
56
|
+
campaignType: this.flag.campaignType,
|
|
57
|
+
slug: this.flag.slug
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import React, { ReactNode, Dispatch, SetStateAction } from
|
|
2
|
-
import { BucketingDTO, CampaignDTO, FlagDTO, IFlagshipConfig, primitive, Visitor } from
|
|
1
|
+
import React, { ReactNode, Dispatch, SetStateAction } from 'react';
|
|
2
|
+
import { BucketingDTO, CampaignDTO, FlagDTO, IFlagshipConfig, primitive, Visitor } from '@flagship.io/js-sdk';
|
|
3
3
|
export interface FsStatus {
|
|
4
4
|
/**
|
|
5
5
|
* Boolean. When true, the SDK is still not ready to render your App otherwise it'll use default modifications.
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// eslint-disable-next-line no-use-before-define
|
|
2
|
+
import React, { useState, useEffect, createContext, useRef } from 'react';
|
|
3
|
+
import { Flagship, FlagshipStatus } from '@flagship.io/js-sdk';
|
|
4
|
+
import { getModificationsFromCampaigns, logError, useNonInitialEffect } from './utils';
|
|
5
|
+
const initStat = {
|
|
6
|
+
status: { isLoading: true, isSdkReady: false }
|
|
7
|
+
};
|
|
8
|
+
export const FlagshipContext = createContext({
|
|
9
|
+
state: Object.assign({}, initStat)
|
|
10
|
+
});
|
|
11
|
+
export const FlagshipProvider = ({ children, fetchNow, envId, apiKey, decisionMode, decisionApiUrl, timeout, logLevel, statusChangedCallback, logManager, pollingInterval, visitorData, onInitStart, onInitDone, onBucketingSuccess, onBucketingFail, loadingComponent, onBucketingUpdated, onUpdate, enableClientCache, initialBucketing, initialCampaigns, initialModifications, initialFlagsData, fetchFlagsOnBucketingUpdated, activateDeduplicationTime, hitDeduplicationTime, visitorCacheImplementation, hitCacheImplementation, disableCache, language }) => {
|
|
12
|
+
let modifications = new Map();
|
|
13
|
+
if (initialFlagsData && initialFlagsData.forEach) {
|
|
14
|
+
initialFlagsData.forEach((flag) => {
|
|
15
|
+
modifications.set(flag.key, flag);
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
else if (initialModifications && initialModifications.forEach) {
|
|
19
|
+
initialModifications.forEach((modification) => {
|
|
20
|
+
modifications.set(modification.key, modification);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
else if (initialCampaigns) {
|
|
24
|
+
modifications = getModificationsFromCampaigns(initialCampaigns);
|
|
25
|
+
}
|
|
26
|
+
const [state, setState] = useState(Object.assign(Object.assign({}, initStat), { modifications }));
|
|
27
|
+
const [lastModified, setLastModified] = useState();
|
|
28
|
+
const stateRef = useRef();
|
|
29
|
+
stateRef.current = state;
|
|
30
|
+
useNonInitialEffect(() => {
|
|
31
|
+
var _a;
|
|
32
|
+
if (fetchFlagsOnBucketingUpdated) {
|
|
33
|
+
(_a = state.visitor) === null || _a === void 0 ? void 0 : _a.fetchFlags();
|
|
34
|
+
}
|
|
35
|
+
}, [lastModified]);
|
|
36
|
+
useNonInitialEffect(() => {
|
|
37
|
+
createVisitor(true);
|
|
38
|
+
}, [JSON.stringify(visitorData)]);
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
initSdk();
|
|
41
|
+
}, [envId, apiKey, decisionMode]);
|
|
42
|
+
function initializeState(param) {
|
|
43
|
+
const newStatus = {
|
|
44
|
+
isSdkReady: param.isSdkReady,
|
|
45
|
+
isLoading: param.isLoading,
|
|
46
|
+
isVisitorDefined: !!param.fsVisitor,
|
|
47
|
+
lastRefresh: new Date().toISOString()
|
|
48
|
+
};
|
|
49
|
+
setState((currentState) => {
|
|
50
|
+
if (!currentState.status.firstInitSuccess) {
|
|
51
|
+
newStatus.firstInitSuccess = new Date().toISOString();
|
|
52
|
+
}
|
|
53
|
+
return Object.assign(Object.assign({}, currentState), { visitor: param.fsVisitor, modifications: param.fsVisitor.modifications, config: Flagship.getConfig(), status: Object.assign(Object.assign({}, currentState.status), newStatus) });
|
|
54
|
+
});
|
|
55
|
+
return newStatus;
|
|
56
|
+
}
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
58
|
+
const onVisitorReady = (fsVisitor, error) => {
|
|
59
|
+
if (error) {
|
|
60
|
+
logError(Flagship.getConfig(), error.message || error, 'onReady');
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const newStatus = initializeState({
|
|
64
|
+
fsVisitor,
|
|
65
|
+
isSdkReady: true,
|
|
66
|
+
isLoading: false
|
|
67
|
+
});
|
|
68
|
+
if (onUpdate) {
|
|
69
|
+
onUpdate({
|
|
70
|
+
fsModifications: fsVisitor.modifications,
|
|
71
|
+
config: Flagship.getConfig(),
|
|
72
|
+
status: newStatus
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
const createVisitor = (fetchFlags = false) => {
|
|
77
|
+
if (!visitorData) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const fsVisitor = Flagship.newVisitor({
|
|
81
|
+
visitorId: visitorData.id,
|
|
82
|
+
context: visitorData.context,
|
|
83
|
+
isAuthenticated: visitorData.isAuthenticated,
|
|
84
|
+
hasConsented: visitorData.hasConsented,
|
|
85
|
+
initialCampaigns,
|
|
86
|
+
initialModifications,
|
|
87
|
+
initialFlagsData
|
|
88
|
+
});
|
|
89
|
+
fsVisitor === null || fsVisitor === void 0 ? void 0 : fsVisitor.on('ready', (error) => {
|
|
90
|
+
onVisitorReady(fsVisitor, error);
|
|
91
|
+
});
|
|
92
|
+
if (!fetchNow && fsVisitor && !fetchFlags) {
|
|
93
|
+
initializeState({
|
|
94
|
+
fsVisitor,
|
|
95
|
+
isSdkReady: true,
|
|
96
|
+
isLoading: false
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
if (fetchFlags && !fetchNow) {
|
|
100
|
+
fsVisitor === null || fsVisitor === void 0 ? void 0 : fsVisitor.fetchFlags();
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
const statusChanged = (status) => {
|
|
104
|
+
if (statusChangedCallback) {
|
|
105
|
+
statusChangedCallback(status);
|
|
106
|
+
}
|
|
107
|
+
switch (status) {
|
|
108
|
+
case FlagshipStatus.STARTING:
|
|
109
|
+
if (status === FlagshipStatus.STARTING && onInitStart) {
|
|
110
|
+
onInitStart();
|
|
111
|
+
}
|
|
112
|
+
break;
|
|
113
|
+
case FlagshipStatus.READY_PANIC_ON:
|
|
114
|
+
case FlagshipStatus.READY:
|
|
115
|
+
if (onInitDone) {
|
|
116
|
+
onInitDone();
|
|
117
|
+
}
|
|
118
|
+
createVisitor();
|
|
119
|
+
break;
|
|
120
|
+
case FlagshipStatus.NOT_INITIALIZED:
|
|
121
|
+
setState((prev) => (Object.assign(Object.assign({}, prev), { config: Flagship.getConfig() })));
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
const onBucketingLastModified = (lastUpdate) => {
|
|
126
|
+
if (onBucketingUpdated) {
|
|
127
|
+
onBucketingUpdated(lastUpdate);
|
|
128
|
+
}
|
|
129
|
+
setLastModified(lastUpdate);
|
|
130
|
+
};
|
|
131
|
+
const initSdk = () => {
|
|
132
|
+
Flagship.start(envId, apiKey, {
|
|
133
|
+
decisionMode,
|
|
134
|
+
fetchNow,
|
|
135
|
+
timeout,
|
|
136
|
+
logLevel,
|
|
137
|
+
statusChangedCallback: statusChanged,
|
|
138
|
+
logManager,
|
|
139
|
+
pollingInterval,
|
|
140
|
+
onBucketingFail,
|
|
141
|
+
onBucketingSuccess,
|
|
142
|
+
enableClientCache,
|
|
143
|
+
decisionApiUrl,
|
|
144
|
+
onBucketingUpdated: onBucketingLastModified,
|
|
145
|
+
initialBucketing,
|
|
146
|
+
activateDeduplicationTime,
|
|
147
|
+
hitDeduplicationTime,
|
|
148
|
+
visitorCacheImplementation,
|
|
149
|
+
hitCacheImplementation,
|
|
150
|
+
disableCache,
|
|
151
|
+
language
|
|
152
|
+
});
|
|
153
|
+
};
|
|
154
|
+
const handleDisplay = () => {
|
|
155
|
+
const isFirstInit = !state.visitor;
|
|
156
|
+
if (state.status.isLoading && loadingComponent && isFirstInit && fetchNow) {
|
|
157
|
+
return React.createElement(React.Fragment, null, loadingComponent);
|
|
158
|
+
}
|
|
159
|
+
return React.createElement(React.Fragment, null, children);
|
|
160
|
+
};
|
|
161
|
+
return (React.createElement(FlagshipContext.Provider, { value: { state, setState } }, handleDisplay()));
|
|
162
|
+
};
|
|
163
|
+
FlagshipProvider.defaultProps = {
|
|
164
|
+
activateDeduplicationTime: 2,
|
|
165
|
+
hitDeduplicationTime: 2,
|
|
166
|
+
fetchNow: true,
|
|
167
|
+
language: 1
|
|
168
|
+
};
|
|
File without changes
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { useContext } from 'react';
|
|
11
|
+
import { FlagshipContext } from './FlagshipContext';
|
|
12
|
+
import { logError, logWarn } from './utils';
|
|
13
|
+
import { Flag } from './Flag';
|
|
14
|
+
import { noVisitorDefault, noVisitorMessage } from './constants';
|
|
15
|
+
const checkType = (value, defaultValue) => (typeof value === 'object' &&
|
|
16
|
+
typeof defaultValue === 'object' &&
|
|
17
|
+
Array.isArray(value) === Array.isArray(defaultValue)) ||
|
|
18
|
+
typeof value === typeof defaultValue;
|
|
19
|
+
const fsModificationsSync = (args) => {
|
|
20
|
+
const { visitor, params, activateAll, state, functionName, config } = args;
|
|
21
|
+
if (visitor) {
|
|
22
|
+
return visitor.getModificationsSync(params, activateAll);
|
|
23
|
+
}
|
|
24
|
+
const check = !state.status.isSdkReady &&
|
|
25
|
+
!!state.modifications &&
|
|
26
|
+
state.modifications.size > 0;
|
|
27
|
+
const flags = {};
|
|
28
|
+
if (check) {
|
|
29
|
+
params.forEach((item) => {
|
|
30
|
+
var _a;
|
|
31
|
+
const modification = (_a = state.modifications) === null || _a === void 0 ? void 0 : _a.get(item.key);
|
|
32
|
+
if (modification && checkType(modification === null || modification === void 0 ? void 0 : modification.value, item.defaultValue)) {
|
|
33
|
+
flags[item.key] = modification.value;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
flags[item.key] = item.defaultValue;
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
return flags;
|
|
40
|
+
}
|
|
41
|
+
logWarn(config, noVisitorDefault, functionName);
|
|
42
|
+
params.forEach((item) => {
|
|
43
|
+
flags[item.key] = item.defaultValue;
|
|
44
|
+
});
|
|
45
|
+
return flags;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* 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.
|
|
49
|
+
* @deprecated use useFsFlag instead
|
|
50
|
+
*/
|
|
51
|
+
export const useFsModifications = (params, activateAll) => {
|
|
52
|
+
const { state } = useContext(FlagshipContext);
|
|
53
|
+
const { visitor, config } = state;
|
|
54
|
+
const functionName = 'useFsModifications';
|
|
55
|
+
return fsModificationsSync({
|
|
56
|
+
functionName,
|
|
57
|
+
state,
|
|
58
|
+
visitor,
|
|
59
|
+
config,
|
|
60
|
+
params,
|
|
61
|
+
activateAll
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* 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.
|
|
66
|
+
* @deprecated use useFsFlag instead
|
|
67
|
+
*/
|
|
68
|
+
export const useFsModification = (params) => {
|
|
69
|
+
var _a;
|
|
70
|
+
const { state } = useContext(FlagshipContext);
|
|
71
|
+
const { visitor, config } = state;
|
|
72
|
+
const functionName = 'useFsModifications';
|
|
73
|
+
if (visitor) {
|
|
74
|
+
return visitor.getModificationSync(params);
|
|
75
|
+
}
|
|
76
|
+
const modification = (_a = state.modifications) === null || _a === void 0 ? void 0 : _a.get(params.key);
|
|
77
|
+
if (!state.status.isSdkReady &&
|
|
78
|
+
modification &&
|
|
79
|
+
checkType(modification === null || modification === void 0 ? void 0 : modification.value, params.defaultValue)) {
|
|
80
|
+
return modification.value;
|
|
81
|
+
}
|
|
82
|
+
logWarn(config, noVisitorDefault, functionName);
|
|
83
|
+
return params.defaultValue;
|
|
84
|
+
};
|
|
85
|
+
const fsModificationInfoSync = (args) => {
|
|
86
|
+
var _a;
|
|
87
|
+
const { key, visitor, state } = args;
|
|
88
|
+
if (visitor) {
|
|
89
|
+
return visitor.getModificationInfoSync(key);
|
|
90
|
+
}
|
|
91
|
+
const modification = (_a = state.modifications) === null || _a === void 0 ? void 0 : _a.get(key);
|
|
92
|
+
if (!state.status.isSdkReady && modification) {
|
|
93
|
+
return modification;
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Get the campaign modification information value matching the given key.
|
|
99
|
+
* @param {string} key key which identify the modification.
|
|
100
|
+
* @deprecated use useFsFlag instead
|
|
101
|
+
*/
|
|
102
|
+
export const useFsModificationInfo = (key) => {
|
|
103
|
+
const { state } = useContext(FlagshipContext);
|
|
104
|
+
const { visitor } = state;
|
|
105
|
+
return fsModificationInfoSync({ key, state, visitor });
|
|
106
|
+
};
|
|
107
|
+
const fsActivate = (params, functionName, visitor, config) => __awaiter(void 0, void 0, void 0, function* () {
|
|
108
|
+
try {
|
|
109
|
+
if (!visitor) {
|
|
110
|
+
logWarn(config, noVisitorMessage, functionName);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
yield visitor.activateModifications(params);
|
|
114
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
logWarn(config, error.message || error, functionName);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
/**
|
|
121
|
+
* This hook returns a flag object by its key. If no flag match the given key an empty flag will be returned.
|
|
122
|
+
* @param key
|
|
123
|
+
* @param defaultValue
|
|
124
|
+
* @returns
|
|
125
|
+
*/
|
|
126
|
+
export const useFsFlag = (key, defaultValue) => {
|
|
127
|
+
const { state } = useContext(FlagshipContext);
|
|
128
|
+
const { visitor } = state;
|
|
129
|
+
if (!visitor) {
|
|
130
|
+
return new Flag(defaultValue, key, state.modifications);
|
|
131
|
+
}
|
|
132
|
+
return visitor.getFlag(key, defaultValue);
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Report this user has seen this modification. Report this user has seen these modifications.
|
|
136
|
+
* @param params
|
|
137
|
+
* @deprecated use useFsFlag instead
|
|
138
|
+
* @returns
|
|
139
|
+
*/
|
|
140
|
+
export const useFsActivate = (params) => __awaiter(void 0, void 0, void 0, function* () {
|
|
141
|
+
const { state } = useContext(FlagshipContext);
|
|
142
|
+
const { visitor, config } = state;
|
|
143
|
+
const functionName = 'useFsModifications';
|
|
144
|
+
yield fsActivate(params, functionName, visitor, config);
|
|
145
|
+
});
|
|
146
|
+
export const useFlagship = () => {
|
|
147
|
+
const { state } = useContext(FlagshipContext);
|
|
148
|
+
const { visitor, config } = state;
|
|
149
|
+
const fsUpdateContext = (context) => {
|
|
150
|
+
const functionName = 'updateContext';
|
|
151
|
+
if (!visitor) {
|
|
152
|
+
logError(config, noVisitorMessage, functionName);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
visitor.clearContext();
|
|
156
|
+
visitor.updateContext(context);
|
|
157
|
+
};
|
|
158
|
+
const fsClearContext = () => {
|
|
159
|
+
const functionName = 'cleanContext';
|
|
160
|
+
if (!visitor) {
|
|
161
|
+
logError(config, noVisitorMessage, functionName);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
visitor.clearContext();
|
|
165
|
+
};
|
|
166
|
+
const fsAuthenticate = (visitorId) => {
|
|
167
|
+
const functionName = 'authenticate';
|
|
168
|
+
if (!visitor) {
|
|
169
|
+
logError(config, noVisitorMessage, functionName);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
visitor.authenticate(visitorId);
|
|
173
|
+
};
|
|
174
|
+
const fsUnauthenticate = () => {
|
|
175
|
+
const functionName = 'unauthenticate';
|
|
176
|
+
if (!visitor) {
|
|
177
|
+
logError(config, noVisitorMessage, functionName);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
visitor.unauthenticate();
|
|
181
|
+
};
|
|
182
|
+
/**
|
|
183
|
+
* Send a Hit to Flagship servers for reporting.
|
|
184
|
+
*/
|
|
185
|
+
const fsSendHit = (hit) => {
|
|
186
|
+
const functionName = 'sendHit';
|
|
187
|
+
if (!visitor) {
|
|
188
|
+
logError(config, noVisitorMessage, functionName);
|
|
189
|
+
return Promise.resolve();
|
|
190
|
+
}
|
|
191
|
+
return visitor.sendHit(hit);
|
|
192
|
+
};
|
|
193
|
+
/**
|
|
194
|
+
* Send a Hit to Flagship servers for reporting.
|
|
195
|
+
*/
|
|
196
|
+
const fsSendHits = (hit) => {
|
|
197
|
+
const functionName = 'sendHits';
|
|
198
|
+
if (!visitor) {
|
|
199
|
+
logError(config, noVisitorMessage, functionName);
|
|
200
|
+
return Promise.resolve();
|
|
201
|
+
}
|
|
202
|
+
return visitor.sendHits(hit);
|
|
203
|
+
};
|
|
204
|
+
let modifications = visitor === null || visitor === void 0 ? void 0 : visitor.getModificationsArray();
|
|
205
|
+
if (!state.status.isSdkReady && state.modifications) {
|
|
206
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
207
|
+
modifications = Array.from(state.modifications, ([_key, item]) => item);
|
|
208
|
+
}
|
|
209
|
+
const activateModification = (params) => __awaiter(void 0, void 0, void 0, function* () {
|
|
210
|
+
const functionName = 'activateModification';
|
|
211
|
+
yield fsActivate(params, functionName, visitor, config);
|
|
212
|
+
});
|
|
213
|
+
const synchronizeModifications = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
214
|
+
if (!visitor) {
|
|
215
|
+
logWarn(config, noVisitorMessage, 'synchronizeModifications');
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
yield visitor.synchronizeModifications();
|
|
219
|
+
});
|
|
220
|
+
const getModifications = (params, activateAll) => {
|
|
221
|
+
const functionName = 'getModifications';
|
|
222
|
+
return fsModificationsSync({
|
|
223
|
+
functionName,
|
|
224
|
+
state,
|
|
225
|
+
visitor,
|
|
226
|
+
config,
|
|
227
|
+
params,
|
|
228
|
+
activateAll
|
|
229
|
+
});
|
|
230
|
+
};
|
|
231
|
+
const getModificationInfo = (key) => {
|
|
232
|
+
return fsModificationInfoSync({ key, state, visitor });
|
|
233
|
+
};
|
|
234
|
+
function getFlag(key, defaultValue) {
|
|
235
|
+
if (!visitor) {
|
|
236
|
+
return new Flag(defaultValue, key, state.modifications);
|
|
237
|
+
}
|
|
238
|
+
return visitor.getFlag(key, defaultValue);
|
|
239
|
+
}
|
|
240
|
+
function fetchFlags() {
|
|
241
|
+
if (!visitor) {
|
|
242
|
+
logWarn(config, noVisitorMessage, 'fetchFlags');
|
|
243
|
+
return Promise.resolve();
|
|
244
|
+
}
|
|
245
|
+
return visitor.fetchFlags();
|
|
246
|
+
}
|
|
247
|
+
function setConsent(hasConsented) {
|
|
248
|
+
if (!visitor) {
|
|
249
|
+
logWarn(config, noVisitorMessage, 'setConsent');
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
visitor.setConsent(hasConsented);
|
|
253
|
+
}
|
|
254
|
+
return {
|
|
255
|
+
visitorId: visitor === null || visitor === void 0 ? void 0 : visitor.visitorId,
|
|
256
|
+
anonymousId: visitor === null || visitor === void 0 ? void 0 : visitor.anonymousId,
|
|
257
|
+
context: Object.assign({}, visitor === null || visitor === void 0 ? void 0 : visitor.context),
|
|
258
|
+
hasConsented: visitor === null || visitor === void 0 ? void 0 : visitor.hasConsented,
|
|
259
|
+
setConsent,
|
|
260
|
+
updateContext: fsUpdateContext,
|
|
261
|
+
clearContext: fsClearContext,
|
|
262
|
+
authenticate: fsAuthenticate,
|
|
263
|
+
unauthenticate: fsUnauthenticate,
|
|
264
|
+
status: state.status,
|
|
265
|
+
activateModification,
|
|
266
|
+
synchronizeModifications,
|
|
267
|
+
getModifications,
|
|
268
|
+
modifications: modifications || [],
|
|
269
|
+
flagsData: (visitor === null || visitor === void 0 ? void 0 : visitor.getFlagsDataArray()) || [],
|
|
270
|
+
getModificationInfo,
|
|
271
|
+
hit: {
|
|
272
|
+
send: fsSendHit,
|
|
273
|
+
sendMultiple: fsSendHits
|
|
274
|
+
},
|
|
275
|
+
getFlag,
|
|
276
|
+
fetchFlags
|
|
277
|
+
};
|
|
278
|
+
};
|
|
File without changes
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export const noVisitorMessage = 'flagship Visitor not initialized.';
|
|
2
|
+
export const noVisitorDefault = 'fsVisitor not initialized, returns default value';
|
|
3
|
+
export const GET_FLAG_CAST_ERROR = 'Flag for key {0} has a different type. Default value is returned.';
|
|
4
|
+
export const GET_METADATA_CAST_ERROR = 'Flag for key {0} has a different type with defaultValue, an empty metadata object is returned';
|