serialize method

Map<String, dynamic> serialize()

Serializes the context into a JSON-compatible map.

This is used for passing context across isolate boundaries.

Implementation

Map<String, dynamic> serialize() {
  final values = <String, dynamic>{};
  final keyNamesCount = <String, int>{};

  // Only serialize baggage if it has entries
  final currentBaggage = baggage;
  if (currentBaggage != null && currentBaggage.getAllEntries().isNotEmpty) {
    values['baggage'] = currentBaggage.toJson();
  }

  // Only serialize span context if not null
  if (spanContext != null) {
    values['spanContext'] = spanContext!.toJson();
  }

  // Serialize remaining context values with their unique IDs
  _values.forEach((key, value) {
    if (key != _baggageKey && key != _spanKey && key != _spanContextKey) {
      // Skip keys that are not marked as transferable
      if (!key.isTransferable) {
        return;
      }

      try {
        // We still check for serializability to be safe, but now we only
        // do it for keys that are expected to be transferable.
        // In the future, we could skip this check for even better performance
        // if we trust the isTransferable flag.
        json.encode(value);

        // If we get here, the value is serializable
        // Handle multiple keys with the same name
        var finalKeyName = key.name;

        // If we've seen this key name before, make it unique
        keyNamesCount[key.name] = (keyNamesCount[key.name] ?? 0) + 1;
        if (keyNamesCount[key.name]! > 1) {
          finalKeyName = '${key.name}-${keyNamesCount[key.name]}';
        }

        // Create a composite key entry that includes both name and uniqueId
        values[finalKeyName] = {
          'value': value,
          'uniqueId': key.uniqueId,
          'originalKeyName':
              key.name, // Store original key name for deserialization
        };
      } catch (e) {
        // Value is not serializable, skip it
      }
    }
  });

  return values;
}