UNPKG

@splitsoftware/splitio-react

Version:

A React library to easily integrate and use Split JS SDK

77 lines (76 loc) 4.45 kB
import { __assign } from "tslib"; import * as React from 'react'; import { useSplitContext } from './SplitContext'; import { getSplitClient, initAttributes, getStatus } from './utils'; /** * `useSplitClient` is a hook that returns an Split Context object with the client and its status corresponding to the provided key. * * @param options - An options object with an optional `splitKey` to retrieve the client, optional `attributes` to configure the client, and update options to control on which SDK events the hook should update. * @returns A Split Context object merged with the client and its status. * * @example * ```js * const { factory, client, isReady, isReadyFromCache, hasTimedout, lastUpdate } = useSplitClient({ splitKey: 'user_id' }); * ``` * * @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#advanced-instantiate-multiple-sdk-clients} */ export function useSplitClient(options) { if (options === void 0) { options = {}; } var context = useSplitContext(); var contextClient = context.client, factory = context.factory; var splitKey = options.splitKey, attributes = options.attributes, _a = options.updateOnSdkReady, updateOnSdkReady = _a === void 0 ? context.updateOnSdkReady : _a, _b = options.updateOnSdkReadyFromCache, updateOnSdkReadyFromCache = _b === void 0 ? context.updateOnSdkReadyFromCache : _b, _c = options.updateOnSdkTimedout, updateOnSdkTimedout = _c === void 0 ? context.updateOnSdkTimedout : _c, _d = options.updateOnSdkUpdate, updateOnSdkUpdate = _d === void 0 ? context.updateOnSdkUpdate : _d; // @TODO Move `getSplitClient` side effects and reduce the function cognitive complexity // @TODO Once `SplitClient` is removed, which updates the context, simplify next line as `const client = factory ? getSplitClient(factory, splitKey) : undefined;` var client = factory && splitKey ? getSplitClient(factory, splitKey) : contextClient; initAttributes(client, attributes); var _e = React.useState(0), lastUpdate = _e[0], setLastUpdate = _e[1]; // `getStatus` is not pure. Its result depends on `client` and `lastUpdate` // eslint-disable-next-line react-hooks/exhaustive-deps var status = React.useMemo(function () { return getStatus(client); }, [client, lastUpdate]); // Handle client events React.useEffect(function () { if (!client) return; var update = function () { return setLastUpdate(getStatus(client).lastUpdate); }; // Clients are created on the hook's call, so the status may have changed var statusOnEffect = getStatus(client); // Subscribe to SDK events if (updateOnSdkReady !== false) { if (!statusOnEffect.isReady) client.once(client.Event.SDK_READY, update); else if (!status.isReady) update(); } if (updateOnSdkReadyFromCache !== false) { if (!statusOnEffect.isReadyFromCache) client.once(client.Event.SDK_READY_FROM_CACHE, update); else if (!status.isReadyFromCache) update(); } if (updateOnSdkTimedout !== false) { if (!statusOnEffect.hasTimedout) { // Required to avoid error log for event already emitted if (!statusOnEffect.isReady) client.once(client.Event.SDK_READY_TIMED_OUT, update); } else { if (!status.hasTimedout) update(); } } if (updateOnSdkUpdate !== false) { client.on(client.Event.SDK_UPDATE, update); if (statusOnEffect.isReady && statusOnEffect.lastUpdate > status.lastUpdate) update(); } return function () { // Unsubscribe from events client.off(client.Event.SDK_READY, update); client.off(client.Event.SDK_READY_FROM_CACHE, update); client.off(client.Event.SDK_READY_TIMED_OUT, update); client.off(client.Event.SDK_UPDATE, update); }; }, [client, updateOnSdkReady, updateOnSdkReadyFromCache, updateOnSdkTimedout, updateOnSdkUpdate, status]); return __assign(__assign({ factory: factory, client: client }, status), { updateOnSdkReady: updateOnSdkReady, updateOnSdkReadyFromCache: updateOnSdkReadyFromCache, updateOnSdkTimedout: updateOnSdkTimedout, updateOnSdkUpdate: updateOnSdkUpdate }); }