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

Code before:

  run(async () => {
    let iterable = withCancel(opts.data, stream.cancelledPromise);

    if (opts.emitAndEndImmediately) {
      iterable = takeWithGrace(iterable, { count: 1, gracePeriodMs: 1 });
    }

    let maxDurationTimer: PromiseTimer | null = null;
    if (
      opts.maxDurationMs != null &&
      opts.maxDurationMs > 0 &&
      opts.maxDurationMs !== Infinity
    ) {
      maxDurationTimer = createPromiseTimer(opts.maxDurationMs).start();
      iterable = withCancel(iterable, maxDurationTimer.promise);
    }

    if (ping.enabled && ping.intervalMs !== Infinity && ping.intervalMs > 0) {
      iterable = withPing(iterable, ping.intervalMs);
    }

    try {
      for await (const value of iterable) {
        if (value === PING_SYM) {
          stream.controller.enqueue({ comment: 'ping' });
          continue;
        }

        const chunk: SSEvent = isTrackedEnvelope(value)
          ? { id: value[0], data: value[1] }
          : { data: value };
        if ('data' in chunk) {
          chunk.data = JSON.stringify(serialize(chunk.data));
        }

        stream.controller.enqueue(chunk);
      }
    } catch (err) {
      // ignore abort errors, send any other errors
      if (!(err instanceof Error) || err.name !== 'AbortError') {
        // `err` must be caused by `opts.data`, `JSON.stringify` or `serialize`.
        // So, a user error in any case.
        const error = getTRPCErrorFromUnknown(err);
        const data = opts.formatError?.({ error }) ?? null;
        stream.controller.enqueue({
          event: SERIALIZED_ERROR_EVENT,
          data: JSON.stringify(serialize(data)),
        });
      }
    } finally {

Review comment (suggestion):
This loop is so much cleaner now - maybe we could get this type of loops even cleaner, we use the same pattern in many places

I'm thinking like
```ts
for await (const chunk of iterable) {
  switch (it.type) {
    case 'ping': {
        // ..
        break;
    }
    // ...
  }
```

We have a lint rule to ensure that switches are exhaustive so it could be quite nice - each `withX`-HOC could add a new `type`


Or maybe there's's an even neater pattern that I'm missing like

```ts
await handleIterableByType(iterable, {
  ping: () => stream.controller.enqueue({ comment: 'ping' }),
})
```

Code after:

  run(async () => {
    let iterable: AsyncIterable<TValue | typeof PING_SYM> = opts.data;
    
    iterable = withCancel(iterable, stream.cancelledPromise);

    if (opts.emitAndEndImmediately) {
      iterable = takeWithGrace(iterable, { count: 1, gracePeriodMs: 1 });
    }

    let maxDurationTimer: PromiseTimer | null = null;
    if (
      opts.maxDurationMs != null &&
      opts.maxDurationMs > 0 &&
      opts.maxDurationMs !== Infinity
    ) {
      maxDurationTimer = createPromiseTimer(opts.maxDurationMs).start();
      iterable = withCancel(iterable, maxDurationTimer.promise);
    }

    if (ping.enabled && ping.intervalMs !== Infinity && ping.intervalMs > 0) {
      iterable = withPing(iterable, ping.intervalMs);
    }

    try {
      for await (const value of iterable) {
        if (value === PING_SYM) {
          stream.controller.enqueue({ comment: 'ping' });
          continue;
        }

        const chunk: SSEvent = isTrackedEnvelope(value)
          ? { id: value[0], data: value[1] }
          : { data: value };
        if ('data' in chunk) {
          chunk.data = JSON.stringify(serialize(chunk.data));
        }

        stream.controller.enqueue(chunk);
      }
    } catch (err) {
      // ignore abort errors, send any other errors
      if (!(err instanceof Error) || err.name !== 'AbortError') {
        // `err` must be caused by `opts.data`, `JSON.stringify` or `serialize`.
        // So, a user error in any case.
        const error = getTRPCErrorFromUnknown(err);
        const data = opts.formatError?.({ error }) ?? null;
        stream.controller.enqueue({
          event: SERIALIZED_ERROR_EVENT,
          data: JSON.stringify(serialize(data)),
        });