@openmarket/rooms-client 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.d.ts +26 -6
- package/dist/client.js +79 -6
- package/dist/shared/rooms-protocol.d.ts +80 -1
- package/dist/shared/rooms-protocol.js +6 -0
- package/dist/social-types.d.ts +2 -0
- package/dist/types.d.ts +1 -1
- package/dist/version.d.ts +2 -2
- package/dist/version.js +2 -2
- package/package.json +7 -2
- package/src/client.ts +139 -8
- package/src/shared/rooms-protocol.ts +95 -1
- package/src/social-types.ts +2 -0
- package/src/types.ts +8 -0
- package/src/version.ts +2 -2
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type RoomAccessMode, type RoomAttachmentInput, type RoomAuditLogPayload, type RoomAuthSuccessPayload, type RoomBackfillPayload, type RoomClientPlatform, type RoomDmHistoryResultPayload, type RoomDmInboxUpdatedPayload, type RoomDmMessagePayload, type RoomDmOpenedPayload, type RoomFriendPresence, type RoomInvitedPayload, type RoomLedgerEntry, type RoomMemberRemovedPayload, type RoomMemberRoleChangedPayload, type RoomMeta, type RoomPinsPayload, type RoomPresencePayload, type RoomReactorsPayload, type RoomReadStatePayload, type RoomReportedPayload, type RoomRole, type RoomSearchResultsPayload, type RoomSearchScope, type RoomSpace, type RoomThreadPayload, type RoomTopic, type RoomTopicAttention, type RoomTopicResultPayload, type RoomTopicsResultPayload, type RoomUserStatus, type RoomWhoPayload } from "./types.js";
|
|
1
|
+
import { type RoomAccessMode, type RoomAttachmentInput, type RoomAuditLogPayload, type RoomAuthSuccessPayload, type RoomBackfillPayload, type RoomClientPlatform, type RoomDmHistoryResultPayload, type RoomDmInboxUpdatedPayload, type RoomDmMessageDeletedPayload, type RoomDmMessageEditedPayload, type RoomDmMessagePayload, type RoomDmOpenedPayload, type RoomDmPinsResultPayload, type RoomDmReactionUpdatedPayload, type RoomForwardMetadata, type RoomFriendPresence, type RoomInvitedPayload, type RoomLedgerEntry, type RoomMemberRemovedPayload, type RoomMemberRoleChangedPayload, type RoomMeta, type RoomPinsPayload, type RoomPresencePayload, type RoomReactorsPayload, type RoomReadStatePayload, type RoomReportedPayload, type RoomRole, type RoomSearchResultsPayload, type RoomSearchScope, type RoomSpace, type RoomThreadPayload, type RoomTopic, type RoomTopicAttention, type RoomTopicResultPayload, type RoomTopicsResultPayload, type RoomUserStatus, type RoomWhoPayload } from "./types.js";
|
|
2
2
|
import { type RoomWebSocketCtor, RoomWsClient } from "./ws-client.js";
|
|
3
3
|
export interface RoomClientConfig {
|
|
4
4
|
url: string;
|
|
@@ -212,6 +212,10 @@ export interface RoomDmSendRequest {
|
|
|
212
212
|
* URL. Stored on the message's imageUrl; the client signs keys on render.
|
|
213
213
|
* Additive — omitted for text-only sends. */
|
|
214
214
|
imageUrl?: string;
|
|
215
|
+
metadata?: RoomForwardMetadata;
|
|
216
|
+
}
|
|
217
|
+
export interface RoomDmReplyRequest extends RoomDmSendRequest {
|
|
218
|
+
replyTo: string;
|
|
215
219
|
}
|
|
216
220
|
export interface RoomDmReadRequest {
|
|
217
221
|
username?: string;
|
|
@@ -260,20 +264,20 @@ export declare function openRoomDmOnClient(client: RoomWsClient, request: RoomDm
|
|
|
260
264
|
export declare function requestRoomDmHistoryOnClient(client: RoomWsClient, request: RoomDmHistoryRequest, timeoutMs?: number): Promise<RoomDmHistoryResultPayload>;
|
|
261
265
|
export declare function markRoomDmReadOnClient(client: RoomWsClient, request: RoomDmReadRequest, timeoutMs?: number): Promise<RoomDmInboxUpdatedPayload>;
|
|
262
266
|
export declare function sendRoomDmOnClient(client: RoomWsClient, request: RoomDmSendRequest, timeoutMs?: number): Promise<RoomDmMessagePayload>;
|
|
263
|
-
|
|
264
|
-
|
|
267
|
+
export declare function replyRoomDmOnClient(client: RoomWsClient, request: RoomDmReplyRequest, timeoutMs?: number): Promise<RoomDmMessagePayload>;
|
|
268
|
+
/** Edit one of my DM messages and wait for the correlated relay update. */
|
|
265
269
|
export declare function editRoomDmOnClient(client: RoomWsClient, request: {
|
|
266
270
|
conversationId?: string;
|
|
267
271
|
username?: string;
|
|
268
272
|
messageId: string;
|
|
269
273
|
content: string;
|
|
270
|
-
}):
|
|
274
|
+
}, timeoutMs?: number): Promise<RoomDmMessageEditedPayload>;
|
|
271
275
|
/** Soft-delete one of my DM messages. The relay fans out DM_MESSAGE_DELETED. */
|
|
272
276
|
export declare function deleteRoomDmOnClient(client: RoomWsClient, request: {
|
|
273
277
|
conversationId?: string;
|
|
274
278
|
username?: string;
|
|
275
279
|
messageId: string;
|
|
276
|
-
}):
|
|
280
|
+
}, timeoutMs?: number): Promise<RoomDmMessageDeletedPayload>;
|
|
277
281
|
/** Toggle a reaction on a DM message. The relay fans out DM_REACTION_UPDATED. */
|
|
278
282
|
export declare function reactRoomDmOnClient(client: RoomWsClient, request: {
|
|
279
283
|
conversationId?: string;
|
|
@@ -281,7 +285,23 @@ export declare function reactRoomDmOnClient(client: RoomWsClient, request: {
|
|
|
281
285
|
messageId: string;
|
|
282
286
|
emoji: string;
|
|
283
287
|
op: "add" | "remove";
|
|
288
|
+
}, timeoutMs?: number): Promise<RoomDmReactionUpdatedPayload>;
|
|
289
|
+
/** Set shared pin state for a DM message. The relay fans out DM_PIN_UPDATED. */
|
|
290
|
+
export declare function pinRoomDmOnClient(client: RoomWsClient, request: {
|
|
291
|
+
conversationId?: string;
|
|
292
|
+
username?: string;
|
|
293
|
+
messageId: string;
|
|
284
294
|
}): void;
|
|
295
|
+
export declare function unpinRoomDmOnClient(client: RoomWsClient, request: {
|
|
296
|
+
conversationId?: string;
|
|
297
|
+
username?: string;
|
|
298
|
+
messageId: string;
|
|
299
|
+
}): void;
|
|
300
|
+
export declare function requestRoomDmPinsOnClient(client: RoomWsClient, request: {
|
|
301
|
+
conversationId?: string;
|
|
302
|
+
username?: string;
|
|
303
|
+
limit?: number;
|
|
304
|
+
}, timeoutMs?: number): Promise<RoomDmPinsResultPayload>;
|
|
285
305
|
export declare function peekRoom(config: RoomClientConfig, options: RoomPeekOptions): Promise<RoomBackfillPayload>;
|
|
286
306
|
export declare function sayRoom(config: RoomClientConfig, options: RoomSayOptions): Promise<RoomSayResult>;
|
|
287
307
|
export declare function joinRoom(config: RoomClientConfig, options: RoomJoinOptions): Promise<RoomJoinedSession>;
|
|
@@ -297,7 +317,7 @@ export declare function attachRejoinOnReconnect(client: RoomWsClient, options: R
|
|
|
297
317
|
* (1..128 chars after trim); dedupe on (userId, clientMsgId) is server-side
|
|
298
318
|
* work and NOT implied here.
|
|
299
319
|
*/
|
|
300
|
-
export declare function postRoomMessage(client: RoomWsClient, room: string, text: string, inReplyTo?: number, attachments?: RoomAttachmentInput[], topicId?: string, clientMsgId?: string): string;
|
|
320
|
+
export declare function postRoomMessage(client: RoomWsClient, room: string, text: string, inReplyTo?: number, attachments?: RoomAttachmentInput[], topicId?: string, clientMsgId?: string, metadata?: RoomForwardMetadata): string;
|
|
301
321
|
export declare function sendRoomTyping(client: RoomWsClient, room: string, state: "start" | "stop"): void;
|
|
302
322
|
export declare function sendRoomStatus(client: RoomWsClient, status: RoomUserStatus, statusText?: string | null, platform?: RoomClientPlatform): void;
|
|
303
323
|
/**
|
package/dist/client.js
CHANGED
|
@@ -480,6 +480,7 @@ export async function sendRoomDmOnClient(client, request, timeoutMs) {
|
|
|
480
480
|
...(request.username ? { username: request.username } : {}),
|
|
481
481
|
...(request.conversationId ? { conversationId: request.conversationId } : {}),
|
|
482
482
|
...(request.imageUrl ? { imageUrl: request.imageUrl } : {}),
|
|
483
|
+
...(request.metadata ? { metadata: request.metadata } : {}),
|
|
483
484
|
},
|
|
484
485
|
timestamp: Date.now(),
|
|
485
486
|
});
|
|
@@ -488,12 +489,35 @@ export async function sendRoomDmOnClient(client, request, timeoutMs) {
|
|
|
488
489
|
msg.payload.message.clientMsgId === clientMsgId, timeoutMs, requestId);
|
|
489
490
|
return sent.payload;
|
|
490
491
|
}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
492
|
+
export async function replyRoomDmOnClient(client, request, timeoutMs) {
|
|
493
|
+
const requestId = randomUUID();
|
|
494
|
+
const clientMsgId = request.clientMsgId ?? randomUUID();
|
|
495
|
+
client.send({
|
|
496
|
+
type: RoomClientMessageType.DM_REPLY,
|
|
497
|
+
payload: {
|
|
498
|
+
requestId,
|
|
499
|
+
content: request.content,
|
|
500
|
+
replyTo: request.replyTo,
|
|
501
|
+
clientMsgId,
|
|
502
|
+
...(request.username ? { username: request.username } : {}),
|
|
503
|
+
...(request.conversationId ? { conversationId: request.conversationId } : {}),
|
|
504
|
+
...(request.imageUrl ? { imageUrl: request.imageUrl } : {}),
|
|
505
|
+
...(request.metadata ? { metadata: request.metadata } : {}),
|
|
506
|
+
},
|
|
507
|
+
timestamp: Date.now(),
|
|
508
|
+
});
|
|
509
|
+
const sent = await client.waitFor(RoomServerMessageType.DM_MESSAGE, (msg) => msg.payload.requestId === requestId ||
|
|
510
|
+
msg.payload.clientMsgId === clientMsgId ||
|
|
511
|
+
msg.payload.message.clientMsgId === clientMsgId, timeoutMs, requestId);
|
|
512
|
+
return sent.payload;
|
|
513
|
+
}
|
|
514
|
+
/** Edit one of my DM messages and wait for the correlated relay update. */
|
|
515
|
+
export async function editRoomDmOnClient(client, request, timeoutMs) {
|
|
516
|
+
const requestId = randomUUID();
|
|
494
517
|
client.send({
|
|
495
518
|
type: RoomClientMessageType.DM_EDIT,
|
|
496
519
|
payload: {
|
|
520
|
+
requestId,
|
|
497
521
|
messageId: request.messageId,
|
|
498
522
|
content: request.content,
|
|
499
523
|
...(request.conversationId ? { conversationId: request.conversationId } : {}),
|
|
@@ -501,24 +525,32 @@ export function editRoomDmOnClient(client, request) {
|
|
|
501
525
|
},
|
|
502
526
|
timestamp: Date.now(),
|
|
503
527
|
});
|
|
528
|
+
const updated = await client.waitFor(RoomServerMessageType.DM_MESSAGE_EDITED, (msg) => msg.payload.requestId === requestId, timeoutMs, requestId);
|
|
529
|
+
return updated.payload;
|
|
504
530
|
}
|
|
505
531
|
/** Soft-delete one of my DM messages. The relay fans out DM_MESSAGE_DELETED. */
|
|
506
|
-
export function deleteRoomDmOnClient(client, request) {
|
|
532
|
+
export async function deleteRoomDmOnClient(client, request, timeoutMs) {
|
|
533
|
+
const requestId = randomUUID();
|
|
507
534
|
client.send({
|
|
508
535
|
type: RoomClientMessageType.DM_DELETE,
|
|
509
536
|
payload: {
|
|
537
|
+
requestId,
|
|
510
538
|
messageId: request.messageId,
|
|
511
539
|
...(request.conversationId ? { conversationId: request.conversationId } : {}),
|
|
512
540
|
...(request.username ? { username: request.username } : {}),
|
|
513
541
|
},
|
|
514
542
|
timestamp: Date.now(),
|
|
515
543
|
});
|
|
544
|
+
const updated = await client.waitFor(RoomServerMessageType.DM_MESSAGE_DELETED, (msg) => msg.payload.requestId === requestId, timeoutMs, requestId);
|
|
545
|
+
return updated.payload;
|
|
516
546
|
}
|
|
517
547
|
/** Toggle a reaction on a DM message. The relay fans out DM_REACTION_UPDATED. */
|
|
518
|
-
export function reactRoomDmOnClient(client, request) {
|
|
548
|
+
export async function reactRoomDmOnClient(client, request, timeoutMs) {
|
|
549
|
+
const requestId = randomUUID();
|
|
519
550
|
client.send({
|
|
520
551
|
type: RoomClientMessageType.DM_REACT,
|
|
521
552
|
payload: {
|
|
553
|
+
requestId,
|
|
522
554
|
messageId: request.messageId,
|
|
523
555
|
emoji: request.emoji,
|
|
524
556
|
op: request.op,
|
|
@@ -527,6 +559,46 @@ export function reactRoomDmOnClient(client, request) {
|
|
|
527
559
|
},
|
|
528
560
|
timestamp: Date.now(),
|
|
529
561
|
});
|
|
562
|
+
const updated = await client.waitFor(RoomServerMessageType.DM_REACTION_UPDATED, (msg) => msg.payload.requestId === requestId, timeoutMs, requestId);
|
|
563
|
+
return updated.payload;
|
|
564
|
+
}
|
|
565
|
+
/** Set shared pin state for a DM message. The relay fans out DM_PIN_UPDATED. */
|
|
566
|
+
export function pinRoomDmOnClient(client, request) {
|
|
567
|
+
client.send({
|
|
568
|
+
type: RoomClientMessageType.DM_PIN,
|
|
569
|
+
payload: {
|
|
570
|
+
messageId: request.messageId,
|
|
571
|
+
...(request.conversationId ? { conversationId: request.conversationId } : {}),
|
|
572
|
+
...(request.username ? { username: request.username } : {}),
|
|
573
|
+
},
|
|
574
|
+
timestamp: Date.now(),
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
export function unpinRoomDmOnClient(client, request) {
|
|
578
|
+
client.send({
|
|
579
|
+
type: RoomClientMessageType.DM_UNPIN,
|
|
580
|
+
payload: {
|
|
581
|
+
messageId: request.messageId,
|
|
582
|
+
...(request.conversationId ? { conversationId: request.conversationId } : {}),
|
|
583
|
+
...(request.username ? { username: request.username } : {}),
|
|
584
|
+
},
|
|
585
|
+
timestamp: Date.now(),
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
export async function requestRoomDmPinsOnClient(client, request, timeoutMs) {
|
|
589
|
+
const requestId = randomUUID();
|
|
590
|
+
client.send({
|
|
591
|
+
type: RoomClientMessageType.DM_PINS,
|
|
592
|
+
payload: {
|
|
593
|
+
requestId,
|
|
594
|
+
...(request.conversationId ? { conversationId: request.conversationId } : {}),
|
|
595
|
+
...(request.username ? { username: request.username } : {}),
|
|
596
|
+
...(request.limit ? { limit: request.limit } : {}),
|
|
597
|
+
},
|
|
598
|
+
timestamp: Date.now(),
|
|
599
|
+
});
|
|
600
|
+
const result = await client.waitFor(RoomServerMessageType.DM_PINS, (message) => message.payload.requestId === requestId, timeoutMs, requestId);
|
|
601
|
+
return result.payload;
|
|
530
602
|
}
|
|
531
603
|
export async function peekRoom(config, options) {
|
|
532
604
|
if (!config.webSocketCtor) {
|
|
@@ -641,7 +713,7 @@ export function attachRejoinOnReconnect(client, options, latestSeq, onRejoined,
|
|
|
641
713
|
* (1..128 chars after trim); dedupe on (userId, clientMsgId) is server-side
|
|
642
714
|
* work and NOT implied here.
|
|
643
715
|
*/
|
|
644
|
-
export function postRoomMessage(client, room, text, inReplyTo, attachments, topicId, clientMsgId) {
|
|
716
|
+
export function postRoomMessage(client, room, text, inReplyTo, attachments, topicId, clientMsgId, metadata) {
|
|
645
717
|
const msgId = clientMsgId ?? randomUUID();
|
|
646
718
|
client.send({
|
|
647
719
|
type: RoomClientMessageType.POST,
|
|
@@ -652,6 +724,7 @@ export function postRoomMessage(client, room, text, inReplyTo, attachments, topi
|
|
|
652
724
|
clientMsgId: msgId,
|
|
653
725
|
...(inReplyTo !== undefined ? { inReplyTo } : {}),
|
|
654
726
|
...(topicId ? { topicId } : {}),
|
|
727
|
+
...(metadata ? { metadata } : {}),
|
|
655
728
|
},
|
|
656
729
|
timestamp: Date.now(),
|
|
657
730
|
});
|
|
@@ -37,10 +37,14 @@ export declare const RoomClientMessageType: {
|
|
|
37
37
|
readonly DM_OPEN: "DM_OPEN";
|
|
38
38
|
readonly DM_HISTORY: "DM_HISTORY";
|
|
39
39
|
readonly DM_SEND: "DM_SEND";
|
|
40
|
+
readonly DM_REPLY: "DM_REPLY";
|
|
40
41
|
readonly DM_READ: "DM_READ";
|
|
41
42
|
readonly DM_EDIT: "DM_EDIT";
|
|
42
43
|
readonly DM_DELETE: "DM_DELETE";
|
|
43
44
|
readonly DM_REACT: "DM_REACT";
|
|
45
|
+
readonly DM_PIN: "DM_PIN";
|
|
46
|
+
readonly DM_UNPIN: "DM_UNPIN";
|
|
47
|
+
readonly DM_PINS: "DM_PINS";
|
|
44
48
|
readonly TOPIC_CREATE: "TOPIC_CREATE";
|
|
45
49
|
readonly TOPIC_RENAME: "TOPIC_RENAME";
|
|
46
50
|
readonly TOPIC_MOVE: "TOPIC_MOVE";
|
|
@@ -94,6 +98,8 @@ export declare const RoomServerMessageType: {
|
|
|
94
98
|
readonly DM_MESSAGE_EDITED: "DM_MESSAGE_EDITED";
|
|
95
99
|
readonly DM_MESSAGE_DELETED: "DM_MESSAGE_DELETED";
|
|
96
100
|
readonly DM_REACTION_UPDATED: "DM_REACTION_UPDATED";
|
|
101
|
+
readonly DM_PIN_UPDATED: "DM_PIN_UPDATED";
|
|
102
|
+
readonly DM_PINS: "DM_PINS";
|
|
97
103
|
readonly TOPIC: "TOPIC";
|
|
98
104
|
readonly TOPICS: "TOPICS";
|
|
99
105
|
readonly TOPIC_UPDATED: "TOPIC_UPDATED";
|
|
@@ -225,6 +231,19 @@ export interface RoomLedgerEntry {
|
|
|
225
231
|
pinnedAt?: string | number | Date | null | undefined;
|
|
226
232
|
attachments?: RoomAttachment[] | undefined;
|
|
227
233
|
roomRole?: RoomRole | null | undefined;
|
|
234
|
+
metadata?: (Record<string, unknown> & Partial<RoomForwardMetadata>) | undefined;
|
|
235
|
+
}
|
|
236
|
+
export type RoomForwardedFrom = {
|
|
237
|
+
kind: "room";
|
|
238
|
+
room: string;
|
|
239
|
+
seq: number;
|
|
240
|
+
handle: string;
|
|
241
|
+
} | {
|
|
242
|
+
kind: "dm";
|
|
243
|
+
handle: string;
|
|
244
|
+
};
|
|
245
|
+
export interface RoomForwardMetadata {
|
|
246
|
+
forwardedFrom: RoomForwardedFrom;
|
|
228
247
|
}
|
|
229
248
|
export interface RoomAttachment {
|
|
230
249
|
/**
|
|
@@ -472,12 +491,14 @@ export interface RoomDmMessage {
|
|
|
472
491
|
createdAt?: string | number | undefined;
|
|
473
492
|
/** Sealed DM: content is '' and the opaque envelope rides here. */
|
|
474
493
|
secret?: RoomLedgerSecretPayload | null | undefined;
|
|
475
|
-
metadata?: Record<string, unknown> | undefined;
|
|
494
|
+
metadata?: (Record<string, unknown> & Partial<RoomForwardMetadata>) | undefined;
|
|
476
495
|
/** Legacy public chat-image URL (renders as-is, no signing). */
|
|
477
496
|
imageUrl?: string | null | undefined;
|
|
478
497
|
/** Private, signed, scanned DM attachments (dm-attachments/ keyspace).
|
|
479
498
|
* Additive: old messages carry none and render unchanged. */
|
|
480
499
|
attachments?: RoomAttachment[] | undefined;
|
|
500
|
+
/** Shared pin state. Legacy messages omit it and read as unpinned. */
|
|
501
|
+
pinned?: boolean | undefined;
|
|
481
502
|
}
|
|
482
503
|
export interface RoomDmOpenPayload {
|
|
483
504
|
requestId?: string;
|
|
@@ -502,6 +523,11 @@ export interface RoomDmSendPayload {
|
|
|
502
523
|
/** DM-attachment key or legacy public image URL; stored on the message's
|
|
503
524
|
* imageUrl. Additive — text-only sends omit it. */
|
|
504
525
|
imageUrl?: string;
|
|
526
|
+
metadata?: RoomForwardMetadata | undefined;
|
|
527
|
+
}
|
|
528
|
+
/** Client → server: send a DM whose parent is another message in the same conversation. */
|
|
529
|
+
export interface RoomDmReplyPayload extends RoomDmSendPayload {
|
|
530
|
+
replyTo: string;
|
|
505
531
|
}
|
|
506
532
|
/** Client → server: edit one of my DM messages (sealed messages are rejected). */
|
|
507
533
|
export interface RoomDmEditPayload {
|
|
@@ -520,6 +546,7 @@ export interface RoomDmDeletePayload {
|
|
|
520
546
|
}
|
|
521
547
|
/** Server → both participants: a DM message was edited. */
|
|
522
548
|
export interface RoomDmMessageEditedPayload {
|
|
549
|
+
requestId?: string;
|
|
523
550
|
conversationId: string;
|
|
524
551
|
messageId: string;
|
|
525
552
|
content: string;
|
|
@@ -528,6 +555,7 @@ export interface RoomDmMessageEditedPayload {
|
|
|
528
555
|
}
|
|
529
556
|
/** Server → both participants: a DM message was soft-deleted (tombstone). */
|
|
530
557
|
export interface RoomDmMessageDeletedPayload {
|
|
558
|
+
requestId?: string;
|
|
531
559
|
conversationId: string;
|
|
532
560
|
messageId: string;
|
|
533
561
|
deletedAt: string | number;
|
|
@@ -544,6 +572,7 @@ export interface RoomDmReactPayload {
|
|
|
544
572
|
}
|
|
545
573
|
/** Server → both participants: a DM message's aggregated reactions changed. */
|
|
546
574
|
export interface RoomDmReactionUpdatedPayload {
|
|
575
|
+
requestId?: string;
|
|
547
576
|
conversationId: string;
|
|
548
577
|
messageId: string;
|
|
549
578
|
reactions: Array<{
|
|
@@ -552,6 +581,31 @@ export interface RoomDmReactionUpdatedPayload {
|
|
|
552
581
|
}>;
|
|
553
582
|
participant: RoomDmParticipant;
|
|
554
583
|
}
|
|
584
|
+
export interface RoomDmPinPayload {
|
|
585
|
+
requestId?: string;
|
|
586
|
+
conversationId?: string;
|
|
587
|
+
username?: string;
|
|
588
|
+
messageId: string;
|
|
589
|
+
}
|
|
590
|
+
export interface RoomDmPinsPayload {
|
|
591
|
+
requestId?: string;
|
|
592
|
+
conversationId?: string;
|
|
593
|
+
username?: string;
|
|
594
|
+
limit?: number;
|
|
595
|
+
}
|
|
596
|
+
export interface RoomDmPinUpdatedPayload {
|
|
597
|
+
requestId?: string;
|
|
598
|
+
conversationId: string;
|
|
599
|
+
participant: RoomDmParticipant;
|
|
600
|
+
messageId: string;
|
|
601
|
+
pinned: boolean;
|
|
602
|
+
}
|
|
603
|
+
export interface RoomDmPinsResultPayload {
|
|
604
|
+
requestId?: string;
|
|
605
|
+
conversationId: string;
|
|
606
|
+
participant: RoomDmParticipant;
|
|
607
|
+
pins: RoomDmMessage[];
|
|
608
|
+
}
|
|
555
609
|
export interface RoomDmReadPayload {
|
|
556
610
|
requestId?: string;
|
|
557
611
|
username?: string;
|
|
@@ -889,6 +943,7 @@ export type RoomClientMessage = {
|
|
|
889
943
|
clientMsgId?: string;
|
|
890
944
|
reason?: string;
|
|
891
945
|
requestId?: string;
|
|
946
|
+
metadata?: RoomForwardMetadata;
|
|
892
947
|
};
|
|
893
948
|
timestamp?: number;
|
|
894
949
|
} | {
|
|
@@ -1074,6 +1129,10 @@ export type RoomClientMessage = {
|
|
|
1074
1129
|
type: typeof RoomClientMessageType.DM_SEND;
|
|
1075
1130
|
payload: RoomDmSendPayload;
|
|
1076
1131
|
timestamp?: number;
|
|
1132
|
+
} | {
|
|
1133
|
+
type: typeof RoomClientMessageType.DM_REPLY;
|
|
1134
|
+
payload: RoomDmReplyPayload;
|
|
1135
|
+
timestamp?: number;
|
|
1077
1136
|
} | {
|
|
1078
1137
|
type: typeof RoomClientMessageType.DM_READ;
|
|
1079
1138
|
payload: RoomDmReadPayload;
|
|
@@ -1090,6 +1149,18 @@ export type RoomClientMessage = {
|
|
|
1090
1149
|
type: typeof RoomClientMessageType.DM_REACT;
|
|
1091
1150
|
payload: RoomDmReactPayload;
|
|
1092
1151
|
timestamp?: number;
|
|
1152
|
+
} | {
|
|
1153
|
+
type: typeof RoomClientMessageType.DM_PIN;
|
|
1154
|
+
payload: RoomDmPinPayload;
|
|
1155
|
+
timestamp?: number;
|
|
1156
|
+
} | {
|
|
1157
|
+
type: typeof RoomClientMessageType.DM_UNPIN;
|
|
1158
|
+
payload: RoomDmPinPayload;
|
|
1159
|
+
timestamp?: number;
|
|
1160
|
+
} | {
|
|
1161
|
+
type: typeof RoomClientMessageType.DM_PINS;
|
|
1162
|
+
payload: RoomDmPinsPayload;
|
|
1163
|
+
timestamp?: number;
|
|
1093
1164
|
} | {
|
|
1094
1165
|
type: typeof RoomClientMessageType.TOPIC_CREATE;
|
|
1095
1166
|
payload: RoomTopicCreatePayload;
|
|
@@ -1296,6 +1367,14 @@ export type RoomServerMessage = {
|
|
|
1296
1367
|
type: typeof RoomServerMessageType.DM_REACTION_UPDATED;
|
|
1297
1368
|
payload: RoomDmReactionUpdatedPayload;
|
|
1298
1369
|
timestamp: number;
|
|
1370
|
+
} | {
|
|
1371
|
+
type: typeof RoomServerMessageType.DM_PIN_UPDATED;
|
|
1372
|
+
payload: RoomDmPinUpdatedPayload;
|
|
1373
|
+
timestamp: number;
|
|
1374
|
+
} | {
|
|
1375
|
+
type: typeof RoomServerMessageType.DM_PINS;
|
|
1376
|
+
payload: RoomDmPinsResultPayload;
|
|
1377
|
+
timestamp: number;
|
|
1299
1378
|
} | {
|
|
1300
1379
|
type: typeof RoomServerMessageType.TOPIC;
|
|
1301
1380
|
payload: RoomTopicResultPayload;
|
|
@@ -37,10 +37,14 @@ export const RoomClientMessageType = {
|
|
|
37
37
|
DM_OPEN: "DM_OPEN",
|
|
38
38
|
DM_HISTORY: "DM_HISTORY",
|
|
39
39
|
DM_SEND: "DM_SEND",
|
|
40
|
+
DM_REPLY: "DM_REPLY",
|
|
40
41
|
DM_READ: "DM_READ",
|
|
41
42
|
DM_EDIT: "DM_EDIT",
|
|
42
43
|
DM_DELETE: "DM_DELETE",
|
|
43
44
|
DM_REACT: "DM_REACT",
|
|
45
|
+
DM_PIN: "DM_PIN",
|
|
46
|
+
DM_UNPIN: "DM_UNPIN",
|
|
47
|
+
DM_PINS: "DM_PINS",
|
|
44
48
|
TOPIC_CREATE: "TOPIC_CREATE",
|
|
45
49
|
TOPIC_RENAME: "TOPIC_RENAME",
|
|
46
50
|
TOPIC_MOVE: "TOPIC_MOVE",
|
|
@@ -93,6 +97,8 @@ export const RoomServerMessageType = {
|
|
|
93
97
|
DM_MESSAGE_EDITED: "DM_MESSAGE_EDITED",
|
|
94
98
|
DM_MESSAGE_DELETED: "DM_MESSAGE_DELETED",
|
|
95
99
|
DM_REACTION_UPDATED: "DM_REACTION_UPDATED",
|
|
100
|
+
DM_PIN_UPDATED: "DM_PIN_UPDATED",
|
|
101
|
+
DM_PINS: "DM_PINS",
|
|
96
102
|
TOPIC: "TOPIC",
|
|
97
103
|
TOPICS: "TOPICS",
|
|
98
104
|
TOPIC_UPDATED: "TOPIC_UPDATED",
|
package/dist/social-types.d.ts
CHANGED
|
@@ -130,6 +130,8 @@ export interface RoomDmMessage {
|
|
|
130
130
|
emoji: string;
|
|
131
131
|
users: string[];
|
|
132
132
|
}>;
|
|
133
|
+
/** Shared pin state. Additive; absent means unpinned. */
|
|
134
|
+
pinned?: boolean;
|
|
133
135
|
/** Client-minted idempotency tag echoed back on DM sends, so a sender's
|
|
134
136
|
* durable queue can settle its optimistic row. Additive (0.4.0). */
|
|
135
137
|
clientMsgId?: string;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type { RoomAccessMode, RoomAttachment, RoomAttachmentInput, RoomAuditEntry, RoomAuditLogPayload, RoomAuditLogRequestPayload, RoomAuthSuccessPayload, RoomBackfillPayload, RoomClientMessage, RoomClientPlatform, RoomCreatedPayload, RoomCreatePayload, RoomDmHistoryPayload, RoomDmHistoryResultPayload, RoomDmInboxUpdatedPayload, RoomDmMessage, RoomDmMessagePayload, RoomDmOpenedPayload, RoomDmOpenPayload, RoomDmParticipant, RoomDmReadPayload, RoomDmSendPayload, RoomEntryUpdatedPayload, RoomErrorPayload, RoomFriendPresence, RoomInvitedPayload, RoomInvitePayload, RoomLedgerEntry, RoomMember, RoomMemberRemovedPayload, RoomMemberRoleChangedPayload, RoomMemberTier, RoomMessagePayload, RoomMeta, RoomModerateMemberPayload, RoomMutedPayload, RoomPinsPayload, RoomPresenceDeltaPayload, RoomPresencePayload, RoomReactorsPayload, RoomReadStatePayload, RoomRemoveMemberPayload, RoomReportedPayload, RoomReportPayload, RoomResyncPayload, RoomRole, RoomRoleChangePayload, RoomSearchPayload, RoomSearchResultsPayload, RoomSearchScope, RoomServerMessage, RoomServerMessageOf, RoomSetAttentionPayload, RoomSetReadOnlyPayload, RoomSpace, RoomSpaceJoinedPayload, RoomSpacesPayload, RoomThreadPayload, RoomTopic, RoomTopicAttention, RoomTopicBucketState, RoomTopicCreatePayload, RoomTopicListPayload, RoomTopicMergePayload, RoomTopicMovePayload, RoomTopicRenamePayload, RoomTopicResolvePayload, RoomTopicResultPayload, RoomTopicSetAttentionPayload, RoomTopicsPolicy, RoomTopicsResultPayload, RoomTopicUpdatedPayload, RoomTypingPayload, RoomUserStatus, RoomWhoPayload, } from "./shared/rooms-protocol.js";
|
|
1
|
+
export type { RoomAccessMode, RoomAttachment, RoomAttachmentInput, RoomAuditEntry, RoomAuditLogPayload, RoomAuditLogRequestPayload, RoomAuthSuccessPayload, RoomBackfillPayload, RoomClientMessage, RoomClientPlatform, RoomCreatedPayload, RoomCreatePayload, RoomDmHistoryPayload, RoomDmHistoryResultPayload, RoomDmInboxUpdatedPayload, RoomDmMessage, RoomDmMessageDeletedPayload, RoomDmMessageEditedPayload, RoomDmMessagePayload, RoomDmOpenedPayload, RoomDmOpenPayload, RoomDmParticipant, RoomDmPinsResultPayload, RoomDmPinUpdatedPayload, RoomDmReactionUpdatedPayload, RoomDmReadPayload, RoomDmReplyPayload, RoomDmSendPayload, RoomEntryUpdatedPayload, RoomErrorPayload, RoomForwardedFrom, RoomForwardMetadata, RoomFriendPresence, RoomInvitedPayload, RoomInvitePayload, RoomLedgerEntry, RoomMember, RoomMemberRemovedPayload, RoomMemberRoleChangedPayload, RoomMemberTier, RoomMessagePayload, RoomMeta, RoomModerateMemberPayload, RoomMutedPayload, RoomPinsPayload, RoomPresenceDeltaPayload, RoomPresencePayload, RoomReactorsPayload, RoomReadStatePayload, RoomRemoveMemberPayload, RoomReportedPayload, RoomReportPayload, RoomResyncPayload, RoomRole, RoomRoleChangePayload, RoomSearchPayload, RoomSearchResultsPayload, RoomSearchScope, RoomServerMessage, RoomServerMessageOf, RoomSetAttentionPayload, RoomSetReadOnlyPayload, RoomSpace, RoomSpaceJoinedPayload, RoomSpacesPayload, RoomThreadPayload, RoomTopic, RoomTopicAttention, RoomTopicBucketState, RoomTopicCreatePayload, RoomTopicListPayload, RoomTopicMergePayload, RoomTopicMovePayload, RoomTopicRenamePayload, RoomTopicResolvePayload, RoomTopicResultPayload, RoomTopicSetAttentionPayload, RoomTopicsPolicy, RoomTopicsResultPayload, RoomTopicUpdatedPayload, RoomTypingPayload, RoomUserStatus, RoomWhoPayload, } from "./shared/rooms-protocol.js";
|
|
2
2
|
export { applyRoomPresenceDelta, isSystemRoomLedgerEntryType, ROOM_PRESENCE_SAMPLE_LIMIT, RoomClientMessageType, RoomLedgerEntryType, RoomServerMessageType, SUPPORTED_ROOM_PROTOCOL_VERSION, } from "./shared/rooms-protocol.js";
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.
|
|
2
|
-
export declare const RUNNER_VERSION = "0.
|
|
1
|
+
export declare const VERSION = "0.7.0";
|
|
2
|
+
export declare const RUNNER_VERSION = "0.7.0";
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = "0.
|
|
2
|
-
export const RUNNER_VERSION = "0.
|
|
1
|
+
export const VERSION = "0.7.0";
|
|
2
|
+
export const RUNNER_VERSION = "0.7.0";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openmarket/rooms-client",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "OM Rooms protocol client: wire types, WebSocket + REST clients, and chat view-models. Browser-safe (no node:/bun: imports).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -17,7 +17,12 @@
|
|
|
17
17
|
"bun": ">=1.3.0",
|
|
18
18
|
"node": ">=22"
|
|
19
19
|
},
|
|
20
|
-
"files": [
|
|
20
|
+
"files": [
|
|
21
|
+
"src",
|
|
22
|
+
"dist",
|
|
23
|
+
"README.md",
|
|
24
|
+
"LICENSE"
|
|
25
|
+
],
|
|
21
26
|
"publishConfig": {
|
|
22
27
|
"access": "public"
|
|
23
28
|
},
|
package/src/client.ts
CHANGED
|
@@ -16,8 +16,13 @@ import {
|
|
|
16
16
|
type RoomClientPlatform,
|
|
17
17
|
type RoomDmHistoryResultPayload,
|
|
18
18
|
type RoomDmInboxUpdatedPayload,
|
|
19
|
+
type RoomDmMessageDeletedPayload,
|
|
20
|
+
type RoomDmMessageEditedPayload,
|
|
19
21
|
type RoomDmMessagePayload,
|
|
20
22
|
type RoomDmOpenedPayload,
|
|
23
|
+
type RoomDmPinsResultPayload,
|
|
24
|
+
type RoomDmReactionUpdatedPayload,
|
|
25
|
+
type RoomForwardMetadata,
|
|
21
26
|
type RoomFriendPresence,
|
|
22
27
|
type RoomInvitedPayload,
|
|
23
28
|
type RoomLedgerEntry,
|
|
@@ -292,6 +297,11 @@ export interface RoomDmSendRequest {
|
|
|
292
297
|
* URL. Stored on the message's imageUrl; the client signs keys on render.
|
|
293
298
|
* Additive — omitted for text-only sends. */
|
|
294
299
|
imageUrl?: string;
|
|
300
|
+
metadata?: RoomForwardMetadata;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
export interface RoomDmReplyRequest extends RoomDmSendRequest {
|
|
304
|
+
replyTo: string;
|
|
295
305
|
}
|
|
296
306
|
|
|
297
307
|
export interface RoomDmReadRequest {
|
|
@@ -969,6 +979,40 @@ export async function sendRoomDmOnClient(
|
|
|
969
979
|
...(request.username ? { username: request.username } : {}),
|
|
970
980
|
...(request.conversationId ? { conversationId: request.conversationId } : {}),
|
|
971
981
|
...(request.imageUrl ? { imageUrl: request.imageUrl } : {}),
|
|
982
|
+
...(request.metadata ? { metadata: request.metadata } : {}),
|
|
983
|
+
},
|
|
984
|
+
timestamp: Date.now(),
|
|
985
|
+
});
|
|
986
|
+
const sent = await client.waitFor(
|
|
987
|
+
RoomServerMessageType.DM_MESSAGE,
|
|
988
|
+
(msg) =>
|
|
989
|
+
msg.payload.requestId === requestId ||
|
|
990
|
+
msg.payload.clientMsgId === clientMsgId ||
|
|
991
|
+
msg.payload.message.clientMsgId === clientMsgId,
|
|
992
|
+
timeoutMs,
|
|
993
|
+
requestId,
|
|
994
|
+
);
|
|
995
|
+
return sent.payload;
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
export async function replyRoomDmOnClient(
|
|
999
|
+
client: RoomWsClient,
|
|
1000
|
+
request: RoomDmReplyRequest,
|
|
1001
|
+
timeoutMs?: number,
|
|
1002
|
+
): Promise<RoomDmMessagePayload> {
|
|
1003
|
+
const requestId = randomUUID();
|
|
1004
|
+
const clientMsgId = request.clientMsgId ?? randomUUID();
|
|
1005
|
+
client.send({
|
|
1006
|
+
type: RoomClientMessageType.DM_REPLY,
|
|
1007
|
+
payload: {
|
|
1008
|
+
requestId,
|
|
1009
|
+
content: request.content,
|
|
1010
|
+
replyTo: request.replyTo,
|
|
1011
|
+
clientMsgId,
|
|
1012
|
+
...(request.username ? { username: request.username } : {}),
|
|
1013
|
+
...(request.conversationId ? { conversationId: request.conversationId } : {}),
|
|
1014
|
+
...(request.imageUrl ? { imageUrl: request.imageUrl } : {}),
|
|
1015
|
+
...(request.metadata ? { metadata: request.metadata } : {}),
|
|
972
1016
|
},
|
|
973
1017
|
timestamp: Date.now(),
|
|
974
1018
|
});
|
|
@@ -984,15 +1028,17 @@ export async function sendRoomDmOnClient(
|
|
|
984
1028
|
return sent.payload;
|
|
985
1029
|
}
|
|
986
1030
|
|
|
987
|
-
/** Edit one of my DM messages
|
|
988
|
-
|
|
989
|
-
export function editRoomDmOnClient(
|
|
1031
|
+
/** Edit one of my DM messages and wait for the correlated relay update. */
|
|
1032
|
+
export async function editRoomDmOnClient(
|
|
990
1033
|
client: RoomWsClient,
|
|
991
1034
|
request: { conversationId?: string; username?: string; messageId: string; content: string },
|
|
992
|
-
|
|
1035
|
+
timeoutMs?: number,
|
|
1036
|
+
): Promise<RoomDmMessageEditedPayload> {
|
|
1037
|
+
const requestId = randomUUID();
|
|
993
1038
|
client.send({
|
|
994
1039
|
type: RoomClientMessageType.DM_EDIT,
|
|
995
1040
|
payload: {
|
|
1041
|
+
requestId,
|
|
996
1042
|
messageId: request.messageId,
|
|
997
1043
|
content: request.content,
|
|
998
1044
|
...(request.conversationId ? { conversationId: request.conversationId } : {}),
|
|
@@ -1000,26 +1046,43 @@ export function editRoomDmOnClient(
|
|
|
1000
1046
|
},
|
|
1001
1047
|
timestamp: Date.now(),
|
|
1002
1048
|
});
|
|
1049
|
+
const updated = await client.waitFor(
|
|
1050
|
+
RoomServerMessageType.DM_MESSAGE_EDITED,
|
|
1051
|
+
(msg) => msg.payload.requestId === requestId,
|
|
1052
|
+
timeoutMs,
|
|
1053
|
+
requestId,
|
|
1054
|
+
);
|
|
1055
|
+
return updated.payload;
|
|
1003
1056
|
}
|
|
1004
1057
|
|
|
1005
1058
|
/** Soft-delete one of my DM messages. The relay fans out DM_MESSAGE_DELETED. */
|
|
1006
|
-
export function deleteRoomDmOnClient(
|
|
1059
|
+
export async function deleteRoomDmOnClient(
|
|
1007
1060
|
client: RoomWsClient,
|
|
1008
1061
|
request: { conversationId?: string; username?: string; messageId: string },
|
|
1009
|
-
|
|
1062
|
+
timeoutMs?: number,
|
|
1063
|
+
): Promise<RoomDmMessageDeletedPayload> {
|
|
1064
|
+
const requestId = randomUUID();
|
|
1010
1065
|
client.send({
|
|
1011
1066
|
type: RoomClientMessageType.DM_DELETE,
|
|
1012
1067
|
payload: {
|
|
1068
|
+
requestId,
|
|
1013
1069
|
messageId: request.messageId,
|
|
1014
1070
|
...(request.conversationId ? { conversationId: request.conversationId } : {}),
|
|
1015
1071
|
...(request.username ? { username: request.username } : {}),
|
|
1016
1072
|
},
|
|
1017
1073
|
timestamp: Date.now(),
|
|
1018
1074
|
});
|
|
1075
|
+
const updated = await client.waitFor(
|
|
1076
|
+
RoomServerMessageType.DM_MESSAGE_DELETED,
|
|
1077
|
+
(msg) => msg.payload.requestId === requestId,
|
|
1078
|
+
timeoutMs,
|
|
1079
|
+
requestId,
|
|
1080
|
+
);
|
|
1081
|
+
return updated.payload;
|
|
1019
1082
|
}
|
|
1020
1083
|
|
|
1021
1084
|
/** Toggle a reaction on a DM message. The relay fans out DM_REACTION_UPDATED. */
|
|
1022
|
-
export function reactRoomDmOnClient(
|
|
1085
|
+
export async function reactRoomDmOnClient(
|
|
1023
1086
|
client: RoomWsClient,
|
|
1024
1087
|
request: {
|
|
1025
1088
|
conversationId?: string;
|
|
@@ -1028,10 +1091,13 @@ export function reactRoomDmOnClient(
|
|
|
1028
1091
|
emoji: string;
|
|
1029
1092
|
op: "add" | "remove";
|
|
1030
1093
|
},
|
|
1031
|
-
|
|
1094
|
+
timeoutMs?: number,
|
|
1095
|
+
): Promise<RoomDmReactionUpdatedPayload> {
|
|
1096
|
+
const requestId = randomUUID();
|
|
1032
1097
|
client.send({
|
|
1033
1098
|
type: RoomClientMessageType.DM_REACT,
|
|
1034
1099
|
payload: {
|
|
1100
|
+
requestId,
|
|
1035
1101
|
messageId: request.messageId,
|
|
1036
1102
|
emoji: request.emoji,
|
|
1037
1103
|
op: request.op,
|
|
@@ -1040,6 +1106,69 @@ export function reactRoomDmOnClient(
|
|
|
1040
1106
|
},
|
|
1041
1107
|
timestamp: Date.now(),
|
|
1042
1108
|
});
|
|
1109
|
+
const updated = await client.waitFor(
|
|
1110
|
+
RoomServerMessageType.DM_REACTION_UPDATED,
|
|
1111
|
+
(msg) => msg.payload.requestId === requestId,
|
|
1112
|
+
timeoutMs,
|
|
1113
|
+
requestId,
|
|
1114
|
+
);
|
|
1115
|
+
return updated.payload;
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
/** Set shared pin state for a DM message. The relay fans out DM_PIN_UPDATED. */
|
|
1119
|
+
export function pinRoomDmOnClient(
|
|
1120
|
+
client: RoomWsClient,
|
|
1121
|
+
request: { conversationId?: string; username?: string; messageId: string },
|
|
1122
|
+
): void {
|
|
1123
|
+
client.send({
|
|
1124
|
+
type: RoomClientMessageType.DM_PIN,
|
|
1125
|
+
payload: {
|
|
1126
|
+
messageId: request.messageId,
|
|
1127
|
+
...(request.conversationId ? { conversationId: request.conversationId } : {}),
|
|
1128
|
+
...(request.username ? { username: request.username } : {}),
|
|
1129
|
+
},
|
|
1130
|
+
timestamp: Date.now(),
|
|
1131
|
+
});
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
export function unpinRoomDmOnClient(
|
|
1135
|
+
client: RoomWsClient,
|
|
1136
|
+
request: { conversationId?: string; username?: string; messageId: string },
|
|
1137
|
+
): void {
|
|
1138
|
+
client.send({
|
|
1139
|
+
type: RoomClientMessageType.DM_UNPIN,
|
|
1140
|
+
payload: {
|
|
1141
|
+
messageId: request.messageId,
|
|
1142
|
+
...(request.conversationId ? { conversationId: request.conversationId } : {}),
|
|
1143
|
+
...(request.username ? { username: request.username } : {}),
|
|
1144
|
+
},
|
|
1145
|
+
timestamp: Date.now(),
|
|
1146
|
+
});
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
export async function requestRoomDmPinsOnClient(
|
|
1150
|
+
client: RoomWsClient,
|
|
1151
|
+
request: { conversationId?: string; username?: string; limit?: number },
|
|
1152
|
+
timeoutMs?: number,
|
|
1153
|
+
): Promise<RoomDmPinsResultPayload> {
|
|
1154
|
+
const requestId = randomUUID();
|
|
1155
|
+
client.send({
|
|
1156
|
+
type: RoomClientMessageType.DM_PINS,
|
|
1157
|
+
payload: {
|
|
1158
|
+
requestId,
|
|
1159
|
+
...(request.conversationId ? { conversationId: request.conversationId } : {}),
|
|
1160
|
+
...(request.username ? { username: request.username } : {}),
|
|
1161
|
+
...(request.limit ? { limit: request.limit } : {}),
|
|
1162
|
+
},
|
|
1163
|
+
timestamp: Date.now(),
|
|
1164
|
+
});
|
|
1165
|
+
const result = await client.waitFor(
|
|
1166
|
+
RoomServerMessageType.DM_PINS,
|
|
1167
|
+
(message) => message.payload.requestId === requestId,
|
|
1168
|
+
timeoutMs,
|
|
1169
|
+
requestId,
|
|
1170
|
+
);
|
|
1171
|
+
return result.payload;
|
|
1043
1172
|
}
|
|
1044
1173
|
|
|
1045
1174
|
export async function peekRoom(
|
|
@@ -1195,6 +1324,7 @@ export function postRoomMessage(
|
|
|
1195
1324
|
attachments?: RoomAttachmentInput[],
|
|
1196
1325
|
topicId?: string,
|
|
1197
1326
|
clientMsgId?: string,
|
|
1327
|
+
metadata?: RoomForwardMetadata,
|
|
1198
1328
|
): string {
|
|
1199
1329
|
const msgId = clientMsgId ?? randomUUID();
|
|
1200
1330
|
client.send({
|
|
@@ -1206,6 +1336,7 @@ export function postRoomMessage(
|
|
|
1206
1336
|
clientMsgId: msgId,
|
|
1207
1337
|
...(inReplyTo !== undefined ? { inReplyTo } : {}),
|
|
1208
1338
|
...(topicId ? { topicId } : {}),
|
|
1339
|
+
...(metadata ? { metadata } : {}),
|
|
1209
1340
|
},
|
|
1210
1341
|
timestamp: Date.now(),
|
|
1211
1342
|
});
|
|
@@ -37,10 +37,14 @@ export const RoomClientMessageType = {
|
|
|
37
37
|
DM_OPEN: "DM_OPEN",
|
|
38
38
|
DM_HISTORY: "DM_HISTORY",
|
|
39
39
|
DM_SEND: "DM_SEND",
|
|
40
|
+
DM_REPLY: "DM_REPLY",
|
|
40
41
|
DM_READ: "DM_READ",
|
|
41
42
|
DM_EDIT: "DM_EDIT",
|
|
42
43
|
DM_DELETE: "DM_DELETE",
|
|
43
44
|
DM_REACT: "DM_REACT",
|
|
45
|
+
DM_PIN: "DM_PIN",
|
|
46
|
+
DM_UNPIN: "DM_UNPIN",
|
|
47
|
+
DM_PINS: "DM_PINS",
|
|
44
48
|
TOPIC_CREATE: "TOPIC_CREATE",
|
|
45
49
|
TOPIC_RENAME: "TOPIC_RENAME",
|
|
46
50
|
TOPIC_MOVE: "TOPIC_MOVE",
|
|
@@ -97,6 +101,8 @@ export const RoomServerMessageType = {
|
|
|
97
101
|
DM_MESSAGE_EDITED: "DM_MESSAGE_EDITED",
|
|
98
102
|
DM_MESSAGE_DELETED: "DM_MESSAGE_DELETED",
|
|
99
103
|
DM_REACTION_UPDATED: "DM_REACTION_UPDATED",
|
|
104
|
+
DM_PIN_UPDATED: "DM_PIN_UPDATED",
|
|
105
|
+
DM_PINS: "DM_PINS",
|
|
100
106
|
TOPIC: "TOPIC",
|
|
101
107
|
TOPICS: "TOPICS",
|
|
102
108
|
TOPIC_UPDATED: "TOPIC_UPDATED",
|
|
@@ -253,6 +259,23 @@ export interface RoomLedgerEntry {
|
|
|
253
259
|
pinnedAt?: string | number | Date | null | undefined;
|
|
254
260
|
attachments?: RoomAttachment[] | undefined;
|
|
255
261
|
roomRole?: RoomRole | null | undefined;
|
|
262
|
+
metadata?: (Record<string, unknown> & Partial<RoomForwardMetadata>) | undefined;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export type RoomForwardedFrom =
|
|
266
|
+
| {
|
|
267
|
+
kind: "room";
|
|
268
|
+
room: string;
|
|
269
|
+
seq: number;
|
|
270
|
+
handle: string;
|
|
271
|
+
}
|
|
272
|
+
| {
|
|
273
|
+
kind: "dm";
|
|
274
|
+
handle: string;
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
export interface RoomForwardMetadata {
|
|
278
|
+
forwardedFrom: RoomForwardedFrom;
|
|
256
279
|
}
|
|
257
280
|
|
|
258
281
|
export interface RoomAttachment {
|
|
@@ -560,12 +583,14 @@ export interface RoomDmMessage {
|
|
|
560
583
|
createdAt?: string | number | undefined;
|
|
561
584
|
/** Sealed DM: content is '' and the opaque envelope rides here. */
|
|
562
585
|
secret?: RoomLedgerSecretPayload | null | undefined;
|
|
563
|
-
metadata?: Record<string, unknown> | undefined;
|
|
586
|
+
metadata?: (Record<string, unknown> & Partial<RoomForwardMetadata>) | undefined;
|
|
564
587
|
/** Legacy public chat-image URL (renders as-is, no signing). */
|
|
565
588
|
imageUrl?: string | null | undefined;
|
|
566
589
|
/** Private, signed, scanned DM attachments (dm-attachments/ keyspace).
|
|
567
590
|
* Additive: old messages carry none and render unchanged. */
|
|
568
591
|
attachments?: RoomAttachment[] | undefined;
|
|
592
|
+
/** Shared pin state. Legacy messages omit it and read as unpinned. */
|
|
593
|
+
pinned?: boolean | undefined;
|
|
569
594
|
}
|
|
570
595
|
|
|
571
596
|
export interface RoomDmOpenPayload {
|
|
@@ -593,6 +618,12 @@ export interface RoomDmSendPayload {
|
|
|
593
618
|
/** DM-attachment key or legacy public image URL; stored on the message's
|
|
594
619
|
* imageUrl. Additive — text-only sends omit it. */
|
|
595
620
|
imageUrl?: string;
|
|
621
|
+
metadata?: RoomForwardMetadata | undefined;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
/** Client → server: send a DM whose parent is another message in the same conversation. */
|
|
625
|
+
export interface RoomDmReplyPayload extends RoomDmSendPayload {
|
|
626
|
+
replyTo: string;
|
|
596
627
|
}
|
|
597
628
|
|
|
598
629
|
/** Client → server: edit one of my DM messages (sealed messages are rejected). */
|
|
@@ -614,6 +645,7 @@ export interface RoomDmDeletePayload {
|
|
|
614
645
|
|
|
615
646
|
/** Server → both participants: a DM message was edited. */
|
|
616
647
|
export interface RoomDmMessageEditedPayload {
|
|
648
|
+
requestId?: string;
|
|
617
649
|
conversationId: string;
|
|
618
650
|
messageId: string;
|
|
619
651
|
content: string;
|
|
@@ -623,6 +655,7 @@ export interface RoomDmMessageEditedPayload {
|
|
|
623
655
|
|
|
624
656
|
/** Server → both participants: a DM message was soft-deleted (tombstone). */
|
|
625
657
|
export interface RoomDmMessageDeletedPayload {
|
|
658
|
+
requestId?: string;
|
|
626
659
|
conversationId: string;
|
|
627
660
|
messageId: string;
|
|
628
661
|
deletedAt: string | number;
|
|
@@ -641,12 +674,42 @@ export interface RoomDmReactPayload {
|
|
|
641
674
|
|
|
642
675
|
/** Server → both participants: a DM message's aggregated reactions changed. */
|
|
643
676
|
export interface RoomDmReactionUpdatedPayload {
|
|
677
|
+
requestId?: string;
|
|
644
678
|
conversationId: string;
|
|
645
679
|
messageId: string;
|
|
646
680
|
reactions: Array<{ emoji: string; users: string[] }>;
|
|
647
681
|
participant: RoomDmParticipant;
|
|
648
682
|
}
|
|
649
683
|
|
|
684
|
+
export interface RoomDmPinPayload {
|
|
685
|
+
requestId?: string;
|
|
686
|
+
conversationId?: string;
|
|
687
|
+
username?: string;
|
|
688
|
+
messageId: string;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
export interface RoomDmPinsPayload {
|
|
692
|
+
requestId?: string;
|
|
693
|
+
conversationId?: string;
|
|
694
|
+
username?: string;
|
|
695
|
+
limit?: number;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
export interface RoomDmPinUpdatedPayload {
|
|
699
|
+
requestId?: string;
|
|
700
|
+
conversationId: string;
|
|
701
|
+
participant: RoomDmParticipant;
|
|
702
|
+
messageId: string;
|
|
703
|
+
pinned: boolean;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
export interface RoomDmPinsResultPayload {
|
|
707
|
+
requestId?: string;
|
|
708
|
+
conversationId: string;
|
|
709
|
+
participant: RoomDmParticipant;
|
|
710
|
+
pins: RoomDmMessage[];
|
|
711
|
+
}
|
|
712
|
+
|
|
650
713
|
export interface RoomDmReadPayload {
|
|
651
714
|
requestId?: string;
|
|
652
715
|
username?: string;
|
|
@@ -1014,6 +1077,7 @@ export type RoomClientMessage =
|
|
|
1014
1077
|
clientMsgId?: string;
|
|
1015
1078
|
reason?: string;
|
|
1016
1079
|
requestId?: string;
|
|
1080
|
+
metadata?: RoomForwardMetadata;
|
|
1017
1081
|
};
|
|
1018
1082
|
timestamp?: number;
|
|
1019
1083
|
}
|
|
@@ -1189,6 +1253,11 @@ export type RoomClientMessage =
|
|
|
1189
1253
|
payload: RoomDmSendPayload;
|
|
1190
1254
|
timestamp?: number;
|
|
1191
1255
|
}
|
|
1256
|
+
| {
|
|
1257
|
+
type: typeof RoomClientMessageType.DM_REPLY;
|
|
1258
|
+
payload: RoomDmReplyPayload;
|
|
1259
|
+
timestamp?: number;
|
|
1260
|
+
}
|
|
1192
1261
|
| {
|
|
1193
1262
|
type: typeof RoomClientMessageType.DM_READ;
|
|
1194
1263
|
payload: RoomDmReadPayload;
|
|
@@ -1209,6 +1278,21 @@ export type RoomClientMessage =
|
|
|
1209
1278
|
payload: RoomDmReactPayload;
|
|
1210
1279
|
timestamp?: number;
|
|
1211
1280
|
}
|
|
1281
|
+
| {
|
|
1282
|
+
type: typeof RoomClientMessageType.DM_PIN;
|
|
1283
|
+
payload: RoomDmPinPayload;
|
|
1284
|
+
timestamp?: number;
|
|
1285
|
+
}
|
|
1286
|
+
| {
|
|
1287
|
+
type: typeof RoomClientMessageType.DM_UNPIN;
|
|
1288
|
+
payload: RoomDmPinPayload;
|
|
1289
|
+
timestamp?: number;
|
|
1290
|
+
}
|
|
1291
|
+
| {
|
|
1292
|
+
type: typeof RoomClientMessageType.DM_PINS;
|
|
1293
|
+
payload: RoomDmPinsPayload;
|
|
1294
|
+
timestamp?: number;
|
|
1295
|
+
}
|
|
1212
1296
|
| {
|
|
1213
1297
|
type: typeof RoomClientMessageType.TOPIC_CREATE;
|
|
1214
1298
|
payload: RoomTopicCreatePayload;
|
|
@@ -1461,6 +1545,16 @@ export type RoomServerMessage =
|
|
|
1461
1545
|
payload: RoomDmReactionUpdatedPayload;
|
|
1462
1546
|
timestamp: number;
|
|
1463
1547
|
}
|
|
1548
|
+
| {
|
|
1549
|
+
type: typeof RoomServerMessageType.DM_PIN_UPDATED;
|
|
1550
|
+
payload: RoomDmPinUpdatedPayload;
|
|
1551
|
+
timestamp: number;
|
|
1552
|
+
}
|
|
1553
|
+
| {
|
|
1554
|
+
type: typeof RoomServerMessageType.DM_PINS;
|
|
1555
|
+
payload: RoomDmPinsResultPayload;
|
|
1556
|
+
timestamp: number;
|
|
1557
|
+
}
|
|
1464
1558
|
| {
|
|
1465
1559
|
type: typeof RoomServerMessageType.TOPIC;
|
|
1466
1560
|
payload: RoomTopicResultPayload;
|
package/src/social-types.ts
CHANGED
|
@@ -144,6 +144,8 @@ export interface RoomDmMessage {
|
|
|
144
144
|
imageUrl?: string | null;
|
|
145
145
|
/** Aggregated reactions (per-emoji userId lists). Additive. */
|
|
146
146
|
reactions?: Array<{ emoji: string; users: string[] }>;
|
|
147
|
+
/** Shared pin state. Additive; absent means unpinned. */
|
|
148
|
+
pinned?: boolean;
|
|
147
149
|
/** Client-minted idempotency tag echoed back on DM sends, so a sender's
|
|
148
150
|
* durable queue can settle its optimistic row. Additive (0.4.0). */
|
|
149
151
|
clientMsgId?: string;
|
package/src/types.ts
CHANGED
|
@@ -15,14 +15,22 @@ export type {
|
|
|
15
15
|
RoomDmHistoryResultPayload,
|
|
16
16
|
RoomDmInboxUpdatedPayload,
|
|
17
17
|
RoomDmMessage,
|
|
18
|
+
RoomDmMessageDeletedPayload,
|
|
19
|
+
RoomDmMessageEditedPayload,
|
|
18
20
|
RoomDmMessagePayload,
|
|
19
21
|
RoomDmOpenedPayload,
|
|
20
22
|
RoomDmOpenPayload,
|
|
21
23
|
RoomDmParticipant,
|
|
24
|
+
RoomDmPinsResultPayload,
|
|
25
|
+
RoomDmPinUpdatedPayload,
|
|
26
|
+
RoomDmReactionUpdatedPayload,
|
|
22
27
|
RoomDmReadPayload,
|
|
28
|
+
RoomDmReplyPayload,
|
|
23
29
|
RoomDmSendPayload,
|
|
24
30
|
RoomEntryUpdatedPayload,
|
|
25
31
|
RoomErrorPayload,
|
|
32
|
+
RoomForwardedFrom,
|
|
33
|
+
RoomForwardMetadata,
|
|
26
34
|
RoomFriendPresence,
|
|
27
35
|
RoomInvitedPayload,
|
|
28
36
|
RoomInvitePayload,
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = "0.
|
|
2
|
-
export const RUNNER_VERSION = "0.
|
|
1
|
+
export const VERSION = "0.7.0";
|
|
2
|
+
export const RUNNER_VERSION = "0.7.0";
|