New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

@reforge-com/javascript

Package Overview
Dependencies
Maintainers
3
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@reforge-com/javascript - npm Package Compare versions

Comparing version
0.0.4
to
0.0.5
+37
-2
dist/index.cjs

@@ -76,5 +76,5 @@ "use strict";

module2.exports = {
packageManager: "yarn@4.9.2",
packageManager: "yarn@4.11.0",
name: "@reforge-com/javascript",
version: "0.0.4",
version: "0.0.5",
description: "Feature Flags & Dynamic Configuration as a Service",

@@ -103,2 +103,3 @@ main: "dist/index.cjs",

jest: "^29.0.0",
"jest-environment-jsdom": "^30.2.0",
"jest-fetch-mock": "^3.0.3",

@@ -155,2 +156,3 @@ prettier: "^3.0.0",

getLogLevelSeverity: () => getLogLevelSeverity,
prefetchReforgeConfig: () => prefetchReforgeConfig,
reforge: () => reforge,

@@ -566,2 +568,14 @@ shouldLogAtLevel: () => shouldLogAtLevel,

};
const prefetchPromise = typeof window !== "undefined" ? window.REFORGE_SDK_PREFETCH_PROMISE : void 0;
if (prefetchPromise && prefetchPromise instanceof Promise) {
window.REFORGE_SDK_PREFETCH_PROMISE = void 0;
return prefetchPromise.catch(
() => (
// If the prefetch failed, we should try to load from the endpoints
new Promise((resolve, reject) => {
this.loadFromEndpoint(0, options, resolve, reject);
})
)
);
}
const promise = new Promise((resolve, reject) => {

@@ -997,2 +1011,22 @@ this.loadFromEndpoint(0, options, resolve, reject);

var reforge = new Reforge();
function prefetchReforgeConfig({
sdkKey,
context,
endpoints = void 0,
timeout = void 0,
collectContextMode = "PERIODIC_EXAMPLE",
clientNameString = "sdk-javascript",
clientVersionString = version
}) {
const clientNameAndVersionString = `${clientNameString}-${clientVersionString}`;
const loader = new Loader({
sdkKey,
context,
endpoints,
timeout,
collectContextMode,
clientVersion: clientNameAndVersionString
});
window.REFORGE_SDK_PREFETCH_PROMISE = loader.load();
}

@@ -1008,2 +1042,3 @@ // index.ts

getLogLevelSeverity,
prefetchReforgeConfig,
reforge,

@@ -1010,0 +1045,0 @@ shouldLogAtLevel,

+1
-1

@@ -1,1 +0,1 @@

{"version":3,"sources":["../package.json","../index.ts","../src/reforge.ts","../src/config.ts","../src/base64Encode.ts","../src/context.ts","../src/exponentialBackoff.ts","../src/logger.ts","../src/periodicSync.ts","../src/evaluationSummaryAggregator.ts","../src/apiHelpers.ts","../src/loader.ts","../src/telemetryUploader.ts","../src/loggerAggregator.ts"],"sourcesContent":["{\n \"packageManager\": \"yarn@4.9.2\",\n \"name\": \"@reforge-com/javascript\",\n \"version\": \"0.0.4\",\n \"description\": \"Feature Flags & Dynamic Configuration as a Service\",\n \"main\": \"dist/index.cjs\",\n \"module\": \"dist/index.mjs\",\n \"types\": \"dist/index.d.ts\",\n \"author\": \"Jeffrey Chupp\",\n \"license\": \"ISC\",\n \"devDependencies\": {\n \"@types/eslint-plugin-jsx-a11y\": \"^6\",\n \"@types/express\": \"^4.17.13\",\n \"@types/jest\": \"^28.1.6\",\n \"@types/uuid\": \"^9.0.5\",\n \"@typescript-eslint/eslint-plugin\": \"^5.33.0\",\n \"@typescript-eslint/parser\": \"^5.33.0\",\n \"esbuild\": \"^0.25.11\",\n \"eslint\": \"^8.21.0\",\n \"eslint-config-airbnb\": \"^19.0.4\",\n \"eslint-config-airbnb-typescript\": \"^17.0.0\",\n \"eslint-config-prettier\": \"^8.8.0\",\n \"eslint-plugin-import\": \"^2.26.0\",\n \"eslint-plugin-jest\": \"^26.8.0\",\n \"eslint-plugin-jsx-a11y\": \"^6.10.2\",\n \"eslint-plugin-react\": \"^7.37.5\",\n \"jest\": \"^29.0.0\",\n \"jest-fetch-mock\": \"^3.0.3\",\n \"prettier\": \"^3.0.0\",\n \"ts-jest\": \"^29.1.1\",\n \"ts-node\": \"^10.9.1\",\n \"tsup\": \"^8.0.2\",\n \"typescript\": \"^5.1.6\"\n },\n \"scripts\": {\n \"build\": \"rm -rf dist/ && tsup\",\n \"dev\": \"tsup --watch\",\n \"bundle\": \"esbuild --minify --target=esnext --bundle --outfile=dist/reforge.bundle.js --global-name=window.reforgeNamespace dist/index.cjs && echo 'window.reforge = window.reforgeNamespace.reforge' >> dist/reforge.bundle.js\",\n \"lint\": \"eslint --ext .ts,.tsx src/\",\n \"lint:fix\": \"eslint --fix --ext .ts,.tsx src/\",\n \"prettier\": \"prettier . -l\",\n \"prettier:fix\": \"prettier --write .\",\n \"test\": \"jest --verbose\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/ReforgeHQ/sdk-javascript.git\"\n },\n \"keywords\": [\n \"feature-flags\",\n \"config\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/ReforgeHQ/sdk-javascript/issues\"\n },\n \"homepage\": \"https://github.com/ReforgeHQ/sdk-javascript#readme\",\n \"dependencies\": {\n \"uuid\": \"^9.0.1\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.mjs\",\n \"require\": \"./dist/index.cjs\"\n }\n }\n}\n","import { reforge, Reforge, ReforgeInitParams, ReforgeBootstrap } from \"./src/reforge\";\nimport { Config } from \"./src/config\";\nimport Context from \"./src/context\";\nimport { LogLevel, getLogLevelSeverity, shouldLogAtLevel } from \"./src/logger\";\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version } = require(\"./package.json\");\n\nexport {\n reforge,\n Reforge,\n ReforgeInitParams,\n Config,\n Context,\n LogLevel,\n getLogLevelSeverity,\n shouldLogAtLevel,\n version,\n};\n\nexport { ReforgeBootstrap };\n\nexport type { ConfigValue } from \"./src/config\";\nexport type {\n Duration,\n ContextValue,\n Contexts,\n TypedFrontEndConfigurationRaw,\n FrontEndConfigurationRaw,\n} from \"./src/types\";\nexport type { CollectContextModeType } from \"./src/loader\";\n","/* eslint-disable max-classes-per-file */\nimport { v4 as uuid } from \"uuid\";\n\nimport { Config, EvaluationPayload, RawConfigWithoutTypes } from \"./config\";\nimport type {\n Duration,\n TypedFrontEndConfigurationRaw,\n FrontEndConfigurationRaw,\n Contexts,\n} from \"./types\";\nimport Context from \"./context\";\nimport { EvaluationSummaryAggregator } from \"./evaluationSummaryAggregator\";\nimport Loader, { CollectContextModeType } from \"./loader\";\nimport {\n PREFIX as loggerPrefix,\n shouldLog,\n ShouldLogParams,\n LogLevel,\n shouldLogAtLevel,\n} from \"./logger\";\nimport TelemetryUploader from \"./telemetryUploader\";\nimport { LoggerAggregator } from \"./loggerAggregator\";\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version } = require(\"../package.json\");\n\ntype EvaluationCallback = <K extends keyof TypedFrontEndConfigurationRaw>(\n key: K,\n value: TypedFrontEndConfigurationRaw[K],\n context: Context | undefined\n) => void;\n\nexport interface ReforgeBootstrap {\n evaluations: EvaluationPayload;\n context: Contexts;\n}\n\nexport type ReforgeInitParams = {\n sdkKey: string;\n context: Context;\n endpoints?: string[] | undefined;\n apiEndpoint?: string;\n timeout?: number;\n afterEvaluationCallback?: EvaluationCallback;\n collectEvaluationSummaries?: boolean;\n collectLoggerNames?: boolean;\n collectContextMode?: CollectContextModeType;\n clientNameString?: string;\n clientVersionString?: string;\n loggerKey?: string;\n};\n\ntype PollStatus =\n | { status: \"not-started\" }\n | { status: \"pending\" }\n | { status: \"stopped\" }\n | { status: \"running\"; frequencyInMs: number };\n\ntype PublicShouldLogParams = Omit<ShouldLogParams, \"get\">;\n\n// Forward declaration for ReforgeLogger\n// eslint-disable-next-line @typescript-eslint/no-use-before-define\nclass ReforgeLogger {\n // eslint-disable-next-line no-use-before-define\n private reforge: Reforge;\n\n // eslint-disable-next-line no-use-before-define\n constructor(reforge: Reforge) {\n this.reforge = reforge;\n }\n\n private log(message: string, level: LogLevel): void {\n const configuredLevel = this.reforge.getLogLevel(\"\");\n\n if (shouldLogAtLevel(configuredLevel, level)) {\n switch (level) {\n case LogLevel.TRACE:\n case LogLevel.DEBUG:\n // eslint-disable-next-line no-console\n console.debug(message);\n break;\n case LogLevel.INFO:\n // eslint-disable-next-line no-console\n console.info(message);\n break;\n case LogLevel.WARN:\n // eslint-disable-next-line no-console\n console.warn(message);\n break;\n case LogLevel.ERROR:\n case LogLevel.FATAL:\n // eslint-disable-next-line no-console\n console.error(message);\n break;\n default:\n // eslint-disable-next-line no-console\n console.error(message);\n }\n }\n }\n\n trace(message: string): void {\n this.log(message, LogLevel.TRACE);\n }\n\n debug(message: string): void {\n this.log(message, LogLevel.DEBUG);\n }\n\n info(message: string): void {\n this.log(message, LogLevel.INFO);\n }\n\n warn(message: string): void {\n this.log(message, LogLevel.WARN);\n }\n\n error(message: string): void {\n this.log(message, LogLevel.ERROR);\n }\n\n fatal(message: string): void {\n this.log(message, LogLevel.FATAL);\n }\n}\n\nexport class Reforge {\n private _configs: { [key: string]: Config } = {};\n\n private _telemetryUploader: TelemetryUploader | undefined;\n\n private _pollCount = 0;\n\n private _pollStatus: PollStatus = { status: \"not-started\" };\n\n private _pollTimeoutId = undefined as ReturnType<typeof setTimeout> | undefined;\n\n private _instanceHash: string = uuid();\n\n private collectEvaluationSummaries = true;\n\n private collectLoggerNames = false;\n\n private evalutionSummaryAggregator: EvaluationSummaryAggregator | undefined;\n\n private loggerAggregator: LoggerAggregator | undefined;\n\n public clientNameString = \"sdk-javascript\";\n\n public loaded = false;\n\n public loader: Loader | undefined;\n\n public afterEvaluationCallback = (() => {}) as EvaluationCallback;\n\n private _context: Context = new Context({});\n\n private _loggerKey = \"log-levels.default\";\n\n public logger: ReforgeLogger;\n\n constructor() {\n this.logger = new ReforgeLogger(this);\n }\n\n async init({\n sdkKey,\n context: providedContext,\n endpoints = undefined,\n apiEndpoint,\n timeout = undefined,\n afterEvaluationCallback = () => {},\n collectEvaluationSummaries = true,\n collectLoggerNames = false,\n collectContextMode = \"PERIODIC_EXAMPLE\",\n clientNameString = \"sdk-javascript\",\n clientVersionString = version,\n loggerKey = \"log-levels.default\",\n }: ReforgeInitParams) {\n const context = providedContext ?? this.context;\n\n if (!context) {\n throw new Error(\"Context must be provided\");\n }\n\n this._context = context;\n this._loggerKey = loggerKey;\n\n this.clientNameString = clientNameString;\n const clientNameAndVersionString = `${clientNameString}-${clientVersionString}`;\n\n this.loader = new Loader({\n sdkKey,\n context,\n endpoints,\n timeout,\n collectContextMode,\n clientVersion: clientNameAndVersionString,\n });\n\n this._telemetryUploader = new TelemetryUploader({\n sdkKey,\n apiEndpoint,\n timeout,\n clientVersion: clientNameAndVersionString,\n });\n\n this.collectEvaluationSummaries = collectEvaluationSummaries;\n if (collectEvaluationSummaries) {\n this.evalutionSummaryAggregator = new EvaluationSummaryAggregator(this, 100000);\n }\n\n this.collectLoggerNames = collectLoggerNames;\n if (collectLoggerNames) {\n this.loggerAggregator = new LoggerAggregator(this, 100000);\n }\n\n if (\n (collectEvaluationSummaries || collectLoggerNames) &&\n typeof window !== \"undefined\" &&\n typeof window.addEventListener === \"function\"\n ) {\n window.addEventListener(\"beforeunload\", () => {\n this.evalutionSummaryAggregator?.sync();\n this.loggerAggregator?.sync();\n });\n }\n\n this.afterEvaluationCallback = afterEvaluationCallback;\n\n return this.load();\n }\n\n public extract(): Record<string, Config[\"value\"]> {\n return Object.entries(this._configs).reduce(\n (agg, [key, value]) => ({\n ...agg,\n [key]: value.value,\n }),\n {} as Record<string, Config[\"value\"]>\n );\n }\n\n public hydrate(rawValues: RawConfigWithoutTypes | EvaluationPayload): void {\n this.setConfigPrivate(rawValues);\n }\n\n get context(): Context {\n return this._context;\n }\n\n get instanceHash(): string {\n return this._instanceHash;\n }\n\n get pollTimeoutId() {\n return this._pollTimeoutId;\n }\n\n get pollCount() {\n return this._pollCount;\n }\n\n get pollStatus() {\n return this._pollStatus;\n }\n\n get telemetryUploader(): TelemetryUploader | undefined {\n return this._telemetryUploader;\n }\n\n private async load() {\n if (!this.loader || !this.context) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n /* eslint-disable no-underscore-dangle */\n if (globalThis && (globalThis as any)._reforgeBootstrap) {\n /* eslint-disable no-underscore-dangle */\n const reforgeBootstrap = (globalThis as any)._reforgeBootstrap as ReforgeBootstrap;\n const bootstrapContext = new Context(reforgeBootstrap.context);\n\n if (this.context.equals(bootstrapContext)) {\n this.setConfigPrivate({ evaluations: reforgeBootstrap.evaluations });\n return Promise.resolve();\n }\n }\n\n // make sure we have the freshest context\n this.loader.context = this.context;\n\n return this.loader\n .load()\n .then((rawValues: any) => {\n this.setConfigPrivate(rawValues as EvaluationPayload);\n })\n .finally(() => {\n if (this.pollStatus.status === \"running\") {\n this._pollCount += 1;\n }\n });\n }\n\n async updateContext(context: Context, skipLoad = false) {\n if (!this.loader) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n this._context = context;\n\n if (skipLoad) {\n return Promise.resolve();\n }\n\n return this.load();\n }\n\n async poll({ frequencyInMs }: { frequencyInMs: number }) {\n if (!this.loader) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n this.stopPolling();\n\n this._pollStatus = { status: \"pending\" };\n\n return this.loader.load().finally(() => {\n this.doPolling({ frequencyInMs });\n });\n }\n\n private doPolling({ frequencyInMs }: { frequencyInMs: number }) {\n this._pollTimeoutId = setTimeout(() => {\n this.load().finally(() => {\n if (this.pollStatus.status === \"running\") {\n this.doPolling({ frequencyInMs });\n }\n });\n }, frequencyInMs);\n\n this._pollStatus = {\n status: \"running\",\n frequencyInMs,\n };\n }\n\n stopPolling() {\n if (this.pollTimeoutId) {\n clearTimeout(this.pollTimeoutId);\n this._pollTimeoutId = undefined;\n }\n\n this._pollStatus = { status: \"stopped\" };\n }\n\n stopTelemetry() {\n if (this.telemetryUploader) {\n this.evalutionSummaryAggregator?.stop();\n this.loggerAggregator?.stop();\n }\n }\n\n private setConfigPrivate(rawValues: RawConfigWithoutTypes | EvaluationPayload) {\n this._configs = Config.digest(rawValues);\n this.loaded = true;\n }\n\n isEnabled<\n // We need to calcuate these live and not store in a type to ensure dynamic evaluation\n // in upstream libraries that override the FrontEndConfigurationRaw interface\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends boolean\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(key: K): boolean {\n return this.get(key) === true;\n }\n\n get<K extends keyof TypedFrontEndConfigurationRaw>(key: K): TypedFrontEndConfigurationRaw[K] {\n if (!this.loaded) {\n if (!key.startsWith(loggerPrefix)) {\n // eslint-disable-next-line no-console\n console.warn(\n `Reforge warning: The client has not finished loading data yet. Unable to look up actual value for key \"${key}\".`\n );\n }\n\n return undefined;\n }\n\n const config = this._configs[key];\n\n const value = config?.value;\n\n if (!key.startsWith(loggerPrefix)) {\n if (this.collectEvaluationSummaries) {\n setTimeout(() => this.evalutionSummaryAggregator?.record(config));\n }\n\n setTimeout(() => this.afterEvaluationCallback(key, value, this.context));\n }\n\n return value;\n }\n\n getDuration<\n // We need to calcuate these live and not store in a type to ensure dynamic evaluation\n // in upstream libraries that override the FrontEndConfigurationRaw interface\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends Duration\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(key: K): Duration | undefined {\n const value = this.get(key);\n\n if (!value) {\n return undefined;\n }\n\n if (\n !Object.prototype.hasOwnProperty.call(value, \"seconds\") ||\n !Object.prototype.hasOwnProperty.call(value, \"ms\")\n ) {\n throw new Error(`Value for key \"${key}\" is not a duration`);\n }\n\n return value as Duration;\n }\n\n shouldLog(args: PublicShouldLogParams, async = true): boolean {\n if (this.collectLoggerNames) {\n const record = () => this.loggerAggregator?.record(args.loggerName, args.desiredLevel);\n if (async) {\n setTimeout(record);\n } else {\n record();\n }\n }\n\n return shouldLog({ ...args, get: this.get.bind(this) });\n }\n\n getLogLevel(_loggerName: string): LogLevel {\n const value = this.get(this._loggerKey);\n\n if (value && typeof value === \"string\") {\n const upperValue = value.toUpperCase();\n if (upperValue in LogLevel) {\n return LogLevel[upperValue as keyof typeof LogLevel];\n }\n }\n\n // Default to DEBUG if no config found or invalid value\n return LogLevel.DEBUG;\n }\n\n isCollectingEvaluationSummaries(): boolean {\n return this.collectEvaluationSummaries;\n }\n\n isCollectingLoggerNames(): boolean {\n return this.collectLoggerNames;\n }\n}\n\nexport const reforge = new Reforge();\n","import { ReforgeLogLevel } from \"./logger\";\nimport { TypedFrontEndConfigurationRaw, ConfigEvaluationMetadata } from \"./types\";\n\nexport type RawConfigWithoutTypes = Record<string, any>;\n\ntype APIKeyMetadata = {\n id: string | number;\n};\n\n// TODO: Why is this definition different from the one in ./types.ts?\ntype Duration = {\n definition: string;\n millis: number;\n};\n\nexport interface IntRange {\n /** if empty treat as Number.MIN_VALUE. Inclusive */\n start?: bigint | undefined;\n /** if empty treat as Number.MAX_VALUE. Exclusive */\n end?: bigint | undefined;\n}\n\nexport enum ProvidedSource {\n EnvVar = \"ENV_VAR\",\n}\nexport interface Provided {\n source?: ProvidedSource | undefined;\n /** eg MY_ENV_VAR */\n lookup?: string | undefined;\n}\n\nexport enum SchemaType {\n UNKNOWN = 0,\n ZOD = 1,\n JSON_SCHEMA = 2,\n}\n\nexport interface Schema {\n schema: string;\n schemaType: SchemaType;\n}\n\nexport interface WeightedValue {\n /** out of 1000 */\n weight: number;\n // eslint-disable-next-line no-use-before-define\n value: ConfigValue | undefined;\n}\n\nexport enum LimitResponse_LimitPolicyNames {\n SecondlyRolling = 1,\n MinutelyRolling = 3,\n HourlyRolling = 5,\n DailyRolling = 7,\n MonthlyRolling = 8,\n Infinite = 9,\n YearlyRolling = 10,\n}\n\nexport enum LimitDefinition_SafetyLevel {\n L4_BEST_EFFORT = 4,\n L5_BOMBPROOF = 5,\n}\n\nexport interface LimitDefinition {\n policyName: LimitResponse_LimitPolicyNames;\n limit: number;\n burst: number;\n accountId: number;\n lastModified: number;\n returnable: boolean;\n /** [default = L4_BEST_EFFORT]; // Overridable by request */\n safetyLevel: LimitDefinition_SafetyLevel;\n}\nexport interface WeightedValues {\n weightedValues: WeightedValue[];\n hashByPropertyName?: string | undefined;\n}\n\nexport type ConfigValue =\n | {\n int: number | undefined;\n }\n | {\n string: string | undefined;\n }\n | {\n bytes: Buffer | undefined;\n }\n | {\n double: number | undefined;\n }\n | {\n bool: boolean | undefined;\n }\n | {\n weightedValues?: WeightedValues | undefined;\n }\n | {\n limitDefinition?: LimitDefinition | undefined;\n }\n | {\n logLevel: ReforgeLogLevel | undefined;\n }\n | {\n stringList: string[] | undefined;\n }\n | {\n intRange: IntRange | undefined;\n }\n | {\n provided: Provided | undefined;\n }\n | {\n duration: Duration | undefined;\n }\n | {\n json: string | undefined;\n }\n | {\n schema: Schema | undefined;\n }\n | {\n /** don't log or telemetry this value */\n confidential: boolean | undefined;\n }\n | {\n /** key name to decrypt with */\n decryptWith: string | undefined;\n };\n\ntype Evaluation = {\n value: ConfigValue;\n configEvaluationMetadata: {\n configRowIndex: string | number;\n conditionalValueIndex: string | number;\n weightedValueIndex?: string | number;\n type: string;\n valueType: string;\n id: string;\n };\n};\n\nexport type EvaluationPayload = {\n evaluations: { [key: string]: Evaluation };\n apikeyMetadata: APIKeyMetadata;\n};\n\nconst parseRawMetadata = (metadata: any) => ({\n configRowIndex: parseInt(metadata.configRowIndex, 10),\n conditionalValueIndex: parseInt(metadata.conditionalValueIndex, 10),\n type: metadata.type,\n configId: metadata.id,\n});\n\nconst valueFor = <K extends keyof TypedFrontEndConfigurationRaw>(\n value: ConfigValue,\n type: keyof ConfigValue,\n key: K\n): TypedFrontEndConfigurationRaw[K] => {\n const rawValue = value[type];\n\n switch (type) {\n case \"json\":\n try {\n return JSON.parse(rawValue as string);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error(`Error parsing JSON from Reforge config ${key}`, e, rawValue);\n return value[type];\n }\n case \"duration\": {\n const duration = rawValue as Duration;\n return {\n ms: duration.millis,\n seconds: duration.millis / 1000,\n };\n }\n default:\n return rawValue;\n }\n};\n\nexport const parseEvaluationPayload = (payload: EvaluationPayload) => {\n // eslint-disable-next-line no-use-before-define\n const configs = {} as { [key: string]: Config };\n Object.keys(payload.evaluations).forEach((key) => {\n const evaluation = payload.evaluations[key];\n\n const type = Object.keys(evaluation.value)[0] as keyof ConfigValue;\n\n // eslint-disable-next-line no-use-before-define\n configs[key] = new Config(\n key,\n valueFor(evaluation.value, type, key),\n type,\n evaluation.value,\n evaluation.configEvaluationMetadata\n ? parseRawMetadata(evaluation.configEvaluationMetadata)\n : undefined\n );\n });\n\n return configs;\n};\n\nconst parseRawConfigWithoutTypes = (payload: RawConfigWithoutTypes) => {\n // eslint-disable-next-line no-use-before-define\n const configs = {} as { [key: string]: Config };\n Object.keys(payload).forEach((key) => {\n const type = typeof payload[key] as keyof ConfigValue;\n // eslint-disable-next-line no-use-before-define\n configs[key] = new Config(key, valueFor({ [type]: payload[key] }, type, key), type);\n });\n\n return configs;\n};\n\nexport class Config<\n K extends keyof TypedFrontEndConfigurationRaw = keyof TypedFrontEndConfigurationRaw,\n> {\n key: K;\n\n value: TypedFrontEndConfigurationRaw[K];\n\n rawValue: ConfigValue | undefined;\n\n type: keyof ConfigValue;\n\n configEvaluationMetadata: ConfigEvaluationMetadata | undefined;\n\n constructor(\n key: K,\n value: TypedFrontEndConfigurationRaw[K],\n type: keyof ConfigValue,\n rawValue?: ConfigValue,\n metadata?: ConfigEvaluationMetadata\n ) {\n this.key = key;\n this.value = value;\n this.type = type;\n this.rawValue = rawValue;\n this.configEvaluationMetadata = metadata;\n }\n\n static digest(payload: EvaluationPayload | RawConfigWithoutTypes) {\n if (payload === undefined) {\n // eslint-disable-next-line no-console\n console.trace(\"Config.digest called with undefined payload\");\n }\n\n if (\"evaluations\" in payload) {\n return parseEvaluationPayload(payload as EvaluationPayload);\n }\n\n return parseRawConfigWithoutTypes(payload as RawConfigWithoutTypes);\n }\n}\n","const base64Encode = (obj: string) => {\n if (typeof window !== \"undefined\") {\n if (typeof TextEncoder === \"undefined\") {\n return window.btoa(obj);\n }\n\n const bytes = new TextEncoder().encode(obj);\n const binString = Array.from(bytes, (byte) => String.fromCodePoint(byte)).join(\"\");\n return btoa(binString);\n }\n\n return Buffer.from(obj).toString(\"base64\");\n};\n\nexport default base64Encode;\n","import { Contexts, ContextValue } from \"./types\";\nimport base64Encode from \"./base64Encode\";\n\nconst isEqual = (a: Contexts, b: Contexts) => {\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n\n if (aKeys.length !== bKeys.length) {\n return false;\n }\n\n return aKeys.every((key) => {\n const aValues = a[key];\n const bValues = b[key];\n\n const aValuesKeys = Object.keys(aValues);\n const bValuesKeys = Object.keys(bValues);\n\n if (aValuesKeys.length !== bValuesKeys.length) {\n return false;\n }\n\n return aValuesKeys.every((ckey) => {\n const aValue = aValues[ckey];\n const bValue = bValues[ckey];\n\n return aValue === bValue;\n });\n });\n};\n\nconst getType = (value: ContextValue) => {\n if (typeof value === \"string\") {\n return \"string\";\n }\n\n if (typeof value === \"number\") {\n if (Number.isInteger(value)) {\n return \"int\";\n }\n\n return \"double\";\n }\n\n return \"bool\";\n};\n\nexport default class Context {\n contexts: Contexts;\n\n constructor(contexts: Contexts) {\n if (!Object.values(contexts).every((item: any) => typeof item === \"object\")) {\n // eslint-disable-next-line no-console\n console.error(\"Context must be an object where the value of each key is also an object\");\n }\n\n if (\n Object.values(contexts).some((item: any) =>\n Object.values(item).some((value: any) => typeof value === \"object\" && value !== null)\n )\n ) {\n // we decided to allow null values, which requres an extra check since typeof null is object\n // eslint-disable-next-line no-console\n console.error(\"Nested objects are not supported in context values at this time\");\n }\n\n this.contexts = contexts;\n }\n\n equals(other: Context) {\n return isEqual(this.contexts, other.contexts);\n }\n\n encode() {\n const formatted = Object.keys(this.contexts).map((key) => {\n const values: Record<string, Record<string, ContextValue>> = {};\n\n Object.keys(this.contexts[key]).forEach((ckey) => {\n values[ckey] = {\n [getType(this.contexts[key][ckey])]: this.contexts[key][ckey],\n };\n });\n\n return {\n type: key,\n values,\n };\n });\n\n return encodeURIComponent(base64Encode(JSON.stringify({ contexts: formatted })));\n }\n}\n","export class ExponentialBackoff {\n private maxDelay: number;\n\n private multiplier: number;\n\n private delay: number;\n\n // arguments are in seconds\n constructor(maxDelay: number, initialDelay = 2, multiplier = 2) {\n this.maxDelay = maxDelay;\n this.multiplier = multiplier;\n this.delay = initialDelay;\n }\n\n call(): number {\n const delayValue = this.delay;\n this.delay = Math.min(this.delay * this.multiplier, this.maxDelay);\n return delayValue * 1000;\n }\n}\n","import { TypedFrontEndConfigurationRaw } from \"./types\";\n\nexport const PREFIX = \"log-level\";\nexport enum ReforgeLogLevel {\n Trace = 1,\n Debug = 2,\n Info = 3,\n Warn = 4,\n Error = 5,\n Fatal = 6,\n}\n\nexport type LogLevelWord = Uppercase<keyof typeof ReforgeLogLevel>;\n\nconst WORD_LEVEL_LOOKUP: Readonly<Record<LogLevelWord, ReforgeLogLevel>> = {\n TRACE: ReforgeLogLevel.Trace,\n DEBUG: ReforgeLogLevel.Debug,\n INFO: ReforgeLogLevel.Info,\n WARN: ReforgeLogLevel.Warn,\n ERROR: ReforgeLogLevel.Error,\n FATAL: ReforgeLogLevel.Fatal,\n};\n\nexport const isValidLogLevel = (possibleLogLevel: string) =>\n Object.keys(WORD_LEVEL_LOOKUP).includes(possibleLogLevel.toUpperCase());\n\nexport interface ShouldLogParams {\n loggerName: string;\n desiredLevel: ReforgeLogLevel;\n defaultLevel: ReforgeLogLevel;\n get: <K extends keyof TypedFrontEndConfigurationRaw>(key: K) => TypedFrontEndConfigurationRaw[K];\n}\n\n// LogLevel enum for public API\nexport enum LogLevel {\n TRACE = \"TRACE\",\n DEBUG = \"DEBUG\",\n INFO = \"INFO\",\n WARN = \"WARN\",\n ERROR = \"ERROR\",\n FATAL = \"FATAL\",\n}\n\n// Get the numeric severity value for a LogLevel (lower = more verbose)\nexport const getLogLevelSeverity = (level: LogLevel): number => WORD_LEVEL_LOOKUP[level];\n\n// Check if a log at desiredLevel should be logged given the configured level\n// Returns true if desiredLevel is at or above the configured level's severity\nexport const shouldLogAtLevel = (configuredLevel: LogLevel, desiredLevel: LogLevel): boolean =>\n WORD_LEVEL_LOOKUP[configuredLevel] <= WORD_LEVEL_LOOKUP[desiredLevel];\n\nexport const shouldLog = ({\n loggerName,\n desiredLevel,\n defaultLevel,\n get,\n}: ShouldLogParams): boolean => {\n const loggerNameWithPrefix = `${PREFIX}.${loggerName}`;\n\n const resolvedLevel = get(loggerNameWithPrefix);\n\n if (resolvedLevel) {\n return (\n WORD_LEVEL_LOOKUP[resolvedLevel.toString().toUpperCase() as LogLevelWord] <= desiredLevel\n );\n }\n\n return defaultLevel <= desiredLevel;\n};\n","import { ExponentialBackoff } from \"./exponentialBackoff\";\nimport { ReforgeLogLevel } from \"./logger\";\nimport { type reforge } from \"./reforge\";\n\nabstract class PeriodicSync<T> {\n protected data: Map<string, T> = new Map();\n\n private startAt: Date;\n\n private syncInterval: any;\n\n protected client: typeof reforge;\n\n private name: string;\n\n private timeoutID: ReturnType<typeof setTimeout> | undefined;\n\n constructor(client: typeof reforge, name: string, syncInterval?: number) {\n this.client = client;\n this.name = name;\n\n this.startAt = new Date();\n\n this.startPeriodicSync(syncInterval);\n }\n\n stop(): void {\n clearTimeout(this.timeoutID);\n }\n\n sync(): void {\n if (this.data.size === 0) return;\n\n this.logInternal(`${this.name} syncing ${this.data.size} items`);\n\n const startAtWas = this.startAt;\n this.startAt = new Date();\n\n this.flush(this.prepareData(), startAtWas);\n }\n\n protected abstract flush(toShip: Map<string, T>, startAtWas: Date): void;\n\n private prepareData(): Map<string, T> {\n const toShip = new Map(this.data);\n this.data.clear();\n\n return toShip;\n }\n\n private startPeriodicSync(syncInterval?: number): void {\n this.startAt = new Date();\n this.syncInterval = PeriodicSync.calculateSyncInterval(syncInterval);\n\n this.scheduleNextSync();\n }\n\n private scheduleNextSync() {\n const interval = this.syncInterval();\n this.timeoutID = setTimeout(() => {\n this.sync();\n this.scheduleNextSync(); // Schedule the next sync after the current one completes\n }, interval);\n }\n\n private static calculateSyncInterval(syncInterval?: number): any {\n if (syncInterval !== undefined) {\n return () => syncInterval;\n }\n\n const backoff = new ExponentialBackoff(60 * 5, 8);\n return () => backoff.call();\n }\n\n protected logInternal(message: string): void {\n const loggerName = `${this.client.clientNameString}.reforge.${this.name}`;\n\n if (\n this.client.shouldLog(\n {\n loggerName,\n desiredLevel: ReforgeLogLevel.Debug,\n defaultLevel: ReforgeLogLevel.Error,\n },\n false // synchronous so that this log ends up in the current batch\n )\n ) {\n // eslint-disable-next-line no-console\n console.log(`${loggerName}: ${message}`);\n }\n }\n}\n\nexport { PeriodicSync };\n","// TODO: should we retry the data chunk if a flush fails?\n\n// TODO: pause when offline?\n\n// TODO: flush when we receive a config update (or as a result of a context update...but that should trigger a config update anyway)\n\nimport { PeriodicSync } from \"./periodicSync\";\nimport { Config } from \"./config\";\nimport { type reforge } from \"./reforge\";\nimport {\n ConfigEvaluationCounter,\n ConfigEvaluationSummaries,\n ConfigEvaluationSummary,\n TelemetryEvents,\n ConfigEvaluationMetadata,\n} from \"./types\";\n\nexport const massageSelectedValue = (config: Config): any => {\n if (config.rawValue && (config.type === \"duration\" || config.type === \"json\")) {\n if (config.type === \"json\") {\n return { json: config.rawValue[config.type] };\n }\n\n return config.rawValue[config.type];\n }\n\n return config.type === \"stringList\" ? { values: config.value } : config.value;\n};\n\nexport const massageConfigForTelemetry = (\n config: Config,\n metadata: Omit<ConfigEvaluationMetadata, \"type\">\n) => ({\n ...metadata,\n selectedValue: {\n [config.type]: massageSelectedValue(config),\n },\n count: 0,\n});\n\nclass EvaluationSummaryAggregator extends PeriodicSync<ConfigEvaluationCounter> {\n private maxKeys: number;\n\n constructor(client: typeof reforge, maxKeys: number, syncInterval?: number) {\n super(client, \"EvaluationSummaryAggregator\", syncInterval ?? 30000);\n\n this.maxKeys = maxKeys;\n }\n\n record(config: Config): void {\n if (this.data.size >= this.maxKeys) return;\n\n if (config?.configEvaluationMetadata) {\n const { type, ...metadata } = config.configEvaluationMetadata;\n const key = `${config.key},${type}`;\n\n // create counter entry if it doesn't exist\n if (!this.data.has(key)) {\n this.data.set(key, massageConfigForTelemetry(config, metadata));\n }\n\n // increment count\n const counter = this.data.get(key);\n if (counter) {\n counter.count += 1;\n }\n }\n }\n\n protected flush(toShip: Map<string, ConfigEvaluationCounter>, startAtWas: Date): void {\n const summaries = {\n start: startAtWas.getTime(),\n end: new Date().getTime(),\n summaries: EvaluationSummaryAggregator.summaries(toShip),\n };\n\n this.client.telemetryUploader?.post(this.events(summaries));\n }\n\n private static summaries(data: Map<string, ConfigEvaluationCounter>): ConfigEvaluationSummary[] {\n return Array.from(data).map((entry: [string, ConfigEvaluationCounter]) => {\n const [configKey, configType] = entry[0].split(\",\");\n const counter = entry[1];\n const counters = [counter]; // this client only ever has one set of counter info per key\n\n return {\n key: configKey,\n type: configType,\n counters,\n };\n });\n }\n\n private events(summaries: ConfigEvaluationSummaries): TelemetryEvents {\n const event = { summaries };\n\n return {\n instanceHash: this.client.instanceHash,\n events: [event],\n };\n }\n}\n\nexport { EvaluationSummaryAggregator };\n","import base64Encode from \"./base64Encode\";\n\nexport const headers = (sdkKey: string, clientVersion: string) => ({\n Authorization: `Basic ${base64Encode(`u:${sdkKey}`)}`,\n \"X-Reforge-SDK-Version\": clientVersion,\n});\n\nexport const DEFAULT_TIMEOUT = 10000;\n","import { DEFAULT_TIMEOUT, headers } from \"./apiHelpers\";\nimport { EvaluationPayload } from \"./config\";\nimport Context from \"./context\";\n\nexport type CollectContextModeType = \"NONE\" | \"SHAPE_ONLY\" | \"PERIODIC_EXAMPLE\";\n\nexport type LoaderParams = {\n sdkKey: string;\n context: Context;\n endpoints?: string[] | undefined;\n timeout?: number;\n collectContextMode?: CollectContextModeType;\n clientVersion?: string;\n};\n\nexport type Headers = {\n [key: string]: string;\n};\n\nexport type FetchOptions = {\n headers: Headers;\n};\n\nconst defaultEndpoints = [\n \"https://primary.reforge.com/api/v2\",\n \"https://secondary.reforge.com/api/v2\",\n];\n\nconst EARLY_TIMEOUT = 2000;\n\nexport default class Loader {\n sdkKey: string;\n\n context: Context;\n\n endpoints: string[];\n\n timeout: number;\n\n abortTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n collectContextMode: CollectContextModeType = \"PERIODIC_EXAMPLE\";\n\n clientVersion: string;\n\n abortController: AbortController | undefined;\n\n isAborted = false;\n\n constructor({\n sdkKey,\n context,\n endpoints = undefined,\n timeout,\n collectContextMode = \"PERIODIC_EXAMPLE\",\n clientVersion = \"\",\n }: LoaderParams) {\n this.sdkKey = sdkKey;\n this.context = context;\n this.endpoints = endpoints || defaultEndpoints;\n this.timeout = timeout || DEFAULT_TIMEOUT;\n this.collectContextMode = collectContextMode;\n this.clientVersion = clientVersion;\n }\n\n url(root: string) {\n return `${root}/configs/eval-with-context/${this.context.encode()}?collectContextMode=${\n this.collectContextMode\n }`;\n }\n\n loadFromEndpoint(\n index: number,\n options: FetchOptions,\n resolve: (value: any) => void,\n reject: (value: any) => void\n ) {\n this.abortController = new AbortController() as AbortController;\n const { signal } = this.abortController;\n this.isAborted = false;\n\n const endpoint = this.endpoints[index];\n const url = this.url(endpoint);\n\n fetch(url, { signal, ...options })\n .then((response) => {\n this.clearAbortTimeout();\n\n if (response.ok) {\n return response.json();\n }\n throw new Error(`${response.status} ${response.statusText}`);\n })\n .then((data) => {\n if (!(\"evaluations\" in data)) {\n throw new Error(`Invalid payload:${JSON.stringify(data)}`);\n }\n\n resolve(data as EvaluationPayload);\n })\n .catch((error) => {\n this.clearAbortTimeout();\n\n if (index < this.endpoints.length - 1) {\n this.loadFromEndpoint(index + 1, options, resolve, reject);\n } else {\n reject(error);\n }\n });\n\n // Use an early timeout if we're not on the last endpoint. But if the user-provided timeout is less than EARLY_TIMEOUT, use that\n const timeout =\n index < this.endpoints.length - 1 ? Math.min(this.timeout, EARLY_TIMEOUT) : this.timeout;\n\n this.abortTimeoutId = setTimeout(() => {\n if (!this.isAborted) {\n this.isAborted = true;\n this.abortController?.abort();\n }\n }, timeout);\n }\n\n load() {\n if (!this.isAborted) {\n this.isAborted = true;\n this.abortController?.abort();\n }\n\n const options = {\n headers: headers(this.sdkKey, this.clientVersion),\n };\n\n const promise = new Promise((resolve, reject) => {\n this.loadFromEndpoint(0, options, resolve, reject);\n });\n\n return promise;\n }\n\n clearAbortTimeout() {\n clearTimeout(this.abortTimeoutId);\n }\n}\n","import { DEFAULT_TIMEOUT, headers } from \"./apiHelpers\";\nimport { TelemetryEvents } from \"./types\";\n\nexport type TelemetryUploaderParams = {\n sdkKey: string;\n apiEndpoint?: string;\n timeout?: number;\n clientVersion: string;\n};\n\nexport default class TelemetryUploader {\n sdkKey: Required<TelemetryUploaderParams>[\"sdkKey\"];\n\n apiEndpoint: Required<TelemetryUploaderParams>[\"apiEndpoint\"];\n\n timeout: Required<TelemetryUploaderParams>[\"timeout\"];\n\n clientVersion: Required<TelemetryUploaderParams>[\"clientVersion\"];\n\n abortTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n constructor({\n sdkKey,\n apiEndpoint = undefined,\n timeout,\n clientVersion,\n }: TelemetryUploaderParams) {\n this.sdkKey = sdkKey;\n this.apiEndpoint = apiEndpoint || \"https://telemetry.reforge.com/api/v1\";\n this.timeout = timeout || DEFAULT_TIMEOUT;\n this.clientVersion = clientVersion;\n }\n\n clearAbortTimeout() {\n clearTimeout(this.abortTimeoutId);\n }\n\n static postUrl(root: string) {\n return `${root}/telemetry`;\n }\n\n postToEndpoint(\n options: RequestInit,\n resolve: (value: unknown) => void,\n reject: (value: unknown) => void\n ) {\n const controller = new AbortController() as AbortController;\n const signal = controller?.signal;\n let isAborted = false;\n\n const url = TelemetryUploader.postUrl(this.apiEndpoint);\n\n fetch(url, { signal, ...options })\n .then((response) => {\n this.clearAbortTimeout();\n\n if (response.ok) {\n return response.json();\n }\n\n // eslint-disable-next-line no-console\n console.warn(\n `Reforge warning: Error uploading telemetry ${response.status} ${response.statusText}`\n );\n\n return response.status;\n })\n .then((response) => {\n resolve(response);\n })\n .catch((error) => {\n this.clearAbortTimeout();\n\n // Silently handle AbortErrors (from timeouts or page navigations)\n if (error.name === \"AbortError\") {\n try {\n // eslint-disable-next-line no-console\n console.debug(\"Reforge telemetry request aborted\");\n } catch (e) {\n // no-op\n }\n resolve({ status: \"aborted\" });\n return;\n }\n\n reject(error);\n });\n\n this.abortTimeoutId = setTimeout(() => {\n if (!isAborted) {\n isAborted = true;\n controller.abort();\n }\n }, this.timeout);\n }\n\n post(data: TelemetryEvents) {\n const options = {\n method: \"POST\",\n headers: {\n ...headers(this.sdkKey, this.clientVersion),\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n body: JSON.stringify(data),\n keepalive: true, // needed for flushing when the window is closed\n };\n\n const promise = new Promise((resolve, reject) => {\n this.postToEndpoint(options, resolve, reject);\n });\n\n return promise;\n }\n}\n","// TODO: should we retry the data chunk if a flush fails?\n\n// TODO: pause when offline?\n\nimport { ReforgeLogLevel } from \"./logger\";\nimport { PeriodicSync } from \"./periodicSync\";\nimport { type reforge } from \"./reforge\";\nimport { LoggerCounter, LoggersTelemetryEvent, TelemetryEvents } from \"./types\";\n\nconst SEVERITY_KEY: { [key in ReforgeLogLevel]: Omit<keyof LoggerCounter, \"loggerName\"> } = {\n [ReforgeLogLevel.Trace]: \"traces\",\n [ReforgeLogLevel.Debug]: \"debugs\",\n [ReforgeLogLevel.Info]: \"infos\",\n [ReforgeLogLevel.Warn]: \"warns\",\n [ReforgeLogLevel.Error]: \"errors\",\n [ReforgeLogLevel.Fatal]: \"fatals\",\n};\n\nclass LoggerAggregator extends PeriodicSync<LoggerCounter> {\n private maxLoggers: number;\n\n constructor(client: typeof reforge, maxLoggers: number, syncInterval?: number) {\n super(client, \"LoggerAggregator\", syncInterval ?? 30000);\n\n this.maxLoggers = maxLoggers;\n }\n\n record(logger: string, level: ReforgeLogLevel): void {\n if (this.data.size >= this.maxLoggers) return;\n\n // create counter entry if it doesn't exist\n if (!this.data.has(logger)) {\n this.data.set(logger, {\n loggerName: logger,\n traces: 0,\n debugs: 0,\n infos: 0,\n warns: 0,\n errors: 0,\n fatals: 0,\n });\n }\n\n // increment count\n const counter = this.data.get(logger);\n if (counter) {\n const severityKey = SEVERITY_KEY[level] as keyof LoggerCounter;\n (counter[severityKey] as number) += 1;\n }\n }\n\n protected flush(toShip: Map<string, LoggerCounter>, startAtWas: Date): void {\n const loggers = {\n startAt: startAtWas.getTime(),\n endAt: new Date().getTime(),\n loggers: Array.from(toShip.values()),\n };\n\n this.client.telemetryUploader?.post(this.events(loggers));\n }\n\n private events(loggers: LoggersTelemetryEvent): TelemetryEvents {\n const event = { loggers };\n\n return {\n instanceHash: this.client.instanceHash,\n events: [event],\n };\n }\n}\n\nexport { LoggerAggregator };\n"],"mappings":"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","names":["exports","module","version","LogLevel","reforge","uuid","version"]}
{"version":3,"sources":["../package.json","../index.ts","../src/reforge.ts","../src/config.ts","../src/base64Encode.ts","../src/context.ts","../src/exponentialBackoff.ts","../src/logger.ts","../src/periodicSync.ts","../src/evaluationSummaryAggregator.ts","../src/apiHelpers.ts","../src/loader.ts","../src/telemetryUploader.ts","../src/loggerAggregator.ts"],"sourcesContent":["{\n \"packageManager\": \"yarn@4.11.0\",\n \"name\": \"@reforge-com/javascript\",\n \"version\": \"0.0.5\",\n \"description\": \"Feature Flags & Dynamic Configuration as a Service\",\n \"main\": \"dist/index.cjs\",\n \"module\": \"dist/index.mjs\",\n \"types\": \"dist/index.d.ts\",\n \"author\": \"Jeffrey Chupp\",\n \"license\": \"ISC\",\n \"devDependencies\": {\n \"@types/eslint-plugin-jsx-a11y\": \"^6\",\n \"@types/express\": \"^4.17.13\",\n \"@types/jest\": \"^28.1.6\",\n \"@types/uuid\": \"^9.0.5\",\n \"@typescript-eslint/eslint-plugin\": \"^5.33.0\",\n \"@typescript-eslint/parser\": \"^5.33.0\",\n \"esbuild\": \"^0.25.11\",\n \"eslint\": \"^8.21.0\",\n \"eslint-config-airbnb\": \"^19.0.4\",\n \"eslint-config-airbnb-typescript\": \"^17.0.0\",\n \"eslint-config-prettier\": \"^8.8.0\",\n \"eslint-plugin-import\": \"^2.26.0\",\n \"eslint-plugin-jest\": \"^26.8.0\",\n \"eslint-plugin-jsx-a11y\": \"^6.10.2\",\n \"eslint-plugin-react\": \"^7.37.5\",\n \"jest\": \"^29.0.0\",\n \"jest-environment-jsdom\": \"^30.2.0\",\n \"jest-fetch-mock\": \"^3.0.3\",\n \"prettier\": \"^3.0.0\",\n \"ts-jest\": \"^29.1.1\",\n \"ts-node\": \"^10.9.1\",\n \"tsup\": \"^8.0.2\",\n \"typescript\": \"^5.1.6\"\n },\n \"scripts\": {\n \"build\": \"rm -rf dist/ && tsup\",\n \"dev\": \"tsup --watch\",\n \"bundle\": \"esbuild --minify --target=esnext --bundle --outfile=dist/reforge.bundle.js --global-name=window.reforgeNamespace dist/index.cjs && echo 'window.reforge = window.reforgeNamespace.reforge' >> dist/reforge.bundle.js\",\n \"lint\": \"eslint --ext .ts,.tsx src/\",\n \"lint:fix\": \"eslint --fix --ext .ts,.tsx src/\",\n \"prettier\": \"prettier . -l\",\n \"prettier:fix\": \"prettier --write .\",\n \"test\": \"jest --verbose\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/ReforgeHQ/sdk-javascript.git\"\n },\n \"keywords\": [\n \"feature-flags\",\n \"config\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/ReforgeHQ/sdk-javascript/issues\"\n },\n \"homepage\": \"https://github.com/ReforgeHQ/sdk-javascript#readme\",\n \"dependencies\": {\n \"uuid\": \"^9.0.1\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.mjs\",\n \"require\": \"./dist/index.cjs\"\n }\n }\n}\n","import {\n reforge,\n Reforge,\n ReforgeInitParams,\n ReforgeBootstrap,\n prefetchReforgeConfig,\n} from \"./src/reforge\";\nimport { Config } from \"./src/config\";\nimport Context from \"./src/context\";\nimport { LogLevel, getLogLevelSeverity, shouldLogAtLevel } from \"./src/logger\";\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version } = require(\"./package.json\");\n\nexport {\n reforge,\n Reforge,\n ReforgeInitParams,\n Config,\n Context,\n LogLevel,\n getLogLevelSeverity,\n shouldLogAtLevel,\n version,\n prefetchReforgeConfig,\n};\n\nexport { ReforgeBootstrap };\n\nexport type { ConfigValue } from \"./src/config\";\nexport type {\n Duration,\n ContextValue,\n Contexts,\n TypedFrontEndConfigurationRaw,\n FrontEndConfigurationRaw,\n} from \"./src/types\";\nexport type { CollectContextModeType } from \"./src/loader\";\n","/* eslint-disable max-classes-per-file */\nimport { v4 as uuid } from \"uuid\";\n\nimport { Config, EvaluationPayload, RawConfigWithoutTypes } from \"./config\";\nimport type {\n Duration,\n TypedFrontEndConfigurationRaw,\n FrontEndConfigurationRaw,\n Contexts,\n} from \"./types\";\nimport Context from \"./context\";\nimport { EvaluationSummaryAggregator } from \"./evaluationSummaryAggregator\";\nimport Loader, { CollectContextModeType } from \"./loader\";\nimport {\n PREFIX as loggerPrefix,\n shouldLog,\n ShouldLogParams,\n LogLevel,\n shouldLogAtLevel,\n} from \"./logger\";\nimport TelemetryUploader from \"./telemetryUploader\";\nimport { LoggerAggregator } from \"./loggerAggregator\";\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version } = require(\"../package.json\");\n\ntype EvaluationCallback = <K extends keyof TypedFrontEndConfigurationRaw>(\n key: K,\n value: TypedFrontEndConfigurationRaw[K],\n context: Context | undefined\n) => void;\n\nexport interface ReforgeBootstrap {\n evaluations: EvaluationPayload;\n context: Contexts;\n}\n\nexport type ReforgeInitParams = {\n sdkKey: string;\n context: Context;\n endpoints?: string[] | undefined;\n apiEndpoint?: string;\n timeout?: number;\n afterEvaluationCallback?: EvaluationCallback;\n collectEvaluationSummaries?: boolean;\n collectLoggerNames?: boolean;\n collectContextMode?: CollectContextModeType;\n clientNameString?: string;\n clientVersionString?: string;\n loggerKey?: string;\n};\n\ntype PollStatus =\n | { status: \"not-started\" }\n | { status: \"pending\" }\n | { status: \"stopped\" }\n | { status: \"running\"; frequencyInMs: number };\n\ntype PublicShouldLogParams = Omit<ShouldLogParams, \"get\">;\n\n// Forward declaration for ReforgeLogger\n// eslint-disable-next-line @typescript-eslint/no-use-before-define\nclass ReforgeLogger {\n // eslint-disable-next-line no-use-before-define\n private reforge: Reforge;\n\n // eslint-disable-next-line no-use-before-define\n constructor(reforge: Reforge) {\n this.reforge = reforge;\n }\n\n private log(message: string, level: LogLevel): void {\n const configuredLevel = this.reforge.getLogLevel(\"\");\n\n if (shouldLogAtLevel(configuredLevel, level)) {\n switch (level) {\n case LogLevel.TRACE:\n case LogLevel.DEBUG:\n // eslint-disable-next-line no-console\n console.debug(message);\n break;\n case LogLevel.INFO:\n // eslint-disable-next-line no-console\n console.info(message);\n break;\n case LogLevel.WARN:\n // eslint-disable-next-line no-console\n console.warn(message);\n break;\n case LogLevel.ERROR:\n case LogLevel.FATAL:\n // eslint-disable-next-line no-console\n console.error(message);\n break;\n default:\n // eslint-disable-next-line no-console\n console.error(message);\n }\n }\n }\n\n trace(message: string): void {\n this.log(message, LogLevel.TRACE);\n }\n\n debug(message: string): void {\n this.log(message, LogLevel.DEBUG);\n }\n\n info(message: string): void {\n this.log(message, LogLevel.INFO);\n }\n\n warn(message: string): void {\n this.log(message, LogLevel.WARN);\n }\n\n error(message: string): void {\n this.log(message, LogLevel.ERROR);\n }\n\n fatal(message: string): void {\n this.log(message, LogLevel.FATAL);\n }\n}\n\nexport class Reforge {\n private _configs: { [key: string]: Config } = {};\n\n private _telemetryUploader: TelemetryUploader | undefined;\n\n private _pollCount = 0;\n\n private _pollStatus: PollStatus = { status: \"not-started\" };\n\n private _pollTimeoutId = undefined as ReturnType<typeof setTimeout> | undefined;\n\n private _instanceHash: string = uuid();\n\n private collectEvaluationSummaries = true;\n\n private collectLoggerNames = false;\n\n private evalutionSummaryAggregator: EvaluationSummaryAggregator | undefined;\n\n private loggerAggregator: LoggerAggregator | undefined;\n\n public clientNameString = \"sdk-javascript\";\n\n public loaded = false;\n\n public loader: Loader | undefined;\n\n public afterEvaluationCallback = (() => {}) as EvaluationCallback;\n\n private _context: Context = new Context({});\n\n private _loggerKey = \"log-levels.default\";\n\n public logger: ReforgeLogger;\n\n constructor() {\n this.logger = new ReforgeLogger(this);\n }\n\n async init({\n sdkKey,\n context: providedContext,\n endpoints = undefined,\n apiEndpoint,\n timeout = undefined,\n afterEvaluationCallback = () => {},\n collectEvaluationSummaries = true,\n collectLoggerNames = false,\n collectContextMode = \"PERIODIC_EXAMPLE\",\n clientNameString = \"sdk-javascript\",\n clientVersionString = version,\n loggerKey = \"log-levels.default\",\n }: ReforgeInitParams) {\n const context = providedContext ?? this.context;\n\n if (!context) {\n throw new Error(\"Context must be provided\");\n }\n\n this._context = context;\n this._loggerKey = loggerKey;\n\n this.clientNameString = clientNameString;\n const clientNameAndVersionString = `${clientNameString}-${clientVersionString}`;\n\n this.loader = new Loader({\n sdkKey,\n context,\n endpoints,\n timeout,\n collectContextMode,\n clientVersion: clientNameAndVersionString,\n });\n\n this._telemetryUploader = new TelemetryUploader({\n sdkKey,\n apiEndpoint,\n timeout,\n clientVersion: clientNameAndVersionString,\n });\n\n this.collectEvaluationSummaries = collectEvaluationSummaries;\n if (collectEvaluationSummaries) {\n this.evalutionSummaryAggregator = new EvaluationSummaryAggregator(this, 100000);\n }\n\n this.collectLoggerNames = collectLoggerNames;\n if (collectLoggerNames) {\n this.loggerAggregator = new LoggerAggregator(this, 100000);\n }\n\n if (\n (collectEvaluationSummaries || collectLoggerNames) &&\n typeof window !== \"undefined\" &&\n typeof window.addEventListener === \"function\"\n ) {\n window.addEventListener(\"beforeunload\", () => {\n this.evalutionSummaryAggregator?.sync();\n this.loggerAggregator?.sync();\n });\n }\n\n this.afterEvaluationCallback = afterEvaluationCallback;\n\n return this.load();\n }\n\n public extract(): Record<string, Config[\"value\"]> {\n return Object.entries(this._configs).reduce(\n (agg, [key, value]) => ({\n ...agg,\n [key]: value.value,\n }),\n {} as Record<string, Config[\"value\"]>\n );\n }\n\n public hydrate(rawValues: RawConfigWithoutTypes | EvaluationPayload): void {\n this.setConfigPrivate(rawValues);\n }\n\n get context(): Context {\n return this._context;\n }\n\n get instanceHash(): string {\n return this._instanceHash;\n }\n\n get pollTimeoutId() {\n return this._pollTimeoutId;\n }\n\n get pollCount() {\n return this._pollCount;\n }\n\n get pollStatus() {\n return this._pollStatus;\n }\n\n get telemetryUploader(): TelemetryUploader | undefined {\n return this._telemetryUploader;\n }\n\n private async load() {\n if (!this.loader || !this.context) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n /* eslint-disable no-underscore-dangle */\n if (globalThis && (globalThis as any)._reforgeBootstrap) {\n /* eslint-disable no-underscore-dangle */\n const reforgeBootstrap = (globalThis as any)._reforgeBootstrap as ReforgeBootstrap;\n const bootstrapContext = new Context(reforgeBootstrap.context);\n\n if (this.context.equals(bootstrapContext)) {\n this.setConfigPrivate({ evaluations: reforgeBootstrap.evaluations });\n return Promise.resolve();\n }\n }\n\n // make sure we have the freshest context\n this.loader.context = this.context;\n\n return this.loader\n .load()\n .then((rawValues: any) => {\n this.setConfigPrivate(rawValues as EvaluationPayload);\n })\n .finally(() => {\n if (this.pollStatus.status === \"running\") {\n this._pollCount += 1;\n }\n });\n }\n\n async updateContext(context: Context, skipLoad = false) {\n if (!this.loader) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n this._context = context;\n\n if (skipLoad) {\n return Promise.resolve();\n }\n\n return this.load();\n }\n\n async poll({ frequencyInMs }: { frequencyInMs: number }) {\n if (!this.loader) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n this.stopPolling();\n\n this._pollStatus = { status: \"pending\" };\n\n return this.loader.load().finally(() => {\n this.doPolling({ frequencyInMs });\n });\n }\n\n private doPolling({ frequencyInMs }: { frequencyInMs: number }) {\n this._pollTimeoutId = setTimeout(() => {\n this.load().finally(() => {\n if (this.pollStatus.status === \"running\") {\n this.doPolling({ frequencyInMs });\n }\n });\n }, frequencyInMs);\n\n this._pollStatus = {\n status: \"running\",\n frequencyInMs,\n };\n }\n\n stopPolling() {\n if (this.pollTimeoutId) {\n clearTimeout(this.pollTimeoutId);\n this._pollTimeoutId = undefined;\n }\n\n this._pollStatus = { status: \"stopped\" };\n }\n\n stopTelemetry() {\n if (this.telemetryUploader) {\n this.evalutionSummaryAggregator?.stop();\n this.loggerAggregator?.stop();\n }\n }\n\n private setConfigPrivate(rawValues: RawConfigWithoutTypes | EvaluationPayload) {\n this._configs = Config.digest(rawValues);\n this.loaded = true;\n }\n\n isEnabled<\n // We need to calcuate these live and not store in a type to ensure dynamic evaluation\n // in upstream libraries that override the FrontEndConfigurationRaw interface\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends boolean\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(key: K): boolean {\n return this.get(key) === true;\n }\n\n get<K extends keyof TypedFrontEndConfigurationRaw>(key: K): TypedFrontEndConfigurationRaw[K] {\n if (!this.loaded) {\n if (!key.startsWith(loggerPrefix)) {\n // eslint-disable-next-line no-console\n console.warn(\n `Reforge warning: The client has not finished loading data yet. Unable to look up actual value for key \"${key}\".`\n );\n }\n\n return undefined;\n }\n\n const config = this._configs[key];\n\n const value = config?.value;\n\n if (!key.startsWith(loggerPrefix)) {\n if (this.collectEvaluationSummaries) {\n setTimeout(() => this.evalutionSummaryAggregator?.record(config));\n }\n\n setTimeout(() => this.afterEvaluationCallback(key, value, this.context));\n }\n\n return value;\n }\n\n getDuration<\n // We need to calcuate these live and not store in a type to ensure dynamic evaluation\n // in upstream libraries that override the FrontEndConfigurationRaw interface\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends Duration\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(key: K): Duration | undefined {\n const value = this.get(key);\n\n if (!value) {\n return undefined;\n }\n\n if (\n !Object.prototype.hasOwnProperty.call(value, \"seconds\") ||\n !Object.prototype.hasOwnProperty.call(value, \"ms\")\n ) {\n throw new Error(`Value for key \"${key}\" is not a duration`);\n }\n\n return value as Duration;\n }\n\n shouldLog(args: PublicShouldLogParams, async = true): boolean {\n if (this.collectLoggerNames) {\n const record = () => this.loggerAggregator?.record(args.loggerName, args.desiredLevel);\n if (async) {\n setTimeout(record);\n } else {\n record();\n }\n }\n\n return shouldLog({ ...args, get: this.get.bind(this) });\n }\n\n getLogLevel(_loggerName: string): LogLevel {\n const value = this.get(this._loggerKey);\n\n if (value && typeof value === \"string\") {\n const upperValue = value.toUpperCase();\n if (upperValue in LogLevel) {\n return LogLevel[upperValue as keyof typeof LogLevel];\n }\n }\n\n // Default to DEBUG if no config found or invalid value\n return LogLevel.DEBUG;\n }\n\n isCollectingEvaluationSummaries(): boolean {\n return this.collectEvaluationSummaries;\n }\n\n isCollectingLoggerNames(): boolean {\n return this.collectLoggerNames;\n }\n}\n\nexport const reforge = new Reforge();\n\nexport function prefetchReforgeConfig({\n sdkKey,\n context,\n endpoints = undefined,\n timeout = undefined,\n collectContextMode = \"PERIODIC_EXAMPLE\",\n clientNameString = \"sdk-javascript\",\n clientVersionString = version,\n}: ReforgeInitParams) {\n const clientNameAndVersionString = `${clientNameString}-${clientVersionString}`;\n\n const loader = new Loader({\n sdkKey,\n context,\n endpoints,\n timeout,\n collectContextMode,\n clientVersion: clientNameAndVersionString,\n });\n\n (window as any).REFORGE_SDK_PREFETCH_PROMISE = loader.load();\n}\n\nexport default prefetchReforgeConfig;\n","import { ReforgeLogLevel } from \"./logger\";\nimport { TypedFrontEndConfigurationRaw, ConfigEvaluationMetadata } from \"./types\";\n\nexport type RawConfigWithoutTypes = Record<string, any>;\n\ntype APIKeyMetadata = {\n id: string | number;\n};\n\n// TODO: Why is this definition different from the one in ./types.ts?\ntype Duration = {\n definition: string;\n millis: number;\n};\n\nexport interface IntRange {\n /** if empty treat as Number.MIN_VALUE. Inclusive */\n start?: bigint | undefined;\n /** if empty treat as Number.MAX_VALUE. Exclusive */\n end?: bigint | undefined;\n}\n\nexport enum ProvidedSource {\n EnvVar = \"ENV_VAR\",\n}\nexport interface Provided {\n source?: ProvidedSource | undefined;\n /** eg MY_ENV_VAR */\n lookup?: string | undefined;\n}\n\nexport enum SchemaType {\n UNKNOWN = 0,\n ZOD = 1,\n JSON_SCHEMA = 2,\n}\n\nexport interface Schema {\n schema: string;\n schemaType: SchemaType;\n}\n\nexport interface WeightedValue {\n /** out of 1000 */\n weight: number;\n // eslint-disable-next-line no-use-before-define\n value: ConfigValue | undefined;\n}\n\nexport enum LimitResponse_LimitPolicyNames {\n SecondlyRolling = 1,\n MinutelyRolling = 3,\n HourlyRolling = 5,\n DailyRolling = 7,\n MonthlyRolling = 8,\n Infinite = 9,\n YearlyRolling = 10,\n}\n\nexport enum LimitDefinition_SafetyLevel {\n L4_BEST_EFFORT = 4,\n L5_BOMBPROOF = 5,\n}\n\nexport interface LimitDefinition {\n policyName: LimitResponse_LimitPolicyNames;\n limit: number;\n burst: number;\n accountId: number;\n lastModified: number;\n returnable: boolean;\n /** [default = L4_BEST_EFFORT]; // Overridable by request */\n safetyLevel: LimitDefinition_SafetyLevel;\n}\nexport interface WeightedValues {\n weightedValues: WeightedValue[];\n hashByPropertyName?: string | undefined;\n}\n\nexport type ConfigValue =\n | {\n int: number | undefined;\n }\n | {\n string: string | undefined;\n }\n | {\n bytes: Buffer | undefined;\n }\n | {\n double: number | undefined;\n }\n | {\n bool: boolean | undefined;\n }\n | {\n weightedValues?: WeightedValues | undefined;\n }\n | {\n limitDefinition?: LimitDefinition | undefined;\n }\n | {\n logLevel: ReforgeLogLevel | undefined;\n }\n | {\n stringList: string[] | undefined;\n }\n | {\n intRange: IntRange | undefined;\n }\n | {\n provided: Provided | undefined;\n }\n | {\n duration: Duration | undefined;\n }\n | {\n json: string | undefined;\n }\n | {\n schema: Schema | undefined;\n }\n | {\n /** don't log or telemetry this value */\n confidential: boolean | undefined;\n }\n | {\n /** key name to decrypt with */\n decryptWith: string | undefined;\n };\n\ntype Evaluation = {\n value: ConfigValue;\n configEvaluationMetadata: {\n configRowIndex: string | number;\n conditionalValueIndex: string | number;\n weightedValueIndex?: string | number;\n type: string;\n valueType: string;\n id: string;\n };\n};\n\nexport type EvaluationPayload = {\n evaluations: { [key: string]: Evaluation };\n apikeyMetadata: APIKeyMetadata;\n};\n\nconst parseRawMetadata = (metadata: any) => ({\n configRowIndex: parseInt(metadata.configRowIndex, 10),\n conditionalValueIndex: parseInt(metadata.conditionalValueIndex, 10),\n type: metadata.type,\n configId: metadata.id,\n});\n\nconst valueFor = <K extends keyof TypedFrontEndConfigurationRaw>(\n value: ConfigValue,\n type: keyof ConfigValue,\n key: K\n): TypedFrontEndConfigurationRaw[K] => {\n const rawValue = value[type];\n\n switch (type) {\n case \"json\":\n try {\n return JSON.parse(rawValue as string);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error(`Error parsing JSON from Reforge config ${key}`, e, rawValue);\n return value[type];\n }\n case \"duration\": {\n const duration = rawValue as Duration;\n return {\n ms: duration.millis,\n seconds: duration.millis / 1000,\n };\n }\n default:\n return rawValue;\n }\n};\n\nexport const parseEvaluationPayload = (payload: EvaluationPayload) => {\n // eslint-disable-next-line no-use-before-define\n const configs = {} as { [key: string]: Config };\n Object.keys(payload.evaluations).forEach((key) => {\n const evaluation = payload.evaluations[key];\n\n const type = Object.keys(evaluation.value)[0] as keyof ConfigValue;\n\n // eslint-disable-next-line no-use-before-define\n configs[key] = new Config(\n key,\n valueFor(evaluation.value, type, key),\n type,\n evaluation.value,\n evaluation.configEvaluationMetadata\n ? parseRawMetadata(evaluation.configEvaluationMetadata)\n : undefined\n );\n });\n\n return configs;\n};\n\nconst parseRawConfigWithoutTypes = (payload: RawConfigWithoutTypes) => {\n // eslint-disable-next-line no-use-before-define\n const configs = {} as { [key: string]: Config };\n Object.keys(payload).forEach((key) => {\n const type = typeof payload[key] as keyof ConfigValue;\n // eslint-disable-next-line no-use-before-define\n configs[key] = new Config(key, valueFor({ [type]: payload[key] }, type, key), type);\n });\n\n return configs;\n};\n\nexport class Config<\n K extends keyof TypedFrontEndConfigurationRaw = keyof TypedFrontEndConfigurationRaw,\n> {\n key: K;\n\n value: TypedFrontEndConfigurationRaw[K];\n\n rawValue: ConfigValue | undefined;\n\n type: keyof ConfigValue;\n\n configEvaluationMetadata: ConfigEvaluationMetadata | undefined;\n\n constructor(\n key: K,\n value: TypedFrontEndConfigurationRaw[K],\n type: keyof ConfigValue,\n rawValue?: ConfigValue,\n metadata?: ConfigEvaluationMetadata\n ) {\n this.key = key;\n this.value = value;\n this.type = type;\n this.rawValue = rawValue;\n this.configEvaluationMetadata = metadata;\n }\n\n static digest(payload: EvaluationPayload | RawConfigWithoutTypes) {\n if (payload === undefined) {\n // eslint-disable-next-line no-console\n console.trace(\"Config.digest called with undefined payload\");\n }\n\n if (\"evaluations\" in payload) {\n return parseEvaluationPayload(payload as EvaluationPayload);\n }\n\n return parseRawConfigWithoutTypes(payload as RawConfigWithoutTypes);\n }\n}\n","const base64Encode = (obj: string) => {\n if (typeof window !== \"undefined\") {\n if (typeof TextEncoder === \"undefined\") {\n return window.btoa(obj);\n }\n\n const bytes = new TextEncoder().encode(obj);\n const binString = Array.from(bytes, (byte) => String.fromCodePoint(byte)).join(\"\");\n return btoa(binString);\n }\n\n return Buffer.from(obj).toString(\"base64\");\n};\n\nexport default base64Encode;\n","import { Contexts, ContextValue } from \"./types\";\nimport base64Encode from \"./base64Encode\";\n\nconst isEqual = (a: Contexts, b: Contexts) => {\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n\n if (aKeys.length !== bKeys.length) {\n return false;\n }\n\n return aKeys.every((key) => {\n const aValues = a[key];\n const bValues = b[key];\n\n const aValuesKeys = Object.keys(aValues);\n const bValuesKeys = Object.keys(bValues);\n\n if (aValuesKeys.length !== bValuesKeys.length) {\n return false;\n }\n\n return aValuesKeys.every((ckey) => {\n const aValue = aValues[ckey];\n const bValue = bValues[ckey];\n\n return aValue === bValue;\n });\n });\n};\n\nconst getType = (value: ContextValue) => {\n if (typeof value === \"string\") {\n return \"string\";\n }\n\n if (typeof value === \"number\") {\n if (Number.isInteger(value)) {\n return \"int\";\n }\n\n return \"double\";\n }\n\n return \"bool\";\n};\n\nexport default class Context {\n contexts: Contexts;\n\n constructor(contexts: Contexts) {\n if (!Object.values(contexts).every((item: any) => typeof item === \"object\")) {\n // eslint-disable-next-line no-console\n console.error(\"Context must be an object where the value of each key is also an object\");\n }\n\n if (\n Object.values(contexts).some((item: any) =>\n Object.values(item).some((value: any) => typeof value === \"object\" && value !== null)\n )\n ) {\n // we decided to allow null values, which requres an extra check since typeof null is object\n // eslint-disable-next-line no-console\n console.error(\"Nested objects are not supported in context values at this time\");\n }\n\n this.contexts = contexts;\n }\n\n equals(other: Context) {\n return isEqual(this.contexts, other.contexts);\n }\n\n encode() {\n const formatted = Object.keys(this.contexts).map((key) => {\n const values: Record<string, Record<string, ContextValue>> = {};\n\n Object.keys(this.contexts[key]).forEach((ckey) => {\n values[ckey] = {\n [getType(this.contexts[key][ckey])]: this.contexts[key][ckey],\n };\n });\n\n return {\n type: key,\n values,\n };\n });\n\n return encodeURIComponent(base64Encode(JSON.stringify({ contexts: formatted })));\n }\n}\n","export class ExponentialBackoff {\n private maxDelay: number;\n\n private multiplier: number;\n\n private delay: number;\n\n // arguments are in seconds\n constructor(maxDelay: number, initialDelay = 2, multiplier = 2) {\n this.maxDelay = maxDelay;\n this.multiplier = multiplier;\n this.delay = initialDelay;\n }\n\n call(): number {\n const delayValue = this.delay;\n this.delay = Math.min(this.delay * this.multiplier, this.maxDelay);\n return delayValue * 1000;\n }\n}\n","import { TypedFrontEndConfigurationRaw } from \"./types\";\n\nexport const PREFIX = \"log-level\";\nexport enum ReforgeLogLevel {\n Trace = 1,\n Debug = 2,\n Info = 3,\n Warn = 4,\n Error = 5,\n Fatal = 6,\n}\n\nexport type LogLevelWord = Uppercase<keyof typeof ReforgeLogLevel>;\n\nconst WORD_LEVEL_LOOKUP: Readonly<Record<LogLevelWord, ReforgeLogLevel>> = {\n TRACE: ReforgeLogLevel.Trace,\n DEBUG: ReforgeLogLevel.Debug,\n INFO: ReforgeLogLevel.Info,\n WARN: ReforgeLogLevel.Warn,\n ERROR: ReforgeLogLevel.Error,\n FATAL: ReforgeLogLevel.Fatal,\n};\n\nexport const isValidLogLevel = (possibleLogLevel: string) =>\n Object.keys(WORD_LEVEL_LOOKUP).includes(possibleLogLevel.toUpperCase());\n\nexport interface ShouldLogParams {\n loggerName: string;\n desiredLevel: ReforgeLogLevel;\n defaultLevel: ReforgeLogLevel;\n get: <K extends keyof TypedFrontEndConfigurationRaw>(key: K) => TypedFrontEndConfigurationRaw[K];\n}\n\n// LogLevel enum for public API\nexport enum LogLevel {\n TRACE = \"TRACE\",\n DEBUG = \"DEBUG\",\n INFO = \"INFO\",\n WARN = \"WARN\",\n ERROR = \"ERROR\",\n FATAL = \"FATAL\",\n}\n\n// Get the numeric severity value for a LogLevel (lower = more verbose)\nexport const getLogLevelSeverity = (level: LogLevel): number => WORD_LEVEL_LOOKUP[level];\n\n// Check if a log at desiredLevel should be logged given the configured level\n// Returns true if desiredLevel is at or above the configured level's severity\nexport const shouldLogAtLevel = (configuredLevel: LogLevel, desiredLevel: LogLevel): boolean =>\n WORD_LEVEL_LOOKUP[configuredLevel] <= WORD_LEVEL_LOOKUP[desiredLevel];\n\nexport const shouldLog = ({\n loggerName,\n desiredLevel,\n defaultLevel,\n get,\n}: ShouldLogParams): boolean => {\n const loggerNameWithPrefix = `${PREFIX}.${loggerName}`;\n\n const resolvedLevel = get(loggerNameWithPrefix);\n\n if (resolvedLevel) {\n return (\n WORD_LEVEL_LOOKUP[resolvedLevel.toString().toUpperCase() as LogLevelWord] <= desiredLevel\n );\n }\n\n return defaultLevel <= desiredLevel;\n};\n","import { ExponentialBackoff } from \"./exponentialBackoff\";\nimport { ReforgeLogLevel } from \"./logger\";\nimport { type reforge } from \"./reforge\";\n\nabstract class PeriodicSync<T> {\n protected data: Map<string, T> = new Map();\n\n private startAt: Date;\n\n private syncInterval: any;\n\n protected client: typeof reforge;\n\n private name: string;\n\n private timeoutID: ReturnType<typeof setTimeout> | undefined;\n\n constructor(client: typeof reforge, name: string, syncInterval?: number) {\n this.client = client;\n this.name = name;\n\n this.startAt = new Date();\n\n this.startPeriodicSync(syncInterval);\n }\n\n stop(): void {\n clearTimeout(this.timeoutID);\n }\n\n sync(): void {\n if (this.data.size === 0) return;\n\n this.logInternal(`${this.name} syncing ${this.data.size} items`);\n\n const startAtWas = this.startAt;\n this.startAt = new Date();\n\n this.flush(this.prepareData(), startAtWas);\n }\n\n protected abstract flush(toShip: Map<string, T>, startAtWas: Date): void;\n\n private prepareData(): Map<string, T> {\n const toShip = new Map(this.data);\n this.data.clear();\n\n return toShip;\n }\n\n private startPeriodicSync(syncInterval?: number): void {\n this.startAt = new Date();\n this.syncInterval = PeriodicSync.calculateSyncInterval(syncInterval);\n\n this.scheduleNextSync();\n }\n\n private scheduleNextSync() {\n const interval = this.syncInterval();\n this.timeoutID = setTimeout(() => {\n this.sync();\n this.scheduleNextSync(); // Schedule the next sync after the current one completes\n }, interval);\n }\n\n private static calculateSyncInterval(syncInterval?: number): any {\n if (syncInterval !== undefined) {\n return () => syncInterval;\n }\n\n const backoff = new ExponentialBackoff(60 * 5, 8);\n return () => backoff.call();\n }\n\n protected logInternal(message: string): void {\n const loggerName = `${this.client.clientNameString}.reforge.${this.name}`;\n\n if (\n this.client.shouldLog(\n {\n loggerName,\n desiredLevel: ReforgeLogLevel.Debug,\n defaultLevel: ReforgeLogLevel.Error,\n },\n false // synchronous so that this log ends up in the current batch\n )\n ) {\n // eslint-disable-next-line no-console\n console.log(`${loggerName}: ${message}`);\n }\n }\n}\n\nexport { PeriodicSync };\n","// TODO: should we retry the data chunk if a flush fails?\n\n// TODO: pause when offline?\n\n// TODO: flush when we receive a config update (or as a result of a context update...but that should trigger a config update anyway)\n\nimport { PeriodicSync } from \"./periodicSync\";\nimport { Config } from \"./config\";\nimport { type reforge } from \"./reforge\";\nimport {\n ConfigEvaluationCounter,\n ConfigEvaluationSummaries,\n ConfigEvaluationSummary,\n TelemetryEvents,\n ConfigEvaluationMetadata,\n} from \"./types\";\n\nexport const massageSelectedValue = (config: Config): any => {\n if (config.rawValue && (config.type === \"duration\" || config.type === \"json\")) {\n if (config.type === \"json\") {\n return { json: config.rawValue[config.type] };\n }\n\n return config.rawValue[config.type];\n }\n\n return config.type === \"stringList\" ? { values: config.value } : config.value;\n};\n\nexport const massageConfigForTelemetry = (\n config: Config,\n metadata: Omit<ConfigEvaluationMetadata, \"type\">\n) => ({\n ...metadata,\n selectedValue: {\n [config.type]: massageSelectedValue(config),\n },\n count: 0,\n});\n\nclass EvaluationSummaryAggregator extends PeriodicSync<ConfigEvaluationCounter> {\n private maxKeys: number;\n\n constructor(client: typeof reforge, maxKeys: number, syncInterval?: number) {\n super(client, \"EvaluationSummaryAggregator\", syncInterval ?? 30000);\n\n this.maxKeys = maxKeys;\n }\n\n record(config: Config): void {\n if (this.data.size >= this.maxKeys) return;\n\n if (config?.configEvaluationMetadata) {\n const { type, ...metadata } = config.configEvaluationMetadata;\n const key = `${config.key},${type}`;\n\n // create counter entry if it doesn't exist\n if (!this.data.has(key)) {\n this.data.set(key, massageConfigForTelemetry(config, metadata));\n }\n\n // increment count\n const counter = this.data.get(key);\n if (counter) {\n counter.count += 1;\n }\n }\n }\n\n protected flush(toShip: Map<string, ConfigEvaluationCounter>, startAtWas: Date): void {\n const summaries = {\n start: startAtWas.getTime(),\n end: new Date().getTime(),\n summaries: EvaluationSummaryAggregator.summaries(toShip),\n };\n\n this.client.telemetryUploader?.post(this.events(summaries));\n }\n\n private static summaries(data: Map<string, ConfigEvaluationCounter>): ConfigEvaluationSummary[] {\n return Array.from(data).map((entry: [string, ConfigEvaluationCounter]) => {\n const [configKey, configType] = entry[0].split(\",\");\n const counter = entry[1];\n const counters = [counter]; // this client only ever has one set of counter info per key\n\n return {\n key: configKey,\n type: configType,\n counters,\n };\n });\n }\n\n private events(summaries: ConfigEvaluationSummaries): TelemetryEvents {\n const event = { summaries };\n\n return {\n instanceHash: this.client.instanceHash,\n events: [event],\n };\n }\n}\n\nexport { EvaluationSummaryAggregator };\n","import base64Encode from \"./base64Encode\";\n\nexport const headers = (sdkKey: string, clientVersion: string) => ({\n Authorization: `Basic ${base64Encode(`u:${sdkKey}`)}`,\n \"X-Reforge-SDK-Version\": clientVersion,\n});\n\nexport const DEFAULT_TIMEOUT = 10000;\n","import { DEFAULT_TIMEOUT, headers } from \"./apiHelpers\";\nimport { EvaluationPayload } from \"./config\";\nimport Context from \"./context\";\n\nexport type CollectContextModeType = \"NONE\" | \"SHAPE_ONLY\" | \"PERIODIC_EXAMPLE\";\n\nexport type LoaderParams = {\n sdkKey: string;\n context: Context;\n endpoints?: string[] | undefined;\n timeout?: number;\n collectContextMode?: CollectContextModeType;\n clientVersion?: string;\n};\n\nexport type Headers = {\n [key: string]: string;\n};\n\nexport type FetchOptions = {\n headers: Headers;\n};\n\nconst defaultEndpoints = [\n \"https://primary.reforge.com/api/v2\",\n \"https://secondary.reforge.com/api/v2\",\n];\n\nconst EARLY_TIMEOUT = 2000;\n\nexport default class Loader {\n sdkKey: string;\n\n context: Context;\n\n endpoints: string[];\n\n timeout: number;\n\n abortTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n collectContextMode: CollectContextModeType = \"PERIODIC_EXAMPLE\";\n\n clientVersion: string;\n\n abortController: AbortController | undefined;\n\n isAborted = false;\n\n constructor({\n sdkKey,\n context,\n endpoints = undefined,\n timeout,\n collectContextMode = \"PERIODIC_EXAMPLE\",\n clientVersion = \"\",\n }: LoaderParams) {\n this.sdkKey = sdkKey;\n this.context = context;\n this.endpoints = endpoints || defaultEndpoints;\n this.timeout = timeout || DEFAULT_TIMEOUT;\n this.collectContextMode = collectContextMode;\n this.clientVersion = clientVersion;\n }\n\n url(root: string) {\n return `${root}/configs/eval-with-context/${this.context.encode()}?collectContextMode=${\n this.collectContextMode\n }`;\n }\n\n loadFromEndpoint(\n index: number,\n options: FetchOptions,\n resolve: (value: any) => void,\n reject: (value: any) => void\n ) {\n this.abortController = new AbortController() as AbortController;\n const { signal } = this.abortController;\n this.isAborted = false;\n\n const endpoint = this.endpoints[index];\n const url = this.url(endpoint);\n\n fetch(url, { signal, ...options })\n .then((response) => {\n this.clearAbortTimeout();\n\n if (response.ok) {\n return response.json();\n }\n throw new Error(`${response.status} ${response.statusText}`);\n })\n .then((data) => {\n if (!(\"evaluations\" in data)) {\n throw new Error(`Invalid payload:${JSON.stringify(data)}`);\n }\n\n resolve(data as EvaluationPayload);\n })\n .catch((error) => {\n this.clearAbortTimeout();\n\n if (index < this.endpoints.length - 1) {\n this.loadFromEndpoint(index + 1, options, resolve, reject);\n } else {\n reject(error);\n }\n });\n\n // Use an early timeout if we're not on the last endpoint. But if the user-provided timeout is less than EARLY_TIMEOUT, use that\n const timeout =\n index < this.endpoints.length - 1 ? Math.min(this.timeout, EARLY_TIMEOUT) : this.timeout;\n\n this.abortTimeoutId = setTimeout(() => {\n if (!this.isAborted) {\n this.isAborted = true;\n this.abortController?.abort();\n }\n }, timeout);\n }\n\n load() {\n if (!this.isAborted) {\n this.isAborted = true;\n this.abortController?.abort();\n }\n\n const options = {\n headers: headers(this.sdkKey, this.clientVersion),\n };\n\n const prefetchPromise =\n typeof window !== \"undefined\" ? (window as any).REFORGE_SDK_PREFETCH_PROMISE : undefined;\n\n if (prefetchPromise && prefetchPromise instanceof Promise) {\n (window as any).REFORGE_SDK_PREFETCH_PROMISE = undefined;\n return prefetchPromise.catch(\n () =>\n // If the prefetch failed, we should try to load from the endpoints\n new Promise((resolve, reject) => {\n this.loadFromEndpoint(0, options, resolve, reject);\n })\n );\n }\n\n const promise = new Promise((resolve, reject) => {\n this.loadFromEndpoint(0, options, resolve, reject);\n });\n\n return promise;\n }\n\n clearAbortTimeout() {\n clearTimeout(this.abortTimeoutId);\n }\n}\n","import { DEFAULT_TIMEOUT, headers } from \"./apiHelpers\";\nimport { TelemetryEvents } from \"./types\";\n\nexport type TelemetryUploaderParams = {\n sdkKey: string;\n apiEndpoint?: string;\n timeout?: number;\n clientVersion: string;\n};\n\nexport default class TelemetryUploader {\n sdkKey: Required<TelemetryUploaderParams>[\"sdkKey\"];\n\n apiEndpoint: Required<TelemetryUploaderParams>[\"apiEndpoint\"];\n\n timeout: Required<TelemetryUploaderParams>[\"timeout\"];\n\n clientVersion: Required<TelemetryUploaderParams>[\"clientVersion\"];\n\n abortTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n constructor({\n sdkKey,\n apiEndpoint = undefined,\n timeout,\n clientVersion,\n }: TelemetryUploaderParams) {\n this.sdkKey = sdkKey;\n this.apiEndpoint = apiEndpoint || \"https://telemetry.reforge.com/api/v1\";\n this.timeout = timeout || DEFAULT_TIMEOUT;\n this.clientVersion = clientVersion;\n }\n\n clearAbortTimeout() {\n clearTimeout(this.abortTimeoutId);\n }\n\n static postUrl(root: string) {\n return `${root}/telemetry`;\n }\n\n postToEndpoint(\n options: RequestInit,\n resolve: (value: unknown) => void,\n reject: (value: unknown) => void\n ) {\n const controller = new AbortController() as AbortController;\n const signal = controller?.signal;\n let isAborted = false;\n\n const url = TelemetryUploader.postUrl(this.apiEndpoint);\n\n fetch(url, { signal, ...options })\n .then((response) => {\n this.clearAbortTimeout();\n\n if (response.ok) {\n return response.json();\n }\n\n // eslint-disable-next-line no-console\n console.warn(\n `Reforge warning: Error uploading telemetry ${response.status} ${response.statusText}`\n );\n\n return response.status;\n })\n .then((response) => {\n resolve(response);\n })\n .catch((error) => {\n this.clearAbortTimeout();\n\n // Silently handle AbortErrors (from timeouts or page navigations)\n if (error.name === \"AbortError\") {\n try {\n // eslint-disable-next-line no-console\n console.debug(\"Reforge telemetry request aborted\");\n } catch (e) {\n // no-op\n }\n resolve({ status: \"aborted\" });\n return;\n }\n\n reject(error);\n });\n\n this.abortTimeoutId = setTimeout(() => {\n if (!isAborted) {\n isAborted = true;\n controller.abort();\n }\n }, this.timeout);\n }\n\n post(data: TelemetryEvents) {\n const options = {\n method: \"POST\",\n headers: {\n ...headers(this.sdkKey, this.clientVersion),\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n body: JSON.stringify(data),\n keepalive: true, // needed for flushing when the window is closed\n };\n\n const promise = new Promise((resolve, reject) => {\n this.postToEndpoint(options, resolve, reject);\n });\n\n return promise;\n }\n}\n","// TODO: should we retry the data chunk if a flush fails?\n\n// TODO: pause when offline?\n\nimport { ReforgeLogLevel } from \"./logger\";\nimport { PeriodicSync } from \"./periodicSync\";\nimport { type reforge } from \"./reforge\";\nimport { LoggerCounter, LoggersTelemetryEvent, TelemetryEvents } from \"./types\";\n\nconst SEVERITY_KEY: { [key in ReforgeLogLevel]: Omit<keyof LoggerCounter, \"loggerName\"> } = {\n [ReforgeLogLevel.Trace]: \"traces\",\n [ReforgeLogLevel.Debug]: \"debugs\",\n [ReforgeLogLevel.Info]: \"infos\",\n [ReforgeLogLevel.Warn]: \"warns\",\n [ReforgeLogLevel.Error]: \"errors\",\n [ReforgeLogLevel.Fatal]: \"fatals\",\n};\n\nclass LoggerAggregator extends PeriodicSync<LoggerCounter> {\n private maxLoggers: number;\n\n constructor(client: typeof reforge, maxLoggers: number, syncInterval?: number) {\n super(client, \"LoggerAggregator\", syncInterval ?? 30000);\n\n this.maxLoggers = maxLoggers;\n }\n\n record(logger: string, level: ReforgeLogLevel): void {\n if (this.data.size >= this.maxLoggers) return;\n\n // create counter entry if it doesn't exist\n if (!this.data.has(logger)) {\n this.data.set(logger, {\n loggerName: logger,\n traces: 0,\n debugs: 0,\n infos: 0,\n warns: 0,\n errors: 0,\n fatals: 0,\n });\n }\n\n // increment count\n const counter = this.data.get(logger);\n if (counter) {\n const severityKey = SEVERITY_KEY[level] as keyof LoggerCounter;\n (counter[severityKey] as number) += 1;\n }\n }\n\n protected flush(toShip: Map<string, LoggerCounter>, startAtWas: Date): void {\n const loggers = {\n startAt: startAtWas.getTime(),\n endAt: new Date().getTime(),\n loggers: Array.from(toShip.values()),\n };\n\n this.client.telemetryUploader?.post(this.events(loggers));\n }\n\n private events(loggers: LoggersTelemetryEvent): TelemetryEvents {\n const event = { loggers };\n\n return {\n instanceHash: this.client.instanceHash,\n events: [event],\n };\n }\n}\n\nexport { LoggerAggregator };\n"],"mappings":"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","names":["exports","module","version","LogLevel","reforge","uuid","version"]}

@@ -245,3 +245,3 @@ type Duration$1 = {

loadFromEndpoint(index: number, options: FetchOptions, resolve: (value: any) => void, reject: (value: any) => void): void;
load(): Promise<unknown>;
load(): Promise<any>;
clearAbortTimeout(): void;

@@ -342,3 +342,3 @@ }

frequencyInMs: number;
}): Promise<unknown>;
}): Promise<any>;
private doPolling;

