@opentelemetry/core
Version:
OpenTelemetry Core provides constants and utilities shared by all OpenTelemetry SDK packages.
95 lines (94 loc) • 3.45 kB
JavaScript
const require_validators = require("../internal/validators.cjs");
//#region src/trace/TraceState.ts
const MAX_TRACE_STATE_ITEMS = 32;
const MAX_TRACE_STATE_LEN = 512;
const LIST_MEMBERS_SEPARATOR = ",";
const LIST_MEMBER_KEY_VALUE_SPLITTER = "=";
/**
* TraceState must be a class and not a simple object type because of the spec
* requirement (https://www.w3.org/TR/trace-context/#tracestate-field).
*
* Here is the list of allowed mutations:
* - New key-value pair should be added into the beginning of the list
* - The value of any key can be updated. Modified keys MUST be moved to the
* beginning of the list.
*/
var TraceState = class TraceState {
_length;
_rawTraceState;
_internalState;
constructor(rawTraceState) {
this._rawTraceState = typeof rawTraceState === "string" ? rawTraceState : "";
this._length = this._rawTraceState.length;
}
set(key, value) {
if (!require_validators.validateKey(key) || !require_validators.validateValue(value)) return this;
const currState = this._getState();
const currValue = currState.get(key);
let newLength = this._length;
if (typeof currValue === "string") newLength += value.length - currValue.length;
else {
if (currState.size >= MAX_TRACE_STATE_ITEMS) return this;
newLength += key.length + value.length + (currState.size > 0 ? 2 : 1);
}
if (newLength > MAX_TRACE_STATE_LEN) return this;
const newState = new Map(currState);
newState.delete(key);
newState.set(key, value);
return this._fromState(newState, newLength);
}
unset(key) {
const currState = this._getState();
const currValue = currState.get(key);
if (typeof currValue !== "string") return this;
let newLength = this._length - (key.length + currValue.length + 1);
if (currState.size > 1) newLength = newLength - 1;
const newState = new Map(currState);
newState.delete(key);
return this._fromState(newState, newLength);
}
get(key) {
return this._getState().get(key);
}
serialize() {
let serialized = "";
let index = 0;
for (const entry of this._getState()) {
if (index > 0) serialized = LIST_MEMBERS_SEPARATOR + serialized;
serialized = `${entry[0]}${LIST_MEMBER_KEY_VALUE_SPLITTER}${entry[1]}` + serialized;
index++;
}
return serialized;
}
_getState() {
if (this._internalState) return this._internalState;
const vendorMembers = this._rawTraceState.split(LIST_MEMBERS_SEPARATOR);
const vendorEntries = /* @__PURE__ */ new Map();
let currentLength = 0;
for (const member of vendorMembers) {
const m = member.trim();
const idx = m.indexOf(LIST_MEMBER_KEY_VALUE_SPLITTER);
if (idx === -1) continue;
const key = m.slice(0, idx);
const value = m.slice(idx + 1);
if (!require_validators.validateKey(key) || !require_validators.validateValue(value)) continue;
const futureLength = currentLength + m.length + (vendorEntries.size > 0 ? 1 : 0);
if (futureLength > MAX_TRACE_STATE_LEN) continue;
vendorEntries.set(key, value);
currentLength = futureLength;
if (vendorEntries.size >= MAX_TRACE_STATE_ITEMS) break;
}
this._length = currentLength;
this._internalState = new Map(Array.from(vendorEntries.entries()).reverse());
return this._internalState;
}
_fromState(state, length) {
const traceState = Object.create(TraceState.prototype);
traceState._internalState = state;
traceState._length = length;
return traceState;
}
};
//#endregion
exports.TraceState = TraceState;
//# sourceMappingURL=TraceState.cjs.map