1 | import { combineReducers } from 'redux';
|
2 | import _createForOfIteratorHelper from '@babel/runtime/helpers/esm/createForOfIteratorHelper';
|
3 | import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
|
4 | import _objectSpread from '@babel/runtime/helpers/esm/objectSpread2';
|
5 | import { isNil, selectAdapterConfigurationStatus, useAdapterContext, getIsFeatureEnabled, getFlagVariation, useAdapterSubscription, ConfigureAdapter, ToggleFeature as ToggleFeature$1, setDisplayName, wrapDisplayName, DEFAULT_FLAG_PROP_KEY, DEFAULT_FLAGS_PROP_KEY } from '@flopflip/react';
|
6 | export { ReconfigureAdapter as ReconfigureFlopFlip, useAdapterReconfiguration } from '@flopflip/react';
|
7 | import { AdapterSubscriptionStatus, AdapterConfigurationStatus } from '@flopflip/types';
|
8 | import React, { useDebugValue, useCallback } from 'react';
|
9 | import { useSelector, useDispatch } from 'react-redux';
|
10 | import _toConsumableArray from '@babel/runtime/helpers/esm/toConsumableArray';
|
11 | import _slicedToArray from '@babel/runtime/helpers/esm/slicedToArray';
|
12 |
|
13 | var STATE_SLICE = '@flopflip';
|
14 |
|
15 |
|
16 | var UPDATE_FLAGS = '@flopflip/flags/update';
|
17 | var initialState$1 = {
|
18 | memory: {}
|
19 | };
|
20 |
|
21 | var reducer$1 = function reducer() {
|
22 | var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState$1;
|
23 | var action = arguments.length > 1 ? arguments[1] : undefined;
|
24 |
|
25 | switch (action.type) {
|
26 | case UPDATE_FLAGS:
|
27 | {
|
28 | if (action.payload.id) {
|
29 | return _objectSpread(_objectSpread({}, state), {}, _defineProperty({}, action.payload.id, _objectSpread(_objectSpread({}, state === null || state === void 0 ? void 0 : state[action.payload.id]), action.payload.flags)));
|
30 | }
|
31 |
|
32 | return _objectSpread(_objectSpread({}, state), Object.fromEntries(action.payload.adapterIdentifiers.map(function (adapterInterfaceIdentifier) {
|
33 | return [adapterInterfaceIdentifier, _objectSpread(_objectSpread({}, state === null || state === void 0 ? void 0 : state[adapterInterfaceIdentifier]), action.payload.flags)];
|
34 | })));
|
35 | }
|
36 |
|
37 | default:
|
38 | return state;
|
39 | }
|
40 | };
|
41 | var createReducer = function createReducer() {
|
42 | var preloadedState = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState$1;
|
43 | return function () {
|
44 | var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : preloadedState;
|
45 | var action = arguments.length > 1 ? arguments[1] : undefined;
|
46 | return reducer$1(state, action);
|
47 | };
|
48 | };
|
49 |
|
50 | var updateFlags = function updateFlags(flagsChange, adapterIdentifiers) {
|
51 | return {
|
52 | type: UPDATE_FLAGS,
|
53 | payload: _objectSpread(_objectSpread({}, flagsChange), {}, {
|
54 | adapterIdentifiers: adapterIdentifiers
|
55 | })
|
56 | };
|
57 | };
|
58 |
|
59 | var selectFlags = function selectFlags() {
|
60 | return function (state) {
|
61 | var _state$STATE_SLICE$fl;
|
62 |
|
63 | return (_state$STATE_SLICE$fl = state[STATE_SLICE].flags) !== null && _state$STATE_SLICE$fl !== void 0 ? _state$STATE_SLICE$fl : {};
|
64 | };
|
65 | };
|
66 | var selectFlag = function selectFlag(flagName, adapterIdentifiers) {
|
67 | return function (state) {
|
68 | var allFlags = selectFlags()(state);
|
69 | var foundFlagVariation = false;
|
70 |
|
71 | var _iterator = _createForOfIteratorHelper(adapterIdentifiers),
|
72 | _step;
|
73 |
|
74 | try {
|
75 | for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
76 | var _allFlags$adapterInte;
|
77 |
|
78 | var adapterInterfaceIdentifier = _step.value;
|
79 | var flagValue = (_allFlags$adapterInte = allFlags[adapterInterfaceIdentifier]) === null || _allFlags$adapterInte === void 0 ? void 0 : _allFlags$adapterInte[flagName];
|
80 |
|
81 | if (!isNil(flagValue)) {
|
82 | foundFlagVariation = flagValue;
|
83 | }
|
84 | }
|
85 | } catch (err) {
|
86 | _iterator.e(err);
|
87 | } finally {
|
88 | _iterator.f();
|
89 | }
|
90 |
|
91 | return foundFlagVariation;
|
92 | };
|
93 | };
|
94 |
|
95 |
|
96 | var UPDATE_STATUS = '@flopflip/status/update';
|
97 | var initialState = {
|
98 | subscriptionStatus: AdapterSubscriptionStatus.Subscribed,
|
99 | configurationStatus: AdapterConfigurationStatus.Unconfigured
|
100 | };
|
101 |
|
102 | var reducer = function reducer() {
|
103 | var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
|
104 | var action = arguments.length > 1 ? arguments[1] : undefined;
|
105 |
|
106 | switch (action.type) {
|
107 | case UPDATE_STATUS:
|
108 | return _objectSpread(_objectSpread({}, state), action.payload.status);
|
109 |
|
110 | default:
|
111 | return state;
|
112 | }
|
113 | };
|
114 |
|
115 | var updateStatus = function updateStatus(statusChange) {
|
116 | return {
|
117 | type: UPDATE_STATUS,
|
118 | payload: statusChange
|
119 | };
|
120 | };
|
121 |
|
122 | var selectStatus = function selectStatus(state) {
|
123 | var status = state[STATE_SLICE].status;
|
124 | return selectAdapterConfigurationStatus(status === null || status === void 0 ? void 0 : status.configurationStatus);
|
125 | };
|
126 |
|
127 | var flopflipReducer = combineReducers({
|
128 | flags: reducer$1,
|
129 | status: reducer
|
130 | });
|
131 | var createFlopflipReducer = function createFlopflipReducer() {
|
132 | var preloadedState = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
|
133 | memory: {}
|
134 | };
|
135 | return combineReducers({
|
136 | flags: createReducer(preloadedState),
|
137 | status: reducer
|
138 | });
|
139 | };
|
140 |
|
141 | function createFlopFlipEnhancer(adapter, adapterArgs) {
|
142 | return function (next) {
|
143 | return function () {
|
144 | var store = next.apply(void 0, arguments);
|
145 |
|
146 | adapter.configure(adapterArgs, {
|
147 |
|
148 |
|
149 | onFlagsStateChange: function onFlagsStateChange(flagsChange) {
|
150 | store.dispatch(updateFlags(flagsChange, [adapter.id]));
|
151 | },
|
152 | onStatusStateChange: function onStatusStateChange(statusChange) {
|
153 | store.dispatch(updateStatus(statusChange));
|
154 | }
|
155 | });
|
156 | return store;
|
157 | };
|
158 | };
|
159 | }
|
160 |
|
161 | function useAdapterStatus() {
|
162 | var adapterStatus = useSelector(selectStatus);
|
163 | useDebugValue({
|
164 | adapterStatus: adapterStatus
|
165 | });
|
166 | return adapterStatus;
|
167 | }
|
168 |
|
169 | function useFeatureToggle(flagName) {
|
170 | var flagVariation = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
171 | var adapterContext = useAdapterContext();
|
172 | var allFlags = useSelector(selectFlags());
|
173 | var isFeatureEnabled = getIsFeatureEnabled(allFlags, adapterContext.adapterEffectIdentifiers, flagName, flagVariation);
|
174 | useDebugValue({
|
175 | flagName: flagName,
|
176 | flagVariation: flagVariation,
|
177 | isEnabled: isFeatureEnabled
|
178 | });
|
179 | return isFeatureEnabled;
|
180 | }
|
181 |
|
182 | function useFeatureToggles(flags) {
|
183 | var allFlags = useSelector(selectFlags());
|
184 | var adapterContext = useAdapterContext();
|
185 | var requestedFlags = Object.entries(flags).reduce(function (previousFlags, _ref) {
|
186 | var _ref2 = _slicedToArray(_ref, 2),
|
187 | flagName = _ref2[0],
|
188 | flagVariation = _ref2[1];
|
189 |
|
190 | var isFeatureEnabled = getIsFeatureEnabled(allFlags, adapterContext.adapterEffectIdentifiers, flagName, flagVariation);
|
191 | return [].concat(_toConsumableArray(previousFlags), [isFeatureEnabled]);
|
192 | }, []);
|
193 | return requestedFlags;
|
194 | }
|
195 |
|
196 | function useFlagVariations(flagNames) {
|
197 | var adapterContext = useAdapterContext();
|
198 | var allFlags = useSelector(selectFlags());
|
199 | var flagVariations = flagNames.map(function (requestedVariation) {
|
200 | return getFlagVariation(allFlags, adapterContext.adapterEffectIdentifiers, requestedVariation);
|
201 | });
|
202 | return flagVariations;
|
203 | }
|
204 |
|
205 | function useFlagVariation(flagName) {
|
206 | var _useFlagVariations = useFlagVariations([flagName]),
|
207 | _useFlagVariations2 = _slicedToArray(_useFlagVariations, 1),
|
208 | flagVariation = _useFlagVariations2[0];
|
209 |
|
210 | return flagVariation;
|
211 | }
|
212 |
|
213 | var useUpdateFlags = function useUpdateFlags(_ref) {
|
214 | var adapterIdentifiers = _ref.adapterIdentifiers;
|
215 | var dispatch = useDispatch();
|
216 | return useCallback(function (flagsChange) {
|
217 | return dispatch(updateFlags(flagsChange, adapterIdentifiers));
|
218 | }, [dispatch, adapterIdentifiers]);
|
219 | };
|
220 |
|
221 | var useUpdateStatus = function useUpdateStatus() {
|
222 | var dispatch = useDispatch();
|
223 | return useCallback(function (statusChange) {
|
224 | return dispatch(updateStatus(statusChange));
|
225 | }, [dispatch]);
|
226 | };
|
227 |
|
228 | var defaultProps = {
|
229 | defaultFlags: {},
|
230 | shouldDeferAdapterConfiguration: false
|
231 | };
|
232 |
|
233 | var Configure = function Configure(props) {
|
234 | var adapterIdentifiers = [props.adapter.id];
|
235 | var handleUpdateFlags = useUpdateFlags({
|
236 | adapterIdentifiers: adapterIdentifiers
|
237 | });
|
238 | var handleUpdateStatus = useUpdateStatus();
|
239 | useAdapterSubscription(props.adapter);
|
240 | return React.createElement(ConfigureAdapter, {
|
241 | adapter: props.adapter,
|
242 | adapterArgs: props.adapterArgs,
|
243 | defaultFlags: props.defaultFlags,
|
244 | shouldDeferAdapterConfiguration: props.shouldDeferAdapterConfiguration,
|
245 | onFlagsStateChange: handleUpdateFlags,
|
246 | onStatusStateChange: handleUpdateStatus
|
247 | }, props.children);
|
248 | };
|
249 |
|
250 | Configure.displayName = 'ConfigureFlopflip';
|
251 | Configure.defaultProps = defaultProps;
|
252 |
|
253 | var ToggleFeature = function ToggleFeature(props) {
|
254 | var isFeatureEnabled = useFeatureToggle(props.flag, props.variation);
|
255 | return React.createElement(ToggleFeature$1, Object.assign({}, props, {
|
256 | isFeatureEnabled: isFeatureEnabled
|
257 | }));
|
258 | };
|
259 |
|
260 | ToggleFeature.displayName = 'ToggleFeature';
|
261 |
|
262 | function branchOnFeatureToggle(_ref, UntoggledComponent) {
|
263 | var flagName = _ref.flag,
|
264 | flagVariation = _ref.variation;
|
265 | return function (ToggledComponent) {
|
266 | var WrappedToggledComponent = function WrappedToggledComponent(ownProps) {
|
267 | var isFeatureEnabled = useFeatureToggle(flagName, flagVariation);
|
268 | if (isFeatureEnabled) return React.createElement(ToggledComponent, ownProps);
|
269 | if (UntoggledComponent) return React.createElement(UntoggledComponent, ownProps);
|
270 | return null;
|
271 | };
|
272 |
|
273 | return WrappedToggledComponent;
|
274 | };
|
275 | }
|
276 |
|
277 | var injectFeatureToggle = (function (flagName) {
|
278 | var propKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_FLAG_PROP_KEY;
|
279 | return function (Component) {
|
280 | var WrappedComponent = function WrappedComponent(ownProps) {
|
281 | var _useFlagVariations = useFlagVariations([flagName]),
|
282 | _useFlagVariations2 = _slicedToArray(_useFlagVariations, 1),
|
283 | flagVariation = _useFlagVariations2[0];
|
284 |
|
285 | var props = _objectSpread(_objectSpread({}, ownProps), {}, _defineProperty({}, propKey, flagVariation));
|
286 |
|
287 | return React.createElement(Component, props);
|
288 | };
|
289 |
|
290 | setDisplayName(wrapDisplayName(WrappedComponent, 'injectFeatureToggle'));
|
291 | return WrappedComponent;
|
292 | };
|
293 | });
|
294 |
|
295 | var injectFeatureToggles = (function (flagNames) {
|
296 | var propKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_FLAGS_PROP_KEY;
|
297 | return function (Component) {
|
298 | var WrappedComponent = function WrappedComponent(ownProps) {
|
299 | var flagVariations = useFlagVariations(flagNames);
|
300 | var flags = Object.fromEntries(flagNames.map(function (flagName, indexOfFlagName) {
|
301 | return [flagName, flagVariations[indexOfFlagName]];
|
302 | }));
|
303 |
|
304 | var props = _objectSpread(_objectSpread({}, ownProps), {}, _defineProperty({}, propKey, flags));
|
305 |
|
306 | return React.createElement(Component, props);
|
307 | };
|
308 |
|
309 | setDisplayName(wrapDisplayName(WrappedComponent, 'injectFeatureToggles'));
|
310 | return WrappedComponent;
|
311 | };
|
312 | });
|
313 |
|
314 | var version = '12.1.14';
|
315 |
|
316 | export { Configure as ConfigureFlopFlip, STATE_SLICE as FLOPFLIP_STATE_SLICE, ToggleFeature, UPDATE_FLAGS, UPDATE_STATUS, branchOnFeatureToggle, createFlopFlipEnhancer, createFlopflipReducer, flopflipReducer, injectFeatureToggle, injectFeatureToggles, selectFlag as selectFeatureFlag, selectFlags as selectFeatureFlags, useAdapterStatus, useFeatureToggle, useFeatureToggles, useFlagVariation, useFlagVariations, version };
|