UNPKG

@flags-sdk/statsig

Version:

Statsig provider for the Flags SDK

202 lines (190 loc) 8.98 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _chunkVSGLINUCcjs = require('./chunk-VSGLINUC.cjs'); // src/index.ts var _statsignodelite = require('statsig-node-lite'); var _statsignodelite2 = _interopRequireDefault(_statsignodelite); // src/edge-runtime-hooks.ts async function createEdgeConfigDataAdapter(options) { const { EdgeConfigDataAdapter } = await Promise.resolve().then(() => _interopRequireWildcard(require("statsig-node-vercel"))); const { createClient } = await Promise.resolve().then(() => _interopRequireWildcard(require("@vercel/edge-config"))); return new EdgeConfigDataAdapter({ edgeConfigItemKey: options.edgeConfigItemKey, edgeConfigClient: createClient(options.edgeConfigConnectionString, { // We disable the development cache as Statsig caches for 10 seconds internally, // and we want to avoid situations where Statsig tries to read the latest value, // but hits the development cache and then caches the outdated value for another 10 seconds, // as this would lead to the developer having to wait 20 seconds to see the latest value. disableDevelopmentCache: true }) }); } var createSyncingHandler = (minSyncDelayMs) => { let isSyncingConfigSpecs = false; let nextConfigSpecSyncTime = Date.now() + minSyncDelayMs; return () => { if (Date.now() >= nextConfigSpecSyncTime && !isSyncingConfigSpecs) { try { isSyncingConfigSpecs = true; const sync = _statsignodelite2.default.syncConfigSpecs().finally(() => { isSyncingConfigSpecs = false; nextConfigSpecSyncTime = Date.now() + minSyncDelayMs; }); Promise.resolve().then(() => _interopRequireWildcard(require("@vercel/functions"))).then(({ waitUntil }) => { waitUntil(sync); }); } catch (e) { } } }; }; // src/index.ts function createStatsigAdapter(options) { const initializeStatsig = async () => { let dataAdapter; if (options.edgeConfig) { dataAdapter = await createEdgeConfigDataAdapter({ edgeConfigItemKey: options.edgeConfig.itemKey, edgeConfigConnectionString: options.edgeConfig.connectionString }); } await _statsignodelite2.default.initialize(options.statsigServerApiKey, { dataAdapter, // ID list syncing is disabled by default // Can be opted in using `options.statsigOptions` initStrategyForIDLists: "none", disableIdListsSync: true, // Set a shorter interval during development so developers see changes earlier rulesetsSyncIntervalMs: process.env.NODE_ENV === "development" ? 5e3 : void 0, ...options.statsigOptions }); }; let _initializePromise; const initialize = async () => { if (!_initializePromise) { _initializePromise = initializeStatsig(); } await _initializePromise; return _statsignodelite2.default; }; const isStatsigUser = (user) => { return user != null && typeof user === "object"; }; const minSyncDelayMs = options.edgeConfig ? 1e3 : 5e3; const syncHandler = createSyncingHandler(minSyncDelayMs); async function predecide(user) { await initialize(); _optionalChain([syncHandler, 'optionalCall', _ => _()]); if (!isStatsigUser(user)) { throw new Error( "@flags-sdk/statsig: Invalid or missing statsigUser from identify. See https://flags-sdk.dev/concepts/identify" ); } return user; } function origin(prefix) { if (!options.statsigProjectId) { return () => void 0; } return (key) => { const keyPart = _nullishCoalesce(key.split(".")[0], () => ( "")); return `https://console.statsig.com/${options.statsigProjectId}/${prefix}/${keyPart}`; }; } function featureGate(getValue, opts) { return { origin: origin("gates"), decide: async ({ key, entities }) => { const user = await predecide(entities); const gate = _optionalChain([opts, 'optionalAccess', _2 => _2.exposureLogging]) ? _statsignodelite2.default.getFeatureGateSync(user, key) : _statsignodelite2.default.getFeatureGateWithExposureLoggingDisabledSync(user, key); return getValue(gate); } }; } function dynamicConfig(getValue, opts) { return { origin: origin("dynamic_configs"), decide: async ({ key, entities }) => { const user = await predecide(entities); const configKey = _nullishCoalesce(key.split(".")[0], () => ( "")); const config = _optionalChain([opts, 'optionalAccess', _3 => _3.exposureLogging]) ? _statsignodelite2.default.getConfigSync(user, configKey) : _statsignodelite2.default.getConfigWithExposureLoggingDisabledSync(user, configKey); return getValue(config); } }; } function experiment(getValue, opts) { return { origin: origin("experiments"), decide: async ({ key, entities }) => { const user = await predecide(entities); const experiment2 = _optionalChain([opts, 'optionalAccess', _4 => _4.exposureLogging]) ? _statsignodelite2.default.getExperimentSync(user, key) : _statsignodelite2.default.getExperimentWithExposureLoggingDisabledSync(user, key); return getValue(experiment2); } }; } function autotune(getValue, opts) { return { origin: origin("autotune"), decide: async ({ key, entities }) => { const user = await predecide(entities); const autotune2 = _optionalChain([opts, 'optionalAccess', _5 => _5.exposureLogging]) ? _statsignodelite2.default.getConfigSync(user, key) : _statsignodelite2.default.getConfigWithExposureLoggingDisabledSync(user, key); return getValue(autotune2); } }; } function layer(getValue, opts) { return { origin: origin("layers"), decide: async ({ key, entities }) => { const user = await predecide(entities); const layer2 = _optionalChain([opts, 'optionalAccess', _6 => _6.exposureLogging]) ? _statsignodelite2.default.getLayerSync(user, key) : _statsignodelite2.default.getLayerWithExposureLoggingDisabledSync(user, key); return getValue(layer2); } }; } return { featureGate, dynamicConfig, experiment, autotune, layer, initialize }; } var defaultStatsigAdapter; function resetDefaultStatsigAdapter() { defaultStatsigAdapter = void 0; } function createDefaultStatsigAdapter() { if (defaultStatsigAdapter) { return defaultStatsigAdapter; } const statsigServerApiKey = process.env.STATSIG_SERVER_API_KEY; const statsigProjectId = process.env.STATSIG_PROJECT_ID; const edgeConfig = process.env.EXPERIMENTATION_CONFIG; const edgeConfigItemKey = process.env.EXPERIMENTATION_CONFIG_ITEM_KEY; if (!(edgeConfig && edgeConfigItemKey)) { defaultStatsigAdapter = createStatsigAdapter({ statsigServerApiKey, statsigProjectId }); } else { defaultStatsigAdapter = createStatsigAdapter({ statsigServerApiKey, edgeConfig: { connectionString: edgeConfig, itemKey: edgeConfigItemKey }, statsigProjectId }); } return defaultStatsigAdapter; } var statsigAdapter = { featureGate: (...args) => createDefaultStatsigAdapter().featureGate(...args), dynamicConfig: (...args) => createDefaultStatsigAdapter().dynamicConfig(...args), experiment: (...args) => createDefaultStatsigAdapter().experiment(...args), autotune: (...args) => createDefaultStatsigAdapter().autotune(...args), layer: (...args) => createDefaultStatsigAdapter().layer(...args), initialize: () => createDefaultStatsigAdapter().initialize() }; exports.Statsig = _statsignodelite2.default; exports.createDefaultStatsigAdapter = createDefaultStatsigAdapter; exports.createStatsigAdapter = createStatsigAdapter; exports.getProviderData = _chunkVSGLINUCcjs.getProviderData; exports.resetDefaultStatsigAdapter = resetDefaultStatsigAdapter; exports.statsigAdapter = statsigAdapter; //# sourceMappingURL=index.cjs.map