@@ -361,5 +361,6 @@ stopPolling(): void;

declare const reforge: Reforge;
declare function prefetchReforgeConfig({ sdkKey, context, endpoints, timeout, collectContextMode, clientNameString, clientVersionString, }: ReforgeInitParams): void;
declare const version: any;
export { type CollectContextModeType, Config, type ConfigValue, Context, type ContextValue, type Contexts, type Duration$1 as Duration, type FrontEndConfigurationRaw, LogLevel, Reforge, type ReforgeBootstrap, type ReforgeInitParams, type TypedFrontEndConfigurationRaw, getLogLevelSeverity, reforge, shouldLogAtLevel, version };
export { type CollectContextModeType, Config, type ConfigValue, Context, type ContextValue, type Contexts, type Duration$1 as Duration, type FrontEndConfigurationRaw, LogLevel, Reforge, type ReforgeBootstrap, type ReforgeInitParams, type TypedFrontEndConfigurationRaw, getLogLevelSeverity, prefetchReforgeConfig, reforge, shouldLogAtLevel, version };

@@ -245,3 +245,3 @@ type Duration$1 = {

loadFromEndpoint(index: number, options: FetchOptions, resolve: (value: any) => void, reject: (value: any) => void): void;
load(): Promise<unknown>;
load(): Promise<any>;
clearAbortTimeout(): void;

@@ -342,3 +342,3 @@ }

