chore(broker): wire mentions through WS topic_send + dedupe imports
WSSendMessage gains an optional mentions field; the broker forwards it into appendTopicMessage so WS-driven topic sends get the same write-time fan-out path as REST POST /v1/messages. v1 messages (today's plaintext-base64) still fall back to a body regex when the field is omitted, so existing CLIs aren't broken; v2 ciphertext clients in phase 3 will populate it. Also drops the duplicate meshMember import (kept the meshMember-as- memberTable alias which the rest of the file uses). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -38,7 +38,6 @@ import {
|
|||||||
meshFileKey,
|
meshFileKey,
|
||||||
meshContext,
|
meshContext,
|
||||||
meshMember as memberTable,
|
meshMember as memberTable,
|
||||||
meshMember,
|
|
||||||
meshMemory,
|
meshMemory,
|
||||||
meshNotification,
|
meshNotification,
|
||||||
meshState,
|
meshState,
|
||||||
@@ -896,12 +895,12 @@ async function fanOutMentions(args: {
|
|||||||
|
|
||||||
const recipients = await db
|
const recipients = await db
|
||||||
.select({
|
.select({
|
||||||
id: meshMember.id,
|
id: memberTable.id,
|
||||||
displayName: meshMember.displayName,
|
displayName: memberTable.displayName,
|
||||||
})
|
})
|
||||||
.from(meshMember)
|
.from(memberTable)
|
||||||
.where(
|
.where(
|
||||||
and(eq(meshMember.meshId, topic.meshId), isNull(meshMember.revokedAt)),
|
and(eq(memberTable.meshId, topic.meshId), isNull(memberTable.revokedAt)),
|
||||||
);
|
);
|
||||||
const tokenSet = new Set(tokens);
|
const tokenSet = new Set(tokens);
|
||||||
const targets = recipients
|
const targets = recipients
|
||||||
|
|||||||
@@ -1952,6 +1952,7 @@ async function handleSend(
|
|||||||
senderSessionPubkey: conn.sessionPubkey ?? undefined,
|
senderSessionPubkey: conn.sessionPubkey ?? undefined,
|
||||||
nonce: msg.nonce,
|
nonce: msg.nonce,
|
||||||
ciphertext: msg.ciphertext,
|
ciphertext: msg.ciphertext,
|
||||||
|
mentions: msg.mentions,
|
||||||
}).catch((e) =>
|
}).catch((e) =>
|
||||||
log.warn("appendTopicMessage failed", { topic_id: topicId, err: String(e) }),
|
log.warn("appendTopicMessage failed", { topic_id: topicId, err: String(e) }),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -98,6 +98,14 @@ export interface WSSendMessage {
|
|||||||
nonce: string; // base64
|
nonce: string; // base64
|
||||||
ciphertext: string; // base64
|
ciphertext: string; // base64
|
||||||
id?: string; // client-side correlation id
|
id?: string; // client-side correlation id
|
||||||
|
/**
|
||||||
|
* Optional client-extracted `@-mention` display names (lowercased,
|
||||||
|
* no `@` prefix, max 16). Required when `body_version: 2` cipher
|
||||||
|
* lands in v0.3.0 phase 3 — the server can't read v2 ciphertext to
|
||||||
|
* regex-match. Today's v1 plaintext path falls back to a regex on
|
||||||
|
* the body when this is absent.
|
||||||
|
*/
|
||||||
|
mentions?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Broker → client: an envelope addressed to this peer. */
|
/** Broker → client: an envelope addressed to this peer. */
|
||||||
|
|||||||
Reference in New Issue
Block a user