@pmate/chat-sdk 0.12.0-next.65 → 0.12.0-next.66
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/lib/chat.d.ts +13 -2
- package/lib/chat.js +7 -1
- package/lib/index.d.ts +1 -1
- package/lib/messageView.d.ts +1 -0
- package/lib/messageView.js +1 -1
- package/lib/runtime/messageLaunch.d.ts +2 -0
- package/lib/runtime/messageLaunch.js +5 -1
- package/package.json +1 -1
package/lib/chat.d.ts
CHANGED
|
@@ -48,6 +48,17 @@ export type MessageQuery = {
|
|
|
48
48
|
all?: boolean;
|
|
49
49
|
refresh?: boolean;
|
|
50
50
|
};
|
|
51
|
+
export type ReadersQuery = {
|
|
52
|
+
afterProfileId?: string;
|
|
53
|
+
revision?: number;
|
|
54
|
+
};
|
|
55
|
+
export type GroupChanges = {
|
|
56
|
+
expectedRevision?: string;
|
|
57
|
+
addMembers?: readonly string[];
|
|
58
|
+
removeMembers?: readonly string[];
|
|
59
|
+
title?: string;
|
|
60
|
+
avatar?: string;
|
|
61
|
+
};
|
|
51
62
|
export type SendOptions = {
|
|
52
63
|
waitFor?: "accepted" | "delivered";
|
|
53
64
|
};
|
|
@@ -92,7 +103,7 @@ export declare class Chat {
|
|
|
92
103
|
private notify;
|
|
93
104
|
observeMessages(threadId: string, ids: string[], event: "visible" | "played"): Promise<void>;
|
|
94
105
|
markRead(threadId: string): Promise<void>;
|
|
95
|
-
getReaders(threadId: string, messageId: string, page?:
|
|
106
|
+
getReaders(threadId: string, messageId: string, page?: ReadersQuery, signal?: AbortSignal): Promise<import("./runtime/messageReaders.js").MessageReadersPage>;
|
|
96
107
|
watchReaders(threadId: string | undefined, ids: string[], receiver?: string): Promise<void>;
|
|
97
108
|
handleReach(event: Parameters<ChatSession<CachedChatMessage>["handleReach"]>[0]): Promise<"handled" | undefined>;
|
|
98
109
|
getVoiceAttachment(threadId: string, messageId: string): Promise<import("./runtime/durableSender.js").VoiceAttachmentLease>;
|
|
@@ -113,7 +124,7 @@ export declare class Chat {
|
|
|
113
124
|
ownerId: string;
|
|
114
125
|
memberIds: readonly string[];
|
|
115
126
|
}>;
|
|
116
|
-
updateGroup(threadId: string, changes:
|
|
127
|
+
updateGroup(threadId: string, changes: GroupChanges): Promise<Readonly<Omit<RuntimeGroup, "versionNumber">>>;
|
|
117
128
|
revokeAccess(): Promise<void>;
|
|
118
129
|
close(): Promise<void>;
|
|
119
130
|
}
|
package/lib/chat.js
CHANGED
|
@@ -191,7 +191,13 @@ export class Chat {
|
|
|
191
191
|
notify(threadId) { this.listeners.get(threadId)?.forEach(listener => listener()); this.listeners.get("")?.forEach(listener => listener()); }
|
|
192
192
|
observeMessages(threadId, ids, event) { return this.threadOperation(threadId, async () => { await this.advanced.observeMessages(threadId, ids, event); }); }
|
|
193
193
|
markRead(threadId) { return this.threadOperation(threadId, async () => { await this.advanced.markRead(threadId); }); }
|
|
194
|
-
getReaders(threadId, messageId, page = {}, signal) {
|
|
194
|
+
getReaders(threadId, messageId, page = {}, signal) {
|
|
195
|
+
return this.threadOperation(threadId, async () => {
|
|
196
|
+
if (Object.keys(page).some(key => !["afterProfileId", "revision"].includes(key)))
|
|
197
|
+
throw new ChatError("invalid-input", "Unsupported reader query");
|
|
198
|
+
return this.advanced.getReaders(threadId, messageId, page, signal);
|
|
199
|
+
});
|
|
200
|
+
}
|
|
195
201
|
watchReaders(threadId, ids, receiver) { return this.threadOperation(threadId, () => this.advanced.observeMessages(threadId, ids, "receipts", receiver)); }
|
|
196
202
|
handleReach(event) { return this.operation(() => this.advanced.handleReach(event)); }
|
|
197
203
|
getVoiceAttachment(threadId, messageId) { return this.threadOperation(threadId, () => this.advanced.getVoiceAttachment(threadId, messageId)); }
|
package/lib/index.d.ts
CHANGED
|
@@ -41,5 +41,5 @@ export * from "./runtime/socialReadClient";
|
|
|
41
41
|
export * from "./ux/imagePaste";
|
|
42
42
|
export * from "./hooks/useImageAttachments";
|
|
43
43
|
export * from "./components/ImageAttachmentTray";
|
|
44
|
-
export { createChat, Chat, ChatError, type ChatThreadSnapshot, type ChatMessage as MessageView, type ChatErrorCode, type ConversationTarget, type OutgoingContent, type CreateChatOptions, type ChatSnapshot, type SentMessage, type MessageQuery } from "./chat.js";
|
|
44
|
+
export { createChat, Chat, ChatError, type ChatThreadSnapshot, type ChatMessage as MessageView, type ChatErrorCode, type ConversationTarget, type OutgoingContent, type CreateChatOptions, type ChatSnapshot, type SentMessage, type MessageQuery, type ReadersQuery, type GroupChanges } from "./chat.js";
|
|
45
45
|
export { useChatSnapshot } from "./hooks/useChatSnapshot.js";
|
package/lib/messageView.d.ts
CHANGED
package/lib/messageView.js
CHANGED
|
@@ -38,7 +38,7 @@ function content(message) {
|
|
|
38
38
|
const imageUrl = media(payload.url) ?? (hint.kind === "image" ? media(hint.imageUrl) : undefined);
|
|
39
39
|
const messageQuote = quote(payload.quote) ?? quote(hint.quote);
|
|
40
40
|
const rawText = text(payload.text) || text(object(body.payload).message);
|
|
41
|
-
const result = { kind: "text", text: validLegacy ? text(hint.content) : rawText, senderName: text(hint.senderName) || undefined, senderAvatar: media(hint.senderAvatar),
|
|
41
|
+
const result = { kind: "text", text: validLegacy ? text(hint.content) : rawText, senderName: text(hint.senderName) || undefined, senderAvatar: media(hint.senderAvatar), timeLabel: text(hint.createdAt) || undefined,
|
|
42
42
|
recipientCount: message.threadKind === "dm" ? 1 : validLegacy ? typeof hint.recipientCount === "number" ? hint.recipientCount : undefined : Array.isArray(message.recipients) ? new Set(message.recipients.filter(id => id !== message.from)).size : undefined };
|
|
43
43
|
if (validLegacy && ["emoji", "system", "attachment", "quote"].includes(String(hint.kind)))
|
|
44
44
|
result.kind = hint.kind;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ChatMessage } from "../messageView.js";
|
|
1
2
|
import { type MessageScope } from "./messageStore.js";
|
|
2
3
|
import { type CachedChatMessage } from "./cachedMessage.js";
|
|
3
4
|
import { type TimelineItem } from "./messageTimeline.js";
|
|
@@ -12,6 +13,7 @@ export type MessageLaunchView = {
|
|
|
12
13
|
threadId: string;
|
|
13
14
|
metadata: MessageLaunchMetadata;
|
|
14
15
|
images: Record<string, string>;
|
|
16
|
+
messages: readonly ChatMessage[]; /** @deprecated Advanced compatibility projection. */
|
|
15
17
|
timeline: readonly TimelineItem<CachedChatMessage>[];
|
|
16
18
|
};
|
|
17
19
|
type Options = {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createMessagePresenter } from "../messageView.js";
|
|
1
2
|
import { Dexie } from "dexie";
|
|
2
3
|
import { IndexedDbMessageStore, messageScopeKey, mergeStoredMessage } from "./messageStore.js";
|
|
3
4
|
import { DurableChatSender } from "./durableSender.js";
|
|
@@ -47,6 +48,7 @@ export async function saveMessageLaunch(input, options = {}) {
|
|
|
47
48
|
export function watchMessageLaunch(input, onChange, onError, options = {}) {
|
|
48
49
|
const { scope, openId, threadId } = input, key = messageScopeKey(scope), store = messages(scope, options), { db, rows } = tickets(options);
|
|
49
50
|
let closed = false, generation = 0, ticket, timer;
|
|
51
|
+
const present = createMessagePresenter();
|
|
50
52
|
const channels = [];
|
|
51
53
|
const stop = () => { if (closed)
|
|
52
54
|
return; closed = true; generation++; clearTimeout(timer); tasks.close(); channels.forEach(channel => channel.close()); store.close(); db.close(); };
|
|
@@ -89,7 +91,9 @@ export function watchMessageLaunch(input, onChange, onError, options = {}) {
|
|
|
89
91
|
return;
|
|
90
92
|
}
|
|
91
93
|
const timeline = projectMessageTimeline({ appId: scope.appId, profileId: scope.profileId, threadId, messages: page.messages, outgoing, decode: message => decodeCachedChatMessage(message, scope), reading: {} }).slice(-30);
|
|
92
|
-
|
|
94
|
+
const normalized = timeline.map(present), visibleImages = new Set(normalized.flatMap(message => message.image ? [message.image.url] : []));
|
|
95
|
+
const images = Object.fromEntries(Object.entries(ticket.images).filter(([url]) => visibleImages.has(url)));
|
|
96
|
+
onChange(timeline.length ? { openId, threadId, metadata: ticket.metadata, images, messages: normalized, timeline } : undefined);
|
|
93
97
|
};
|
|
94
98
|
const tasks = new WindowedTasks(16, fail);
|
|
95
99
|
if (typeof BroadcastChannel !== "undefined") {
|
package/package.json
CHANGED