@flopflip/react-redux
Version:
A feature toggle wrapper to use LaunchDarkly with React Redux
368 lines (367 loc) • 14.7 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
//#region \0rolldown/runtime.js
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
//#endregion
let react = require("react");
react = __toESM(react, 1);
let _flopflip_react = require("@flopflip/react");
let react_redux = require("react-redux");
let _reduxjs_toolkit = require("@reduxjs/toolkit");
let _flopflip_types = require("@flopflip/types");
//#region src/constants.ts
const STATE_SLICE = "@flopflip";
//#endregion
//#region \0@oxc-project+runtime@0.134.0/helpers/esm/typeof.js
function _typeof(o) {
"@babel/helpers - typeof";
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
return typeof o;
} : function(o) {
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
}, _typeof(o);
}
//#endregion
//#region \0@oxc-project+runtime@0.134.0/helpers/esm/toPrimitive.js
function toPrimitive(t, r) {
if ("object" != _typeof(t) || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t, r || "default");
if ("object" != _typeof(i)) return i;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t);
}
//#endregion
//#region \0@oxc-project+runtime@0.134.0/helpers/esm/toPropertyKey.js
function toPropertyKey(t) {
var i = toPrimitive(t, "string");
return "symbol" == _typeof(i) ? i : i + "";
}
//#endregion
//#region \0@oxc-project+runtime@0.134.0/helpers/esm/defineProperty.js
function _defineProperty(e, r, t) {
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
value: t,
enumerable: !0,
configurable: !0,
writable: !0
}) : e[r] = t, e;
}
//#endregion
//#region \0@oxc-project+runtime@0.134.0/helpers/esm/objectSpread2.js
function ownKeys(e, r) {
var t = Object.keys(e);
if (Object.getOwnPropertySymbols) {
var o = Object.getOwnPropertySymbols(e);
r && (o = o.filter(function(r) {
return Object.getOwnPropertyDescriptor(e, r).enumerable;
})), t.push.apply(t, o);
}
return t;
}
function _objectSpread2(e) {
for (var r = 1; r < arguments.length; r++) {
var t = null != arguments[r] ? arguments[r] : {};
r % 2 ? ownKeys(Object(t), !0).forEach(function(r) {
_defineProperty(e, r, t[r]);
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r) {
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
});
}
return e;
}
//#endregion
//#region src/ducks/flags.ts
const initialState = { memory: {} };
const flagsSlice = (0, _reduxjs_toolkit.createSlice)({
name: "flags",
initialState,
reducers: { updateFlags: {
reducer(state, action) {
if (action.payload.id) {
state[action.payload.id] = _objectSpread2(_objectSpread2({}, state[action.payload.id]), action.payload.flags);
return;
}
for (const adapterId of action.payload.adapterIdentifiers) state[adapterId] = _objectSpread2(_objectSpread2({}, state[adapterId]), action.payload.flags);
},
prepare(flagsChange, adapterIdentifiers) {
return { payload: _objectSpread2(_objectSpread2({}, flagsChange), {}, { adapterIdentifiers }) };
}
} }
});
const { updateFlags } = flagsSlice.actions;
const reducer$1 = flagsSlice.reducer;
const createReducer = (preloadedState = initialState) => {
return (state = preloadedState, action) => reducer$1(state, action);
};
const selectFlags = () => (state) => {
var _state$STATE_SLICE$fl;
return (_state$STATE_SLICE$fl = state["@flopflip"].flags) !== null && _state$STATE_SLICE$fl !== void 0 ? _state$STATE_SLICE$fl : {};
};
const selectFlag = (flagName, adapterIdentifiers) => (state) => {
const allFlags = selectFlags()(state);
let foundFlagVariation = false;
for (const adapterId of adapterIdentifiers) {
var _allFlags$adapterId;
const flagValue = (_allFlags$adapterId = allFlags[adapterId]) === null || _allFlags$adapterId === void 0 ? void 0 : _allFlags$adapterId[flagName];
if (!(0, _flopflip_react.isNil)(flagValue)) foundFlagVariation = flagValue;
}
return foundFlagVariation;
};
//#endregion
//#region src/use-feature-toggle.ts
function useFeatureToggle(flagName, flagVariation = true) {
const adapterContext = (0, _flopflip_react.useAdapterContext)();
const isFeatureEnabled = (0, _flopflip_react.getIsFeatureEnabled)((0, react_redux.useSelector)(selectFlags()), adapterContext.adapterEffectIdentifiers, flagName, flagVariation);
(0, react.useDebugValue)({
flagName,
flagVariation,
isEnabled: isFeatureEnabled
});
return isFeatureEnabled;
}
//#endregion
//#region src/branch-on-feature-toggle.tsx
function branchOnFeatureToggle({ flag: flagName, variation: flagVariation }, UntoggledComponent) {
return (ToggledComponent) => {
function WrappedToggledComponent(ownProps) {
if (useFeatureToggle(flagName, flagVariation)) return /* @__PURE__ */ react.default.createElement(ToggledComponent, ownProps);
if (UntoggledComponent) return /* @__PURE__ */ react.default.createElement(UntoggledComponent, ownProps);
return null;
}
return WrappedToggledComponent;
};
}
//#endregion
//#region src/use-update-flags.ts
const useUpdateFlags = ({ adapterIdentifiers }) => {
const dispatch = (0, react_redux.useDispatch)();
return (0, react.useCallback)((flagsChange) => dispatch(updateFlags(flagsChange, adapterIdentifiers)), [dispatch, adapterIdentifiers]);
};
//#endregion
//#region src/ducks/status.ts
const statusSlice = (0, _reduxjs_toolkit.createSlice)({
name: "status",
initialState: {},
reducers: { updateStatus: {
reducer(state, action) {
if (action.payload.id) {
state[action.payload.id] = _objectSpread2(_objectSpread2({}, state[action.payload.id]), action.payload.status);
return;
}
for (const adapterInterfaceIdentifier of action.payload.adapterIdentifiers) state[adapterInterfaceIdentifier] = _objectSpread2(_objectSpread2({}, state[adapterInterfaceIdentifier]), action.payload.status);
},
prepare(statusChange, adapterIdentifiers) {
return { payload: _objectSpread2(_objectSpread2({}, statusChange), {}, { adapterIdentifiers }) };
}
} }
});
const { updateStatus } = statusSlice.actions;
const reducer = statusSlice.reducer;
const selectStatus = ({ adapterIdentifiers } = {}) => (state) => {
const { status } = state[STATE_SLICE];
return (0, _flopflip_react.selectAdapterConfigurationStatus)(status, adapterIdentifiers);
};
//#endregion
//#region src/use-update-status.ts
const useUpdateStatus = () => {
const dispatch = (0, react_redux.useDispatch)();
return (0, react.useCallback)((statusChange) => dispatch(updateStatus(statusChange, Object.keys(_flopflip_types.adapterIdentifiers))), [dispatch]);
};
//#endregion
//#region src/configure.tsx
function Configure({ adapter, adapterArgs, children, defaultFlags = {}, shouldDeferAdapterConfiguration = false }) {
const handleUpdateFlags = useUpdateFlags({ adapterIdentifiers: [adapter.id] });
const handleUpdateStatus = useUpdateStatus();
(0, _flopflip_react.useAdapterSubscription)(adapter);
return /* @__PURE__ */ react.default.createElement(_flopflip_react.ConfigureAdapter, {
adapter,
adapterArgs,
defaultFlags,
shouldDeferAdapterConfiguration,
onFlagsStateChange: handleUpdateFlags,
onStatusStateChange: handleUpdateStatus
}, children);
}
Configure.displayName = "ConfigureFlopflip";
//#endregion
//#region src/ducks/index.ts
const flopflipReducer = (0, _reduxjs_toolkit.combineReducers)({
flags: reducer$1,
status: reducer
});
const createFlopflipReducer = (preloadedState = { memory: {} }) => (0, _reduxjs_toolkit.combineReducers)({
flags: createReducer(preloadedState),
status: reducer
});
//#endregion
//#region src/enhancer.ts
const configureAdapter = (0, _reduxjs_toolkit.createAction)("flopflip/configureAdapter");
function createFlopFlipEnhancer(adapter, adapterArgs) {
return (next) => (...args) => {
const store = next(...args);
store.dispatch(configureAdapter({
adapter,
adapterArgs
}));
adapter.configure(adapterArgs, {
onFlagsStateChange: (flagsChange) => {
store.dispatch(updateFlags(flagsChange, [adapter.id]));
},
onStatusStateChange: (statusChange) => {
store.dispatch(updateStatus(statusChange, Object.keys(_flopflip_types.adapterIdentifiers)));
}
});
return store;
};
}
//#endregion
//#region src/use-flag-variations.ts
function useFlagVariations(flagNames) {
const adapterContext = (0, _flopflip_react.useAdapterContext)();
const allFlags = (0, react_redux.useSelector)(selectFlags());
return flagNames.map((requestedVariation) => (0, _flopflip_react.getFlagVariation)(allFlags, adapterContext.adapterEffectIdentifiers, requestedVariation));
}
//#endregion
//#region src/inject-feature-toggle.tsx
const injectFeatureToggle = (flagName, propKey = _flopflip_react.DEFAULT_FLAG_PROP_KEY) => (Component) => {
function WrappedComponent(ownProps) {
const [flagVariation] = useFlagVariations([flagName]);
const props = _objectSpread2(_objectSpread2({}, ownProps), {}, { [propKey]: flagVariation });
return /* @__PURE__ */ react.default.createElement(Component, props);
}
(0, _flopflip_react.setDisplayName)((0, _flopflip_react.wrapDisplayName)(WrappedComponent, "injectFeatureToggle"));
return WrappedComponent;
};
//#endregion
//#region src/inject-feature-toggles.tsx
const injectFeatureToggles = (flagNames, propKey = _flopflip_react.DEFAULT_FLAGS_PROP_KEY) => (Component) => {
function WrappedComponent(ownProps) {
const flagVariations = useFlagVariations(flagNames);
const flags = Object.fromEntries(flagNames.map((flagName, indexOfFlagName) => [flagName, flagVariations[indexOfFlagName]]));
const props = _objectSpread2(_objectSpread2({}, ownProps), {}, { [propKey]: flags });
return /* @__PURE__ */ react.default.createElement(Component, props);
}
(0, _flopflip_react.setDisplayName)((0, _flopflip_react.wrapDisplayName)(WrappedComponent, "injectFeatureToggles"));
return WrappedComponent;
};
//#endregion
//#region \0@oxc-project+runtime@0.134.0/helpers/esm/objectWithoutPropertiesLoose.js
function _objectWithoutPropertiesLoose(r, e) {
if (null == r) return {};
var t = {};
for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
if (e.includes(n)) continue;
t[n] = r[n];
}
return t;
}
//#endregion
//#region \0@oxc-project+runtime@0.134.0/helpers/esm/objectWithoutProperties.js
function _objectWithoutProperties(e, t) {
if (null == e) return {};
var o, r, i = _objectWithoutPropertiesLoose(e, t);
if (Object.getOwnPropertySymbols) {
var s = Object.getOwnPropertySymbols(e);
for (r = 0; r < s.length; r++) o = s[r], t.includes(o) || {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
}
return i;
}
//#endregion
//#region src/toggle-feature.tsx
const _excluded = ["flag", "variation"];
function ToggleFeature(_ref) {
let { flag, variation } = _ref, remainingProps = _objectWithoutProperties(_ref, _excluded);
const isFeatureEnabled = useFeatureToggle(flag, variation);
return /* @__PURE__ */ react.default.createElement(_flopflip_react.ToggleFeature, _objectSpread2(_objectSpread2({
flag,
variation
}, remainingProps), {}, { isFeatureEnabled }));
}
ToggleFeature.displayName = "ToggleFeature";
//#endregion
//#region src/use-adapter-status.ts
function useAdapterStatus({ adapterIdentifiers } = {}) {
const adapterStatus = (0, react_redux.useSelector)(selectStatus({ adapterIdentifiers }));
(0, react.useDebugValue)({ adapterStatus });
return adapterStatus;
}
//#endregion
//#region src/use-all-feature-toggles.ts
function useAllFeatureToggles() {
const adapterContext = (0, _flopflip_react.useAdapterContext)();
const allFlags = (0, react_redux.useSelector)(selectFlags());
return [...adapterContext.adapterEffectIdentifiers].toReversed().reduce((_allFlags, adapterIdentifier) => _objectSpread2(_objectSpread2({}, _allFlags), allFlags[adapterIdentifier]), {});
}
//#endregion
//#region src/use-feature-toggles.ts
function useFeatureToggles(flags) {
const allFlags = (0, react_redux.useSelector)(selectFlags());
const adapterContext = (0, _flopflip_react.useAdapterContext)();
return Object.entries(flags).reduce((previousFlags, [flagName, flagVariation]) => {
const isFeatureEnabled = (0, _flopflip_react.getIsFeatureEnabled)(allFlags, adapterContext.adapterEffectIdentifiers, flagName, flagVariation);
previousFlags.push(isFeatureEnabled);
return previousFlags;
}, []);
}
//#endregion
//#region src/use-flag-variation.ts
function useFlagVariation(flagName) {
const [flagVariation] = useFlagVariations([flagName]);
return flagVariation;
}
//#endregion
//#region src/index.ts
const version = "__@FLOPFLIP/VERSION_OF_RELEASE__";
//#endregion
exports.ConfigureFlopFlip = Configure;
exports.FLOPFLIP_STATE_SLICE = STATE_SLICE;
Object.defineProperty(exports, "ReconfigureFlopFlip", {
enumerable: true,
get: function() {
return _flopflip_react.ReconfigureAdapter;
}
});
exports.ToggleFeature = ToggleFeature;
exports.branchOnFeatureToggle = branchOnFeatureToggle;
exports.createFlopFlipEnhancer = createFlopFlipEnhancer;
exports.createFlopflipReducer = createFlopflipReducer;
exports.flopflipReducer = flopflipReducer;
exports.injectFeatureToggle = injectFeatureToggle;
exports.injectFeatureToggles = injectFeatureToggles;
exports.selectFeatureFlag = selectFlag;
exports.selectFeatureFlags = selectFlags;
Object.defineProperty(exports, "useAdapterReconfiguration", {
enumerable: true,
get: function() {
return _flopflip_react.useAdapterReconfiguration;
}
});
exports.useAdapterStatus = useAdapterStatus;
exports.useAllFeatureToggles = useAllFeatureToggles;
exports.useFeatureToggle = useFeatureToggle;
exports.useFeatureToggles = useFeatureToggles;
exports.useFlagVariation = useFlagVariation;
exports.useFlagVariations = useFlagVariations;
exports.version = version;
//# sourceMappingURL=index.cjs.map