frequencyInMs: number;
}): Promise<unknown>;
}): Promise<any>;
private doPolling;

@@ -361,5 +361,6 @@ stopPolling(): void;

declare const reforge: Reforge;
declare function prefetchReforgeConfig({ sdkKey, context, endpoints, timeout, collectContextMode, clientNameString, clientVersionString, }: ReforgeInitParams): void;
declare const version: any;
export { type CollectContextModeType, Config, type ConfigValue, Context, type ContextValue, type Contexts, type Duration$1 as Duration, type FrontEndConfigurationRaw, LogLevel, Reforge, type ReforgeBootstrap, type ReforgeInitParams, type TypedFrontEndConfigurationRaw, getLogLevelSeverity, reforge, shouldLogAtLevel, version };
export { type CollectContextModeType, Config, type ConfigValue, Context, type ContextValue, type Contexts, type Duration$1 as Duration, type FrontEndConfigurationRaw, LogLevel, Reforge, type ReforgeBootstrap, type ReforgeInitParams, type TypedFrontEndConfigurationRaw, getLogLevelSeverity, prefetchReforgeConfig, reforge, shouldLogAtLevel, version };

@@ -61,5 +61,5 @@ var __defProp = Object.defineProperty;

module.exports = {
packageManager: "yarn@4.9.2",
packageManager: "yarn@4.11.0",
name: "@reforge-com/javascript",
version: "0.0.4",
version: "0.0.5",
description: "Feature Flags & Dynamic Configuration as a Service",

@@ -88,2 +88,3 @@ main: "dist/index.cjs",

jest: "^29.0.0",
"jest-environment-jsdom": "^30.2.0",
"jest-fetch-mock": "^3.0.3",

@@ -536,2 +537,14 @@ prettier: "^3.0.0",

};
const prefetchPromise = typeof window !== "undefined" ? window.REFORGE_SDK_PREFETCH_PROMISE : void 0;
if (prefetchPromise && prefetchPromise instanceof Promise) {
window.REFORGE_SDK_PREFETCH_PROMISE = void 0;
return prefetchPromise.catch(
() => (
// If the prefetch failed, we should try to load from the endpoints
new Promise((resolve, reject) => {
this.loadFromEndpoint(0, options, resolve, reject);
})
)
);
}
const promise = new Promise((resolve, reject) => {

@@ -967,2 +980,22 @@ this.loadFromEndpoint(0, options, resolve, reject);

var reforge = new Reforge();
function prefetchReforgeConfig({
sdkKey,
context,
endpoints = void 0,
timeout = void 0,
collectContextMode = "PERIODIC_EXAMPLE",
clientNameString = "sdk-javascript",
clientVersionString = version
}) {
const clientNameAndVersionString = `${clientNameString}-${clientVersionString}`;
const loader = new Loader({
sdkKey,
context,
endpoints,
timeout,
collectContextMode,
clientVersion: clientNameAndVersionString
});
window.REFORGE_SDK_PREFETCH_PROMISE = loader.load();
}

@@ -977,2 +1010,3 @@ // index.ts

getLogLevelSeverity,
prefetchReforgeConfig,
reforge,

@@ -979,0 +1013,0 @@ shouldLogAtLevel,

@@ -1,1 +0,1 @@

{"version":3,"sources":["../package.json","../src/reforge.ts","../src/config.ts","../src/base64Encode.ts","../src/context.ts","../src/exponentialBackoff.ts","../src/logger.ts","../src/periodicSync.ts","../src/evaluationSummaryAggregator.ts","../src/apiHelpers.ts","../src/loader.ts","../src/telemetryUploader.ts","../src/loggerAggregator.ts","../index.ts"],"sourcesContent":["{\n \"packageManager\": \"yarn@4.9.2\",\n \"name\": \"@reforge-com/javascript\",\n \"version\": \"0.0.4\",\n \"description\": \"Feature Flags & Dynamic Configuration as a Service\",\n \"main\": \"dist/index.cjs\",\n \"module\": \"dist/index.mjs\",\n \"types\": \"dist/index.d.ts\",\n \"author\": \"Jeffrey Chupp\",\n \"license\": \"ISC\",\n \"devDependencies\": {\n \"@types/eslint-plugin-jsx-a11y\": \"^6\",\n \"@types/express\": \"^4.17.13\",\n \"@types/jest\": \"^28.1.6\",\n \"@types/uuid\": \"^9.0.5\",\n \"@typescript-eslint/eslint-plugin\": \"^5.33.0\",\n \"@typescript-eslint/parser\": \"^5.33.0\",\n \"esbuild\": \"^0.25.11\",\n \"eslint\": \"^8.21.0\",\n \"eslint-config-airbnb\": \"^19.0.4\",\n \"eslint-config-airbnb-typescript\": \"^17.0.0\",\n \"eslint-config-prettier\": \"^8.8.0\",\n \"eslint-plugin-import\": \"^2.26.0\",\n \"eslint-plugin-jest\": \"^26.8.0\",\n \"eslint-plugin-jsx-a11y\": \"^6.10.2\",\n \"eslint-plugin-react\": \"^7.37.5\",\n \"jest\": \"^29.0.0\",\n \"jest-fetch-mock\": \"^3.0.3\",\n \"prettier\": \"^3.0.0\",\n \"ts-jest\": \"^29.1.1\",\n \"ts-node\": \"^10.9.1\",\n \"tsup\": \"^8.0.2\",\n \"typescript\": \"^5.1.6\"\n },\n \"scripts\": {\n \"build\": \"rm -rf dist/ && tsup\",\n \"dev\": \"tsup --watch\",\n \"bundle\": \"esbuild --minify --target=esnext --bundle --outfile=dist/reforge.bundle.js --global-name=window.reforgeNamespace dist/index.cjs && echo 'window.reforge = window.reforgeNamespace.reforge' >> dist/reforge.bundle.js\",\n \"lint\": \"eslint --ext .ts,.tsx src/\",\n \"lint:fix\": \"eslint --fix --ext .ts,.tsx src/\",\n \"prettier\": \"prettier . -l\",\n \"prettier:fix\": \"prettier --write .\",\n \"test\": \"jest --verbose\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/ReforgeHQ/sdk-javascript.git\"\n },\n \"keywords\": [\n \"feature-flags\",\n \"config\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/ReforgeHQ/sdk-javascript/issues\"\n },\n \"homepage\": \"https://github.com/ReforgeHQ/sdk-javascript#readme\",\n \"dependencies\": {\n \"uuid\": \"^9.0.1\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.mjs\",\n \"require\": \"./dist/index.cjs\"\n }\n }\n}\n","/* eslint-disable max-classes-per-file */\nimport { v4 as uuid } from \"uuid\";\n\nimport { Config, EvaluationPayload, RawConfigWithoutTypes } from \"./config\";\nimport type {\n Duration,\n TypedFrontEndConfigurationRaw,\n FrontEndConfigurationRaw,\n Contexts,\n} from \"./types\";\nimport Context from \"./context\";\nimport { EvaluationSummaryAggregator } from \"./evaluationSummaryAggregator\";\nimport Loader, { CollectContextModeType } from \"./loader\";\nimport {\n PREFIX as loggerPrefix,\n shouldLog,\n ShouldLogParams,\n LogLevel,\n shouldLogAtLevel,\n} from \"./logger\";\nimport TelemetryUploader from \"./telemetryUploader\";\nimport { LoggerAggregator } from \"./loggerAggregator\";\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version } = require(\"../package.json\");\n\ntype EvaluationCallback = <K extends keyof TypedFrontEndConfigurationRaw>(\n key: K,\n value: TypedFrontEndConfigurationRaw[K],\n context: Context | undefined\n) => void;\n\nexport interface ReforgeBootstrap {\n evaluations: EvaluationPayload;\n context: Contexts;\n}\n\nexport type ReforgeInitParams = {\n sdkKey: string;\n context: Context;\n endpoints?: string[] | undefined;\n apiEndpoint?: string;\n timeout?: number;\n afterEvaluationCallback?: EvaluationCallback;\n collectEvaluationSummaries?: boolean;\n collectLoggerNames?: boolean;\n collectContextMode?: CollectContextModeType;\n clientNameString?: string;\n clientVersionString?: string;\n loggerKey?: string;\n};\n\ntype PollStatus =\n | { status: \"not-started\" }\n | { status: \"pending\" }\n | { status: \"stopped\" }\n | { status: \"running\"; frequencyInMs: number };\n\ntype PublicShouldLogParams = Omit<ShouldLogParams, \"get\">;\n\n// Forward declaration for ReforgeLogger\n// eslint-disable-next-line @typescript-eslint/no-use-before-define\nclass ReforgeLogger {\n // eslint-disable-next-line no-use-before-define\n private reforge: Reforge;\n\n // eslint-disable-next-line no-use-before-define\n constructor(reforge: Reforge) {\n this.reforge = reforge;\n }\n\n private log(message: string, level: LogLevel): void {\n const configuredLevel = this.reforge.getLogLevel(\"\");\n\n if (shouldLogAtLevel(configuredLevel, level)) {\n switch (level) {\n case LogLevel.TRACE:\n case LogLevel.DEBUG:\n // eslint-disable-next-line no-console\n console.debug(message);\n break;\n case LogLevel.INFO:\n // eslint-disable-next-line no-console\n console.info(message);\n break;\n case LogLevel.WARN:\n // eslint-disable-next-line no-console\n console.warn(message);\n break;\n case LogLevel.ERROR:\n case LogLevel.FATAL:\n // eslint-disable-next-line no-console\n console.error(message);\n break;\n default:\n // eslint-disable-next-line no-console\n console.error(message);\n }\n }\n }\n\n trace(message: string): void {\n this.log(message, LogLevel.TRACE);\n }\n\n debug(message: string): void {\n this.log(message, LogLevel.DEBUG);\n }\n\n info(message: string): void {\n this.log(message, LogLevel.INFO);\n }\n\n warn(message: string): void {\n this.log(message, LogLevel.WARN);\n }\n\n error(message: string): void {\n this.log(message, LogLevel.ERROR);\n }\n\n fatal(message: string): void {\n this.log(message, LogLevel.FATAL);\n }\n}\n\nexport class Reforge {\n private _configs: { [key: string]: Config } = {};\n\n private _telemetryUploader: TelemetryUploader | undefined;\n\n private _pollCount = 0;\n\n private _pollStatus: PollStatus = { status: \"not-started\" };\n\n private _pollTimeoutId = undefined as ReturnType<typeof setTimeout> | undefined;\n\n private _instanceHash: string = uuid();\n\n private collectEvaluationSummaries = true;\n\n private collectLoggerNames = false;\n\n private evalutionSummaryAggregator: EvaluationSummaryAggregator | undefined;\n\n private loggerAggregator: LoggerAggregator | undefined;\n\n public clientNameString = \"sdk-javascript\";\n\n public loaded = false;\n\n public loader: Loader | undefined;\n\n public afterEvaluationCallback = (() => {}) as EvaluationCallback;\n\n private _context: Context = new Context({});\n\n private _loggerKey = \"log-levels.default\";\n\n public logger: ReforgeLogger;\n\n constructor() {\n this.logger = new ReforgeLogger(this);\n }\n\n async init({\n sdkKey,\n context: providedContext,\n endpoints = undefined,\n apiEndpoint,\n timeout = undefined,\n afterEvaluationCallback = () => {},\n collectEvaluationSummaries = true,\n collectLoggerNames = false,\n collectContextMode = \"PERIODIC_EXAMPLE\",\n clientNameString = \"sdk-javascript\",\n clientVersionString = version,\n loggerKey = \"log-levels.default\",\n }: ReforgeInitParams) {\n const context = providedContext ?? this.context;\n\n if (!context) {\n throw new Error(\"Context must be provided\");\n }\n\n this._context = context;\n this._loggerKey = loggerKey;\n\n this.clientNameString = clientNameString;\n const clientNameAndVersionString = `${clientNameString}-${clientVersionString}`;\n\n this.loader = new Loader({\n sdkKey,\n context,\n endpoints,\n timeout,\n collectContextMode,\n clientVersion: clientNameAndVersionString,\n });\n\n this._telemetryUploader = new TelemetryUploader({\n sdkKey,\n apiEndpoint,\n timeout,\n clientVersion: clientNameAndVersionString,\n });\n\n this.collectEvaluationSummaries = collectEvaluationSummaries;\n if (collectEvaluationSummaries) {\n this.evalutionSummaryAggregator = new EvaluationSummaryAggregator(this, 100000);\n }\n\n this.collectLoggerNames = collectLoggerNames;\n if (collectLoggerNames) {\n this.loggerAggregator = new LoggerAggregator(this, 100000);\n }\n\n if (\n (collectEvaluationSummaries || collectLoggerNames) &&\n typeof window !== \"undefined\" &&\n typeof window.addEventListener === \"function\"\n ) {\n window.addEventListener(\"beforeunload\", () => {\n this.evalutionSummaryAggregator?.sync();\n this.loggerAggregator?.sync();\n });\n }\n\n this.afterEvaluationCallback = afterEvaluationCallback;\n\n return this.load();\n }\n\n public extract(): Record<string, Config[\"value\"]> {\n return Object.entries(this._configs).reduce(\n (agg, [key, value]) => ({\n ...agg,\n [key]: value.value,\n }),\n {} as Record<string, Config[\"value\"]>\n );\n }\n\n public hydrate(rawValues: RawConfigWithoutTypes | EvaluationPayload): void {\n this.setConfigPrivate(rawValues);\n }\n\n get context(): Context {\n return this._context;\n }\n\n get instanceHash(): string {\n return this._instanceHash;\n }\n\n get pollTimeoutId() {\n return this._pollTimeoutId;\n }\n\n get pollCount() {\n return this._pollCount;\n }\n\n get pollStatus() {\n return this._pollStatus;\n }\n\n get telemetryUploader(): TelemetryUploader | undefined {\n return this._telemetryUploader;\n }\n\n private async load() {\n if (!this.loader || !this.context) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n /* eslint-disable no-underscore-dangle */\n if (globalThis && (globalThis as any)._reforgeBootstrap) {\n /* eslint-disable no-underscore-dangle */\n const reforgeBootstrap = (globalThis as any)._reforgeBootstrap as ReforgeBootstrap;\n const bootstrapContext = new Context(reforgeBootstrap.context);\n\n if (this.context.equals(bootstrapContext)) {\n this.setConfigPrivate({ evaluations: reforgeBootstrap.evaluations });\n return Promise.resolve();\n }\n }\n\n // make sure we have the freshest context\n this.loader.context = this.context;\n\n return this.loader\n .load()\n .then((rawValues: any) => {\n this.setConfigPrivate(rawValues as EvaluationPayload);\n })\n .finally(() => {\n if (this.pollStatus.status === \"running\") {\n this._pollCount += 1;\n }\n });\n }\n\n async updateContext(context: Context, skipLoad = false) {\n if (!this.loader) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n this._context = context;\n\n if (skipLoad) {\n return Promise.resolve();\n }\n\n return this.load();\n }\n\n async poll({ frequencyInMs }: { frequencyInMs: number }) {\n if (!this.loader) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n this.stopPolling();\n\n this._pollStatus = { status: \"pending\" };\n\n return this.loader.load().finally(() => {\n this.doPolling({ frequencyInMs });\n });\n }\n\n private doPolling({ frequencyInMs }: { frequencyInMs: number }) {\n this._pollTimeoutId = setTimeout(() => {\n this.load().finally(() => {\n if (this.pollStatus.status === \"running\") {\n this.doPolling({ frequencyInMs });\n }\n });\n }, frequencyInMs);\n\n this._pollStatus = {\n status: \"running\",\n frequencyInMs,\n };\n }\n\n stopPolling() {\n if (this.pollTimeoutId) {\n clearTimeout(this.pollTimeoutId);\n this._pollTimeoutId = undefined;\n }\n\n this._pollStatus = { status: \"stopped\" };\n }\n\n stopTelemetry() {\n if (this.telemetryUploader) {\n this.evalutionSummaryAggregator?.stop();\n this.loggerAggregator?.stop();\n }\n }\n\n private setConfigPrivate(rawValues: RawConfigWithoutTypes | EvaluationPayload) {\n this._configs = Config.digest(rawValues);\n this.loaded = true;\n }\n\n isEnabled<\n // We need to calcuate these live and not store in a type to ensure dynamic evaluation\n // in upstream libraries that override the FrontEndConfigurationRaw interface\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends boolean\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(key: K): boolean {\n return this.get(key) === true;\n }\n\n get<K extends keyof TypedFrontEndConfigurationRaw>(key: K): TypedFrontEndConfigurationRaw[K] {\n if (!this.loaded) {\n if (!key.startsWith(loggerPrefix)) {\n // eslint-disable-next-line no-console\n console.warn(\n `Reforge warning: The client has not finished loading data yet. Unable to look up actual value for key \"${key}\".`\n );\n }\n\n return undefined;\n }\n\n const config = this._configs[key];\n\n const value = config?.value;\n\n if (!key.startsWith(loggerPrefix)) {\n if (this.collectEvaluationSummaries) {\n setTimeout(() => this.evalutionSummaryAggregator?.record(config));\n }\n\n setTimeout(() => this.afterEvaluationCallback(key, value, this.context));\n }\n\n return value;\n }\n\n getDuration<\n // We need to calcuate these live and not store in a type to ensure dynamic evaluation\n // in upstream libraries that override the FrontEndConfigurationRaw interface\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends Duration\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(key: K): Duration | undefined {\n const value = this.get(key);\n\n if (!value) {\n return undefined;\n }\n\n if (\n !Object.prototype.hasOwnProperty.call(value, \"seconds\") ||\n !Object.prototype.hasOwnProperty.call(value, \"ms\")\n ) {\n throw new Error(`Value for key \"${key}\" is not a duration`);\n }\n\n return value as Duration;\n }\n\n shouldLog(args: PublicShouldLogParams, async = true): boolean {\n if (this.collectLoggerNames) {\n const record = () => this.loggerAggregator?.record(args.loggerName, args.desiredLevel);\n if (async) {\n setTimeout(record);\n } else {\n record();\n }\n }\n\n return shouldLog({ ...args, get: this.get.bind(this) });\n }\n\n getLogLevel(_loggerName: string): LogLevel {\n const value = this.get(this._loggerKey);\n\n if (value && typeof value === \"string\") {\n const upperValue = value.toUpperCase();\n if (upperValue in LogLevel) {\n return LogLevel[upperValue as keyof typeof LogLevel];\n }\n }\n\n // Default to DEBUG if no config found or invalid value\n return LogLevel.DEBUG;\n }\n\n isCollectingEvaluationSummaries(): boolean {\n return this.collectEvaluationSummaries;\n }\n\n isCollectingLoggerNames(): boolean {\n return this.collectLoggerNames;\n }\n}\n\nexport const reforge = new Reforge();\n","import { ReforgeLogLevel } from \"./logger\";\nimport { TypedFrontEndConfigurationRaw, ConfigEvaluationMetadata } from \"./types\";\n\nexport type RawConfigWithoutTypes = Record<string, any>;\n\ntype APIKeyMetadata = {\n id: string | number;\n};\n\n// TODO: Why is this definition different from the one in ./types.ts?\ntype Duration = {\n definition: string;\n millis: number;\n};\n\nexport interface IntRange {\n /** if empty treat as Number.MIN_VALUE. Inclusive */\n start?: bigint | undefined;\n /** if empty treat as Number.MAX_VALUE. Exclusive */\n end?: bigint | undefined;\n}\n\nexport enum ProvidedSource {\n EnvVar = \"ENV_VAR\",\n}\nexport interface Provided {\n source?: ProvidedSource | undefined;\n /** eg MY_ENV_VAR */\n lookup?: string | undefined;\n}\n\nexport enum SchemaType {\n UNKNOWN = 0,\n ZOD = 1,\n JSON_SCHEMA = 2,\n}\n\nexport interface Schema {\n schema: string;\n schemaType: SchemaType;\n}\n\nexport interface WeightedValue {\n /** out of 1000 */\n weight: number;\n // eslint-disable-next-line no-use-before-define\n value: ConfigValue | undefined;\n}\n\nexport enum LimitResponse_LimitPolicyNames {\n SecondlyRolling = 1,\n MinutelyRolling = 3,\n HourlyRolling = 5,\n DailyRolling = 7,\n MonthlyRolling = 8,\n Infinite = 9,\n YearlyRolling = 10,\n}\n\nexport enum LimitDefinition_SafetyLevel {\n L4_BEST_EFFORT = 4,\n L5_BOMBPROOF = 5,\n}\n\nexport interface LimitDefinition {\n policyName: LimitResponse_LimitPolicyNames;\n limit: number;\n burst: number;\n accountId: number;\n lastModified: number;\n returnable: boolean;\n /** [default = L4_BEST_EFFORT]; // Overridable by request */\n safetyLevel: LimitDefinition_SafetyLevel;\n}\nexport interface WeightedValues {\n weightedValues: WeightedValue[];\n hashByPropertyName?: string | undefined;\n}\n\nexport type ConfigValue =\n | {\n int: number | undefined;\n }\n | {\n string: string | undefined;\n }\n | {\n bytes: Buffer | undefined;\n }\n | {\n double: number | undefined;\n }\n | {\n bool: boolean | undefined;\n }\n | {\n weightedValues?: WeightedValues | undefined;\n }\n | {\n limitDefinition?: LimitDefinition | undefined;\n }\n | {\n logLevel: ReforgeLogLevel | undefined;\n }\n | {\n stringList: string[] | undefined;\n }\n | {\n intRange: IntRange | undefined;\n }\n | {\n provided: Provided | undefined;\n }\n | {\n duration: Duration | undefined;\n }\n | {\n json: string | undefined;\n }\n | {\n schema: Schema | undefined;\n }\n | {\n /** don't log or telemetry this value */\n confidential: boolean | undefined;\n }\n | {\n /** key name to decrypt with */\n decryptWith: string | undefined;\n };\n\ntype Evaluation = {\n value: ConfigValue;\n configEvaluationMetadata: {\n configRowIndex: string | number;\n conditionalValueIndex: string | number;\n weightedValueIndex?: string | number;\n type: string;\n valueType: string;\n id: string;\n };\n};\n\nexport type EvaluationPayload = {\n evaluations: { [key: string]: Evaluation };\n apikeyMetadata: APIKeyMetadata;\n};\n\nconst parseRawMetadata = (metadata: any) => ({\n configRowIndex: parseInt(metadata.configRowIndex, 10),\n conditionalValueIndex: parseInt(metadata.conditionalValueIndex, 10),\n type: metadata.type,\n configId: metadata.id,\n});\n\nconst valueFor = <K extends keyof TypedFrontEndConfigurationRaw>(\n value: ConfigValue,\n type: keyof ConfigValue,\n key: K\n): TypedFrontEndConfigurationRaw[K] => {\n const rawValue = value[type];\n\n switch (type) {\n case \"json\":\n try {\n return JSON.parse(rawValue as string);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error(`Error parsing JSON from Reforge config ${key}`, e, rawValue);\n return value[type];\n }\n case \"duration\": {\n const duration = rawValue as Duration;\n return {\n ms: duration.millis,\n seconds: duration.millis / 1000,\n };\n }\n default:\n return rawValue;\n }\n};\n\nexport const parseEvaluationPayload = (payload: EvaluationPayload) => {\n // eslint-disable-next-line no-use-before-define\n const configs = {} as { [key: string]: Config };\n Object.keys(payload.evaluations).forEach((key) => {\n const evaluation = payload.evaluations[key];\n\n const type = Object.keys(evaluation.value)[0] as keyof ConfigValue;\n\n // eslint-disable-next-line no-use-before-define\n configs[key] = new Config(\n key,\n valueFor(evaluation.value, type, key),\n type,\n evaluation.value,\n evaluation.configEvaluationMetadata\n ? parseRawMetadata(evaluation.configEvaluationMetadata)\n : undefined\n );\n });\n\n return configs;\n};\n\nconst parseRawConfigWithoutTypes = (payload: RawConfigWithoutTypes) => {\n // eslint-disable-next-line no-use-before-define\n const configs = {} as { [key: string]: Config };\n Object.keys(payload).forEach((key) => {\n const type = typeof payload[key] as keyof ConfigValue;\n // eslint-disable-next-line no-use-before-define\n configs[key] = new Config(key, valueFor({ [type]: payload[key] }, type, key), type);\n });\n\n return configs;\n};\n\nexport class Config<\n K extends keyof TypedFrontEndConfigurationRaw = keyof TypedFrontEndConfigurationRaw,\n> {\n key: K;\n\n value: TypedFrontEndConfigurationRaw[K];\n\n rawValue: ConfigValue | undefined;\n\n type: keyof ConfigValue;\n\n configEvaluationMetadata: ConfigEvaluationMetadata | undefined;\n\n constructor(\n key: K,\n value: TypedFrontEndConfigurationRaw[K],\n type: keyof ConfigValue,\n rawValue?: ConfigValue,\n metadata?: ConfigEvaluationMetadata\n ) {\n this.key = key;\n this.value = value;\n this.type = type;\n this.rawValue = rawValue;\n this.configEvaluationMetadata = metadata;\n }\n\n static digest(payload: EvaluationPayload | RawConfigWithoutTypes) {\n if (payload === undefined) {\n // eslint-disable-next-line no-console\n console.trace(\"Config.digest called with undefined payload\");\n }\n\n if (\"evaluations\" in payload) {\n return parseEvaluationPayload(payload as EvaluationPayload);\n }\n\n return parseRawConfigWithoutTypes(payload as RawConfigWithoutTypes);\n }\n}\n","const base64Encode = (obj: string) => {\n if (typeof window !== \"undefined\") {\n if (typeof TextEncoder === \"undefined\") {\n return window.btoa(obj);\n }\n\n const bytes = new TextEncoder().encode(obj);\n const binString = Array.from(bytes, (byte) => String.fromCodePoint(byte)).join(\"\");\n return btoa(binString);\n }\n\n return Buffer.from(obj).toString(\"base64\");\n};\n\nexport default base64Encode;\n","import { Contexts, ContextValue } from \"./types\";\nimport base64Encode from \"./base64Encode\";\n\nconst isEqual = (a: Contexts, b: Contexts) => {\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n\n if (aKeys.length !== bKeys.length) {\n return false;\n }\n\n return aKeys.every((key) => {\n const aValues = a[key];\n const bValues = b[key];\n\n const aValuesKeys = Object.keys(aValues);\n const bValuesKeys = Object.keys(bValues);\n\n if (aValuesKeys.length !== bValuesKeys.length) {\n return false;\n }\n\n return aValuesKeys.every((ckey) => {\n const aValue = aValues[ckey];\n const bValue = bValues[ckey];\n\n return aValue === bValue;\n });\n });\n};\n\nconst getType = (value: ContextValue) => {\n if (typeof value === \"string\") {\n return \"string\";\n }\n\n if (typeof value === \"number\") {\n if (Number.isInteger(value)) {\n return \"int\";\n }\n\n return \"double\";\n }\n\n return \"bool\";\n};\n\nexport default class Context {\n contexts: Contexts;\n\n constructor(contexts: Contexts) {\n if (!Object.values(contexts).every((item: any) => typeof item === \"object\")) {\n // eslint-disable-next-line no-console\n console.error(\"Context must be an object where the value of each key is also an object\");\n }\n\n if (\n Object.values(contexts).some((item: any) =>\n Object.values(item).some((value: any) => typeof value === \"object\" && value !== null)\n )\n ) {\n // we decided to allow null values, which requres an extra check since typeof null is object\n // eslint-disable-next-line no-console\n console.error(\"Nested objects are not supported in context values at this time\");\n }\n\n this.contexts = contexts;\n }\n\n equals(other: Context) {\n return isEqual(this.contexts, other.contexts);\n }\n\n encode() {\n const formatted = Object.keys(this.contexts).map((key) => {\n const values: Record<string, Record<string, ContextValue>> = {};\n\n Object.keys(this.contexts[key]).forEach((ckey) => {\n values[ckey] = {\n [getType(this.contexts[key][ckey])]: this.contexts[key][ckey],\n };\n });\n\n return {\n type: key,\n values,\n };\n });\n\n return encodeURIComponent(base64Encode(JSON.stringify({ contexts: formatted })));\n }\n}\n","export class ExponentialBackoff {\n private maxDelay: number;\n\n private multiplier: number;\n\n private delay: number;\n\n // arguments are in seconds\n constructor(maxDelay: number, initialDelay = 2, multiplier = 2) {\n this.maxDelay = maxDelay;\n this.multiplier = multiplier;\n this.delay = initialDelay;\n }\n\n call(): number {\n const delayValue = this.delay;\n this.delay = Math.min(this.delay * this.multiplier, this.maxDelay);\n return delayValue * 1000;\n }\n}\n","import { TypedFrontEndConfigurationRaw } from \"./types\";\n\nexport const PREFIX = \"log-level\";\nexport enum ReforgeLogLevel {\n Trace = 1,\n Debug = 2,\n Info = 3,\n Warn = 4,\n Error = 5,\n Fatal = 6,\n}\n\nexport type LogLevelWord = Uppercase<keyof typeof ReforgeLogLevel>;\n\nconst WORD_LEVEL_LOOKUP: Readonly<Record<LogLevelWord, ReforgeLogLevel>> = {\n TRACE: ReforgeLogLevel.Trace,\n DEBUG: ReforgeLogLevel.Debug,\n INFO: ReforgeLogLevel.Info,\n WARN: ReforgeLogLevel.Warn,\n ERROR: ReforgeLogLevel.Error,\n FATAL: ReforgeLogLevel.Fatal,\n};\n\nexport const isValidLogLevel = (possibleLogLevel: string) =>\n Object.keys(WORD_LEVEL_LOOKUP).includes(possibleLogLevel.toUpperCase());\n\nexport interface ShouldLogParams {\n loggerName: string;\n desiredLevel: ReforgeLogLevel;\n defaultLevel: ReforgeLogLevel;\n get: <K extends keyof TypedFrontEndConfigurationRaw>(key: K) => TypedFrontEndConfigurationRaw[K];\n}\n\n// LogLevel enum for public API\nexport enum LogLevel {\n TRACE = \"TRACE\",\n DEBUG = \"DEBUG\",\n INFO = \"INFO\",\n WARN = \"WARN\",\n ERROR = \"ERROR\",\n FATAL = \"FATAL\",\n}\n\n// Get the numeric severity value for a LogLevel (lower = more verbose)\nexport const getLogLevelSeverity = (level: LogLevel): number => WORD_LEVEL_LOOKUP[level];\n\n// Check if a log at desiredLevel should be logged given the configured level\n// Returns true if desiredLevel is at or above the configured level's severity\nexport const shouldLogAtLevel = (configuredLevel: LogLevel, desiredLevel: LogLevel): boolean =>\n WORD_LEVEL_LOOKUP[configuredLevel] <= WORD_LEVEL_LOOKUP[desiredLevel];\n\nexport const shouldLog = ({\n loggerName,\n desiredLevel,\n defaultLevel,\n get,\n}: ShouldLogParams): boolean => {\n const loggerNameWithPrefix = `${PREFIX}.${loggerName}`;\n\n const resolvedLevel = get(loggerNameWithPrefix);\n\n if (resolvedLevel) {\n return (\n WORD_LEVEL_LOOKUP[resolvedLevel.toString().toUpperCase() as LogLevelWord] <= desiredLevel\n );\n }\n\n return defaultLevel <= desiredLevel;\n};\n","import { ExponentialBackoff } from \"./exponentialBackoff\";\nimport { ReforgeLogLevel } from \"./logger\";\nimport { type reforge } from \"./reforge\";\n\nabstract class PeriodicSync<T> {\n protected data: Map<string, T> = new Map();\n\n private startAt: Date;\n\n private syncInterval: any;\n\n protected client: typeof reforge;\n\n private name: string;\n\n private timeoutID: ReturnType<typeof setTimeout> | undefined;\n\n constructor(client: typeof reforge, name: string, syncInterval?: number) {\n this.client = client;\n this.name = name;\n\n this.startAt = new Date();\n\n this.startPeriodicSync(syncInterval);\n }\n\n stop(): void {\n clearTimeout(this.timeoutID);\n }\n\n sync(): void {\n if (this.data.size === 0) return;\n\n this.logInternal(`${this.name} syncing ${this.data.size} items`);\n\n const startAtWas = this.startAt;\n this.startAt = new Date();\n\n this.flush(this.prepareData(), startAtWas);\n }\n\n protected abstract flush(toShip: Map<string, T>, startAtWas: Date): void;\n\n private prepareData(): Map<string, T> {\n const toShip = new Map(this.data);\n this.data.clear();\n\n return toShip;\n }\n\n private startPeriodicSync(syncInterval?: number): void {\n this.startAt = new Date();\n this.syncInterval = PeriodicSync.calculateSyncInterval(syncInterval);\n\n this.scheduleNextSync();\n }\n\n private scheduleNextSync() {\n const interval = this.syncInterval();\n this.timeoutID = setTimeout(() => {\n this.sync();\n this.scheduleNextSync(); // Schedule the next sync after the current one completes\n }, interval);\n }\n\n private static calculateSyncInterval(syncInterval?: number): any {\n if (syncInterval !== undefined) {\n return () => syncInterval;\n }\n\n const backoff = new ExponentialBackoff(60 * 5, 8);\n return () => backoff.call();\n }\n\n protected logInternal(message: string): void {\n const loggerName = `${this.client.clientNameString}.reforge.${this.name}`;\n\n if (\n this.client.shouldLog(\n {\n loggerName,\n desiredLevel: ReforgeLogLevel.Debug,\n defaultLevel: ReforgeLogLevel.Error,\n },\n false // synchronous so that this log ends up in the current batch\n )\n ) {\n // eslint-disable-next-line no-console\n console.log(`${loggerName}: ${message}`);\n }\n }\n}\n\nexport { PeriodicSync };\n","// TODO: should we retry the data chunk if a flush fails?\n\n// TODO: pause when offline?\n\n// TODO: flush when we receive a config update (or as a result of a context update...but that should trigger a config update anyway)\n\nimport { PeriodicSync } from \"./periodicSync\";\nimport { Config } from \"./config\";\nimport { type reforge } from \"./reforge\";\nimport {\n ConfigEvaluationCounter,\n ConfigEvaluationSummaries,\n ConfigEvaluationSummary,\n TelemetryEvents,\n ConfigEvaluationMetadata,\n} from \"./types\";\n\nexport const massageSelectedValue = (config: Config): any => {\n if (config.rawValue && (config.type === \"duration\" || config.type === \"json\")) {\n if (config.type === \"json\") {\n return { json: config.rawValue[config.type] };\n }\n\n return config.rawValue[config.type];\n }\n\n return config.type === \"stringList\" ? { values: config.value } : config.value;\n};\n\nexport const massageConfigForTelemetry = (\n config: Config,\n metadata: Omit<ConfigEvaluationMetadata, \"type\">\n) => ({\n ...metadata,\n selectedValue: {\n [config.type]: massageSelectedValue(config),\n },\n count: 0,\n});\n\nclass EvaluationSummaryAggregator extends PeriodicSync<ConfigEvaluationCounter> {\n private maxKeys: number;\n\n constructor(client: typeof reforge, maxKeys: number, syncInterval?: number) {\n super(client, \"EvaluationSummaryAggregator\", syncInterval ?? 30000);\n\n this.maxKeys = maxKeys;\n }\n\n record(config: Config): void {\n if (this.data.size >= this.maxKeys) return;\n\n if (config?.configEvaluationMetadata) {\n const { type, ...metadata } = config.configEvaluationMetadata;\n const key = `${config.key},${type}`;\n\n // create counter entry if it doesn't exist\n if (!this.data.has(key)) {\n this.data.set(key, massageConfigForTelemetry(config, metadata));\n }\n\n // increment count\n const counter = this.data.get(key);\n if (counter) {\n counter.count += 1;\n }\n }\n }\n\n protected flush(toShip: Map<string, ConfigEvaluationCounter>, startAtWas: Date): void {\n const summaries = {\n start: startAtWas.getTime(),\n end: new Date().getTime(),\n summaries: EvaluationSummaryAggregator.summaries(toShip),\n };\n\n this.client.telemetryUploader?.post(this.events(summaries));\n }\n\n private static summaries(data: Map<string, ConfigEvaluationCounter>): ConfigEvaluationSummary[] {\n return Array.from(data).map((entry: [string, ConfigEvaluationCounter]) => {\n const [configKey, configType] = entry[0].split(\",\");\n const counter = entry[1];\n const counters = [counter]; // this client only ever has one set of counter info per key\n\n return {\n key: configKey,\n type: configType,\n counters,\n };\n });\n }\n\n private events(summaries: ConfigEvaluationSummaries): TelemetryEvents {\n const event = { summaries };\n\n return {\n instanceHash: this.client.instanceHash,\n events: [event],\n };\n }\n}\n\nexport { EvaluationSummaryAggregator };\n","import base64Encode from \"./base64Encode\";\n\nexport const headers = (sdkKey: string, clientVersion: string) => ({\n Authorization: `Basic ${base64Encode(`u:${sdkKey}`)}`,\n \"X-Reforge-SDK-Version\": clientVersion,\n});\n\nexport const DEFAULT_TIMEOUT = 10000;\n","import { DEFAULT_TIMEOUT, headers } from \"./apiHelpers\";\nimport { EvaluationPayload } from \"./config\";\nimport Context from \"./context\";\n\nexport type CollectContextModeType = \"NONE\" | \"SHAPE_ONLY\" | \"PERIODIC_EXAMPLE\";\n\nexport type LoaderParams = {\n sdkKey: string;\n context: Context;\n endpoints?: string[] | undefined;\n timeout?: number;\n collectContextMode?: CollectContextModeType;\n clientVersion?: string;\n};\n\nexport type Headers = {\n [key: string]: string;\n};\n\nexport type FetchOptions = {\n headers: Headers;\n};\n\nconst defaultEndpoints = [\n \"https://primary.reforge.com/api/v2\",\n \"https://secondary.reforge.com/api/v2\",\n];\n\nconst EARLY_TIMEOUT = 2000;\n\nexport default class Loader {\n sdkKey: string;\n\n context: Context;\n\n endpoints: string[];\n\n timeout: number;\n\n abortTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n collectContextMode: CollectContextModeType = \"PERIODIC_EXAMPLE\";\n\n clientVersion: string;\n\n abortController: AbortController | undefined;\n\n isAborted = false;\n\n constructor({\n sdkKey,\n context,\n endpoints = undefined,\n timeout,\n collectContextMode = \"PERIODIC_EXAMPLE\",\n clientVersion = \"\",\n }: LoaderParams) {\n this.sdkKey = sdkKey;\n this.context = context;\n this.endpoints = endpoints || defaultEndpoints;\n this.timeout = timeout || DEFAULT_TIMEOUT;\n this.collectContextMode = collectContextMode;\n this.clientVersion = clientVersion;\n }\n\n url(root: string) {\n return `${root}/configs/eval-with-context/${this.context.encode()}?collectContextMode=${\n this.collectContextMode\n }`;\n }\n\n loadFromEndpoint(\n index: number,\n options: FetchOptions,\n resolve: (value: any) => void,\n reject: (value: any) => void\n ) {\n this.abortController = new AbortController() as AbortController;\n const { signal } = this.abortController;\n this.isAborted = false;\n\n const endpoint = this.endpoints[index];\n const url = this.url(endpoint);\n\n fetch(url, { signal, ...options })\n .then((response) => {\n this.clearAbortTimeout();\n\n if (response.ok) {\n return response.json();\n }\n throw new Error(`${response.status} ${response.statusText}`);\n })\n .then((data) => {\n if (!(\"evaluations\" in data)) {\n throw new Error(`Invalid payload:${JSON.stringify(data)}`);\n }\n\n resolve(data as EvaluationPayload);\n })\n .catch((error) => {\n this.clearAbortTimeout();\n\n if (index < this.endpoints.length - 1) {\n this.loadFromEndpoint(index + 1, options, resolve, reject);\n } else {\n reject(error);\n }\n });\n\n // Use an early timeout if we're not on the last endpoint. But if the user-provided timeout is less than EARLY_TIMEOUT, use that\n const timeout =\n index < this.endpoints.length - 1 ? Math.min(this.timeout, EARLY_TIMEOUT) : this.timeout;\n\n this.abortTimeoutId = setTimeout(() => {\n if (!this.isAborted) {\n this.isAborted = true;\n this.abortController?.abort();\n }\n }, timeout);\n }\n\n load() {\n if (!this.isAborted) {\n this.isAborted = true;\n this.abortController?.abort();\n }\n\n const options = {\n headers: headers(this.sdkKey, this.clientVersion),\n };\n\n const promise = new Promise((resolve, reject) => {\n this.loadFromEndpoint(0, options, resolve, reject);\n });\n\n return promise;\n }\n\n clearAbortTimeout() {\n clearTimeout(this.abortTimeoutId);\n }\n}\n","import { DEFAULT_TIMEOUT, headers } from \"./apiHelpers\";\nimport { TelemetryEvents } from \"./types\";\n\nexport type TelemetryUploaderParams = {\n sdkKey: string;\n apiEndpoint?: string;\n timeout?: number;\n clientVersion: string;\n};\n\nexport default class TelemetryUploader {\n sdkKey: Required<TelemetryUploaderParams>[\"sdkKey\"];\n\n apiEndpoint: Required<TelemetryUploaderParams>[\"apiEndpoint\"];\n\n timeout: Required<TelemetryUploaderParams>[\"timeout\"];\n\n clientVersion: Required<TelemetryUploaderParams>[\"clientVersion\"];\n\n abortTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n constructor({\n sdkKey,\n apiEndpoint = undefined,\n timeout,\n clientVersion,\n }: TelemetryUploaderParams) {\n this.sdkKey = sdkKey;\n this.apiEndpoint = apiEndpoint || \"https://telemetry.reforge.com/api/v1\";\n this.timeout = timeout || DEFAULT_TIMEOUT;\n this.clientVersion = clientVersion;\n }\n\n clearAbortTimeout() {\n clearTimeout(this.abortTimeoutId);\n }\n\n static postUrl(root: string) {\n return `${root}/telemetry`;\n }\n\n postToEndpoint(\n options: RequestInit,\n resolve: (value: unknown) => void,\n reject: (value: unknown) => void\n ) {\n const controller = new AbortController() as AbortController;\n const signal = controller?.signal;\n let isAborted = false;\n\n const url = TelemetryUploader.postUrl(this.apiEndpoint);\n\n fetch(url, { signal, ...options })\n .then((response) => {\n this.clearAbortTimeout();\n\n if (response.ok) {\n return response.json();\n }\n\n // eslint-disable-next-line no-console\n console.warn(\n `Reforge warning: Error uploading telemetry ${response.status} ${response.statusText}`\n );\n\n return response.status;\n })\n .then((response) => {\n resolve(response);\n })\n .catch((error) => {\n this.clearAbortTimeout();\n\n // Silently handle AbortErrors (from timeouts or page navigations)\n if (error.name === \"AbortError\") {\n try {\n // eslint-disable-next-line no-console\n console.debug(\"Reforge telemetry request aborted\");\n } catch (e) {\n // no-op\n }\n resolve({ status: \"aborted\" });\n return;\n }\n\n reject(error);\n });\n\n this.abortTimeoutId = setTimeout(() => {\n if (!isAborted) {\n isAborted = true;\n controller.abort();\n }\n }, this.timeout);\n }\n\n post(data: TelemetryEvents) {\n const options = {\n method: \"POST\",\n headers: {\n ...headers(this.sdkKey, this.clientVersion),\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n body: JSON.stringify(data),\n keepalive: true, // needed for flushing when the window is closed\n };\n\n const promise = new Promise((resolve, reject) => {\n this.postToEndpoint(options, resolve, reject);\n });\n\n return promise;\n }\n}\n","// TODO: should we retry the data chunk if a flush fails?\n\n// TODO: pause when offline?\n\nimport { ReforgeLogLevel } from \"./logger\";\nimport { PeriodicSync } from \"./periodicSync\";\nimport { type reforge } from \"./reforge\";\nimport { LoggerCounter, LoggersTelemetryEvent, TelemetryEvents } from \"./types\";\n\nconst SEVERITY_KEY: { [key in ReforgeLogLevel]: Omit<keyof LoggerCounter, \"loggerName\"> } = {\n [ReforgeLogLevel.Trace]: \"traces\",\n [ReforgeLogLevel.Debug]: \"debugs\",\n [ReforgeLogLevel.Info]: \"infos\",\n [ReforgeLogLevel.Warn]: \"warns\",\n [ReforgeLogLevel.Error]: \"errors\",\n [ReforgeLogLevel.Fatal]: \"fatals\",\n};\n\nclass LoggerAggregator extends PeriodicSync<LoggerCounter> {\n private maxLoggers: number;\n\n constructor(client: typeof reforge, maxLoggers: number, syncInterval?: number) {\n super(client, \"LoggerAggregator\", syncInterval ?? 30000);\n\n this.maxLoggers = maxLoggers;\n }\n\n record(logger: string, level: ReforgeLogLevel): void {\n if (this.data.size >= this.maxLoggers) return;\n\n // create counter entry if it doesn't exist\n if (!this.data.has(logger)) {\n this.data.set(logger, {\n loggerName: logger,\n traces: 0,\n debugs: 0,\n infos: 0,\n warns: 0,\n errors: 0,\n fatals: 0,\n });\n }\n\n // increment count\n const counter = this.data.get(logger);\n if (counter) {\n const severityKey = SEVERITY_KEY[level] as keyof LoggerCounter;\n (counter[severityKey] as number) += 1;\n }\n }\n\n protected flush(toShip: Map<string, LoggerCounter>, startAtWas: Date): void {\n const loggers = {\n startAt: startAtWas.getTime(),\n endAt: new Date().getTime(),\n loggers: Array.from(toShip.values()),\n };\n\n this.client.telemetryUploader?.post(this.events(loggers));\n }\n\n private events(loggers: LoggersTelemetryEvent): TelemetryEvents {\n const event = { loggers };\n\n return {\n instanceHash: this.client.instanceHash,\n events: [event],\n };\n }\n}\n\nexport { LoggerAggregator };\n","import { reforge, Reforge, ReforgeInitParams, ReforgeBootstrap } from \"./src/reforge\";\nimport { Config } from \"./src/config\";\nimport Context from \"./src/context\";\nimport { LogLevel, getLogLevelSeverity, shouldLogAtLevel } from \"./src/logger\";\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version } = require(\"./package.json\");\n\nexport {\n reforge,\n Reforge,\n ReforgeInitParams,\n Config,\n Context,\n LogLevel,\n getLogLevelSeverity,\n shouldLogAtLevel,\n version,\n};\n\nexport { ReforgeBootstrap };\n\nexport type { ConfigValue } from \"./src/config\";\nexport type {\n Duration,\n ContextValue,\n Contexts,\n TypedFrontEndConfigurationRaw,\n FrontEndConfigurationRaw,\n} from \"./src/types\";\nexport type { CollectContextModeType } from \"./src/loader\";\n"],"mappings":"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","names":["LogLevel","reforge","version"]}
{"version":3,"sources":["../package.json","../src/reforge.ts","../src/config.ts","../src/base64Encode.ts","../src/context.ts","../src/exponentialBackoff.ts","../src/logger.ts","../src/periodicSync.ts","../src/evaluationSummaryAggregator.ts","../src/apiHelpers.ts","../src/loader.ts","../src/telemetryUploader.ts","../src/loggerAggregator.ts","../index.ts"],"sourcesContent":["{\n \"packageManager\": \"yarn@4.11.0\",\n \"name\": \"@reforge-com/javascript\",\n \"version\": \"0.0.5\",\n \"description\": \"Feature Flags & Dynamic Configuration as a Service\",\n \"main\": \"dist/index.cjs\",\n \"module\": \"dist/index.mjs\",\n \"types\": \"dist/index.d.ts\",\n \"author\": \"Jeffrey Chupp\",\n \"license\": \"ISC\",\n \"devDependencies\": {\n \"@types/eslint-plugin-jsx-a11y\": \"^6\",\n \"@types/express\": \"^4.17.13\",\n \"@types/jest\": \"^28.1.6\",\n \"@types/uuid\": \"^9.0.5\",\n \"@typescript-eslint/eslint-plugin\": \"^5.33.0\",\n \"@typescript-eslint/parser\": \"^5.33.0\",\n \"esbuild\": \"^0.25.11\",\n \"eslint\": \"^8.21.0\",\n \"eslint-config-airbnb\": \"^19.0.4\",\n \"eslint-config-airbnb-typescript\": \"^17.0.0\",\n \"eslint-config-prettier\": \"^8.8.0\",\n \"eslint-plugin-import\": \"^2.26.0\",\n \"eslint-plugin-jest\": \"^26.8.0\",\n \"eslint-plugin-jsx-a11y\": \"^6.10.2\",\n \"eslint-plugin-react\": \"^7.37.5\",\n \"jest\": \"^29.0.0\",\n \"jest-environment-jsdom\": \"^30.2.0\",\n \"jest-fetch-mock\": \"^3.0.3\",\n \"prettier\": \"^3.0.0\",\n \"ts-jest\": \"^29.1.1\",\n \"ts-node\": \"^10.9.1\",\n \"tsup\": \"^8.0.2\",\n \"typescript\": \"^5.1.6\"\n },\n \"scripts\": {\n \"build\": \"rm -rf dist/ && tsup\",\n \"dev\": \"tsup --watch\",\n \"bundle\": \"esbuild --minify --target=esnext --bundle --outfile=dist/reforge.bundle.js --global-name=window.reforgeNamespace dist/index.cjs && echo 'window.reforge = window.reforgeNamespace.reforge' >> dist/reforge.bundle.js\",\n \"lint\": \"eslint --ext .ts,.tsx src/\",\n \"lint:fix\": \"eslint --fix --ext .ts,.tsx src/\",\n \"prettier\": \"prettier . -l\",\n \"prettier:fix\": \"prettier --write .\",\n \"test\": \"jest --verbose\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/ReforgeHQ/sdk-javascript.git\"\n },\n \"keywords\": [\n \"feature-flags\",\n \"config\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/ReforgeHQ/sdk-javascript/issues\"\n },\n \"homepage\": \"https://github.com/ReforgeHQ/sdk-javascript#readme\",\n \"dependencies\": {\n \"uuid\": \"^9.0.1\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.mjs\",\n \"require\": \"./dist/index.cjs\"\n }\n }\n}\n","/* eslint-disable max-classes-per-file */\nimport { v4 as uuid } from \"uuid\";\n\nimport { Config, EvaluationPayload, RawConfigWithoutTypes } from \"./config\";\nimport type {\n Duration,\n TypedFrontEndConfigurationRaw,\n FrontEndConfigurationRaw,\n Contexts,\n} from \"./types\";\nimport Context from \"./context\";\nimport { EvaluationSummaryAggregator } from \"./evaluationSummaryAggregator\";\nimport Loader, { CollectContextModeType } from \"./loader\";\nimport {\n PREFIX as loggerPrefix,\n shouldLog,\n ShouldLogParams,\n LogLevel,\n shouldLogAtLevel,\n} from \"./logger\";\nimport TelemetryUploader from \"./telemetryUploader\";\nimport { LoggerAggregator } from \"./loggerAggregator\";\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version } = require(\"../package.json\");\n\ntype EvaluationCallback = <K extends keyof TypedFrontEndConfigurationRaw>(\n key: K,\n value: TypedFrontEndConfigurationRaw[K],\n context: Context | undefined\n) => void;\n\nexport interface ReforgeBootstrap {\n evaluations: EvaluationPayload;\n context: Contexts;\n}\n\nexport type ReforgeInitParams = {\n sdkKey: string;\n context: Context;\n endpoints?: string[] | undefined;\n apiEndpoint?: string;\n timeout?: number;\n afterEvaluationCallback?: EvaluationCallback;\n collectEvaluationSummaries?: boolean;\n collectLoggerNames?: boolean;\n collectContextMode?: CollectContextModeType;\n clientNameString?: string;\n clientVersionString?: string;\n loggerKey?: string;\n};\n\ntype PollStatus =\n | { status: \"not-started\" }\n | { status: \"pending\" }\n | { status: \"stopped\" }\n | { status: \"running\"; frequencyInMs: number };\n\ntype PublicShouldLogParams = Omit<ShouldLogParams, \"get\">;\n\n// Forward declaration for ReforgeLogger\n// eslint-disable-next-line @typescript-eslint/no-use-before-define\nclass ReforgeLogger {\n // eslint-disable-next-line no-use-before-define\n private reforge: Reforge;\n\n // eslint-disable-next-line no-use-before-define\n constructor(reforge: Reforge) {\n this.reforge = reforge;\n }\n\n private log(message: string, level: LogLevel): void {\n const configuredLevel = this.reforge.getLogLevel(\"\");\n\n if (shouldLogAtLevel(configuredLevel, level)) {\n switch (level) {\n case LogLevel.TRACE:\n case LogLevel.DEBUG:\n // eslint-disable-next-line no-console\n console.debug(message);\n break;\n case LogLevel.INFO:\n // eslint-disable-next-line no-console\n console.info(message);\n break;\n case LogLevel.WARN:\n // eslint-disable-next-line no-console\n console.warn(message);\n break;\n case LogLevel.ERROR:\n case LogLevel.FATAL:\n // eslint-disable-next-line no-console\n console.error(message);\n break;\n default:\n // eslint-disable-next-line no-console\n console.error(message);\n }\n }\n }\n\n trace(message: string): void {\n this.log(message, LogLevel.TRACE);\n }\n\n debug(message: string): void {\n this.log(message, LogLevel.DEBUG);\n }\n\n info(message: string): void {\n this.log(message, LogLevel.INFO);\n }\n\n warn(message: string): void {\n this.log(message, LogLevel.WARN);\n }\n\n error(message: string): void {\n this.log(message, LogLevel.ERROR);\n }\n\n fatal(message: string): void {\n this.log(message, LogLevel.FATAL);\n }\n}\n\nexport class Reforge {\n private _configs: { [key: string]: Config } = {};\n\n private _telemetryUploader: TelemetryUploader | undefined;\n\n private _pollCount = 0;\n\n private _pollStatus: PollStatus = { status: \"not-started\" };\n\n private _pollTimeoutId = undefined as ReturnType<typeof setTimeout> | undefined;\n\n private _instanceHash: string = uuid();\n\n private collectEvaluationSummaries = true;\n\n private collectLoggerNames = false;\n\n private evalutionSummaryAggregator: EvaluationSummaryAggregator | undefined;\n\n private loggerAggregator: LoggerAggregator | undefined;\n\n public clientNameString = \"sdk-javascript\";\n\n public loaded = false;\n\n public loader: Loader | undefined;\n\n public afterEvaluationCallback = (() => {}) as EvaluationCallback;\n\n private _context: Context = new Context({});\n\n private _loggerKey = \"log-levels.default\";\n\n public logger: ReforgeLogger;\n\n constructor() {\n this.logger = new ReforgeLogger(this);\n }\n\n async init({\n sdkKey,\n context: providedContext,\n endpoints = undefined,\n apiEndpoint,\n timeout = undefined,\n afterEvaluationCallback = () => {},\n collectEvaluationSummaries = true,\n collectLoggerNames = false,\n collectContextMode = \"PERIODIC_EXAMPLE\",\n clientNameString = \"sdk-javascript\",\n clientVersionString = version,\n loggerKey = \"log-levels.default\",\n }: ReforgeInitParams) {\n const context = providedContext ?? this.context;\n\n if (!context) {\n throw new Error(\"Context must be provided\");\n }\n\n this._context = context;\n this._loggerKey = loggerKey;\n\n this.clientNameString = clientNameString;\n const clientNameAndVersionString = `${clientNameString}-${clientVersionString}`;\n\n this.loader = new Loader({\n sdkKey,\n context,\n endpoints,\n timeout,\n collectContextMode,\n clientVersion: clientNameAndVersionString,\n });\n\n this._telemetryUploader = new TelemetryUploader({\n sdkKey,\n apiEndpoint,\n timeout,\n clientVersion: clientNameAndVersionString,\n });\n\n this.collectEvaluationSummaries = collectEvaluationSummaries;\n if (collectEvaluationSummaries) {\n this.evalutionSummaryAggregator = new EvaluationSummaryAggregator(this, 100000);\n }\n\n this.collectLoggerNames = collectLoggerNames;\n if (collectLoggerNames) {\n this.loggerAggregator = new LoggerAggregator(this, 100000);\n }\n\n if (\n (collectEvaluationSummaries || collectLoggerNames) &&\n typeof window !== \"undefined\" &&\n typeof window.addEventListener === \"function\"\n ) {\n window.addEventListener(\"beforeunload\", () => {\n this.evalutionSummaryAggregator?.sync();\n this.loggerAggregator?.sync();\n });\n }\n\n this.afterEvaluationCallback = afterEvaluationCallback;\n\n return this.load();\n }\n\n public extract(): Record<string, Config[\"value\"]> {\n return Object.entries(this._configs).reduce(\n (agg, [key, value]) => ({\n ...agg,\n [key]: value.value,\n }),\n {} as Record<string, Config[\"value\"]>\n );\n }\n\n public hydrate(rawValues: RawConfigWithoutTypes | EvaluationPayload): void {\n this.setConfigPrivate(rawValues);\n }\n\n get context(): Context {\n return this._context;\n }\n\n get instanceHash(): string {\n return this._instanceHash;\n }\n\n get pollTimeoutId() {\n return this._pollTimeoutId;\n }\n\n get pollCount() {\n return this._pollCount;\n }\n\n get pollStatus() {\n return this._pollStatus;\n }\n\n get telemetryUploader(): TelemetryUploader | undefined {\n return this._telemetryUploader;\n }\n\n private async load() {\n if (!this.loader || !this.context) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n /* eslint-disable no-underscore-dangle */\n if (globalThis && (globalThis as any)._reforgeBootstrap) {\n /* eslint-disable no-underscore-dangle */\n const reforgeBootstrap = (globalThis as any)._reforgeBootstrap as ReforgeBootstrap;\n const bootstrapContext = new Context(reforgeBootstrap.context);\n\n if (this.context.equals(bootstrapContext)) {\n this.setConfigPrivate({ evaluations: reforgeBootstrap.evaluations });\n return Promise.resolve();\n }\n }\n\n // make sure we have the freshest context\n this.loader.context = this.context;\n\n return this.loader\n .load()\n .then((rawValues: any) => {\n this.setConfigPrivate(rawValues as EvaluationPayload);\n })\n .finally(() => {\n if (this.pollStatus.status === \"running\") {\n this._pollCount += 1;\n }\n });\n }\n\n async updateContext(context: Context, skipLoad = false) {\n if (!this.loader) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n this._context = context;\n\n if (skipLoad) {\n return Promise.resolve();\n }\n\n return this.load();\n }\n\n async poll({ frequencyInMs }: { frequencyInMs: number }) {\n if (!this.loader) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n this.stopPolling();\n\n this._pollStatus = { status: \"pending\" };\n\n return this.loader.load().finally(() => {\n this.doPolling({ frequencyInMs });\n });\n }\n\n private doPolling({ frequencyInMs }: { frequencyInMs: number }) {\n this._pollTimeoutId = setTimeout(() => {\n this.load().finally(() => {\n if (this.pollStatus.status === \"running\") {\n this.doPolling({ frequencyInMs });\n }\n });\n }, frequencyInMs);\n\n this._pollStatus = {\n status: \"running\",\n frequencyInMs,\n };\n }\n\n stopPolling() {\n if (this.pollTimeoutId) {\n clearTimeout(this.pollTimeoutId);\n this._pollTimeoutId = undefined;\n }\n\n this._pollStatus = { status: \"stopped\" };\n }\n\n stopTelemetry() {\n if (this.telemetryUploader) {\n this.evalutionSummaryAggregator?.stop();\n this.loggerAggregator?.stop();\n }\n }\n\n private setConfigPrivate(rawValues: RawConfigWithoutTypes | EvaluationPayload) {\n this._configs = Config.digest(rawValues);\n this.loaded = true;\n }\n\n isEnabled<\n // We need to calcuate these live and not store in a type to ensure dynamic evaluation\n // in upstream libraries that override the FrontEndConfigurationRaw interface\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends boolean\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(key: K): boolean {\n return this.get(key) === true;\n }\n\n get<K extends keyof TypedFrontEndConfigurationRaw>(key: K): TypedFrontEndConfigurationRaw[K] {\n if (!this.loaded) {\n if (!key.startsWith(loggerPrefix)) {\n // eslint-disable-next-line no-console\n console.warn(\n `Reforge warning: The client has not finished loading data yet. Unable to look up actual value for key \"${key}\".`\n );\n }\n\n return undefined;\n }\n\n const config = this._configs[key];\n\n const value = config?.value;\n\n if (!key.startsWith(loggerPrefix)) {\n if (this.collectEvaluationSummaries) {\n setTimeout(() => this.evalutionSummaryAggregator?.record(config));\n }\n\n setTimeout(() => this.afterEvaluationCallback(key, value, this.context));\n }\n\n return value;\n }\n\n getDuration<\n // We need to calcuate these live and not store in a type to ensure dynamic evaluation\n // in upstream libraries that override the FrontEndConfigurationRaw interface\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends Duration\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(key: K): Duration | undefined {\n const value = this.get(key);\n\n if (!value) {\n return undefined;\n }\n\n if (\n !Object.prototype.hasOwnProperty.call(value, \"seconds\") ||\n !Object.prototype.hasOwnProperty.call(value, \"ms\")\n ) {\n throw new Error(`Value for key \"${key}\" is not a duration`);\n }\n\n return value as Duration;\n }\n\n shouldLog(args: PublicShouldLogParams, async = true): boolean {\n if (this.collectLoggerNames) {\n const record = () => this.loggerAggregator?.record(args.loggerName, args.desiredLevel);\n if (async) {\n setTimeout(record);\n } else {\n record();\n }\n }\n\n return shouldLog({ ...args, get: this.get.bind(this) });\n }\n\n getLogLevel(_loggerName: string): LogLevel {\n const value = this.get(this._loggerKey);\n\n if (value && typeof value === \"string\") {\n const upperValue = value.toUpperCase();\n if (upperValue in LogLevel) {\n return LogLevel[upperValue as keyof typeof LogLevel];\n }\n }\n\n // Default to DEBUG if no config found or invalid value\n return LogLevel.DEBUG;\n }\n\n isCollectingEvaluationSummaries(): boolean {\n return this.collectEvaluationSummaries;\n }\n\n isCollectingLoggerNames(): boolean {\n return this.collectLoggerNames;\n }\n}\n\nexport const reforge = new Reforge();\n\nexport function prefetchReforgeConfig({\n sdkKey,\n context,\n endpoints = undefined,\n timeout = undefined,\n collectContextMode = \"PERIODIC_EXAMPLE\",\n clientNameString = \"sdk-javascript\",\n clientVersionString = version,\n}: ReforgeInitParams) {\n const clientNameAndVersionString = `${clientNameString}-${clientVersionString}`;\n\n const loader = new Loader({\n sdkKey,\n context,\n endpoints,\n timeout,\n collectContextMode,\n clientVersion: clientNameAndVersionString,\n });\n\n (window as any).REFORGE_SDK_PREFETCH_PROMISE = loader.load();\n}\n\nexport default prefetchReforgeConfig;\n","import { ReforgeLogLevel } from \"./logger\";\nimport { TypedFrontEndConfigurationRaw, ConfigEvaluationMetadata } from \"./types\";\n\nexport type RawConfigWithoutTypes = Record<string, any>;\n\ntype APIKeyMetadata = {\n id: string | number;\n};\n\n// TODO: Why is this definition different from the one in ./types.ts?\ntype Duration = {\n definition: string;\n millis: number;\n};\n\nexport interface IntRange {\n /** if empty treat as Number.MIN_VALUE. Inclusive */\n start?: bigint | undefined;\n /** if empty treat as Number.MAX_VALUE. Exclusive */\n end?: bigint | undefined;\n}\n\nexport enum ProvidedSource {\n EnvVar = \"ENV_VAR\",\n}\nexport interface Provided {\n source?: ProvidedSource | undefined;\n /** eg MY_ENV_VAR */\n lookup?: string | undefined;\n}\n\nexport enum SchemaType {\n UNKNOWN = 0,\n ZOD = 1,\n JSON_SCHEMA = 2,\n}\n\nexport interface Schema {\n schema: string;\n schemaType: SchemaType;\n}\n\nexport interface WeightedValue {\n /** out of 1000 */\n weight: number;\n // eslint-disable-next-line no-use-before-define\n value: ConfigValue | undefined;\n}\n\nexport enum LimitResponse_LimitPolicyNames {\n SecondlyRolling = 1,\n MinutelyRolling = 3,\n HourlyRolling = 5,\n DailyRolling = 7,\n MonthlyRolling = 8,\n Infinite = 9,\n YearlyRolling = 10,\n}\n\nexport enum LimitDefinition_SafetyLevel {\n L4_BEST_EFFORT = 4,\n L5_BOMBPROOF = 5,\n}\n\nexport interface LimitDefinition {\n policyName: LimitResponse_LimitPolicyNames;\n limit: number;\n burst: number;\n accountId: number;\n lastModified: number;\n returnable: boolean;\n /** [default = L4_BEST_EFFORT]; // Overridable by request */\n safetyLevel: LimitDefinition_SafetyLevel;\n}\nexport interface WeightedValues {\n weightedValues: WeightedValue[];\n hashByPropertyName?: string | undefined;\n}\n\nexport type ConfigValue =\n | {\n int: number | undefined;\n }\n | {\n string: string | undefined;\n }\n | {\n bytes: Buffer | undefined;\n }\n | {\n double: number | undefined;\n }\n | {\n bool: boolean | undefined;\n }\n | {\n weightedValues?: WeightedValues | undefined;\n }\n | {\n limitDefinition?: LimitDefinition | undefined;\n }\n | {\n logLevel: ReforgeLogLevel | undefined;\n }\n | {\n stringList: string[] | undefined;\n }\n | {\n intRange: IntRange | undefined;\n }\n | {\n provided: Provided | undefined;\n }\n | {\n duration: Duration | undefined;\n }\n | {\n json: string | undefined;\n }\n | {\n schema: Schema | undefined;\n }\n | {\n /** don't log or telemetry this value */\n confidential: boolean | undefined;\n }\n | {\n /** key name to decrypt with */\n decryptWith: string | undefined;\n };\n\ntype Evaluation = {\n value: ConfigValue;\n configEvaluationMetadata: {\n configRowIndex: string | number;\n conditionalValueIndex: string | number;\n weightedValueIndex?: string | number;\n type: string;\n valueType: string;\n id: string;\n };\n};\n\nexport type EvaluationPayload = {\n evaluations: { [key: string]: Evaluation };\n apikeyMetadata: APIKeyMetadata;\n};\n\nconst parseRawMetadata = (metadata: any) => ({\n configRowIndex: parseInt(metadata.configRowIndex, 10),\n conditionalValueIndex: parseInt(metadata.conditionalValueIndex, 10),\n type: metadata.type,\n configId: metadata.id,\n});\n\nconst valueFor = <K extends keyof TypedFrontEndConfigurationRaw>(\n value: ConfigValue,\n type: keyof ConfigValue,\n key: K\n): TypedFrontEndConfigurationRaw[K] => {\n const rawValue = value[type];\n\n switch (type) {\n case \"json\":\n try {\n return JSON.parse(rawValue as string);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error(`Error parsing JSON from Reforge config ${key}`, e, rawValue);\n return value[type];\n }\n case \"duration\": {\n const duration = rawValue as Duration;\n return {\n ms: duration.millis,\n seconds: duration.millis / 1000,\n };\n }\n default:\n return rawValue;\n }\n};\n\nexport const parseEvaluationPayload = (payload: EvaluationPayload) => {\n // eslint-disable-next-line no-use-before-define\n const configs = {} as { [key: string]: Config };\n Object.keys(payload.evaluations).forEach((key) => {\n const evaluation = payload.evaluations[key];\n\n const type = Object.keys(evaluation.value)[0] as keyof ConfigValue;\n\n // eslint-disable-next-line no-use-before-define\n configs[key] = new Config(\n key,\n valueFor(evaluation.value, type, key),\n type,\n evaluation.value,\n evaluation.configEvaluationMetadata\n ? parseRawMetadata(evaluation.configEvaluationMetadata)\n : undefined\n );\n });\n\n return configs;\n};\n\nconst parseRawConfigWithoutTypes = (payload: RawConfigWithoutTypes) => {\n // eslint-disable-next-line no-use-before-define\n const configs = {} as { [key: string]: Config };\n Object.keys(payload).forEach((key) => {\n const type = typeof payload[key] as keyof ConfigValue;\n // eslint-disable-next-line no-use-before-define\n configs[key] = new Config(key, valueFor({ [type]: payload[key] }, type, key), type);\n });\n\n return configs;\n};\n\nexport class Config<\n K extends keyof TypedFrontEndConfigurationRaw = keyof TypedFrontEndConfigurationRaw,\n> {\n key: K;\n\n value: TypedFrontEndConfigurationRaw[K];\n\n rawValue: ConfigValue | undefined;\n\n type: keyof ConfigValue;\n\n configEvaluationMetadata: ConfigEvaluationMetadata | undefined;\n\n constructor(\n key: K,\n value: TypedFrontEndConfigurationRaw[K],\n type: keyof ConfigValue,\n rawValue?: ConfigValue,\n metadata?: ConfigEvaluationMetadata\n ) {\n this.key = key;\n this.value = value;\n this.type = type;\n this.rawValue = rawValue;\n this.configEvaluationMetadata = metadata;\n }\n\n static digest(payload: EvaluationPayload | RawConfigWithoutTypes) {\n if (payload === undefined) {\n // eslint-disable-next-line no-console\n console.trace(\"Config.digest called with undefined payload\");\n }\n\n if (\"evaluations\" in payload) {\n return parseEvaluationPayload(payload as EvaluationPayload);\n }\n\n return parseRawConfigWithoutTypes(payload as RawConfigWithoutTypes);\n }\n}\n","const base64Encode = (obj: string) => {\n if (typeof window !== \"undefined\") {\n if (typeof TextEncoder === \"undefined\") {\n return window.btoa(obj);\n }\n\n const bytes = new TextEncoder().encode(obj);\n const binString = Array.from(bytes, (byte) => String.fromCodePoint(byte)).join(\"\");\n return btoa(binString);\n }\n\n return Buffer.from(obj).toString(\"base64\");\n};\n\nexport default base64Encode;\n","import { Contexts, ContextValue } from \"./types\";\nimport base64Encode from \"./base64Encode\";\n\nconst isEqual = (a: Contexts, b: Contexts) => {\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n\n if (aKeys.length !== bKeys.length) {\n return false;\n }\n\n return aKeys.every((key) => {\n const aValues = a[key];\n const bValues = b[key];\n\n const aValuesKeys = Object.keys(aValues);\n const bValuesKeys = Object.keys(bValues);\n\n if (aValuesKeys.length !== bValuesKeys.length) {\n return false;\n }\n\n return aValuesKeys.every((ckey) => {\n const aValue = aValues[ckey];\n const bValue = bValues[ckey];\n\n return aValue === bValue;\n });\n });\n};\n\nconst getType = (value: ContextValue) => {\n if (typeof value === \"string\") {\n return \"string\";\n }\n\n if (typeof value === \"number\") {\n if (Number.isInteger(value)) {\n return \"int\";\n }\n\n return \"double\";\n }\n\n return \"bool\";\n};\n\nexport default class Context {\n contexts: Contexts;\n\n constructor(contexts: Contexts) {\n if (!Object.values(contexts).every((item: any) => typeof item === \"object\")) {\n // eslint-disable-next-line no-console\n console.error(\"Context must be an object where the value of each key is also an object\");\n }\n\n if (\n Object.values(contexts).some((item: any) =>\n Object.values(item).some((value: any) => typeof value === \"object\" && value !== null)\n )\n ) {\n // we decided to allow null values, which requres an extra check since typeof null is object\n // eslint-disable-next-line no-console\n console.error(\"Nested objects are not supported in context values at this time\");\n }\n\n this.contexts = contexts;\n }\n\n equals(other: Context) {\n return isEqual(this.contexts, other.contexts);\n }\n\n encode() {\n const formatted = Object.keys(this.contexts).map((key) => {\n const values: Record<string, Record<string, ContextValue>> = {};\n\n Object.keys(this.contexts[key]).forEach((ckey) => {\n values[ckey] = {\n [getType(this.contexts[key][ckey])]: this.contexts[key][ckey],\n };\n });\n\n return {\n type: key,\n values,\n };\n });\n\n return encodeURIComponent(base64Encode(JSON.stringify({ contexts: formatted })));\n }\n}\n","export class ExponentialBackoff {\n private maxDelay: number;\n\n private multiplier: number;\n\n private delay: number;\n\n // arguments are in seconds\n constructor(maxDelay: number, initialDelay = 2, multiplier = 2) {\n this.maxDelay = maxDelay;\n this.multiplier = multiplier;\n this.delay = initialDelay;\n }\n\n call(): number {\n const delayValue = this.delay;\n this.delay = Math.min(this.delay * this.multiplier, this.maxDelay);\n return delayValue * 1000;\n }\n}\n","import { TypedFrontEndConfigurationRaw } from \"./types\";\n\nexport const PREFIX = \"log-level\";\nexport enum ReforgeLogLevel {\n Trace = 1,\n Debug = 2,\n Info = 3,\n Warn = 4,\n Error = 5,\n Fatal = 6,\n}\n\nexport type LogLevelWord = Uppercase<keyof typeof ReforgeLogLevel>;\n\nconst WORD_LEVEL_LOOKUP: Readonly<Record<LogLevelWord, ReforgeLogLevel>> = {\n TRACE: ReforgeLogLevel.Trace,\n DEBUG: ReforgeLogLevel.Debug,\n INFO: ReforgeLogLevel.Info,\n WARN: ReforgeLogLevel.Warn,\n ERROR: ReforgeLogLevel.Error,\n FATAL: ReforgeLogLevel.Fatal,\n};\n\nexport const isValidLogLevel = (possibleLogLevel: string) =>\n Object.keys(WORD_LEVEL_LOOKUP).includes(possibleLogLevel.toUpperCase());\n\nexport interface ShouldLogParams {\n loggerName: string;\n desiredLevel: ReforgeLogLevel;\n defaultLevel: ReforgeLogLevel;\n get: <K extends keyof TypedFrontEndConfigurationRaw>(key: K) => TypedFrontEndConfigurationRaw[K];\n}\n\n// LogLevel enum for public API\nexport enum LogLevel {\n TRACE = \"TRACE\",\n DEBUG = \"DEBUG\",\n INFO = \"INFO\",\n WARN = \"WARN\",\n ERROR = \"ERROR\",\n FATAL = \"FATAL\",\n}\n\n// Get the numeric severity value for a LogLevel (lower = more verbose)\nexport const getLogLevelSeverity = (level: LogLevel): number => WORD_LEVEL_LOOKUP[level];\n\n// Check if a log at desiredLevel should be logged given the configured level\n// Returns true if desiredLevel is at or above the configured level's severity\nexport const shouldLogAtLevel = (configuredLevel: LogLevel, desiredLevel: LogLevel): boolean =>\n WORD_LEVEL_LOOKUP[configuredLevel] <= WORD_LEVEL_LOOKUP[desiredLevel];\n\nexport const shouldLog = ({\n loggerName,\n desiredLevel,\n defaultLevel,\n get,\n}: ShouldLogParams): boolean => {\n const loggerNameWithPrefix = `${PREFIX}.${loggerName}`;\n\n const resolvedLevel = get(loggerNameWithPrefix);\n\n if (resolvedLevel) {\n return (\n WORD_LEVEL_LOOKUP[resolvedLevel.toString().toUpperCase() as LogLevelWord] <= desiredLevel\n );\n }\n\n return defaultLevel <= desiredLevel;\n};\n","import { ExponentialBackoff } from \"./exponentialBackoff\";\nimport { ReforgeLogLevel } from \"./logger\";\nimport { type reforge } from \"./reforge\";\n\nabstract class PeriodicSync<T> {\n protected data: Map<string, T> = new Map();\n\n private startAt: Date;\n\n private syncInterval: any;\n\n protected client: typeof reforge;\n\n private name: string;\n\n private timeoutID: ReturnType<typeof setTimeout> | undefined;\n\n constructor(client: typeof reforge, name: string, syncInterval?: number) {\n this.client = client;\n this.name = name;\n\n this.startAt = new Date();\n\n this.startPeriodicSync(syncInterval);\n }\n\n stop(): void {\n clearTimeout(this.timeoutID);\n }\n\n sync(): void {\n if (this.data.size === 0) return;\n\n this.logInternal(`${this.name} syncing ${this.data.size} items`);\n\n const startAtWas = this.startAt;\n this.startAt = new Date();\n\n this.flush(this.prepareData(), startAtWas);\n }\n\n protected abstract flush(toShip: Map<string, T>, startAtWas: Date): void;\n\n private prepareData(): Map<string, T> {\n const toShip = new Map(this.data);\n this.data.clear();\n\n return toShip;\n }\n\n private startPeriodicSync(syncInterval?: number): void {\n this.startAt = new Date();\n this.syncInterval = PeriodicSync.calculateSyncInterval(syncInterval);\n\n this.scheduleNextSync();\n }\n\n private scheduleNextSync() {\n const interval = this.syncInterval();\n this.timeoutID = setTimeout(() => {\n this.sync();\n this.scheduleNextSync(); // Schedule the next sync after the current one completes\n }, interval);\n }\n\n private static calculateSyncInterval(syncInterval?: number): any {\n if (syncInterval !== undefined) {\n return () => syncInterval;\n }\n\n const backoff = new ExponentialBackoff(60 * 5, 8);\n return () => backoff.call();\n }\n\n protected logInternal(message: string): void {\n const loggerName = `${this.client.clientNameString}.reforge.${this.name}`;\n\n if (\n this.client.shouldLog(\n {\n loggerName,\n desiredLevel: ReforgeLogLevel.Debug,\n defaultLevel: ReforgeLogLevel.Error,\n },\n false // synchronous so that this log ends up in the current batch\n )\n ) {\n // eslint-disable-next-line no-console\n console.log(`${loggerName}: ${message}`);\n }\n }\n}\n\nexport { PeriodicSync };\n","// TODO: should we retry the data chunk if a flush fails?\n\n// TODO: pause when offline?\n\n// TODO: flush when we receive a config update (or as a result of a context update...but that should trigger a config update anyway)\n\nimport { PeriodicSync } from \"./periodicSync\";\nimport { Config } from \"./config\";\nimport { type reforge } from \"./reforge\";\nimport {\n ConfigEvaluationCounter,\n ConfigEvaluationSummaries,\n ConfigEvaluationSummary,\n TelemetryEvents,\n ConfigEvaluationMetadata,\n} from \"./types\";\n\nexport const massageSelectedValue = (config: Config): any => {\n if (config.rawValue && (config.type === \"duration\" || config.type === \"json\")) {\n if (config.type === \"json\") {\n return { json: config.rawValue[config.type] };\n }\n\n return config.rawValue[config.type];\n }\n\n return config.type === \"stringList\" ? { values: config.value } : config.value;\n};\n\nexport const massageConfigForTelemetry = (\n config: Config,\n metadata: Omit<ConfigEvaluationMetadata, \"type\">\n) => ({\n ...metadata,\n selectedValue: {\n [config.type]: massageSelectedValue(config),\n },\n count: 0,\n});\n\nclass EvaluationSummaryAggregator extends PeriodicSync<ConfigEvaluationCounter> {\n private maxKeys: number;\n\n constructor(client: typeof reforge, maxKeys: number, syncInterval?: number) {\n super(client, \"EvaluationSummaryAggregator\", syncInterval ?? 30000);\n\n this.maxKeys = maxKeys;\n }\n\n record(config: Config): void {\n if (this.data.size >= this.maxKeys) return;\n\n if (config?.configEvaluationMetadata) {\n const { type, ...metadata } = config.configEvaluationMetadata;\n const key = `${config.key},${type}`;\n\n // create counter entry if it doesn't exist\n if (!this.data.has(key)) {\n this.data.set(key, massageConfigForTelemetry(config, metadata));\n }\n\n // increment count\n const counter = this.data.get(key);\n if (counter) {\n counter.count += 1;\n }\n }\n }\n\n protected flush(toShip: Map<string, ConfigEvaluationCounter>, startAtWas: Date): void {\n const summaries = {\n start: startAtWas.getTime(),\n end: new Date().getTime(),\n summaries: EvaluationSummaryAggregator.summaries(toShip),\n };\n\n this.client.telemetryUploader?.post(this.events(summaries));\n }\n\n private static summaries(data: Map<string, ConfigEvaluationCounter>): ConfigEvaluationSummary[] {\n return Array.from(data).map((entry: [string, ConfigEvaluationCounter]) => {\n const [configKey, configType] = entry[0].split(\",\");\n const counter = entry[1];\n const counters = [counter]; // this client only ever has one set of counter info per key\n\n return {\n key: configKey,\n type: configType,\n counters,\n };\n });\n }\n\n private events(summaries: ConfigEvaluationSummaries): TelemetryEvents {\n const event = { summaries };\n\n return {\n instanceHash: this.client.instanceHash,\n events: [event],\n };\n }\n}\n\nexport { EvaluationSummaryAggregator };\n","import base64Encode from \"./base64Encode\";\n\nexport const headers = (sdkKey: string, clientVersion: string) => ({\n Authorization: `Basic ${base64Encode(`u:${sdkKey}`)}`,\n \"X-Reforge-SDK-Version\": clientVersion,\n});\n\nexport const DEFAULT_TIMEOUT = 10000;\n","import { DEFAULT_TIMEOUT, headers } from \"./apiHelpers\";\nimport { EvaluationPayload } from \"./config\";\nimport Context from \"./context\";\n\nexport type CollectContextModeType = \"NONE\" | \"SHAPE_ONLY\" | \"PERIODIC_EXAMPLE\";\n\nexport type LoaderParams = {\n sdkKey: string;\n context: Context;\n endpoints?: string[] | undefined;\n timeout?: number;\n collectContextMode?: CollectContextModeType;\n clientVersion?: string;\n};\n\nexport type Headers = {\n [key: string]: string;\n};\n\nexport type FetchOptions = {\n headers: Headers;\n};\n\nconst defaultEndpoints = [\n \"https://primary.reforge.com/api/v2\",\n \"https://secondary.reforge.com/api/v2\",\n];\n\nconst EARLY_TIMEOUT = 2000;\n\nexport default class Loader {\n sdkKey: string;\n\n context: Context;\n\n endpoints: string[];\n\n timeout: number;\n\n abortTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n collectContextMode: CollectContextModeType = \"PERIODIC_EXAMPLE\";\n\n clientVersion: string;\n\n abortController: AbortController | undefined;\n\n isAborted = false;\n\n constructor({\n sdkKey,\n context,\n endpoints = undefined,\n timeout,\n collectContextMode = \"PERIODIC_EXAMPLE\",\n clientVersion = \"\",\n }: LoaderParams) {\n this.sdkKey = sdkKey;\n this.context = context;\n this.endpoints = endpoints || defaultEndpoints;\n this.timeout = timeout || DEFAULT_TIMEOUT;\n this.collectContextMode = collectContextMode;\n this.clientVersion = clientVersion;\n }\n\n url(root: string) {\n return `${root}/configs/eval-with-context/${this.context.encode()}?collectContextMode=${\n this.collectContextMode\n }`;\n }\n\n loadFromEndpoint(\n index: number,\n options: FetchOptions,\n resolve: (value: any) => void,\n reject: (value: any) => void\n ) {\n this.abortController = new AbortController() as AbortController;\n const { signal } = this.abortController;\n this.isAborted = false;\n\n const endpoint = this.endpoints[index];\n const url = this.url(endpoint);\n\n fetch(url, { signal, ...options })\n .then((response) => {\n this.clearAbortTimeout();\n\n if (response.ok) {\n return response.json();\n }\n throw new Error(`${response.status} ${response.statusText}`);\n })\n .then((data) => {\n if (!(\"evaluations\" in data)) {\n throw new Error(`Invalid payload:${JSON.stringify(data)}`);\n }\n\n resolve(data as EvaluationPayload);\n })\n .catch((error) => {\n this.clearAbortTimeout();\n\n if (index < this.endpoints.length - 1) {\n this.loadFromEndpoint(index + 1, options, resolve, reject);\n } else {\n reject(error);\n }\n });\n\n // Use an early timeout if we're not on the last endpoint. But if the user-provided timeout is less than EARLY_TIMEOUT, use that\n const timeout =\n index < this.endpoints.length - 1 ? Math.min(this.timeout, EARLY_TIMEOUT) : this.timeout;\n\n this.abortTimeoutId = setTimeout(() => {\n if (!this.isAborted) {\n this.isAborted = true;\n this.abortController?.abort();\n }\n }, timeout);\n }\n\n load() {\n if (!this.isAborted) {\n this.isAborted = true;\n this.abortController?.abort();\n }\n\n const options = {\n headers: headers(this.sdkKey, this.clientVersion),\n };\n\n const prefetchPromise =\n typeof window !== \"undefined\" ? (window as any).REFORGE_SDK_PREFETCH_PROMISE : undefined;\n\n if (prefetchPromise && prefetchPromise instanceof Promise) {\n (window as any).REFORGE_SDK_PREFETCH_PROMISE = undefined;\n return prefetchPromise.catch(\n () =>\n // If the prefetch failed, we should try to load from the endpoints\n new Promise((resolve, reject) => {\n this.loadFromEndpoint(0, options, resolve, reject);\n })\n );\n }\n\n const promise = new Promise((resolve, reject) => {\n this.loadFromEndpoint(0, options, resolve, reject);\n });\n\n return promise;\n }\n\n clearAbortTimeout() {\n clearTimeout(this.abortTimeoutId);\n }\n}\n","import { DEFAULT_TIMEOUT, headers } from \"./apiHelpers\";\nimport { TelemetryEvents } from \"./types\";\n\nexport type TelemetryUploaderParams = {\n sdkKey: string;\n apiEndpoint?: string;\n timeout?: number;\n clientVersion: string;\n};\n\nexport default class TelemetryUploader {\n sdkKey: Required<TelemetryUploaderParams>[\"sdkKey\"];\n\n apiEndpoint: Required<TelemetryUploaderParams>[\"apiEndpoint\"];\n\n timeout: Required<TelemetryUploaderParams>[\"timeout\"];\n\n clientVersion: Required<TelemetryUploaderParams>[\"clientVersion\"];\n\n abortTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n constructor({\n sdkKey,\n apiEndpoint = undefined,\n timeout,\n clientVersion,\n }: TelemetryUploaderParams) {\n this.sdkKey = sdkKey;\n this.apiEndpoint = apiEndpoint || \"https://telemetry.reforge.com/api/v1\";\n this.timeout = timeout || DEFAULT_TIMEOUT;\n this.clientVersion = clientVersion;\n }\n\n clearAbortTimeout() {\n clearTimeout(this.abortTimeoutId);\n }\n\n static postUrl(root: string) {\n return `${root}/telemetry`;\n }\n\n postToEndpoint(\n options: RequestInit,\n resolve: (value: unknown) => void,\n reject: (value: unknown) => void\n ) {\n const controller = new AbortController() as AbortController;\n const signal = controller?.signal;\n let isAborted = false;\n\n const url = TelemetryUploader.postUrl(this.apiEndpoint);\n\n fetch(url, { signal, ...options })\n .then((response) => {\n this.clearAbortTimeout();\n\n if (response.ok) {\n return response.json();\n }\n\n // eslint-disable-next-line no-console\n console.warn(\n `Reforge warning: Error uploading telemetry ${response.status} ${response.statusText}`\n );\n\n return response.status;\n })\n .then((response) => {\n resolve(response);\n })\n .catch((error) => {\n this.clearAbortTimeout();\n\n // Silently handle AbortErrors (from timeouts or page navigations)\n if (error.name === \"AbortError\") {\n try {\n // eslint-disable-next-line no-console\n console.debug(\"Reforge telemetry request aborted\");\n } catch (e) {\n // no-op\n }\n resolve({ status: \"aborted\" });\n return;\n }\n\n reject(error);\n });\n\n this.abortTimeoutId = setTimeout(() => {\n if (!isAborted) {\n isAborted = true;\n controller.abort();\n }\n }, this.timeout);\n }\n\n post(data: TelemetryEvents) {\n const options = {\n method: \"POST\",\n headers: {\n ...headers(this.sdkKey, this.clientVersion),\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n body: JSON.stringify(data),\n keepalive: true, // needed for flushing when the window is closed\n };\n\n const promise = new Promise((resolve, reject) => {\n this.postToEndpoint(options, resolve, reject);\n });\n\n return promise;\n }\n}\n","// TODO: should we retry the data chunk if a flush fails?\n\n// TODO: pause when offline?\n\nimport { ReforgeLogLevel } from \"./logger\";\nimport { PeriodicSync } from \"./periodicSync\";\nimport { type reforge } from \"./reforge\";\nimport { LoggerCounter, LoggersTelemetryEvent, TelemetryEvents } from \"./types\";\n\nconst SEVERITY_KEY: { [key in ReforgeLogLevel]: Omit<keyof LoggerCounter, \"loggerName\"> } = {\n [ReforgeLogLevel.Trace]: \"traces\",\n [ReforgeLogLevel.Debug]: \"debugs\",\n [ReforgeLogLevel.Info]: \"infos\",\n [ReforgeLogLevel.Warn]: \"warns\",\n [ReforgeLogLevel.Error]: \"errors\",\n [ReforgeLogLevel.Fatal]: \"fatals\",\n};\n\nclass LoggerAggregator extends PeriodicSync<LoggerCounter> {\n private maxLoggers: number;\n\n constructor(client: typeof reforge, maxLoggers: number, syncInterval?: number) {\n super(client, \"LoggerAggregator\", syncInterval ?? 30000);\n\n this.maxLoggers = maxLoggers;\n }\n\n record(logger: string, level: ReforgeLogLevel): void {\n if (this.data.size >= this.maxLoggers) return;\n\n // create counter entry if it doesn't exist\n if (!this.data.has(logger)) {\n this.data.set(logger, {\n loggerName: logger,\n traces: 0,\n debugs: 0,\n infos: 0,\n warns: 0,\n errors: 0,\n fatals: 0,\n });\n }\n\n // increment count\n const counter = this.data.get(logger);\n if (counter) {\n const severityKey = SEVERITY_KEY[level] as keyof LoggerCounter;\n (counter[severityKey] as number) += 1;\n }\n }\n\n protected flush(toShip: Map<string, LoggerCounter>, startAtWas: Date): void {\n const loggers = {\n startAt: startAtWas.getTime(),\n endAt: new Date().getTime(),\n loggers: Array.from(toShip.values()),\n };\n\n this.client.telemetryUploader?.post(this.events(loggers));\n }\n\n private events(loggers: LoggersTelemetryEvent): TelemetryEvents {\n const event = { loggers };\n\n return {\n instanceHash: this.client.instanceHash,\n events: [event],\n };\n }\n}\n\nexport { LoggerAggregator };\n","import {\n reforge,\n Reforge,\n ReforgeInitParams,\n ReforgeBootstrap,\n prefetchReforgeConfig,\n} from \"./src/reforge\";\nimport { Config } from \"./src/config\";\nimport Context from \"./src/context\";\nimport { LogLevel, getLogLevelSeverity, shouldLogAtLevel } from \"./src/logger\";\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version } = require(\"./package.json\");\n\nexport {\n reforge,\n Reforge,\n ReforgeInitParams,\n Config,\n Context,\n LogLevel,\n getLogLevelSeverity,\n shouldLogAtLevel,\n version,\n prefetchReforgeConfig,\n};\n\nexport { ReforgeBootstrap };\n\nexport type { ConfigValue } from \"./src/config\";\nexport type {\n Duration,\n ContextValue,\n Contexts,\n TypedFrontEndConfigurationRaw,\n FrontEndConfigurationRaw,\n} from \"./src/types\";\nexport type { CollectContextModeType } from \"./src/loader\";\n"],"mappings":"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","names":["LogLevel","reforge","version"]}

@@ -1,2 +0,2 @@

"use strict";var window;(window||={}).reforgeNamespace=(()=>{var h=(e,r)=>()=>(r||e((r={exports:{}}).exports,r),r.exports);var Y=h(Q=>{"use strict";Object.defineProperty(Q,"__esModule",{value:!0});Q.default=We;var I,He=new Uint8Array(16);function We(){if(!I&&(I=typeof crypto<"u"&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!I))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return I(He)}});var ue=h(C=>{"use strict";Object.defineProperty(C,"__esModule",{value:!0});C.default=void 0;var Je=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;C.default=Je});var T=h(U=>{"use strict";Object.defineProperty(U,"__esModule",{value:!0});U.default=void 0;var Ge=Xe(ue());function Xe(e){return e&&e.__esModule?e:{default:e}}function ze(e){return typeof e=="string"&&Ge.default.test(e)}var Qe=ze;U.default=Qe});var P=h(R=>{"use strict";Object.defineProperty(R,"__esModule",{value:!0});R.default=void 0;R.unsafeStringify=ce;var Ye=Ze(T());function Ze(e){return e&&e.__esModule?e:{default:e}}var g=[];for(let e=0;e<256;++e)g.push((e+256).toString(16).slice(1));function ce(e,r=0){return g[e[r+0]]+g[e[r+1]]+g[e[r+2]]+g[e[r+3]]+"-"+g[e[r+4]]+g[e[r+5]]+"-"+g[e[r+6]]+g[e[r+7]]+"-"+g[e[r+8]]+g[e[r+9]]+"-"+g[e[r+10]]+g[e[r+11]]+g[e[r+12]]+g[e[r+13]]+g[e[r+14]]+g[e[r+15]]}function et(e,r=0){let t=ce(e,r);if(!(0,Ye.default)(t))throw TypeError("Stringified UUID is invalid");return t}var tt=et;R.default=tt});var de=h(D=>{"use strict";Object.defineProperty(D,"__esModule",{value:!0});D.default=void 0;var rt=it(Y()),nt=P();function it(e){return e&&e.__esModule?e:{default:e}}var fe,Z,ee=0,te=0;function ot(e,r,t){let n=r&&t||0,i=r||new Array(16);e=e||{};let o=e.node||fe,s=e.clockseq!==void 0?e.clockseq:Z;if(o==null||s==null){let d=e.random||(e.rng||rt.default)();o==null&&(o=fe=[d[0]|1,d[1],d[2],d[3],d[4],d[5]]),s==null&&(s=Z=(d[6]<<8|d[7])&16383)}let l=e.msecs!==void 0?e.msecs:Date.now(),a=e.nsecs!==void 0?e.nsecs:te+1,u=l-ee+(a-te)/1e4;if(u<0&&e.clockseq===void 0&&(s=s+1&16383),(u<0||l>ee)&&e.nsecs===void 0&&(a=0),a>=1e4)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");ee=l,te=a,Z=s,l+=122192928e5;let c=((l&268435455)*1e4+a)%4294967296;i[n++]=c>>>24&255,i[n++]=c>>>16&255,i[n++]=c>>>8&255,i[n++]=c&255;let y=l/4294967296*1e4&268435455;i[n++]=y>>>8&255,i[n++]=y&255,i[n++]=y>>>24&15|16,i[n++]=y>>>16&255,i[n++]=s>>>8|128,i[n++]=s&255;for(let d=0;d<6;++d)i[n+d]=o[d];return r||(0,nt.unsafeStringify)(i)}var st=ot;D.default=st});var re=h(j=>{"use strict";Object.defineProperty(j,"__esModule",{value:!0});j.default=void 0;var at=lt(T());function lt(e){return e&&e.__esModule?e:{default:e}}function ut(e){if(!(0,at.default)(e))throw TypeError("Invalid UUID");let r,t=new Uint8Array(16);return t[0]=(r=parseInt(e.slice(0,8),16))>>>24,t[1]=r>>>16&255,t[2]=r>>>8&255,t[3]=r&255,t[4]=(r=parseInt(e.slice(9,13),16))>>>8,t[5]=r&255,t[6]=(r=parseInt(e.slice(14,18),16))>>>8,t[7]=r&255,t[8]=(r=parseInt(e.slice(19,23),16))>>>8,t[9]=r&255,t[10]=(r=parseInt(e.slice(24,36),16))/1099511627776&255,t[11]=r/4294967296&255,t[12]=r>>>24&255,t[13]=r>>>16&255,t[14]=r>>>8&255,t[15]=r&255,t}var ct=ut;j.default=ct});var ne=h(A=>{"use strict";Object.defineProperty(A,"__esModule",{value:!0});A.URL=A.DNS=void 0;A.default=pt;var ft=P(),dt=ht(re());function ht(e){return e&&e.__esModule?e:{default:e}}function gt(e){e=unescape(encodeURIComponent(e));let r=[];for(let t=0;t<e.length;++t)r.push(e.charCodeAt(t));return r}var he="6ba7b810-9dad-11d1-80b4-00c04fd430c8";A.DNS=he;var ge="6ba7b811-9dad-11d1-80b4-00c04fd430c8";A.URL=ge;function pt(e,r,t){function n(i,o,s,l){var a;if(typeof i=="string"&&(i=gt(i)),typeof o=="string"&&(o=(0,dt.default)(o)),((a=o)===null||a===void 0?void 0:a.length)!==16)throw TypeError("Namespace must be array-like (16 iterable integer values, 0-255)");let u=new Uint8Array(16+i.length);if(u.set(o),u.set(i,o.length),u=t(u),u[6]=u[6]&15|r,u[8]=u[8]&63|128,s){l=l||0;for(let c=0;c<16;++c)s[l+c]=u[c];return s}return(0,ft.unsafeStringify)(u)}try{n.name=e}catch{}return n.DNS=he,n.URL=ge,n}});var ve=h(L=>{"use strict";Object.defineProperty(L,"__esModule",{value:!0});L.default=void 0;function vt(e){if(typeof e=="string"){let r=unescape(encodeURIComponent(e));e=new Uint8Array(r.length);for(let t=0;t<r.length;++t)e[t]=r.charCodeAt(t)}return mt(_t(yt(e),e.length*8))}function mt(e){let r=[],t=e.length*32,n="0123456789abcdef";for(let i=0;i<t;i+=8){let o=e[i>>5]>>>i%32&255,s=parseInt(n.charAt(o>>>4&15)+n.charAt(o&15),16);r.push(s)}return r}function pe(e){return(e+64>>>9<<4)+14+1}function _t(e,r){e[r>>5]|=128<<r%32,e[pe(r)-1]=r;let t=1732584193,n=-271733879,i=-1732584194,o=271733878;for(let s=0;s<e.length;s+=16){let l=t,a=n,u=i,c=o;t=p(t,n,i,o,e[s],7,-680876936),o=p(o,t,n,i,e[s+1],12,-389564586),i=p(i,o,t,n,e[s+2],17,606105819),n=p(n,i,o,t,e[s+3],22,-1044525330),t=p(t,n,i,o,e[s+4],7,-176418897),o=p(o,t,n,i,e[s+5],12,1200080426),i=p(i,o,t,n,e[s+6],17,-1473231341),n=p(n,i,o,t,e[s+7],22,-45705983),t=p(t,n,i,o,e[s+8],7,1770035416),o=p(o,t,n,i,e[s+9],12,-1958414417),i=p(i,o,t,n,e[s+10],17,-42063),n=p(n,i,o,t,e[s+11],22,-1990404162),t=p(t,n,i,o,e[s+12],7,1804603682),o=p(o,t,n,i,e[s+13],12,-40341101),i=p(i,o,t,n,e[s+14],17,-1502002290),n=p(n,i,o,t,e[s+15],22,1236535329),t=v(t,n,i,o,e[s+1],5,-165796510),o=v(o,t,n,i,e[s+6],9,-1069501632),i=v(i,o,t,n,e[s+11],14,643717713),n=v(n,i,o,t,e[s],20,-373897302),t=v(t,n,i,o,e[s+5],5,-701558691),o=v(o,t,n,i,e[s+10],9,38016083),i=v(i,o,t,n,e[s+15],14,-660478335),n=v(n,i,o,t,e[s+4],20,-405537848),t=v(t,n,i,o,e[s+9],5,568446438),o=v(o,t,n,i,e[s+14],9,-1019803690),i=v(i,o,t,n,e[s+3],14,-187363961),n=v(n,i,o,t,e[s+8],20,1163531501),t=v(t,n,i,o,e[s+13],5,-1444681467),o=v(o,t,n,i,e[s+2],9,-51403784),i=v(i,o,t,n,e[s+7],14,1735328473),n=v(n,i,o,t,e[s+12],20,-1926607734),t=m(t,n,i,o,e[s+5],4,-378558),o=m(o,t,n,i,e[s+8],11,-2022574463),i=m(i,o,t,n,e[s+11],16,1839030562),n=m(n,i,o,t,e[s+14],23,-35309556),t=m(t,n,i,o,e[s+1],4,-1530992060),o=m(o,t,n,i,e[s+4],11,1272893353),i=m(i,o,t,n,e[s+7],16,-155497632),n=m(n,i,o,t,e[s+10],23,-1094730640),t=m(t,n,i,o,e[s+13],4,681279174),o=m(o,t,n,i,e[s],11,-358537222),i=m(i,o,t,n,e[s+3],16,-722521979),n=m(n,i,o,t,e[s+6],23,76029189),t=m(t,n,i,o,e[s+9],4,-640364487),o=m(o,t,n,i,e[s+12],11,-421815835),i=m(i,o,t,n,e[s+15],16,530742520),n=m(n,i,o,t,e[s+2],23,-995338651),t=_(t,n,i,o,e[s],6,-198630844),o=_(o,t,n,i,e[s+7],10,1126891415),i=_(i,o,t,n,e[s+14],15,-1416354905),n=_(n,i,o,t,e[s+5],21,-57434055),t=_(t,n,i,o,e[s+12],6,1700485571),o=_(o,t,n,i,e[s+3],10,-1894986606),i=_(i,o,t,n,e[s+10],15,-1051523),n=_(n,i,o,t,e[s+1],21,-2054922799),t=_(t,n,i,o,e[s+8],6,1873313359),o=_(o,t,n,i,e[s+15],10,-30611744),i=_(i,o,t,n,e[s+6],15,-1560198380),n=_(n,i,o,t,e[s+13],21,1309151649),t=_(t,n,i,o,e[s+4],6,-145523070),o=_(o,t,n,i,e[s+11],10,-1120210379),i=_(i,o,t,n,e[s+2],15,718787259),n=_(n,i,o,t,e[s+9],21,-343485551),t=x(t,l),n=x(n,a),i=x(i,u),o=x(o,c)}return[t,n,i,o]}function yt(e){if(e.length===0)return[];let r=e.length*8,t=new Uint32Array(pe(r));for(let n=0;n<r;n+=8)t[n>>5]|=(e[n/8]&255)<<n%32;return t}function x(e,r){let t=(e&65535)+(r&65535);return(e>>16)+(r>>16)+(t>>16)<<16|t&65535}function wt(e,r){return e<<r|e>>>32-r}function M(e,r,t,n,i,o){return x(wt(x(x(r,e),x(n,o)),i),t)}function p(e,r,t,n,i,o,s){return M(r&t|~r&n,e,r,i,o,s)}function v(e,r,t,n,i,o,s){return M(r&n|t&~n,e,r,i,o,s)}function m(e,r,t,n,i,o,s){return M(r^t^n,e,r,i,o,s)}function _(e,r,t,n,i,o,s){return M(t^(r|~n),e,r,i,o,s)}var bt=vt;L.default=bt});var _e=h(q=>{"use strict";Object.defineProperty(q,"__esModule",{value:!0});q.default=void 0;var xt=me(ne()),At=me(ve());function me(e){return e&&e.__esModule?e:{default:e}}var Et=(0,xt.default)("v3",48,At.default),Ot=Et;q.default=Ot});var ye=h(N=>{"use strict";Object.defineProperty(N,"__esModule",{value:!0});N.default=void 0;var Tt=typeof crypto<"u"&&crypto.randomUUID&&crypto.randomUUID.bind(crypto),Rt={randomUUID:Tt};N.default=Rt});var xe=h(V=>{"use strict";Object.defineProperty(V,"__esModule",{value:!0});V.default=void 0;var we=be(ye()),Pt=be(Y()),St=P();function be(e){return e&&e.__esModule?e:{default:e}}function It(e,r,t){if(we.default.randomUUID&&!r&&!e)return we.default.randomUUID();e=e||{};let n=e.random||(e.rng||Pt.default)();if(n[6]=n[6]&15|64,n[8]=n[8]&63|128,r){t=t||0;for(let i=0;i<16;++i)r[t+i]=n[i];return r}return(0,St.unsafeStringify)(n)}var Ct=It;V.default=Ct});var Ae=h(k=>{"use strict";Object.defineProperty(k,"__esModule",{value:!0});k.default=void 0;function Ut(e,r,t,n){switch(e){case 0:return r&t^~r&n;case 1:return r^t^n;case 2:return r&t^r&n^t&n;case 3:return r^t^n}}function ie(e,r){return e<<r|e>>>32-r}function Dt(e){let r=[1518500249,1859775393,2400959708,3395469782],t=[1732584193,4023233417,2562383102,271733878,3285377520];if(typeof e=="string"){let s=unescape(encodeURIComponent(e));e=[];for(let l=0;l<s.length;++l)e.push(s.charCodeAt(l))}else Array.isArray(e)||(e=Array.prototype.slice.call(e));e.push(128);let n=e.length/4+2,i=Math.ceil(n/16),o=new Array(i);for(let s=0;s<i;++s){let l=new Uint32Array(16);for(let a=0;a<16;++a)l[a]=e[s*64+a*4]<<24|e[s*64+a*4+1]<<16|e[s*64+a*4+2]<<8|e[s*64+a*4+3];o[s]=l}o[i-1][14]=(e.length-1)*8/Math.pow(2,32),o[i-1][14]=Math.floor(o[i-1][14]),o[i-1][15]=(e.length-1)*8&4294967295;for(let s=0;s<i;++s){let l=new Uint32Array(80);for(let f=0;f<16;++f)l[f]=o[s][f];for(let f=16;f<80;++f)l[f]=ie(l[f-3]^l[f-8]^l[f-14]^l[f-16],1);let a=t[0],u=t[1],c=t[2],y=t[3],d=t[4];for(let f=0;f<80;++f){let O=Math.floor(f/20),S=ie(a,5)+Ut(O,u,c,y)+d+r[O]+l[f]>>>0;d=y,y=c,c=ie(u,30)>>>0,u=a,a=S}t[0]=t[0]+a>>>0,t[1]=t[1]+u>>>0,t[2]=t[2]+c>>>0,t[3]=t[3]+y>>>0,t[4]=t[4]+d>>>0}return[t[0]>>24&255,t[0]>>16&255,t[0]>>8&255,t[0]&255,t[1]>>24&255,t[1]>>16&255,t[1]>>8&255,t[1]&255,t[2]>>24&255,t[2]>>16&255,t[2]>>8&255,t[2]&255,t[3]>>24&255,t[3]>>16&255,t[3]>>8&255,t[3]&255,t[4]>>24&255,t[4]>>16&255,t[4]>>8&255,t[4]&255]}var jt=Dt;k.default=jt});var Oe=h($=>{"use strict";Object.defineProperty($,"__esModule",{value:!0});$.default=void 0;var Mt=Ee(ne()),Lt=Ee(Ae());function Ee(e){return e&&e.__esModule?e:{default:e}}var qt=(0,Mt.default)("v5",80,Lt.default),Nt=qt;$.default=Nt});var Te=h(F=>{"use strict";Object.defineProperty(F,"__esModule",{value:!0});F.default=void 0;var Vt="00000000-0000-0000-0000-000000000000";F.default=Vt});var Re=h(K=>{"use strict";Object.defineProperty(K,"__esModule",{value:!0});K.default=void 0;var kt=$t(T());function $t(e){return e&&e.__esModule?e:{default:e}}function Ft(e){if(!(0,kt.default)(e))throw TypeError("Invalid UUID");return parseInt(e.slice(14,15),16)}var Kt=Ft;K.default=Kt});var Pe=h(w=>{"use strict";Object.defineProperty(w,"__esModule",{value:!0});Object.defineProperty(w,"NIL",{enumerable:!0,get:function(){return Gt.default}});Object.defineProperty(w,"parse",{enumerable:!0,get:function(){return Yt.default}});Object.defineProperty(w,"stringify",{enumerable:!0,get:function(){return Qt.default}});Object.defineProperty(w,"v1",{enumerable:!0,get:function(){return Bt.default}});Object.defineProperty(w,"v3",{enumerable:!0,get:function(){return Ht.default}});Object.defineProperty(w,"v4",{enumerable:!0,get:function(){return Wt.default}});Object.defineProperty(w,"v5",{enumerable:!0,get:function(){return Jt.default}});Object.defineProperty(w,"validate",{enumerable:!0,get:function(){return zt.default}});Object.defineProperty(w,"version",{enumerable:!0,get:function(){return Xt.default}});var Bt=b(de()),Ht=b(_e()),Wt=b(xe()),Jt=b(Oe()),Gt=b(Te()),Xt=b(Re()),zt=b(T()),Qt=b(P()),Yt=b(re());function b(e){return e&&e.__esModule?e:{default:e}}});var Ir=h((Gr,Be)=>{var X=Object.defineProperty,Zt=Object.defineProperties,er=Object.getOwnPropertyDescriptor,tr=Object.getOwnPropertyDescriptors,Ie=Object.getOwnPropertyNames,H=Object.getOwnPropertySymbols,ae=Object.prototype.hasOwnProperty,Ce=Object.prototype.propertyIsEnumerable,Se=(e,r,t)=>r in e?X(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t,E=(e,r)=>{for(var t in r||(r={}))ae.call(r,t)&&Se(e,t,r[t]);if(H)for(var t of H(r))Ce.call(r,t)&&Se(e,t,r[t]);return e},W=(e,r)=>Zt(e,tr(r)),rr=(e,r)=>{var t={};for(var n in e)ae.call(e,n)&&r.indexOf(n)<0&&(t[n]=e[n]);if(e!=null&&H)for(var n of H(e))r.indexOf(n)<0&&Ce.call(e,n)&&(t[n]=e[n]);return t},nr=(e,r)=>function(){return r||(0,e[Ie(e)[0]])((r={exports:{}}).exports,r),r.exports},ir=(e,r)=>{for(var t in r)X(e,t,{get:r[t],enumerable:!0})},or=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of Ie(r))!ae.call(e,i)&&i!==t&&X(e,i,{get:()=>r[i],enumerable:!(n=er(r,i))||n.enumerable});return e},sr=e=>or(X({},"__esModule",{value:!0}),e),B=(e,r,t)=>new Promise((n,i)=>{var o=a=>{try{l(t.next(a))}catch(u){i(u)}},s=a=>{try{l(t.throw(a))}catch(u){i(u)}},l=a=>a.done?n(a.value):Promise.resolve(a.value).then(o,s);l((t=t.apply(e,r)).next())}),Ue=nr({"package.json"(e,r){r.exports={packageManager:"yarn@4.9.2",name:"@reforge-com/javascript",version:"0.0.4",description:"Feature Flags & Dynamic Configuration as a Service",main:"dist/index.cjs",module:"dist/index.mjs",types:"dist/index.d.ts",author:"Jeffrey Chupp",license:"ISC",devDependencies:{"@types/eslint-plugin-jsx-a11y":"^6","@types/express":"^4.17.13","@types/jest":"^28.1.6","@types/uuid":"^9.0.5","@typescript-eslint/eslint-plugin":"^5.33.0","@typescript-eslint/parser":"^5.33.0",esbuild:"^0.25.11",eslint:"^8.21.0","eslint-config-airbnb":"^19.0.4","eslint-config-airbnb-typescript":"^17.0.0","eslint-config-prettier":"^8.8.0","eslint-plugin-import":"^2.26.0","eslint-plugin-jest":"^26.8.0","eslint-plugin-jsx-a11y":"^6.10.2","eslint-plugin-react":"^7.37.5",jest:"^29.0.0","jest-fetch-mock":"^3.0.3",prettier:"^3.0.0","ts-jest":"^29.1.1","ts-node":"^10.9.1",tsup:"^8.0.2",typescript:"^5.1.6"},scripts:{build:"rm -rf dist/ && tsup",dev:"tsup --watch",bundle:"esbuild --minify --target=esnext --bundle --outfile=dist/reforge.bundle.js --global-name=window.reforgeNamespace dist/index.cjs && echo 'window.reforge = window.reforgeNamespace.reforge' >> dist/reforge.bundle.js",lint:"eslint --ext .ts,.tsx src/","lint:fix":"eslint --fix --ext .ts,.tsx src/",prettier:"prettier . -l","prettier:fix":"prettier --write .",test:"jest --verbose"},repository:{type:"git",url:"https://github.com/ReforgeHQ/sdk-javascript.git"},keywords:["feature-flags","config"],bugs:{url:"https://github.com/ReforgeHQ/sdk-javascript/issues"},homepage:"https://github.com/ReforgeHQ/sdk-javascript#readme",dependencies:{uuid:"^9.0.1"},exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.mjs",require:"./dist/index.cjs"}}}}}),De={};ir(De,{Config:()=>z,Context:()=>oe,LogLevel:()=>G,Reforge:()=>Ke,getLogLevelSeverity:()=>pr,reforge:()=>Pr,shouldLogAtLevel:()=>Le,version:()=>Sr});Be.exports=sr(De);var ar=Pe(),lr=e=>({configRowIndex:parseInt(e.configRowIndex,10),conditionalValueIndex:parseInt(e.conditionalValueIndex,10),type:e.type,configId:e.id}),je=(e,r,t)=>{let n=e[r];switch(r){case"json":try{return JSON.parse(n)}catch(i){return console.error(`Error parsing JSON from Reforge config ${t}`,i,n),e[r]}case"duration":{let i=n;return{ms:i.millis,seconds:i.millis/1e3}}default:return n}},ur=e=>{let r={};return Object.keys(e.evaluations).forEach(t=>{let n=e.evaluations[t],i=Object.keys(n.value)[0];r[t]=new z(t,je(n.value,i,t),i,n.value,n.configEvaluationMetadata?lr(n.configEvaluationMetadata):void 0)}),r},cr=e=>{let r={};return Object.keys(e).forEach(t=>{let n=typeof e[t];r[t]=new z(t,je({[n]:e[t]},n,t),n)}),r},z=class{constructor(e,r,t,n,i){this.key=e,this.value=r,this.type=t,this.rawValue=n,this.configEvaluationMetadata=i}static digest(e){return e===void 0&&console.trace("Config.digest called with undefined payload"),"evaluations"in e?ur(e):cr(e)}},fr=e=>{if(typeof window<"u"){if(typeof TextEncoder>"u")return window.btoa(e);let r=new TextEncoder().encode(e),t=Array.from(r,n=>String.fromCodePoint(n)).join("");return btoa(t)}return Buffer.from(e).toString("base64")},Me=fr,dr=(e,r)=>{let t=Object.keys(e),n=Object.keys(r);return t.length!==n.length?!1:t.every(i=>{let o=e[i],s=r[i],l=Object.keys(o),a=Object.keys(s);return l.length!==a.length?!1:l.every(u=>{let c=o[u],y=s[u];return c===y})})},hr=e=>typeof e=="string"?"string":typeof e=="number"?Number.isInteger(e)?"int":"double":"bool",oe=class{constructor(e){Object.values(e).every(r=>typeof r=="object")||console.error("Context must be an object where the value of each key is also an object"),Object.values(e).some(r=>Object.values(r).some(t=>typeof t=="object"&&t!==null))&&console.error("Nested objects are not supported in context values at this time"),this.contexts=e}equals(e){return dr(this.contexts,e.contexts)}encode(){let e=Object.keys(this.contexts).map(r=>{let t={};return Object.keys(this.contexts[r]).forEach(n=>{t[n]={[hr(this.contexts[r][n])]:this.contexts[r][n]}}),{type:r,values:t}});return encodeURIComponent(Me(JSON.stringify({contexts:e})))}},gr=class{constructor(e,r=2,t=2){this.maxDelay=e,this.multiplier=t,this.delay=r}call(){let e=this.delay;return this.delay=Math.min(this.delay*this.multiplier,this.maxDelay),e*1e3}},se="log-level",J={TRACE:1,DEBUG:2,INFO:3,WARN:4,ERROR:5,FATAL:6},G=(e=>(e.TRACE="TRACE",e.DEBUG="DEBUG",e.INFO="INFO",e.WARN="WARN",e.ERROR="ERROR",e.FATAL="FATAL",e))(G||{}),pr=e=>J[e],Le=(e,r)=>J[e]<=J[r],vr=({loggerName:e,desiredLevel:r,defaultLevel:t,get:n})=>{let i=`${se}.${e}`,o=n(i);return o?J[o.toString().toUpperCase()]<=r:t<=r},qe=class Ne{constructor(r,t,n){this.data=new Map,this.client=r,this.name=t,this.startAt=new Date,this.startPeriodicSync(n)}stop(){clearTimeout(this.timeoutID)}sync(){if(this.data.size===0)return;this.logInternal(`${this.name} syncing ${this.data.size} items`);let r=this.startAt;this.startAt=new Date,this.flush(this.prepareData(),r)}prepareData(){let r=new Map(this.data);return this.data.clear(),r}startPeriodicSync(r){this.startAt=new Date,this.syncInterval=Ne.calculateSyncInterval(r),this.scheduleNextSync()}scheduleNextSync(){let r=this.syncInterval();this.timeoutID=setTimeout(()=>{this.sync(),this.scheduleNextSync()},r)}static calculateSyncInterval(r){if(r!==void 0)return()=>r;let t=new gr(300,8);return()=>t.call()}logInternal(r){let t=`${this.client.clientNameString}.reforge.${this.name}`;this.client.shouldLog({loggerName:t,desiredLevel:2,defaultLevel:5},!1)&&console.log(`${t}: ${r}`)}},mr=e=>e.rawValue&&(e.type==="duration"||e.type==="json")?e.type==="json"?{json:e.rawValue[e.type]}:e.rawValue[e.type]:e.type==="stringList"?{values:e.value}:e.value,_r=(e,r)=>W(E({},r),{selectedValue:{[e.type]:mr(e)},count:0}),yr=class Ve extends qe{constructor(r,t,n){super(r,"EvaluationSummaryAggregator",n??3e4),this.maxKeys=t}record(r){if(!(this.data.size>=this.maxKeys)&&r?.configEvaluationMetadata){let t=r.configEvaluationMetadata,{type:n}=t,i=rr(t,["type"]),o=`${r.key},${n}`;this.data.has(o)||this.data.set(o,_r(r,i));let s=this.data.get(o);s&&(s.count+=1)}}flush(r,t){var n;let i={start:t.getTime(),end:new Date().getTime(),summaries:Ve.summaries(r)};(n=this.client.telemetryUploader)==null||n.post(this.events(i))}static summaries(r){return Array.from(r).map(t=>{let[n,i]=t[0].split(","),s=[t[1]];return{key:n,type:i,counters:s}})}events(r){let t={summaries:r};return{instanceHash:this.client.instanceHash,events:[t]}}},ke=(e,r)=>({Authorization:`Basic ${Me(`u:${e}`)}`,"X-Reforge-SDK-Version":r}),$e=1e4,wr=["https://primary.reforge.com/api/v2","https://secondary.reforge.com/api/v2"],br=2e3,xr=class{constructor({sdkKey:e,context:r,endpoints:t=void 0,timeout:n,collectContextMode:i="PERIODIC_EXAMPLE",clientVersion:o=""}){this.collectContextMode="PERIODIC_EXAMPLE",this.isAborted=!1,this.sdkKey=e,this.context=r,this.endpoints=t||wr,this.timeout=n||$e,this.collectContextMode=i,this.clientVersion=o}url(e){return`${e}/configs/eval-with-context/${this.context.encode()}?collectContextMode=${this.collectContextMode}`}loadFromEndpoint(e,r,t,n){this.abortController=new AbortController;let{signal:i}=this.abortController;this.isAborted=!1;let o=this.endpoints[e],s=this.url(o);fetch(s,E({signal:i},r)).then(a=>{if(this.clearAbortTimeout(),a.ok)return a.json();throw new Error(`${a.status} ${a.statusText}`)}).then(a=>{if(!("evaluations"in a))throw new Error(`Invalid payload:${JSON.stringify(a)}`);t(a)}).catch(a=>{this.clearAbortTimeout(),e<this.endpoints.length-1?this.loadFromEndpoint(e+1,r,t,n):n(a)});let l=e<this.endpoints.length-1?Math.min(this.timeout,br):this.timeout;this.abortTimeoutId=setTimeout(()=>{var a;this.isAborted||(this.isAborted=!0,(a=this.abortController)==null||a.abort())},l)}load(){var e;this.isAborted||(this.isAborted=!0,(e=this.abortController)==null||e.abort());let r={headers:ke(this.sdkKey,this.clientVersion)};return new Promise((n,i)=>{this.loadFromEndpoint(0,r,n,i)})}clearAbortTimeout(){clearTimeout(this.abortTimeoutId)}},Ar=class Fe{constructor({sdkKey:r,apiEndpoint:t=void 0,timeout:n,clientVersion:i}){this.sdkKey=r,this.apiEndpoint=t||"https://telemetry.reforge.com/api/v1",this.timeout=n||$e,this.clientVersion=i}clearAbortTimeout(){clearTimeout(this.abortTimeoutId)}static postUrl(r){return`${r}/telemetry`}postToEndpoint(r,t,n){let i=new AbortController,o=i?.signal,s=!1,l=Fe.postUrl(this.apiEndpoint);fetch(l,E({signal:o},r)).then(a=>(this.clearAbortTimeout(),a.ok?a.json():(console.warn(`Reforge warning: Error uploading telemetry ${a.status} ${a.statusText}`),a.status))).then(a=>{t(a)}).catch(a=>{if(this.clearAbortTimeout(),a.name==="AbortError"){try{console.debug("Reforge telemetry request aborted")}catch{}t({status:"aborted"});return}n(a)}),this.abortTimeoutId=setTimeout(()=>{s||(s=!0,i.abort())},this.timeout)}post(r){let t={method:"POST",headers:W(E({},ke(this.sdkKey,this.clientVersion)),{"Content-Type":"application/json",Accept:"application/json"}),body:JSON.stringify(r),keepalive:!0};return new Promise((i,o)=>{this.postToEndpoint(t,i,o)})}},Er={1:"traces",2:"debugs",3:"infos",4:"warns",5:"errors",6:"fatals"},Or=class extends qe{constructor(e,r,t){super(e,"LoggerAggregator",t??3e4),this.maxLoggers=r}record(e,r){if(this.data.size>=this.maxLoggers)return;this.data.has(e)||this.data.set(e,{loggerName:e,traces:0,debugs:0,infos:0,warns:0,errors:0,fatals:0});let t=this.data.get(e);if(t){let n=Er[r];t[n]+=1}}flush(e,r){var t;let n={startAt:r.getTime(),endAt:new Date().getTime(),loggers:Array.from(e.values())};(t=this.client.telemetryUploader)==null||t.post(this.events(n))}events(e){let r={loggers:e};return{instanceHash:this.client.instanceHash,events:[r]}}},{version:Tr}=Ue(),Rr=class{constructor(e){this.reforge=e}log(e,r){let t=this.reforge.getLogLevel("");if(Le(t,r))switch(r){case"TRACE":case"DEBUG":console.debug(e);break;case"INFO":console.info(e);break;case"WARN":console.warn(e);break;case"ERROR":case"FATAL":console.error(e);break;default:console.error(e)}}trace(e){this.log(e,"TRACE")}debug(e){this.log(e,"DEBUG")}info(e){this.log(e,"INFO")}warn(e){this.log(e,"WARN")}error(e){this.log(e,"ERROR")}fatal(e){this.log(e,"FATAL")}},Ke=class{constructor(){this._configs={},this._pollCount=0,this._pollStatus={status:"not-started"},this._pollTimeoutId=void 0,this._instanceHash=(0,ar.v4)(),this.collectEvaluationSummaries=!0,this.collectLoggerNames=!1,this.clientNameString="sdk-javascript",this.loaded=!1,this.afterEvaluationCallback=(()=>{}),this._context=new oe({}),this._loggerKey="log-levels.default",this.logger=new Rr(this)}init(e){return B(this,arguments,function*({sdkKey:r,context:t,endpoints:n=void 0,apiEndpoint:i,timeout:o=void 0,afterEvaluationCallback:s=()=>{},collectEvaluationSummaries:l=!0,collectLoggerNames:a=!1,collectContextMode:u="PERIODIC_EXAMPLE",clientNameString:c="sdk-javascript",clientVersionString:y=Tr,loggerKey:d="log-levels.default"}){let f=t??this.context;if(!f)throw new Error("Context must be provided");this._context=f,this._loggerKey=d,this.clientNameString=c;let O=`${c}-${y}`;return this.loader=new xr({sdkKey:r,context:f,endpoints:n,timeout:o,collectContextMode:u,clientVersion:O}),this._telemetryUploader=new Ar({sdkKey:r,apiEndpoint:i,timeout:o,clientVersion:O}),this.collectEvaluationSummaries=l,l&&(this.evalutionSummaryAggregator=new yr(this,1e5)),this.collectLoggerNames=a,a&&(this.loggerAggregator=new Or(this,1e5)),(l||a)&&typeof window<"u"&&typeof window.addEventListener=="function"&&window.addEventListener("beforeunload",()=>{var S,le;(S=this.evalutionSummaryAggregator)==null||S.sync(),(le=this.loggerAggregator)==null||le.sync()}),this.afterEvaluationCallback=s,this.load()})}extract(){return Object.entries(this._configs).reduce((e,[r,t])=>W(E({},e),{[r]:t.value}),{})}hydrate(e){this.setConfigPrivate(e)}get context(){return this._context}get instanceHash(){return this._instanceHash}get pollTimeoutId(){return this._pollTimeoutId}get pollCount(){return this._pollCount}get pollStatus(){return this._pollStatus}get telemetryUploader(){return this._telemetryUploader}load(){return B(this,null,function*(){if(!this.loader||!this.context)throw new Error("Reforge not initialized. Call init() first.");if(globalThis&&globalThis._reforgeBootstrap){let e=globalThis._reforgeBootstrap,r=new oe(e.context);if(this.context.equals(r))return this.setConfigPrivate({evaluations:e.evaluations}),Promise.resolve()}return this.loader.context=this.context,this.loader.load().then(e=>{this.setConfigPrivate(e)}).finally(()=>{this.pollStatus.status==="running"&&(this._pollCount+=1)})})}updateContext(e,r=!1){return B(this,null,function*(){if(!this.loader)throw new Error("Reforge not initialized. Call init() first.");return this._context=e,r?Promise.resolve():this.load()})}poll(e){return B(this,arguments,function*({frequencyInMs:r}){if(!this.loader)throw new Error("Reforge not initialized. Call init() first.");return this.stopPolling(),this._pollStatus={status:"pending"},this.loader.load().finally(()=>{this.doPolling({frequencyInMs:r})})})}doPolling({frequencyInMs:e}){this._pollTimeoutId=setTimeout(()=>{this.load().finally(()=>{this.pollStatus.status==="running"&&this.doPolling({frequencyInMs:e})})},e),this._pollStatus={status:"running",frequencyInMs:e}}stopPolling(){this.pollTimeoutId&&(clearTimeout(this.pollTimeoutId),this._pollTimeoutId=void 0),this._pollStatus={status:"stopped"}}stopTelemetry(){var e,r;this.telemetryUploader&&((e=this.evalutionSummaryAggregator)==null||e.stop(),(r=this.loggerAggregator)==null||r.stop())}setConfigPrivate(e){this._configs=z.digest(e),this.loaded=!0}isEnabled(e){return this.get(e)===!0}get(e){if(!this.loaded){e.startsWith(se)||console.warn(`Reforge warning: The client has not finished loading data yet. Unable to look up actual value for key "${e}".`);return}let r=this._configs[e],t=r?.value;return e.startsWith(se)||(this.collectEvaluationSummaries&&setTimeout(()=>{var n;return(n=this.evalutionSummaryAggregator)==null?void 0:n.record(r)}),setTimeout(()=>this.afterEvaluationCallback(e,t,this.context))),t}getDuration(e){let r=this.get(e);if(r){if(!Object.prototype.hasOwnProperty.call(r,"seconds")||!Object.prototype.hasOwnProperty.call(r,"ms"))throw new Error(`Value for key "${e}" is not a duration`);return r}}shouldLog(e,r=!0){if(this.collectLoggerNames){let t=()=>{var n;return(n=this.loggerAggregator)==null?void 0:n.record(e.loggerName,e.desiredLevel)};r?setTimeout(t):t()}return vr(W(E({},e),{get:this.get.bind(this)}))}getLogLevel(e){let r=this.get(this._loggerKey);if(r&&typeof r=="string"){let t=r.toUpperCase();if(t in G)return G[t]}return"DEBUG"}isCollectingEvaluationSummaries(){return this.collectEvaluationSummaries}isCollectingLoggerNames(){return this.collectLoggerNames}},Pr=new Ke,{version:Sr}=Ue()});return Ir();})();
"use strict";var window;(window||={}).reforgeNamespace=(()=>{var h=(e,r)=>()=>(r||e((r={exports:{}}).exports,r),r.exports);var Y=h(Q=>{"use strict";Object.defineProperty(Q,"__esModule",{value:!0});Q.default=Je;var I,Ge=new Uint8Array(16);function Je(){if(!I&&(I=typeof crypto<"u"&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!I))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return I(Ge)}});var ue=h(C=>{"use strict";Object.defineProperty(C,"__esModule",{value:!0});C.default=void 0;var Xe=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;C.default=Xe});var A=h(D=>{"use strict";Object.defineProperty(D,"__esModule",{value:!0});D.default=void 0;var ze=Qe(ue());function Qe(e){return e&&e.__esModule?e:{default:e}}function Ye(e){return typeof e=="string"&&ze.default.test(e)}var Ze=Ye;D.default=Ze});var T=h(P=>{"use strict";Object.defineProperty(P,"__esModule",{value:!0});P.default=void 0;P.unsafeStringify=ce;var et=tt(A());function tt(e){return e&&e.__esModule?e:{default:e}}var g=[];for(let e=0;e<256;++e)g.push((e+256).toString(16).slice(1));function ce(e,r=0){return g[e[r+0]]+g[e[r+1]]+g[e[r+2]]+g[e[r+3]]+"-"+g[e[r+4]]+g[e[r+5]]+"-"+g[e[r+6]]+g[e[r+7]]+"-"+g[e[r+8]]+g[e[r+9]]+"-"+g[e[r+10]]+g[e[r+11]]+g[e[r+12]]+g[e[r+13]]+g[e[r+14]]+g[e[r+15]]}function rt(e,r=0){let t=ce(e,r);if(!(0,et.default)(t))throw TypeError("Stringified UUID is invalid");return t}var nt=rt;P.default=nt});var de=h(M=>{"use strict";Object.defineProperty(M,"__esModule",{value:!0});M.default=void 0;var it=st(Y()),ot=T();function st(e){return e&&e.__esModule?e:{default:e}}var fe,Z,ee=0,te=0;function at(e,r,t){let n=r&&t||0,i=r||new Array(16);e=e||{};let o=e.node||fe,s=e.clockseq!==void 0?e.clockseq:Z;if(o==null||s==null){let d=e.random||(e.rng||it.default)();o==null&&(o=fe=[d[0]|1,d[1],d[2],d[3],d[4],d[5]]),s==null&&(s=Z=(d[6]<<8|d[7])&16383)}let l=e.msecs!==void 0?e.msecs:Date.now(),a=e.nsecs!==void 0?e.nsecs:te+1,u=l-ee+(a-te)/1e4;if(u<0&&e.clockseq===void 0&&(s=s+1&16383),(u<0||l>ee)&&e.nsecs===void 0&&(a=0),a>=1e4)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");ee=l,te=a,Z=s,l+=122192928e5;let c=((l&268435455)*1e4+a)%4294967296;i[n++]=c>>>24&255,i[n++]=c>>>16&255,i[n++]=c>>>8&255,i[n++]=c&255;let y=l/4294967296*1e4&268435455;i[n++]=y>>>8&255,i[n++]=y&255,i[n++]=y>>>24&15|16,i[n++]=y>>>16&255,i[n++]=s>>>8|128,i[n++]=s&255;for(let d=0;d<6;++d)i[n+d]=o[d];return r||(0,ot.unsafeStringify)(i)}var lt=at;M.default=lt});var re=h(j=>{"use strict";Object.defineProperty(j,"__esModule",{value:!0});j.default=void 0;var ut=ct(A());function ct(e){return e&&e.__esModule?e:{default:e}}function ft(e){if(!(0,ut.default)(e))throw TypeError("Invalid UUID");let r,t=new Uint8Array(16);return t[0]=(r=parseInt(e.slice(0,8),16))>>>24,t[1]=r>>>16&255,t[2]=r>>>8&255,t[3]=r&255,t[4]=(r=parseInt(e.slice(9,13),16))>>>8,t[5]=r&255,t[6]=(r=parseInt(e.slice(14,18),16))>>>8,t[7]=r&255,t[8]=(r=parseInt(e.slice(19,23),16))>>>8,t[9]=r&255,t[10]=(r=parseInt(e.slice(24,36),16))/1099511627776&255,t[11]=r/4294967296&255,t[12]=r>>>24&255,t[13]=r>>>16&255,t[14]=r>>>8&255,t[15]=r&255,t}var dt=ft;j.default=dt});var ne=h(x=>{"use strict";Object.defineProperty(x,"__esModule",{value:!0});x.URL=x.DNS=void 0;x.default=mt;var ht=T(),gt=pt(re());function pt(e){return e&&e.__esModule?e:{default:e}}function vt(e){e=unescape(encodeURIComponent(e));let r=[];for(let t=0;t<e.length;++t)r.push(e.charCodeAt(t));return r}var he="6ba7b810-9dad-11d1-80b4-00c04fd430c8";x.DNS=he;var ge="6ba7b811-9dad-11d1-80b4-00c04fd430c8";x.URL=ge;function mt(e,r,t){function n(i,o,s,l){var a;if(typeof i=="string"&&(i=vt(i)),typeof o=="string"&&(o=(0,gt.default)(o)),((a=o)===null||a===void 0?void 0:a.length)!==16)throw TypeError("Namespace must be array-like (16 iterable integer values, 0-255)");let u=new Uint8Array(16+i.length);if(u.set(o),u.set(i,o.length),u=t(u),u[6]=u[6]&15|r,u[8]=u[8]&63|128,s){l=l||0;for(let c=0;c<16;++c)s[l+c]=u[c];return s}return(0,ht.unsafeStringify)(u)}try{n.name=e}catch{}return n.DNS=he,n.URL=ge,n}});var ve=h(L=>{"use strict";Object.defineProperty(L,"__esModule",{value:!0});L.default=void 0;function _t(e){if(typeof e=="string"){let r=unescape(encodeURIComponent(e));e=new Uint8Array(r.length);for(let t=0;t<r.length;++t)e[t]=r.charCodeAt(t)}return yt(wt(bt(e),e.length*8))}function yt(e){let r=[],t=e.length*32,n="0123456789abcdef";for(let i=0;i<t;i+=8){let o=e[i>>5]>>>i%32&255,s=parseInt(n.charAt(o>>>4&15)+n.charAt(o&15),16);r.push(s)}return r}function pe(e){return(e+64>>>9<<4)+14+1}function wt(e,r){e[r>>5]|=128<<r%32,e[pe(r)-1]=r;let t=1732584193,n=-271733879,i=-1732584194,o=271733878;for(let s=0;s<e.length;s+=16){let l=t,a=n,u=i,c=o;t=p(t,n,i,o,e[s],7,-680876936),o=p(o,t,n,i,e[s+1],12,-389564586),i=p(i,o,t,n,e[s+2],17,606105819),n=p(n,i,o,t,e[s+3],22,-1044525330),t=p(t,n,i,o,e[s+4],7,-176418897),o=p(o,t,n,i,e[s+5],12,1200080426),i=p(i,o,t,n,e[s+6],17,-1473231341),n=p(n,i,o,t,e[s+7],22,-45705983),t=p(t,n,i,o,e[s+8],7,1770035416),o=p(o,t,n,i,e[s+9],12,-1958414417),i=p(i,o,t,n,e[s+10],17,-42063),n=p(n,i,o,t,e[s+11],22,-1990404162),t=p(t,n,i,o,e[s+12],7,1804603682),o=p(o,t,n,i,e[s+13],12,-40341101),i=p(i,o,t,n,e[s+14],17,-1502002290),n=p(n,i,o,t,e[s+15],22,1236535329),t=v(t,n,i,o,e[s+1],5,-165796510),o=v(o,t,n,i,e[s+6],9,-1069501632),i=v(i,o,t,n,e[s+11],14,643717713),n=v(n,i,o,t,e[s],20,-373897302),t=v(t,n,i,o,e[s+5],5,-701558691),o=v(o,t,n,i,e[s+10],9,38016083),i=v(i,o,t,n,e[s+15],14,-660478335),n=v(n,i,o,t,e[s+4],20,-405537848),t=v(t,n,i,o,e[s+9],5,568446438),o=v(o,t,n,i,e[s+14],9,-1019803690),i=v(i,o,t,n,e[s+3],14,-187363961),n=v(n,i,o,t,e[s+8],20,1163531501),t=v(t,n,i,o,e[s+13],5,-1444681467),o=v(o,t,n,i,e[s+2],9,-51403784),i=v(i,o,t,n,e[s+7],14,1735328473),n=v(n,i,o,t,e[s+12],20,-1926607734),t=m(t,n,i,o,e[s+5],4,-378558),o=m(o,t,n,i,e[s+8],11,-2022574463),i=m(i,o,t,n,e[s+11],16,1839030562),n=m(n,i,o,t,e[s+14],23,-35309556),t=m(t,n,i,o,e[s+1],4,-1530992060),o=m(o,t,n,i,e[s+4],11,1272893353),i=m(i,o,t,n,e[s+7],16,-155497632),n=m(n,i,o,t,e[s+10],23,-1094730640),t=m(t,n,i,o,e[s+13],4,681279174),o=m(o,t,n,i,e[s],11,-358537222),i=m(i,o,t,n,e[s+3],16,-722521979),n=m(n,i,o,t,e[s+6],23,76029189),t=m(t,n,i,o,e[s+9],4,-640364487),o=m(o,t,n,i,e[s+12],11,-421815835),i=m(i,o,t,n,e[s+15],16,530742520),n=m(n,i,o,t,e[s+2],23,-995338651),t=_(t,n,i,o,e[s],6,-198630844),o=_(o,t,n,i,e[s+7],10,1126891415),i=_(i,o,t,n,e[s+14],15,-1416354905),n=_(n,i,o,t,e[s+5],21,-57434055),t=_(t,n,i,o,e[s+12],6,1700485571),o=_(o,t,n,i,e[s+3],10,-1894986606),i=_(i,o,t,n,e[s+10],15,-1051523),n=_(n,i,o,t,e[s+1],21,-2054922799),t=_(t,n,i,o,e[s+8],6,1873313359),o=_(o,t,n,i,e[s+15],10,-30611744),i=_(i,o,t,n,e[s+6],15,-1560198380),n=_(n,i,o,t,e[s+13],21,1309151649),t=_(t,n,i,o,e[s+4],6,-145523070),o=_(o,t,n,i,e[s+11],10,-1120210379),i=_(i,o,t,n,e[s+2],15,718787259),n=_(n,i,o,t,e[s+9],21,-343485551),t=E(t,l),n=E(n,a),i=E(i,u),o=E(o,c)}return[t,n,i,o]}function bt(e){if(e.length===0)return[];let r=e.length*8,t=new Uint32Array(pe(r));for(let n=0;n<r;n+=8)t[n>>5]|=(e[n/8]&255)<<n%32;return t}function E(e,r){let t=(e&65535)+(r&65535);return(e>>16)+(r>>16)+(t>>16)<<16|t&65535}function Et(e,r){return e<<r|e>>>32-r}function U(e,r,t,n,i,o){return E(Et(E(E(r,e),E(n,o)),i),t)}function p(e,r,t,n,i,o,s){return U(r&t|~r&n,e,r,i,o,s)}function v(e,r,t,n,i,o,s){return U(r&n|t&~n,e,r,i,o,s)}function m(e,r,t,n,i,o,s){return U(r^t^n,e,r,i,o,s)}function _(e,r,t,n,i,o,s){return U(t^(r|~n),e,r,i,o,s)}var xt=_t;L.default=xt});var _e=h(q=>{"use strict";Object.defineProperty(q,"__esModule",{value:!0});q.default=void 0;var Ot=me(ne()),Rt=me(ve());function me(e){return e&&e.__esModule?e:{default:e}}var At=(0,Ot.default)("v3",48,Rt.default),Pt=At;q.default=Pt});var ye=h(N=>{"use strict";Object.defineProperty(N,"__esModule",{value:!0});N.default=void 0;var Tt=typeof crypto<"u"&&crypto.randomUUID&&crypto.randomUUID.bind(crypto),St={randomUUID:Tt};N.default=St});var Ee=h(V=>{"use strict";Object.defineProperty(V,"__esModule",{value:!0});V.default=void 0;var we=be(ye()),It=be(Y()),Ct=T();function be(e){return e&&e.__esModule?e:{default:e}}function Dt(e,r,t){if(we.default.randomUUID&&!r&&!e)return we.default.randomUUID();e=e||{};let n=e.random||(e.rng||It.default)();if(n[6]=n[6]&15|64,n[8]=n[8]&63|128,r){t=t||0;for(let i=0;i<16;++i)r[t+i]=n[i];return r}return(0,Ct.unsafeStringify)(n)}var Mt=Dt;V.default=Mt});var xe=h(k=>{"use strict";Object.defineProperty(k,"__esModule",{value:!0});k.default=void 0;function jt(e,r,t,n){switch(e){case 0:return r&t^~r&n;case 1:return r^t^n;case 2:return r&t^r&n^t&n;case 3:return r^t^n}}function ie(e,r){return e<<r|e>>>32-r}function Ut(e){let r=[1518500249,1859775393,2400959708,3395469782],t=[1732584193,4023233417,2562383102,271733878,3285377520];if(typeof e=="string"){let s=unescape(encodeURIComponent(e));e=[];for(let l=0;l<s.length;++l)e.push(s.charCodeAt(l))}else Array.isArray(e)||(e=Array.prototype.slice.call(e));e.push(128);let n=e.length/4+2,i=Math.ceil(n/16),o=new Array(i);for(let s=0;s<i;++s){let l=new Uint32Array(16);for(let a=0;a<16;++a)l[a]=e[s*64+a*4]<<24|e[s*64+a*4+1]<<16|e[s*64+a*4+2]<<8|e[s*64+a*4+3];o[s]=l}o[i-1][14]=(e.length-1)*8/Math.pow(2,32),o[i-1][14]=Math.floor(o[i-1][14]),o[i-1][15]=(e.length-1)*8&4294967295;for(let s=0;s<i;++s){let l=new Uint32Array(80);for(let f=0;f<16;++f)l[f]=o[s][f];for(let f=16;f<80;++f)l[f]=ie(l[f-3]^l[f-8]^l[f-14]^l[f-16],1);let a=t[0],u=t[1],c=t[2],y=t[3],d=t[4];for(let f=0;f<80;++f){let R=Math.floor(f/20),S=ie(a,5)+jt(R,u,c,y)+d+r[R]+l[f]>>>0;d=y,y=c,c=ie(u,30)>>>0,u=a,a=S}t[0]=t[0]+a>>>0,t[1]=t[1]+u>>>0,t[2]=t[2]+c>>>0,t[3]=t[3]+y>>>0,t[4]=t[4]+d>>>0}return[t[0]>>24&255,t[0]>>16&255,t[0]>>8&255,t[0]&255,t[1]>>24&255,t[1]>>16&255,t[1]>>8&255,t[1]&255,t[2]>>24&255,t[2]>>16&255,t[2]>>8&255,t[2]&255,t[3]>>24&255,t[3]>>16&255,t[3]>>8&255,t[3]&255,t[4]>>24&255,t[4]>>16&255,t[4]>>8&255,t[4]&255]}var Lt=Ut;k.default=Lt});var Re=h($=>{"use strict";Object.defineProperty($,"__esModule",{value:!0});$.default=void 0;var qt=Oe(ne()),Nt=Oe(xe());function Oe(e){return e&&e.__esModule?e:{default:e}}var Vt=(0,qt.default)("v5",80,Nt.default),kt=Vt;$.default=kt});var Ae=h(F=>{"use strict";Object.defineProperty(F,"__esModule",{value:!0});F.default=void 0;var $t="00000000-0000-0000-0000-000000000000";F.default=$t});var Pe=h(K=>{"use strict";Object.defineProperty(K,"__esModule",{value:!0});K.default=void 0;var Ft=Kt(A());function Kt(e){return e&&e.__esModule?e:{default:e}}function Ht(e){if(!(0,Ft.default)(e))throw TypeError("Invalid UUID");return parseInt(e.slice(14,15),16)}var Bt=Ht;K.default=Bt});var Te=h(w=>{"use strict";Object.defineProperty(w,"__esModule",{value:!0});Object.defineProperty(w,"NIL",{enumerable:!0,get:function(){return zt.default}});Object.defineProperty(w,"parse",{enumerable:!0,get:function(){return er.default}});Object.defineProperty(w,"stringify",{enumerable:!0,get:function(){return Zt.default}});Object.defineProperty(w,"v1",{enumerable:!0,get:function(){return Wt.default}});Object.defineProperty(w,"v3",{enumerable:!0,get:function(){return Gt.default}});Object.defineProperty(w,"v4",{enumerable:!0,get:function(){return Jt.default}});Object.defineProperty(w,"v5",{enumerable:!0,get:function(){return Xt.default}});Object.defineProperty(w,"validate",{enumerable:!0,get:function(){return Yt.default}});Object.defineProperty(w,"version",{enumerable:!0,get:function(){return Qt.default}});var Wt=b(de()),Gt=b(_e()),Jt=b(Ee()),Xt=b(Re()),zt=b(Ae()),Qt=b(Pe()),Yt=b(A()),Zt=b(T()),er=b(re());function b(e){return e&&e.__esModule?e:{default:e}}});var Cr=h((Xr,We)=>{var X=Object.defineProperty,tr=Object.defineProperties,rr=Object.getOwnPropertyDescriptor,nr=Object.getOwnPropertyDescriptors,Ie=Object.getOwnPropertyNames,B=Object.getOwnPropertySymbols,ae=Object.prototype.hasOwnProperty,Ce=Object.prototype.propertyIsEnumerable,Se=(e,r,t)=>r in e?X(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t,O=(e,r)=>{for(var t in r||(r={}))ae.call(r,t)&&Se(e,t,r[t]);if(B)for(var t of B(r))Ce.call(r,t)&&Se(e,t,r[t]);return e},W=(e,r)=>tr(e,nr(r)),ir=(e,r)=>{var t={};for(var n in e)ae.call(e,n)&&r.indexOf(n)<0&&(t[n]=e[n]);if(e!=null&&B)for(var n of B(e))r.indexOf(n)<0&&Ce.call(e,n)&&(t[n]=e[n]);return t},or=(e,r)=>function(){return r||(0,e[Ie(e)[0]])((r={exports:{}}).exports,r),r.exports},sr=(e,r)=>{for(var t in r)X(e,t,{get:r[t],enumerable:!0})},ar=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of Ie(r))!ae.call(e,i)&&i!==t&&X(e,i,{get:()=>r[i],enumerable:!(n=rr(r,i))||n.enumerable});return e},lr=e=>ar(X({},"__esModule",{value:!0}),e),H=(e,r,t)=>new Promise((n,i)=>{var o=a=>{try{l(t.next(a))}catch(u){i(u)}},s=a=>{try{l(t.throw(a))}catch(u){i(u)}},l=a=>a.done?n(a.value):Promise.resolve(a.value).then(o,s);l((t=t.apply(e,r)).next())}),De=or({"package.json"(e,r){r.exports={packageManager:"yarn@4.11.0",name:"@reforge-com/javascript",version:"0.0.5",description:"Feature Flags & Dynamic Configuration as a Service",main:"dist/index.cjs",module:"dist/index.mjs",types:"dist/index.d.ts",author:"Jeffrey Chupp",license:"ISC",devDependencies:{"@types/eslint-plugin-jsx-a11y":"^6","@types/express":"^4.17.13","@types/jest":"^28.1.6","@types/uuid":"^9.0.5","@typescript-eslint/eslint-plugin":"^5.33.0","@typescript-eslint/parser":"^5.33.0",esbuild:"^0.25.11",eslint:"^8.21.0","eslint-config-airbnb":"^19.0.4","eslint-config-airbnb-typescript":"^17.0.0","eslint-config-prettier":"^8.8.0","eslint-plugin-import":"^2.26.0","eslint-plugin-jest":"^26.8.0","eslint-plugin-jsx-a11y":"^6.10.2","eslint-plugin-react":"^7.37.5",jest:"^29.0.0","jest-environment-jsdom":"^30.2.0","jest-fetch-mock":"^3.0.3",prettier:"^3.0.0","ts-jest":"^29.1.1","ts-node":"^10.9.1",tsup:"^8.0.2",typescript:"^5.1.6"},scripts:{build:"rm -rf dist/ && tsup",dev:"tsup --watch",bundle:"esbuild --minify --target=esnext --bundle --outfile=dist/reforge.bundle.js --global-name=window.reforgeNamespace dist/index.cjs && echo 'window.reforge = window.reforgeNamespace.reforge' >> dist/reforge.bundle.js",lint:"eslint --ext .ts,.tsx src/","lint:fix":"eslint --fix --ext .ts,.tsx src/",prettier:"prettier . -l","prettier:fix":"prettier --write .",test:"jest --verbose"},repository:{type:"git",url:"https://github.com/ReforgeHQ/sdk-javascript.git"},keywords:["feature-flags","config"],bugs:{url:"https://github.com/ReforgeHQ/sdk-javascript/issues"},homepage:"https://github.com/ReforgeHQ/sdk-javascript#readme",dependencies:{uuid:"^9.0.1"},exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.mjs",require:"./dist/index.cjs"}}}}}),Me={};sr(Me,{Config:()=>z,Context:()=>oe,LogLevel:()=>J,Reforge:()=>Be,getLogLevelSeverity:()=>mr,prefetchReforgeConfig:()=>Sr,reforge:()=>Tr,shouldLogAtLevel:()=>Le,version:()=>Ir});We.exports=lr(Me);var ur=Te(),cr=e=>({configRowIndex:parseInt(e.configRowIndex,10),conditionalValueIndex:parseInt(e.conditionalValueIndex,10),type:e.type,configId:e.id}),je=(e,r,t)=>{let n=e[r];switch(r){case"json":try{return JSON.parse(n)}catch(i){return console.error(`Error parsing JSON from Reforge config ${t}`,i,n),e[r]}case"duration":{let i=n;return{ms:i.millis,seconds:i.millis/1e3}}default:return n}},fr=e=>{let r={};return Object.keys(e.evaluations).forEach(t=>{let n=e.evaluations[t],i=Object.keys(n.value)[0];r[t]=new z(t,je(n.value,i,t),i,n.value,n.configEvaluationMetadata?cr(n.configEvaluationMetadata):void 0)}),r},dr=e=>{let r={};return Object.keys(e).forEach(t=>{let n=typeof e[t];r[t]=new z(t,je({[n]:e[t]},n,t),n)}),r},z=class{constructor(e,r,t,n,i){this.key=e,this.value=r,this.type=t,this.rawValue=n,this.configEvaluationMetadata=i}static digest(e){return e===void 0&&console.trace("Config.digest called with undefined payload"),"evaluations"in e?fr(e):dr(e)}},hr=e=>{if(typeof window<"u"){if(typeof TextEncoder>"u")return window.btoa(e);let r=new TextEncoder().encode(e),t=Array.from(r,n=>String.fromCodePoint(n)).join("");return btoa(t)}return Buffer.from(e).toString("base64")},Ue=hr,gr=(e,r)=>{let t=Object.keys(e),n=Object.keys(r);return t.length!==n.length?!1:t.every(i=>{let o=e[i],s=r[i],l=Object.keys(o),a=Object.keys(s);return l.length!==a.length?!1:l.every(u=>{let c=o[u],y=s[u];return c===y})})},pr=e=>typeof e=="string"?"string":typeof e=="number"?Number.isInteger(e)?"int":"double":"bool",oe=class{constructor(e){Object.values(e).every(r=>typeof r=="object")||console.error("Context must be an object where the value of each key is also an object"),Object.values(e).some(r=>Object.values(r).some(t=>typeof t=="object"&&t!==null))&&console.error("Nested objects are not supported in context values at this time"),this.contexts=e}equals(e){return gr(this.contexts,e.contexts)}encode(){let e=Object.keys(this.contexts).map(r=>{let t={};return Object.keys(this.contexts[r]).forEach(n=>{t[n]={[pr(this.contexts[r][n])]:this.contexts[r][n]}}),{type:r,values:t}});return encodeURIComponent(Ue(JSON.stringify({contexts:e})))}},vr=class{constructor(e,r=2,t=2){this.maxDelay=e,this.multiplier=t,this.delay=r}call(){let e=this.delay;return this.delay=Math.min(this.delay*this.multiplier,this.maxDelay),e*1e3}},se="log-level",G={TRACE:1,DEBUG:2,INFO:3,WARN:4,ERROR:5,FATAL:6},J=(e=>(e.TRACE="TRACE",e.DEBUG="DEBUG",e.INFO="INFO",e.WARN="WARN",e.ERROR="ERROR",e.FATAL="FATAL",e))(J||{}),mr=e=>G[e],Le=(e,r)=>G[e]<=G[r],_r=({loggerName:e,desiredLevel:r,defaultLevel:t,get:n})=>{let i=`${se}.${e}`,o=n(i);return o?G[o.toString().toUpperCase()]<=r:t<=r},qe=class Ne{constructor(r,t,n){this.data=new Map,this.client=r,this.name=t,this.startAt=new Date,this.startPeriodicSync(n)}stop(){clearTimeout(this.timeoutID)}sync(){if(this.data.size===0)return;this.logInternal(`${this.name} syncing ${this.data.size} items`);let r=this.startAt;this.startAt=new Date,this.flush(this.prepareData(),r)}prepareData(){let r=new Map(this.data);return this.data.clear(),r}startPeriodicSync(r){this.startAt=new Date,this.syncInterval=Ne.calculateSyncInterval(r),this.scheduleNextSync()}scheduleNextSync(){let r=this.syncInterval();this.timeoutID=setTimeout(()=>{this.sync(),this.scheduleNextSync()},r)}static calculateSyncInterval(r){if(r!==void 0)return()=>r;let t=new vr(300,8);return()=>t.call()}logInternal(r){let t=`${this.client.clientNameString}.reforge.${this.name}`;this.client.shouldLog({loggerName:t,desiredLevel:2,defaultLevel:5},!1)&&console.log(`${t}: ${r}`)}},yr=e=>e.rawValue&&(e.type==="duration"||e.type==="json")?e.type==="json"?{json:e.rawValue[e.type]}:e.rawValue[e.type]:e.type==="stringList"?{values:e.value}:e.value,wr=(e,r)=>W(O({},r),{selectedValue:{[e.type]:yr(e)},count:0}),br=class Ve extends qe{constructor(r,t,n){super(r,"EvaluationSummaryAggregator",n??3e4),this.maxKeys=t}record(r){if(!(this.data.size>=this.maxKeys)&&r?.configEvaluationMetadata){let t=r.configEvaluationMetadata,{type:n}=t,i=ir(t,["type"]),o=`${r.key},${n}`;this.data.has(o)||this.data.set(o,wr(r,i));let s=this.data.get(o);s&&(s.count+=1)}}flush(r,t){var n;let i={start:t.getTime(),end:new Date().getTime(),summaries:Ve.summaries(r)};(n=this.client.telemetryUploader)==null||n.post(this.events(i))}static summaries(r){return Array.from(r).map(t=>{let[n,i]=t[0].split(","),s=[t[1]];return{key:n,type:i,counters:s}})}events(r){let t={summaries:r};return{instanceHash:this.client.instanceHash,events:[t]}}},ke=(e,r)=>({Authorization:`Basic ${Ue(`u:${e}`)}`,"X-Reforge-SDK-Version":r}),$e=1e4,Er=["https://primary.reforge.com/api/v2","https://secondary.reforge.com/api/v2"],xr=2e3,Fe=class{constructor({sdkKey:e,context:r,endpoints:t=void 0,timeout:n,collectContextMode:i="PERIODIC_EXAMPLE",clientVersion:o=""}){this.collectContextMode="PERIODIC_EXAMPLE",this.isAborted=!1,this.sdkKey=e,this.context=r,this.endpoints=t||Er,this.timeout=n||$e,this.collectContextMode=i,this.clientVersion=o}url(e){return`${e}/configs/eval-with-context/${this.context.encode()}?collectContextMode=${this.collectContextMode}`}loadFromEndpoint(e,r,t,n){this.abortController=new AbortController;let{signal:i}=this.abortController;this.isAborted=!1;let o=this.endpoints[e],s=this.url(o);fetch(s,O({signal:i},r)).then(a=>{if(this.clearAbortTimeout(),a.ok)return a.json();throw new Error(`${a.status} ${a.statusText}`)}).then(a=>{if(!("evaluations"in a))throw new Error(`Invalid payload:${JSON.stringify(a)}`);t(a)}).catch(a=>{this.clearAbortTimeout(),e<this.endpoints.length-1?this.loadFromEndpoint(e+1,r,t,n):n(a)});let l=e<this.endpoints.length-1?Math.min(this.timeout,xr):this.timeout;this.abortTimeoutId=setTimeout(()=>{var a;this.isAborted||(this.isAborted=!0,(a=this.abortController)==null||a.abort())},l)}load(){var e;this.isAborted||(this.isAborted=!0,(e=this.abortController)==null||e.abort());let r={headers:ke(this.sdkKey,this.clientVersion)},t=typeof window<"u"?window.REFORGE_SDK_PREFETCH_PROMISE:void 0;return t&&t instanceof Promise?(window.REFORGE_SDK_PREFETCH_PROMISE=void 0,t.catch(()=>new Promise((i,o)=>{this.loadFromEndpoint(0,r,i,o)}))):new Promise((i,o)=>{this.loadFromEndpoint(0,r,i,o)})}clearAbortTimeout(){clearTimeout(this.abortTimeoutId)}},Or=class Ke{constructor({sdkKey:r,apiEndpoint:t=void 0,timeout:n,clientVersion:i}){this.sdkKey=r,this.apiEndpoint=t||"https://telemetry.reforge.com/api/v1",this.timeout=n||$e,this.clientVersion=i}clearAbortTimeout(){clearTimeout(this.abortTimeoutId)}static postUrl(r){return`${r}/telemetry`}postToEndpoint(r,t,n){let i=new AbortController,o=i?.signal,s=!1,l=Ke.postUrl(this.apiEndpoint);fetch(l,O({signal:o},r)).then(a=>(this.clearAbortTimeout(),a.ok?a.json():(console.warn(`Reforge warning: Error uploading telemetry ${a.status} ${a.statusText}`),a.status))).then(a=>{t(a)}).catch(a=>{if(this.clearAbortTimeout(),a.name==="AbortError"){try{console.debug("Reforge telemetry request aborted")}catch{}t({status:"aborted"});return}n(a)}),this.abortTimeoutId=setTimeout(()=>{s||(s=!0,i.abort())},this.timeout)}post(r){let t={method:"POST",headers:W(O({},ke(this.sdkKey,this.clientVersion)),{"Content-Type":"application/json",Accept:"application/json"}),body:JSON.stringify(r),keepalive:!0};return new Promise((i,o)=>{this.postToEndpoint(t,i,o)})}},Rr={1:"traces",2:"debugs",3:"infos",4:"warns",5:"errors",6:"fatals"},Ar=class extends qe{constructor(e,r,t){super(e,"LoggerAggregator",t??3e4),this.maxLoggers=r}record(e,r){if(this.data.size>=this.maxLoggers)return;this.data.has(e)||this.data.set(e,{loggerName:e,traces:0,debugs:0,infos:0,warns:0,errors:0,fatals:0});let t=this.data.get(e);if(t){let n=Rr[r];t[n]+=1}}flush(e,r){var t;let n={startAt:r.getTime(),endAt:new Date().getTime(),loggers:Array.from(e.values())};(t=this.client.telemetryUploader)==null||t.post(this.events(n))}events(e){let r={loggers:e};return{instanceHash:this.client.instanceHash,events:[r]}}},{version:He}=De(),Pr=class{constructor(e){this.reforge=e}log(e,r){let t=this.reforge.getLogLevel("");if(Le(t,r))switch(r){case"TRACE":case"DEBUG":console.debug(e);break;case"INFO":console.info(e);break;case"WARN":console.warn(e);break;case"ERROR":case"FATAL":console.error(e);break;default:console.error(e)}}trace(e){this.log(e,"TRACE")}debug(e){this.log(e,"DEBUG")}info(e){this.log(e,"INFO")}warn(e){this.log(e,"WARN")}error(e){this.log(e,"ERROR")}fatal(e){this.log(e,"FATAL")}},Be=class{constructor(){this._configs={},this._pollCount=0,this._pollStatus={status:"not-started"},this._pollTimeoutId=void 0,this._instanceHash=(0,ur.v4)(),this.collectEvaluationSummaries=!0,this.collectLoggerNames=!1,this.clientNameString="sdk-javascript",this.loaded=!1,this.afterEvaluationCallback=(()=>{}),this._context=new oe({}),this._loggerKey="log-levels.default",this.logger=new Pr(this)}init(e){return H(this,arguments,function*({sdkKey:r,context:t,endpoints:n=void 0,apiEndpoint:i,timeout:o=void 0,afterEvaluationCallback:s=()=>{},collectEvaluationSummaries:l=!0,collectLoggerNames:a=!1,collectContextMode:u="PERIODIC_EXAMPLE",clientNameString:c="sdk-javascript",clientVersionString:y=He,loggerKey:d="log-levels.default"}){let f=t??this.context;if(!f)throw new Error("Context must be provided");this._context=f,this._loggerKey=d,this.clientNameString=c;let R=`${c}-${y}`;return this.loader=new Fe({sdkKey:r,context:f,endpoints:n,timeout:o,collectContextMode:u,clientVersion:R}),this._telemetryUploader=new Or({sdkKey:r,apiEndpoint:i,timeout:o,clientVersion:R}),this.collectEvaluationSummaries=l,l&&(this.evalutionSummaryAggregator=new br(this,1e5)),this.collectLoggerNames=a,a&&(this.loggerAggregator=new Ar(this,1e5)),(l||a)&&typeof window<"u"&&typeof window.addEventListener=="function"&&window.addEventListener("beforeunload",()=>{var S,le;(S=this.evalutionSummaryAggregator)==null||S.sync(),(le=this.loggerAggregator)==null||le.sync()}),this.afterEvaluationCallback=s,this.load()})}extract(){return Object.entries(this._configs).reduce((e,[r,t])=>W(O({},e),{[r]:t.value}),{})}hydrate(e){this.setConfigPrivate(e)}get context(){return this._context}get instanceHash(){return this._instanceHash}get pollTimeoutId(){return this._pollTimeoutId}get pollCount(){return this._pollCount}get pollStatus(){return this._pollStatus}get telemetryUploader(){return this._telemetryUploader}load(){return H(this,null,function*(){if(!this.loader||!this.context)throw new Error("Reforge not initialized. Call init() first.");if(globalThis&&globalThis._reforgeBootstrap){let e=globalThis._reforgeBootstrap,r=new oe(e.context);if(this.context.equals(r))return this.setConfigPrivate({evaluations:e.evaluations}),Promise.resolve()}return this.loader.context=this.context,this.loader.load().then(e=>{this.setConfigPrivate(e)}).finally(()=>{this.pollStatus.status==="running"&&(this._pollCount+=1)})})}updateContext(e,r=!1){return H(this,null,function*(){if(!this.loader)throw new Error("Reforge not initialized. Call init() first.");return this._context=e,r?Promise.resolve():this.load()})}poll(e){return H(this,arguments,function*({frequencyInMs:r}){if(!this.loader)throw new Error("Reforge not initialized. Call init() first.");return this.stopPolling(),this._pollStatus={status:"pending"},this.loader.load().finally(()=>{this.doPolling({frequencyInMs:r})})})}doPolling({frequencyInMs:e}){this._pollTimeoutId=setTimeout(()=>{this.load().finally(()=>{this.pollStatus.status==="running"&&this.doPolling({frequencyInMs:e})})},e),this._pollStatus={status:"running",frequencyInMs:e}}stopPolling(){this.pollTimeoutId&&(clearTimeout(this.pollTimeoutId),this._pollTimeoutId=void 0),this._pollStatus={status:"stopped"}}stopTelemetry(){var e,r;this.telemetryUploader&&((e=this.evalutionSummaryAggregator)==null||e.stop(),(r=this.loggerAggregator)==null||r.stop())}setConfigPrivate(e){this._configs=z.digest(e),this.loaded=!0}isEnabled(e){return this.get(e)===!0}get(e){if(!this.loaded){e.startsWith(se)||console.warn(`Reforge warning: The client has not finished loading data yet. Unable to look up actual value for key "${e}".`);return}let r=this._configs[e],t=r?.value;return e.startsWith(se)||(this.collectEvaluationSummaries&&setTimeout(()=>{var n;return(n=this.evalutionSummaryAggregator)==null?void 0:n.record(r)}),setTimeout(()=>this.afterEvaluationCallback(e,t,this.context))),t}getDuration(e){let r=this.get(e);if(r){if(!Object.prototype.hasOwnProperty.call(r,"seconds")||!Object.prototype.hasOwnProperty.call(r,"ms"))throw new Error(`Value for key "${e}" is not a duration`);return r}}shouldLog(e,r=!0){if(this.collectLoggerNames){let t=()=>{var n;return(n=this.loggerAggregator)==null?void 0:n.record(e.loggerName,e.desiredLevel)};r?setTimeout(t):t()}return _r(W(O({},e),{get:this.get.bind(this)}))}getLogLevel(e){let r=this.get(this._loggerKey);if(r&&typeof r=="string"){let t=r.toUpperCase();if(t in J)return J[t]}return"DEBUG"}isCollectingEvaluationSummaries(){return this.collectEvaluationSummaries}isCollectingLoggerNames(){return this.collectLoggerNames}},Tr=new Be;function Sr({sdkKey:e,context:r,endpoints:t=void 0,timeout:n=void 0,collectContextMode:i="PERIODIC_EXAMPLE",clientNameString:o="sdk-javascript",clientVersionString:s=He}){let l=`${o}-${s}`,a=new Fe({sdkKey:e,context:r,endpoints:t,timeout:n,collectContextMode:i,clientVersion:l});window.REFORGE_SDK_PREFETCH_PROMISE=a.load()}var{version:Ir}=De()});return Cr();})();
window.reforge = window.reforgeNamespace.reforge
{
"packageManager": "yarn@4.9.2",
"packageManager": "yarn@4.11.0",
"name": "@reforge-com/javascript",
"version": "0.0.4",
"version": "0.0.5",
"description": "Feature Flags & Dynamic Configuration as a Service",

@@ -28,2 +28,3 @@ "main": "dist/index.cjs",

"jest": "^29.0.0",
"jest-environment-jsdom": "^30.2.0",
"jest-fetch-mock": "^3.0.3",

@@ -30,0 +31,0 @@ "prettier": "^3.0.0",

@@ -68,2 +68,22 @@ # @reforge-com/javascript

## Prefetching
To avoid a request waterfall, you can start fetching the configuration early in your app's
lifecycle, before the React SDK or `reforge.init()` is called.
```javascript
import { prefetchReforgeConfig, Context } from "@reforge-com/javascript";
prefetchReforgeConfig({
sdkKey: "1234",
context: new Context({
user: {
email: "test@example.com",
},
}),
});
```
When you later call `reforge.init()`, it will automatically use the prefetched promise if available.
## Client API

@@ -70,0 +90,0 @@