CI / build + unit (pull_request) Successful in 1m8s
Production incident: the bridge TCP connection went zombie — outbound sends kept working for ~10 h while inbound packets stopped entirely, and /api/status stayed connected:true because nothing detects inbound silence on an established connection. - Track lastPacketAt: updated on every chunk received from the bridge in the lowest-level socket 'data' path (any frame kind, decodable or not) and reset when a connection successfully starts, so a fresh connection can't self-trigger. - Idle watchdog: a 30 s interval checks connected AND now - lastPacketAt > MESH_IDLE_TIMEOUT_MS (new env, default 600000 = 10 min) — logs WARN with the idle duration and destroys the socket so the EXISTING connect/retry loop re-establishes it with a fresh sync. No changes to connect-error retry or backoff; this only adds detection for established-but-silent connections. - TCP keepalive: socket.setKeepAlive(true, 30_000) on the bridge socket — cheap insurance against dead peers at the TCP level. Tests (fake-bridge based): silence past an overridden timeout forces a disconnect + reconnect; inbound traffic keeps resetting the idle clock so no false trigger; the default timeout does not fire in a test window; and setKeepAlive(true, 30_000) is asserted on the socket. checkIdle() is public so tests drive a tick without waiting for the real interval (like flushHistory()).
55 lines
1.6 KiB
JSON
55 lines
1.6 KiB
JSON
{
|
|
"name": "mesh-bot",
|
|
"version": "0.21.1",
|
|
"description": "",
|
|
"author": "",
|
|
"private": true,
|
|
"license": "UNLICENSED",
|
|
"scripts": {
|
|
"build": "nest build",
|
|
"deploy": "nest deploy",
|
|
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
"start": "nest start",
|
|
"start:dev": "nest start --watch",
|
|
"start:debug": "nest start --debug --watch",
|
|
"start:prod": "node dist/main",
|
|
"lint": "oxlint src/ test/",
|
|
"test": "vitest run",
|
|
"test:watch": "vitest",
|
|
"test:cov": "vitest run --coverage",
|
|
"test:debug": "vitest --inspect-brk --no-file-parallelism",
|
|
"test:e2e": "vitest run --config ./vitest.config.e2e.ts"
|
|
},
|
|
"dependencies": {
|
|
"@bufbuild/protobuf": "^2.15.0",
|
|
"@meshtastic/protobufs": "^2.8.0",
|
|
"@modelcontextprotocol/sdk": "^1.30.1",
|
|
"@nestjs/common": "^12.0.1",
|
|
"@nestjs/core": "^12.0.1",
|
|
"@nestjs/platform-express": "^12.0.1",
|
|
"@nestjs/schedule": "^12.0.2",
|
|
"@nestjs/swagger": "^12.0.2",
|
|
"@scalar/nestjs-api-reference": "^1.2.21",
|
|
"fast-xml-parser": "^5.11.1",
|
|
"reflect-metadata": "^0.2.2",
|
|
"rxjs": "^7.8.1"
|
|
},
|
|
"devDependencies": {
|
|
"@nestjs/cli": "^12.0.0",
|
|
"@nestjs/mau": "^0.2.6",
|
|
"@nestjs/schematics": "^12.0.0",
|
|
"@nestjs/testing": "^12.0.1",
|
|
"@types/express": "^5.0.0",
|
|
"@types/node": "^24.0.0",
|
|
"@types/supertest": "^7.0.0",
|
|
"@vitest/coverage-v8": "^4.1.2",
|
|
"oxlint": "^1.58.0",
|
|
"prettier": "^3.4.2",
|
|
"source-map-support": "^0.5.21",
|
|
"supertest": "^7.0.0",
|
|
"typescript": "^6.0.2",
|
|
"vite-tsconfig-paths": "^5.1.4",
|
|
"vitest": "^4.1.2"
|
|
}
|
|
}
|