@flags-sdk/statsig
Version:
Statsig provider for the Flags SDK
202 lines (199 loc) • 6.99 kB
JavaScript
import {
getProviderData
} from "./chunk-U4AIHMP7.js";
// src/index.ts
import Statsig2 from "statsig-node-lite";
// src/edge-runtime-hooks.ts
import Statsig from "statsig-node-lite";
async function createEdgeConfigDataAdapter(options) {
const { EdgeConfigDataAdapter } = await import("statsig-node-vercel");
const { createClient } = await import("@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 = Statsig.syncConfigSpecs().finally(() => {
isSyncingConfigSpecs = false;
nextConfigSpecSyncTime = Date.now() + minSyncDelayMs;
});
import("@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 Statsig2.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 Statsig2;
};
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();
syncHandler?.();
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 = 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 = opts?.exposureLogging ? Statsig2.getFeatureGateSync(user, key) : Statsig2.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 = key.split(".")[0] ?? "";
const config = opts?.exposureLogging ? Statsig2.getConfigSync(user, configKey) : Statsig2.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 = opts?.exposureLogging ? Statsig2.getExperimentSync(user, key) : Statsig2.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 = opts?.exposureLogging ? Statsig2.getConfigSync(user, key) : Statsig2.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 = opts?.exposureLogging ? Statsig2.getLayerSync(user, key) : Statsig2.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()
};
export {
Statsig2 as Statsig,
createDefaultStatsigAdapter,
createStatsigAdapter,
getProviderData,
resetDefaultStatsigAdapter,
statsigAdapter
};
//# sourceMappingURL=index.js.map