chore: Enable "curly" rule to avoid single-statement if confusion/errors.

This commit is contained in:
cpojer
2026-01-31 16:19:20 +09:00
parent 009b16fab8
commit 5ceff756e1
1266 changed files with 27871 additions and 9393 deletions

View File

@@ -13,19 +13,25 @@ export type ResolvedSignalAccount = {
function listConfiguredAccountIds(cfg: OpenClawConfig): string[] {
const accounts = cfg.channels?.signal?.accounts;
if (!accounts || typeof accounts !== "object") return [];
if (!accounts || typeof accounts !== "object") {
return [];
}
return Object.keys(accounts).filter(Boolean);
}
export function listSignalAccountIds(cfg: OpenClawConfig): string[] {
const ids = listConfiguredAccountIds(cfg);
if (ids.length === 0) return [DEFAULT_ACCOUNT_ID];
if (ids.length === 0) {
return [DEFAULT_ACCOUNT_ID];
}
return ids.toSorted((a, b) => a.localeCompare(b));
}
export function resolveDefaultSignalAccountId(cfg: OpenClawConfig): string {
const ids = listSignalAccountIds(cfg);
if (ids.includes(DEFAULT_ACCOUNT_ID)) return DEFAULT_ACCOUNT_ID;
if (ids.includes(DEFAULT_ACCOUNT_ID)) {
return DEFAULT_ACCOUNT_ID;
}
return ids[0] ?? DEFAULT_ACCOUNT_ID;
}
@@ -34,7 +40,9 @@ function resolveAccountConfig(
accountId: string,
): SignalAccountConfig | undefined {
const accounts = cfg.channels?.signal?.accounts;
if (!accounts || typeof accounts !== "object") return undefined;
if (!accounts || typeof accounts !== "object") {
return undefined;
}
return accounts[accountId] as SignalAccountConfig | undefined;
}

View File

@@ -33,7 +33,9 @@ function normalizeBaseUrl(url: string): string {
if (!trimmed) {
throw new Error("Signal base URL is required");
}
if (/^https?:\/\//i.test(trimmed)) return trimmed.replace(/\/+$/, "");
if (/^https?:\/\//i.test(trimmed)) {
return trimmed.replace(/\/+$/, "");
}
return `http://${trimmed}`.replace(/\/+$/, "");
}
@@ -117,7 +119,9 @@ export async function streamSignalEvents(params: {
}): Promise<void> {
const baseUrl = normalizeBaseUrl(params.baseUrl);
const url = new URL(`${baseUrl}/api/v1/events`);
if (params.account) url.searchParams.set("account", params.account);
if (params.account) {
url.searchParams.set("account", params.account);
}
const fetchImpl = resolveFetch();
if (!fetchImpl) {
@@ -138,7 +142,9 @@ export async function streamSignalEvents(params: {
let currentEvent: SignalSseEvent = {};
const flushEvent = () => {
if (!currentEvent.data && !currentEvent.event && !currentEvent.id) return;
if (!currentEvent.data && !currentEvent.event && !currentEvent.id) {
return;
}
params.onEvent({
event: currentEvent.event,
data: currentEvent.data,
@@ -149,13 +155,17 @@ export async function streamSignalEvents(params: {
while (true) {
const { value, done } = await reader.read();
if (done) break;
if (done) {
break;
}
buffer += decoder.decode(value, { stream: true });
let lineEnd = buffer.indexOf("\n");
while (lineEnd !== -1) {
let line = buffer.slice(0, lineEnd);
buffer = buffer.slice(lineEnd + 1);
if (line.endsWith("\r")) line = line.slice(0, -1);
if (line.endsWith("\r")) {
line = line.slice(0, -1);
}
if (line === "") {
flushEvent();

View File

@@ -20,11 +20,17 @@ export type SignalDaemonHandle = {
export function classifySignalCliLogLine(line: string): "log" | "error" | null {
const trimmed = line.trim();
if (!trimmed) return null;
if (!trimmed) {
return null;
}
// signal-cli commonly writes all logs to stderr; treat severity explicitly.
if (/\b(ERROR|WARN|WARNING)\b/.test(trimmed)) return "error";
if (/\b(ERROR|WARN|WARNING)\b/.test(trimmed)) {
return "error";
}
// Some signal-cli failures are not tagged with WARN/ERROR but should still be surfaced loudly.
if (/\b(FAILED|SEVERE|EXCEPTION)\b/i.test(trimmed)) return "error";
if (/\b(FAILED|SEVERE|EXCEPTION)\b/i.test(trimmed)) {
return "error";
}
return "log";
}
@@ -40,9 +46,15 @@ function buildDaemonArgs(opts: SignalDaemonOpts): string[] {
if (opts.receiveMode) {
args.push("--receive-mode", opts.receiveMode);
}
if (opts.ignoreAttachments) args.push("--ignore-attachments");
if (opts.ignoreStories) args.push("--ignore-stories");
if (opts.sendReadReceipts) args.push("--send-read-receipts");
if (opts.ignoreAttachments) {
args.push("--ignore-attachments");
}
if (opts.ignoreStories) {
args.push("--ignore-stories");
}
if (opts.sendReadReceipts) {
args.push("--send-read-receipts");
}
return args;
}
@@ -58,15 +70,21 @@ export function spawnSignalDaemon(opts: SignalDaemonOpts): SignalDaemonHandle {
child.stdout?.on("data", (data) => {
for (const line of data.toString().split(/\r?\n/)) {
const kind = classifySignalCliLogLine(line);
if (kind === "log") log(`signal-cli: ${line.trim()}`);
else if (kind === "error") error(`signal-cli: ${line.trim()}`);
if (kind === "log") {
log(`signal-cli: ${line.trim()}`);
} else if (kind === "error") {
error(`signal-cli: ${line.trim()}`);
}
}
});
child.stderr?.on("data", (data) => {
for (const line of data.toString().split(/\r?\n/)) {
const kind = classifySignalCliLogLine(line);
if (kind === "log") log(`signal-cli: ${line.trim()}`);
else if (kind === "error") error(`signal-cli: ${line.trim()}`);
if (kind === "log") {
log(`signal-cli: ${line.trim()}`);
} else if (kind === "error") {
error(`signal-cli: ${line.trim()}`);
}
}
});
child.on("error", (err) => {

View File

@@ -54,8 +54,12 @@ function mapStyle(style: MarkdownStyle): SignalTextStyle | null {
function mergeStyles(styles: SignalTextStyleRange[]): SignalTextStyleRange[] {
const sorted = [...styles].toSorted((a, b) => {
if (a.start !== b.start) return a.start - b.start;
if (a.length !== b.length) return a.length - b.length;
if (a.start !== b.start) {
return a.start - b.start;
}
if (a.length !== b.length) {
return a.length - b.length;
}
return a.style.localeCompare(b.style);
});
@@ -80,7 +84,9 @@ function clampStyles(styles: SignalTextStyleRange[], maxLength: number): SignalT
const start = Math.max(0, Math.min(style.start, maxLength));
const end = Math.min(style.start + style.length, maxLength);
const length = end - start;
if (length > 0) clamped.push({ start, length, style: style.style });
if (length > 0) {
clamped.push({ start, length, style: style.style });
}
}
return clamped;
}
@@ -89,7 +95,9 @@ function applyInsertionsToStyles(
spans: SignalStyleSpan[],
insertions: Insertion[],
): SignalStyleSpan[] {
if (insertions.length === 0) return spans;
if (insertions.length === 0) {
return spans;
}
const sortedInsertions = [...insertions].toSorted((a, b) => a.pos - b.pos);
let updated = spans;
@@ -135,7 +143,9 @@ function applyInsertionsToStyles(
function renderSignalText(ir: MarkdownIR): SignalFormattedText {
const text = ir.text ?? "";
if (!text) return { text: "", styles: [] };
if (!text) {
return { text: "", styles: [] };
}
const sortedLinks = [...ir.links].toSorted((a, b) => a.start - b.start);
let out = "";
@@ -143,7 +153,9 @@ function renderSignalText(ir: MarkdownIR): SignalFormattedText {
const insertions: Insertion[] = [];
for (const link of sortedLinks) {
if (link.start < cursor) continue;
if (link.start < cursor) {
continue;
}
out += text.slice(cursor, link.end);
const href = link.href.trim();
@@ -170,7 +182,9 @@ function renderSignalText(ir: MarkdownIR): SignalFormattedText {
const mappedStyles: SignalStyleSpan[] = ir.styles
.map((span) => {
const mapped = mapStyle(span.style);
if (!mapped) return null;
if (!mapped) {
return null;
}
return { start: span.start, end: span.end, style: mapped };
})
.filter((span): span is SignalStyleSpan => span !== null);

View File

@@ -17,7 +17,9 @@ function looksLikeUuid(value: string): boolean {
return true;
}
const compact = value.replace(/-/g, "");
if (!/^[0-9a-f]+$/i.test(compact)) return false;
if (!/^[0-9a-f]+$/i.test(compact)) {
return false;
}
return /[a-f]/i.test(compact);
}
@@ -69,14 +71,20 @@ export function resolveSignalPeerId(sender: SignalSender): string {
function parseSignalAllowEntry(entry: string): SignalAllowEntry | null {
const trimmed = entry.trim();
if (!trimmed) return null;
if (trimmed === "*") return { kind: "any" };
if (!trimmed) {
return null;
}
if (trimmed === "*") {
return { kind: "any" };
}
const stripped = stripSignalPrefix(trimmed);
const lower = stripped.toLowerCase();
if (lower.startsWith("uuid:")) {
const raw = stripped.slice("uuid:".length).trim();
if (!raw) return null;
if (!raw) {
return null;
}
return { kind: "uuid", raw };
}
@@ -88,11 +96,15 @@ function parseSignalAllowEntry(entry: string): SignalAllowEntry | null {
}
export function isSignalSenderAllowed(sender: SignalSender, allowFrom: string[]): boolean {
if (allowFrom.length === 0) return false;
if (allowFrom.length === 0) {
return false;
}
const parsed = allowFrom
.map(parseSignalAllowEntry)
.filter((entry): entry is SignalAllowEntry => entry !== null);
if (parsed.some((entry) => entry.kind === "any")) return true;
if (parsed.some((entry) => entry.kind === "any")) {
return true;
}
return parsed.some((entry) => {
if (entry.kind === "phone" && sender.kind === "phone") {
return entry.e164 === sender.e164;
@@ -110,8 +122,14 @@ export function isSignalGroupAllowed(params: {
sender: SignalSender;
}): boolean {
const { groupPolicy, allowFrom, sender } = params;
if (groupPolicy === "disabled") return false;
if (groupPolicy === "open") return true;
if (allowFrom.length === 0) return false;
if (groupPolicy === "disabled") {
return false;
}
if (groupPolicy === "open") {
return true;
}
if (allowFrom.length === 0) {
return false;
}
return isSignalSenderAllowed(sender, allowFrom);
}

View File

@@ -95,7 +95,9 @@ function resolveSignalReactionTargets(reaction: SignalReactionMessage): SignalRe
function isSignalReactionMessage(
reaction: SignalReactionMessage | null | undefined,
): reaction is SignalReactionMessage {
if (!reaction) return false;
if (!reaction) {
return false;
}
const emoji = reaction.emoji?.trim();
const timestamp = reaction.targetSentTimestamp;
const hasTarget = Boolean(reaction.targetAuthor?.trim() || reaction.targetAuthorUuid?.trim());
@@ -111,10 +113,14 @@ function shouldEmitSignalReactionNotification(params: {
}) {
const { mode, account, targets, sender, allowlist } = params;
const effectiveMode = mode ?? "own";
if (effectiveMode === "off") return false;
if (effectiveMode === "off") {
return false;
}
if (effectiveMode === "own") {
const accountId = account?.trim();
if (!accountId || !targets || targets.length === 0) return false;
if (!accountId || !targets || targets.length === 0) {
return false;
}
const normalizedAccount = normalizeE164(accountId);
return targets.some((target) => {
if (target.kind === "uuid") {
@@ -124,7 +130,9 @@ function shouldEmitSignalReactionNotification(params: {
});
}
if (effectiveMode === "allowlist") {
if (!sender || !allowlist || allowlist.length === 0) return false;
if (!sender || !allowlist || allowlist.length === 0) {
return false;
}
return isSignalSenderAllowed(sender, allowlist);
}
return true;
@@ -160,7 +168,9 @@ async function waitForSignalDaemonReady(params: {
runtime: params.runtime,
check: async () => {
const res = await signalCheck(params.baseUrl, 1000);
if (res.ok) return { ok: true };
if (res.ok) {
return { ok: true };
}
return {
ok: false,
error: res.error ?? (res.status ? `HTTP ${res.status}` : "unreachable"),
@@ -178,7 +188,9 @@ async function fetchAttachment(params: {
maxBytes: number;
}): Promise<{ path: string; contentType?: string } | null> {
const { attachment } = params;
if (!attachment?.id) return null;
if (!attachment?.id) {
return null;
}
if (attachment.size && attachment.size > params.maxBytes) {
throw new Error(
`Signal attachment ${attachment.id} exceeds ${(params.maxBytes / (1024 * 1024)).toFixed(0)}MB limit`,
@@ -187,15 +199,23 @@ async function fetchAttachment(params: {
const rpcParams: Record<string, unknown> = {
id: attachment.id,
};
if (params.account) rpcParams.account = params.account;
if (params.groupId) rpcParams.groupId = params.groupId;
else if (params.sender) rpcParams.recipient = params.sender;
else return null;
if (params.account) {
rpcParams.account = params.account;
}
if (params.groupId) {
rpcParams.groupId = params.groupId;
} else if (params.sender) {
rpcParams.recipient = params.sender;
} else {
return null;
}
const result = await signalRpcRequest<{ data?: string }>("getAttachment", rpcParams, {
baseUrl: params.baseUrl,
});
if (!result?.data) return null;
if (!result?.data) {
return null;
}
const buffer = Buffer.from(result.data, "base64");
const saved = await saveMediaBuffer(
buffer,
@@ -222,7 +242,9 @@ async function deliverReplies(params: {
for (const payload of replies) {
const mediaList = payload.mediaUrls ?? (payload.mediaUrl ? [payload.mediaUrl] : []);
const text = payload.text ?? "";
if (!text && mediaList.length === 0) continue;
if (!text && mediaList.length === 0) {
continue;
}
if (mediaList.length === 0) {
for (const chunk of chunkTextWithMode(text, textLimit, chunkMode)) {
await sendMessageSignal(target, chunk, {
@@ -367,7 +389,9 @@ export async function monitorSignalProvider(opts: MonitorSignalOpts = {}): Promi
},
});
} catch (err) {
if (opts.abortSignal?.aborted) return;
if (opts.abortSignal?.aborted) {
return;
}
throw err;
} finally {
opts.abortSignal?.removeEventListener("abort", onAbort);

View File

@@ -176,7 +176,9 @@ export function createSignalEventHandler(deps: SignalEventHandlerDeps) {
const typingCallbacks = createTypingCallbacks({
start: async () => {
if (!ctxPayload.To) return;
if (!ctxPayload.To) {
return;
}
await sendTypingSignal(ctxPayload.To, {
baseUrl: deps.baseUrl,
account: deps.account,
@@ -252,17 +254,25 @@ export function createSignalEventHandler(deps: SignalEventHandlerDeps) {
debounceMs: inboundDebounceMs,
buildKey: (entry) => {
const conversationId = entry.isGroup ? (entry.groupId ?? "unknown") : entry.senderPeerId;
if (!conversationId || !entry.senderPeerId) return null;
if (!conversationId || !entry.senderPeerId) {
return null;
}
return `signal:${deps.accountId}:${conversationId}:${entry.senderPeerId}`;
},
shouldDebounce: (entry) => {
if (!entry.bodyText.trim()) return false;
if (entry.mediaPath || entry.mediaType) return false;
if (!entry.bodyText.trim()) {
return false;
}
if (entry.mediaPath || entry.mediaType) {
return false;
}
return !hasControlCommand(entry.bodyText, deps.cfg);
},
onFlush: async (entries) => {
const last = entries.at(-1);
if (!last) return;
if (!last) {
return;
}
if (entries.length === 1) {
await handleSignalInboundMessage(last);
return;
@@ -271,7 +281,9 @@ export function createSignalEventHandler(deps: SignalEventHandlerDeps) {
.map((entry) => entry.bodyText)
.filter(Boolean)
.join("\\n");
if (!combinedText.trim()) return;
if (!combinedText.trim()) {
return;
}
await handleSignalInboundMessage({
...last,
bodyText: combinedText,
@@ -285,7 +297,9 @@ export function createSignalEventHandler(deps: SignalEventHandlerDeps) {
});
return async (event: { event?: string; data?: string }) => {
if (event.event !== "receive" || !event.data) return;
if (event.event !== "receive" || !event.data) {
return;
}
let payload: SignalReceivePayload | null = null;
try {
@@ -298,13 +312,21 @@ export function createSignalEventHandler(deps: SignalEventHandlerDeps) {
deps.runtime.error?.(`receive exception: ${payload.exception.message}`);
}
const envelope = payload?.envelope;
if (!envelope) return;
if (envelope.syncMessage) return;
if (!envelope) {
return;
}
if (envelope.syncMessage) {
return;
}
const sender = resolveSignalSender(envelope);
if (!sender) return;
if (!sender) {
return;
}
if (deps.account && sender.kind === "phone") {
if (sender.e164 === normalizeE164(deps.account)) return;
if (sender.e164 === normalizeE164(deps.account)) {
return;
}
}
const dataMessage = envelope.dataMessage ?? envelope.editMessage?.dataMessage;
@@ -319,7 +341,9 @@ export function createSignalEventHandler(deps: SignalEventHandlerDeps) {
Boolean(messageText || quoteText) || Boolean(!reaction && dataMessage?.attachments?.length);
if (reaction && !hasBodyContent) {
if (reaction.isRemove) return; // Ignore reaction removals
if (reaction.isRemove) {
return;
} // Ignore reaction removals
const emojiLabel = reaction.emoji?.trim() || "emoji";
const senderDisplay = formatSignalSenderDisplay(sender);
const senderName = envelope.sourceName ?? senderDisplay;
@@ -332,7 +356,9 @@ export function createSignalEventHandler(deps: SignalEventHandlerDeps) {
sender,
allowlist: deps.reactionAllowlist,
});
if (!shouldNotify) return;
if (!shouldNotify) {
return;
}
const groupId = reaction.groupInfo?.groupId ?? undefined;
const groupName = reaction.groupInfo?.groupName ?? undefined;
@@ -373,13 +399,17 @@ export function createSignalEventHandler(deps: SignalEventHandlerDeps) {
enqueueSystemEvent(text, { sessionKey: route.sessionKey, contextKey });
return;
}
if (!dataMessage) return;
if (!dataMessage) {
return;
}
const senderDisplay = formatSignalSenderDisplay(sender);
const senderRecipient = resolveSignalRecipient(sender);
const senderPeerId = resolveSignalPeerId(sender);
const senderAllowId = formatSignalSenderId(sender);
if (!senderRecipient) return;
if (!senderRecipient) {
return;
}
const senderIdLine = formatSignalPairingIdLine(sender);
const groupId = dataMessage.groupInfo?.groupId ?? undefined;
const groupName = dataMessage.groupInfo?.groupName ?? undefined;
@@ -391,7 +421,9 @@ export function createSignalEventHandler(deps: SignalEventHandlerDeps) {
deps.dmPolicy === "open" ? true : isSignalSenderAllowed(sender, effectiveDmAllow);
if (!isGroup) {
if (deps.dmPolicy === "disabled") return;
if (deps.dmPolicy === "disabled") {
return;
}
if (!dmAllowed) {
if (deps.dmPolicy === "pairing") {
const senderId = senderAllowId;
@@ -490,11 +522,16 @@ export function createSignalEventHandler(deps: SignalEventHandlerDeps) {
}
const kind = mediaKindFromMime(mediaType ?? undefined);
if (kind) placeholder = `<media:${kind}>`;
else if (dataMessage.attachments?.length) placeholder = "<media:attachment>";
if (kind) {
placeholder = `<media:${kind}>`;
} else if (dataMessage.attachments?.length) {
placeholder = "<media:attachment>";
}
const bodyText = messageText || placeholder || dataMessage.quote?.text?.trim() || "";
if (!bodyText) return;
if (!bodyText) {
return;
}
const receiptTimestamp =
typeof envelope.timestamp === "number"

View File

@@ -9,10 +9,14 @@ export type SignalProbe = {
};
function parseSignalVersion(value: unknown): string | null {
if (typeof value === "string" && value.trim()) return value.trim();
if (typeof value === "string" && value.trim()) {
return value.trim();
}
if (typeof value === "object" && value !== null) {
const version = (value as { version?: unknown }).version;
if (typeof version === "string" && version.trim()) return version.trim();
if (typeof version === "string" && version.trim()) {
return version.trim();
}
}
return null;
}

View File

@@ -23,13 +23,17 @@ export type SignalReactionResult = {
function normalizeSignalId(raw: string): string {
const trimmed = raw.trim();
if (!trimmed) return "";
if (!trimmed) {
return "";
}
return trimmed.replace(/^signal:/i, "").trim();
}
function normalizeSignalUuid(raw: string): string {
const trimmed = normalizeSignalId(raw);
if (!trimmed) return "";
if (!trimmed) {
return "";
}
if (trimmed.toLowerCase().startsWith("uuid:")) {
return trimmed.slice("uuid:".length).trim();
}
@@ -44,9 +48,13 @@ function resolveTargetAuthorParams(params: {
const candidates = [params.targetAuthor, params.targetAuthorUuid, params.fallback];
for (const candidate of candidates) {
const raw = candidate?.trim();
if (!raw) continue;
if (!raw) {
continue;
}
const normalized = normalizeSignalUuid(raw);
if (normalized) return { targetAuthor: normalized };
if (normalized) {
return { targetAuthor: normalized };
}
}
return {};
}
@@ -118,9 +126,15 @@ export async function sendReactionSignal(
targetTimestamp,
...targetAuthorParams,
};
if (normalizedRecipient) params.recipients = [normalizedRecipient];
if (groupId) params.groupIds = [groupId];
if (account) params.account = account;
if (normalizedRecipient) {
params.recipients = [normalizedRecipient];
}
if (groupId) {
params.groupIds = [groupId];
}
if (account) {
params.account = account;
}
const result = await signalRpcRequest<{ timestamp?: number }>("sendReaction", params, {
baseUrl,
@@ -179,9 +193,15 @@ export async function removeReactionSignal(
remove: true,
...targetAuthorParams,
};
if (normalizedRecipient) params.recipients = [normalizedRecipient];
if (groupId) params.groupIds = [groupId];
if (account) params.account = account;
if (normalizedRecipient) {
params.recipients = [normalizedRecipient];
}
if (groupId) {
params.groupIds = [groupId];
}
if (account) {
params.account = account;
}
const result = await signalRpcRequest<{ timestamp?: number }>("sendReaction", params, {
baseUrl,

View File

@@ -34,7 +34,9 @@ type SignalTarget =
function parseTarget(raw: string): SignalTarget {
let value = raw.trim();
if (!value) throw new Error("Signal recipient is required");
if (!value) {
throw new Error("Signal recipient is required");
}
const lower = value.toLowerCase();
if (lower.startsWith("signal:")) {
value = value.slice("signal:".length).trim();
@@ -72,15 +74,21 @@ function buildTargetParams(
allow: SignalTargetAllowlist,
): SignalTargetParams | null {
if (target.type === "recipient") {
if (!allow.recipient) return null;
if (!allow.recipient) {
return null;
}
return { recipient: [target.recipient] };
}
if (target.type === "group") {
if (!allow.group) return null;
if (!allow.group) {
return null;
}
return { groupId: target.groupId };
}
if (target.type === "username") {
if (!allow.username) return null;
if (!allow.username) {
return null;
}
return { username: [target.username] };
}
return null;
@@ -139,7 +147,9 @@ export async function sendMessageSignal(
let textStyles: SignalTextStyleRange[] = [];
const textMode = opts.textMode ?? "markdown";
const maxBytes = (() => {
if (typeof opts.maxBytes === "number") return opts.maxBytes;
if (typeof opts.maxBytes === "number") {
return opts.maxBytes;
}
if (typeof accountInfo.config.mediaMaxMb === "number") {
return accountInfo.config.mediaMaxMb * 1024 * 1024;
}
@@ -186,7 +196,9 @@ export async function sendMessageSignal(
(style) => `${style.start}:${style.length}:${style.style}`,
);
}
if (account) params.account = account;
if (account) {
params.account = account;
}
if (attachments && attachments.length > 0) {
params.attachments = attachments;
}
@@ -221,10 +233,16 @@ export async function sendTypingSignal(
recipient: true,
group: true,
});
if (!targetParams) return false;
if (!targetParams) {
return false;
}
const params: Record<string, unknown> = { ...targetParams };
if (account) params.account = account;
if (opts.stop) params.stop = true;
if (account) {
params.account = account;
}
if (opts.stop) {
params.stop = true;
}
await signalRpcRequest("sendTyping", params, {
baseUrl,
timeoutMs: opts.timeoutMs,
@@ -237,18 +255,24 @@ export async function sendReadReceiptSignal(
targetTimestamp: number,
opts: SignalRpcOpts & { type?: SignalReceiptType } = {},
): Promise<boolean> {
if (!Number.isFinite(targetTimestamp) || targetTimestamp <= 0) return false;
if (!Number.isFinite(targetTimestamp) || targetTimestamp <= 0) {
return false;
}
const { baseUrl, account } = resolveSignalRpcContext(opts);
const targetParams = buildTargetParams(parseTarget(to), {
recipient: true,
});
if (!targetParams) return false;
if (!targetParams) {
return false;
}
const params: Record<string, unknown> = {
...targetParams,
targetTimestamp,
type: opts.type ?? "read",
};
if (account) params.account = account;
if (account) {
params.account = account;
}
await signalRpcRequest("sendReceipt", params, {
baseUrl,
timeoutMs: opts.timeoutMs,

View File

@@ -35,7 +35,9 @@ export async function runSignalSseLoop({
let reconnectAttempts = 0;
const logReconnectVerbose = (message: string) => {
if (!shouldLogVerbose()) return;
if (!shouldLogVerbose()) {
return;
}
logVerbose(message);
};
@@ -50,13 +52,17 @@ export async function runSignalSseLoop({
onEvent(event);
},
});
if (abortSignal?.aborted) return;
if (abortSignal?.aborted) {
return;
}
reconnectAttempts += 1;
const delayMs = computeBackoff(reconnectPolicy, reconnectAttempts);
logReconnectVerbose(`Signal SSE stream ended, reconnecting in ${delayMs / 1000}s...`);
await sleepWithAbort(delayMs, abortSignal);
} catch (err) {
if (abortSignal?.aborted) return;
if (abortSignal?.aborted) {
return;
}
runtime.error?.(`Signal SSE stream error: ${String(err)}`);
reconnectAttempts += 1;
const delayMs = computeBackoff(reconnectPolicy, reconnectAttempts);
@@ -64,7 +70,9 @@ export async function runSignalSseLoop({
try {
await sleepWithAbort(delayMs, abortSignal);
} catch (sleepErr) {
if (abortSignal?.aborted) return;
if (abortSignal?.aborted) {
return;
}
throw sleepErr;
}
}