{"version":3,"sources":["../src/prefab.ts","../src/config.ts","../src/base64Encode.ts","../src/context.ts","../src/exponentialBackoff.ts","../src/periodicSync.ts","../src/evaluationSummaryAggregator.ts","../src/apiHelpers.ts","../src/loader.ts","../src/logger.ts","../src/telemetryUploader.ts","../src/loggerAggregator.ts","../src/version.ts"],"sourcesContent":["import { v4 as uuid } from \"uuid\";\n\nimport { Config, EvaluationPayload, RawConfigWithoutTypes } from \"./config\";\nimport ConfigValue, { type Duration } from \"./configValue\";\nimport Context, { Contexts } from \"./context\";\nimport { EvaluationSummaryAggregator } from \"./evaluationSummaryAggregator\";\nimport Loader, { CollectContextModeType } from \"./loader\";\nimport { PREFIX as loggerPrefix, isValidLogLevel, Severity, shouldLog } from \"./logger\";\nimport TelemetryUploader from \"./telemetryUploader\";\nimport { LoggerAggregator } from \"./loggerAggregator\";\nimport version from \"./version\";\n\ntype EvaluationCallback = (key: string, value: ConfigValue, context: Context | undefined) => void;\n\nexport interface PrefabBootstrap {\n  evaluations: EvaluationPayload;\n  context: Contexts;\n}\n\ntype InitParams = {\n  apiKey: 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};\n\ntype PollStatus =\n  | { status: \"not-started\" }\n  | { status: \"pending\" }\n  | { status: \"stopped\" }\n  | { status: \"running\"; frequencyInMs: number };\n\nexport class Prefab {\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 = \"prefab-cloud-js\";\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  async init({\n    apiKey,\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 = \"prefab-cloud-js\",\n    clientVersionString = version,\n  }: InitParams) {\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\n    this.clientNameString = clientNameString;\n    const clientNameAndVersionString = `${clientNameString}-${clientVersionString}`;\n\n    this.loader = new Loader({\n      apiKey,\n      context,\n      endpoints,\n      timeout,\n      collectContextMode,\n      clientVersion: clientNameAndVersionString,\n    });\n\n    this._telemetryUploader = new TelemetryUploader({\n      apiKey,\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  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  hydrate(rawValues: RawConfigWithoutTypes | EvaluationPayload): void {\n    this.setConfigPrivate(rawValues);\n  }\n\n  get configs(): Record<string, Config> {\n    return this._configs;\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(\"Prefab not initialized. Call init() first.\");\n    }\n\n    /* eslint-disable no-underscore-dangle */\n    if (globalThis && (globalThis as any)._prefabBootstrap) {\n      /* eslint-disable no-underscore-dangle */\n      const prefabBootstrap = (globalThis as any)._prefabBootstrap as PrefabBootstrap;\n      const bootstrapContext = new Context(prefabBootstrap.context);\n\n      if (this.context.equals(bootstrapContext)) {\n        this.setConfigPrivate({ evaluations: prefabBootstrap.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(\"Prefab 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(\"Prefab 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  setConfig(rawValues: RawConfigWithoutTypes | EvaluationPayload) {\n    // Log message in yellow without adding chalk dependency\n    console.warn(\"\\x1b[33m%s\\x1b[0m\", 'Deprecated: Use \"prefab.hydrate\" instead');\n\n    this.setConfigPrivate(rawValues);\n  }\n\n  private setConfigPrivate(rawValues: RawConfigWithoutTypes | EvaluationPayload) {\n    this._configs = Config.digest(rawValues);\n    this.loaded = true;\n  }\n\n  isEnabled(key: string): boolean {\n    return this.get(key) === true;\n  }\n\n  get(key: string): ConfigValue {\n    if (!this.loaded) {\n      if (!key.startsWith(loggerPrefix)) {\n        // eslint-disable-next-line no-console\n        console.warn(\n          `Prefab 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(key: string): 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: Omit<Parameters<typeof shouldLog>[0], \"get\">, async = true): boolean {\n    if (this.collectLoggerNames && isValidLogLevel(args.desiredLevel)) {\n      const record = () =>\n        this.loggerAggregator?.record(args.loggerName, args.desiredLevel.toUpperCase() as Severity);\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  isCollectingEvaluationSummaries(): boolean {\n    return this.collectEvaluationSummaries;\n  }\n\n  isCollectingLoggerNames(): boolean {\n    return this.collectLoggerNames;\n  }\n}\n\nexport const prefab = new Prefab();\n","import ConfigKey from \"./configKey\";\nimport ConfigValue from \"./configValue\";\n\nexport type RawConfigWithoutTypes = { [key: string]: any };\n\nexport type ConfigEvaluationMetadata = {\n  configRowIndex: number;\n  conditionalValueIndex: number;\n  type: string;\n  configId: string;\n};\n\ntype APIKeyMetadata = {\n  id: string | number;\n};\n\ntype Duration = {\n  definition: string;\n  millis: number;\n};\n\ntype Value = {\n  [key: string]: number | string | string[] | boolean | Duration;\n};\n\ntype Evaluation = {\n  value: Value;\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 = (value: Value, type: string, key: string): ConfigValue => {\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 Prefab 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];\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];\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  key: ConfigKey;\n\n  value: ConfigValue;\n\n  rawValue: Value | undefined;\n\n  type: string;\n\n  configEvaluationMetadata: ConfigEvaluationMetadata | undefined;\n\n  constructor(\n    key: ConfigKey,\n    value: ConfigValue,\n    type: string,\n    rawValue?: Value,\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 Key from \"./key\";\nimport ContextValue from \"./contextValue\";\nimport base64Encode from \"./base64Encode\";\n\nexport type Contexts = { [key: Key]: Record<string, ContextValue> };\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 initialDelay: number;\n\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.initialDelay = initialDelay;\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 { ExponentialBackoff } from \"./exponentialBackoff\";\nimport { type prefab } from \"./prefab\";\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 prefab;\n\n  private name: string;\n\n  private timeoutID: ReturnType<typeof setTimeout> | undefined;\n\n  constructor(client: typeof prefab, 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}.prefab.${this.name}`;\n\n    if (\n      this.client.shouldLog(\n        {\n          loggerName,\n          desiredLevel: \"debug\",\n          defaultLevel: \"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, ConfigEvaluationMetadata } from \"./config\";\nimport { type prefab } from \"./prefab\";\n\nexport type ConfigEvaluationCounter = Omit<ConfigEvaluationMetadata, \"type\"> & {\n  selectedValue: any;\n  count: number;\n};\n\ntype ConfigEvaluationSummary = {\n  key: string;\n  type: string; // FEATURE_FLAG, CONFIG, etc\n  counters: ConfigEvaluationCounter[];\n};\n\ntype ConfigEvaluationSummaries = {\n  start: number;\n  end: number;\n  summaries: ConfigEvaluationSummary[];\n};\n\ntype TelemetryEvent = {\n  summaries: ConfigEvaluationSummaries;\n};\n\ntype TelemetryEvents = {\n  instanceHash: string;\n  events: TelemetryEvent[];\n};\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 prefab, 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 = (apiKey: string, clientVersion: string) => ({\n  Authorization: `Basic ${base64Encode(`u:${apiKey}`)}`,\n  \"X-PrefabCloud-Client-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  apiKey: 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 = [\"belt\", \"suspenders\", \"waistband\"].map(\n  (subdomain) => `https://${subdomain}.prefab.cloud/api/v2`\n);\n\nconst EARLY_TIMEOUT = 2000;\n\nexport default class Loader {\n  apiKey: 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    apiKey,\n    context,\n    endpoints = undefined,\n    timeout,\n    collectContextMode = \"PERIODIC_EXAMPLE\",\n    clientVersion = \"\",\n  }: LoaderParams) {\n    this.apiKey = apiKey;\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.apiKey, 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 ConfigValue from \"./configValue\";\n\nexport const PREFIX = \"log-level\";\n\nconst WORD_LEVEL_LOOKUP: Readonly<Record<string, number>> = {\n  TRACE: 1,\n  DEBUG: 2,\n  INFO: 3,\n  WARN: 5,\n  ERROR: 6,\n  FATAL: 9,\n};\n\nexport type Severity = keyof typeof WORD_LEVEL_LOOKUP;\n\nexport const isValidLogLevel = (logLevel: string) =>\n  Object.keys(WORD_LEVEL_LOOKUP).includes(logLevel.toUpperCase());\n\nexport const shouldLog = ({\n  loggerName,\n  desiredLevel,\n  defaultLevel,\n  get,\n}: {\n  loggerName: string;\n  desiredLevel: string;\n  defaultLevel: string;\n  get: (key: string) => ConfigValue;\n}): boolean => {\n  let loggerNameWithPrefix = `${PREFIX}.${loggerName}`;\n  const desiredLevelNumber = WORD_LEVEL_LOOKUP[desiredLevel.toUpperCase()];\n\n  while (loggerNameWithPrefix.length > 0) {\n    const resolvedLevel = get(loggerNameWithPrefix);\n\n    if (resolvedLevel !== undefined) {\n      return WORD_LEVEL_LOOKUP[resolvedLevel.toString()] <= desiredLevelNumber;\n    }\n\n    if (loggerNameWithPrefix.indexOf(\".\") === -1) {\n      break;\n    }\n\n    loggerNameWithPrefix = loggerNameWithPrefix.slice(0, loggerNameWithPrefix.lastIndexOf(\".\"));\n  }\n\n  return WORD_LEVEL_LOOKUP[defaultLevel.toUpperCase()] <= desiredLevelNumber;\n};\n","import { DEFAULT_TIMEOUT, headers } from \"./apiHelpers\";\n\nexport type TelemetryUploaderParams = {\n  apiKey: string;\n  apiEndpoint?: string | undefined;\n  timeout?: number;\n  clientVersion: string;\n};\n\nexport default class TelemetryUploader {\n  apiKey: string;\n\n  apiEndpoint: string;\n\n  timeout: number;\n\n  clientVersion: string;\n\n  abortTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n  constructor({\n    apiKey,\n    apiEndpoint = undefined,\n    timeout,\n    clientVersion,\n  }: TelemetryUploaderParams) {\n    this.apiKey = apiKey;\n    this.apiEndpoint = apiEndpoint || \"https://telemetry.prefab.cloud/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(options: object, resolve: (value: any) => void, reject: (value: any) => void) {\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          `Prefab 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(\"Prefab 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: any) {\n    const options = {\n      method: \"POST\",\n      headers: {\n        ...headers(this.apiKey, 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 { Severity } from \"./logger\";\nimport { PeriodicSync } from \"./periodicSync\";\nimport { type prefab } from \"./prefab\";\n\ntype LoggerCounter = {\n  loggerName: string;\n  traces: number;\n  debugs: number;\n  infos: number;\n  warns: number;\n  errors: number;\n  fatals: number;\n};\n\ntype LoggersTelemetryEvent = {\n  startAt: number;\n  endAt: number;\n  loggers: LoggerCounter[];\n};\n\ntype TelemetryEvent = {\n  loggers: LoggersTelemetryEvent;\n};\n\ntype TelemetryEvents = {\n  instanceHash: string;\n  events: TelemetryEvent[];\n};\n\nconst SEVERITY_KEY: { [key in Severity]: keyof LoggerCounter } = {\n  TRACE: \"traces\",\n  DEBUG: \"debugs\",\n  INFO: \"infos\",\n  WARN: \"warns\",\n  ERROR: \"errors\",\n  FATAL: \"fatals\",\n};\n\nclass LoggerAggregator extends PeriodicSync<LoggerCounter> {\n  private maxLoggers: number;\n\n  constructor(client: typeof prefab, maxLoggers: number, syncInterval?: number) {\n    super(client, \"LoggerAggregator\", syncInterval ?? 30000);\n\n    this.maxLoggers = maxLoggers;\n  }\n\n  record(logger: string, level: Severity): 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","// THIS FILE IS GENERATED\nexport default \"0.4.7\";\n"],"mappings":"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","names":[]}