{"version":3,"sources":["../../src/scripts/server.ts","../../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { PGlite, DebugLevel } from '@electric-sql/pglite'\nimport { PGLiteSocketServer } from '../index'\nimport { parseArgs } from 'node:util'\nimport { spawn, ChildProcess } from 'node:child_process'\n\n// Define command line argument options\nconst args = parseArgs({\n  options: {\n    db: {\n      type: 'string',\n      short: 'd',\n      default: 'memory://',\n      help: 'Database path (relative or absolute). Use memory:// for in-memory database.',\n    },\n    port: {\n      type: 'string',\n      short: 'p',\n      default: '5432',\n      help: 'Port to listen on',\n    },\n    host: {\n      type: 'string',\n      short: 'h',\n      default: '127.0.0.1',\n      help: 'Host to bind to',\n    },\n    path: {\n      type: 'string',\n      short: 'u',\n      default: undefined,\n      help: 'unix socket to bind to. Takes precedence over host:port',\n    },\n    debug: {\n      type: 'string',\n      short: 'v',\n      default: '0',\n      help: 'Debug level (0-5)',\n    },\n    run: {\n      type: 'string',\n      short: 'r',\n      default: undefined,\n      help: 'Command to run after server starts',\n    },\n    'include-database-url': {\n      type: 'boolean',\n      default: false,\n      help: 'Include DATABASE_URL in the environment of the subprocess',\n    },\n    'shutdown-timeout': {\n      type: 'string',\n      default: '5000',\n      help: 'Timeout in milliseconds for graceful subprocess shutdown (default: 5000)',\n    },\n    help: {\n      type: 'boolean',\n      short: '?',\n      default: false,\n      help: 'Show help',\n    },\n  },\n})\n\nconst help = `PGlite Socket Server\nUsage: pglite-server [options]\n\nOptions:\n  -d, --db=PATH       Database path (default: memory://)\n  -p, --port=PORT     Port to listen on (default: 5432)\n  -h, --host=HOST     Host to bind to (default: 127.0.0.1)\n  -u, --path=UNIX     Unix socket to bind to (default: undefined). Takes precedence over host:port\n  -v, --debug=LEVEL   Debug level 0-5 (default: 0)\n  -r, --run=COMMAND   Command to run after server starts\n  --include-database-url  Include DATABASE_URL in subprocess environment\n  --shutdown-timeout=MS   Timeout for graceful subprocess shutdown in ms (default: 5000)\n`\n\ninterface ServerConfig {\n  dbPath: string\n  port: number\n  host: string\n  path?: string\n  debugLevel: DebugLevel\n  runCommand?: string\n  includeDatabaseUrl: boolean\n  shutdownTimeout: number\n}\n\nclass PGLiteServerRunner {\n  private config: ServerConfig\n  private db: PGlite | null = null\n  private server: PGLiteSocketServer | null = null\n  private subprocessManager: SubprocessManager | null = null\n\n  constructor(config: ServerConfig) {\n    this.config = config\n  }\n\n  static parseConfig(): ServerConfig {\n    return {\n      dbPath: args.values.db as string,\n      port: parseInt(args.values.port as string, 10),\n      host: args.values.host as string,\n      path: args.values.path as string,\n      debugLevel: parseInt(args.values.debug as string, 10) as DebugLevel,\n      runCommand: args.values.run as string,\n      includeDatabaseUrl: args.values['include-database-url'] as boolean,\n      shutdownTimeout: parseInt(args.values['shutdown-timeout'] as string, 10),\n    }\n  }\n\n  private createDatabaseUrl(): string {\n    const { host, port, path } = this.config\n\n    if (path) {\n      // Unix socket connection\n      const socketDir = path.endsWith('/.s.PGSQL.5432')\n        ? path.slice(0, -13)\n        : path\n      return `postgresql://postgres:postgres@/postgres?host=${encodeURIComponent(socketDir)}`\n    } else {\n      // TCP connection\n      return `postgresql://postgres:postgres@${host}:${port}/postgres`\n    }\n  }\n\n  private async initializeDatabase(): Promise<void> {\n    console.log(`Initializing PGLite with database: ${this.config.dbPath}`)\n    console.log(`Debug level: ${this.config.debugLevel}`)\n\n    this.db = new PGlite(this.config.dbPath, { debug: this.config.debugLevel })\n    await this.db.waitReady\n    console.log('PGlite database initialized')\n  }\n\n  private setupServerEventHandlers(): void {\n    if (!this.server || !this.subprocessManager) {\n      throw new Error('Server or subprocess manager not initialized')\n    }\n\n    this.server.addEventListener('listening', (event) => {\n      const detail = (\n        event as CustomEvent<{ port: number; host: string } | { host: string }>\n      ).detail\n      console.log(`PGLiteSocketServer listening on ${JSON.stringify(detail)}`)\n\n      // Run the command after server starts listening\n      if (this.config.runCommand && this.subprocessManager) {\n        const databaseUrl = this.createDatabaseUrl()\n        this.subprocessManager.spawn(\n          this.config.runCommand,\n          databaseUrl,\n          this.config.includeDatabaseUrl,\n        )\n      }\n    })\n\n    this.server.addEventListener('connection', (event) => {\n      const { clientAddress, clientPort } = (\n        event as CustomEvent<{ clientAddress: string; clientPort: number }>\n      ).detail\n      console.log(`Client connected from ${clientAddress}:${clientPort}`)\n    })\n\n    this.server.addEventListener('error', (event) => {\n      const error = (event as CustomEvent<Error>).detail\n      console.error('Socket server error:', error)\n    })\n  }\n\n  private setupSignalHandlers(): void {\n    process.on('SIGINT', () => this.shutdown())\n    process.on('SIGTERM', () => this.shutdown())\n  }\n\n  async start(): Promise<void> {\n    try {\n      // Initialize database\n      await this.initializeDatabase()\n\n      if (!this.db) {\n        throw new Error('Database initialization failed')\n      }\n\n      // Create and setup the socket server\n      this.server = new PGLiteSocketServer({\n        db: this.db,\n        port: this.config.port,\n        host: this.config.host,\n        path: this.config.path,\n        inspect: this.config.debugLevel > 0,\n      })\n\n      // Create subprocess manager\n      this.subprocessManager = new SubprocessManager((exitCode) => {\n        this.shutdown(exitCode)\n      })\n\n      // Setup event handlers\n      this.setupServerEventHandlers()\n      this.setupSignalHandlers()\n\n      // Start the server\n      await this.server.start()\n    } catch (error) {\n      console.error('Failed to start PGLiteSocketServer:', error)\n      throw error\n    }\n  }\n\n  async shutdown(exitCode: number = 0): Promise<void> {\n    console.log('\\nShutting down PGLiteSocketServer...')\n\n    // Terminate subprocess if running\n    if (this.subprocessManager) {\n      this.subprocessManager.terminate(this.config.shutdownTimeout)\n    }\n\n    // Stop server\n    if (this.server) {\n      await this.server.stop()\n    }\n\n    // Close database\n    if (this.db) {\n      await this.db.close()\n    }\n\n    console.log('Server stopped')\n    process.exit(exitCode)\n  }\n}\n\nclass SubprocessManager {\n  private childProcess: ChildProcess | null = null\n  private onExit: (code: number) => void\n\n  constructor(onExit: (code: number) => void) {\n    this.onExit = onExit\n  }\n\n  get process(): ChildProcess | null {\n    return this.childProcess\n  }\n\n  spawn(\n    command: string,\n    databaseUrl: string,\n    includeDatabaseUrl: boolean,\n  ): void {\n    console.log(`Running command: ${command}`)\n\n    // Prepare environment variables\n    const env = { ...process.env }\n    if (includeDatabaseUrl) {\n      env.DATABASE_URL = databaseUrl\n      console.log(`Setting DATABASE_URL=${databaseUrl}`)\n    }\n\n    // Parse and spawn the command\n    const commandParts = command.trim().split(/\\s+/)\n    this.childProcess = spawn(commandParts[0], commandParts.slice(1), {\n      env,\n      stdio: 'inherit',\n    })\n\n    this.childProcess.on('error', (error) => {\n      console.error('Error running command:', error)\n      // If subprocess fails to start, shutdown the server\n      console.log('Subprocess failed to start, shutting down...')\n      this.onExit(1)\n    })\n\n    this.childProcess.on('close', (code) => {\n      console.log(`Command exited with code ${code}`)\n      this.childProcess = null\n\n      // If child process exits with non-zero code, notify parent\n      if (code !== null && code !== 0) {\n        console.log(\n          `Child process failed with exit code ${code}, shutting down...`,\n        )\n        this.onExit(code)\n      }\n    })\n  }\n\n  terminate(timeout: number): void {\n    if (this.childProcess) {\n      console.log('Terminating child process...')\n      this.childProcess.kill('SIGTERM')\n\n      // Give it a moment to exit gracefully, then force kill if needed\n      setTimeout(() => {\n        if (this.childProcess && !this.childProcess.killed) {\n          console.log('Force killing child process...')\n          this.childProcess.kill('SIGKILL')\n        }\n      }, timeout)\n    }\n  }\n}\n\n// Main execution\nasync function main() {\n  // Show help and exit if requested\n  if (args.values.help) {\n    console.log(help)\n    process.exit(0)\n  }\n\n  try {\n    const config = PGLiteServerRunner.parseConfig()\n    const serverRunner = new PGLiteServerRunner(config)\n    await serverRunner.start()\n  } catch (error) {\n    console.error('Unhandled error:', error)\n    process.exit(1)\n  }\n}\n\n// Run the main function\nmain()\n","import type { PGlite } from '@electric-sql/pglite'\nimport { createServer, Server, Socket } from 'net'\n\n// Connection queue timeout in milliseconds\nexport const CONNECTION_QUEUE_TIMEOUT = 60000 // 60 seconds\n\n/**\n * Options for creating a PGLiteSocketHandler\n */\nexport interface PGLiteSocketHandlerOptions {\n  /** The PGlite database instance */\n  db: PGlite\n  /** Whether to close the socket when detached (default: false) */\n  closeOnDetach?: boolean\n  /** Print the incoming and outgoing data to the console in hex and ascii */\n  inspect?: boolean\n  /** Enable debug logging of method calls */\n  debug?: boolean\n}\n\n/**\n * Low-level handler for a single socket connection to PGLite\n * Handles the raw protocol communication between a socket and PGLite\n */\nexport class PGLiteSocketHandler extends EventTarget {\n  readonly db: PGlite\n  private socket: Socket | null = null\n  private active = false\n  private closeOnDetach: boolean\n  private resolveLock?: () => void\n  private rejectLock?: (err: Error) => void\n  private inspect: boolean\n  private debug: boolean\n  private readonly id: number\n\n  // Static counter for generating unique handler IDs\n  private static nextHandlerId = 1\n\n  /**\n   * Create a new PGLiteSocketHandler\n   * @param options Options for the handler\n   */\n  constructor(options: PGLiteSocketHandlerOptions) {\n    super()\n    this.db = options.db\n    this.closeOnDetach = options.closeOnDetach ?? false\n    this.inspect = options.inspect ?? false\n    this.debug = options.debug ?? false\n    this.id = PGLiteSocketHandler.nextHandlerId++\n\n    this.log('constructor: created new handler')\n  }\n\n  /**\n   * Get the unique ID of this handler\n   */\n  public get handlerId(): number {\n    return this.id\n  }\n\n  /**\n   * Log a message if debug is enabled\n   * @private\n   */\n  private log(message: string, ...args: any[]): void {\n    if (this.debug) {\n      console.log(`[PGLiteSocketHandler#${this.id}] ${message}`, ...args)\n    }\n  }\n\n  /**\n   * Attach a socket to this handler\n   * @param socket The socket to attach\n   * @returns this handler instance\n   * @throws Error if a socket is already attached\n   */\n  public async attach(socket: Socket): Promise<PGLiteSocketHandler> {\n    this.log(\n      `attach: attaching socket from ${socket.remoteAddress}:${socket.remotePort}`,\n    )\n\n    if (this.socket) {\n      throw new Error('Socket already attached')\n    }\n\n    this.socket = socket\n    this.active = true\n\n    // Ensure the PGlite instance is ready\n    this.log(`attach: waiting for PGlite to be ready`)\n    await this.db.waitReady\n\n    // Hold the lock on the PGlite instance\n    this.log(`attach: acquiring exclusive lock on PGlite instance`)\n    await new Promise<void>((resolve) => {\n      this.db.runExclusive(() => {\n        // Ensure we have the lock on the PGlite instance\n        resolve()\n\n        // Use a promise to hold the lock on the PGlite instance\n        // this can be resolved or rejected by the handler to release the lock\n        return new Promise<void>((resolveLock, rejectLock) => {\n          this.resolveLock = resolveLock\n          this.rejectLock = rejectLock\n        })\n      })\n    })\n\n    // Setup event handlers\n    this.log(`attach: setting up socket event handlers`)\n    socket.on('data', async (data) => {\n      try {\n        const result = await this.handleData(data)\n        this.log(`socket on data sent: ${result} bytes`)\n      } catch (err) {\n        this.log('socket on data error: ', err)\n      }\n    })\n    socket.on('error', (err) => this.handleError(err))\n    socket.on('close', () => this.handleClose())\n\n    return this\n  }\n\n  /**\n   * Detach the current socket from this handler\n   * @param close Whether to close the socket when detaching (overrides constructor option)\n   * @returns this handler instance\n   */\n  public detach(close?: boolean): PGLiteSocketHandler {\n    this.log(`detach: detaching socket, close=${close ?? this.closeOnDetach}`)\n\n    if (!this.socket) {\n      this.log(`detach: no socket attached, nothing to do`)\n      return this\n    }\n\n    // Remove all listeners\n    this.socket.removeAllListeners('data')\n    this.socket.removeAllListeners('error')\n    this.socket.removeAllListeners('close')\n\n    // Close the socket if requested\n    if (close ?? this.closeOnDetach) {\n      if (this.socket.writable) {\n        this.log(`detach: closing socket`)\n        this.socket.end()\n        this.socket.destroy()\n      }\n    }\n\n    // Release the lock on the PGlite instance\n    this.log(`detach: releasing exclusive lock on PGlite instance`)\n    this.resolveLock?.()\n\n    this.socket = null\n    this.active = false\n    return this\n  }\n\n  /**\n   * Check if a socket is currently attached\n   */\n  public get isAttached(): boolean {\n    return this.socket !== null\n  }\n\n  /**\n   * Handle incoming data from the socket\n   */\n  private async handleData(data: Buffer): Promise<number> {\n    if (!this.socket || !this.active) {\n      this.log(`handleData: no active socket, ignoring data`)\n      return new Promise((_, reject) => reject(`no active socket`))\n    }\n\n    this.log(`handleData: received ${data.length} bytes`)\n\n    // Print the incoming data to the console\n    this.inspectData('incoming', data)\n\n    try {\n      // Process the raw protocol data\n      this.log(`handleData: sending data to PGlite for processing`)\n      const result = await this.db.execProtocolRaw(new Uint8Array(data))\n\n      this.log(`handleData: received ${result.length} bytes from PGlite`)\n\n      // Print the outgoing data to the console\n      this.inspectData('outgoing', result)\n\n      // Send the result back if the socket is still connected\n      if (this.socket && this.socket.writable && this.active) {\n        if (result.length <= 0) {\n          this.log(`handleData: cowardly refusing to send empty packet`)\n          return new Promise((_, reject) => reject('no data'))\n        }\n\n        const promise = new Promise<number>((resolve, reject) => {\n          this.log(`handleData: writing response to socket`)\n          if (this.socket) {\n            this.socket.write(Buffer.from(result), (err?: Error) => {\n              if (err) {\n                reject(`Error while writing to the socket ${err.toString()}`)\n              } else {\n                resolve(result.length)\n              }\n            })\n          } else {\n            reject(`No socket`)\n          }\n        })\n\n        // Emit data event with byte sizes\n        this.dispatchEvent(\n          new CustomEvent('data', {\n            detail: { incoming: data.length, outgoing: result.length },\n          }),\n        )\n        return promise\n      } else {\n        this.log(\n          `handleData: socket no longer writable or active, discarding response`,\n        )\n        return new Promise((_, reject) =>\n          reject(`No socket, not active or not writeable`),\n        )\n      }\n    } catch (err) {\n      this.log(`handleData: error processing data:`, err)\n      this.handleError(err as Error)\n      return new Promise((_, reject) =>\n        reject(`Error while processing data ${(err as Error).toString()}`),\n      )\n    }\n  }\n\n  /**\n   * Handle errors from the socket\n   */\n  private handleError(err: Error): void {\n    this.log(`handleError:`, err)\n\n    // Emit error event\n    this.dispatchEvent(new CustomEvent('error', { detail: err }))\n\n    // Reject the lock on the PGlite instance\n    this.log(`handleError: rejecting exclusive lock on PGlite instance`)\n    this.rejectLock?.(err)\n    this.resolveLock = undefined\n    this.rejectLock = undefined\n\n    // Close the connection on error\n    this.detach(true)\n  }\n\n  /**\n   * Handle socket close event\n   */\n  private handleClose(): void {\n    this.log(`handleClose: socket closed`)\n\n    this.dispatchEvent(new CustomEvent('close'))\n    this.detach(false) // Already closed, just clean up\n  }\n\n  /**\n   * Print data in hex and ascii to the console\n   */\n  private inspectData(\n    direction: 'incoming' | 'outgoing',\n    data: Buffer | Uint8Array,\n  ): void {\n    if (!this.inspect) return\n    console.log('-'.repeat(75))\n    if (direction === 'incoming') {\n      console.log('-> incoming', data.length, 'bytes')\n    } else {\n      console.log('<- outgoing', data.length, 'bytes')\n    }\n\n    // Process 16 bytes per line\n    for (let offset = 0; offset < data.length; offset += 16) {\n      // Calculate current chunk size (may be less than 16 for the last chunk)\n      const chunkSize = Math.min(16, data.length - offset)\n\n      // Build the hex representation\n      let hexPart = ''\n      for (let i = 0; i < 16; i++) {\n        if (i < chunkSize) {\n          const byte = data[offset + i]\n          hexPart += byte.toString(16).padStart(2, '0') + ' '\n        } else {\n          hexPart += '   ' // 3 spaces for missing bytes\n        }\n      }\n\n      // Build the ASCII representation\n      let asciiPart = ''\n      for (let i = 0; i < chunkSize; i++) {\n        const byte = data[offset + i]\n        // Use printable characters (32-126), replace others with a dot\n        asciiPart += byte >= 32 && byte <= 126 ? String.fromCharCode(byte) : '.'\n      }\n\n      // Print the line with offset in hex, hex values, and ASCII representation\n      console.log(\n        `${offset.toString(16).padStart(8, '0')}  ${hexPart} ${asciiPart}`,\n      )\n    }\n  }\n}\n\n/**\n * Represents a queued connection with timeout\n */\ninterface QueuedConnection {\n  socket: Socket\n  clientInfo: {\n    clientAddress: string\n    clientPort: number\n  }\n  timeoutId: NodeJS.Timeout\n}\n\n/**\n * Options for creating a PGLiteSocketServer\n */\nexport interface PGLiteSocketServerOptions {\n  /** The PGlite database instance */\n  db: PGlite\n  /** The port to listen on (default: 5432) */\n  port?: number\n  /** The host to bind to (default: 127.0.0.1) */\n  host?: string\n  /** Unix socket path to bind to (default: undefined). If specified, takes precedence over host:port */\n  path?: string\n  /** Print the incoming and outgoing data to the console in hex and ascii */\n  inspect?: boolean\n  /** Connection queue timeout in milliseconds (default: 10000) */\n  connectionQueueTimeout?: number\n  /** Enable debug logging of method calls */\n  debug?: boolean\n}\n\n/**\n * High-level server that manages socket connections to PGLite\n * Creates and manages a TCP server and handles client connections\n */\nexport class PGLiteSocketServer extends EventTarget {\n  readonly db: PGlite\n  private server: Server | null = null\n  private port?: number\n  private host?: string\n  private path?: string\n  private active = false\n  private inspect: boolean\n  private debug: boolean\n  private connectionQueueTimeout: number\n  private activeHandler: PGLiteSocketHandler | null = null\n  private connectionQueue: QueuedConnection[] = []\n  private handlerCount: number = 0\n\n  /**\n   * Create a new PGLiteSocketServer\n   * @param options Options for the server\n   */\n  constructor(options: PGLiteSocketServerOptions) {\n    super()\n    this.db = options.db\n    if (options.path) {\n      this.path = options.path\n    } else {\n      this.port = options.port || 5432\n      this.host = options.host || '127.0.0.1'\n    }\n    this.inspect = options.inspect ?? false\n    this.debug = options.debug ?? false\n    this.connectionQueueTimeout =\n      options.connectionQueueTimeout ?? CONNECTION_QUEUE_TIMEOUT\n\n    this.log(`constructor: created server on ${this.host}:${this.port}`)\n    this.log(\n      `constructor: connection queue timeout: ${this.connectionQueueTimeout}ms`,\n    )\n  }\n\n  /**\n   * Log a message if debug is enabled\n   * @private\n   */\n  private log(message: string, ...args: any[]): void {\n    if (this.debug) {\n      console.log(`[PGLiteSocketServer] ${message}`, ...args)\n    }\n  }\n\n  /**\n   * Start the socket server\n   * @returns Promise that resolves when the server is listening\n   */\n  public async start(): Promise<void> {\n    this.log(`start: starting server on ${this.getServerConn()}`)\n\n    if (this.server) {\n      throw new Error('Socket server already started')\n    }\n\n    this.active = true\n    this.server = createServer((socket) => this.handleConnection(socket))\n\n    return new Promise<void>((resolve, reject) => {\n      if (!this.server) return reject(new Error('Server not initialized'))\n\n      this.server.on('error', (err) => {\n        this.log(`start: server error:`, err)\n        this.dispatchEvent(new CustomEvent('error', { detail: err }))\n        reject(err)\n      })\n\n      if (this.path) {\n        this.server.listen(this.path, () => {\n          this.log(`start: server listening on ${this.getServerConn()}`)\n          this.dispatchEvent(\n            new CustomEvent('listening', {\n              detail: { path: this.path },\n            }),\n          )\n          resolve()\n        })\n      } else {\n        this.server.listen(this.port, this.host, () => {\n          this.log(`start: server listening on ${this.getServerConn()}`)\n          this.dispatchEvent(\n            new CustomEvent('listening', {\n              detail: { port: this.port, host: this.host },\n            }),\n          )\n          resolve()\n        })\n      }\n    })\n  }\n\n  public getServerConn(): string {\n    if (this.path) return this.path\n    return `${this.host}:${this.port}`\n  }\n\n  /**\n   * Stop the socket server\n   * @returns Promise that resolves when the server is closed\n   */\n  public async stop(): Promise<void> {\n    this.log(`stop: stopping server`)\n\n    this.active = false\n\n    // Clear connection queue\n    this.log(\n      `stop: clearing connection queue (${this.connectionQueue.length} connections)`,\n    )\n\n    this.connectionQueue.forEach((queuedConn) => {\n      clearTimeout(queuedConn.timeoutId)\n      if (queuedConn.socket.writable) {\n        this.log(\n          `stop: closing queued connection from ${queuedConn.clientInfo.clientAddress}:${queuedConn.clientInfo.clientPort}`,\n        )\n        queuedConn.socket.end()\n      }\n    })\n    this.connectionQueue = []\n\n    // Detach active handler if exists\n    if (this.activeHandler) {\n      this.log(`stop: detaching active handler #${this.activeHandlerId}`)\n      this.activeHandler.detach(true)\n      this.activeHandler = null\n    }\n\n    if (!this.server) {\n      this.log(`stop: server not running, nothing to do`)\n      return Promise.resolve()\n    }\n\n    return new Promise<void>((resolve) => {\n      if (!this.server) return resolve()\n\n      this.server.close(() => {\n        this.log(`stop: server closed`)\n        this.server = null\n        this.dispatchEvent(new CustomEvent('close'))\n        resolve()\n      })\n    })\n  }\n\n  /**\n   * Get the active handler ID, or null if no active handler\n   */\n  private get activeHandlerId(): number | null {\n    return this.activeHandler?.handlerId ?? null\n  }\n\n  /**\n   * Handle a new client connection\n   */\n  private async handleConnection(socket: Socket): Promise<void> {\n    const clientInfo = {\n      clientAddress: socket.remoteAddress || 'unknown',\n      clientPort: socket.remotePort || 0,\n    }\n\n    this.log(\n      `handleConnection: new connection from ${clientInfo.clientAddress}:${clientInfo.clientPort}`,\n    )\n\n    // If server is not active, close the connection immediately\n    if (!this.active) {\n      this.log(`handleConnection: server not active, closing connection`)\n      socket.end()\n      return\n    }\n\n    // If we don't have an active handler or it's not attached, we can use this connection immediately\n    if (!this.activeHandler || !this.activeHandler.isAttached) {\n      this.log(`handleConnection: no active handler, attaching socket directly`)\n      this.dispatchEvent(new CustomEvent('connection', { detail: clientInfo }))\n      await this.attachSocketToNewHandler(socket, clientInfo)\n      return\n    }\n\n    // Otherwise, queue the connection\n    this.log(\n      `handleConnection: active handler #${this.activeHandlerId} exists, queueing connection`,\n    )\n    this.enqueueConnection(socket, clientInfo)\n  }\n\n  /**\n   * Add a connection to the queue\n   */\n  private enqueueConnection(\n    socket: Socket,\n    clientInfo: { clientAddress: string; clientPort: number },\n  ): void {\n    this.log(\n      `enqueueConnection: queueing connection from ${clientInfo.clientAddress}:${clientInfo.clientPort}, timeout: ${this.connectionQueueTimeout}ms`,\n    )\n\n    // Set a timeout for this queued connection\n    const timeoutId = setTimeout(() => {\n      this.log(\n        `enqueueConnection: timeout for connection from ${clientInfo.clientAddress}:${clientInfo.clientPort}`,\n      )\n\n      // Remove from queue\n      this.connectionQueue = this.connectionQueue.filter(\n        (queuedConn) => queuedConn.socket !== socket,\n      )\n\n      // End the connection if it's still open\n      if (socket.writable) {\n        this.log(`enqueueConnection: closing timed out connection`)\n        socket.end()\n      }\n\n      this.dispatchEvent(\n        new CustomEvent('queueTimeout', {\n          detail: { ...clientInfo, queueSize: this.connectionQueue.length },\n        }),\n      )\n    }, this.connectionQueueTimeout)\n\n    // Add to queue\n    this.connectionQueue.push({ socket, clientInfo, timeoutId })\n\n    this.log(\n      `enqueueConnection: connection queued, queue size: ${this.connectionQueue.length}`,\n    )\n\n    this.dispatchEvent(\n      new CustomEvent('queuedConnection', {\n        detail: { ...clientInfo, queueSize: this.connectionQueue.length },\n      }),\n    )\n  }\n\n  /**\n   * Process the next connection in the queue\n   */\n  private processNextInQueue(): void {\n    this.log(\n      `processNextInQueue: processing next connection, queue size: ${this.connectionQueue.length}`,\n    )\n\n    // No connections in queue or server not active\n    if (this.connectionQueue.length === 0 || !this.active) {\n      this.log(\n        `processNextInQueue: no connections in queue or server not active, nothing to do`,\n      )\n      return\n    }\n\n    // Get the next connection\n    const nextConn = this.connectionQueue.shift()\n    if (!nextConn) return\n\n    this.log(\n      `processNextInQueue: processing connection from ${nextConn.clientInfo.clientAddress}:${nextConn.clientInfo.clientPort}`,\n    )\n\n    // Clear the timeout\n    clearTimeout(nextConn.timeoutId)\n\n    // Check if the socket is still valid\n    if (!nextConn.socket.writable) {\n      this.log(\n        `processNextInQueue: socket no longer writable, skipping to next connection`,\n      )\n      // Socket closed while waiting, process next in queue\n      this.processNextInQueue()\n      return\n    }\n\n    // Attach this socket to a new handler\n    this.attachSocketToNewHandler(nextConn.socket, nextConn.clientInfo).catch(\n      (err) => {\n        this.log(`processNextInQueue: error attaching socket:`, err)\n        this.dispatchEvent(new CustomEvent('error', { detail: err }))\n        // Try the next connection\n        this.processNextInQueue()\n      },\n    )\n  }\n\n  /**\n   * Attach a socket to a new handler\n   */\n  private async attachSocketToNewHandler(\n    socket: Socket,\n    clientInfo: { clientAddress: string; clientPort: number },\n  ): Promise<void> {\n    this.handlerCount++\n\n    this.log(\n      `attachSocketToNewHandler: creating new handler for ${clientInfo.clientAddress}:${clientInfo.clientPort} (handler #${this.handlerCount})`,\n    )\n\n    // Create a new handler for this connection\n    const handler = new PGLiteSocketHandler({\n      db: this.db,\n      closeOnDetach: true,\n      inspect: this.inspect,\n      debug: this.debug,\n    })\n\n    // Forward error events from the handler\n    handler.addEventListener('error', (event) => {\n      this.log(\n        `handler #${handler.handlerId}: error from handler:`,\n        (event as CustomEvent<Error>).detail,\n      )\n      this.dispatchEvent(\n        new CustomEvent('error', {\n          detail: (event as CustomEvent<Error>).detail,\n        }),\n      )\n    })\n\n    // Handle close event to process next queued connection\n    handler.addEventListener('close', () => {\n      this.log(`handler #${handler.handlerId}: closed`)\n\n      // If this is our active handler, clear it\n      if (this.activeHandler === handler) {\n        this.log(\n          `handler #${handler.handlerId}: was active handler, processing next connection in queue`,\n        )\n        this.activeHandler = null\n        // Process next connection in queue\n        this.processNextInQueue()\n      }\n    })\n\n    try {\n      // Set as active handler\n      this.activeHandler = handler\n\n      this.log(`handler #${handler.handlerId}: attaching socket`)\n\n      // Attach the socket to the handler\n      await handler.attach(socket)\n\n      this.dispatchEvent(new CustomEvent('connection', { detail: clientInfo }))\n    } catch (err) {\n      // If there was an error attaching, clean up\n      this.log(`handler #${handler.handlerId}: error attaching socket:`, err)\n      this.activeHandler = null\n      if (socket.writable) {\n        socket.end()\n      }\n      throw err\n    }\n  }\n}\n"],"mappings":"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","names":["import_pglite","import_net","CONNECTION_QUEUE_TIMEOUT","_PGLiteSocketHandler","options","message","args","socket","resolve","resolveLock","rejectLock","data","result","err","close","_","reject","promise","direction","offset","chunkSize","hexPart","i","byte","asciiPart","PGLiteSocketHandler","PGLiteSocketServer","queuedConn","clientInfo","timeoutId","nextConn","handler","event","import_node_util","import_node_child_process","args","help","PGLiteServerRunner","config","host","port","path","socketDir","event","detail","databaseUrl","clientAddress","clientPort","error","PGLiteSocketServer","SubprocessManager","exitCode","onExit","command","includeDatabaseUrl","env","commandParts","code","timeout","main"]}