@flipt-io/flipt-client-react
Version:
Flipt Client Evaluation React SDK
459 lines (433 loc) • 17.9 kB
JavaScript
;
var require$$0 = require('react');
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function __generator(thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
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;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
}
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
var shim = {exports: {}};
var useSyncExternalStoreShim_production = {};
/**
* @license React
* use-sync-external-store-shim.production.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var hasRequiredUseSyncExternalStoreShim_production;
function requireUseSyncExternalStoreShim_production () {
if (hasRequiredUseSyncExternalStoreShim_production) return useSyncExternalStoreShim_production;
hasRequiredUseSyncExternalStoreShim_production = 1;
var React = require$$0;
function is(x, y) {
return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);
}
var objectIs = "function" === typeof Object.is ? Object.is : is,
useState = React.useState,
useEffect = React.useEffect,
useLayoutEffect = React.useLayoutEffect,
useDebugValue = React.useDebugValue;
function useSyncExternalStore$2(subscribe, getSnapshot) {
var value = getSnapshot(),
_useState = useState({ inst: { value: value, getSnapshot: getSnapshot } }),
inst = _useState[0].inst,
forceUpdate = _useState[1];
useLayoutEffect(
function () {
inst.value = value;
inst.getSnapshot = getSnapshot;
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
},
[subscribe, value, getSnapshot]
);
useEffect(
function () {
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
return subscribe(function () {
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
});
},
[subscribe]
);
useDebugValue(value);
return value;
}
function checkIfSnapshotChanged(inst) {
var latestGetSnapshot = inst.getSnapshot;
inst = inst.value;
try {
var nextValue = latestGetSnapshot();
return !objectIs(inst, nextValue);
} catch (error) {
return true;
}
}
function useSyncExternalStore$1(subscribe, getSnapshot) {
return getSnapshot();
}
var shim =
"undefined" === typeof window ||
"undefined" === typeof window.document ||
"undefined" === typeof window.document.createElement
? useSyncExternalStore$1
: useSyncExternalStore$2;
useSyncExternalStoreShim_production.useSyncExternalStore =
void 0 !== React.useSyncExternalStore ? React.useSyncExternalStore : shim;
return useSyncExternalStoreShim_production;
}
var useSyncExternalStoreShim_development = {};
/**
* @license React
* use-sync-external-store-shim.development.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var hasRequiredUseSyncExternalStoreShim_development;
function requireUseSyncExternalStoreShim_development () {
if (hasRequiredUseSyncExternalStoreShim_development) return useSyncExternalStoreShim_development;
hasRequiredUseSyncExternalStoreShim_development = 1;
"production" !== process.env.NODE_ENV &&
(function () {
function is(x, y) {
return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);
}
function useSyncExternalStore$2(subscribe, getSnapshot) {
didWarnOld18Alpha ||
void 0 === React.startTransition ||
((didWarnOld18Alpha = true),
console.error(
"You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."
));
var value = getSnapshot();
if (!didWarnUncachedGetSnapshot) {
var cachedValue = getSnapshot();
objectIs(value, cachedValue) ||
(console.error(
"The result of getSnapshot should be cached to avoid an infinite loop"
),
(didWarnUncachedGetSnapshot = true));
}
cachedValue = useState({
inst: { value: value, getSnapshot: getSnapshot }
});
var inst = cachedValue[0].inst,
forceUpdate = cachedValue[1];
useLayoutEffect(
function () {
inst.value = value;
inst.getSnapshot = getSnapshot;
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
},
[subscribe, value, getSnapshot]
);
useEffect(
function () {
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
return subscribe(function () {
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
});
},
[subscribe]
);
useDebugValue(value);
return value;
}
function checkIfSnapshotChanged(inst) {
var latestGetSnapshot = inst.getSnapshot;
inst = inst.value;
try {
var nextValue = latestGetSnapshot();
return !objectIs(inst, nextValue);
} catch (error) {
return true;
}
}
function useSyncExternalStore$1(subscribe, getSnapshot) {
return getSnapshot();
}
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
"function" ===
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart &&
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
var React = require$$0,
objectIs = "function" === typeof Object.is ? Object.is : is,
useState = React.useState,
useEffect = React.useEffect,
useLayoutEffect = React.useLayoutEffect,
useDebugValue = React.useDebugValue,
didWarnOld18Alpha = false,
didWarnUncachedGetSnapshot = false,
shim =
"undefined" === typeof window ||
"undefined" === typeof window.document ||
"undefined" === typeof window.document.createElement
? useSyncExternalStore$1
: useSyncExternalStore$2;
useSyncExternalStoreShim_development.useSyncExternalStore =
void 0 !== React.useSyncExternalStore ? React.useSyncExternalStore : shim;
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
"function" ===
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
})();
return useSyncExternalStoreShim_development;
}
var hasRequiredShim;
function requireShim () {
if (hasRequiredShim) return shim.exports;
hasRequiredShim = 1;
if (process.env.NODE_ENV === 'production') {
shim.exports = requireUseSyncExternalStoreShim_production();
} else {
shim.exports = requireUseSyncExternalStoreShim_development();
}
return shim.exports;
}
var shimExports = requireShim();
var useStore = function (options) {
var storeRef = require$$0.useRef({
client: null,
isLoading: true,
error: null,
subscribe: function (listener) {
listeners.add(listener);
return function () { return listeners.delete(listener); };
},
attach: function () {
mountedRef.current = true;
setupPolling();
},
detach: function () {
mountedRef.current = false;
clearInterval(intervalIdRef.current);
intervalIdRef.current = undefined;
}
});
var listeners = require$$0.useMemo(function () { return new Set(); }, []);
var notify = require$$0.useCallback(function () {
listeners.forEach(function (l) { return l(); });
}, [listeners]);
var intervalIdRef = require$$0.useRef(undefined);
var mountedRef = require$$0.useRef(false);
var setupPolling = require$$0.useCallback(function () {
// Default to 120 seconds if updateInterval is not set
var interval = (options.updateInterval !== undefined ? options.updateInterval : 120) *
1000;
if (interval > 0 &&
mountedRef.current &&
storeRef.current.client !== null &&
intervalIdRef.current === undefined) {
intervalIdRef.current = setInterval(function () {
if (typeof window !== 'undefined' &&
navigator.onLine &&
storeRef.current.client) {
storeRef.current.client
.refresh()
.then(function (updated) {
if (updated) {
notify();
}
})
.catch(function (error) {
console.error('Error refreshing client:', error);
storeRef.current.error = error;
notify();
});
}
}, interval);
}
}, [options, notify]);
require$$0.useEffect(function () {
mountedRef.current = true;
return function () {
mountedRef.current = false;
if (intervalIdRef.current) {
clearInterval(intervalIdRef.current);
intervalIdRef.current = undefined;
}
};
}, []);
require$$0.useEffect(function () {
var isMounted = true;
var initializeClient = function () { return __awaiter(void 0, void 0, void 0, function () {
var FliptClient_1, client, err_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 3, , 4]);
return [4 /*yield*/, import('@flipt-io/flipt-client-js')];
case 1:
FliptClient_1 = (_a.sent()).FliptClient;
return [4 /*yield*/, FliptClient_1.init(__assign({}, options))];
case 2:
client = _a.sent();
if (isMounted) {
storeRef.current.client = client;
storeRef.current.isLoading = false;
setupPolling();
notify();
}
return [3 /*break*/, 4];
case 3:
err_1 = _a.sent();
if (isMounted) {
console.error('Error initializing client:', err_1);
storeRef.current.error = err_1;
storeRef.current.isLoading = false;
notify();
}
return [3 /*break*/, 4];
case 4: return [2 /*return*/];
}
});
}); };
initializeClient().catch(function (err) {
console.error('Unhandled error in initializeClient:', err);
if (isMounted) {
storeRef.current.error = err;
storeRef.current.isLoading = false;
notify();
}
});
return function () {
isMounted = false;
};
}, [options, notify, setupPolling]);
return storeRef.current;
};
var FliptContext = require$$0.createContext(null);
var useFliptContext = function () {
var context = require$$0.useContext(FliptContext);
if (context === null) {
throw new Error('useFliptContext must be used within a FliptProvider');
}
return context;
};
var useFliptSelector = function (selector) {
var store = require$$0.useContext(FliptContext);
if (store === null) {
throw new Error('useFliptSelector must be used within a FliptProvider');
}
var selectorWrapper = require$$0.useCallback(function () {
return selector(store.client, store.isLoading, store.error);
}, [store, selector]);
return shimExports.useSyncExternalStore(store.subscribe, selectorWrapper, selectorWrapper);
};
var useFliptBoolean = function (flagKey, fallback, entityId, context) {
if (context === void 0) { context = {}; }
var result = useFliptSelector(function (client, isLoading, error) {
if (client && !isLoading && !error) {
try {
return client.evaluateBoolean({
flagKey: flagKey,
entityId: entityId,
context: context
}).enabled;
}
catch (e) {
console.error("Error evaluating boolean flag ".concat(flagKey, ":"), e);
}
}
return fallback;
});
return result;
};
var useFliptVariant = function (flagKey, fallback, entityId, context) {
if (context === void 0) { context = {}; }
var result = useFliptSelector(function (client, isLoading, error) {
if (client && !isLoading && !error) {
try {
return client.evaluateVariant({
flagKey: flagKey,
entityId: entityId,
context: context
}).variantKey;
}
catch (e) {
console.error("Error evaluating variant flag ".concat(flagKey, ":"), e);
}
}
return fallback;
});
return result;
};
var FliptProvider = function (_a) {
var children = _a.children, options = _a.options;
var store = require$$0.useState(useStore(options))[0];
require$$0.useEffect(function () {
store.attach();
return function () {
store.detach();
};
}, [store]);
return (require$$0.createElement(FliptContext.Provider, { value: store }, children));
};
exports.FliptProvider = FliptProvider;
exports.useFliptBoolean = useFliptBoolean;
exports.useFliptContext = useFliptContext;
exports.useFliptSelector = useFliptSelector;
exports.useFliptVariant = useFliptVariant;
//# sourceMappingURL=index.cjs.map