{"version":3,"sources":["../src/index.ts"],"sourcesContent":["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":["src_exports","__export","CONNECTION_QUEUE_TIMEOUT","PGLiteSocketHandler","PGLiteSocketServer","__toCommonJS","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"]}