@pmate/chat-sdk 0.12.0-next.7 → 0.12.0-next.71
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/README.md +170 -81
- package/lib/advanced.d.ts +10 -0
- package/lib/advanced.js +10 -0
- package/lib/chat.d.ts +5 -0
- package/lib/chat.js +11 -0
- package/lib/chatContract.d.ts +148 -0
- package/lib/chatContract.js +1 -0
- package/lib/chatError.d.ts +11 -0
- package/lib/chatError.js +13 -0
- package/lib/chatTypes.d.ts +121 -0
- package/lib/chatTypes.js +1 -0
- package/lib/commands.d.ts +20 -0
- package/lib/commands.js +12 -0
- package/lib/components/ChatInputDesktop.js +5 -4
- package/lib/components/ChatInputMobile.js +5 -4
- package/lib/components/CommandMenu.d.ts +15 -0
- package/lib/components/CommandMenu.js +10 -0
- package/lib/credentials.d.ts +26 -0
- package/lib/credentials.js +110 -0
- package/lib/fileMetadata.d.ts +9 -0
- package/lib/fileMetadata.js +18 -0
- package/lib/framework.d.ts +11 -0
- package/lib/framework.js +12 -0
- package/lib/history.d.ts +4 -0
- package/lib/history.js +8 -0
- package/lib/hooks/useChatSnapshot.d.ts +4 -0
- package/lib/hooks/useChatSnapshot.js +9 -0
- package/lib/hooks/useComposerSuggestions.d.ts +50 -0
- package/lib/hooks/useComposerSuggestions.js +70 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.js +5 -0
- package/lib/internal/chatEngine.d.ts +131 -0
- package/lib/internal/chatEngine.js +280 -0
- package/lib/internal/chatRegistry.d.ts +4 -0
- package/lib/internal/chatRegistry.js +4 -0
- package/lib/internal/createPublicChat.d.ts +4 -0
- package/lib/internal/createPublicChat.js +52 -0
- package/lib/messageView.d.ts +6 -0
- package/lib/messageView.js +103 -0
- package/lib/runtime/batchedReadIndex.d.ts +16 -3
- package/lib/runtime/batchedReadIndex.js +50 -4
- package/lib/runtime/cachedMessage.d.ts +12 -0
- package/lib/runtime/cachedMessage.js +18 -0
- package/lib/runtime/chatClient.d.ts +2 -0
- package/lib/runtime/chatClient.js +8 -3
- package/lib/runtime/chatError.d.ts +3 -0
- package/lib/runtime/chatError.js +15 -0
- package/lib/runtime/chatSession.d.ts +127 -13
- package/lib/runtime/chatSession.js +727 -40
- package/lib/runtime/connectivity.d.ts +4 -0
- package/lib/runtime/connectivity.js +8 -0
- package/lib/runtime/conversationDirectory.d.ts +37 -0
- package/lib/runtime/conversationDirectory.js +116 -0
- package/lib/runtime/conversationRead.d.ts +13 -0
- package/lib/runtime/conversationRead.js +34 -0
- package/lib/runtime/conversationReading.d.ts +28 -0
- package/lib/runtime/conversationReading.js +47 -0
- package/lib/runtime/createChat.d.ts +11 -7
- package/lib/runtime/createChat.js +46 -23
- package/lib/runtime/durableSender.d.ts +97 -14
- package/lib/runtime/durableSender.js +786 -71
- package/lib/runtime/groupClient.d.ts +76 -0
- package/lib/runtime/groupClient.js +325 -0
- package/lib/runtime/index.d.ts +7 -0
- package/lib/runtime/index.js +5 -0
- package/lib/runtime/messageClient.d.ts +35 -8
- package/lib/runtime/messageClient.js +364 -66
- package/lib/runtime/messageControls.d.ts +19 -0
- package/lib/runtime/messageControls.js +44 -0
- package/lib/runtime/messageLaunch.d.ts +44 -0
- package/lib/runtime/messageLaunch.js +137 -0
- package/lib/runtime/messageQuotes.d.ts +3 -0
- package/lib/runtime/messageQuotes.js +17 -0
- package/lib/runtime/messageReaders.d.ts +12 -1
- package/lib/runtime/messageReaders.js +67 -3
- package/lib/runtime/messageStore.d.ts +40 -2
- package/lib/runtime/messageStore.js +227 -11
- package/lib/runtime/messageTimeline.d.ts +50 -0
- package/lib/runtime/messageTimeline.js +120 -0
- package/lib/runtime/outboxSchema.d.ts +5 -0
- package/lib/runtime/outboxSchema.js +59 -0
- package/lib/runtime/outgoingContent.d.ts +89 -0
- package/lib/runtime/outgoingContent.js +113 -0
- package/lib/runtime/readBatchJournal.d.ts +35 -0
- package/lib/runtime/readBatchJournal.js +210 -0
- package/lib/runtime/readCounts.d.ts +15 -1
- package/lib/runtime/readCounts.js +97 -9
- package/lib/runtime/readIndex.d.ts +68 -7
- package/lib/runtime/readIndex.js +460 -22
- package/lib/runtime/readSchema.d.ts +2 -0
- package/lib/runtime/readSchema.js +58 -0
- package/lib/runtime/readSync.d.ts +1 -0
- package/lib/runtime/readSync.js +26 -9
- package/lib/runtime/readingClient.d.ts +19 -0
- package/lib/runtime/readingClient.js +131 -19
- package/lib/runtime/readingContent.d.ts +5 -0
- package/lib/runtime/readingContent.js +23 -0
- package/lib/runtime/responseCache.d.ts +59 -0
- package/lib/runtime/responseCache.js +232 -0
- package/lib/runtime/socialReadClient.d.ts +4 -2
- package/lib/runtime/socialReadClient.js +12 -8
- package/lib/runtime/voiceUpload.d.ts +2 -0
- package/lib/runtime/voiceUpload.js +27 -0
- package/lib/types/chatInput.d.ts +3 -0
- package/package.json +27 -2
|
@@ -123,7 +123,7 @@ export class ChatClient {
|
|
|
123
123
|
/** Non-secret identity used to validate a shared browser transport. */
|
|
124
124
|
identityScope() {
|
|
125
125
|
const identity = this.session?.identity ?? this.session?.session?.identity;
|
|
126
|
-
return { appId: this.options.appId, profileId: this.profileIdValue ?? this.options.profileId, accountId: identity?.accountId, teamId: this.options.teamId };
|
|
126
|
+
return { appId: this.options.appId, profileId: this.profileIdValue ?? this.options.profileId, accountId: identity?.accountId, teamId: this.options.teamId, clientInstanceId: this.instanceId };
|
|
127
127
|
}
|
|
128
128
|
watchConnection(handler) {
|
|
129
129
|
this.connectionHandlers.add(handler);
|
|
@@ -161,7 +161,7 @@ export class ChatClient {
|
|
|
161
161
|
catch (error) {
|
|
162
162
|
if (generation !== this.generation)
|
|
163
163
|
return;
|
|
164
|
-
if (error instanceof ChatAckError) {
|
|
164
|
+
if (error instanceof ChatAckError || ["authentication-required", "access-denied"].includes(error?.code ?? "")) {
|
|
165
165
|
this.close();
|
|
166
166
|
this.setConnection("authentication_required");
|
|
167
167
|
}
|
|
@@ -295,7 +295,12 @@ export class ChatClient {
|
|
|
295
295
|
});
|
|
296
296
|
}
|
|
297
297
|
async sendAuth() {
|
|
298
|
-
const
|
|
298
|
+
const generation = this.generation;
|
|
299
|
+
const token = this.options.getToken ? await this.options.getToken() : this.session?.token;
|
|
300
|
+
if (generation !== this.generation)
|
|
301
|
+
throw new Error("ChatClient closed");
|
|
302
|
+
if (this.session && token)
|
|
303
|
+
this.session = { ...this.session, token };
|
|
299
304
|
if (!token) {
|
|
300
305
|
throw new Error("Missing PMate session token");
|
|
301
306
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ChatError } from "../chatError.js";
|
|
2
|
+
export { ChatError } from "../chatError.js";
|
|
3
|
+
export function asChatError(error) {
|
|
4
|
+
if (error instanceof ChatError)
|
|
5
|
+
return error;
|
|
6
|
+
const value = error;
|
|
7
|
+
const status = value?.status, message = value?.message ?? String(error);
|
|
8
|
+
const code = status === 401 ? "authentication-required" : status === 403 || /ACCESS_REVOKED|ACCESS_DENIED|SCOPE_CHANGED/.test(message) ? "access-denied"
|
|
9
|
+
: /CLOSED/.test(message) ? "closed"
|
|
10
|
+
: status === 409 || /REVISION_CONFLICT|PROJECTION_CHANGED/.test(message) ? "conflict"
|
|
11
|
+
: /BACKPRESSURE|TOO_LARGE/.test(message) ? "busy"
|
|
12
|
+
: status === 400 || /INVALID_|CONVERSATION_MISMATCH|CONVERSATION_UNKNOWN|NOT_OWNED/.test(message) ? "invalid-input"
|
|
13
|
+
: /QuotaExceeded|DatabaseClosed|UnknownError|AbortError/.test(value?.name ?? "") || /STORAGE_|DATABASE_|CACHE_WRITE/.test(message) ? "storage-unavailable" : "unavailable";
|
|
14
|
+
return new ChatError(code, message, { cause: error, status });
|
|
15
|
+
}
|
|
@@ -1,59 +1,124 @@
|
|
|
1
|
+
import { type ConversationTarget } from "./conversationDirectory.js";
|
|
2
|
+
import { type ChatGroup } from "./groupClient.js";
|
|
3
|
+
import type { SocialGroup } from "./socialReadClient.js";
|
|
4
|
+
import { type ChatConversation, type OutgoingContent } from "./outgoingContent.js";
|
|
5
|
+
import { type TimelineItem } from "./messageTimeline.js";
|
|
6
|
+
import { type ReadingCandidate, type MessageReadingState } from "./conversationReading.js";
|
|
7
|
+
import type { ConversationReadMessage } from "./conversationRead.js";
|
|
8
|
+
import { type ReadCountsResult } from "./readCounts.js";
|
|
9
|
+
import type { OnlineReachEvent } from "./reach.js";
|
|
1
10
|
import { type MessageReadersQuery } from "./messageReaders.js";
|
|
2
11
|
import { type MessageClientOptions, type MessageSnapshot } from "./messageClient.js";
|
|
3
|
-
import { DurableChatSender } from "./durableSender.js";
|
|
4
|
-
import { type ReadingClientOptions } from "./readingClient.js";
|
|
12
|
+
import { DurableChatSender, type SendMessageInput, type DurableSenderOptions, type VoiceAttachmentLease } from "./durableSender.js";
|
|
13
|
+
import { ReadingClient, type ReadingClientOptions } from "./readingClient.js";
|
|
5
14
|
import { ChatClient, type ChatClientOptions, type ChatConnectionState } from "./chatClient.js";
|
|
6
15
|
import { unreadInConversation } from "./readIndex.js";
|
|
7
16
|
import type { StoredMessage } from "./messageStore.js";
|
|
8
|
-
import type {
|
|
17
|
+
import type { ChatRuntimeMessage } from "./protocol.js";
|
|
9
18
|
export type ChatSessionOptions<T extends StoredMessage> = {
|
|
19
|
+
onDispose?: () => void;
|
|
10
20
|
messages: MessageClientOptions<T>;
|
|
11
21
|
connection: ChatClientOptions;
|
|
12
22
|
sharedConnection?: ChatClient;
|
|
23
|
+
activeThreadId?: string;
|
|
24
|
+
uploadVoice?: DurableSenderOptions["uploadVoice"];
|
|
25
|
+
reconcileOutgoing?: DurableSenderOptions["reconcile"];
|
|
26
|
+
loadGroup?: (groupId: string, signal: AbortSignal) => Promise<SocialGroup>;
|
|
13
27
|
reading: ReadingClientOptions;
|
|
14
28
|
decode: (message: ChatRuntimeMessage) => T | undefined;
|
|
29
|
+
readingCandidate?: (message: T) => ReadingCandidate | undefined;
|
|
15
30
|
onError: (error: unknown) => void;
|
|
16
31
|
};
|
|
17
32
|
export type ChatThreadSnapshot<T> = {
|
|
18
33
|
messages: readonly T[];
|
|
34
|
+
timeline: readonly TimelineItem<T>[];
|
|
19
35
|
outgoing: ReturnType<DurableChatSender["snapshot"]>;
|
|
20
36
|
hasEarlier: boolean;
|
|
21
37
|
resetVersion: number;
|
|
22
38
|
complete: boolean;
|
|
23
|
-
|
|
39
|
+
group?: ChatGroup;
|
|
40
|
+
readCounts?: ReadCountsResult;
|
|
41
|
+
unread: ReturnType<typeof unreadInConversation> | undefined;
|
|
42
|
+
messageReading: Readonly<Record<string, MessageReadingState>>;
|
|
24
43
|
};
|
|
25
44
|
export type ChatSummarySnapshot<T> = {
|
|
26
45
|
threads: readonly {
|
|
27
46
|
threadId: string;
|
|
28
47
|
lastMessage?: T;
|
|
48
|
+
lastItem?: TimelineItem<T>;
|
|
49
|
+
group?: ChatGroup;
|
|
29
50
|
unread: ChatThreadSnapshot<T>["unread"];
|
|
30
51
|
outgoingCount: number;
|
|
31
52
|
}[];
|
|
32
|
-
unreadMessageCount: number;
|
|
33
|
-
badgeCount: number;
|
|
53
|
+
unreadMessageCount: number | undefined;
|
|
54
|
+
badgeCount: number | undefined;
|
|
34
55
|
connection: ChatConnectionState;
|
|
35
56
|
};
|
|
36
57
|
/** Owns all browser message clients. Hosts subscribe to stable thread snapshots. */
|
|
37
58
|
export declare class ChatSession<T extends StoredMessage> {
|
|
38
59
|
private options;
|
|
60
|
+
private conversations;
|
|
39
61
|
private messages;
|
|
40
62
|
private connection;
|
|
41
63
|
private reading;
|
|
42
64
|
private readers;
|
|
65
|
+
private groups?;
|
|
66
|
+
private counts?;
|
|
67
|
+
private countsReceiver?;
|
|
68
|
+
private countsThread?;
|
|
69
|
+
private countSnapshots;
|
|
70
|
+
private countClosings;
|
|
71
|
+
private countTasks;
|
|
72
|
+
private controlTails;
|
|
73
|
+
private acceptedControls;
|
|
74
|
+
private controlCount;
|
|
75
|
+
private controlBytes;
|
|
43
76
|
private sender;
|
|
44
77
|
private listeners;
|
|
45
78
|
private snapshots;
|
|
79
|
+
private timelineDecoded;
|
|
80
|
+
private decodeTimeline;
|
|
81
|
+
private historyEdges;
|
|
82
|
+
private earlierReads;
|
|
46
83
|
private off;
|
|
47
84
|
private globalListeners;
|
|
48
85
|
private globalSnapshot?;
|
|
86
|
+
private closedThread;
|
|
87
|
+
private closedSummary;
|
|
49
88
|
private connectionState;
|
|
50
89
|
private catchUp;
|
|
90
|
+
private readingAllowed;
|
|
91
|
+
private readingListeners;
|
|
92
|
+
private acceptedReading;
|
|
93
|
+
private readingAccess?;
|
|
51
94
|
private readingStarted;
|
|
95
|
+
private readingStarting?;
|
|
96
|
+
private withdrawn;
|
|
97
|
+
private revoking?;
|
|
52
98
|
private closed;
|
|
53
99
|
private starting?;
|
|
100
|
+
private initializing?;
|
|
54
101
|
private closing?;
|
|
55
102
|
constructor(options: ChatSessionOptions<T>);
|
|
103
|
+
private scheduleCatchUp;
|
|
56
104
|
start(): Promise<void>;
|
|
105
|
+
/** Initializes local state and background reading sync without opening a
|
|
106
|
+
* second transport when the host already owns calls/presence. */
|
|
107
|
+
initialize(): Promise<void>;
|
|
108
|
+
private startReading;
|
|
109
|
+
/** One-time migration only: never establishes trusted history coverage. */
|
|
110
|
+
importLegacyMessages(threadId: string, messages: T[]): Promise<void>;
|
|
111
|
+
getReadingSnapshot(): import("./readIndex.js").ReadIndexState | undefined;
|
|
112
|
+
subscribeReading(listener: () => void): () => void;
|
|
113
|
+
private setReadingAllowed;
|
|
114
|
+
private readingAuthority;
|
|
115
|
+
private authorizeReading;
|
|
116
|
+
private readingOperation;
|
|
117
|
+
refreshReading(): void;
|
|
118
|
+
synchronizeReading(cursor?: string, profileId?: string): Promise<import("./readIndex.js").ReadIndexState>;
|
|
119
|
+
/** Explicit text-history acknowledgement; unheard audio stays unread. */
|
|
120
|
+
markRead(threadId: string, messages?: readonly ConversationReadMessage[]): Promise<import("./readIndex.js").ReadIndexState>;
|
|
121
|
+
updateReading(transform: Parameters<ReadingClient["update"]>[0]): Promise<import("./readIndex.js").ReadIndexState>;
|
|
57
122
|
private assertOpen;
|
|
58
123
|
getMessages(threadId: string, options?: {
|
|
59
124
|
limit?: number;
|
|
@@ -61,25 +126,74 @@ export declare class ChatSession<T extends StoredMessage> {
|
|
|
61
126
|
timestamp: number;
|
|
62
127
|
id: string;
|
|
63
128
|
};
|
|
129
|
+
earlier?: boolean;
|
|
64
130
|
all?: boolean;
|
|
65
131
|
refresh?: boolean;
|
|
66
132
|
}): Promise<MessageSnapshot<T>>;
|
|
133
|
+
private confirmMessages;
|
|
134
|
+
private rememberHistoryEdge;
|
|
135
|
+
private readEarlier;
|
|
67
136
|
private readAll;
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
137
|
+
/** Reads trusted local group metadata immediately; SDK refreshes it in the background. */
|
|
138
|
+
getGroup(thread: ChatConversation | string, options?: {
|
|
139
|
+
refresh?: boolean;
|
|
140
|
+
}): Promise<ChatGroup>;
|
|
141
|
+
createGroup(thread: ChatConversation, content: {
|
|
142
|
+
title: string;
|
|
143
|
+
members: readonly string[];
|
|
144
|
+
}): Promise<ChatGroup>;
|
|
145
|
+
updateGroup(target: ChatConversation | string, changes: {
|
|
146
|
+
expectedRevision?: string;
|
|
147
|
+
addMembers?: readonly string[];
|
|
148
|
+
removeMembers?: readonly string[];
|
|
149
|
+
title?: string;
|
|
150
|
+
avatar?: string;
|
|
151
|
+
}): Promise<ChatGroup>;
|
|
152
|
+
sendMessage(threadId: string, input: OutgoingContent, options?: {
|
|
153
|
+
waitFor?: "accepted" | "delivered";
|
|
154
|
+
}): Promise<ChatRuntimeMessage>;
|
|
155
|
+
sendMessage(thread: ChatConversation, input: OutgoingContent, options?: {
|
|
156
|
+
waitFor?: "accepted" | "delivered";
|
|
157
|
+
}): Promise<ChatRuntimeMessage>;
|
|
158
|
+
sendMessage(threadId: string, input: SendMessageInput, options?: {
|
|
159
|
+
waitFor?: "accepted" | "delivered";
|
|
72
160
|
}): Promise<ChatRuntimeMessage>;
|
|
161
|
+
private sendWire;
|
|
162
|
+
getConversation(target: ConversationTarget): Promise<string>;
|
|
163
|
+
private sendContent;
|
|
164
|
+
private resolveConversation;
|
|
165
|
+
/** Validated target identity survives content redaction; no roster is exposed. */
|
|
166
|
+
getConversationTarget(threadId: string): ChatConversation | undefined;
|
|
167
|
+
private sendControl;
|
|
73
168
|
getReaders(threadId: string, messageId: string, page?: Omit<MessageReadersQuery, "threadId" | "messageId">, signal?: AbortSignal): Promise<import("./messageReaders.js").MessageReadersPage>;
|
|
169
|
+
/** Resolve voice media uniformly; pending local bytes are loaded only on demand. */
|
|
170
|
+
getVoiceAttachment(threadId: string, messageId: string): Promise<VoiceAttachmentLease>;
|
|
74
171
|
retryMessage(messageId: string): Promise<ChatRuntimeMessage>;
|
|
75
|
-
observeMessages(threadId: string, ids: string[], event: "visible" | "played"):
|
|
172
|
+
observeMessages(threadId: string, ids: string[], event: "visible" | "played"): ReturnType<ReadingClient["recordVisible"]>;
|
|
173
|
+
observeMessages(threadId: string | undefined, ids: string[], event: "receipts", clientInstanceId?: string): Promise<void>;
|
|
174
|
+
/** Bridge transports can delegate social events without maintaining clients. */
|
|
175
|
+
handleReach(event: OnlineReachEvent): Promise<"handled" | undefined>;
|
|
176
|
+
private wakeCounts;
|
|
177
|
+
private publishCountSnapshot;
|
|
178
|
+
private publishCounts;
|
|
179
|
+
private watchCounts;
|
|
76
180
|
getSnapshot(): ChatSummarySnapshot<T>;
|
|
77
181
|
getSnapshot(threadId: string): ChatThreadSnapshot<T>;
|
|
78
|
-
|
|
79
|
-
|
|
182
|
+
private buildThreadSnapshot;
|
|
183
|
+
/** Delivers the current stable snapshot immediately, then only meaningful changes. */
|
|
184
|
+
subscribe(listener: (snapshot: ChatSummarySnapshot<T>) => void): () => void;
|
|
185
|
+
subscribe(threadId: string, listener: (snapshot: ChatThreadSnapshot<T>) => void, fields?: readonly (keyof ChatThreadSnapshot<T>)[]): () => void;
|
|
186
|
+
/** Change-only bridge for useSyncExternalStore and other framework adapters. */
|
|
187
|
+
subscribeChanges(listener: () => void): () => void;
|
|
188
|
+
subscribeChanges(threadId: string, listener: () => void, fields?: readonly (keyof ChatThreadSnapshot<T>)[]): () => void;
|
|
80
189
|
private publishAll;
|
|
81
190
|
private buildGlobal;
|
|
82
191
|
private publishGlobal;
|
|
83
192
|
private publish;
|
|
193
|
+
/** Permanently retire this identity/team session. UI withdrawal is immediate;
|
|
194
|
+
* completion means all durable stores have crossed the same authority epoch. */
|
|
195
|
+
revokeAccess(): Promise<void>;
|
|
196
|
+
get active(): boolean;
|
|
84
197
|
close(): Promise<void>;
|
|
198
|
+
private dispose;
|
|
85
199
|
}
|