Files
smartrequest/readme.hints.md

6.0 KiB

SmartRequest Architecture Hints

Core Features

  • supports http
  • supports https
  • supports unix sockets on Node.js, Bun, and Deno
  • supports formData
  • supports file uploads
  • supports best practice keepAlive
  • dedicated functions for working with JSON request/response cycles
  • written in TypeScript
  • continuously updated
  • supports Node.js, Bun, Deno, and browser environments with automatic runtime detection
  • runtime-specific implementations using native APIs (Node http/https, Bun fetch, Deno fetch with HttpClient, browser fetch)
  • used in modules like @push.rocks/smartproxy and @api.global/typedrequest

Architecture Overview (as of v4.x with Bun and Deno support)

  • The project has a multi-layer architecture with runtime abstraction
  • Base layer (ts/core_base/) contains abstract classes and unified types
  • Node.js implementation (ts/core_node/) uses native http/https modules with unix socket support
  • Bun implementation (ts/core_bun/) uses Bun's native fetch with unix socket support via unix option
  • Deno implementation (ts/core_deno/) uses Deno's fetch with unix socket support via HttpClient proxy
  • Browser implementation (ts/core_fetch/) uses standard Fetch API for browser compatibility
  • Core module (ts/core/) uses @push.rocks/smartenv to detect runtime and dynamically load appropriate implementation
  • Client API (ts/client/) provides a fluent, chainable interface that works across all runtimes
  • Runtime detection order: Deno → Bun → Node.js → Browser (following smartenv detection best practices)

Key Components

Core Base Module (ts/core_base/)

  • request.ts: Abstract CoreRequest class defining the request interface
  • response.ts: Abstract CoreResponse class with fetch-like API
    • Defines stream() method that always returns web-style ReadableStream
    • Body can only be consumed once (throws error on second attempt)
  • types.ts: Unified TypeScript interfaces and types
    • Single ICoreRequestOptions interface for all implementations
    • Implementations handle unsupported options by throwing errors

Core Node Module (ts/core_node/)

  • request.ts: Node.js implementation using http/https modules
    • Supports unix socket connections and keep-alive agents
    • Converts Node.js specific options from unified interface
  • response.ts: Node.js CoreResponse implementation
    • stream() method converts Node.js stream to web ReadableStream
    • streamNode() method returns native Node.js stream
    • Methods like json(), text(), arrayBuffer() handle parsing

Core Fetch Module (ts/core_fetch/)

  • request.ts: Fetch API implementation for browsers
    • Throws errors for Node.js specific options (agent, socketPath)
    • Native support for CORS, credentials, and other browser features
  • response.ts: Fetch-based CoreResponse implementation
    • stream() returns native web ReadableStream from response.body
    • streamNode() throws error explaining it's not available in browser

Core Bun Module (ts/core_bun/)

  • request.ts: Bun implementation using native fetch with unix socket support
    • Uses Bun's unix fetch option for unix socket connections
    • Supports both unix and socketPath options (converts socketPath to unix)
    • Handles URL parsing for http://unix:/path/to/socket:/http/path format
    • Throws errors for Node.js specific options (agent)
  • response.ts: Bun-based CoreResponse implementation
    • stream() returns native web ReadableStream from response.body
    • streamNode() throws error (Bun uses web streams; users should use stream() instead)
  • types.ts: Extends base types with IBunRequestOptions including unix option

Core Deno Module (ts/core_deno/)

  • request.ts: Deno implementation using fetch with HttpClient proxy for unix sockets
    • Creates and caches Deno.HttpClient instances per socket path
    • Supports both explicit client option and automatic client creation from socketPath
    • HttpClient cache prevents creating multiple clients for same socket
    • Provides clearClientCache() static method for cleanup
    • Throws errors for Node.js specific options (agent)
  • response.ts: Deno-based CoreResponse implementation
    • stream() returns native web ReadableStream from response.body
    • streamNode() throws error (Deno uses web streams, not Node.js streams)
  • types.ts: Extends base types with IDenoRequestOptions including client option

Core Module (ts/core/)

  • Dynamically loads appropriate implementation based on environment
  • Uses @push.rocks/smartenv for environment detection
  • Exports unified types from core_base

Client API (ts/client/)

  • SmartRequest: Fluent API with method chaining
  • Returns CoreResponse objects with fetch-like methods
  • Supports pagination, retries, timeouts, and various response types

Stream Handling

  • stream() method always returns web-style ReadableStream across all platforms
  • In Node.js, converts native streams to web streams
  • streamNode() availability by runtime:
    • Node.js: Returns native Node.js ReadableStream (only runtime that supports this)
    • Bun: Throws error (use web streams via stream() instead)
    • Deno: Throws error (Deno uses web streams only)
    • Browser: Throws error (browsers use web streams only)
  • Consistent API across platforms with web streams as the common denominator
  • Only Node.js provides native Node.js streams via streamNode()

Binary Request Handling

  • Binary requests handled through ArrayBuffer API
  • Response body kept as Buffer/ArrayBuffer without string conversion
  • No automatic transformations applied to binary data

Testing

  • Use pnpm test to run all tests
  • Tests use @git.zone/tstest/tapbundle for assertions
  • Test file naming conventions:
    • test.node.ts - Node.js only tests
    • test.bun.ts - Bun only tests
    • test.deno.ts - Deno only tests
    • test.node+bun+deno.ts - Server-side runtime tests (all three)
    • test.browser.ts or test.chrome.ts - Browser tests
  • Unix socket tests check for Docker socket availability and skip if not present
  • Browser tests run in headless Chromium via puppeteer