/**
 * Runs the server side of the unstable Effect devtools socket protocol.
 *
 * Use this module when an integration needs to accept devtools clients over a
 * `SocketServer`, decode newline-delimited JSON messages, and handle each
 * connection with application-specific logic. It does not interpret spans or
 * metrics itself; it gives handlers a typed surface for the telemetry described
 * by `DevToolsSchema`.
 *
 * **Mental model**
 *
 * Each accepted socket becomes one `Client`. Incoming `Ping` requests are
 * answered internally with `Pong`, while all other decoded requests are offered
 * to the client's queue. Handler code reads that queue and sends non-pong
 * responses such as `MetricsRequest` through `Client.send`.
 *
 * **Gotchas**
 *
 * The client queue is scoped to the socket-processing fiber and is shut down
 * when that fiber terminates. Treat it as per-connection state, not as a
 * process-wide telemetry bus.
 *
 * @since 4.0.0
 */
import * as Effect from "../../Effect.js";
import * as Queue from "../../Queue.js";
import * as Schema from "../../Schema.js";
import * as Stream from "../../Stream.js";
import * as Ndjson from "../encoding/Ndjson.js";
import * as Socket from "../socket/Socket.js";
import * as SocketServer from "../socket/SocketServer.js";
import * as DevToolsSchema from "./DevToolsSchema.js";
const RequestSchema = /*#__PURE__*/Schema.toCodecJson(DevToolsSchema.Request);
const ResponseSchema = /*#__PURE__*/Schema.toCodecJson(DevToolsSchema.Response);
/**
 * Runs the devtools socket server.
 *
 * **Details**
 *
 * Each connection is decoded as NDJSON devtools protocol messages, `Ping`
 * requests are answered with `Pong`, and all other requests are delivered
 * through the `Client` passed to the handler.
 *
 * @category constructors
 * @since 4.0.0
 */
export const run = /*#__PURE__*/Effect.fnUntraced(function* (handle) {
  const server = yield* SocketServer.SocketServer;
  return yield* server.run(Effect.fnUntraced(function* (socket) {
    const responses = yield* Queue.unbounded();
    const requests = yield* Queue.unbounded();
    const client = {
      queue: requests,
      send: response => Queue.offer(responses, response).pipe(Effect.asVoid)
    };
    yield* Stream.fromQueue(responses).pipe(Stream.pipeThroughChannel(Ndjson.duplexSchemaString(Socket.toChannelString(socket), {
      inputSchema: ResponseSchema,
      outputSchema: RequestSchema
    })), Stream.runForEach(request => request._tag === "Ping" ? Queue.offer(responses, {
      _tag: "Pong"
    }) : Queue.offer(requests, request)), Effect.ensuring(Queue.shutdown(responses).pipe(Effect.andThen(Queue.shutdown(requests)))), Effect.forkChild);
    return yield* handle(client);
  }));
});
//# sourceMappingURL=DevToolsServer.js.map