Repository: trpc/trpc
File: packages/server/src/unstable-core-do-not-import/stream/sse.ts (TypeScript)

Code before:
        data: JSON.stringify(serialize(data)),
      };
    }
  }

  const stream = readableStreamFrom(generatorWithErrorHandling());

  return stream.pipeThrough(
    new TransformStream({
      transform(
        chunk,
        controller: TransformStreamDefaultController<Uint8Array>,
      ) {
        if ('event' in chunk) {
          controller.enqueue(textEncoder.encode(`event: ${chunk.event}\n`));
        }
        if ('data' in chunk) {
          controller.enqueue(textEncoder.encode(`data: ${chunk.data}\n`));
        }
        if ('id' in chunk) {
          controller.enqueue(textEncoder.encode(`id: ${chunk.id}\n`));
        }
        if ('comment' in chunk) {
          controller.enqueue(textEncoder.encode(`: ${chunk.comment}\n`));
        }
        controller.enqueue(textEncoder.encode('\n\n'));
      },
    }),
  );
}

interface ConsumerStreamResultBase<TConfig extends ConsumerConfig> {
  eventSource: InstanceType<TConfig['EventSource']> | null;
}

interface ConsumerStreamResultData<TConfig extends ConsumerConfig>
  extends ConsumerStreamResultBase<TConfig> {
  type: 'data';
  data: inferTrackedOutput<TConfig['data']>;
}

interface ConsumerStreamResultError<TConfig extends ConsumerConfig>
  extends ConsumerStreamResultBase<TConfig> {
  type: 'serialized-error';
  error: TConfig['error'];
}

interface ConsumerStreamResultConnecting<TConfig extends ConsumerConfig>
  extends ConsumerStreamResultBase<TConfig> {
  type: 'connecting';
  event: EventSourceLike.EventOf<TConfig['EventSource']> | null;

Review comment (suggestion):
Skip this and instead do a nother pipethrough with a [TextEncoderStream](https://developer.mozilla.org/en-US/docs/Web/API/TextEncoderStream)

Code after:
    }
  }

  const stream = readableStreamFrom(generatorWithErrorHandling());

  return stream
    .pipeThrough(
      new TransformStream({
        transform(chunk, controller: TransformStreamDefaultController<string>) {
          if ('event' in chunk) {
            controller.enqueue(`event: ${chunk.event}\n`);
          }
          if ('data' in chunk) {
            controller.enqueue(`data: ${chunk.data}\n`);
          }
          if ('id' in chunk) {
            controller.enqueue(`id: ${chunk.id}\n`);
          }
          if ('comment' in chunk) {
            controller.enqueue(`: ${chunk.comment}\n`);
          }
          controller.enqueue('\n\n');
        },
      }),
    )
    .pipeThrough(new TextEncoderStream());
}

interface ConsumerStreamResultBase<TConfig extends ConsumerConfig> {
  eventSource: InstanceType<TConfig['EventSource']> | null;
}

interface ConsumerStreamResultData<TConfig extends ConsumerConfig>
  extends ConsumerStreamResultBase<TConfig> {
  type: 'data';
  data: inferTrackedOutput<TConfig['data']>;
}

interface ConsumerStreamResultError<TConfig extends ConsumerConfig>
  extends ConsumerStreamResultBase<TConfig> {
  type: 'serialized-error';
  error: TConfig['error'];
}

interface ConsumerStreamResultConnecting<TConfig extends ConsumerConfig>
  extends ConsumerStreamResultBase<TConfig> {
  type: 'connecting';
  event: EventSourceLike.EventOf<TConfig['EventSource']> | null;
}
interface ConsumerStreamResultTimeout<TConfig extends ConsumerConfig>
  extends ConsumerStreamResultBase<TConfig> {