style(gateway,backend): clear all biome warnings (no warnings left behind)
Address every remaining biome lint/format warning across both services so the codebase ships warning-free: - textCacheStore: drop unused deleteExpiredQdrantPoints import; hash image cache key (sha256[:32]) so long/base64 URLs no longer blow the text_analysis_cache PK B-tree 8191-byte index (was aborting the media analysis lock INSERT). - bootstrap: drop unused unhandledRejection promise param. - moderationOrchestrator: drop unused destructure at L197. - mediaDownloader / textBatchProcessor / transmitter: replace non-null assertions with proper null guards (stickerName ?? '', urlImages.get guard, backpressureQueue.shift guard). - backend utils: throw lastError ?? fallback instead of lastError!. - message-capture: remove unused (retentionDb), (moderationActionsDb, reviewsDb); simplify renderDiscordMentions guard to optional chain. - transmitter: remove dead write-only field + its assignments. No behavior change beyond the cache-key hashing (now deterministic fixed-length) and the intentional null-safety guards.
This commit is contained in:
@@ -108,5 +108,5 @@ export async function retryWithBackoff<T>(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw lastError!;
|
throw lastError ?? new Error("Request failed after all retries");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -315,7 +315,7 @@ export async function initializeDiscordGateway() {
|
|||||||
gracefulShutdown("uncaughtException");
|
gracefulShutdown("uncaughtException");
|
||||||
});
|
});
|
||||||
|
|
||||||
process.on("unhandledRejection", (reason, promise) => {
|
process.on("unhandledRejection", (reason) => {
|
||||||
const err =
|
const err =
|
||||||
reason instanceof Error ? reason : new Error(String(reason ?? "unknown"));
|
reason instanceof Error ? reason : new Error(String(reason ?? "unknown"));
|
||||||
const code = (err as NodeJS.ErrnoException).code ?? "";
|
const code = (err as NodeJS.ErrnoException).code ?? "";
|
||||||
|
|||||||
@@ -450,7 +450,7 @@ export async function downloadMediaCandidate(
|
|||||||
if (candidate.customEmojiId || candidate.stickerName) {
|
if (candidate.customEmojiId || candidate.stickerName) {
|
||||||
const vck = candidate.customEmojiId
|
const vck = candidate.customEmojiId
|
||||||
? makeCustomEmojiCacheKey(candidate.customEmojiId)
|
? makeCustomEmojiCacheKey(candidate.customEmojiId)
|
||||||
: makeStickerCacheKey(candidate.stickerName!);
|
: makeStickerCacheKey(candidate.stickerName ?? "");
|
||||||
const cached = await getCachedMediaAnalysis(vck);
|
const cached = await getCachedMediaAnalysis(vck);
|
||||||
if (cached) {
|
if (cached) {
|
||||||
const existing = mediaAnalysisMap.get(targetId) ?? [];
|
const existing = mediaAnalysisMap.get(targetId) ?? [];
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ export async function runModerationAnalysis(
|
|||||||
if (embeddings && embeddings.length === texts.length) {
|
if (embeddings && embeddings.length === texts.length) {
|
||||||
// index-aligned with semanticCandidates
|
// index-aligned with semanticCandidates
|
||||||
for (let i = 0; i < semanticCandidates.length; i++) {
|
for (let i = 0; i < semanticCandidates.length; i++) {
|
||||||
const { target, cacheKey } = semanticCandidates[i];
|
const { cacheKey } = semanticCandidates[i];
|
||||||
embeddingsByKey.set(cacheKey, embeddings[i]);
|
embeddingsByKey.set(cacheKey, embeddings[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -249,7 +249,8 @@ export async function runTextOnlyBatch(
|
|||||||
if (pics.length === 0) return { id: msg.id, lines: [] as string[] };
|
if (pics.length === 0) return { id: msg.id, lines: [] as string[] };
|
||||||
const lines = await Promise.all(
|
const lines = await Promise.all(
|
||||||
pics.map(async (url) => {
|
pics.map(async (url) => {
|
||||||
const img = urlImages.get(url)!;
|
const img = urlImages.get(url);
|
||||||
|
if (!img) return null;
|
||||||
try {
|
try {
|
||||||
const { data: resizedBuffer, mimeType: resizedMime } =
|
const { data: resizedBuffer, mimeType: resizedMime } =
|
||||||
await resizeImageForVision(img.data, maxDim);
|
await resizeImageForVision(img.data, maxDim);
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { createChildLogger } from "@/shared/logger/index";
|
|||||||
import { executeAll, executeGet } from "../../shared/database/drizzle.js";
|
import { executeAll, executeGet } from "../../shared/database/drizzle.js";
|
||||||
import { findBestEmbeddingMatch } from "./embeddingClient.js";
|
import { findBestEmbeddingMatch } from "./embeddingClient.js";
|
||||||
import {
|
import {
|
||||||
deleteExpiredQdrantPoints,
|
|
||||||
deleteQdrantPoint,
|
deleteQdrantPoint,
|
||||||
deleteQdrantPointsByContentHash,
|
deleteQdrantPointsByContentHash,
|
||||||
isQdrantConfigured,
|
isQdrantConfigured,
|
||||||
|
|||||||
@@ -515,7 +515,7 @@ export function renderDiscordMentions(
|
|||||||
content: string,
|
content: string,
|
||||||
metadata: string | null | undefined,
|
metadata: string | null | undefined,
|
||||||
): string {
|
): string {
|
||||||
if (!content || !content.includes("<")) return content;
|
if (!content?.includes("<")) return content;
|
||||||
const parsed = parseRichMessageMetadata(metadata);
|
const parsed = parseRichMessageMetadata(metadata);
|
||||||
const roleName = new Map(
|
const roleName = new Map(
|
||||||
(parsed?.mentionedRoles ?? []).map((r) => [r.id, r.name] as const),
|
(parsed?.mentionedRoles ?? []).map((r) => [r.id, r.name] as const),
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { and, desc, eq, inArray, type SQL, sql } from "drizzle-orm";
|
import { and, desc, eq, inArray, type SQL } from "drizzle-orm";
|
||||||
import type { NodePgDatabase } from "drizzle-orm/node-postgres";
|
import type { NodePgDatabase } from "drizzle-orm/node-postgres";
|
||||||
import type * as schema from "../../shared/database/schema.js";
|
import type * as schema from "../../shared/database/schema.js";
|
||||||
import { moderationActionsTable } from "../../shared/database/schema.js";
|
import { moderationActionsTable } from "../../shared/database/schema.js";
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { and, eq, isNull, or } from "drizzle-orm";
|
import { and, eq, isNull } from "drizzle-orm";
|
||||||
import type { NodePgDatabase } from "drizzle-orm/node-postgres";
|
import type { NodePgDatabase } from "drizzle-orm/node-postgres";
|
||||||
import { createChildLogger, type Logger } from "@/shared/logger/index";
|
import { createChildLogger, type Logger } from "@/shared/logger/index";
|
||||||
import type * as schema from "../../shared/database/schema.js";
|
import type * as schema from "../../shared/database/schema.js";
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { and, desc, eq, inArray, type SQL, sql } from "drizzle-orm";
|
import { and, desc, eq, inArray, type SQL } from "drizzle-orm";
|
||||||
import type { NodePgDatabase } from "drizzle-orm/node-postgres";
|
import type { NodePgDatabase } from "drizzle-orm/node-postgres";
|
||||||
import type * as schema from "../../shared/database/schema.js";
|
import type * as schema from "../../shared/database/schema.js";
|
||||||
import { messageReviewsTable } from "../../shared/database/schema.js";
|
import { messageReviewsTable } from "../../shared/database/schema.js";
|
||||||
|
|||||||
@@ -27,8 +27,6 @@ export class VoiceTransmitter {
|
|||||||
private gate = Promise.resolve();
|
private gate = Promise.resolve();
|
||||||
/** Set true before sending SIGTERM so exit handler knows it's intentional */
|
/** Set true before sending SIGTERM so exit handler knows it's intentional */
|
||||||
private _expectedExit = false;
|
private _expectedExit = false;
|
||||||
/** True while the underlying stream is in a drain state (backpressure) */
|
|
||||||
private draining = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start listening for PCM audio data from Redis and stream to Discord
|
* Start listening for PCM audio data from Redis and stream to Discord
|
||||||
@@ -179,15 +177,13 @@ export class VoiceTransmitter {
|
|||||||
const canContinue = stream.write(pcmBuffer);
|
const canContinue = stream.write(pcmBuffer);
|
||||||
// Backpressure: queue until drain
|
// Backpressure: queue until drain
|
||||||
if (!canContinue) {
|
if (!canContinue) {
|
||||||
this.draining = true;
|
|
||||||
stream.once("drain", () => {
|
stream.once("drain", () => {
|
||||||
this.draining = false;
|
|
||||||
// Re-acquire stream reference (could have been replaced by restart)
|
|
||||||
const currentStream = this.pcmStream;
|
const currentStream = this.pcmStream;
|
||||||
if (!currentStream || !this.isActive) return;
|
if (!currentStream || !this.isActive) return;
|
||||||
// Flush queued chunks
|
// Flush queued chunks
|
||||||
while (this.backpressureQueue.length > 0) {
|
while (this.backpressureQueue.length > 0) {
|
||||||
const queued = this.backpressureQueue.shift()!;
|
const queued = this.backpressureQueue.shift();
|
||||||
|
if (!queued) break;
|
||||||
try {
|
try {
|
||||||
if (!currentStream.write(queued)) break;
|
if (!currentStream.write(queued)) break;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -237,7 +233,6 @@ export class VoiceTransmitter {
|
|||||||
this.isActive = false;
|
this.isActive = false;
|
||||||
|
|
||||||
this.backpressureQueue = [];
|
this.backpressureQueue = [];
|
||||||
this.draining = false;
|
|
||||||
|
|
||||||
if (this.pcmStream) {
|
if (this.pcmStream) {
|
||||||
this.pcmStream.removeAllListeners("drain");
|
this.pcmStream.removeAllListeners("drain");
|
||||||
|
|||||||
Reference in New Issue
Block a user