UNPKG

@toggle.tiger/toggletiger

Version:

A package to retrieve configuration from blobstore based on org, app, env, and config ID.

101 lines (100 loc) 4.43 kB
var __awaiter = (this && this.__awaiter) || function (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()); }); }; import { jsx as _jsx } from "react/jsx-runtime"; import axios from "axios"; import { createContext, useEffect, useRef, useState } from "react"; const initialState = { environmentFlags: null }; export const FeatureFlagContext = createContext(initialState); export const FeatureFlagProvider = ({ children, sdkKey, baseUrl = "http://127.0.0.1:10000/devstoreaccount1/configurations", pollingInterval }) => { const [environmentFlags, setEnvironmentFlags] = useState(null); const isLoadingRef = useRef(false); const loadConfig = () => __awaiter(void 0, void 0, void 0, function* () { if (isLoadingRef.current) { return; } isLoadingRef.current = true; try { const etagKey = `toggletiger_etag_${sdkKey}`; const lastModifiedKey = `toggletiger_lastmod_${sdkKey}`; const flagsKey = `toggletiger_flags_${sdkKey}`; const cachedETag = localStorage.getItem(etagKey); const cachedLastModified = localStorage.getItem(lastModifiedKey); const cachedFlagsJson = localStorage.getItem(flagsKey); let cachedFlags = null; if (cachedFlagsJson) { try { cachedFlags = JSON.parse(cachedFlagsJson); if (cachedFlags) { setEnvironmentFlags(cachedFlags); } } catch (_a) { // Ignore parsing errors } } const configUrl = `${baseUrl}/${sdkKey}`; const headers = {}; if (cachedETag) { headers["If-None-Match"] = cachedETag; } if (cachedLastModified) { headers["If-Modified-Since"] = cachedLastModified; } const response = yield axios.get(configUrl, { headers, validateStatus: (status) => status === 200 || status === 304 }); if (response.status === 304) { return; } if (response.status === 200) { const newETag = response.headers.etag || response.headers.ETag; const newLastModified = response.headers["last-modified"] || response.headers["Last-Modified"]; if (newETag) { localStorage.setItem(etagKey, newETag); } if (newLastModified) { localStorage.setItem(lastModifiedKey, newLastModified); } const config = response.data; if (config) { setEnvironmentFlags(config.environmentFlags); localStorage.setItem(flagsKey, JSON.stringify(config.environmentFlags)); } } } catch (error) { if (axios.isAxiosError(error) && error.response) { const status = error.response.status; if (status === 304 || status === 412) { return; } } setEnvironmentFlags(null); } finally { isLoadingRef.current = false; } }); // biome-ignore lint/correctness/useExhaustiveDependencies: sdkKey and baseUrl are stable props useEffect(() => { loadConfig(); if (pollingInterval && pollingInterval > 0) { const intervalId = setInterval(() => { loadConfig(); }, pollingInterval); return () => clearInterval(intervalId); } }, [sdkKey, baseUrl, pollingInterval]); return (_jsx(FeatureFlagContext.Provider, { value: { environmentFlags }, children: children })); };