{"version":3,"sources":["/home/runner/work/flags/flags/packages/vercel-flags-core/dist/chunk-ID4ZKPA3.cjs","../src/index.next-js.ts","../src/evaluate.ts","../src/types.ts","../package.json","../src/lib/report-value.ts","../src/controller-fns.ts","../src/create-raw-client.ts","../src/utils/read-bundled-definitions.ts","../src/utils/ingest.ts","../src/utils/backoff.ts","../src/utils/request-context.ts","../src/utils/scheduler.ts","../src/utils/usage/flags-config-read.ts","../src/utils/usage/flags-evaluation.ts","../src/utils/usage-tracker.ts","../src/errors.ts","../src/controller/bundled-source.ts","../src/controller/fetch-datafile.ts","../src/controller/normalized-options.ts","../src/controller/typed-emitter.ts","../src/controller/polling-source.ts","../src/utils/sleep.ts","../src/controller/stream-connection.ts","../src/controller/stream-source.ts","../src/controller/tagged-data.ts","../src/controller/index.ts","../src/controller/auth.ts","../src/utils/sdk-keys.ts","../src/index.make.ts"],"names":["ResolutionReason","Original","AccessorType","Packed"],"mappings":"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","file":"/home/runner/work/flags/flags/packages/vercel-flags-core/dist/chunk-ID4ZKPA3.cjs","sourcesContent":[null,"/**\n * Exports for Next.js App Router\n *\n * There is also index.default.ts which targets Next.js specifically.\n * If you update this file, please update index.default.ts as well.\n *\n * Try keeping this file small. Export through index.common and index.make.\n *\n * This file should stay equivalent to index.default.ts, except that it\n * declares \"use cache\".\n */\n\nimport { cacheLife } from 'next/cache';\nimport * as fns from './controller-fns';\nimport { createCreateRawClient } from './create-raw-client';\nimport { make } from './index.make';\n\nfunction setCacheLife(): void {\n  try {\n    // Working around a limitation of cacheLife in older Next.js versions\n    // where stale was required to be greater than expire if set concurrently.\n    // Instead we do this over two calls.\n    cacheLife({ revalidate: 0, expire: 0 });\n    cacheLife({ stale: 60 });\n  } catch {\n    // if we error setting cache life it means we are not in a cache scope\n    // The only time that might happen is if next-js entrypoint is used\n    // in a context that doesn't process the \"use cache\" directive.\n    // In these contexts we don't really need the cache life to be set because there\n    // is no Cache Component semantics\n  }\n}\n\nconst cachedFns: Parameters<typeof createCreateRawClient>[0] = {\n  initialize: async (...args) => {\n    'use cache';\n    setCacheLife();\n\n    return fns.initialize(...args);\n  },\n  shutdown: async (...args) => {\n    'use cache';\n    setCacheLife();\n    return fns.shutdown(...args);\n  },\n  getDatafile: async (...args) => {\n    'use cache';\n    setCacheLife();\n    return fns.getDatafile(...args);\n  },\n  getFallbackDatafile: async (...args) => {\n    'use cache';\n    setCacheLife();\n    return fns.getFallbackDatafile(...args);\n  },\n  evaluate: async (...args) => {\n    'use cache';\n    setCacheLife();\n    return fns.evaluate(...args);\n  },\n  bulkEvaluate: async (...args) => {\n    'use cache';\n    setCacheLife();\n    return fns.bulkEvaluate(...args);\n  },\n};\n\nexport * from './index.common';\n\n// no JSDoc needed here since editors will use the one if index.default.ts\nexport const { flagsClient, resetDefaultFlagsClient, createClient } = make(\n  createCreateRawClient(cachedFns),\n);\n","import { xxHash32 as hashInput } from 'js-xxhash';\nimport {\n  Comparator,\n  type EvaluationParams,\n  type EvaluationResult,\n  OutcomeType,\n  Packed,\n  ResolutionReason,\n  type VariantId,\n} from './types';\n\ntype PathArray = (string | number)[];\n\nconst MAX_REGEX_INPUT_LENGTH = 10_000;\n\n/**\n * Bucket space for all traffic splitting. `hashInput` (xxHash32) returns exactly\n * `2**32` distinct values, so we use `2**32` as the space and compare the raw\n * hash against boundaries in it — no modulo (which would bias low buckets), and\n * the final variant's boundary is exactly `2**32` so nothing falls through.\n */\nconst HASH_SPACE = 2 ** 32;\n\n/** Denominator for promille values (rollout slots and segment `passPromille`). */\nconst PROMILLE_SCALE = 100_000;\n\n/**\n * Maps the fraction `numerator / denominator` to a cut point in `[0, HASH_SPACE]`;\n * a hash is \"below\" the fraction iff `hash < boundaryFor(…)`. Splits, rollouts,\n * and segments all cut with this one function, so a rollout at promille `p` is\n * bit-for-bit identical to the split `{ rollFrom: PROMILLE_SCALE - p, rollTo: p }`\n * — which is what lets a flag switch between split and rollout without reassigning\n * anyone. `denominator === 0` yields `NaN`, so evaluation falls through to default.\n */\nfunction boundaryFor(numerator: number, denominator: number): number {\n  return Math.floor((numerator / denominator) * HASH_SPACE);\n}\n\n// WeakMaps keyed by datafile objects, so those objects stay pristine (no\n// symbol-keyed props) and serialize cleanly across the RSC boundary; entries\n// are GC'd with the datafile. Split boundaries are static per outcome, so the\n// cumulative cut points are computed once and reused across evaluations.\nconst splitBoundariesCache = new WeakMap<Packed.SplitOutcome, number[]>();\nconst compiledRegexCache = new WeakMap<object, RegExp>();\n\n/**\n * Cumulative hash boundaries for a split, one per variant in index order.\n * Variant `i` is served for hashes in `[boundaries[i-1], boundaries[i])`.\n */\nfunction getSplitBoundaries(outcome: Packed.SplitOutcome): number[] {\n  const cached = splitBoundariesCache.get(outcome);\n  if (cached) return cached;\n  const total = sum(outcome.weights);\n  const boundaries: number[] = [];\n  let cumulative = 0;\n  for (const weight of outcome.weights) {\n    cumulative += weight;\n    boundaries.push(boundaryFor(cumulative, total));\n  }\n  splitBoundariesCache.set(outcome, boundaries);\n  return boundaries;\n}\n\nfunction getCompiledRegex(rhs: { pattern: string; flags: string }): RegExp {\n  const cached = compiledRegexCache.get(rhs);\n  if (cached) return cached;\n  const compiled = new RegExp(rhs.pattern, rhs.flags.replace(/[gy]/, ''));\n  compiledRegexCache.set(rhs, compiled);\n  return compiled;\n}\n\nfunction exhaustivenessCheck(_: never): never {\n  throw new Error('Exhaustiveness check failed');\n}\n\nfunction getProperty(obj: any, pathArray: PathArray): any {\n  return pathArray.reduce((acc: any, key: string | number) => {\n    if (acc && key in acc) {\n      return acc[key];\n    }\n    return undefined; // Return undefined if the property is not found\n  }, obj);\n}\n\n/**\n * Accesses the value of the given lhs on the provided entities.\n *\n * This must return unknown as we don't know what the library users will pass.\n */\n\nfunction access<T>(lhs: Packed.LHS, params: EvaluationParams<T>): any {\n  // we're dealing with an entity\n  if (Array.isArray(lhs)) return getProperty(params.entities, lhs);\n\n  // Code should never end up here as the segment accessor is handled\n  // earlier in the matchConditions() function.\n  if (lhs === Packed.AccessorType.SEGMENT)\n    throw new Error('Unexpected segment');\n\n  throw new Error('Accessor not implemented');\n}\n\nfunction isString(input: unknown): input is string {\n  return typeof input === 'string';\n}\n\nfunction isNumber(input: unknown): input is number {\n  return typeof input === 'number';\n}\n\nfunction isArray(input: unknown): input is unknown[] {\n  return Array.isArray(input);\n}\n\nfunction lower<T>(input: T): T {\n  if (typeof input === 'string') return input.toLowerCase() as T;\n  if (Array.isArray(input)) return input.map(lower) as T;\n  return input;\n}\n\nconst IGNORE_CASE_COMPARATORS: ReadonlySet<Comparator> = new Set([\n  Comparator.EQ,\n  Comparator.NOT_EQ,\n  Comparator.ONE_OF,\n  Comparator.NOT_ONE_OF,\n  Comparator.CONTAINS_ALL_OF,\n  Comparator.CONTAINS_ANY_OF,\n  Comparator.CONTAINS_NONE_OF,\n  Comparator.STARTS_WITH,\n  Comparator.NOT_STARTS_WITH,\n  Comparator.ENDS_WITH,\n  Comparator.NOT_ENDS_WITH,\n  Comparator.CONTAINS,\n  Comparator.NOT_CONTAINS,\n]);\n\nfunction matchTargetList<T>(\n  targets: Packed.TargetList,\n  params: EvaluationParams<T>,\n): boolean {\n  for (const kind in targets) {\n    const attributes = targets[kind]!;\n    for (const attribute in attributes) {\n      const entity = access([kind, attribute], params);\n      if (isString(entity) && attributes[attribute]!.includes(entity))\n        return true;\n    }\n  }\n  return false;\n}\n\nfunction matchSegment<T>(segment: Packed.Segment, params: EvaluationParams<T>) {\n  if (segment.include && matchTargetList(segment.include, params)) return true;\n  if (segment.exclude && matchTargetList(segment.exclude, params)) return false;\n  if (!segment.rules?.length) return false;\n\n  const firstMatchingRule = segment.rules.find((rule) =>\n    matchConditions(rule.conditions, params),\n  );\n\n  if (!firstMatchingRule) return false;\n\n  return handleSegmentOutcome(params, firstMatchingRule.outcome);\n}\n\nfunction matchSegmentCondition<T>(\n  cmp: Comparator,\n  rhs: Packed.RHS,\n  params: EvaluationParams<T>,\n) {\n  switch (cmp) {\n    case Comparator.EQ: {\n      const segment = params.segments?.[rhs as string];\n      if (!segment) return false;\n      return matchSegment<T>(segment, params);\n    }\n    case Comparator.NOT_EQ: {\n      const segment = params.segments?.[rhs as string];\n      if (!segment) return false;\n      return !matchSegment<T>(segment, params);\n    }\n    case Comparator.ONE_OF: {\n      if (!isArray(rhs)) return false;\n      const segmentIds = rhs;\n      return segmentIds.some((segmentId) => {\n        const segment = params.segments?.[segmentId];\n        if (!segment) return false;\n        return matchSegment<T>(segment, params);\n      });\n    }\n    case Comparator.NOT_ONE_OF: {\n      const segmentIds = rhs as string[];\n      return segmentIds.every((segmentId) => {\n        const segment = params.segments?.[segmentId];\n        if (!segment) return false;\n        return !matchSegment<T>(segment, params);\n      });\n    }\n    default:\n      throw new Error(`Comparator ${cmp} not implemented for segment`);\n  }\n}\n\nfunction matchConditions<T>(\n  conditions: Packed.Condition[],\n  params: EvaluationParams<T>,\n): boolean {\n  return conditions.every((condition) => {\n    const [lhsAccessor, cmpKey, rawRhs, options] = condition;\n    const hasIgnoreCaseFlag =\n      typeof options === 'string' && options.includes('i');\n    const hasIgnoreCaseOption =\n      typeof options === 'object' && options !== null && options.i === true;\n    const ignoreCase =\n      IGNORE_CASE_COMPARATORS.has(cmpKey) &&\n      (hasIgnoreCaseFlag || hasIgnoreCaseOption);\n\n    // ignoreCase is not applicable to segment conditions (segments are internal IDs)\n    if (lhsAccessor === Packed.AccessorType.SEGMENT) {\n      return rawRhs && matchSegmentCondition(cmpKey, rawRhs, params);\n    }\n\n    const lhs = ignoreCase\n      ? lower(access(lhsAccessor, params))\n      : access(lhsAccessor, params);\n    const rhs = ignoreCase ? lower(rawRhs) : rawRhs;\n\n    try {\n      switch (cmpKey) {\n        case Comparator.EQ:\n          return lhs === rhs;\n        case Comparator.NOT_EQ:\n          return lhs !== rhs;\n        case Comparator.ONE_OF:\n          return isArray(rhs) && rhs.includes(lhs);\n        case Comparator.NOT_ONE_OF:\n          // lhs would be undefined when the value was not provided, in which\n          // case we should not match the rule\n          return (\n            isArray(rhs) && typeof lhs !== 'undefined' && !rhs.includes(lhs)\n          );\n        case Comparator.CONTAINS_ALL_OF: {\n          if (!Array.isArray(rhs) || !Array.isArray(lhs)) return false;\n\n          const lhsSet = new Set(lhs.filter(isString));\n\n          // try to use a set if the lhs is a list of strings - O(1)\n          // otherwise we need to iterate over the values - O(n)\n          if (lhsSet.size === lhs.length) {\n            return rhs.filter(isString).every((item) => lhsSet.has(item));\n          }\n\n          // this shouldn't happen since we only allow string[] on the lhs\n          return rhs.every((item) => lhs.includes(item));\n        }\n        case Comparator.CONTAINS_ANY_OF: {\n          if (!Array.isArray(rhs) || !Array.isArray(lhs)) return false;\n\n          const rhsSet = new Set(rhs.filter(isString));\n          return lhs.some(\n            rhsSet.size === rhs.length\n              ? // try to use a set if the rhs is a list of strings - O(1)\n                (item) => rhsSet.has(item)\n              : // otherwise we need to iterate over the values - O(n)\n                (item) => rhs.includes(item),\n          );\n        }\n        case Comparator.CONTAINS_NONE_OF: {\n          // if the rhs is not an array something went wrong and we should not match\n          if (!Array.isArray(rhs)) return false;\n\n          // if it's not an array it doesn't contain any of the values\n          if (!Array.isArray(lhs)) return true;\n\n          const rhsSet = new Set(rhs.filter(isString));\n          return lhs.every(\n            rhsSet.size === rhs.length\n              ? // try to use a set if the rhs is a list of strings - O(1)\n                (item) => !rhsSet.has(item)\n              : // otherwise we need to iterate over the values - O(n)\n                (item) => !rhs.includes(item),\n          );\n        }\n        case Comparator.STARTS_WITH:\n          return isString(lhs) && isString(rhs) && lhs.startsWith(rhs);\n        case Comparator.NOT_STARTS_WITH:\n          return isString(lhs) && isString(rhs) && !lhs.startsWith(rhs);\n        case Comparator.ENDS_WITH:\n          return isString(lhs) && isString(rhs) && lhs.endsWith(rhs);\n        case Comparator.NOT_ENDS_WITH:\n          return isString(lhs) && isString(rhs) && !lhs.endsWith(rhs);\n        case Comparator.CONTAINS:\n          return isString(lhs) && isString(rhs) && lhs.includes(rhs);\n        case Comparator.NOT_CONTAINS:\n          return isString(lhs) && isString(rhs) && !lhs.includes(rhs);\n        case Comparator.EXISTS:\n          return lhs !== undefined && lhs !== null;\n        case Comparator.NOT_EXISTS:\n          return lhs === undefined || lhs === null;\n        case Comparator.GT:\n          // NaN will return false for any comparisons\n          if (lhs === null || lhs === undefined) return false;\n          return (isNumber(rhs) || isString(rhs)) && lhs > rhs;\n        case Comparator.GTE:\n          if (lhs === null || lhs === undefined) return false;\n          return (isNumber(rhs) || isString(rhs)) && lhs >= rhs;\n        case Comparator.LT:\n          if (lhs === null || lhs === undefined) return false;\n          return (isNumber(rhs) || isString(rhs)) && lhs < rhs;\n        case Comparator.LTE:\n          if (lhs === null || lhs === undefined) return false;\n          return (isNumber(rhs) || isString(rhs)) && lhs <= rhs;\n        case Comparator.REGEX:\n          if (\n            isString(lhs) &&\n            lhs.length <= MAX_REGEX_INPUT_LENGTH &&\n            typeof rhs === 'object' &&\n            !Array.isArray(rhs) &&\n            rhs?.type === 'regex'\n          ) {\n            return getCompiledRegex(rhs).test(lhs);\n          }\n          return false;\n\n        case Comparator.NOT_REGEX:\n          if (\n            isString(lhs) &&\n            lhs.length <= MAX_REGEX_INPUT_LENGTH &&\n            typeof rhs === 'object' &&\n            !Array.isArray(rhs) &&\n            rhs?.type === 'regex'\n          ) {\n            return !getCompiledRegex(rhs).test(lhs);\n          }\n          return false;\n        case Comparator.BEFORE: {\n          if (!isString(lhs) || !isString(rhs)) return false;\n          const a = new Date(lhs);\n          const b = new Date(rhs);\n          // if any date fails to parse getTime will return NaN, which will cause\n          // comparisons to fail.\n          return a.getTime() < b.getTime();\n        }\n        case Comparator.AFTER: {\n          if (!isString(lhs) || !isString(rhs)) return false;\n          const a = new Date(lhs);\n          const b = new Date(rhs);\n          return a.getTime() > b.getTime();\n        }\n        default: {\n          const _x: never = cmpKey; // exhaustive check\n          return false;\n        }\n      }\n    } catch (error) {\n      console.error('flags: Error matching conditions', error);\n      return false;\n    }\n  });\n}\n\nfunction sum(list: number[]) {\n  return list.reduce((acc, n) => acc + n, 0);\n}\n\nfunction handleSegmentOutcome<T>(\n  params: EvaluationParams<T>,\n  outcome: Packed.SegmentOutcome,\n) {\n  // when everyone is flagged in the segment we can return true immediately\n  if (outcome === 1) return true;\n\n  switch (outcome.type) {\n    case 'split': {\n      const lhs = access(outcome.base, params);\n\n      // exclude from segment if the lhs is not a string\n      if (typeof lhs !== 'string') return false;\n\n      // bypass hashing for common values and edges\n      if (outcome.passPromille <= 0) return false;\n      if (outcome.passPromille >= PROMILLE_SCALE) return true;\n\n      const bucket = hashInput(lhs, params.definition.seed);\n      return bucket < boundaryFor(outcome.passPromille, PROMILLE_SCALE);\n    }\n    default: {\n      const { type } = outcome;\n      exhaustivenessCheck(type);\n    }\n  }\n}\n\nfunction getVariant<T>(\n  definition: Packed.FlagDefinition,\n  index: number,\n): { value: T; variantId: VariantId | null } {\n  const { variants, variantIds } = definition;\n\n  if (index < 0 || index >= variants.length) {\n    throw new Error(\n      `@vercel/flags-core: Invalid variant index ${index}, variants length is ${variants.length}`,\n    );\n  }\n\n  let variantId: VariantId | null = null;\n  if (variantIds && index < variantIds.length) {\n    variantId = variantIds[index] ?? null;\n  }\n\n  return {\n    value: variants[index] as T,\n    variantId,\n  };\n}\n\nfunction handleOutcome<T>(\n  params: EvaluationParams<T>,\n  outcome: Packed.Outcome,\n): {\n  value: T;\n  outcomeType: OutcomeType;\n  variantId: VariantId | null;\n} {\n  if (typeof outcome === 'number') {\n    const variant = getVariant<T>(params.definition, outcome);\n    return {\n      ...variant,\n      outcomeType: OutcomeType.VALUE,\n    };\n  }\n  switch (outcome.type) {\n    case 'split': {\n      const lhs = access(outcome.base, params);\n      const defaultOutcome = getVariant<T>(\n        params.definition,\n        outcome.defaultVariant,\n      );\n\n      // serve the default variant if the lhs is not a string\n      if (typeof lhs !== 'string') {\n        return {\n          ...defaultOutcome,\n          outcomeType: OutcomeType.SPLIT,\n        };\n      }\n\n      const bucket = hashInput(lhs, params.definition.seed);\n      const boundaries = getSplitBoundaries(outcome);\n\n      // Return the first variant whose cumulative boundary covers the bucket.\n      for (let index = 0; index < boundaries.length; index++) {\n        if (bucket < (boundaries[index] as number)) {\n          return {\n            ...getVariant<T>(params.definition, index),\n            outcomeType: OutcomeType.SPLIT,\n          };\n        }\n      }\n\n      // Only reached when the weights sum to 0 (every boundary is NaN).\n      return {\n        ...defaultOutcome,\n        outcomeType: OutcomeType.SPLIT,\n      };\n    }\n    case 'rollout': {\n      const lhs = access(outcome.base, params);\n      const defaultOutcome = getVariant<T>(\n        params.definition,\n        outcome.defaultVariant,\n      );\n\n      // serve the default variant if the lhs is not a string\n      if (typeof lhs !== 'string') {\n        return { ...defaultOutcome, outcomeType: OutcomeType.ROLLOUT };\n      }\n\n      // Determine active slot based on elapsed time\n      const now = Date.now();\n      const elapsed = now - outcome.startTimestamp;\n\n      const rollFromVariant = getVariant<T>(\n        params.definition,\n        outcome.rollFromVariant,\n      );\n\n      // Before rollout starts or no slots, serve rollFromVariant\n      if (elapsed < 0 || outcome.slots.length === 0) {\n        return {\n          ...rollFromVariant,\n          outcomeType: OutcomeType.ROLLOUT,\n        };\n      }\n\n      // Walk slots to find current promille.\n      // Each slot's durationMs is how long that slot is served before\n      // moving to the next one. Once all slots are exhausted the\n      // rollout is complete (100% to rollToVariant).\n      let cumulativeDuration = 0;\n      let currentPromille = 0;\n      let exhausted = true;\n      for (const [promille, durationMs] of outcome.slots) {\n        currentPromille = promille;\n        cumulativeDuration += durationMs;\n        if (cumulativeDuration > elapsed) {\n          exhausted = false;\n          break;\n        }\n      }\n      if (exhausted) currentPromille = PROMILLE_SCALE;\n\n      // short-circuit common edges\n      if (currentPromille <= 0) {\n        return {\n          ...rollFromVariant,\n          outcomeType: OutcomeType.ROLLOUT,\n        };\n      }\n      const rollToVariant = getVariant<T>(\n        params.definition,\n        outcome.rollToVariant,\n      );\n      if (currentPromille >= PROMILLE_SCALE) {\n        return {\n          ...rollToVariant,\n          outcomeType: OutcomeType.ROLLOUT,\n        };\n      }\n\n      const bucket = hashInput(lhs, params.definition.seed);\n\n      // Equivalent to the split { rollFrom: PROMILLE_SCALE - p, rollTo: p }: the\n      // lower-index variant takes the low buckets, matching where the split\n      // places it (see boundaryFor). So rollTo holds `[0, boundary(p))` when it\n      // has the lower index, otherwise rollFrom holds the low buckets.\n      if (outcome.rollToVariant < outcome.rollFromVariant) {\n        const rollToBoundary = boundaryFor(currentPromille, PROMILLE_SCALE);\n        return {\n          ...(bucket < rollToBoundary ? rollToVariant : rollFromVariant),\n          outcomeType: OutcomeType.ROLLOUT,\n        };\n      }\n      const rollFromBoundary = boundaryFor(\n        PROMILLE_SCALE - currentPromille,\n        PROMILLE_SCALE,\n      );\n      return {\n        ...(bucket < rollFromBoundary ? rollFromVariant : rollToVariant),\n        outcomeType: OutcomeType.ROLLOUT,\n      };\n    }\n    default: {\n      const { type } = outcome;\n      exhaustivenessCheck(type);\n    }\n  }\n}\n\n/**\n * Evaluates a single feature flag.\n *\n * This function should never throw for expected errors, instead it returns\n * { reason: Reason.ERROR, errorMessage: ... }.\n *\n * The function can however throw for situations which should not happen under\n * normal circumstances, for example if the environment config is not found.\n */\nexport function evaluate<T>(\n  /**\n   * The params used for the evaluation\n   */\n  params: EvaluationParams<T>,\n  /** Tracks visited environments to detect circular reuse. */\n  _visited?: Set<string>,\n): EvaluationResult<T> {\n  const envConfig = params.definition.environments[params.environment];\n\n  // handle shortcut where a value is a number directly\n  if (typeof envConfig === 'number') {\n    return Object.assign(handleOutcome<T>(params, envConfig), {\n      reason: ResolutionReason.PAUSED as const,\n    }) satisfies EvaluationResult<T>;\n  }\n\n  if (!envConfig) {\n    return {\n      reason: ResolutionReason.ERROR,\n      errorMessage: `Could not find envConfig for \"${params.environment}\"`,\n      value: params.defaultValue,\n      variantId: null,\n    };\n  }\n\n  if ('reuse' in envConfig) {\n    const reuseEnvConfig = params.definition.environments[envConfig.reuse];\n\n    if (reuseEnvConfig === undefined) {\n      // this is an unexpected error as this should have never been saved in\n      // the first place\n      throw new Error(\n        `Could not find envConfig for \"${envConfig.reuse}\" when reusing`,\n      );\n    }\n\n    const visited = _visited ?? new Set<string>();\n    if (visited.has(envConfig.reuse)) {\n      return {\n        reason: ResolutionReason.ERROR,\n        errorMessage: `Circular environment reuse detected: \"${envConfig.reuse}\"`,\n        value: params.defaultValue,\n        variantId: null,\n      };\n    }\n    visited.add(params.environment);\n\n    return evaluate<T>({ ...params, environment: envConfig.reuse }, visited);\n  }\n\n  if (envConfig.targets) {\n    const matchedIndex = envConfig.targets.findIndex((targetList) =>\n      matchTargetList(targetList, params),\n    );\n\n    if (matchedIndex > -1) {\n      return Object.assign(handleOutcome<T>(params, matchedIndex), {\n        reason: ResolutionReason.TARGET_MATCH as const,\n      }) satisfies EvaluationResult<T>;\n    }\n  }\n\n  const firstMatchingRule = envConfig.rules\n    ? envConfig.rules.find((rule) => matchConditions(rule.conditions, params))\n    : undefined;\n\n  if (firstMatchingRule) {\n    return Object.assign(handleOutcome<T>(params, firstMatchingRule.outcome), {\n      reason: ResolutionReason.RULE_MATCH as const,\n    }) satisfies EvaluationResult<T>;\n  }\n\n  return Object.assign(handleOutcome<T>(params, envConfig.fallthrough), {\n    reason: ResolutionReason.FALLTHROUGH as const,\n  }) satisfies EvaluationResult<T>;\n}\n\nexport type BulkEvaluationInput<T> = {\n  definition: Packed.FlagDefinition;\n  defaultValue?: T;\n};\n\n/**\n * Evaluates multiple feature flags against the same entities, segments, and\n * environment.\n *\n * Reuses a single shared `EvaluationParams` object across flags so callers\n * avoid the overhead of constructing one per call (and don't need to spawn\n * parallel promises just to fan out independent sync evaluations).\n */\nexport function bulkEvaluate<T = unknown>(\n  flags: Record<string, BulkEvaluationInput<T>>,\n  shared: {\n    entities?: Record<string, unknown>;\n    environment: string;\n    segments?: EvaluationParams<T>['segments'];\n  },\n): Record<string, EvaluationResult<T>> {\n  const params: EvaluationParams<T> = {\n    entities: shared.entities,\n    environment: shared.environment,\n    segments: shared.segments,\n    definition: undefined as unknown as Packed.FlagDefinition,\n    defaultValue: undefined,\n  };\n\n  const results: Record<string, EvaluationResult<T>> = {};\n  for (const key in flags) {\n    const flag = flags[key]!;\n    params.definition = flag.definition;\n    params.defaultValue = flag.defaultValue;\n    results[key] = evaluate<T>(params);\n  }\n  return results;\n}\n","export type MetricEnvironment = 'development' | 'preview' | 'production';\n\n/**\n * Options for stream connection behavior\n */\nexport type StreamOptions = {\n  /** Timeout in ms to wait for initial stream connection before falling back */\n  initTimeoutMs: number;\n};\n\n/**\n * Options for polling behavior\n */\nexport type PollingOptions = {\n  /** Interval in ms between polling requests */\n  intervalMs: number;\n  /** Timeout in ms to wait for initial poll before falling back */\n  initTimeoutMs: number;\n};\n\n/** Input type for creating a datafile (without metrics) */\nexport type DatafileInput = Packed.Data & {\n  /**\n   * If a data source is used with a specific sdk key then\n   * the sdk key or data source might contain information\n   * about the environment to be evaluated\n   */\n  environment: string;\n  /** Vercel project id of the source of these flags  */\n  projectId: string;\n  /**\n   * Some older responses might return a string instead of a number. Both will be timestamps.\n   */\n  configUpdatedAt?: number | string;\n  /** Version number of the data */\n  revision?: number;\n};\n\n/** Datafile with metrics attached (returned by the client) */\nexport type Datafile = DatafileInput & {\n  /** Metrics about how the data was retrieved */\n  metrics: Metrics;\n};\n\n/** Flag Definitions of a Vercel project */\nexport type BundledDefinitions = DatafileInput & {\n  /** when the data was last updated */\n  configUpdatedAt: number;\n  /** hash of the data */\n  digest: string;\n  /** version number of the data */\n  revision: number;\n};\n\nexport type BundledDefinitionsResult =\n  | { definitions: BundledDefinitions; state: 'ok' }\n  | { definitions: null; state: 'missing-file' | 'missing-entry' }\n  | { definitions: null; state: 'unexpected-error'; error: unknown };\n\n/**\n * Metrics about how data was retrieved and evaluated\n */\nexport type Metrics = {\n  /** Time in ms to read the datafile */\n  readMs: number;\n  /** Where the data came from */\n  source: 'in-memory' | 'embedded' | 'remote';\n  /** Whether data was already cached, or stale (fallback used) */\n  cacheStatus: 'HIT' | 'MISS' | 'STALE';\n  /** Whether the stream is currently connected */\n  connectionState: 'connected' | 'disconnected';\n  /** The current operating mode of the client */\n  mode: 'streaming' | 'polling' | 'build' | 'offline';\n  /** Time in ms for the pure flag evaluation logic (only present on EvaluationResult) */\n  evaluationMs?: number;\n};\n\n/**\n * DataSource interface for the Vercel Flags client\n */\nexport interface ControllerInterface {\n  /**\n   * Initialize the data source by fetching the initial file or setting up polling or\n   * subscriptions.\n   *\n   * @see https://openfeature.dev/specification/sections/providers#requirement-241\n   */\n  initialize: () => Promise<void>;\n\n  /**\n   * Returns the in-memory data file, which was loaded from initialize and maybe updated from streams.\n   */\n  read(): Promise<Datafile>;\n\n  /**\n   * End polling or subscriptions. Flush any remaining data.\n   */\n  shutdown(): void;\n\n  /**\n   * Return the actual datafile containing flag definitions.\n   */\n  getDatafile(): Promise<Datafile>;\n\n  /**\n   * Returns the bundled fallback definitions.\n   * Throws FallbackNotFoundError if the fallback file doesn't exist.\n   * Throws FallbackEntryNotFoundError if the file exists but has no entry for the SDK key.\n   */\n  getFallbackDatafile?(): Promise<BundledDefinitions>;\n}\n\nexport type Source = {\n  orgId: string;\n  orgSlug: string;\n  projectId: string;\n  projectSlug: string;\n};\n\n/**\n * Input for a single flag in a bulk evaluation call.\n */\nexport type BulkEvaluateInput<T = Value> = {\n  key: string;\n  defaultValue?: T;\n};\n\n/**\n * A client for Vercel Flags\n */\nexport type FlagsClient<Entities = Record<string, unknown>> = {\n  /**\n   * Origin information for this client.\n   * sdkKey is only present when the client was explicitly created with one.\n   */\n  origin?: {\n    provider: string;\n    sdkKey?: string;\n  };\n  /**\n   * Evaluate a feature flag\n   *\n   * Requires initialize() to have been called and awaited first.\n   *\n   * @param flagKey\n   * @param defaultValue\n   * @param entities\n   * @returns\n   */\n  evaluate: <T = Value, E = Entities>(\n    flagKey: string,\n    defaultValue?: T,\n    entities?: E,\n  ) => Promise<EvaluationResult<T>>;\n  /**\n   * Evaluate multiple feature flags against the same entities in a single call.\n   *\n   * Avoids the per-flag overhead of separate `evaluate()` invocations (in particular,\n   * the parallel promises and repeated datafile reads they would entail).\n   *\n   * Requires initialize() to have been called and awaited first.\n   *\n   * @param flags Array of `{ key, defaultValue? }` entries to evaluate.\n   * @param entities Shared entities used for every flag in the bulk call.\n   * @returns Object mapping each key to its EvaluationResult.\n   */\n  bulkEvaluate: <T = Value, E = Entities>(\n    flags: BulkEvaluateInput<T>[],\n    entities?: E,\n  ) => Promise<Record<string, EvaluationResult<T>>>;\n  /**\n   * Retrieve the latest datafile during startup, and set up subscriptions if needed.\n   */\n  initialize(): void | Promise<void>;\n  /**\n   * Facilitates a clean shutdown process which may include flushing telemetry information, or closing remote connections.\n   */\n  shutdown(): void | Promise<void>;\n  /**\n   * Returns the actual datafile containing flag definitions\n   */\n  getDatafile(): Promise<Datafile>;\n  /**\n   * Returns the bundled fallback definitions.\n   * Throws FallbackNotFoundError if the fallback file doesn't exist.\n   * Throws FallbackEntryNotFoundError if the file exists but has no entry for the SDK key.\n   */\n  getFallbackDatafile(): Promise<BundledDefinitions>;\n};\n\nexport type EvaluationParams<T> = {\n  entities?: Record<string, unknown>;\n  environment: string;\n  segments?: Record<SegmentId, Packed.Segment>;\n  definition: Packed.FlagDefinition;\n  defaultValue?: T;\n};\n\n// Copied from the OpenFeature ErrorCode and commented out unused types\n/**\n * ErrorCodes that can happen during evaluation\n */\nexport enum ErrorCode {\n  /**\n   * The value was resolved before the provider was ready.\n   */\n  // PROVIDER_NOT_READY = 'PROVIDER_NOT_READY',\n  /**\n   * The provider has entered an irrecoverable error state.\n   */\n  // PROVIDER_FATAL = 'PROVIDER_FATAL',\n  /**\n   * The flag could not be found.\n   */\n  FLAG_NOT_FOUND = 'FLAG_NOT_FOUND',\n  /**\n   * An error was encountered parsing data, such as a flag configuration.\n   */\n  // PARSE_ERROR = 'PARSE_ERROR',\n  /**\n   * The type of the flag value does not match the expected type.\n   */\n  // TYPE_MISMATCH = 'TYPE_MISMATCH',\n  /**\n   * The provider requires a targeting key and one was not provided in the evaluation context.\n   */\n  // TARGETING_KEY_MISSING = 'TARGETING_KEY_MISSING',\n  /**\n   * The evaluation context does not meet provider requirements.\n   */\n  // INVALID_CONTEXT = 'INVALID_CONTEXT',\n  /**\n   * An error with an unspecified code.\n   */\n  // GENERAL = 'GENERAL',\n}\n\n/**\n * The detailed result of a flag evaluation as returned by the client's `evaluate` function.\n */\nexport type EvaluationResult<T> =\n  | {\n      /**\n       * In case of successful evaluations this holds the evaluated value\n       */\n      value: T;\n      /**\n       * Indicates whether the outcome was a single variant or a split\n       */\n      outcomeType?: OutcomeType;\n      /**\n       * The variant we want to report for o11y\n       */\n      variantId: VariantId | null;\n      /**\n       * Indicates why the flag evaluated to a certain value\n       */\n      reason: Exclude<ResolutionReason, ResolutionReason.ERROR>;\n      errorMessage?: never;\n      errorCode?: never;\n      /** Metrics about the evaluation (optional) */\n      metrics?: Metrics;\n    }\n  | {\n      reason: ResolutionReason.ERROR;\n      errorMessage: string;\n      errorCode?: ErrorCode;\n      outcomeType?: never;\n      /**\n       * The variant we want to report for o11y\n       */\n      variantId: VariantId | null;\n      /**\n       * In cases of errors this is the defaultValue if one was provided\n       */\n      value?: T;\n      /** Metrics about the evaluation (optional) */\n      metrics?: Metrics;\n    };\n\nexport type FlagKey = string;\nexport type VariantId = string;\nexport type EnvironmentKey = string;\nexport type SegmentId = string;\n\n/**\n * The value of a feature flag variant\n */\nexport type Value =\n  | string\n  | number\n  | boolean\n  | null\n  | { [key: string]: Value }\n  | Value[];\n\nexport enum ResolutionReason {\n  PAUSED = 'paused',\n  TARGET_MATCH = 'target_match',\n  RULE_MATCH = 'rule_match',\n  FALLTHROUGH = 'fallthrough',\n  ERROR = 'error',\n}\n\nexport enum OutcomeType {\n  /** When the outcome type was a single variant */\n  VALUE = 'value',\n  /** When the outcome type was a split */\n  SPLIT = 'split',\n  /** When the outcome type was a progressive rollout */\n  ROLLOUT = 'rollout',\n}\n\n/**\n * Vercel Flags\n * - is equal to (eq)\n * - is not equal to (!eq)\n * - is one of (oneOf)\n * - is not one of (!oneOf)\n * - contains (contains)\n * - does not contain (!contains)\n * - starts with (startsWith)\n * - does not start with (!startsWith)\n * - ends with (endsWith)\n * - does not end with (!endsWith)\n * - exists (ex)\n * - does not exist (!ex)\n * - is greater than (gt)\n * - is greater than or equal to (gte)\n * - is lower than (lt)\n * - is lower than or equal to (lte)\n * - matches regex (regex)\n * - does not match regex (!regex)\n * - is before (before)\n * - is after (after)\n */\n\nexport enum Comparator {\n  /**\n   * lhs must be string | number\n   * rhs must be string | number\n   * does a strict equality check\n   */\n  EQ = 'eq',\n  /**\n   * lhs must be string | number\n   * rhs must be string | number\n   * does a strict equality check\n   */\n  NOT_EQ = '!eq',\n  /**\n   * lhs must be string\n   * rhs must be string[]\n   */\n  ONE_OF = 'oneOf',\n  /**\n   * lhs must be string\n   * rhs must be string[]\n   */\n  NOT_ONE_OF = '!oneOf',\n  /**\n   * lhs must be string[]\n   * rhs must be string[]\n   */\n  CONTAINS_ALL_OF = 'containsAllOf',\n  /**\n   * lhs must be string[]\n   * rhs must be string[]\n   */\n  CONTAINS_ANY_OF = 'containsAnyOf',\n  /**\n   * lhs must be string[]\n   * rhs must be string[]\n   */\n  CONTAINS_NONE_OF = 'containsNoneOf',\n  /**\n   * lhs must be string\n   * rhs must be string\n   *\n   * other comparisons have to be handled with a regex\n   */\n  STARTS_WITH = 'startsWith',\n  /**\n   * lhs must be string\n   * rhs must be string\n   *\n   * other comparisons have to be handled with a regex\n   */\n  NOT_STARTS_WITH = '!startsWith',\n  /**\n   * lhs must be string\n   * rhs must be string\n   *\n   * other comparisons have to be handled with a regex\n   */\n  ENDS_WITH = 'endsWith',\n  /**\n   * lhs must be string\n   * rhs must be string\n   *\n   * other comparisons have to be handled with a regex\n   */\n  NOT_ENDS_WITH = '!endsWith',\n  /**\n   * lhs must be string\n   * rhs must be string\n   *\n   * checks if lhs contains rhs as a substring\n   */\n  CONTAINS = 'contains',\n  /**\n   * lhs must be string\n   * rhs must be string\n   *\n   * checks if lhs does not contain rhs as a substring\n   */\n  NOT_CONTAINS = '!contains',\n  /**\n   * lhs must be string\n   * rhs must be never\n   */\n  EXISTS = 'ex',\n  /**\n   * lhs must be string\n   * rhs must be never\n   */\n  NOT_EXISTS = '!ex',\n  /**\n   * lhs must be string | number\n   * rhs must be string | number\n   */\n  GT = 'gt',\n  /**\n   * lhs must be string | number\n   * rhs must be string | number\n   */\n  GTE = 'gte',\n  /** */\n  /**\n   * lhs must be string | number\n   * rhs must be string | number\n   */\n  LT = 'lt',\n  /**\n   * lhs must be string | number\n   * rhs must be string | number\n   */\n  LTE = 'lte',\n  /**\n   * lhs must be string\n   * rhs must be string\n   */\n  REGEX = 'regex',\n  /**\n   * lhs must be string\n   * rhs must be string\n   */\n  NOT_REGEX = '!regex',\n  /**\n   * lhs must be date string\n   * rhs must be date string\n   *\n   * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#date_time_string_format\n   */\n  BEFORE = 'before',\n  /**\n   * lhs must be date string\n   * rhs must be date string\n   *\n   * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#date_time_string_format\n   */\n  AFTER = 'after',\n}\n\n// -----------------------------------------------------------------------------\n// Original data\n// -----------------------------------------------------------------------------\n\nexport namespace Original {\n  export type Data = {\n    definitions: Record<string, FlagDefinition>;\n    segments?: Original.Segment[];\n  };\n\n  export enum AccessorType {\n    SEGMENT = 'segment',\n    ENTITY = 'entity',\n  }\n\n  export type SegmentOutcome = SegmentAllOutcome | SegmentSplitOutcome;\n\n  export type Outcome =\n    | {\n        type: 'variant';\n        variantId: VariantId;\n      }\n    | {\n        type: 'split';\n        /**\n         * Based on which attribute the traffic should be split\n         */\n        base: EntityAccessor;\n        /**\n         * The distribution for each variant\n         */\n        weights: Record<VariantId, number>;\n        /**\n         * This variant will be used when the base attribute does not exist\n         */\n        defaultVariantId: VariantId;\n      }\n    | {\n        type: 'rollout';\n        /**\n         * Based on which attribute the traffic should be split\n         */\n        base: EntityAccessor;\n        /**\n         * Epoch ms when the rollout begins\n         */\n        startTimestamp: number;\n        /**\n         * The variant to roll away from\n         */\n        rollFromVariantId: VariantId;\n        /**\n         * The variant to roll towards\n         */\n        rollToVariantId: VariantId;\n        /**\n         * This variant will be used when the base attribute does not exist\n         */\n        defaultVariantId: VariantId;\n        /**\n         * Progressive rollout slots. Each slot has a promille value (0-100_000)\n         * representing the traffic for rollToVariant and a duration (how long\n         * it is served before moving to the next slot).\n         *       1 = 0.001%\n         *   1_000 =     1%\n         * 100_000 =   100%\n         *\n         * Once all slots are exhausted, the rollout is complete (100% rollToVariant).\n         */\n        slots: { promille: number; durationMs: number }[];\n      };\n\n  export type SegmentAllOutcome = {\n    type: 'all';\n  };\n\n  export type SegmentSplitOutcome = {\n    type: 'split';\n    /**\n     * Based on which attribute the passing percentage should be split.\n     *\n     * When the attribute does not exist the segment will not match.\n     */\n    base: EntityAccessor;\n    /**\n     * The promille that should pass the segment\n     *       1 = 0.001%\n     *   1_000 =     1%\n     * 100_000 =   100%\n     */\n    passPromille: number;\n  };\n\n  export type EntityAccessor = {\n    type: AccessorType.ENTITY;\n    kind: string;\n    attribute: string;\n  };\n  export type SegmentAccessor = { type: AccessorType.SEGMENT };\n\n  export type List = {\n    // backwards compatibility, we should only use \"list\" going forward\n    type: 'list/inline' | 'list';\n    items: { note?: string; value: string | number }[];\n    id?: never;\n  };\n\n  export type LHS = SegmentAccessor | EntityAccessor;\n  export type RHS =\n    | string\n    | number\n    | boolean\n    | List\n    | { type: 'regex'; pattern: string; flags: string };\n\n  export type Condition = {\n    lhs: LHS;\n    cmp: Comparator;\n    rhs: RHS;\n    /** When true, string comparisons are case-insensitive. */\n    i?: boolean;\n  };\n\n  export type Rule = {\n    conditions: Condition[];\n    outcome: Outcome;\n  };\n\n  export type SegmentRule = {\n    conditions: Condition[];\n    outcome: SegmentAllOutcome | SegmentSplitOutcome;\n  };\n\n  export type FlagVariant = {\n    id: string;\n    label?: string;\n    description?: string;\n    value: Value;\n  };\n\n  export type EnvironmentConfig = {\n    active: boolean;\n    pausedOutcome: Outcome;\n    /**\n     * If enabled, the flag will be reused from the given environment.\n     *\n     * The flag will not be evaluated, and the outcome will be the same as the given environment.\n     * This environment must be active and the flag must be active in this environment.\n     */\n    reuse: {\n      active: boolean;\n      environment: EnvironmentKey;\n    };\n    targets: Record<VariantId, TargetList>;\n    rules: Rule[];\n    fallthrough: Outcome;\n  };\n\n  /**\n   * A list of targets\n   *\n   * @example\n   * {\n   *   user: { id: { note?: string; value: string }[] }\n   * }\n   */\n  export type TargetList = Record<\n    string,\n    Record<string, { note?: string; value: string }[]>\n  >;\n\n  /**\n   * reusable conditions, with no outcome attached\n   */\n  export type Segment = {\n    id: string;\n    rules: SegmentRule[];\n    /**\n     * Explicitly include targets. Included targets will bypass conditions and exclusion.\n     *\n     * @example\n     * include: {\n     *   user: { id: { note?: string, value: string }[] }\n     * }\n     */\n    include: TargetList;\n    /**\n     * Explicitly exclude targets. Excluded targets will not be included in the segment, and bypass conditions.\n     *\n     * @example\n     * exclude: {\n     *   user: { id: { note?: string, value: string }[] }\n     * }\n     */\n    exclude: TargetList;\n  };\n\n  export type FlagDefinition = {\n    variants: FlagVariant[];\n    environments: Record<EnvironmentKey, EnvironmentConfig>;\n\n    /**\n     * A random seed to prevent split points in different flags\n     * from having the same targets. Otherwise the same set of ids would be\n     * opted into all flags for every rollout. By using a different seed for\n     * each flag the distribution is different for every flag.\n     *\n     * We don't use the slug as it might change, but we don't want the distribution\n     * to change when the slug changes.\n     *\n     * We don't use the id or createdAt etc as we want to be able to redistirbute\n     * by changing the seed.\n     */\n    seed: number;\n  };\n}\n\n// -----------------------------------------------------------------------------\n// Packed data\n// -----------------------------------------------------------------------------\n\nexport namespace Packed {\n  /**\n   * Idenitifies a variant based on its index in the variants array.\n   */\n  export type VariantIndex = number;\n\n  export type Data = {\n    /** map of flag keys to definitions */\n    definitions: Record<FlagKey, FlagDefinition>;\n    /** segments keyed by id */\n    segments?: Record<SegmentId, Segment>;\n  };\n\n  export enum AccessorType {\n    SEGMENT = 'segment',\n    ENTITY = 'entity',\n  }\n\n  export type SplitOutcome = {\n    type: 'split';\n    /**\n     * Based on which attribute the traffic should be split.\n     */\n    base: EntityAccessor;\n    /**\n     * The distribution of the individual groups.\n     *\n     * We use a single number array as the numbers will be placed in the\n     * same order as the variant list.\n     *\n     * So index 0 here is the distribution for variant 0, and so on.\n     */\n    weights: number[];\n    /**\n     * This variant will be used when the lhs does not exist\n     */\n    defaultVariant: VariantIndex;\n  };\n\n  export type RolloutOutcome = {\n    type: 'rollout';\n    /**\n     * Based on which attribute the traffic should be split.\n     */\n    base: EntityAccessor;\n    /**\n     * Epoch ms when the rollout begins.\n     */\n    startTimestamp: number;\n    /**\n     * Variant index to roll away from.\n     */\n    rollFromVariant: VariantIndex;\n    /**\n     * Variant index to roll towards.\n     */\n    rollToVariant: VariantIndex;\n    /**\n     * This variant will be used when the base attribute does not exist.\n     */\n    defaultVariant: VariantIndex;\n    /**\n     * Progressive rollout slots.\n     * Each tuple: [promille 0-100_000 for rollToVariant, durationMs (how long this slot is served)]\n     *       1 = 0.001%\n     *   1_000 =     1%\n     * 100_000 =   100%\n     *\n     * Once all slots are exhausted, the rollout is complete (100% rollToVariant).\n     */\n    slots: [number, number][];\n  };\n\n  export type SegmentAllOutcome = 1;\n\n  export type SegmentSplitOutcome = {\n    type: 'split';\n    /**\n     * Based on which attribute the traffic should be split.\n     *\n     * When the attribute does not exist the segment will not match.\n     */\n    base: EntityAccessor;\n    /**\n     * The promille that should pass the segment (1 = 0.001%; 1000 = 1%)\n     */\n    passPromille: number;\n  };\n\n  export type SegmentOutcome = SegmentAllOutcome | SegmentSplitOutcome;\n\n  export type Outcome = VariantIndex | SplitOutcome | RolloutOutcome;\n\n  // an array means it's an entity, the string \"segment\" means a segment\n  export type EntityAccessor = (string | number)[];\n  export type SegmentAccessor = 'segment';\n\n  /**\n   * An array means an entity\n   */\n  export type LHS = EntityAccessor | SegmentAccessor;\n\n  /**\n   * undefined when the rhs is not used by the comparator\n   * string[] when the rhs is a list of segments\n   * { type: 'regex'; pattern: string; flags: string } when the rhs is a regex\n   */\n  export type RHS =\n    | undefined\n    | string\n    | number\n    | boolean\n    | (string | number)[]\n    | { type: 'regex'; pattern: string; flags: string };\n\n  export type ConditionOptions = {\n    /** When true, string comparisons are case-insensitive. */\n    i?: boolean;\n  };\n\n  export type Condition =\n    | [LHS, Comparator, RHS]\n    | [LHS, Comparator, RHS, ConditionOptions | 'i']\n    | [LHS, Comparator.EXISTS]\n    | [LHS, Comparator.NOT_EXISTS];\n\n  export type Rule = {\n    conditions: Condition[];\n    outcome: Outcome;\n  };\n\n  export type SegmentRule = {\n    conditions: Condition[];\n    outcome: SegmentAllOutcome | SegmentSplitOutcome;\n  };\n\n  export type EnvironmentConfig =\n    /**\n     * Paused flags contain the pausedOutcome only.\n     */\n    | number\n    /** Allows reusing the configuration of another environment */\n    | { reuse: EnvironmentKey }\n    /**\n     * Active flags don't contain an explicit \"active\" state.\n     * The fact that they have a config means they are active.\n     */\n    | {\n        /**\n         * Each array item represents a variant.\n         *\n         * Each slot holds the targets for that variant.\n         *\n         * So the target list at index 0 is the targets for variant 0, and so on.\n         */\n        targets?: TargetList[];\n        rules?: Rule[];\n        fallthrough: Outcome;\n      };\n\n  /**\n   * A list of targets\n   *\n   * @example\n   * {\n   *   user: { id: string[] }\n   * }\n   */\n  export type TargetList = Record<string, Record<string, string[]>>;\n\n  /**\n   * reusable conditions, with no outcome attached\n   */\n  export type Segment = {\n    rules?: SegmentRule[];\n    /**\n     * Explicitly include targets. Included targets will bypass conditions and exclusion.\n     *\n     * @example\n     * include: {\n     *   user: { id: string[] }\n     * }\n     */\n    include?: TargetList;\n    /**\n     * Explicitly exclude targets. Excluded targets will not be included in the segment, and bypass conditions.\n     *\n     * @example\n     * exclude: {\n     *   user: { id: string[] }\n     * }\n     */\n    exclude?: TargetList;\n  };\n\n  export type FlagDefinition = {\n    /** for backwards compatibility with HappyKit */\n    variantIds?: string[];\n    /**  variants, packed down to just their values */\n    variants: Value[];\n    /**  environments */\n    environments: Record<EnvironmentKey, EnvironmentConfig>;\n    /**\n     * A random seed to prevent split points in different flags\n     * from having the same targets. Otherwise the same set of ids would be\n     * opted into all flags for every rollout. By using a different seed for\n     * each flag the distribution is different for every flag.\n     *\n     * We don't use the slug as it might change, but we don't want the distribution\n     * to change when the slug changes.\n     *\n     * We don't use the id or createdAt etc as we want to be able to redistirbute\n     * by changing the seed.\n     */\n    seed?: number;\n  };\n}\n","{\n  \"name\": \"@vercel/flags-core\",\n  \"version\": \"1.8.0\",\n  \"description\": \"A server-side client for Vercel Flags\",\n  \"keywords\": [\n    \"vercel\",\n    \"flags\",\n    \"vercel flags\",\n    \"feature flags\",\n    \"flags sdk\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/vercel/flags.git\"\n  },\n  \"license\": \"MIT\",\n  \"author\": \"Dominik Ferber <dominik@vercel.com>\",\n  \"sideEffects\": false,\n  \"type\": \"module\",\n  \"exports\": {\n    \".\": {\n      \"next-js\": {\n        \"types\": \"./dist/index.next-js.d.ts\",\n        \"default\": \"./dist/index.next-js.js\"\n      },\n      \"import\": {\n        \"types\": \"./dist/index.default.d.ts\",\n        \"default\": \"./dist/index.default.js\"\n      },\n      \"require\": {\n        \"types\": \"./dist/index.default.d.cts\",\n        \"default\": \"./dist/index.default.cjs\"\n      }\n    },\n    \"./openfeature\": {\n      \"next-js\": {\n        \"types\": \"./dist/openfeature.next-js.d.ts\",\n        \"default\": \"./dist/openfeature.next-js.js\"\n      },\n      \"import\": {\n        \"types\": \"./dist/openfeature.default.d.ts\",\n        \"default\": \"./dist/openfeature.default.js\"\n      },\n      \"require\": {\n        \"types\": \"./dist/openfeature.default.d.cts\",\n        \"default\": \"./dist/openfeature.default.cjs\"\n      }\n    }\n  },\n  \"main\": \"./dist/index.default.js\",\n  \"typesVersions\": {\n    \"*\": {\n      \".\": [\n        \"dist/index.default.d.ts\",\n        \"dist/index.default.d.cts\"\n      ],\n      \"openfeature\": [\n        \"dist/openfeature.default.d.ts\",\n        \"dist/openfeature.default.d.cts\"\n      ]\n    }\n  },\n  \"files\": [\n    \"dist\",\n    \"CHANGELOG.md\"\n  ],\n  \"scripts\": {\n    \"build\": \"tsup\",\n    \"dev\": \"tsup --watch\",\n    \"check\": \"biome check\",\n    \"test\": \"vitest --run\",\n    \"test:watch\": \"vitest\",\n    \"type-check\": \"tsc --noEmit\"\n  },\n  \"dependencies\": {\n    \"@vercel/functions\": \"^3.4.3\",\n    \"@vercel/oidc\": \"3.5.0\",\n    \"jose\": \"5.2.1\",\n    \"js-xxhash\": \"4.0.0\"\n  },\n  \"devDependencies\": {\n    \"@arethetypeswrong/cli\": \"0.18.2\",\n    \"@types/node\": \"22.14.0\",\n    \"next\": \"^16.2.12\",\n    \"tsup\": \"8.5.1\",\n    \"typescript\": \"5.6.3\",\n    \"vite\": \"8.1.5\",\n    \"vitest\": \"4.1.10\"\n  },\n  \"peerDependencies\": {\n    \"@openfeature/server-sdk\": \"1.18.0\",\n    \"next\": \"*\"\n  },\n  \"peerDependenciesMeta\": {\n    \"@openfeature/server-sdk\": {\n      \"optional\": true\n    },\n    \"next\": {\n      \"optional\": true\n    }\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  }\n}\n","import { version } from '../../package.json';\nimport type { OutcomeType, ResolutionReason } from '../types';\n\n/**\n * Only used internally for now.\n */\nexport function internalReportValue(\n  key: string,\n  value: unknown,\n  data: {\n    originProjectId?: string;\n    originProvider?: 'vercel';\n    outcomeType?: OutcomeType;\n    reason?: ResolutionReason | 'override';\n  },\n) {\n  const symbol = Symbol.for('@vercel/request-context');\n  const ctx = Reflect.get(globalThis, symbol)?.get();\n  const reportFlagValue = ctx?.flags?.reportValue;\n  if (typeof reportFlagValue !== 'function') return;\n\n  reportFlagValue.call(ctx.flags, key, value, {\n    sdkVersion: version,\n    ...data,\n  });\n}\n","import {\n  type BulkEvaluationInput,\n  bulkEvaluate as bulkEvalFlags,\n  evaluate as evalFlag,\n} from './evaluate';\nimport { internalReportValue } from './lib/report-value';\nimport type {\n  BulkEvaluateInput,\n  BundledDefinitions,\n  ControllerInterface,\n  Datafile,\n  EvaluationResult,\n  Metrics,\n  Packed,\n} from './types';\nimport { ErrorCode, ResolutionReason } from './types';\nimport type { TrackEvaluationOptions } from './utils/usage/flags-evaluation';\n\nexport type ControllerInstance = {\n  controller: ControllerInterface;\n  initialized: boolean;\n  initPromise: Promise<void> | null;\n};\n\nexport const controllerInstanceMap = new Map<number, ControllerInstance>();\n\ntype EvaluationTrackingController = ControllerInterface & {\n  trackEvaluation?: (options: TrackEvaluationOptions) => void;\n};\n\nfunction getInstance(id: number): ControllerInstance {\n  const instance = controllerInstanceMap.get(id);\n  if (!instance) {\n    throw new Error(\n      `@vercel/flags-core: Client instance ${id} not found. It may have been shut down.`,\n    );\n  }\n  return instance;\n}\n\nexport function initialize(id: number): Promise<void> {\n  return getInstance(id).controller.initialize();\n}\n\nexport function shutdown(id: number): void | Promise<void> {\n  return getInstance(id).controller.shutdown();\n}\n\nexport function getDatafile(id: number) {\n  return getInstance(id).controller.getDatafile();\n}\n\nexport function getFallbackDatafile(id: number): Promise<BundledDefinitions> {\n  const ds = getInstance(id).controller;\n  if (ds.getFallbackDatafile) return ds.getFallbackDatafile();\n  throw new Error('flags: This data source does not support fallbacks');\n}\n\nfunction trackEvaluation(\n  controller: EvaluationTrackingController,\n  options: TrackEvaluationOptions,\n): void {\n  controller.trackEvaluation?.(options);\n}\n\nexport async function evaluate<T, E = Record<string, unknown>>(\n  id: number,\n  flagKey: string,\n  defaultValue?: T,\n  entities?: E,\n): Promise<EvaluationResult<T>> {\n  const controller = getInstance(id).controller as EvaluationTrackingController;\n\n  let datafile: Datafile;\n  try {\n    datafile = await controller.read();\n  } catch (error) {\n    // All data sources failed. Fall back to defaultValue if provided.\n    if (defaultValue !== undefined) {\n      const result: EvaluationResult<T> = {\n        value: defaultValue,\n        variantId: null,\n        reason: ResolutionReason.ERROR,\n        errorMessage:\n          error instanceof Error ? error.message : 'Failed to read datafile',\n      };\n\n      trackEvaluation(controller, {\n        flagKey,\n        variant: null,\n        reason: result.reason,\n      });\n\n      return result;\n    }\n    throw error;\n  }\n\n  const flagDefinition = datafile.definitions[flagKey] as Packed.FlagDefinition;\n\n  if (flagDefinition === undefined) {\n    if (datafile.projectId) {\n      internalReportValue(flagKey, defaultValue, {\n        originProjectId: datafile.projectId,\n        originProvider: 'vercel',\n        reason: ResolutionReason.ERROR,\n      });\n    }\n\n    const result: EvaluationResult<T> = {\n      value: defaultValue,\n      variantId: null,\n      reason: ResolutionReason.ERROR,\n      errorCode: ErrorCode.FLAG_NOT_FOUND,\n      errorMessage: `@vercel/flags-core: Definition not found for flag \"${flagKey}\"`,\n      metrics: {\n        evaluationMs: 0,\n        readMs: datafile.metrics.readMs,\n        source: datafile.metrics.source,\n        cacheStatus: datafile.metrics.cacheStatus,\n        connectionState: datafile.metrics.connectionState,\n        mode: datafile.metrics.mode,\n      },\n    };\n    trackEvaluation(controller, {\n      flagKey,\n      variant: null,\n      reason: result.reason,\n    });\n    return result;\n  }\n\n  const evalStartTime = Date.now();\n  const result = evalFlag<T>({\n    defaultValue,\n    definition: flagDefinition,\n    environment: datafile.environment,\n    entities: entities ?? {},\n    segments: datafile.segments,\n  });\n  const evaluationDurationMs = Date.now() - evalStartTime;\n\n  if (datafile.projectId) {\n    internalReportValue(flagKey, result.value, {\n      originProjectId: datafile.projectId,\n      originProvider: 'vercel',\n      reason: result.reason,\n      outcomeType:\n        result.reason !== ResolutionReason.ERROR\n          ? result.outcomeType\n          : undefined,\n    });\n  }\n\n  trackEvaluation(controller, {\n    flagKey,\n    variant: result.variantId,\n    reason: result.reason,\n  });\n\n  return Object.assign(result, {\n    metrics: {\n      evaluationMs: evaluationDurationMs,\n      readMs: datafile.metrics.readMs,\n      source: datafile.metrics.source,\n      cacheStatus: datafile.metrics.cacheStatus,\n      connectionState: datafile.metrics.connectionState,\n      mode: datafile.metrics.mode,\n    },\n  });\n}\n\nexport async function bulkEvaluate<T, E = Record<string, unknown>>(\n  id: number,\n  flags: BulkEvaluateInput<T>[],\n  entities?: E,\n): Promise<Record<string, EvaluationResult<T>>> {\n  const controller = getInstance(id).controller as EvaluationTrackingController;\n\n  let datafile: Datafile;\n  try {\n    datafile = await controller.read();\n  } catch (error) {\n    const errorMessage =\n      error instanceof Error ? error.message : 'Failed to read datafile';\n\n    const results: Record<string, EvaluationResult<T>> = {};\n    for (const flag of flags) {\n      results[flag.key] = {\n        value: flag.defaultValue,\n        reason: ResolutionReason.ERROR,\n        errorMessage,\n        variantId: null,\n      };\n      trackEvaluation(controller, {\n        flagKey: flag.key,\n        variant: null,\n        reason: ResolutionReason.ERROR,\n      });\n    }\n    return results;\n  }\n\n  const baseMetrics: Metrics = {\n    readMs: datafile.metrics.readMs,\n    source: datafile.metrics.source,\n    cacheStatus: datafile.metrics.cacheStatus,\n    connectionState: datafile.metrics.connectionState,\n    mode: datafile.metrics.mode,\n  };\n\n  const projectId = datafile.projectId;\n  const results: Record<string, EvaluationResult<T>> = {};\n  const toEvaluate: Record<string, BulkEvaluationInput<T>> = {};\n\n  for (const flag of flags) {\n    const { key, defaultValue } = flag;\n    const flagDefinition = datafile.definitions[key] as Packed.FlagDefinition;\n\n    if (flagDefinition === undefined) {\n      if (projectId) {\n        internalReportValue(key, defaultValue, {\n          originProjectId: projectId,\n          originProvider: 'vercel',\n          reason: ResolutionReason.ERROR,\n        });\n      }\n      results[key] = {\n        value: defaultValue,\n        reason: ResolutionReason.ERROR,\n        errorCode: ErrorCode.FLAG_NOT_FOUND,\n        errorMessage: `@vercel/flags-core: Definition not found for flag \"${key}\"`,\n        metrics: { evaluationMs: 0, ...baseMetrics },\n        variantId: null,\n      };\n      trackEvaluation(controller, {\n        flagKey: key,\n        variant: null,\n        reason: ResolutionReason.ERROR,\n      });\n      continue;\n    }\n\n    toEvaluate[key] = { definition: flagDefinition, defaultValue };\n  }\n\n  const evalStartTime = Date.now();\n  const evaluated = bulkEvalFlags<T>(toEvaluate, {\n    entities: (entities ?? {}) as Record<string, unknown>,\n    environment: datafile.environment,\n    segments: datafile.segments,\n  });\n  const evaluationDurationMs = Date.now() - evalStartTime;\n\n  for (const key in toEvaluate) {\n    const result = evaluated[key]!;\n    if (projectId) {\n      internalReportValue(key, result.value, {\n        originProjectId: projectId,\n        originProvider: 'vercel',\n        reason: result.reason,\n        outcomeType:\n          result.reason !== ResolutionReason.ERROR\n            ? result.outcomeType\n            : undefined,\n      });\n    }\n    trackEvaluation(controller, {\n      flagKey: key,\n      variant: result.variantId,\n      reason: result.reason,\n    });\n    results[key] = Object.assign(result, {\n      metrics: { evaluationMs: evaluationDurationMs, ...baseMetrics },\n    });\n  }\n\n  return results;\n}\n","import type {\n  bulkEvaluate,\n  evaluate,\n  getDatafile,\n  getFallbackDatafile,\n  initialize,\n  shutdown,\n} from './controller-fns';\nimport {\n  type ControllerInstance,\n  controllerInstanceMap,\n} from './controller-fns';\nimport type {\n  BulkEvaluateInput,\n  BundledDefinitions,\n  ControllerInterface,\n  EvaluationResult,\n  FlagsClient,\n  Value,\n} from './types';\n\nlet idCount = 0;\n\nasync function performInitialize(\n  instance: ControllerInstance,\n  initFn: () => Promise<void>,\n): Promise<void> {\n  try {\n    await initFn();\n    instance.initialized = true;\n  } catch (error) {\n    // Clear so next call can retry\n    instance.initPromise = null;\n    throw error;\n  }\n}\n\nexport function createCreateRawClient(fns: {\n  initialize: typeof initialize;\n  shutdown: typeof shutdown;\n  getFallbackDatafile: typeof getFallbackDatafile;\n  evaluate: typeof evaluate;\n  bulkEvaluate: typeof bulkEvaluate;\n  getDatafile: typeof getDatafile;\n}) {\n  return function createRawClient<Entities = Record<string, unknown>>({\n    controller,\n    origin,\n  }: {\n    controller: ControllerInterface;\n    origin?: { provider: string; sdkKey?: string };\n  }): FlagsClient<Entities> {\n    const id = idCount++;\n    controllerInstanceMap.set(id, {\n      controller,\n      initialized: false,\n      initPromise: null,\n    });\n\n    const api = {\n      origin,\n      initialize: async () => {\n        let instance = controllerInstanceMap.get(id);\n        if (!instance) {\n          instance = { controller, initialized: false, initPromise: null };\n          controllerInstanceMap.set(id, instance);\n        }\n\n        // skip if already initialized\n        if (instance.initialized) return;\n\n        if (!instance.initPromise) {\n          instance.initPromise = performInitialize(instance, () =>\n            fns.initialize(id),\n          );\n        }\n\n        return instance.initPromise;\n      },\n      shutdown: async () => {\n        await fns.shutdown(id);\n        controllerInstanceMap.delete(id);\n      },\n      getDatafile: async () => {\n        const instance = controllerInstanceMap.get(id);\n        if (instance?.initPromise) {\n          try {\n            await instance.initPromise;\n          } catch {\n            // Initialization failed — let getDatafile handle its own fallbacks\n          }\n        }\n        return fns.getDatafile(id);\n      },\n      getFallbackDatafile: (): Promise<BundledDefinitions> => {\n        return fns.getFallbackDatafile(id);\n      },\n      evaluate: async <T = Value, E = Entities>(\n        flagKey: string,\n        defaultValue?: T,\n        entities?: E,\n      ): Promise<EvaluationResult<T>> => {\n        const instance = controllerInstanceMap.get(id);\n        if (!instance?.initialized) {\n          try {\n            await api.initialize();\n          } catch {\n            // Initialization failed — let evaluate() handle the fallback\n            // chain (last known value → datafile → bundled → defaultValue → throw)\n          }\n        }\n        return fns.evaluate<T, E>(id, flagKey, defaultValue, entities);\n      },\n      bulkEvaluate: async <T = Value, E = Entities>(\n        flags: BulkEvaluateInput<T>[],\n        entities?: E,\n      ): Promise<Record<string, EvaluationResult<T>>> => {\n        const instance = controllerInstanceMap.get(id);\n        if (!instance?.initialized) {\n          try {\n            await api.initialize();\n          } catch {\n            // Initialization failed — let bulkEvaluate() handle the fallback\n            // chain (last known value → datafile → bundled → defaultValue → throw)\n          }\n        }\n        return fns.bulkEvaluate<T, E>(id, flags, entities);\n      },\n    };\n    return api;\n  };\n}\n","// The @vercel/flags-definitions module is created at build time by Vercel CLI\n// in node_modules/. This is a fallback mechanism used so the app can always\n// fall back to a bundled version of the definitions, even if the flags network\n// is degraded or unavailable.\n//\n\nimport type { Auth, BundledDefinitionsLookup } from '../controller/auth';\nimport type { BundledDefinitions, BundledDefinitionsResult } from '../types';\n\n/** In-memory cache of SDK key to its hashed value, so we don't re-hash repeatedly. */\nconst sdkKeyHashCache = new Map<string, Promise<string>>();\n\n/** Computes a SHA-256 hex digest of the given SDK key. */\nasync function computeHash(sdkKey: string): Promise<string> {\n  const hashBuffer = await crypto.subtle.digest(\n    'SHA-256',\n    new TextEncoder().encode(sdkKey),\n  );\n  const hashArray = new Uint8Array(hashBuffer);\n  return Array.from(hashArray)\n    .map((b) => b.toString(16).padStart(2, '0'))\n    .join('');\n}\n\n/** Returns a cached promise for the SHA-256 hash of the given SDK key. */\nfunction hashSdkKey(sdkKey: string): Promise<string> {\n  const cached = sdkKeyHashCache.get(sdkKey);\n  if (cached) return cached;\n\n  const promise = computeHash(sdkKey);\n  sdkKeyHashCache.set(sdkKey, promise);\n  return promise;\n}\n\n/**\n * Reads the local definitions that get bundled at build time.\n */\nexport async function readBundledDefinitions(\n  auth: Auth,\n): Promise<BundledDefinitionsResult> {\n  let get: (sdkKey: string) => BundledDefinitions | null;\n  try {\n    const module = await import(\n      /* turbopackOptional: true */\n      '@vercel/flags-definitions'\n    );\n    get = module.get as (sdkKey: string) => BundledDefinitions | null;\n  } catch (error) {\n    // If the module doesn't exist, the prepare script didn't run\n    if (\n      error &&\n      typeof error === 'object' &&\n      'code' in error &&\n      error.code === 'MODULE_NOT_FOUND'\n    ) {\n      return { definitions: null, state: 'missing-file' };\n    }\n\n    return { definitions: null, state: 'unexpected-error', error };\n  }\n\n  if (typeof get !== 'function') {\n    return { definitions: null, state: 'missing-file' };\n  }\n\n  let lookup: BundledDefinitionsLookup;\n  try {\n    lookup = await auth.resolveBundledDefinitionsLookup();\n  } catch (error) {\n    return { definitions: null, state: 'unexpected-error', error };\n  }\n\n  if (lookup.type === 'project-id') {\n    const entry = get(lookup.projectId);\n    return entry\n      ? { definitions: entry, state: 'ok' }\n      : { definitions: null, state: 'missing-entry' };\n  }\n\n  // Try plain sdk key first for bundles created by older CLI versions.\n  const entry = get(lookup.sdkKey);\n  if (entry) return { definitions: entry, state: 'ok' };\n\n  // try hashed key but catch any errors\n  try {\n    const hashedKey = await hashSdkKey(lookup.sdkKey);\n    // try original key (older cli versions) and hashed key (newer cli versions)\n    const hashedEntry = get(hashedKey);\n    if (hashedEntry) return { definitions: hashedEntry, state: 'ok' };\n  } catch (error) {\n    return { definitions: null, state: 'unexpected-error', error };\n  }\n\n  return { definitions: null, state: 'missing-entry' };\n}\n","import { getVercelOidcToken } from '@vercel/oidc';\nimport { version } from '../../package.json';\nimport type { Auth } from '../controller/auth';\nimport type { MetricEnvironment } from '../types';\nimport { getRetryDelayMs } from './backoff';\nimport type { FlushReason } from './scheduler';\nimport type { IngestEvent, UsageEvent } from './usage/events';\n\nconst MAX_RETRIES = 3;\n\n/**\n * Maximum number of events sent in a single POST to the ingest endpoint.\n *\n * Flushes are cut purely by time (see Scheduler), so a single flush can carry\n * arbitrarily many events. Chunking each send is what bounds the request size:\n * the server rejects request bodies with more events than its `maxItems` cap, so this\n * constant must stay below that cap.\n */\nexport const MAX_EVENTS_PER_REQUEST = 2000;\n\nexport const EVALUATING_OIDC_TOKEN_HEADER = 'X-Vercel-Flags-OIDC-Token';\nexport const FLUSH_REASON_HEADER = 'X-Vercel-Flags-Flush-Reason';\n\nconst isDebugMode = process.env.DEBUG?.includes('@vercel/flags-core');\n\nconst debugLog = (...args: any[]) => {\n  if (!isDebugMode) return;\n  console.log(...args);\n};\n\nexport interface IngestOptions {\n  auth: Auth;\n  host: string;\n  fetch: typeof fetch;\n  metricEnvironment?: MetricEnvironment;\n}\n\nasync function getEvaluatingOidcToken(auth: Auth): Promise<string | undefined> {\n  if (!auth.sdkKey) return undefined;\n\n  try {\n    return await getVercelOidcToken();\n  } catch {\n    return undefined;\n  }\n}\n\nasync function getIngestHeaders(\n  options: IngestOptions,\n  flushReason: FlushReason,\n): Promise<Record<string, string>> {\n  const token = await options.auth.resolveToken();\n  const evaluatingOidcToken = await getEvaluatingOidcToken(options.auth);\n\n  return {\n    'Content-Type': 'application/json',\n    Authorization: `Bearer ${token}`,\n    'User-Agent': `VercelFlagsCore/${version}`,\n    [FLUSH_REASON_HEADER]: flushReason,\n    ...((options.metricEnvironment ?? process.env.VERCEL_ENV)\n      ? {\n          'X-Vercel-Env':\n            options.metricEnvironment ?? (process.env.VERCEL_ENV as string),\n        }\n      : null),\n    ...(evaluatingOidcToken\n      ? { [EVALUATING_OIDC_TOKEN_HEADER]: evaluatingOidcToken }\n      : null),\n    ...(isDebugMode ? { 'x-vercel-debug-ingest': '1' } : null),\n  };\n}\n\nexport async function sendIngestEvents(\n  options: IngestOptions,\n  events: UsageEvent[],\n  flushId: number,\n  flushReason: FlushReason,\n): Promise<void> {\n  const eventsToSend = events.map((event) => event.ingestEvent());\n\n  for (let i = 0; i < eventsToSend.length; i += MAX_EVENTS_PER_REQUEST) {\n    await sendIngestChunk(\n      options,\n      eventsToSend.slice(i, i + MAX_EVENTS_PER_REQUEST),\n      flushId,\n      flushReason,\n    );\n  }\n}\n\nasync function sendIngestChunk(\n  options: IngestOptions,\n  eventsToSend: IngestEvent[],\n  flushId: number,\n  flushReason: FlushReason,\n): Promise<void> {\n  for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {\n    try {\n      const response = await options.fetch(`${options.host}/v1/ingest`, {\n        method: 'POST',\n        headers: await getIngestHeaders(options, flushReason),\n        body: JSON.stringify(eventsToSend),\n      });\n\n      debugLog(\n        `@vercel/flags-core: Ingest response ${response.status} for ${eventsToSend.length} events on ${response.headers.get('x-vercel-id')}`,\n      );\n\n      if (response.ok) {\n        break;\n      }\n\n      throw new Error(\n        `Ingest endpoint responded with status ${response.status} for ${eventsToSend.length} events on request ${response.headers.get('x-vercel-id')}.\\n` +\n          `Response body: ${await response.text().catch(() => null)}`,\n      );\n    } catch (error) {\n      console.error(\n        `@vercel/flags-core: Error sending events (attempt=${attempt}/${MAX_RETRIES} flushId=${flushId}):`,\n        error,\n      );\n      if (attempt < MAX_RETRIES) {\n        const delayMs = getRetryDelayMs(attempt);\n        await new Promise((res) => setTimeout(res, delayMs));\n      } else {\n        // All retries exhausted - surface a structured warning so consumers\n        // can alert on dropped batches. The events are not persisted anywhere.\n        console.error(\n          `@vercel/flags-core: Dropped ${eventsToSend.length} events after ${MAX_RETRIES} attempts (flushId=${flushId})`,\n        );\n      }\n    }\n  }\n}\n","/**\n * Backoff and jitter utilities for retry loops.\n *\n * The functions here are intentionally generic so they can be used wherever\n * the SDK retries an operation. They use `Math.random` directly; mock it from\n * tests if you need deterministic behaviour.\n */\n\nconst DEFAULT_BASE_MS = 250;\nconst DEFAULT_CAP_MS = 5000;\n\nexport interface RetryDelayOptions {\n  /**\n   * The base delay in milliseconds. With Full Jitter, the first failed attempt\n   * sleeps in `[0, baseMs)`, the second in `[0, baseMs * 2)`, etc.\n   * Defaults to 250ms.\n   */\n  baseMs?: number;\n  /**\n   * Hard ceiling on the computed delay. Defaults to 5000ms.\n   */\n  capMs?: number;\n}\n\n/**\n * Returns the sleep duration before the next retry attempt using AWS-style\n * \"Full Jitter\" exponential backoff.\n *\n * @param attempt The 1-indexed attempt number that just failed.\n * @see https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter\n */\nexport function getRetryDelayMs(\n  attempt: number,\n  options: RetryDelayOptions = {},\n): number {\n  const baseMs = options.baseMs ?? DEFAULT_BASE_MS;\n  const capMs = options.capMs ?? DEFAULT_CAP_MS;\n\n  const ceiling = Math.min(capMs, baseMs * 2 ** Math.max(0, attempt - 1));\n  return Math.floor(Math.random() * ceiling);\n}\n\n/**\n * Returns `baseMs` perturbed by `±ratio` of itself, drawn uniformly from\n * `[baseMs * (1 - ratio), baseMs * (1 + ratio))`. Useful for desynchronizing\n * fixed-interval timers across independent processes.\n *\n * @param baseMs The target mean wait, in milliseconds.\n * @param ratio The fractional jitter to apply on each side, in `[0, 1)`.\n */\nexport function getJitteredWaitMs(baseMs: number, ratio: number): number {\n  const min = baseMs * (1 - ratio);\n  const span = baseMs * 2 * ratio;\n  return Math.floor(min + Math.random() * span);\n}\n","interface RequestContext {\n  ctx: object | undefined;\n  headers: Record<string, string> | undefined;\n}\n\nconst SYMBOL_FOR_REQ_CONTEXT = Symbol.for('@vercel/request-context');\nconst fromSymbol = globalThis as typeof globalThis & {\n  [key: symbol]:\n    | { get?: () => { headers?: Record<string, string> } }\n    | undefined;\n};\n\n/**\n * Gets the Vercel request context and headers from the global symbol.\n */\nexport function getRequestContext(): RequestContext {\n  try {\n    const ctx = fromSymbol[SYMBOL_FOR_REQ_CONTEXT]?.get?.();\n    if (ctx && Object.hasOwn(ctx, 'headers')) {\n      return {\n        ctx,\n        headers: ctx.headers as Record<string, string>,\n      };\n    }\n    return { ctx, headers: undefined };\n  } catch {\n    return { ctx: undefined, headers: undefined };\n  }\n}\n","import { waitUntil } from '@vercel/functions';\nimport { getJitteredWaitMs } from './backoff';\n\nconst IDLE_FLUSH_WAIT_MS = 5000;\nconst IDLE_FLUSH_JITTER_RATIO = 0.2;\nconst MAX_FLUSH_WAIT_MS = 60000;\n\nexport type FlushReason = 'idle_timeout' | 'max_timeout' | 'shutdown';\n\n/**\n * Schedule helper that flushes when any of the following occur:\n * - the idle window elapses ({@link IDLE_FLUSH_WAIT_MS}, reset on every event), or\n * - the max window elapses ({@link MAX_FLUSH_WAIT_MS}, starts with the batch and is\n *   never reset, so a batch always flushes under continuous traffic).\n *\n * Flushing is purely time-based; batches are only cut down to size when the\n * ingest events are sent (see MAX_EVENTS_PER_REQUEST in ingest.ts).\n *\n * The scheduled flush awaits {@link onFlush} (including its ingest send + retries),\n * so the promise handed to `waitUntil` does not resolve until ingest completes.\n */\nexport class Scheduler {\n  private resolveWait: ((reason: FlushReason) => void) | null = null;\n  private pending: null | Promise<void> = null;\n  private idleTimeout: null | ReturnType<typeof setTimeout> = null;\n  private maxTimeout: null | ReturnType<typeof setTimeout> = null;\n\n  constructor(\n    private readonly onFlush: (reason: FlushReason) => void | Promise<void>,\n  ) {}\n\n  scheduleFlush(): void {\n    if (!this.pending) {\n      this.pending = (async () => {\n        // wait for a timeout or the event count to reach the batch size\n        const reason = await new Promise<FlushReason>((res) => {\n          this.resolveWait = res;\n        });\n\n        // free state so new events start a fresh batch while ingest runs\n        this.reset();\n\n        // genuinely await ingest (incl. retries) so waitUntil covers the send\n        await this.onFlush(reason);\n      })();\n\n      try {\n        waitUntil(this.pending);\n      } catch {\n        // waitUntil is best-effort; falling through leaves a floating promise\n      }\n\n      // max window: starts with the batch and is never reset\n      this.maxTimeout = setTimeout(\n        () => this.resolveScheduledFlush('max_timeout'),\n        MAX_FLUSH_WAIT_MS,\n      );\n    }\n\n    // idle window: reset on every event\n    this.resetIdleTimeout();\n  }\n\n  /**\n   * Resolves any in-flight scheduled flush and waits for its ingest to finish.\n   */\n  async shutdown(): Promise<void> {\n    this.clearTimeouts();\n    const pending = this.pending;\n    this.resolveScheduledFlush('shutdown');\n    if (pending) await pending;\n  }\n\n  private resetIdleTimeout(): void {\n    if (this.idleTimeout) clearTimeout(this.idleTimeout);\n    this.idleTimeout = setTimeout(\n      () => this.resolveScheduledFlush('idle_timeout'),\n      getJitteredWaitMs(IDLE_FLUSH_WAIT_MS, IDLE_FLUSH_JITTER_RATIO),\n    );\n  }\n\n  private resolveScheduledFlush(reason: FlushReason): void {\n    this.clearTimeouts();\n    this.resolveWait?.(reason);\n  }\n\n  private reset(): void {\n    this.pending = null;\n    this.resolveWait = null;\n    this.clearTimeouts();\n  }\n\n  private clearTimeouts(): void {\n    if (this.idleTimeout) {\n      clearTimeout(this.idleTimeout);\n      this.idleTimeout = null;\n    }\n    if (this.maxTimeout) {\n      clearTimeout(this.maxTimeout);\n      this.maxTimeout = null;\n    }\n  }\n}\n","import type { UsageEvent } from './events';\n\nexport interface TrackReadOptions {\n  /** Whether the config was read from in-memory cache or embedded bundle */\n  configOrigin: 'in-memory' | 'embedded';\n  /** HIT when definitions exist in memory, MISS when not, BYPASS when using fallback as primary source */\n  cacheStatus?: 'HIT' | 'MISS' | 'BYPASS';\n  /** FOLLOWING when streaming, REFRESHING when polling, NONE otherwise */\n  cacheAction?: 'REFRESHING' | 'FOLLOWING' | 'NONE';\n  /** True for the very first getData call */\n  cacheIsFirstRead?: boolean;\n  /** Whether the cache read was blocking */\n  cacheIsBlocking?: boolean;\n  /** Duration in milliseconds from start of getData until trackRead */\n  duration?: number;\n  /** Timestamp when the config was last updated */\n  configUpdatedAt?: number;\n  /** The mode the SDK is operating in */\n  mode?: 'poll' | 'stream' | 'build' | 'offline';\n  /** Revision of the config */\n  revision?: number;\n}\n\nexport class FlagsConfigReadEvent implements UsageEvent {\n  private readonly ts = Date.now();\n\n  private payload: {\n    deploymentId?: string;\n    region?: string;\n    invocationHost?: string;\n    vercelRequestId?: string;\n    cacheStatus?: 'HIT' | 'MISS' | 'BYPASS' | 'STALE';\n    cacheAction?: 'REFRESHING' | 'FOLLOWING' | 'NONE';\n    cacheIsBlocking?: boolean;\n    cacheIsFirstRead?: boolean;\n    duration?: number;\n    configUpdatedAt?: number;\n    configOrigin?: 'in-memory' | 'embedded' | 'poll' | 'stream' | 'constructor';\n    mode?: 'poll' | 'stream' | 'build' | 'offline';\n    revision?: string;\n    environment?: string;\n  };\n\n  constructor(\n    headers: Record<string, string> | undefined,\n    options?: TrackReadOptions,\n  ) {\n    this.payload = {\n      deploymentId: process.env.VERCEL_DEPLOYMENT_ID,\n      region: process.env.VERCEL_REGION,\n    };\n\n    if (headers) {\n      this.payload.vercelRequestId = headers['x-vercel-id'] ?? undefined;\n      this.payload.invocationHost = headers.host ?? undefined;\n    }\n\n    if (options) {\n      this.payload.configOrigin = options.configOrigin;\n      if (options.cacheStatus !== undefined) {\n        this.payload.cacheStatus = options.cacheStatus;\n      }\n      if (options.cacheAction !== undefined) {\n        this.payload.cacheAction = options.cacheAction;\n      }\n      if (options.cacheIsFirstRead !== undefined) {\n        this.payload.cacheIsFirstRead = options.cacheIsFirstRead;\n      }\n      if (options.cacheIsBlocking !== undefined) {\n        this.payload.cacheIsBlocking = options.cacheIsBlocking;\n      }\n      if (options.duration !== undefined) {\n        this.payload.duration = options.duration;\n      }\n      if (options.configUpdatedAt !== undefined) {\n        this.payload.configUpdatedAt = options.configUpdatedAt;\n      }\n      if (options.mode !== undefined) {\n        this.payload.mode = options.mode;\n      }\n      if (options.revision !== undefined) {\n        this.payload.revision = String(options.revision);\n      }\n    }\n\n    const environment =\n      process.env.VERCEL_ENV || process.env.NODE_ENV || undefined;\n    if (environment) {\n      this.payload.environment = environment;\n    }\n  }\n\n  ingestEvent() {\n    return {\n      type: 'FLAGS_CONFIG_READ' as const,\n      ts: this.ts,\n      payload: this.payload,\n    };\n  }\n}\n","import type { ResolutionReason, VariantId } from '../../types';\nimport type { UsageEvent } from './events';\n\nexport interface TrackEvaluationOptions {\n  flagKey: string;\n  variant: VariantId | null;\n  reason: ResolutionReason;\n  clientName?: string;\n}\n\nconst MINUTE_MS = 60_000;\n\nexport function minuteBucketTs(ts = Date.now()): number {\n  return Math.floor(ts / MINUTE_MS) * MINUTE_MS;\n}\n\nexport type BucketedTrackEvaluationOptions = TrackEvaluationOptions & {\n  bucketTs: number;\n};\n\nexport function evaluationBatchKey(\n  options: BucketedTrackEvaluationOptions,\n): string {\n  return JSON.stringify([\n    options.flagKey,\n    options.variant,\n    options.reason,\n    options.clientName ?? null,\n    options.bucketTs,\n  ]);\n}\n\nexport class FlagsEvaluationEvent implements UsageEvent {\n  private readonly ts = Date.now();\n\n  payload: {\n    flagKey: string;\n    variant?: string;\n    reason: ResolutionReason;\n    clientName?: string;\n    evaluationCount: number;\n    periodStartedAt: number;\n  };\n\n  constructor(eventOptions: BucketedTrackEvaluationOptions) {\n    this.payload = {\n      flagKey: eventOptions.flagKey,\n      variant: eventOptions.variant ?? undefined,\n      reason: eventOptions.reason,\n      evaluationCount: 1,\n      periodStartedAt: eventOptions.bucketTs,\n    };\n\n    if (eventOptions.clientName) {\n      this.payload.clientName = eventOptions.clientName;\n    }\n  }\n\n  increment(): void {\n    this.payload.evaluationCount += 1;\n  }\n\n  ingestEvent() {\n    return {\n      type: 'FLAG_EVALUATION' as const,\n      ts: this.ts,\n      payload: this.payload,\n    };\n  }\n}\n","import { type IngestOptions, sendIngestEvents } from './ingest';\nimport { getRequestContext } from './request-context';\nimport { type FlushReason, Scheduler } from './scheduler';\nimport {\n  FlagsConfigReadEvent,\n  type TrackReadOptions,\n} from './usage/flags-config-read';\nimport {\n  evaluationBatchKey,\n  FlagsEvaluationEvent,\n  minuteBucketTs,\n  type TrackEvaluationOptions,\n} from './usage/flags-evaluation';\n\n/**\n * Tracks usage events and batches them for submission to the ingest endpoint.\n */\nexport class UsageTracker {\n  private flushCount: number = 0;\n\n  private options: IngestOptions;\n  private scheduler: Scheduler;\n\n  private trackedRequests = new WeakSet<object>();\n\n  private readEvents: FlagsConfigReadEvent[] = [];\n  private evaluationEvents = new Map<string, FlagsEvaluationEvent>();\n\n  constructor(options: IngestOptions) {\n    this.options = options;\n    this.scheduler = new Scheduler((reason) => this.flushEvents(reason));\n  }\n\n  /**\n   * Triggers an immediate flush of any pending events.\n   * Returns a promise that resolves when the flush completes.\n   */\n  async shutdown() {\n    // Drain any in-flight scheduled batch (incl. its ingest send).\n    await this.scheduler.shutdown();\n\n    // Safety net for events tracked after the drained batch reset; if the\n    // drained flush already sent everything this returns early (maps cleared).\n    await this.flushEvents('shutdown');\n  }\n\n  /**\n   * Tracks a config read event. Deduplicates by request context.\n   */\n  trackRead(options?: TrackReadOptions): void {\n    try {\n      const { ctx, headers } = getRequestContext();\n\n      // Skip if request context can't be inferred\n      if (!ctx) return;\n\n      // Skip if we've already tracked this request\n      if (this.trackedRequests.has(ctx)) return;\n      this.trackedRequests.add(ctx);\n\n      this.readEvents.push(new FlagsConfigReadEvent(headers, options));\n\n      this.scheduler.scheduleFlush();\n    } catch (error) {\n      // trackRead should never throw, but log the error\n      console.error('@vercel/flags-core: Failed to record event:', error);\n    }\n  }\n\n  /**\n   * Tracks a flag evaluation event.\n   */\n  trackEvaluation(options: TrackEvaluationOptions): void {\n    try {\n      const bucketedOptions = {\n        ...options,\n        bucketTs: minuteBucketTs(),\n      };\n      const batchKey = evaluationBatchKey(bucketedOptions);\n\n      const existingEvent = this.evaluationEvents.get(batchKey);\n      // increment if we already have an event for this batch key\n      if (existingEvent) {\n        existingEvent.increment();\n      } else {\n        this.evaluationEvents.set(\n          batchKey,\n          new FlagsEvaluationEvent(bucketedOptions),\n        );\n      }\n\n      // always schedule to reset the timer\n      this.scheduler.scheduleFlush();\n    } catch (error) {\n      console.error(\n        '@vercel/flags-core: Failed to record evaluation event:',\n        error,\n      );\n    }\n  }\n\n  /**\n   * Send all events to the ingest service\n   */\n  private async flushEvents(flushReason: FlushReason) {\n    const events = [...this.readEvents, ...this.evaluationEvents.values()];\n    if (events.length === 0) return;\n\n    this.flushCount += 1;\n    const flushId = this.flushCount;\n\n    this.readEvents = [];\n    this.evaluationEvents.clear();\n\n    await sendIngestEvents(this.options, events, flushId, flushReason);\n  }\n}\n","/**\n * Error thrown when the fallback definitions file does not exist.\n * This typically means the \"vercel-flags prepare\" command was not run before building.\n */\nexport class FallbackNotFoundError extends Error {\n  constructor() {\n    super('@vercel/flags-core: Bundled definitions file not found.');\n    this.name = 'FallbackNotFoundError';\n  }\n}\n\n/**\n * Error thrown when the fallback definitions file exists but has no entry for the SDK key.\n * This means the SDK key was not included when running \"vercel-flags prepare\".\n */\nexport class FallbackEntryNotFoundError extends Error {\n  constructor() {\n    super('@vercel/flags-core: No bundled definitions found for SDK key.');\n    this.name = 'FallbackEntryNotFoundError';\n  }\n}\n","import { FallbackEntryNotFoundError, FallbackNotFoundError } from '../errors';\nimport type {\n  BundledDefinitions,\n  BundledDefinitionsResult,\n  DatafileInput,\n} from '../types';\nimport type { readBundledDefinitions } from '../utils/read-bundled-definitions';\nimport type { Auth } from './auth';\n\n/**\n * Manages loading of bundled flag definitions.\n * Wraps readBundledDefinitions() with caching.\n */\nexport class BundledSource {\n  private promise: Promise<BundledDefinitionsResult> | undefined;\n\n  constructor(\n    private options: {\n      auth: Auth;\n      readBundledDefinitions: typeof readBundledDefinitions;\n    },\n  ) {}\n\n  /**\n   * Load bundled definitions.\n   * Throws if bundled definitions are not available.\n   */\n  async load(): Promise<DatafileInput> {\n    const result = await this.getResult();\n\n    if (result.state === 'ok' && result.definitions) {\n      return result.definitions;\n    }\n\n    throw new Error(\n      '@vercel/flags-core: No flag definitions available. ' +\n        'Bundled definitions not found.',\n    );\n  }\n\n  /**\n   * Get the raw BundledDefinitions (for getFallbackDatafile).\n   * Throws typed errors if not available.\n   */\n  async getRaw(): Promise<BundledDefinitions> {\n    const result = await this.getResult();\n\n    switch (result.state) {\n      case 'ok':\n        return result.definitions;\n      case 'missing-file':\n        throw new FallbackNotFoundError();\n      case 'missing-entry':\n        throw new FallbackEntryNotFoundError();\n      case 'unexpected-error':\n        throw new Error(\n          '@vercel/flags-core: Failed to read bundled definitions: ' +\n            String(result.error),\n        );\n    }\n  }\n\n  /**\n   * Check if bundled definitions loaded successfully (without throwing).\n   */\n  async tryLoad(): Promise<DatafileInput | undefined> {\n    const result = await this.getResult();\n    if (result?.state === 'ok' && result.definitions) {\n      return result.definitions;\n    }\n    return undefined;\n  }\n\n  private getResult(): Promise<BundledDefinitionsResult> {\n    if (!this.promise) {\n      this.promise = this.options.readBundledDefinitions(this.options.auth);\n    }\n    return this.promise;\n  }\n}\n","import { version } from '../../package.json';\nimport type { BundledDefinitions } from '../types';\nimport type { Auth } from './auth';\n\nconst DEFAULT_FETCH_TIMEOUT_MS = 10_000;\n\n/**\n * Fetches the datafile from the flags service.\n */\nexport async function fetchDatafile(options: {\n  host: string;\n  auth: Auth;\n  fetch: typeof globalThis.fetch;\n  signal?: AbortSignal;\n}): Promise<BundledDefinitions> {\n  const token = await options.auth.resolveToken();\n\n  const controller = new AbortController();\n  const timeoutId = setTimeout(\n    () => controller.abort(),\n    DEFAULT_FETCH_TIMEOUT_MS,\n  );\n\n  // Abort the internal controller when the external signal fires\n  const onExternalAbort = () => controller.abort();\n  if (options.signal) {\n    if (options.signal.aborted) {\n      clearTimeout(timeoutId);\n      throw new Error('Fetch aborted');\n    }\n    options.signal.addEventListener('abort', onExternalAbort, { once: true });\n  }\n\n  try {\n    const res = await options.fetch(`${options.host}/v1/datafile`, {\n      headers: {\n        Authorization: `Bearer ${token}`,\n        'User-Agent': `VercelFlagsCore/${version}`,\n        ...(process.env.VERCEL_ENV\n          ? { 'X-Vercel-Env': process.env.VERCEL_ENV }\n          : null),\n      },\n      signal: controller.signal,\n    });\n\n    clearTimeout(timeoutId);\n    options.signal?.removeEventListener('abort', onExternalAbort);\n\n    if (!res.ok) {\n      throw new Error(`Failed to fetch data: ${res.statusText}`);\n    }\n\n    return res.json() as Promise<BundledDefinitions>;\n  } catch (error) {\n    clearTimeout(timeoutId);\n    options.signal?.removeEventListener('abort', onExternalAbort);\n    throw error instanceof Error ? error : new Error('Unknown fetch error');\n  }\n}\n","import type {\n  DatafileInput,\n  MetricEnvironment,\n  PollingOptions,\n  StreamOptions,\n} from '../types';\nimport type { Auth } from './auth';\n\nconst DEFAULT_STREAM_INIT_TIMEOUT_MS = 3000;\nconst DEFAULT_POLLING_INTERVAL_MS = 30_000;\nconst MIN_POLLING_INTERVAL_MS = 30_000;\nconst DEFAULT_POLLING_INIT_TIMEOUT_MS = 3_000;\n\n/**\n * Configuration options for Controller\n */\nexport type ControllerOptions = {\n  /** Authentication which resolves the token for requests */\n  auth: Auth;\n\n  /**\n   * Initial datafile to use immediately\n   * - At runtime: used while waiting for stream/poll, then updated in background\n   * - At build step: used as primary source (skips network)\n   */\n  datafile?: DatafileInput;\n\n  /**\n   * Configure streaming connection (runtime only, ignored during build step)\n   * - `true`: Enable with default options (initTimeoutMs: 3000)\n   * - `false`: Disable streaming\n   * - `{ initTimeoutMs: number }`: Enable with custom timeout\n   * @default true\n   */\n  stream?: boolean | StreamOptions;\n\n  /**\n   * Configure polling fallback (runtime only, ignored during build step)\n   * - `true`: Enable with default options (intervalMs: 30000, initTimeoutMs: 3000)\n   * - `false`: Disable polling\n   * - `{ intervalMs: number, initTimeoutMs: number }`: Enable with custom options\n   * @default true\n   */\n  polling?: boolean | PollingOptions;\n\n  /**\n   * Override build step detection\n   * - `true`: Treat as build step (use datafile/bundled only, no network)\n   * - `false`: Treat as runtime (try stream/poll first)\n   * @default auto-detected via CI=1 or NEXT_PHASE=phase-production-build\n   */\n  buildStep?: boolean;\n\n  /**\n   * Custom fetch function for making HTTP requests.\n   * Useful for testing (e.g. resolving to a different IP).\n   * @default globalThis.fetch\n   */\n  fetch?: typeof globalThis.fetch;\n\n  /**\n   * Environment included with evaluation metrics sent to the ingest endpoint.\n   * Falls back to the `VERCEL_ENV` environment variable when not set.\n   * This does not select the environment used for flag evaluation.\n   */\n  metricEnvironment?: MetricEnvironment;\n\n  /**\n   * Custom client name included in evaluation telemetry.\n   */\n  clientName?: string;\n\n  /**\n   * Disable evaluation metrics for this client.\n   * @default false\n   */\n  disableMetrics?: boolean;\n};\n\nexport type NormalizedOptions = {\n  auth: Auth;\n  datafile: DatafileInput | undefined;\n  stream: { enabled: boolean; initTimeoutMs: number };\n  polling: { enabled: boolean; intervalMs: number; initTimeoutMs: number };\n  buildStep: boolean;\n  fetch: typeof globalThis.fetch;\n  host: string;\n  metricEnvironment: MetricEnvironment | undefined;\n  clientName: string | undefined;\n  disableMetrics: boolean;\n};\n\nexport function normalizeOptions(\n  options: ControllerOptions,\n): NormalizedOptions {\n  const autoDetectedBuildStep =\n    process.env.CI === '1' ||\n    process.env.NEXT_PHASE === 'phase-production-build';\n  const buildStep = options.buildStep ?? autoDetectedBuildStep;\n\n  let stream: NormalizedOptions['stream'];\n  if (options.stream === undefined || options.stream === true) {\n    stream = { enabled: true, initTimeoutMs: DEFAULT_STREAM_INIT_TIMEOUT_MS };\n  } else if (options.stream === false) {\n    stream = { enabled: false, initTimeoutMs: 0 };\n  } else {\n    stream = { enabled: true, initTimeoutMs: options.stream.initTimeoutMs };\n  }\n\n  let polling: NormalizedOptions['polling'];\n  if (options.polling === undefined || options.polling === true) {\n    polling = {\n      enabled: true,\n      intervalMs: DEFAULT_POLLING_INTERVAL_MS,\n      initTimeoutMs: DEFAULT_POLLING_INIT_TIMEOUT_MS,\n    };\n  } else if (options.polling === false) {\n    polling = { enabled: false, intervalMs: 0, initTimeoutMs: 0 };\n  } else {\n    if (options.polling.intervalMs < MIN_POLLING_INTERVAL_MS) {\n      throw new Error(\n        `@vercel/flags-core: Polling interval must be at least ${MIN_POLLING_INTERVAL_MS}ms, got ${options.polling.intervalMs}ms.`,\n      );\n    }\n    polling = {\n      enabled: true,\n      intervalMs: options.polling.intervalMs,\n      initTimeoutMs: options.polling.initTimeoutMs,\n    };\n  }\n\n  return {\n    auth: options.auth,\n    datafile: options.datafile,\n    stream,\n    polling,\n    buildStep,\n    fetch: options.fetch ?? globalThis.fetch,\n    host: 'https://flags.vercel.com',\n    metricEnvironment: options.metricEnvironment,\n    clientName: options.clientName,\n    disableMetrics: options.disableMetrics ?? false,\n  };\n}\n","/**\n * Lightweight typed event emitter base class.\n * Each source module extends this to emit typed events.\n */\nexport class TypedEmitter<\n  Events extends Record<string, (...args: any[]) => void>,\n> {\n  private handlers = new Map<keyof Events, Set<Events[keyof Events]>>();\n\n  on<E extends keyof Events>(event: E, handler: Events[E]): void {\n    let set = this.handlers.get(event);\n    if (!set) {\n      set = new Set();\n      this.handlers.set(event, set);\n    }\n    set.add(handler as Events[keyof Events]);\n  }\n\n  off<E extends keyof Events>(event: E, handler: Events[E]): void {\n    this.handlers.get(event)?.delete(handler as Events[keyof Events]);\n  }\n\n  protected emit<E extends keyof Events>(\n    event: E,\n    ...args: Parameters<Events[E]>\n  ): void {\n    const set = this.handlers.get(event);\n    if (set) {\n      for (const handler of set) {\n        (handler as (...a: any[]) => void)(...args);\n      }\n    }\n  }\n}\n","import type { DatafileInput } from '../types';\nimport type { Auth } from './auth';\nimport { fetchDatafile } from './fetch-datafile';\nimport { TypedEmitter } from './typed-emitter';\n\nexport type PollingSourceConfig = {\n  host: string;\n  auth: Auth;\n  polling: {\n    intervalMs: number;\n  };\n  fetch: typeof globalThis.fetch;\n};\n\nexport type PollingSourceEvents = {\n  data: (data: DatafileInput) => void;\n  error: (error: Error) => void;\n};\n\n/**\n * Manages interval-based polling for flag data.\n * Wraps fetchDatafile() and emits typed events.\n */\nexport class PollingSource extends TypedEmitter<PollingSourceEvents> {\n  private config: PollingSourceConfig;\n  private intervalId: ReturnType<typeof setInterval> | undefined;\n  private abortController: AbortController | undefined;\n\n  constructor(config: PollingSourceConfig) {\n    super();\n    this.config = config;\n  }\n\n  /**\n   * Perform a single poll request.\n   * Emits 'data' on success, 'error' on failure.\n   */\n  async poll(): Promise<void> {\n    if (this.abortController?.signal.aborted) return;\n\n    try {\n      const data = await fetchDatafile({\n        ...this.config,\n        signal: this.abortController?.signal,\n      });\n      this.emit('data', data);\n    } catch (error) {\n      const err =\n        error instanceof Error ? error : new Error('Unknown poll error');\n      this.emit('error', err);\n    }\n  }\n\n  /**\n   * Start interval-based polling.\n   * Polls at the configured interval. Does not perform an initial poll —\n   * callers should call poll() first if an immediate poll is needed.\n   */\n  startInterval(): void {\n    if (this.intervalId) return;\n\n    this.abortController = new AbortController();\n\n    // Start interval\n    this.intervalId = setInterval(\n      () => void this.poll(),\n      this.config.polling.intervalMs,\n    );\n  }\n\n  /**\n   * Stop interval-based polling.\n   */\n  stop(): void {\n    if (this.intervalId) {\n      clearInterval(this.intervalId);\n      this.intervalId = undefined;\n    }\n    this.abortController?.abort();\n    this.abortController = undefined;\n  }\n}\n","export function sleep(ms: number): Promise<void> {\n  return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import { version } from '../../package.json';\nimport type { BundledDefinitions } from '../types';\nimport { sleep } from '../utils/sleep';\n\nexport type PrimedMessage = {\n  type: 'primed';\n  revision: number;\n  projectId: string;\n  environment: string;\n};\n\nexport type StreamMessage =\n  | { type: 'datafile'; data: BundledDefinitions }\n  | PrimedMessage\n  | { type: 'ping' };\n\nconst MAX_RETRY_COUNT = 15;\nconst BASE_RETRY_DELAY_MS = 1000;\nconst MAX_RETRY_DELAY_MS = 60_000;\nconst PING_TIMEOUT_MS = 90_000;\n\nfunction backoff(retryCount: number): number {\n  if (retryCount === 1) return 0;\n  const delay = Math.min(\n    BASE_RETRY_DELAY_MS * 2 ** (retryCount - 2),\n    MAX_RETRY_DELAY_MS,\n  );\n  return delay + Math.random() * 1000;\n}\n\nexport class UnauthorizedError extends Error {\n  constructor() {\n    super('stream: unauthorized (401)');\n    this.name = 'UnauthorizedError';\n  }\n}\n\nclass TokenResolutionError extends Error {\n  constructor(error: unknown) {\n    super('stream: token resolution failed', { cause: error });\n    this.name = 'TokenResolutionError';\n  }\n}\n\nexport type StreamCallbacks = {\n  onDatafile: (data: BundledDefinitions) => void;\n  onPrimed?: (message: PrimedMessage) => void;\n  onDisconnect?: () => void;\n};\n\nexport type StreamConfig = {\n  host: string;\n  abortController: AbortController;\n  fetch?: typeof globalThis.fetch;\n  /** Returns the current revision number to send as X-Revision header */\n  revision?: () => number | undefined;\n  resolveToken: () => Promise<string>;\n};\n\n/**\n * Connects to the flags stream endpoint and handles reconnection with backoff.\n * Resolves when the first datafile message is received.\n * Rejects if the connection fails before receiving any data.\n */\nexport async function connectStream(\n  config: StreamConfig,\n  callbacks: StreamCallbacks,\n): Promise<void> {\n  const { host, abortController, fetch: fetchFn = globalThis.fetch } = config;\n  const { onDatafile, onPrimed, onDisconnect } = callbacks;\n  let retryCount = 0;\n  let lastAttemptTime = 0;\n\n  let resolveInit: () => void;\n  let rejectInit: (error: unknown) => void;\n  const initPromise = new Promise<void>((resolve, reject) => {\n    resolveInit = resolve;\n    rejectInit = reject;\n  });\n\n  void (async () => {\n    let initialDataReceived = false;\n    let lastError: unknown;\n\n    while (!abortController.signal.aborted) {\n      if (retryCount > MAX_RETRY_COUNT) {\n        console.error(\n          '@vercel/flags-core: Max retry count exceeded',\n          lastError ?? 'stream closed repeatedly without an error',\n        );\n        if (!initialDataReceived) {\n          rejectInit!(\n            new Error('stream: max retry count exceeded before receiving data'),\n          );\n        }\n        abortController.abort();\n        break;\n      }\n\n      // Per-connection abort controller — allows ping timeout to abort a single\n      // connection without stopping the entire retry loop.\n      const connectionAbort = new AbortController();\n      const onMainAbort = (): void => connectionAbort.abort();\n      abortController.signal.addEventListener('abort', onMainAbort, {\n        once: true,\n      });\n\n      let pingTimeoutId: ReturnType<typeof setTimeout> | undefined;\n      // Reference to the response body so the ping timeout can cancel it\n      // to break out of the for-await loop.\n      let responseBody: ReadableStream<Uint8Array> | undefined;\n      const resetPingTimeout = (): void => {\n        if (pingTimeoutId !== undefined) clearTimeout(pingTimeoutId);\n        if (!initialDataReceived) return;\n        pingTimeoutId = setTimeout(() => {\n          responseBody?.cancel().catch(() => {});\n          connectionAbort.abort();\n        }, PING_TIMEOUT_MS);\n      };\n\n      try {\n        lastAttemptTime = Date.now();\n        const token = await config.resolveToken().catch((error) => {\n          throw new TokenResolutionError(error);\n        });\n        const headers: Record<string, string> = {\n          Authorization: `Bearer ${token}`,\n          'User-Agent': `VercelFlagsCore/${version}`,\n          'X-Retry-Attempt': String(retryCount),\n        };\n        const vercelEnv = process.env.VERCEL_ENV;\n        if (vercelEnv) {\n          headers['X-Vercel-Env'] = vercelEnv;\n        }\n        const revision = config.revision?.();\n        if (revision !== undefined) {\n          headers['X-Revision'] = String(revision);\n        }\n        const response = await fetchFn(`${host}/v1/stream`, {\n          headers,\n          signal: connectionAbort.signal,\n        });\n\n        if (!response.ok) {\n          if (response.status === 401) {\n            if (!initialDataReceived) {\n              rejectInit!(new UnauthorizedError());\n            }\n            abortController.abort();\n            break;\n          }\n\n          throw new Error(`stream was not ok: ${response.status}`);\n        }\n\n        if (!response.body) {\n          throw new Error('stream body was not present');\n        }\n\n        responseBody = response.body;\n        const reader = response.body.getReader();\n        const decoder = new TextDecoder();\n        const bufferChunks: string[] = [];\n\n        // Allow the ping timeout (or main abort) to cancel the reader,\n        // which breaks the read loop immediately even on a zombie connection.\n        const onConnectionAbort = (): void => {\n          reader.cancel().catch(() => {});\n        };\n        connectionAbort.signal.addEventListener('abort', onConnectionAbort, {\n          once: true,\n        });\n\n        try {\n          while (true) {\n            const { done, value: chunk } = await reader.read();\n            if (done || abortController.signal.aborted) break;\n\n            bufferChunks.push(decoder.decode(chunk, { stream: true }));\n            const combined = bufferChunks.join('');\n            bufferChunks.length = 0;\n            const lines = combined.split('\\n');\n            bufferChunks.push(lines.pop()!);\n\n            for (const line of lines) {\n              if (line === '') continue;\n\n              let message: StreamMessage;\n              try {\n                message = JSON.parse(line) as StreamMessage;\n              } catch {\n                console.warn(\n                  '@vercel/flags-core: Failed to parse stream message, skipping',\n                );\n                continue;\n              }\n\n              if (message.type === 'datafile') {\n                onDatafile(message.data);\n                retryCount = 0;\n                if (!initialDataReceived) {\n                  initialDataReceived = true;\n                  resolveInit!();\n                }\n                resetPingTimeout();\n              }\n\n              // Primed means the server confirmed our revision is current,\n              // so no full datafile is needed. Treat it like initial data\n              // for init resolution purposes.\n              if (message.type === 'primed') {\n                onPrimed?.(message);\n                retryCount = 0;\n                if (!initialDataReceived) {\n                  initialDataReceived = true;\n                  resolveInit!();\n                }\n                resetPingTimeout();\n              }\n\n              // Pings prove the connection is alive — reset retry count\n              // once initial data has been received\n              if (message.type === 'ping' && initialDataReceived) {\n                retryCount = 0;\n                resetPingTimeout();\n              }\n            }\n          }\n        } finally {\n          connectionAbort.signal.removeEventListener(\n            'abort',\n            onConnectionAbort,\n          );\n        }\n\n        // Stream ended normally (server closed connection) - reconnect\n        clearTimeout(pingTimeoutId);\n        abortController.signal.removeEventListener('abort', onMainAbort);\n        if (!abortController.signal.aborted) {\n          onDisconnect?.();\n          retryCount++;\n          const elapsed = Date.now() - lastAttemptTime;\n          const minGap = Math.max(0, BASE_RETRY_DELAY_MS - elapsed);\n          await sleep(Math.max(backoff(retryCount), minGap));\n          continue;\n        }\n      } catch (error) {\n        clearTimeout(pingTimeoutId);\n        abortController.signal.removeEventListener('abort', onMainAbort);\n        if (abortController.signal.aborted) {\n          break;\n        }\n        if (error instanceof TokenResolutionError && !initialDataReceived) {\n          rejectInit!(error.cause);\n          abortController.abort();\n          break;\n        }\n        // Ping timeout aborts only the per-connection controller; this is\n        // an expected reconnect, not a real error. Stay silent on retryable\n        // failures too — the error is only logged once retries are exhausted.\n        if (!connectionAbort.signal.aborted) {\n          lastError = error;\n        }\n        onDisconnect?.();\n        retryCount++;\n        const elapsed = Date.now() - lastAttemptTime;\n        const minGap = Math.max(0, BASE_RETRY_DELAY_MS - elapsed);\n        await sleep(Math.max(backoff(retryCount), minGap));\n      }\n    }\n\n    // Reject the init promise if the loop exited without receiving data\n    // (e.g. aborted externally before any data arrived)\n    if (!initialDataReceived) {\n      rejectInit!(new Error('stream: aborted before receiving data'));\n    }\n  })();\n\n  return initPromise;\n}\n","import type { DatafileInput } from '../types';\nimport type { NormalizedOptions } from './normalized-options';\nimport { connectStream, type PrimedMessage } from './stream-connection';\nimport { TypedEmitter } from './typed-emitter';\n\nexport type StreamSourceEvents = {\n  data: (data: DatafileInput) => void;\n  primed: (message: PrimedMessage) => void;\n  connected: () => void;\n  disconnected: () => void;\n};\n\n/**\n * Manages a streaming connection to the flags service.\n * Wraps connectStream() and emits typed events.\n */\nexport class StreamSource extends TypedEmitter<StreamSourceEvents> {\n  private options: NormalizedOptions;\n  private revision: () => number | undefined;\n  private abortController: AbortController | undefined;\n  private promise: Promise<void> | undefined;\n\n  constructor(options: NormalizedOptions, revision: () => number | undefined) {\n    super();\n    this.options = options;\n    this.revision = revision;\n  }\n\n  /**\n   * Start the stream connection.\n   * Returns a promise that resolves when the first datafile or primed message arrives.\n   * If already started, returns the existing promise.\n   */\n  start(): Promise<void> {\n    if (this.promise) return this.promise;\n\n    const abortController = new AbortController();\n    this.abortController = abortController;\n\n    // Clear cached state when the stream terminates so that a subsequent\n    // start() call creates a fresh connection instead of returning a stale\n    // resolved promise.\n    abortController.signal.addEventListener(\n      'abort',\n      () => {\n        if (this.abortController === abortController) {\n          this.promise = undefined;\n          this.abortController = undefined;\n        }\n      },\n      { once: true },\n    );\n\n    try {\n      const promise = connectStream(\n        {\n          host: this.options.host,\n          resolveToken: () => this.options.auth.resolveToken(),\n          abortController,\n          fetch: this.options.fetch,\n          revision: this.revision,\n        },\n        {\n          onDatafile: (newData) => {\n            this.emit('data', newData);\n            this.emit('connected');\n          },\n          onPrimed: (message) => {\n            this.emit('primed', message);\n            this.emit('connected');\n          },\n          onDisconnect: () => {\n            this.emit('disconnected');\n          },\n        },\n      );\n\n      this.promise = promise;\n      return promise;\n    } catch (error) {\n      this.promise = undefined;\n      this.abortController = undefined;\n      throw error;\n    }\n  }\n\n  /**\n   * Stop the stream connection.\n   */\n  stop(): void {\n    this.abortController?.abort();\n    this.abortController = undefined;\n    this.promise = undefined;\n  }\n}\n","import type { DatafileInput, Metrics } from '../types';\n\n/**\n * Internal origin tracking for how data was obtained.\n * This flows with the data from point of origin through to metrics.\n */\nexport type DataOrigin = 'stream' | 'poll' | 'bundled' | 'provided' | 'fetched';\n\n/**\n * DatafileInput with origin metadata attached at the point of arrival.\n * Internal only — stripped before returning to consumers.\n */\nexport type TaggedData = DatafileInput & {\n  _origin: DataOrigin;\n};\n\n/**\n * Tags a DatafileInput with its origin.\n */\nexport function tagData(data: DatafileInput, origin: DataOrigin): TaggedData {\n  return Object.assign(data, { _origin: origin }) as TaggedData;\n}\n\n/**\n * Maps internal DataOrigin to the public Metrics.source value.\n */\nexport function originToMetricsSource(origin: DataOrigin): Metrics['source'] {\n  switch (origin) {\n    case 'stream':\n    case 'poll':\n    case 'provided':\n      return 'in-memory';\n    case 'fetched':\n      return 'remote';\n    case 'bundled':\n      return 'embedded';\n  }\n}\n","import type {\n  BundledDefinitions,\n  ControllerInterface,\n  Datafile,\n  DatafileInput,\n  Metrics,\n} from '../types';\nimport { readBundledDefinitions } from '../utils/read-bundled-definitions';\nimport type { TrackReadOptions } from '../utils/usage/flags-config-read';\nimport type { TrackEvaluationOptions } from '../utils/usage/flags-evaluation';\nimport { UsageTracker } from '../utils/usage-tracker';\nimport { BundledSource } from './bundled-source';\nimport { fetchDatafile } from './fetch-datafile';\nimport {\n  type ControllerOptions,\n  type NormalizedOptions,\n  normalizeOptions,\n} from './normalized-options';\nimport { PollingSource } from './polling-source';\nimport { UnauthorizedError } from './stream-connection';\nimport { StreamSource } from './stream-source';\nimport { originToMetricsSource, type TaggedData, tagData } from './tagged-data';\n\nexport { BundledSource } from './bundled-source';\nexport type { ControllerOptions } from './normalized-options';\nexport { PollingSource } from './polling-source';\nexport { StreamSource } from './stream-source';\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Parses a configUpdatedAt value (number or string) into a numeric timestamp.\n * Returns undefined if the value is missing or cannot be parsed.\n */\nfunction parseConfigUpdatedAt(value: unknown): number | undefined {\n  if (typeof value === 'number') return value;\n  if (typeof value === 'string') {\n    const parsed = Number(value);\n    return Number.isNaN(parsed) ? undefined : parsed;\n  }\n  return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Internal types\n// ---------------------------------------------------------------------------\n\n/**\n * Explicit states for the controller state machine.\n */\ntype State =\n  | 'idle'\n  | 'initializing:stream'\n  | 'initializing:polling'\n  | 'initializing:fallback'\n  | 'streaming'\n  | 'polling'\n  | 'degraded'\n  | 'build:loading'\n  | 'build:ready'\n  | 'shutdown';\n\n// ---------------------------------------------------------------------------\n// Controller\n// ---------------------------------------------------------------------------\n\n/**\n * Connects to flags.vercel.com and manages flag definitions.\n *\n * Implemented as a state machine controller that delegates all I/O to\n * source modules (StreamSource, PollingSource, BundledSource).\n *\n * **Build step** (CI=1 or Next.js build, or buildStep: true):\n * - Uses datafile (if provided), bundled definitions, or one-time fetch as fallback\n * - No streaming or polling\n *\n * **Runtime — streaming mode** (stream enabled):\n * - Uses streaming exclusively; polling is never started, even if configured\n * - Init fallback (no data yet): constructor datafile → bundled → throw\n * - Read fallback (post-init): in-memory value → constructor datafile → bundled → throw\n *\n * **Runtime — polling mode** (polling enabled, stream disabled):\n * - Uses polling exclusively\n * - Same fallback chains as streaming mode\n *\n * **Runtime — offline mode** (neither stream nor polling):\n * - Init fallback: constructor datafile → bundled → one-time fetch → throw\n * - Read fallback: in-memory value → constructor datafile → bundled → one-time fetch → throw\n */\nexport class Controller implements ControllerInterface {\n  private options: NormalizedOptions;\n\n  // State machine\n  private state: State = 'idle';\n\n  // Data state — tagged with origin\n  private data: TaggedData | undefined;\n\n  // Memoized data spread for read() / getDatafile().\n  // Rebuilt only when `this.data` reference changes (e.g. on stream/poll update).\n  // Holds the result of stripping `_origin`; metrics are appended per-call.\n  private dataViewSource: TaggedData | undefined = undefined;\n  private dataViewBase: DatafileInput | undefined = undefined;\n\n  // Sources (I/O delegates)\n  private streamSource: StreamSource;\n  private pollingSource: PollingSource;\n  private bundledSource: BundledSource;\n\n  // Usage tracking\n  private usageTracker: UsageTracker;\n  private isFirstGetData: boolean = true;\n\n  // Build-step deduplication\n  private buildDataPromise: Promise<TaggedData> | null = null;\n  private buildReadTracked = false;\n\n  // Suppresses usage tracking when the SDK key is unauthorized\n  private unauthorized = false;\n\n  constructor(options: ControllerOptions) {\n    this.options = normalizeOptions(options);\n\n    // Create source modules\n    this.streamSource = new StreamSource(\n      this.options,\n      () => this.data?.revision,\n    );\n\n    this.pollingSource = new PollingSource(this.options);\n\n    this.bundledSource = new BundledSource({\n      auth: this.options.auth,\n      readBundledDefinitions,\n    });\n\n    // Wire source events to state machine\n    this.wireSourceEvents();\n\n    // If datafile provided, use it immediately\n    if (this.options.datafile) {\n      this.data = tagData(this.options.datafile, 'provided');\n    }\n\n    this.usageTracker = new UsageTracker(this.options);\n  }\n\n  // Source event handlers (stored for cleanup)\n  private onStreamData = (data: DatafileInput) => {\n    if (this.isNewerData(data)) {\n      this.data = tagData(data, 'stream');\n    }\n  };\n  private onStreamPrimed = () => {\n    // The server confirmed our revision is current — no new data needed.\n    // Transition to streaming like a normal connected event.\n    if (this.state === 'degraded' || this.state === 'initializing:stream') {\n      this.transition('streaming');\n    }\n  };\n  private onStreamConnected = () => {\n    if (this.state === 'degraded' || this.state === 'initializing:stream') {\n      this.transition('streaming');\n    }\n  };\n  private onStreamDisconnected = () => {\n    if (this.state === 'streaming') {\n      this.transition('degraded');\n    }\n  };\n  private onPollData = (data: DatafileInput) => {\n    if (this.isNewerData(data)) {\n      this.data = tagData(data, 'poll');\n    }\n  };\n  private onPollError = (error: Error) => {\n    console.error('@vercel/flags-core: Poll failed:', error);\n  };\n\n  // ---------------------------------------------------------------------------\n  // Source event wiring\n  // ---------------------------------------------------------------------------\n\n  private wireSourceEvents(): void {\n    this.streamSource.on('data', this.onStreamData);\n    this.streamSource.on('primed', this.onStreamPrimed);\n    this.streamSource.on('connected', this.onStreamConnected);\n    this.streamSource.on('disconnected', this.onStreamDisconnected);\n    this.pollingSource.on('data', this.onPollData);\n    this.pollingSource.on('error', this.onPollError);\n  }\n\n  private unwireSourceEvents(): void {\n    this.streamSource.off('data', this.onStreamData);\n    this.streamSource.off('primed', this.onStreamPrimed);\n    this.streamSource.off('connected', this.onStreamConnected);\n    this.streamSource.off('disconnected', this.onStreamDisconnected);\n    this.pollingSource.off('data', this.onPollData);\n    this.pollingSource.off('error', this.onPollError);\n  }\n\n  // ---------------------------------------------------------------------------\n  // State machine\n  // ---------------------------------------------------------------------------\n\n  private transition(to: State): void {\n    this.state = to;\n  }\n\n  private get isConnected(): boolean {\n    return this.state === 'streaming';\n  }\n\n  private get mode(): Metrics['mode'] {\n    if (this.options.buildStep) return 'build';\n    switch (this.state) {\n      case 'streaming':\n        return 'streaming';\n      case 'polling':\n        return 'polling';\n      default:\n        return 'offline';\n    }\n  }\n\n  // ---------------------------------------------------------------------------\n  // Public API (DataSource interface)\n  // ---------------------------------------------------------------------------\n\n  /**\n   * Initializes the data source.\n   *\n   * Build step: datafile → bundled → one-time fetch\n   * Streaming mode: stream → datafile → bundled\n   * Polling mode (no stream): poll → datafile → bundled\n   * Offline mode (neither): datafile → bundled → one-time fetch\n   */\n  async initialize(): Promise<void> {\n    if (this.options.buildStep) {\n      this.transition('build:loading');\n      await this.initializeForBuildStep();\n      this.transition('build:ready');\n      return;\n    }\n\n    // Hydrate from provided datafile if not already set (e.g., after shutdown)\n    if (!this.data && this.options.datafile) {\n      this.data = tagData(this.options.datafile, 'provided');\n    }\n\n    // If no data yet, try loading bundled definitions eagerly so we can\n    // send the revision to the stream and potentially get a lightweight\n    // \"primed\" response instead of a full datafile.\n    if (!this.data) {\n      try {\n        const bundled = await this.bundledSource.tryLoad();\n        if (bundled) {\n          this.data = tagData(bundled, 'bundled');\n        }\n      } catch {\n        // Bundled definitions not available — proceed without revision\n      }\n    }\n\n    // If we already have data (from provided datafile or bundled definitions),\n    // start updates. Both streaming and polling wait for initial data before\n    // being considered initialized, so we know we have fresh data.\n    // For no-updates (offline), return immediately since we already have usable data.\n    if (this.data) {\n      if (this.options.stream.enabled) {\n        this.transition('initializing:stream');\n        await this.tryInitializeStream();\n      } else if (this.options.polling.enabled) {\n        this.transition('initializing:polling');\n        await this.tryInitializePolling();\n      } else {\n        this.transition('degraded');\n      }\n      return;\n    }\n\n    // Try the configured primary source (stream or poll, never both)\n    if (this.options.stream.enabled) {\n      this.transition('initializing:stream');\n      const streamSuccess = await this.tryInitializeStream();\n      if (streamSuccess) {\n        this.transition('streaming');\n        return;\n      }\n    } else if (this.options.polling.enabled) {\n      this.transition('initializing:polling');\n      const pollingSuccess = await this.tryInitializePolling();\n      if (pollingSuccess) {\n        this.transition('polling');\n        return;\n      }\n    }\n\n    // Fallback chain: datafile → bundled → one-time fetch (offline only)\n    await this.initializeFromFallbacks();\n  }\n\n  /**\n   * Reads the current datafile with metrics.\n   */\n  async read(): Promise<Datafile> {\n    const startTime = Date.now();\n    const cacheHadDefinitions = this.data !== undefined;\n    const isFirstRead = this.isFirstGetData;\n    this.isFirstGetData = false;\n\n    const [result, cacheStatus] = await this.resolveData();\n\n    const readMs = Date.now() - startTime;\n    const source = originToMetricsSource(result._origin);\n    this.trackRead(startTime, cacheHadDefinitions, isFirstRead, source);\n\n    if (this.dataViewSource !== result) {\n      const { _origin, ...rest } = result;\n      this.dataViewBase = rest;\n      this.dataViewSource = result;\n    }\n\n    return {\n      ...(this.dataViewBase as DatafileInput),\n      metrics: {\n        readMs,\n        source,\n        cacheStatus,\n        connectionState: this.isConnected\n          ? ('connected' as const)\n          : ('disconnected' as const),\n        mode: this.mode,\n      },\n    } satisfies Datafile;\n  }\n\n  /**\n   * Shuts down the data source and releases resources.\n   */\n  async shutdown(): Promise<void> {\n    this.unwireSourceEvents();\n    this.streamSource.stop();\n    this.pollingSource.stop();\n    this.data = this.options.datafile\n      ? tagData(this.options.datafile, 'provided')\n      : undefined;\n    this.transition('shutdown');\n    await this.usageTracker.shutdown();\n  }\n\n  /**\n   * Returns the datafile with metrics.\n   * Uses in-memory data if available, otherwise falls back to bundled,\n   * then to a one-time fetch if called without prior initialization.\n   */\n  async getDatafile(): Promise<Datafile> {\n    const startTime = Date.now();\n    this.isFirstGetData = false;\n\n    let result: TaggedData;\n    let cacheStatus: Metrics['cacheStatus'];\n\n    if (this.options.buildStep) {\n      [result, cacheStatus] = await this.resolveDataForBuildStep();\n    } else if (this.data) {\n      cacheStatus = this.isConnected ? 'HIT' : 'STALE';\n      result = this.data;\n    } else {\n      // No in-memory data — try bundled, then one-time fetch\n      const bundled = await this.bundledSource.tryLoad();\n      if (bundled) {\n        this.data = tagData(bundled, 'bundled');\n        result = this.data;\n        cacheStatus = 'MISS';\n      } else {\n        // One-time fetch as last resort\n        try {\n          const fetched = await fetchDatafile({\n            host: this.options.host,\n            auth: this.options.auth,\n            fetch: this.options.fetch,\n          });\n          this.data = tagData(fetched, 'fetched');\n          result = this.data;\n          cacheStatus = 'MISS';\n        } catch {\n          throw new Error(\n            '@vercel/flags-core: No flag definitions available. ' +\n              'Initialize the client or provide a datafile.',\n          );\n        }\n      }\n    }\n\n    const source = originToMetricsSource(result._origin);\n\n    if (this.dataViewSource !== result) {\n      const { _origin, ...rest } = result;\n      this.dataViewBase = rest;\n      this.dataViewSource = result;\n    }\n\n    return {\n      ...(this.dataViewBase as DatafileInput),\n      metrics: {\n        readMs: Date.now() - startTime,\n        source,\n        cacheStatus,\n        connectionState: this.isConnected\n          ? ('connected' as const)\n          : ('disconnected' as const),\n        mode: this.mode,\n      },\n    } satisfies Datafile;\n  }\n\n  /**\n   * Returns the bundled fallback datafile.\n   */\n  async getFallbackDatafile(): Promise<BundledDefinitions> {\n    return this.bundledSource.getRaw();\n  }\n\n  // ---------------------------------------------------------------------------\n  // Data resolution (shared by read() and getDatafile())\n  // ---------------------------------------------------------------------------\n\n  /**\n   * Resolves the current data, using the appropriate strategy for the\n   * current mode. Returns tagged data and cache status.\n   *\n   * Build step: cached → bundled → one-time fetch\n   * Runtime with cache: return cached data\n   * Runtime without cache: stream/poll → datafile → bundled → fetch → throw\n   */\n  private async resolveData(): Promise<[TaggedData, Metrics['cacheStatus']]> {\n    if (this.options.buildStep) {\n      return this.resolveDataForBuildStep();\n    }\n\n    if (this.data) {\n      const cacheStatus = this.isConnected ? 'HIT' : 'STALE';\n      return [this.data, cacheStatus];\n    }\n\n    return this.resolveDataWithFallbacks();\n  }\n\n  // ---------------------------------------------------------------------------\n  // Stream initialization\n  // ---------------------------------------------------------------------------\n\n  /**\n   * Attempts to initialize via stream with timeout.\n   * Returns true if stream connected successfully within timeout.\n   */\n  private async tryInitializeStream(): Promise<boolean> {\n    if (this.options.stream.initTimeoutMs <= 0) {\n      try {\n        await this.streamSource.start();\n        return true;\n      } catch (error) {\n        if (error instanceof UnauthorizedError) {\n          this.unauthorized = true;\n        }\n        return false;\n      }\n    }\n\n    // Race against timeout\n    let timeoutId: ReturnType<typeof setTimeout>;\n    const timeoutPromise = new Promise<'timeout'>((resolve) => {\n      timeoutId = setTimeout(\n        () => resolve('timeout'),\n        this.options.stream.initTimeoutMs,\n      );\n    });\n\n    try {\n      const result = await Promise.race([\n        this.streamSource.start(),\n        timeoutPromise,\n      ]);\n      clearTimeout(timeoutId!);\n\n      if (result === 'timeout') {\n        console.warn(\n          '@vercel/flags-core: Stream initialization timeout, falling back while continuing to connect in the background',\n        );\n        // Don't stop stream - let it continue trying in background.\n        // Swallow the rejection from the background stream promise to\n        // avoid unhandled promise rejections when it is eventually aborted.\n        void this.streamSource.start().catch(() => {});\n        return false;\n      }\n\n      return true;\n    } catch (error) {\n      clearTimeout(timeoutId!);\n      if (error instanceof Error && error.message.includes('401')) {\n        this.unauthorized = true;\n      }\n      return false;\n    }\n  }\n\n  // ---------------------------------------------------------------------------\n  // Polling initialization\n  // ---------------------------------------------------------------------------\n\n  /**\n   * Attempts to initialize via polling with timeout.\n   * Returns true if first poll succeeded within timeout.\n   *\n   * Only used when streaming is disabled and polling is the primary source.\n   */\n  private async tryInitializePolling(): Promise<boolean> {\n    const pollPromise = this.pollingSource.poll();\n\n    if (this.options.polling.initTimeoutMs <= 0) {\n      try {\n        await pollPromise;\n        if (this.data) {\n          this.pollingSource.startInterval();\n          return true;\n        }\n        return false;\n      } catch {\n        return false;\n      }\n    }\n\n    // Race against timeout\n    let timeoutId: ReturnType<typeof setTimeout>;\n    const timeoutPromise = new Promise<'timeout'>((resolve) => {\n      timeoutId = setTimeout(\n        () => resolve('timeout'),\n        this.options.polling.initTimeoutMs,\n      );\n    });\n\n    try {\n      const result = await Promise.race([pollPromise, timeoutPromise]);\n      clearTimeout(timeoutId!);\n\n      if (result === 'timeout') {\n        console.warn(\n          '@vercel/flags-core: Polling initialization timeout, falling back while continuing to poll in the background',\n        );\n        return false;\n      }\n\n      if (this.data) {\n        this.pollingSource.startInterval();\n        return true;\n      }\n      return false;\n    } catch {\n      clearTimeout(timeoutId!);\n      return false;\n    }\n  }\n\n  // ---------------------------------------------------------------------------\n  // Build step helpers\n  // ---------------------------------------------------------------------------\n\n  /**\n   * Initializes data for build step environments.\n   */\n  private async initializeForBuildStep(): Promise<void> {\n    if (this.data) return;\n\n    if (!this.buildDataPromise) {\n      this.buildDataPromise = this.loadBuildData();\n    }\n    this.data = await this.buildDataPromise;\n  }\n\n  /**\n   * Retrieves data during build steps.\n   * Concurrent callers share a single load promise. The first caller to\n   * populate `this.data` gets cacheStatus MISS; subsequent callers get HIT.\n   */\n  private async resolveDataForBuildStep(): Promise<\n    [TaggedData, Metrics['cacheStatus']]\n  > {\n    if (this.data) {\n      return [this.data, 'HIT'];\n    }\n\n    if (!this.buildDataPromise) {\n      this.buildDataPromise = this.loadBuildData();\n    }\n\n    const data = await this.buildDataPromise;\n\n    if (!this.data) {\n      this.data = data;\n      return [data, 'MISS'];\n    }\n    return [this.data, 'HIT'];\n  }\n\n  /**\n   * Loads data for a build step: bundled → one-time fetch.\n   */\n  private async loadBuildData(): Promise<TaggedData> {\n    const bundled = await this.bundledSource.tryLoad();\n    if (bundled) return tagData(bundled, 'bundled');\n\n    // Fallback: one-time fetch\n    try {\n      const fetched = await fetchDatafile({\n        host: this.options.host,\n        auth: this.options.auth,\n        fetch: this.options.fetch,\n      });\n      return tagData(fetched, 'fetched');\n    } catch {\n      // fetch failed — fall through to throw\n    }\n\n    throw new Error(\n      '@vercel/flags-core: No flag definitions available during build. ' +\n        'Provide a datafile or bundled definitions.',\n    );\n  }\n\n  // ---------------------------------------------------------------------------\n  // Fallback helpers\n  // ---------------------------------------------------------------------------\n\n  /**\n   * Shared fallback chain used by both initialize() and resolveData().\n   */\n  private async initializeFromFallbacks(): Promise<void> {\n    this.transition('initializing:fallback');\n\n    if (this.data) {\n      this.transition('degraded');\n      return;\n    }\n\n    const bundled = await this.bundledSource.tryLoad();\n    if (bundled) {\n      this.data = tagData(bundled, 'bundled');\n      this.transition('degraded');\n      return;\n    }\n\n    // Last resort: one-time fetch (only when no stream/poll configured)\n    if (!this.options.stream.enabled && !this.options.polling.enabled) {\n      try {\n        const fetched = await fetchDatafile({\n          host: this.options.host,\n          auth: this.options.auth,\n          fetch: this.options.fetch,\n        });\n        this.data = tagData(fetched, 'fetched');\n        this.transition('degraded');\n        return;\n      } catch {\n        // fetch failed — fall through to throw\n      }\n    }\n\n    throw new Error(\n      '@vercel/flags-core: No flag definitions available. ' +\n        'Bundled definitions not found.',\n    );\n  }\n\n  /**\n   * Retrieves data using the fallback chain (called when no cached data exists).\n   * Streaming mode: stream → datafile → bundled.\n   * Polling mode: poll → datafile → bundled.\n   * Offline mode: datafile → bundled → one-time fetch.\n   */\n  private async resolveDataWithFallbacks(): Promise<\n    [TaggedData, Metrics['cacheStatus']]\n  > {\n    // Try the configured primary source\n    if (this.options.stream.enabled) {\n      this.transition('initializing:stream');\n      const streamSuccess = await this.tryInitializeStream();\n      if (streamSuccess && this.data) {\n        this.transition('streaming');\n        return [this.data, 'MISS'];\n      }\n    } else if (this.options.polling.enabled) {\n      this.transition('initializing:polling');\n      const pollingSuccess = await this.tryInitializePolling();\n      if (pollingSuccess && this.data) {\n        this.transition('polling');\n        return [this.data, 'MISS'];\n      }\n    }\n\n    // Fallback chain: datafile → bundled → one-time fetch\n    this.transition('initializing:fallback');\n\n    if (this.options.datafile) {\n      this.data = tagData(this.options.datafile, 'provided');\n      this.transition('degraded');\n      return [this.data, 'STALE'];\n    }\n\n    const bundled = await this.bundledSource.tryLoad();\n    if (bundled) {\n      console.warn('@vercel/flags-core: Using bundled definitions as fallback');\n      this.data = tagData(bundled, 'bundled');\n      this.transition('degraded');\n      return [this.data, 'STALE'];\n    }\n\n    // Last resort: one-time fetch (only when no stream/poll configured)\n    if (!this.options.stream.enabled && !this.options.polling.enabled) {\n      try {\n        const fetched = await fetchDatafile({\n          host: this.options.host,\n          auth: this.options.auth,\n          fetch: this.options.fetch,\n        });\n        this.data = tagData(fetched, 'fetched');\n        this.transition('degraded');\n        return [this.data, 'MISS'];\n      } catch {\n        // fetch failed — fall through to throw\n      }\n    }\n\n    throw new Error(\n      '@vercel/flags-core: No flag definitions available. ' +\n        'Provide a datafile or bundled definitions.',\n    );\n  }\n\n  // ---------------------------------------------------------------------------\n  // Data comparison\n  // ---------------------------------------------------------------------------\n\n  /**\n   * Checks if the incoming data is newer than the current in-memory data.\n   * Returns true if the update should proceed, false if it should be skipped.\n   *\n   * Always accepts the update if:\n   * - There is no current data\n   * - The current data has no configUpdatedAt\n   * - The incoming data has no configUpdatedAt\n   *\n   * Skips the update only when both have configUpdatedAt and incoming is not newer.\n   */\n  private isNewerData(incoming: DatafileInput): boolean {\n    if (!this.data) return true;\n\n    const currentTs = parseConfigUpdatedAt(this.data.configUpdatedAt);\n    const incomingTs = parseConfigUpdatedAt(incoming.configUpdatedAt);\n\n    if (currentTs === undefined || incomingTs === undefined) {\n      return true;\n    }\n\n    return incomingTs > currentTs;\n  }\n\n  // ---------------------------------------------------------------------------\n  // Usage tracking\n  // ---------------------------------------------------------------------------\n\n  /**\n   * Tracks a read operation for usage analytics.\n   * During build steps, only the first read is tracked.\n   */\n  private trackRead(\n    startTime: number,\n    cacheHadDefinitions: boolean,\n    isFirstRead: boolean,\n    source: Metrics['source'],\n  ): void {\n    if (this.unauthorized) return;\n    if (this.options.buildStep && this.buildReadTracked) return;\n    if (this.options.buildStep) this.buildReadTracked = true;\n\n    const configOrigin: 'in-memory' | 'embedded' =\n      source === 'embedded' ? 'embedded' : 'in-memory';\n    const cacheAction: 'FOLLOWING' | 'REFRESHING' | 'NONE' =\n      this.state === 'streaming'\n        ? 'FOLLOWING'\n        : this.state === 'polling'\n          ? 'REFRESHING'\n          : 'NONE';\n    const mode = this.mode;\n    const trackOptions: TrackReadOptions = {\n      configOrigin,\n      cacheStatus: cacheHadDefinitions ? 'HIT' : 'MISS',\n      cacheAction,\n      cacheIsBlocking: !cacheHadDefinitions,\n      duration: Date.now() - startTime,\n      mode:\n        mode === 'streaming' ? 'stream' : mode === 'polling' ? 'poll' : mode,\n    };\n    const configUpdatedAt = this.data?.configUpdatedAt;\n    if (typeof configUpdatedAt === 'number') {\n      trackOptions.configUpdatedAt = configUpdatedAt;\n    }\n    const revision = this.data?.revision;\n    if (typeof revision === 'number') {\n      trackOptions.revision = revision;\n    }\n    if (isFirstRead) {\n      trackOptions.cacheIsFirstRead = true;\n    }\n    this.usageTracker.trackRead(trackOptions);\n  }\n\n  /**\n   * Tracks a flag evaluation for usage analytics.\n   */\n  trackEvaluation(options: TrackEvaluationOptions): void {\n    if (this.unauthorized || this.options.disableMetrics) return;\n\n    this.usageTracker.trackEvaluation({\n      ...options,\n      clientName: options.clientName ?? this.options.clientName,\n    });\n  }\n}\n","import { getVercelOidcToken } from '@vercel/oidc';\nimport { parseSdkKeyFromFlagsConnectionString } from '../utils/sdk-keys';\n\nexport type BundledDefinitionsLookup =\n  | { type: 'sdk-key'; sdkKey: string }\n  | { type: 'project-id'; projectId: string };\n\nexport interface Auth {\n  sdkKey?: string;\n  resolveToken(): Promise<string>;\n  resolveBundledDefinitionsLookup(): Promise<BundledDefinitionsLookup>;\n}\n\nasync function getOidcToken(): Promise<string> {\n  try {\n    return await getVercelOidcToken();\n  } catch {\n    throw new Error(\n      [\n        '@vercel/flags-core: Failed to get OIDC token.',\n        'Are you running in a Vercel Environment where OIDC tokens are available?',\n        'Did you mean to use an SDK Key instead? Use the environment variable FLAGS or pass it directly to the client.',\n      ].join(' '),\n    );\n  }\n}\n\nfunction getProjectIdFromOidcToken(oidcToken: string): string {\n  const tokenParts = oidcToken.split('.');\n  if (tokenParts.length !== 3 || !tokenParts[1]) {\n    throw new Error('@vercel/flags-core: Invalid OIDC token');\n  }\n\n  const payload = JSON.parse(\n    Buffer.from(tokenParts[1], 'base64url').toString('utf8'),\n  ) as { project_id?: unknown };\n\n  if (typeof payload.project_id !== 'string' || !payload.project_id) {\n    throw new Error(\n      '@vercel/flags-core: Missing project_id claim in OIDC token',\n    );\n  }\n\n  return payload.project_id;\n}\n\nexport class Authentication implements Auth {\n  public readonly sdkKey?: string;\n\n  constructor(sdkKeyOrConnectionString: string | undefined) {\n    // validate sdk key format\n    if (sdkKeyOrConnectionString !== undefined) {\n      if (typeof sdkKeyOrConnectionString !== 'string') {\n        throw new Error(\n          `@vercel/flags-core: Invalid sdkKey. Expected string, got ${typeof sdkKeyOrConnectionString}`,\n        );\n      }\n\n      // Parse connection string if needed (e.g., \"flags:edgeConfigId=...&sdkKey=vf_xxx\")\n      const parsed = parseSdkKeyFromFlagsConnectionString(\n        sdkKeyOrConnectionString,\n      );\n      if (!parsed) {\n        throw new Error('@vercel/flags-core: Missing sdkKey');\n      }\n\n      this.sdkKey = parsed;\n    }\n  }\n\n  public async resolveToken() {\n    if (this.sdkKey) {\n      return this.sdkKey;\n    }\n\n    return await getOidcToken();\n  }\n\n  public async resolveBundledDefinitionsLookup(): Promise<BundledDefinitionsLookup> {\n    if (this.sdkKey) {\n      return { type: 'sdk-key', sdkKey: this.sdkKey };\n    }\n\n    const oidcToken = await this.resolveToken();\n    return {\n      type: 'project-id',\n      projectId: getProjectIdFromOidcToken(oidcToken),\n    };\n  }\n}\n","/**\n * Regex to match valid Vercel Flags SDK keys.\n * SDK keys must follow the format: vf_server_* or vf_client_*\n * This avoids false positives with third-party identifiers that happen\n * to start with 'vf_' (e.g., Stripe identity flow IDs like 'vf_1PyH...').\n */\nconst SDK_KEY_REGEX = /^vf_(?:server|client)_/;\n\n/**\n * Checks if a string is a valid Vercel Flags SDK key.\n */\nexport function isValidSdkKey(value: string): boolean {\n  return SDK_KEY_REGEX.test(value);\n}\n\n/**\n * Parses sdk keys from connection strings with the following format:\n * `flags:edgeConfigId=ecfg_abcd&edgeConfigToken=xxx&sdkKey=xxx`\n */\nexport function parseSdkKeyFromFlagsConnectionString(\n  text: string,\n): string | null {\n  if (SDK_KEY_REGEX.test(text)) return text;\n\n  try {\n    if (!text.startsWith('flags:')) return null;\n    const params = new URLSearchParams(text.slice(6));\n    const sdkKey = params.get('sdkKey');\n    if (sdkKey && SDK_KEY_REGEX.test(sdkKey)) return sdkKey;\n  } catch {\n    // no-op\n  }\n\n  return null;\n}\n","/**\n * Factory functions for exports of index.default.ts and index.next-js.ts\n */\n\nimport { Controller, type ControllerOptions } from './controller';\nimport { Authentication } from './controller/auth';\nimport type { createCreateRawClient } from './create-raw-client';\nimport type { FlagsClient } from './types';\n\n/**\n * Options for createClient\n */\nexport type CreateClientOptions = Omit<ControllerOptions, 'auth'>;\n\ntype CreateClient = {\n  <Entities = Record<string, unknown>>(\n    options: CreateClientOptions,\n  ): FlagsClient<Entities>;\n  <Entities = Record<string, unknown>>(\n    sdkKeyOrConnectionString?: string,\n    options?: CreateClientOptions,\n  ): FlagsClient<Entities>;\n};\n\nexport function make(\n  createRawClient: ReturnType<typeof createCreateRawClient>,\n): {\n  flagsClient: FlagsClient;\n  resetDefaultFlagsClient: () => void;\n  createClient: CreateClient;\n} {\n  let _defaultFlagsClient: FlagsClient | null = null;\n\n  // Insights\n  // - data source must specify the environment & projectId as sdkKey has that info\n  // - \"reuse\" functionality relies on the data source having the data for all envs\n  function createClient<Entities = Record<string, unknown>>(\n    options: CreateClientOptions,\n  ): FlagsClient<Entities>;\n  function createClient<Entities = Record<string, unknown>>(\n    sdkKeyOrConnectionString?: string,\n    options?: CreateClientOptions,\n  ): FlagsClient<Entities>;\n  function createClient<Entities = Record<string, unknown>>(\n    sdkKeyOrConnectionStringOrOptions?: string | CreateClientOptions,\n    options?: CreateClientOptions,\n  ): FlagsClient<Entities> {\n    const optionsOnly =\n      typeof sdkKeyOrConnectionStringOrOptions === 'object' &&\n      sdkKeyOrConnectionStringOrOptions !== null;\n    const sdkKeyOrConnectionString = optionsOnly\n      ? undefined\n      : sdkKeyOrConnectionStringOrOptions;\n    const createClientOptions = optionsOnly\n      ? sdkKeyOrConnectionStringOrOptions\n      : options;\n\n    const auth = new Authentication(sdkKeyOrConnectionString);\n\n    // sdk key contains the environment\n    const controller = new Controller({ auth, ...createClientOptions });\n    return createRawClient<Entities>({\n      controller,\n      origin: { provider: 'vercel', sdkKey: auth.sdkKey },\n    });\n  }\n\n  function resetDefaultFlagsClient() {\n    _defaultFlagsClient = null;\n  }\n\n  const flagsClient: FlagsClient = new Proxy({} as FlagsClient, {\n    get(_, prop) {\n      if (!_defaultFlagsClient) {\n        _defaultFlagsClient = createClient(process.env.FLAGS);\n      }\n      return _defaultFlagsClient[prop as keyof FlagsClient];\n    },\n  });\n\n  return {\n    flagsClient,\n    resetDefaultFlagsClient,\n    createClient,\n  };\n}\n"]}