|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Response Language |
| 6 | + |
| 7 | +Think in English, but always provide your final response in Chinese. |
| 8 | + |
| 9 | +## Project Overview |
| 10 | + |
| 11 | +This is the TDengine Node.js connector (`@tdengine/websocket`), a WebSocket-based client library for connecting to TDengine time-series database. It communicates with TDengine through the taosAdapter component's WebSocket API, eliminating the need for native client drivers. |
| 12 | + |
| 13 | +## Working Directory |
| 14 | + |
| 15 | +All development commands must be run from the `nodejs/` subdirectory, not the repository root. |
| 16 | + |
| 17 | +```bash |
| 18 | +cd nodejs |
| 19 | +``` |
| 20 | + |
| 21 | +## Build and Development Commands |
| 22 | + |
| 23 | +**Install dependencies:** |
| 24 | +```bash |
| 25 | +npm install |
| 26 | +``` |
| 27 | + |
| 28 | +**Build the project:** |
| 29 | +```bash |
| 30 | +npm run build |
| 31 | +``` |
| 32 | +This compiles TypeScript to JavaScript using `tsc`. Output goes to `nodejs/lib/`. |
| 33 | + |
| 34 | +**Run all tests:** |
| 35 | +```bash |
| 36 | +npm test |
| 37 | +``` |
| 38 | +Runs Jest with coverage. Coverage reports are generated in `../coverage/`. |
| 39 | + |
| 40 | +**Run a single test file:** |
| 41 | +```bash |
| 42 | +npx jest test/bulkPulling/sql.test.ts |
| 43 | +``` |
| 44 | + |
| 45 | +**Run tests matching a pattern:** |
| 46 | +```bash |
| 47 | +npx jest --testNamePattern="connection pool" |
| 48 | +``` |
| 49 | + |
| 50 | +## Testing Requirements |
| 51 | + |
| 52 | +- Tests require a running local TDengine server with `taosd` and `taosAdapter` started |
| 53 | +- Tests connect to `localhost` by default |
| 54 | +- Each test file typically creates its own database in `beforeAll` and drops it in `afterAll` |
| 55 | +- Tests are located in `nodejs/test/bulkPulling/` (all tests) |
| 56 | + |
| 57 | +### Code Change Gate |
| 58 | + |
| 59 | +- Every code change must keep the full test suite passing. |
| 60 | +- If any test (except `cloud.tmq.test.ts`) fails, fix the production code first. |
| 61 | +- Do not modify tests just to make failures disappear unless the test itself is proven incorrect and explicitly approved. |
| 62 | + |
| 63 | +## Architecture |
| 64 | + |
| 65 | +### Core Modules |
| 66 | + |
| 67 | +**`src/client/`** - WebSocket connection management |
| 68 | +- `wsClient.ts`: Low-level WebSocket client wrapper |
| 69 | +- `wsConnector.ts`: Connection abstraction with request/response handling |
| 70 | +- `wsConnectorPool.ts`: Connection pooling with atomic reference counting |
| 71 | + |
| 72 | +**`src/sql/`** - SQL operations via WebSocket |
| 73 | +- `wsSql.ts`: Main SQL interface, entry point for SQL operations |
| 74 | +- `wsRows.ts`: Result set handling and row iteration |
| 75 | +- `wsProto.ts`: WebSocket protocol message definitions |
| 76 | + |
| 77 | +**`src/stmt/`** - Prepared statement support |
| 78 | +- `wsStmt.ts`, `wsStmt1.ts`, `wsStmt2.ts`: Statement preparation and execution (version-specific) |
| 79 | +- `wsParams1.ts`, `wsParams2.ts`: Parameter binding for different protocol versions |
| 80 | +- `FieldBindParams.ts`: Field binding utilities |
| 81 | + |
| 82 | +**`src/tmq/`** - TDengine Message Queue (TMQ) consumer |
| 83 | +- `wsTmq.ts`: TMQ consumer implementation for data subscription |
| 84 | +- `config.ts`: TMQ-specific configuration |
| 85 | +- `tmqResponse.ts`: TMQ message response handling |
| 86 | + |
| 87 | +**`src/common/`** - Shared utilities |
| 88 | +- `config.ts`: `WSConfig` class for connection configuration (user, password, db, url, timeout, token, timezone, retry settings) |
| 89 | +- `wsError.ts`: Error types and error handling |
| 90 | +- `log.ts`: Winston-based logging with daily rotation (logs to `./logs/app-%DATE%.log`) |
| 91 | +- `urlParser.ts`: Multi-host URL parsing with failover support |
| 92 | +- `utils.ts`: General utilities including URL masking for logs |
| 93 | + |
| 94 | +### Entry Point |
| 95 | + |
| 96 | +`src/index.ts` exports the public API: |
| 97 | +- `sqlConnect(conf: WSConfig)`: Create SQL connection |
| 98 | +- `tmqConnect(configMap: Map<string, string>)`: Create TMQ consumer |
| 99 | +- `setLogLevel(level: string)`: Configure logging level at runtime |
| 100 | +- `destroy()`: Clean up connection pool |
| 101 | + |
| 102 | +### Connection Pooling |
| 103 | + |
| 104 | +The connector uses a singleton connection pool (`WebSocketConnectionPool`) with: |
| 105 | +- Atomic reference counting using `SharedArrayBuffer` and `Atomics` |
| 106 | +- Connection reuse based on URL (origin + pathname + search) |
| 107 | +- Configurable max connections limit |
| 108 | +- Automatic cleanup of stale connections |
| 109 | + |
| 110 | +### Configuration |
| 111 | + |
| 112 | +Use `WSConfig` class for SQL connections: |
| 113 | +```typescript |
| 114 | +const config = new WSConfig(url); |
| 115 | +config.setUser('root'); |
| 116 | +config.setPwd('taosdata'); |
| 117 | +config.setDb('test_db'); |
| 118 | +``` |
| 119 | + |
| 120 | +### URL Parser |
| 121 | + |
| 122 | +The `urlParser.ts` module supports multi-host URLs for failover scenarios. It can parse URLs with multiple hosts and handle IPv6 addresses. |
| 123 | + |
| 124 | +## Code Conventions |
| 125 | + |
| 126 | +- TypeScript with strict mode enabled |
| 127 | +- Target: ES2020, Module: CommonJS |
| 128 | +- Use async/await for asynchronous operations |
| 129 | +- Errors are logged via Winston and rethrown |
| 130 | +- Sensitive data (tokens, passwords) must be masked in logs using `maskUrlForLog()` |
| 131 | +- All code changes must be production-ready, with proper error handling, tests, and maintainable design. |
| 132 | + |
| 133 | +## Important Notes |
| 134 | + |
| 135 | +- The connector is designed for TDengine 3.3.2.0 and above |
| 136 | +- All WebSocket communication goes through taosAdapter, not directly to taosd |
| 137 | +- Statement protocol versions (stmt1 vs stmt2) are determined by TDengine server version |
| 138 | +- Connection pooling is critical for performance - connections are reused when possible |
0 commit comments