{"version":3,"file":"tracestate-impl.js","sourceRoot":"","sources":["../../../../src/trace/internal/tracestate-impl.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { TraceState } from '../trace_state';\nimport { validateKey, validateValue } from './tracestate-validators';\n\nconst MAX_TRACE_STATE_ITEMS = 32;\nconst MAX_TRACE_STATE_LEN = 512;\nconst LIST_MEMBERS_SEPARATOR = ',';\nconst LIST_MEMBER_KEY_VALUE_SPLITTER = '=';\n\n/**\n * TraceState must be a class and not a simple object type because of the spec\n * requirement (https://www.w3.org/TR/trace-context/#tracestate-field).\n *\n * Here is the list of allowed mutations:\n * - New key-value pair should be added into the beginning of the list\n * - The value of any key can be updated. Modified keys MUST be moved to the\n * beginning of the list.\n */\nexport class TraceStateImpl implements TraceState {\n  private _internalState: Map<string, string> = new Map();\n\n  constructor(rawTraceState?: string) {\n    if (rawTraceState) this._parse(rawTraceState);\n  }\n\n  set(key: string, value: string): TraceStateImpl {\n    // TODO: Benchmark the different approaches(map vs list) and\n    // use the faster one.\n    const traceState = this._clone();\n    if (traceState._internalState.has(key)) {\n      traceState._internalState.delete(key);\n    }\n    traceState._internalState.set(key, value);\n    return traceState;\n  }\n\n  unset(key: string): TraceStateImpl {\n    const traceState = this._clone();\n    traceState._internalState.delete(key);\n    return traceState;\n  }\n\n  get(key: string): string | undefined {\n    return this._internalState.get(key);\n  }\n\n  serialize(): string {\n    return (\n      Array.from(this._internalState.keys())\n        // Use reduceRight() because keys are stored in reverse insertion order.\n        .reduceRight((agg: string[], key) => {\n          agg.push(key + LIST_MEMBER_KEY_VALUE_SPLITTER + this.get(key));\n          return agg;\n        }, [])\n        .join(LIST_MEMBERS_SEPARATOR)\n    );\n  }\n\n  private _parse(rawTraceState: string) {\n    if (rawTraceState.length > MAX_TRACE_STATE_LEN) return;\n    this._internalState = rawTraceState\n      .split(LIST_MEMBERS_SEPARATOR)\n      // Use reduceRight() so new keys (.set(...)) will be placed at the beginning\n      .reduceRight((agg: Map<string, string>, part: string) => {\n        const listMember = part.trim(); // Optional Whitespace (OWS) handling\n        const i = listMember.indexOf(LIST_MEMBER_KEY_VALUE_SPLITTER);\n        if (i !== -1) {\n          const key = listMember.slice(0, i);\n          const value = listMember.slice(i + 1, part.length);\n          if (validateKey(key) && validateValue(value)) {\n            agg.set(key, value);\n          } else {\n            // TODO: Consider to add warning log\n          }\n        }\n        return agg;\n      }, new Map());\n\n    // Because of the reverse() requirement, trunc must be done after map is created\n    if (this._internalState.size > MAX_TRACE_STATE_ITEMS) {\n      this._internalState = new Map(\n        Array.from(this._internalState.entries())\n          .reverse() // Use reverse same as original tracestate parse chain\n          .slice(0, MAX_TRACE_STATE_ITEMS)\n      );\n    }\n  }\n\n  // @ts-expect-error TS6133 Accessed in tests only.\n  private _keys(): string[] {\n    return Array.from(this._internalState.keys()).reverse();\n  }\n\n  private _clone(): TraceStateImpl {\n    const traceState = new TraceStateImpl();\n    traceState._internalState = new Map(this._internalState);\n    return traceState;\n  }\n}\n"]}