@nopeek/chat 0.1.0
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 +17 -0
- package/dist/crypto.d.ts +80 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +161 -0
- package/dist/crypto.js.map +1 -0
- package/dist/index.d.ts +471 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1258 -0
- package/dist/index.js.map +1 -0
- package/package.json +29 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
/** Secrets that can unlock an encrypted history backup. Either one is sufficient. */
|
|
2
|
+
export interface BackupSecrets {
|
|
3
|
+
password?: string;
|
|
4
|
+
recoveryCode?: string;
|
|
5
|
+
/** When rotating the password, the old one — used only to unwrap the existing
|
|
6
|
+
* backup envelope so unrelated wraps (e.g. the recovery code) survive. */
|
|
7
|
+
previousPassword?: string;
|
|
8
|
+
}
|
|
9
|
+
/** Descriptor returned by uploadEncrypted / expected by downloadDecrypt. */
|
|
10
|
+
export interface EncryptedBlobRef {
|
|
11
|
+
blobUrl: string;
|
|
12
|
+
contentKey: string;
|
|
13
|
+
iv: string;
|
|
14
|
+
size: number;
|
|
15
|
+
}
|
|
16
|
+
export interface AttachmentInput {
|
|
17
|
+
/** Raw file bytes. */
|
|
18
|
+
bytes: ArrayBuffer;
|
|
19
|
+
name: string;
|
|
20
|
+
contentType: string;
|
|
21
|
+
width?: number;
|
|
22
|
+
height?: number;
|
|
23
|
+
durationSec?: number;
|
|
24
|
+
/** Optional precomputed thumbnail bytes (e.g. a downscaled image/video frame). */
|
|
25
|
+
thumbnail?: {
|
|
26
|
+
bytes: ArrayBuffer;
|
|
27
|
+
contentType: string;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** One tappable action a bot offers (inline under a message, or in its bar). */
|
|
31
|
+
export interface BotAction {
|
|
32
|
+
/** Stable id echoed back verbatim in the action_invoke body. */
|
|
33
|
+
id: string;
|
|
34
|
+
/** Button label shown to humans. */
|
|
35
|
+
label: string;
|
|
36
|
+
/** Optional visual emphasis; clients default to a neutral chip. */
|
|
37
|
+
style?: "default" | "primary" | "danger";
|
|
38
|
+
}
|
|
39
|
+
export interface ConnectOptions {
|
|
40
|
+
apiUrl: string;
|
|
41
|
+
sessionToken: string;
|
|
42
|
+
appId: string;
|
|
43
|
+
userId: string;
|
|
44
|
+
/** Persist device identity + channel keys. Defaults to localStorage when available. */
|
|
45
|
+
storage?: KeyValueStore;
|
|
46
|
+
platform?: "web" | "ios" | "android" | "desktop" | "server";
|
|
47
|
+
autoConnectWs?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Don't register a brand-new device during connect() when no local device
|
|
50
|
+
* identity exists yet. Use this on login flows that may RESTORE the user's
|
|
51
|
+
* real device identity from an encrypted backup — registering first would
|
|
52
|
+
* orphan one device per fresh login (device proliferation), and orphan
|
|
53
|
+
* devices poison MLS key-package claims for every peer. After connect():
|
|
54
|
+
* - if a backup exists, call restore() — it adopts the backed-up deviceId
|
|
55
|
+
* and keys, then registers key packages and opens the WebSocket;
|
|
56
|
+
* - otherwise call registerDevice() to create a genuinely new device.
|
|
57
|
+
* When this flag is set and no local device exists, the WebSocket is NOT
|
|
58
|
+
* connected until one of those two completes (it needs a deviceId).
|
|
59
|
+
*/
|
|
60
|
+
deferDeviceRegistration?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Preshared-key mode. When supplied, the SDK derives each channel's key from
|
|
63
|
+
* this function instead of running the MLS welcome ceremony — every device
|
|
64
|
+
* that can compute the same key can read the channel, with no per-device
|
|
65
|
+
* key distribution. Messages are still encrypted end-to-end and the server
|
|
66
|
+
* still only ever sees ciphertext. Intended for closed groups where all
|
|
67
|
+
* members share a secret out of band (and for the hosted two-user demo).
|
|
68
|
+
*/
|
|
69
|
+
deriveChannelKey?: (channelId: string) => Promise<CryptoKey>;
|
|
70
|
+
}
|
|
71
|
+
export interface KeyValueStore {
|
|
72
|
+
get(key: string): string | null | Promise<string | null>;
|
|
73
|
+
set(key: string, value: string): void | Promise<void>;
|
|
74
|
+
}
|
|
75
|
+
export interface DecryptedMessage {
|
|
76
|
+
messageId: string;
|
|
77
|
+
channelId: string;
|
|
78
|
+
senderUserId: string;
|
|
79
|
+
seq: number;
|
|
80
|
+
threadParentId: string | null;
|
|
81
|
+
createdAt: string;
|
|
82
|
+
editedAt: string | null;
|
|
83
|
+
recalledAt: string | null;
|
|
84
|
+
/** Decrypted (E2EE) or plaintext body; null when recalled or undecryptable. */
|
|
85
|
+
body: {
|
|
86
|
+
type: string;
|
|
87
|
+
text?: string;
|
|
88
|
+
[k: string]: unknown;
|
|
89
|
+
} | null;
|
|
90
|
+
encrypted: boolean;
|
|
91
|
+
decryptionFailed?: boolean;
|
|
92
|
+
}
|
|
93
|
+
type Listener = (...args: never[]) => void;
|
|
94
|
+
declare class Emitter {
|
|
95
|
+
private listeners;
|
|
96
|
+
on(event: string, fn: (...args: never[]) => void): () => void;
|
|
97
|
+
off(event: string, fn: Listener): void;
|
|
98
|
+
emit(event: string, ...args: unknown[]): void;
|
|
99
|
+
}
|
|
100
|
+
export declare class NoPeek extends Emitter {
|
|
101
|
+
readonly apiUrl: string;
|
|
102
|
+
readonly appId: string;
|
|
103
|
+
readonly userId: string;
|
|
104
|
+
deviceId: string;
|
|
105
|
+
private token;
|
|
106
|
+
private store;
|
|
107
|
+
private keys;
|
|
108
|
+
private ws;
|
|
109
|
+
private reqCounter;
|
|
110
|
+
private pending;
|
|
111
|
+
private channelKeys;
|
|
112
|
+
private mlsGroupToChannel;
|
|
113
|
+
/** Latest known presence per user, updated on every presence frame (incl. the
|
|
114
|
+
* connect-time snapshot that may arrive before app listeners attach). */
|
|
115
|
+
private presenceState;
|
|
116
|
+
private reconnectDelay;
|
|
117
|
+
private closed;
|
|
118
|
+
/** Set while the app is backgrounded: the WS is intentionally dropped so the
|
|
119
|
+
* server clears presence and delivers pushes instead. Distinct from `closed`
|
|
120
|
+
* (permanent) — a suspended client reconnects on resume(). */
|
|
121
|
+
private suspended;
|
|
122
|
+
private pingTimer;
|
|
123
|
+
private platform;
|
|
124
|
+
private autoWs;
|
|
125
|
+
private deferRegistration;
|
|
126
|
+
/** Set when connect() had to register a brand-new device — restore() revokes it
|
|
127
|
+
* if the backup turns out to hold the user's real device identity. */
|
|
128
|
+
private justRegisteredDeviceId;
|
|
129
|
+
readonly channels: Channels;
|
|
130
|
+
readonly deriveChannelKey?: (channelId: string) => Promise<CryptoKey>;
|
|
131
|
+
static connect(opts: ConnectOptions): Promise<NoPeek>;
|
|
132
|
+
private constructor();
|
|
133
|
+
/** Ensure a channel key exists via the preshared-key hook; returns false if no hook. */
|
|
134
|
+
deriveAndSet(channelId: string): Promise<boolean>;
|
|
135
|
+
api<T = unknown>(method: string, path: string, body?: unknown): Promise<T>;
|
|
136
|
+
private ensureDevice;
|
|
137
|
+
/** Whether this client has a server-registered device identity yet. False only
|
|
138
|
+
* during a deferred connect, before restore()/registerDevice() completes. */
|
|
139
|
+
get deviceRegistered(): boolean;
|
|
140
|
+
/**
|
|
141
|
+
* Complete a deferred connect by registering a brand-new device. Call this
|
|
142
|
+
* only when the user has NO restorable backup (genuine new user/device) —
|
|
143
|
+
* otherwise call restore(), which adopts the backed-up device identity.
|
|
144
|
+
* No-op when a device identity already exists. Publishes key packages and
|
|
145
|
+
* opens the WebSocket (unless autoConnectWs was disabled).
|
|
146
|
+
*/
|
|
147
|
+
registerDevice(): Promise<void>;
|
|
148
|
+
/** POST the current keypair as a new device and persist the identity locally. */
|
|
149
|
+
private registerDeviceNow;
|
|
150
|
+
private persistDevice;
|
|
151
|
+
private persistChannelKeys;
|
|
152
|
+
private ensureKeyPackages;
|
|
153
|
+
connectWs(): Promise<void>;
|
|
154
|
+
/** Heartbeat: keep the socket alive while foregrounded so the server's idle
|
|
155
|
+
* timeout only fires once the client actually stops pinging (backgrounded /
|
|
156
|
+
* crashed / lost network), at which point presence clears and pushes resume. */
|
|
157
|
+
private startPing;
|
|
158
|
+
private stopPing;
|
|
159
|
+
/** Drop the WS when the app goes to the background (native): the server clears
|
|
160
|
+
* presence immediately and routes new messages to APNs/FCM push instead of a
|
|
161
|
+
* socket that iOS is about to freeze. Safe to call repeatedly. */
|
|
162
|
+
suspend(): void;
|
|
163
|
+
/** Reconnect when the app returns to the foreground. */
|
|
164
|
+
resume(): void;
|
|
165
|
+
close(): void;
|
|
166
|
+
sendFrame(frame: Record<string, unknown>): Promise<unknown>;
|
|
167
|
+
private handleFrame;
|
|
168
|
+
private handleWelcome;
|
|
169
|
+
/** Fetch any welcomes we missed while offline. */
|
|
170
|
+
syncChannelKey(channelId: string, mlsGroupId: string): Promise<boolean>;
|
|
171
|
+
getChannelKey(channelId: string): CryptoKey | null;
|
|
172
|
+
/** How many channel keys this device currently holds (for backup-freshness checks). */
|
|
173
|
+
get channelKeyCount(): number;
|
|
174
|
+
/** Encrypt bytes under a fresh content key and upload the ciphertext to S3. */
|
|
175
|
+
uploadEncrypted(bytes: ArrayBuffer): Promise<EncryptedBlobRef>;
|
|
176
|
+
/**
|
|
177
|
+
* Enable/refresh an encrypted key backup so the user can restore their chats
|
|
178
|
+
* on a new device. Back up your channel keys + device identity under a key
|
|
179
|
+
* derived from `recoveryCode` (which the user keeps; NoPeek never sees it).
|
|
180
|
+
* Call `generateRecoveryCode()` to make one, show it to the user ONCE, then
|
|
181
|
+
* pass it here. Returns the backupId.
|
|
182
|
+
*/
|
|
183
|
+
/**
|
|
184
|
+
* Encrypted history backup. The chat payload is encrypted with a random data
|
|
185
|
+
* key, which is then WRAPPED separately by each provided secret — so the same
|
|
186
|
+
* backup can be unlocked by the account **password** OR the **recovery code**.
|
|
187
|
+
* This is what lets a user restore on a new device by just signing in with
|
|
188
|
+
* their password; the recovery code is only needed as a last resort (e.g. the
|
|
189
|
+
* password was reset). Accepts a string (treated as a recovery code, legacy)
|
|
190
|
+
* or `{ password?, recoveryCode? }`.
|
|
191
|
+
*/
|
|
192
|
+
backup(secrets: BackupSecrets | string): Promise<string>;
|
|
193
|
+
/**
|
|
194
|
+
* Restore chats on a NEW device from the latest encrypted backup. Pass the
|
|
195
|
+
* account password (preferred) and/or the recovery code — whichever unlocks
|
|
196
|
+
* the backup is used. Rehydrates channel keys so server-stored history
|
|
197
|
+
* decrypts. Returns the number of channels restored.
|
|
198
|
+
*/
|
|
199
|
+
restore(secrets: BackupSecrets | string): Promise<number>;
|
|
200
|
+
/** Cached escrow availability for THIS caller ({enabled, escrowPublicKey}). */
|
|
201
|
+
private escrowCfg;
|
|
202
|
+
/** Set by restoreViaEscrow(): the recovered raw data key (b64), so a follow-up
|
|
203
|
+
* backup() can preserve wraps it can't unlock (e.g. after a password reset). */
|
|
204
|
+
private escrowRestoredDK;
|
|
205
|
+
/** Whether the server escrows backup keys for this user's workspace (cached). */
|
|
206
|
+
private escrowConfig;
|
|
207
|
+
/**
|
|
208
|
+
* Recover chats with NO client-held secret, via server-side key escrow
|
|
209
|
+
* (workspace opt-in). The newest backup's `wraps.escrow` blob — the data key
|
|
210
|
+
* wrapped under the server's escrow PUBLIC key at backup time — is posted to
|
|
211
|
+
* the authenticated escrow-unwrap endpoint; the server decrypts it with the
|
|
212
|
+
* escrow PRIVATE key (Secrets Manager, never the DB) and returns the raw
|
|
213
|
+
* data key. The rest is identical to the password restore path.
|
|
214
|
+
*
|
|
215
|
+
* SECURITY: possession of a valid session is the gate. After a password
|
|
216
|
+
* reset, a session means the user proved email ownership via the emailed
|
|
217
|
+
* reset code — so "email owner → full recovery" is the EXPLICIT tradeoff of
|
|
218
|
+
* escrow mode. Strict (zero-custody) workspaces have no escrow wrap and the
|
|
219
|
+
* endpoint refuses them. Returns the number of channels restored.
|
|
220
|
+
*/
|
|
221
|
+
restoreViaEscrow(): Promise<number>;
|
|
222
|
+
/**
|
|
223
|
+
* Adopt the device identity stored in a backup so a returning user on a fresh
|
|
224
|
+
* install ends up with EXACTLY their original deviceId — not a freshly minted
|
|
225
|
+
* one. Only applies when this client has no established local identity (a
|
|
226
|
+
* deferred connect, or an identity registered moments ago during this very
|
|
227
|
+
* connect, which is then revoked as an orphan). A long-standing local device
|
|
228
|
+
* identity is never hijacked — for those, restore() only rehydrates channel
|
|
229
|
+
* keys, exactly as before.
|
|
230
|
+
*/
|
|
231
|
+
private adoptBackedUpDevice;
|
|
232
|
+
/** Whether this user has any restorable backup on the server. */
|
|
233
|
+
hasBackup(): Promise<boolean>;
|
|
234
|
+
/** Fetch an encrypted attachment blob and decrypt it back to bytes. */
|
|
235
|
+
downloadDecrypt(ref: {
|
|
236
|
+
blobUrl: string;
|
|
237
|
+
contentKey: string;
|
|
238
|
+
iv: string;
|
|
239
|
+
}): Promise<ArrayBuffer>;
|
|
240
|
+
/** App branding/theme tokens (colors, font, radius…) set by the customer. Null until loaded. */
|
|
241
|
+
branding: Record<string, unknown> | null;
|
|
242
|
+
/** Fetch the app's branding tokens (customer white-label theme). */
|
|
243
|
+
loadBranding(): Promise<Record<string, unknown> | null>;
|
|
244
|
+
/** Current known presence for a user (survives listener-attach timing). */
|
|
245
|
+
getPresence(userId: string): {
|
|
246
|
+
status: "online" | "offline";
|
|
247
|
+
lastSeenAt: string | null;
|
|
248
|
+
} | null;
|
|
249
|
+
isOnline(userId: string): boolean;
|
|
250
|
+
/** pollMessageId -> (userId -> selected optionIds). Latest vote wins. */
|
|
251
|
+
private pollVotes;
|
|
252
|
+
private recordPollVote;
|
|
253
|
+
/** Public entry so Channel.history() can fold in historical votes. */
|
|
254
|
+
applyPollVote(pollMessageId: string, userId: string, optionIds: string[]): void;
|
|
255
|
+
/** Aggregate results for a poll: { optionId -> count } plus total voters. */
|
|
256
|
+
pollResults(pollMessageId: string): {
|
|
257
|
+
counts: Record<string, number>;
|
|
258
|
+
voters: number;
|
|
259
|
+
};
|
|
260
|
+
myPollVote(pollMessageId: string): string[];
|
|
261
|
+
/** eventMessageId -> (userId -> "yes" | "no" | "maybe"). Latest response wins. */
|
|
262
|
+
private rsvps;
|
|
263
|
+
private recordRsvp;
|
|
264
|
+
/** Public entry so Channel.history() can fold in historical RSVPs. */
|
|
265
|
+
applyRsvp(eventMessageId: string, userId: string, response: "yes" | "no" | "maybe"): void;
|
|
266
|
+
/** Tally for an event: counts by response + the responding userIds per bucket. */
|
|
267
|
+
rsvpResults(eventMessageId: string): {
|
|
268
|
+
counts: {
|
|
269
|
+
yes: number;
|
|
270
|
+
no: number;
|
|
271
|
+
maybe: number;
|
|
272
|
+
};
|
|
273
|
+
voters: {
|
|
274
|
+
yes: string[];
|
|
275
|
+
no: string[];
|
|
276
|
+
maybe: string[];
|
|
277
|
+
};
|
|
278
|
+
};
|
|
279
|
+
myRsvp(eventMessageId: string): "yes" | "no" | "maybe" | null;
|
|
280
|
+
setChannelKey(channelId: string, key: CryptoKey): void;
|
|
281
|
+
decryptEnvelope(env: Record<string, unknown>): Promise<DecryptedMessage>;
|
|
282
|
+
}
|
|
283
|
+
export interface ChannelRecord {
|
|
284
|
+
channelId: string;
|
|
285
|
+
channelTypeKey: string;
|
|
286
|
+
kind: string;
|
|
287
|
+
e2ee: boolean;
|
|
288
|
+
name: string;
|
|
289
|
+
mlsGroupId: string | null;
|
|
290
|
+
memberCount: number;
|
|
291
|
+
[k: string]: unknown;
|
|
292
|
+
}
|
|
293
|
+
declare class Channels {
|
|
294
|
+
private np;
|
|
295
|
+
constructor(np: NoPeek);
|
|
296
|
+
list(): Promise<Channel[]>;
|
|
297
|
+
get(channelId: string): Promise<Channel>;
|
|
298
|
+
/**
|
|
299
|
+
* Create a channel. For E2EE channels this performs the full key ceremony:
|
|
300
|
+
* generate channel key → claim key packages for every member device →
|
|
301
|
+
* commit epoch 0→1 → send Welcome with the wrapped key to each device.
|
|
302
|
+
*/
|
|
303
|
+
create(opts: {
|
|
304
|
+
channelTypeKey: string;
|
|
305
|
+
name?: string;
|
|
306
|
+
memberIds?: string[];
|
|
307
|
+
metadata?: Record<string, string>;
|
|
308
|
+
}): Promise<Channel>;
|
|
309
|
+
}
|
|
310
|
+
export declare class Channel {
|
|
311
|
+
private np;
|
|
312
|
+
record: ChannelRecord;
|
|
313
|
+
constructor(np: NoPeek, record: ChannelRecord);
|
|
314
|
+
get channelId(): string;
|
|
315
|
+
get e2ee(): boolean;
|
|
316
|
+
/** E2EE key ceremony (creator side). */
|
|
317
|
+
establishKeys(memberIds: string[]): Promise<void>;
|
|
318
|
+
/** Joiner side: derive (preshared mode) or pull the welcome if we lack the key. */
|
|
319
|
+
ensureKey(): Promise<boolean>;
|
|
320
|
+
/** Low-level: send an arbitrary structured payload (image, poll, contact…). */
|
|
321
|
+
sendPayload(payload: Record<string, unknown>, opts?: {
|
|
322
|
+
threadParentId?: string;
|
|
323
|
+
clientMessageId?: string;
|
|
324
|
+
}): Promise<DecryptedMessage>;
|
|
325
|
+
send(body: {
|
|
326
|
+
text?: string;
|
|
327
|
+
type?: string;
|
|
328
|
+
metadata?: Record<string, string>;
|
|
329
|
+
threadParentId?: string;
|
|
330
|
+
linkPreview?: Record<string, unknown>;
|
|
331
|
+
}): Promise<DecryptedMessage>;
|
|
332
|
+
/** Encrypt + upload a file and send it as an image/video/audio/file message. */
|
|
333
|
+
sendAttachment(a: AttachmentInput, opts?: {
|
|
334
|
+
caption?: string;
|
|
335
|
+
threadParentId?: string;
|
|
336
|
+
}): Promise<DecryptedMessage>;
|
|
337
|
+
/** Convenience wrapper for a browser File/Blob (uses .name/.type). */
|
|
338
|
+
sendFile(file: {
|
|
339
|
+
arrayBuffer(): Promise<ArrayBuffer>;
|
|
340
|
+
name?: string;
|
|
341
|
+
type?: string;
|
|
342
|
+
}, opts?: {
|
|
343
|
+
caption?: string;
|
|
344
|
+
thumbnail?: AttachmentInput["thumbnail"];
|
|
345
|
+
width?: number;
|
|
346
|
+
height?: number;
|
|
347
|
+
durationSec?: number;
|
|
348
|
+
}): Promise<DecryptedMessage>;
|
|
349
|
+
/** Download + decrypt an attachment; returns a Blob you can objectURL. */
|
|
350
|
+
fetchAttachment(att: {
|
|
351
|
+
blobUrl: string;
|
|
352
|
+
contentKey: string;
|
|
353
|
+
iv: string;
|
|
354
|
+
contentType?: string;
|
|
355
|
+
}): Promise<Blob>;
|
|
356
|
+
sendPoll(poll: {
|
|
357
|
+
question: string;
|
|
358
|
+
options: string[];
|
|
359
|
+
multiple?: boolean;
|
|
360
|
+
anonymous?: boolean;
|
|
361
|
+
closesAt?: string;
|
|
362
|
+
}): Promise<DecryptedMessage>;
|
|
363
|
+
/** Cast (or, with an empty array, retract) a vote on a poll message. */
|
|
364
|
+
votePoll(pollMessageId: string, optionIds: string[]): Promise<void>;
|
|
365
|
+
sendContact(contact: {
|
|
366
|
+
name: string;
|
|
367
|
+
organization?: string;
|
|
368
|
+
phones?: {
|
|
369
|
+
label?: string;
|
|
370
|
+
value: string;
|
|
371
|
+
}[];
|
|
372
|
+
emails?: {
|
|
373
|
+
label?: string;
|
|
374
|
+
value: string;
|
|
375
|
+
}[];
|
|
376
|
+
url?: string;
|
|
377
|
+
}): Promise<DecryptedMessage>;
|
|
378
|
+
sendCalendarEvent(event: {
|
|
379
|
+
title: string;
|
|
380
|
+
start: string;
|
|
381
|
+
end?: string;
|
|
382
|
+
location?: string;
|
|
383
|
+
description?: string;
|
|
384
|
+
allDay?: boolean;
|
|
385
|
+
url?: string;
|
|
386
|
+
organizer?: string;
|
|
387
|
+
}): Promise<DecryptedMessage>;
|
|
388
|
+
rsvp(eventMessageId: string, response: "yes" | "no" | "maybe"): Promise<void>;
|
|
389
|
+
sendLocation(lat: number, lng: number, label?: string): Promise<DecryptedMessage>;
|
|
390
|
+
/**
|
|
391
|
+
* Bot → humans: a message with tappable action buttons under the text
|
|
392
|
+
* (Telegram-style inline keyboard). Humans respond via invokeAction().
|
|
393
|
+
*/
|
|
394
|
+
sendActions(opts: {
|
|
395
|
+
text?: string;
|
|
396
|
+
actions: BotAction[];
|
|
397
|
+
}): Promise<DecryptedMessage>;
|
|
398
|
+
/**
|
|
399
|
+
* Bot → humans: advertise (or replace) the bot's persistent quick-action
|
|
400
|
+
* bar for this chat. Clients render the LATEST action_bar per bot as chips
|
|
401
|
+
* above the composer; sending a new one supersedes the previous.
|
|
402
|
+
*/
|
|
403
|
+
sendActionBar(opts: {
|
|
404
|
+
actions: BotAction[];
|
|
405
|
+
}): Promise<DecryptedMessage>;
|
|
406
|
+
/**
|
|
407
|
+
* Human → bot: what a tapped action button sends. `label` is optional
|
|
408
|
+
* display sugar so clients can echo "You ran <label>" without a lookup.
|
|
409
|
+
*/
|
|
410
|
+
invokeAction(opts: {
|
|
411
|
+
actionId: string;
|
|
412
|
+
label?: string;
|
|
413
|
+
params?: Record<string, unknown>;
|
|
414
|
+
}): Promise<DecryptedMessage>;
|
|
415
|
+
edit(messageId: string, body: {
|
|
416
|
+
text: string;
|
|
417
|
+
}): Promise<void>;
|
|
418
|
+
recall(messageId: string): Promise<void>;
|
|
419
|
+
react(messageId: string, emoji: string, op?: "add" | "remove"): Promise<void>;
|
|
420
|
+
typing(isTyping: boolean): void;
|
|
421
|
+
markRead(messageId: string): Promise<void>;
|
|
422
|
+
history(opts?: {
|
|
423
|
+
beforeSeq?: number;
|
|
424
|
+
limit?: number;
|
|
425
|
+
}): Promise<DecryptedMessage[]>;
|
|
426
|
+
pollResults(pollMessageId: string): {
|
|
427
|
+
counts: Record<string, number>;
|
|
428
|
+
voters: number;
|
|
429
|
+
};
|
|
430
|
+
myPollVote(pollMessageId: string): string[];
|
|
431
|
+
rsvpResults(eventMessageId: string): {
|
|
432
|
+
counts: {
|
|
433
|
+
yes: number;
|
|
434
|
+
no: number;
|
|
435
|
+
maybe: number;
|
|
436
|
+
};
|
|
437
|
+
voters: {
|
|
438
|
+
yes: string[];
|
|
439
|
+
no: string[];
|
|
440
|
+
maybe: string[];
|
|
441
|
+
};
|
|
442
|
+
};
|
|
443
|
+
myRsvp(eventMessageId: string): "yes" | "no" | "maybe" | null;
|
|
444
|
+
on(event: "message" | "messageUpdated" | "messageRecalled" | "reaction" | "typing" | "receipt" | "pollVote" | "rsvp", fn: (payload: never) => void): () => void;
|
|
445
|
+
}
|
|
446
|
+
export { b64, deriveSharedChannelKey, generateRecoveryCode } from "./crypto.js";
|
|
447
|
+
/** Open the OS file picker. `accept` e.g. "image/*", "video/*", "*/*". */
|
|
448
|
+
export declare function pickFiles(opts?: {
|
|
449
|
+
accept?: string;
|
|
450
|
+
multiple?: boolean;
|
|
451
|
+
capture?: "user" | "environment";
|
|
452
|
+
}): Promise<File[]>;
|
|
453
|
+
/** Pick images from the gallery. */
|
|
454
|
+
export declare const pickImages: (multiple?: boolean) => Promise<File[]>;
|
|
455
|
+
/** Pick a video. */
|
|
456
|
+
export declare const pickVideo: () => Promise<File[]>;
|
|
457
|
+
/** Open the rear camera to take a photo (mobile web). */
|
|
458
|
+
export declare const capturePhoto: () => Promise<File[]>;
|
|
459
|
+
/**
|
|
460
|
+
* Downscale an image File to a JPEG thumbnail (browser only). Returns bytes +
|
|
461
|
+
* intrinsic dimensions, suitable for channel.sendFile({ thumbnail, width, height }).
|
|
462
|
+
*/
|
|
463
|
+
export declare function makeImageThumbnail(file: File, max?: number): Promise<{
|
|
464
|
+
thumbnail: {
|
|
465
|
+
bytes: ArrayBuffer;
|
|
466
|
+
contentType: string;
|
|
467
|
+
};
|
|
468
|
+
width: number;
|
|
469
|
+
height: number;
|
|
470
|
+
}>;
|
|
471
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|