@tagea/capacitor-matrix 0.0.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/README.md ADDED
@@ -0,0 +1,1474 @@
1
+ # @tremaze/capacitor-matrix
2
+
3
+ A [Capacitor](https://capacitorjs.com/) plugin that provides a unified API for the [Matrix](https://matrix.org/) communication protocol across Web, Android, and iOS.
4
+
5
+ - **Web** — powered by [matrix-js-sdk](https://github.com/matrix-org/matrix-js-sdk)
6
+ - **Android** — powered by [matrix-rust-sdk](https://github.com/nicegram/nicegram-android-nicegram-matrix-sdk) (Kotlin bindings)
7
+ - **iOS** — powered by [matrix-rust-components-swift](https://github.com/matrix-org/matrix-rust-components-swift)
8
+
9
+ ## Features
10
+
11
+ - **Authentication** — password login, token-based login, session persistence
12
+ - **Real-time sync** — incremental sync with state change events
13
+ - **Rooms** — create, join, leave, list rooms with summaries
14
+ - **Messaging** — send/receive text, notices, emotes; paginated message history
15
+ - **Media** — upload and send images, audio, video, and files; resolve `mxc://` URLs
16
+ - **Reactions & Redactions** — react to messages, delete (redact) events
17
+ - **Room management** — rename rooms, set topics, invite/kick/ban/unban users
18
+ - **Typing indicators** — send and receive typing notifications
19
+ - **Presence** — set and query online/offline/unavailable status
20
+ - **End-to-end encryption** — cross-signing, key backup, secret storage, recovery, room key export/import
21
+
22
+ ## Requirements
23
+
24
+ | Platform | Minimum Version |
25
+ | -------- | --------------- |
26
+ | Capacitor | 8.0.0 |
27
+ | iOS | 16.0 |
28
+ | Android | API 24 (Android 7.0) |
29
+
30
+ ## Install
31
+
32
+ ```bash
33
+ npm install @tremaze/capacitor-matrix
34
+ npx cap sync
35
+ ```
36
+
37
+ ### iOS
38
+
39
+ No additional setup required. The Swift Package Manager dependency on `matrix-rust-components-swift` is resolved automatically.
40
+
41
+ ### Android
42
+
43
+ The plugin uses `matrix-rust-sdk` via Maven. Ensure your project's `build.gradle` includes `mavenCentral()` in the repositories block (this is the default for new Capacitor projects).
44
+
45
+ ## Usage
46
+
47
+ ### Import
48
+
49
+ ```typescript
50
+ import { Matrix } from '@tremaze/capacitor-matrix';
51
+ ```
52
+
53
+ ### Authentication
54
+
55
+ ```typescript
56
+ // Login with username and password
57
+ const session = await Matrix.login({
58
+ homeserverUrl: 'https://matrix.example.com',
59
+ userId: '@alice:example.com',
60
+ password: 'secret',
61
+ });
62
+ console.log('Logged in as', session.userId);
63
+
64
+ // Or restore a session using a stored access token
65
+ const session = await Matrix.loginWithToken({
66
+ homeserverUrl: 'https://matrix.example.com',
67
+ accessToken: 'syt_...',
68
+ userId: '@alice:example.com',
69
+ deviceId: 'ABCDEF',
70
+ });
71
+
72
+ // Check for an existing session (persisted in localStorage on web)
73
+ const existing = await Matrix.getSession();
74
+ if (existing) {
75
+ console.log('Already logged in as', existing.userId);
76
+ }
77
+
78
+ // Logout
79
+ await Matrix.logout();
80
+ ```
81
+
82
+ ### Sync
83
+
84
+ Start the background sync loop to receive real-time updates:
85
+
86
+ ```typescript
87
+ // Listen for sync state changes
88
+ await Matrix.addListener('syncStateChange', ({ state, error }) => {
89
+ console.log('Sync state:', state); // 'INITIAL' | 'SYNCING' | 'ERROR' | 'STOPPED'
90
+ if (error) console.error('Sync error:', error);
91
+ });
92
+
93
+ await Matrix.startSync();
94
+
95
+ // Later, stop syncing
96
+ await Matrix.stopSync();
97
+ ```
98
+
99
+ ### Rooms
100
+
101
+ ```typescript
102
+ // List joined rooms
103
+ const { rooms } = await Matrix.getRooms();
104
+ rooms.forEach((room) => {
105
+ console.log(room.name, `(${room.memberCount} members)`);
106
+ });
107
+
108
+ // Create a room
109
+ const { roomId } = await Matrix.createRoom({
110
+ name: 'Project Chat',
111
+ topic: 'Discussion about the project',
112
+ isEncrypted: true,
113
+ invite: ['@bob:example.com'],
114
+ });
115
+
116
+ // Join a room by ID or alias
117
+ await Matrix.joinRoom({ roomIdOrAlias: '#general:example.com' });
118
+
119
+ // Leave a room
120
+ await Matrix.leaveRoom({ roomId: '!abc:example.com' });
121
+
122
+ // Get room members
123
+ const { members } = await Matrix.getRoomMembers({ roomId });
124
+ ```
125
+
126
+ ### Messaging
127
+
128
+ ```typescript
129
+ // Send a text message
130
+ const { eventId } = await Matrix.sendMessage({
131
+ roomId: '!abc:example.com',
132
+ body: 'Hello, world!',
133
+ });
134
+
135
+ // Send a notice or emote
136
+ await Matrix.sendMessage({
137
+ roomId,
138
+ body: 'This is a notice',
139
+ msgtype: 'm.notice',
140
+ });
141
+
142
+ // Load message history (paginated)
143
+ const { events, nextBatch } = await Matrix.getRoomMessages({
144
+ roomId,
145
+ limit: 50,
146
+ });
147
+
148
+ // Load older messages
149
+ const older = await Matrix.getRoomMessages({
150
+ roomId,
151
+ limit: 50,
152
+ from: nextBatch,
153
+ });
154
+
155
+ // Listen for new messages in real time
156
+ await Matrix.addListener('messageReceived', ({ event }) => {
157
+ console.log(`${event.senderId}: ${event.content.body}`);
158
+ });
159
+ ```
160
+
161
+ ### Media
162
+
163
+ ```typescript
164
+ // Send an image (provide a file URI on native, or a blob URL on web)
165
+ await Matrix.sendMessage({
166
+ roomId,
167
+ body: 'photo.jpg',
168
+ msgtype: 'm.image',
169
+ fileUri: 'file:///path/to/photo.jpg',
170
+ fileName: 'photo.jpg',
171
+ mimeType: 'image/jpeg',
172
+ });
173
+
174
+ // Resolve an mxc:// URL to an HTTP URL for display
175
+ const { httpUrl } = await Matrix.getMediaUrl({
176
+ mxcUrl: 'mxc://example.com/abc123',
177
+ });
178
+ ```
179
+
180
+ ### Reactions & Redactions
181
+
182
+ ```typescript
183
+ // React to a message
184
+ await Matrix.sendReaction({
185
+ roomId,
186
+ eventId: '$someEvent',
187
+ key: '👍',
188
+ });
189
+
190
+ // Redact (delete) a message
191
+ await Matrix.redactEvent({
192
+ roomId,
193
+ eventId: '$someEvent',
194
+ reason: 'Sent by mistake',
195
+ });
196
+ ```
197
+
198
+ ### Room Management
199
+
200
+ ```typescript
201
+ await Matrix.setRoomName({ roomId, name: 'New Room Name' });
202
+ await Matrix.setRoomTopic({ roomId, topic: 'Updated topic' });
203
+
204
+ await Matrix.inviteUser({ roomId, userId: '@carol:example.com' });
205
+ await Matrix.kickUser({ roomId, userId: '@dave:example.com', reason: 'Inactive' });
206
+ await Matrix.banUser({ roomId, userId: '@eve:example.com' });
207
+ await Matrix.unbanUser({ roomId, userId: '@eve:example.com' });
208
+ ```
209
+
210
+ ### Typing Indicators
211
+
212
+ ```typescript
213
+ // Send a typing notification
214
+ await Matrix.sendTyping({ roomId, isTyping: true, timeout: 5000 });
215
+
216
+ // Stop typing
217
+ await Matrix.sendTyping({ roomId, isTyping: false });
218
+
219
+ // Listen for typing events
220
+ await Matrix.addListener('typingChanged', ({ roomId, userIds }) => {
221
+ if (userIds.length > 0) {
222
+ console.log(`${userIds.join(', ')} typing in ${roomId}`);
223
+ }
224
+ });
225
+ ```
226
+
227
+ ### Presence
228
+
229
+ ```typescript
230
+ // Set your presence
231
+ await Matrix.setPresence({ presence: 'online', statusMsg: 'Available' });
232
+
233
+ // Get another user's presence
234
+ const info = await Matrix.getPresence({ userId: '@bob:example.com' });
235
+ console.log(info.presence, info.statusMsg);
236
+ ```
237
+
238
+ ### End-to-End Encryption
239
+
240
+ ```typescript
241
+ // Initialize the crypto module (call after login, before startSync)
242
+ await Matrix.initializeCrypto();
243
+
244
+ // Check encryption status
245
+ const status = await Matrix.getEncryptionStatus();
246
+ console.log('Cross-signing ready:', status.isCrossSigningReady);
247
+ console.log('Key backup enabled:', status.isKeyBackupEnabled);
248
+
249
+ // Bootstrap cross-signing (first-time device setup)
250
+ await Matrix.bootstrapCrossSigning();
251
+
252
+ // Set up server-side key backup
253
+ const backup = await Matrix.setupKeyBackup();
254
+
255
+ // Set up recovery (generates a recovery key)
256
+ const { recoveryKey } = await Matrix.setupRecovery();
257
+ console.log('Save this recovery key:', recoveryKey);
258
+
259
+ // Or use a passphrase-based recovery key
260
+ const recovery = await Matrix.setupRecovery({ passphrase: 'my secret phrase' });
261
+
262
+ // Recover on a new device
263
+ await Matrix.recoverAndSetup({ recoveryKey: 'EsXa ...' });
264
+ // or
265
+ await Matrix.recoverAndSetup({ passphrase: 'my secret phrase' });
266
+
267
+ // Export/import room keys (for manual backup)
268
+ const { data } = await Matrix.exportRoomKeys({ passphrase: 'backup-pass' });
269
+ await Matrix.importRoomKeys({ data, passphrase: 'backup-pass' });
270
+ ```
271
+
272
+ ### Event Listeners
273
+
274
+ ```typescript
275
+ // Room updates (name change, new members, etc.)
276
+ await Matrix.addListener('roomUpdated', ({ roomId, summary }) => {
277
+ console.log(`Room ${summary.name} updated`);
278
+ });
279
+
280
+ // Read receipt updates (fires when another user reads messages in a room)
281
+ await Matrix.addListener('receiptReceived', ({ roomId }) => {
282
+ console.log(`New read receipt in ${roomId}`);
283
+ // Refresh message statuses to update read indicators
284
+ });
285
+
286
+ // Clean up all listeners
287
+ await Matrix.removeAllListeners();
288
+ ```
289
+
290
+ ### Read Markers
291
+
292
+ ```typescript
293
+ // Mark a room as read up to a specific event
294
+ await Matrix.markRoomAsRead({
295
+ roomId: '!abc:example.com',
296
+ eventId: '$latestEvent',
297
+ });
298
+
299
+ // Refresh read statuses for specific messages (useful after receiving a receiptReceived event)
300
+ const { events } = await Matrix.refreshEventStatuses({
301
+ roomId: '!abc:example.com',
302
+ eventIds: ['$event1', '$event2'],
303
+ });
304
+ events.forEach((evt) => {
305
+ console.log(`${evt.eventId}: ${evt.status}`, evt.readBy);
306
+ });
307
+ ```
308
+
309
+ ## API Reference
310
+
311
+ The full API reference is auto-generated below from the TypeScript definitions.
312
+
313
+ <docgen-index>
314
+
315
+ * [`login(...)`](#login)
316
+ * [`loginWithToken(...)`](#loginwithtoken)
317
+ * [`logout()`](#logout)
318
+ * [`getSession()`](#getsession)
319
+ * [`startSync()`](#startsync)
320
+ * [`stopSync()`](#stopsync)
321
+ * [`getSyncState()`](#getsyncstate)
322
+ * [`createRoom(...)`](#createroom)
323
+ * [`getRooms()`](#getrooms)
324
+ * [`getRoomMembers(...)`](#getroommembers)
325
+ * [`joinRoom(...)`](#joinroom)
326
+ * [`leaveRoom(...)`](#leaveroom)
327
+ * [`forgetRoom(...)`](#forgetroom)
328
+ * [`sendMessage(...)`](#sendmessage)
329
+ * [`editMessage(...)`](#editmessage)
330
+ * [`sendReply(...)`](#sendreply)
331
+ * [`getRoomMessages(...)`](#getroommessages)
332
+ * [`markRoomAsRead(...)`](#markroomasread)
333
+ * [`refreshEventStatuses(...)`](#refresheventstatuses)
334
+ * [`redactEvent(...)`](#redactevent)
335
+ * [`sendReaction(...)`](#sendreaction)
336
+ * [`setRoomName(...)`](#setroomname)
337
+ * [`setRoomTopic(...)`](#setroomtopic)
338
+ * [`setRoomAvatar(...)`](#setroomavatar)
339
+ * [`inviteUser(...)`](#inviteuser)
340
+ * [`kickUser(...)`](#kickuser)
341
+ * [`banUser(...)`](#banuser)
342
+ * [`unbanUser(...)`](#unbanuser)
343
+ * [`sendTyping(...)`](#sendtyping)
344
+ * [`getMediaUrl(...)`](#getmediaurl)
345
+ * [`getThumbnailUrl(...)`](#getthumbnailurl)
346
+ * [`uploadContent(...)`](#uploadcontent)
347
+ * [`searchUsers(...)`](#searchusers)
348
+ * [`setPresence(...)`](#setpresence)
349
+ * [`getPresence(...)`](#getpresence)
350
+ * [`getDevices()`](#getdevices)
351
+ * [`deleteDevice(...)`](#deletedevice)
352
+ * [`setPusher(...)`](#setpusher)
353
+ * [`initializeCrypto()`](#initializecrypto)
354
+ * [`getEncryptionStatus()`](#getencryptionstatus)
355
+ * [`bootstrapCrossSigning()`](#bootstrapcrosssigning)
356
+ * [`setupKeyBackup()`](#setupkeybackup)
357
+ * [`getKeyBackupStatus()`](#getkeybackupstatus)
358
+ * [`restoreKeyBackup(...)`](#restorekeybackup)
359
+ * [`setupRecovery(...)`](#setuprecovery)
360
+ * [`isRecoveryEnabled()`](#isrecoveryenabled)
361
+ * [`recoverAndSetup(...)`](#recoverandsetup)
362
+ * [`resetRecoveryKey(...)`](#resetrecoverykey)
363
+ * [`exportRoomKeys(...)`](#exportroomkeys)
364
+ * [`importRoomKeys(...)`](#importroomkeys)
365
+ * [`addListener('syncStateChange', ...)`](#addlistenersyncstatechange-)
366
+ * [`addListener('messageReceived', ...)`](#addlistenermessagereceived-)
367
+ * [`addListener('roomUpdated', ...)`](#addlistenerroomupdated-)
368
+ * [`addListener('typingChanged', ...)`](#addlistenertypingchanged-)
369
+ * [`addListener('receiptReceived', ...)`](#addlistenerreceiptreceived-)
370
+ * [`addListener('presenceChanged', ...)`](#addlistenerpresencechanged-)
371
+ * [`removeAllListeners()`](#removealllisteners)
372
+ * [Interfaces](#interfaces)
373
+ * [Type Aliases](#type-aliases)
374
+
375
+ </docgen-index>
376
+
377
+ <docgen-api>
378
+ <!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
379
+
380
+ ### login(...)
381
+
382
+ ```typescript
383
+ login(options: LoginOptions) => Promise<SessionInfo>
384
+ ```
385
+
386
+ | Param | Type |
387
+ | ------------- | ----------------------------------------------------- |
388
+ | **`options`** | <code><a href="#loginoptions">LoginOptions</a></code> |
389
+
390
+ **Returns:** <code>Promise&lt;<a href="#sessioninfo">SessionInfo</a>&gt;</code>
391
+
392
+ --------------------
393
+
394
+
395
+ ### loginWithToken(...)
396
+
397
+ ```typescript
398
+ loginWithToken(options: LoginWithTokenOptions) => Promise<SessionInfo>
399
+ ```
400
+
401
+ | Param | Type |
402
+ | ------------- | ----------------------------------------------------------------------- |
403
+ | **`options`** | <code><a href="#loginwithtokenoptions">LoginWithTokenOptions</a></code> |
404
+
405
+ **Returns:** <code>Promise&lt;<a href="#sessioninfo">SessionInfo</a>&gt;</code>
406
+
407
+ --------------------
408
+
409
+
410
+ ### logout()
411
+
412
+ ```typescript
413
+ logout() => Promise<void>
414
+ ```
415
+
416
+ --------------------
417
+
418
+
419
+ ### getSession()
420
+
421
+ ```typescript
422
+ getSession() => Promise<SessionInfo | null>
423
+ ```
424
+
425
+ **Returns:** <code>Promise&lt;<a href="#sessioninfo">SessionInfo</a> | null&gt;</code>
426
+
427
+ --------------------
428
+
429
+
430
+ ### startSync()
431
+
432
+ ```typescript
433
+ startSync() => Promise<void>
434
+ ```
435
+
436
+ --------------------
437
+
438
+
439
+ ### stopSync()
440
+
441
+ ```typescript
442
+ stopSync() => Promise<void>
443
+ ```
444
+
445
+ --------------------
446
+
447
+
448
+ ### getSyncState()
449
+
450
+ ```typescript
451
+ getSyncState() => Promise<{ state: SyncState; }>
452
+ ```
453
+
454
+ **Returns:** <code>Promise&lt;{ state: <a href="#syncstate">SyncState</a>; }&gt;</code>
455
+
456
+ --------------------
457
+
458
+
459
+ ### createRoom(...)
460
+
461
+ ```typescript
462
+ createRoom(options: { name?: string; topic?: string; isEncrypted?: boolean; isDirect?: boolean; invite?: string[]; preset?: 'private_chat' | 'trusted_private_chat' | 'public_chat'; historyVisibility?: 'invited' | 'joined' | 'shared' | 'world_readable'; }) => Promise<{ roomId: string; }>
463
+ ```
464
+
465
+ | Param | Type |
466
+ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
467
+ | **`options`** | <code>{ name?: string; topic?: string; isEncrypted?: boolean; isDirect?: boolean; invite?: string[]; preset?: 'private_chat' \| 'trusted_private_chat' \| 'public_chat'; historyVisibility?: 'invited' \| 'joined' \| 'shared' \| 'world_readable'; }</code> |
468
+
469
+ **Returns:** <code>Promise&lt;{ roomId: string; }&gt;</code>
470
+
471
+ --------------------
472
+
473
+
474
+ ### getRooms()
475
+
476
+ ```typescript
477
+ getRooms() => Promise<{ rooms: RoomSummary[]; }>
478
+ ```
479
+
480
+ **Returns:** <code>Promise&lt;{ rooms: RoomSummary[]; }&gt;</code>
481
+
482
+ --------------------
483
+
484
+
485
+ ### getRoomMembers(...)
486
+
487
+ ```typescript
488
+ getRoomMembers(options: { roomId: string; }) => Promise<{ members: RoomMember[]; }>
489
+ ```
490
+
491
+ | Param | Type |
492
+ | ------------- | -------------------------------- |
493
+ | **`options`** | <code>{ roomId: string; }</code> |
494
+
495
+ **Returns:** <code>Promise&lt;{ members: RoomMember[]; }&gt;</code>
496
+
497
+ --------------------
498
+
499
+
500
+ ### joinRoom(...)
501
+
502
+ ```typescript
503
+ joinRoom(options: { roomIdOrAlias: string; }) => Promise<{ roomId: string; }>
504
+ ```
505
+
506
+ | Param | Type |
507
+ | ------------- | --------------------------------------- |
508
+ | **`options`** | <code>{ roomIdOrAlias: string; }</code> |
509
+
510
+ **Returns:** <code>Promise&lt;{ roomId: string; }&gt;</code>
511
+
512
+ --------------------
513
+
514
+
515
+ ### leaveRoom(...)
516
+
517
+ ```typescript
518
+ leaveRoom(options: { roomId: string; }) => Promise<void>
519
+ ```
520
+
521
+ | Param | Type |
522
+ | ------------- | -------------------------------- |
523
+ | **`options`** | <code>{ roomId: string; }</code> |
524
+
525
+ --------------------
526
+
527
+
528
+ ### forgetRoom(...)
529
+
530
+ ```typescript
531
+ forgetRoom(options: { roomId: string; }) => Promise<void>
532
+ ```
533
+
534
+ | Param | Type |
535
+ | ------------- | -------------------------------- |
536
+ | **`options`** | <code>{ roomId: string; }</code> |
537
+
538
+ --------------------
539
+
540
+
541
+ ### sendMessage(...)
542
+
543
+ ```typescript
544
+ sendMessage(options: SendMessageOptions) => Promise<{ eventId: string; }>
545
+ ```
546
+
547
+ | Param | Type |
548
+ | ------------- | ----------------------------------------------------------------- |
549
+ | **`options`** | <code><a href="#sendmessageoptions">SendMessageOptions</a></code> |
550
+
551
+ **Returns:** <code>Promise&lt;{ eventId: string; }&gt;</code>
552
+
553
+ --------------------
554
+
555
+
556
+ ### editMessage(...)
557
+
558
+ ```typescript
559
+ editMessage(options: EditMessageOptions) => Promise<{ eventId: string; }>
560
+ ```
561
+
562
+ | Param | Type |
563
+ | ------------- | ----------------------------------------------------------------- |
564
+ | **`options`** | <code><a href="#editmessageoptions">EditMessageOptions</a></code> |
565
+
566
+ **Returns:** <code>Promise&lt;{ eventId: string; }&gt;</code>
567
+
568
+ --------------------
569
+
570
+
571
+ ### sendReply(...)
572
+
573
+ ```typescript
574
+ sendReply(options: SendReplyOptions) => Promise<{ eventId: string; }>
575
+ ```
576
+
577
+ | Param | Type |
578
+ | ------------- | ------------------------------------------------------------- |
579
+ | **`options`** | <code><a href="#sendreplyoptions">SendReplyOptions</a></code> |
580
+
581
+ **Returns:** <code>Promise&lt;{ eventId: string; }&gt;</code>
582
+
583
+ --------------------
584
+
585
+
586
+ ### getRoomMessages(...)
587
+
588
+ ```typescript
589
+ getRoomMessages(options: { roomId: string; limit?: number; from?: string; }) => Promise<{ events: MatrixEvent[]; nextBatch?: string; }>
590
+ ```
591
+
592
+ | Param | Type |
593
+ | ------------- | --------------------------------------------------------------- |
594
+ | **`options`** | <code>{ roomId: string; limit?: number; from?: string; }</code> |
595
+
596
+ **Returns:** <code>Promise&lt;{ events: MatrixEvent[]; nextBatch?: string; }&gt;</code>
597
+
598
+ --------------------
599
+
600
+
601
+ ### markRoomAsRead(...)
602
+
603
+ ```typescript
604
+ markRoomAsRead(options: { roomId: string; eventId: string; }) => Promise<void>
605
+ ```
606
+
607
+ | Param | Type |
608
+ | ------------- | ------------------------------------------------- |
609
+ | **`options`** | <code>{ roomId: string; eventId: string; }</code> |
610
+
611
+ --------------------
612
+
613
+
614
+ ### refreshEventStatuses(...)
615
+
616
+ ```typescript
617
+ refreshEventStatuses(options: { roomId: string; eventIds: string[]; }) => Promise<{ events: MatrixEvent[]; }>
618
+ ```
619
+
620
+ | Param | Type |
621
+ | ------------- | ---------------------------------------------------- |
622
+ | **`options`** | <code>{ roomId: string; eventIds: string[]; }</code> |
623
+
624
+ **Returns:** <code>Promise&lt;{ events: MatrixEvent[]; }&gt;</code>
625
+
626
+ --------------------
627
+
628
+
629
+ ### redactEvent(...)
630
+
631
+ ```typescript
632
+ redactEvent(options: { roomId: string; eventId: string; reason?: string; }) => Promise<void>
633
+ ```
634
+
635
+ | Param | Type |
636
+ | ------------- | ------------------------------------------------------------------ |
637
+ | **`options`** | <code>{ roomId: string; eventId: string; reason?: string; }</code> |
638
+
639
+ --------------------
640
+
641
+
642
+ ### sendReaction(...)
643
+
644
+ ```typescript
645
+ sendReaction(options: { roomId: string; eventId: string; key: string; }) => Promise<{ eventId: string; }>
646
+ ```
647
+
648
+ | Param | Type |
649
+ | ------------- | -------------------------------------------------------------- |
650
+ | **`options`** | <code>{ roomId: string; eventId: string; key: string; }</code> |
651
+
652
+ **Returns:** <code>Promise&lt;{ eventId: string; }&gt;</code>
653
+
654
+ --------------------
655
+
656
+
657
+ ### setRoomName(...)
658
+
659
+ ```typescript
660
+ setRoomName(options: { roomId: string; name: string; }) => Promise<void>
661
+ ```
662
+
663
+ | Param | Type |
664
+ | ------------- | ---------------------------------------------- |
665
+ | **`options`** | <code>{ roomId: string; name: string; }</code> |
666
+
667
+ --------------------
668
+
669
+
670
+ ### setRoomTopic(...)
671
+
672
+ ```typescript
673
+ setRoomTopic(options: { roomId: string; topic: string; }) => Promise<void>
674
+ ```
675
+
676
+ | Param | Type |
677
+ | ------------- | ----------------------------------------------- |
678
+ | **`options`** | <code>{ roomId: string; topic: string; }</code> |
679
+
680
+ --------------------
681
+
682
+
683
+ ### setRoomAvatar(...)
684
+
685
+ ```typescript
686
+ setRoomAvatar(options: { roomId: string; mxcUrl: string; }) => Promise<void>
687
+ ```
688
+
689
+ | Param | Type |
690
+ | ------------- | ------------------------------------------------ |
691
+ | **`options`** | <code>{ roomId: string; mxcUrl: string; }</code> |
692
+
693
+ --------------------
694
+
695
+
696
+ ### inviteUser(...)
697
+
698
+ ```typescript
699
+ inviteUser(options: { roomId: string; userId: string; }) => Promise<void>
700
+ ```
701
+
702
+ | Param | Type |
703
+ | ------------- | ------------------------------------------------ |
704
+ | **`options`** | <code>{ roomId: string; userId: string; }</code> |
705
+
706
+ --------------------
707
+
708
+
709
+ ### kickUser(...)
710
+
711
+ ```typescript
712
+ kickUser(options: { roomId: string; userId: string; reason?: string; }) => Promise<void>
713
+ ```
714
+
715
+ | Param | Type |
716
+ | ------------- | ----------------------------------------------------------------- |
717
+ | **`options`** | <code>{ roomId: string; userId: string; reason?: string; }</code> |
718
+
719
+ --------------------
720
+
721
+
722
+ ### banUser(...)
723
+
724
+ ```typescript
725
+ banUser(options: { roomId: string; userId: string; reason?: string; }) => Promise<void>
726
+ ```
727
+
728
+ | Param | Type |
729
+ | ------------- | ----------------------------------------------------------------- |
730
+ | **`options`** | <code>{ roomId: string; userId: string; reason?: string; }</code> |
731
+
732
+ --------------------
733
+
734
+
735
+ ### unbanUser(...)
736
+
737
+ ```typescript
738
+ unbanUser(options: { roomId: string; userId: string; }) => Promise<void>
739
+ ```
740
+
741
+ | Param | Type |
742
+ | ------------- | ------------------------------------------------ |
743
+ | **`options`** | <code>{ roomId: string; userId: string; }</code> |
744
+
745
+ --------------------
746
+
747
+
748
+ ### sendTyping(...)
749
+
750
+ ```typescript
751
+ sendTyping(options: { roomId: string; isTyping: boolean; timeout?: number; }) => Promise<void>
752
+ ```
753
+
754
+ | Param | Type |
755
+ | ------------- | --------------------------------------------------------------------- |
756
+ | **`options`** | <code>{ roomId: string; isTyping: boolean; timeout?: number; }</code> |
757
+
758
+ --------------------
759
+
760
+
761
+ ### getMediaUrl(...)
762
+
763
+ ```typescript
764
+ getMediaUrl(options: { mxcUrl: string; }) => Promise<{ httpUrl: string; }>
765
+ ```
766
+
767
+ | Param | Type |
768
+ | ------------- | -------------------------------- |
769
+ | **`options`** | <code>{ mxcUrl: string; }</code> |
770
+
771
+ **Returns:** <code>Promise&lt;{ httpUrl: string; }&gt;</code>
772
+
773
+ --------------------
774
+
775
+
776
+ ### getThumbnailUrl(...)
777
+
778
+ ```typescript
779
+ getThumbnailUrl(options: ThumbnailUrlOptions) => Promise<{ httpUrl: string; }>
780
+ ```
781
+
782
+ | Param | Type |
783
+ | ------------- | ------------------------------------------------------------------- |
784
+ | **`options`** | <code><a href="#thumbnailurloptions">ThumbnailUrlOptions</a></code> |
785
+
786
+ **Returns:** <code>Promise&lt;{ httpUrl: string; }&gt;</code>
787
+
788
+ --------------------
789
+
790
+
791
+ ### uploadContent(...)
792
+
793
+ ```typescript
794
+ uploadContent(options: UploadContentOptions) => Promise<UploadContentResult>
795
+ ```
796
+
797
+ | Param | Type |
798
+ | ------------- | --------------------------------------------------------------------- |
799
+ | **`options`** | <code><a href="#uploadcontentoptions">UploadContentOptions</a></code> |
800
+
801
+ **Returns:** <code>Promise&lt;<a href="#uploadcontentresult">UploadContentResult</a>&gt;</code>
802
+
803
+ --------------------
804
+
805
+
806
+ ### searchUsers(...)
807
+
808
+ ```typescript
809
+ searchUsers(options: { searchTerm: string; limit?: number; }) => Promise<{ results: UserProfile[]; limited: boolean; }>
810
+ ```
811
+
812
+ | Param | Type |
813
+ | ------------- | ---------------------------------------------------- |
814
+ | **`options`** | <code>{ searchTerm: string; limit?: number; }</code> |
815
+
816
+ **Returns:** <code>Promise&lt;{ results: UserProfile[]; limited: boolean; }&gt;</code>
817
+
818
+ --------------------
819
+
820
+
821
+ ### setPresence(...)
822
+
823
+ ```typescript
824
+ setPresence(options: { presence: 'online' | 'offline' | 'unavailable'; statusMsg?: string; }) => Promise<void>
825
+ ```
826
+
827
+ | Param | Type |
828
+ | ------------- | -------------------------------------------------------------------------------------- |
829
+ | **`options`** | <code>{ presence: 'online' \| 'offline' \| 'unavailable'; statusMsg?: string; }</code> |
830
+
831
+ --------------------
832
+
833
+
834
+ ### getPresence(...)
835
+
836
+ ```typescript
837
+ getPresence(options: { userId: string; }) => Promise<PresenceInfo>
838
+ ```
839
+
840
+ | Param | Type |
841
+ | ------------- | -------------------------------- |
842
+ | **`options`** | <code>{ userId: string; }</code> |
843
+
844
+ **Returns:** <code>Promise&lt;<a href="#presenceinfo">PresenceInfo</a>&gt;</code>
845
+
846
+ --------------------
847
+
848
+
849
+ ### getDevices()
850
+
851
+ ```typescript
852
+ getDevices() => Promise<{ devices: DeviceInfo[]; }>
853
+ ```
854
+
855
+ **Returns:** <code>Promise&lt;{ devices: DeviceInfo[]; }&gt;</code>
856
+
857
+ --------------------
858
+
859
+
860
+ ### deleteDevice(...)
861
+
862
+ ```typescript
863
+ deleteDevice(options: { deviceId: string; auth?: Record<string, unknown>; }) => Promise<void>
864
+ ```
865
+
866
+ | Param | Type |
867
+ | ------------- | ---------------------------------------------------------------------------------------------- |
868
+ | **`options`** | <code>{ deviceId: string; auth?: <a href="#record">Record</a>&lt;string, unknown&gt;; }</code> |
869
+
870
+ --------------------
871
+
872
+
873
+ ### setPusher(...)
874
+
875
+ ```typescript
876
+ setPusher(options: PusherOptions) => Promise<void>
877
+ ```
878
+
879
+ | Param | Type |
880
+ | ------------- | ------------------------------------------------------- |
881
+ | **`options`** | <code><a href="#pusheroptions">PusherOptions</a></code> |
882
+
883
+ --------------------
884
+
885
+
886
+ ### initializeCrypto()
887
+
888
+ ```typescript
889
+ initializeCrypto() => Promise<void>
890
+ ```
891
+
892
+ --------------------
893
+
894
+
895
+ ### getEncryptionStatus()
896
+
897
+ ```typescript
898
+ getEncryptionStatus() => Promise<EncryptionStatus>
899
+ ```
900
+
901
+ **Returns:** <code>Promise&lt;<a href="#encryptionstatus">EncryptionStatus</a>&gt;</code>
902
+
903
+ --------------------
904
+
905
+
906
+ ### bootstrapCrossSigning()
907
+
908
+ ```typescript
909
+ bootstrapCrossSigning() => Promise<void>
910
+ ```
911
+
912
+ --------------------
913
+
914
+
915
+ ### setupKeyBackup()
916
+
917
+ ```typescript
918
+ setupKeyBackup() => Promise<KeyBackupStatus>
919
+ ```
920
+
921
+ **Returns:** <code>Promise&lt;<a href="#keybackupstatus">KeyBackupStatus</a>&gt;</code>
922
+
923
+ --------------------
924
+
925
+
926
+ ### getKeyBackupStatus()
927
+
928
+ ```typescript
929
+ getKeyBackupStatus() => Promise<KeyBackupStatus>
930
+ ```
931
+
932
+ **Returns:** <code>Promise&lt;<a href="#keybackupstatus">KeyBackupStatus</a>&gt;</code>
933
+
934
+ --------------------
935
+
936
+
937
+ ### restoreKeyBackup(...)
938
+
939
+ ```typescript
940
+ restoreKeyBackup(options?: { recoveryKey?: string | undefined; } | undefined) => Promise<{ importedKeys: number; }>
941
+ ```
942
+
943
+ | Param | Type |
944
+ | ------------- | -------------------------------------- |
945
+ | **`options`** | <code>{ recoveryKey?: string; }</code> |
946
+
947
+ **Returns:** <code>Promise&lt;{ importedKeys: number; }&gt;</code>
948
+
949
+ --------------------
950
+
951
+
952
+ ### setupRecovery(...)
953
+
954
+ ```typescript
955
+ setupRecovery(options?: { passphrase?: string | undefined; } | undefined) => Promise<RecoveryKeyInfo>
956
+ ```
957
+
958
+ | Param | Type |
959
+ | ------------- | ------------------------------------- |
960
+ | **`options`** | <code>{ passphrase?: string; }</code> |
961
+
962
+ **Returns:** <code>Promise&lt;<a href="#recoverykeyinfo">RecoveryKeyInfo</a>&gt;</code>
963
+
964
+ --------------------
965
+
966
+
967
+ ### isRecoveryEnabled()
968
+
969
+ ```typescript
970
+ isRecoveryEnabled() => Promise<{ enabled: boolean; }>
971
+ ```
972
+
973
+ **Returns:** <code>Promise&lt;{ enabled: boolean; }&gt;</code>
974
+
975
+ --------------------
976
+
977
+
978
+ ### recoverAndSetup(...)
979
+
980
+ ```typescript
981
+ recoverAndSetup(options: { recoveryKey?: string; passphrase?: string; }) => Promise<void>
982
+ ```
983
+
984
+ | Param | Type |
985
+ | ------------- | ----------------------------------------------------------- |
986
+ | **`options`** | <code>{ recoveryKey?: string; passphrase?: string; }</code> |
987
+
988
+ --------------------
989
+
990
+
991
+ ### resetRecoveryKey(...)
992
+
993
+ ```typescript
994
+ resetRecoveryKey(options?: { passphrase?: string | undefined; } | undefined) => Promise<RecoveryKeyInfo>
995
+ ```
996
+
997
+ | Param | Type |
998
+ | ------------- | ------------------------------------- |
999
+ | **`options`** | <code>{ passphrase?: string; }</code> |
1000
+
1001
+ **Returns:** <code>Promise&lt;<a href="#recoverykeyinfo">RecoveryKeyInfo</a>&gt;</code>
1002
+
1003
+ --------------------
1004
+
1005
+
1006
+ ### exportRoomKeys(...)
1007
+
1008
+ ```typescript
1009
+ exportRoomKeys(options: { passphrase: string; }) => Promise<{ data: string; }>
1010
+ ```
1011
+
1012
+ | Param | Type |
1013
+ | ------------- | ------------------------------------ |
1014
+ | **`options`** | <code>{ passphrase: string; }</code> |
1015
+
1016
+ **Returns:** <code>Promise&lt;{ data: string; }&gt;</code>
1017
+
1018
+ --------------------
1019
+
1020
+
1021
+ ### importRoomKeys(...)
1022
+
1023
+ ```typescript
1024
+ importRoomKeys(options: { data: string; passphrase: string; }) => Promise<{ importedKeys: number; }>
1025
+ ```
1026
+
1027
+ | Param | Type |
1028
+ | ------------- | -------------------------------------------------- |
1029
+ | **`options`** | <code>{ data: string; passphrase: string; }</code> |
1030
+
1031
+ **Returns:** <code>Promise&lt;{ importedKeys: number; }&gt;</code>
1032
+
1033
+ --------------------
1034
+
1035
+
1036
+ ### addListener('syncStateChange', ...)
1037
+
1038
+ ```typescript
1039
+ addListener(event: 'syncStateChange', listenerFunc: (data: SyncStateChangeEvent) => void) => Promise<PluginListenerHandle>
1040
+ ```
1041
+
1042
+ | Param | Type |
1043
+ | ------------------ | ---------------------------------------------------------------------------------------- |
1044
+ | **`event`** | <code>'syncStateChange'</code> |
1045
+ | **`listenerFunc`** | <code>(data: <a href="#syncstatechangeevent">SyncStateChangeEvent</a>) =&gt; void</code> |
1046
+
1047
+ **Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>
1048
+
1049
+ --------------------
1050
+
1051
+
1052
+ ### addListener('messageReceived', ...)
1053
+
1054
+ ```typescript
1055
+ addListener(event: 'messageReceived', listenerFunc: (data: MessageReceivedEvent) => void) => Promise<PluginListenerHandle>
1056
+ ```
1057
+
1058
+ | Param | Type |
1059
+ | ------------------ | ---------------------------------------------------------------------------------------- |
1060
+ | **`event`** | <code>'messageReceived'</code> |
1061
+ | **`listenerFunc`** | <code>(data: <a href="#messagereceivedevent">MessageReceivedEvent</a>) =&gt; void</code> |
1062
+
1063
+ **Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>
1064
+
1065
+ --------------------
1066
+
1067
+
1068
+ ### addListener('roomUpdated', ...)
1069
+
1070
+ ```typescript
1071
+ addListener(event: 'roomUpdated', listenerFunc: (data: RoomUpdatedEvent) => void) => Promise<PluginListenerHandle>
1072
+ ```
1073
+
1074
+ | Param | Type |
1075
+ | ------------------ | -------------------------------------------------------------------------------- |
1076
+ | **`event`** | <code>'roomUpdated'</code> |
1077
+ | **`listenerFunc`** | <code>(data: <a href="#roomupdatedevent">RoomUpdatedEvent</a>) =&gt; void</code> |
1078
+
1079
+ **Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>
1080
+
1081
+ --------------------
1082
+
1083
+
1084
+ ### addListener('typingChanged', ...)
1085
+
1086
+ ```typescript
1087
+ addListener(event: 'typingChanged', listenerFunc: (data: TypingEvent) => void) => Promise<PluginListenerHandle>
1088
+ ```
1089
+
1090
+ | Param | Type |
1091
+ | ------------------ | ---------------------------------------------------------------------- |
1092
+ | **`event`** | <code>'typingChanged'</code> |
1093
+ | **`listenerFunc`** | <code>(data: <a href="#typingevent">TypingEvent</a>) =&gt; void</code> |
1094
+
1095
+ **Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>
1096
+
1097
+ --------------------
1098
+
1099
+
1100
+ ### addListener('receiptReceived', ...)
1101
+
1102
+ ```typescript
1103
+ addListener(event: 'receiptReceived', listenerFunc: (data: ReceiptReceivedEvent) => void) => Promise<PluginListenerHandle>
1104
+ ```
1105
+
1106
+ | Param | Type |
1107
+ | ------------------ | ---------------------------------------------------------------------------------------- |
1108
+ | **`event`** | <code>'receiptReceived'</code> |
1109
+ | **`listenerFunc`** | <code>(data: <a href="#receiptreceivedevent">ReceiptReceivedEvent</a>) =&gt; void</code> |
1110
+
1111
+ **Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>
1112
+
1113
+ --------------------
1114
+
1115
+
1116
+ ### addListener('presenceChanged', ...)
1117
+
1118
+ ```typescript
1119
+ addListener(event: 'presenceChanged', listenerFunc: (data: PresenceChangedEvent) => void) => Promise<PluginListenerHandle>
1120
+ ```
1121
+
1122
+ | Param | Type |
1123
+ | ------------------ | ---------------------------------------------------------------------------------------- |
1124
+ | **`event`** | <code>'presenceChanged'</code> |
1125
+ | **`listenerFunc`** | <code>(data: <a href="#presencechangedevent">PresenceChangedEvent</a>) =&gt; void</code> |
1126
+
1127
+ **Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>
1128
+
1129
+ --------------------
1130
+
1131
+
1132
+ ### removeAllListeners()
1133
+
1134
+ ```typescript
1135
+ removeAllListeners() => Promise<void>
1136
+ ```
1137
+
1138
+ --------------------
1139
+
1140
+
1141
+ ### Interfaces
1142
+
1143
+
1144
+ #### SessionInfo
1145
+
1146
+ | Prop | Type |
1147
+ | ------------------- | ------------------- |
1148
+ | **`accessToken`** | <code>string</code> |
1149
+ | **`userId`** | <code>string</code> |
1150
+ | **`deviceId`** | <code>string</code> |
1151
+ | **`homeserverUrl`** | <code>string</code> |
1152
+
1153
+
1154
+ #### LoginOptions
1155
+
1156
+ | Prop | Type |
1157
+ | ------------------- | ------------------- |
1158
+ | **`homeserverUrl`** | <code>string</code> |
1159
+ | **`userId`** | <code>string</code> |
1160
+ | **`password`** | <code>string</code> |
1161
+
1162
+
1163
+ #### LoginWithTokenOptions
1164
+
1165
+ | Prop | Type |
1166
+ | ------------------- | ------------------- |
1167
+ | **`homeserverUrl`** | <code>string</code> |
1168
+ | **`accessToken`** | <code>string</code> |
1169
+ | **`userId`** | <code>string</code> |
1170
+ | **`deviceId`** | <code>string</code> |
1171
+
1172
+
1173
+ #### RoomSummary
1174
+
1175
+ | Prop | Type |
1176
+ | ----------------- | --------------------------------------------------- |
1177
+ | **`roomId`** | <code>string</code> |
1178
+ | **`name`** | <code>string</code> |
1179
+ | **`topic`** | <code>string</code> |
1180
+ | **`memberCount`** | <code>number</code> |
1181
+ | **`isEncrypted`** | <code>boolean</code> |
1182
+ | **`unreadCount`** | <code>number</code> |
1183
+ | **`lastEventTs`** | <code>number</code> |
1184
+ | **`membership`** | <code>'join' \| 'invite' \| 'leave' \| 'ban'</code> |
1185
+ | **`avatarUrl`** | <code>string</code> |
1186
+ | **`isDirect`** | <code>boolean</code> |
1187
+
1188
+
1189
+ #### RoomMember
1190
+
1191
+ | Prop | Type |
1192
+ | ----------------- | --------------------------------------------------- |
1193
+ | **`userId`** | <code>string</code> |
1194
+ | **`displayName`** | <code>string</code> |
1195
+ | **`membership`** | <code>'join' \| 'invite' \| 'leave' \| 'ban'</code> |
1196
+ | **`avatarUrl`** | <code>string</code> |
1197
+
1198
+
1199
+ #### SendMessageOptions
1200
+
1201
+ | Prop | Type |
1202
+ | -------------- | --------------------------------------------------------------------------------------------------- |
1203
+ | **`roomId`** | <code>string</code> |
1204
+ | **`body`** | <code>string</code> |
1205
+ | **`msgtype`** | <code>'m.text' \| 'm.notice' \| 'm.emote' \| 'm.image' \| 'm.audio' \| 'm.video' \| 'm.file'</code> |
1206
+ | **`fileUri`** | <code>string</code> |
1207
+ | **`fileName`** | <code>string</code> |
1208
+ | **`mimeType`** | <code>string</code> |
1209
+ | **`fileSize`** | <code>number</code> |
1210
+
1211
+
1212
+ #### EditMessageOptions
1213
+
1214
+ | Prop | Type |
1215
+ | ------------- | ------------------- |
1216
+ | **`roomId`** | <code>string</code> |
1217
+ | **`eventId`** | <code>string</code> |
1218
+ | **`newBody`** | <code>string</code> |
1219
+
1220
+
1221
+ #### SendReplyOptions
1222
+
1223
+ | Prop | Type |
1224
+ | -------------------- | --------------------------------------------------------------------------------------------------- |
1225
+ | **`roomId`** | <code>string</code> |
1226
+ | **`body`** | <code>string</code> |
1227
+ | **`replyToEventId`** | <code>string</code> |
1228
+ | **`msgtype`** | <code>'m.text' \| 'm.notice' \| 'm.emote' \| 'm.image' \| 'm.audio' \| 'm.video' \| 'm.file'</code> |
1229
+ | **`fileUri`** | <code>string</code> |
1230
+ | **`fileName`** | <code>string</code> |
1231
+ | **`mimeType`** | <code>string</code> |
1232
+ | **`fileSize`** | <code>number</code> |
1233
+
1234
+
1235
+ #### MatrixEvent
1236
+
1237
+ | Prop | Type | Description |
1238
+ | -------------------- | ---------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
1239
+ | **`eventId`** | <code>string</code> | |
1240
+ | **`roomId`** | <code>string</code> | |
1241
+ | **`senderId`** | <code>string</code> | |
1242
+ | **`type`** | <code>string</code> | |
1243
+ | **`content`** | <code><a href="#record">Record</a>&lt;string, unknown&gt;</code> | |
1244
+ | **`originServerTs`** | <code>number</code> | |
1245
+ | **`status`** | <code>'sending' \| 'sent' \| 'delivered' \| 'read'</code> | Delivery/read status for own messages: 'sending' \| 'sent' \| 'delivered' \| 'read' |
1246
+ | **`readBy`** | <code>string[]</code> | User IDs that have read this event |
1247
+ | **`unsigned`** | <code><a href="#record">Record</a>&lt;string, unknown&gt;</code> | Unsigned data (e.g. m.relations for edits, transaction_id for local echo) |
1248
+
1249
+
1250
+ #### ThumbnailUrlOptions
1251
+
1252
+ | Prop | Type |
1253
+ | ------------ | ------------------------------ |
1254
+ | **`mxcUrl`** | <code>string</code> |
1255
+ | **`width`** | <code>number</code> |
1256
+ | **`height`** | <code>number</code> |
1257
+ | **`method`** | <code>'scale' \| 'crop'</code> |
1258
+
1259
+
1260
+ #### UploadContentResult
1261
+
1262
+ | Prop | Type |
1263
+ | ---------------- | ------------------- |
1264
+ | **`contentUri`** | <code>string</code> |
1265
+
1266
+
1267
+ #### UploadContentOptions
1268
+
1269
+ | Prop | Type |
1270
+ | -------------- | ------------------- |
1271
+ | **`fileUri`** | <code>string</code> |
1272
+ | **`fileName`** | <code>string</code> |
1273
+ | **`mimeType`** | <code>string</code> |
1274
+
1275
+
1276
+ #### UserProfile
1277
+
1278
+ | Prop | Type |
1279
+ | ----------------- | ------------------- |
1280
+ | **`userId`** | <code>string</code> |
1281
+ | **`displayName`** | <code>string</code> |
1282
+ | **`avatarUrl`** | <code>string</code> |
1283
+
1284
+
1285
+ #### PresenceInfo
1286
+
1287
+ | Prop | Type |
1288
+ | ------------------- | --------------------------------------------------- |
1289
+ | **`presence`** | <code>'online' \| 'offline' \| 'unavailable'</code> |
1290
+ | **`statusMsg`** | <code>string</code> |
1291
+ | **`lastActiveAgo`** | <code>number</code> |
1292
+
1293
+
1294
+ #### DeviceInfo
1295
+
1296
+ | Prop | Type |
1297
+ | ----------------- | ------------------- |
1298
+ | **`deviceId`** | <code>string</code> |
1299
+ | **`displayName`** | <code>string</code> |
1300
+ | **`lastSeenTs`** | <code>number</code> |
1301
+ | **`lastSeenIp`** | <code>string</code> |
1302
+
1303
+
1304
+ #### PusherOptions
1305
+
1306
+ | Prop | Type |
1307
+ | ----------------------- | ---------------------------------------------- |
1308
+ | **`pushkey`** | <code>string</code> |
1309
+ | **`kind`** | <code>string \| null</code> |
1310
+ | **`appId`** | <code>string</code> |
1311
+ | **`appDisplayName`** | <code>string</code> |
1312
+ | **`deviceDisplayName`** | <code>string</code> |
1313
+ | **`lang`** | <code>string</code> |
1314
+ | **`data`** | <code>{ url: string; format?: string; }</code> |
1315
+
1316
+
1317
+ #### EncryptionStatus
1318
+
1319
+ | Prop | Type |
1320
+ | -------------------------- | ----------------------------------------------------------------- |
1321
+ | **`isCrossSigningReady`** | <code>boolean</code> |
1322
+ | **`crossSigningStatus`** | <code><a href="#crosssigningstatus">CrossSigningStatus</a></code> |
1323
+ | **`isKeyBackupEnabled`** | <code>boolean</code> |
1324
+ | **`keyBackupVersion`** | <code>string</code> |
1325
+ | **`isSecretStorageReady`** | <code>boolean</code> |
1326
+
1327
+
1328
+ #### CrossSigningStatus
1329
+
1330
+ | Prop | Type |
1331
+ | -------------------- | -------------------- |
1332
+ | **`hasMaster`** | <code>boolean</code> |
1333
+ | **`hasSelfSigning`** | <code>boolean</code> |
1334
+ | **`hasUserSigning`** | <code>boolean</code> |
1335
+ | **`isReady`** | <code>boolean</code> |
1336
+
1337
+
1338
+ #### KeyBackupStatus
1339
+
1340
+ | Prop | Type |
1341
+ | ------------- | -------------------- |
1342
+ | **`exists`** | <code>boolean</code> |
1343
+ | **`version`** | <code>string</code> |
1344
+ | **`enabled`** | <code>boolean</code> |
1345
+
1346
+
1347
+ #### RecoveryKeyInfo
1348
+
1349
+ | Prop | Type |
1350
+ | ----------------- | ------------------- |
1351
+ | **`recoveryKey`** | <code>string</code> |
1352
+
1353
+
1354
+ #### PluginListenerHandle
1355
+
1356
+ | Prop | Type |
1357
+ | ------------ | ----------------------------------------- |
1358
+ | **`remove`** | <code>() =&gt; Promise&lt;void&gt;</code> |
1359
+
1360
+
1361
+ #### SyncStateChangeEvent
1362
+
1363
+ | Prop | Type |
1364
+ | ----------- | ----------------------------------------------- |
1365
+ | **`state`** | <code><a href="#syncstate">SyncState</a></code> |
1366
+ | **`error`** | <code>string</code> |
1367
+
1368
+
1369
+ #### MessageReceivedEvent
1370
+
1371
+ | Prop | Type |
1372
+ | ----------- | --------------------------------------------------- |
1373
+ | **`event`** | <code><a href="#matrixevent">MatrixEvent</a></code> |
1374
+
1375
+
1376
+ #### RoomUpdatedEvent
1377
+
1378
+ | Prop | Type |
1379
+ | ------------- | --------------------------------------------------- |
1380
+ | **`roomId`** | <code>string</code> |
1381
+ | **`summary`** | <code><a href="#roomsummary">RoomSummary</a></code> |
1382
+
1383
+
1384
+ #### TypingEvent
1385
+
1386
+ | Prop | Type |
1387
+ | ------------- | --------------------- |
1388
+ | **`roomId`** | <code>string</code> |
1389
+ | **`userIds`** | <code>string[]</code> |
1390
+
1391
+
1392
+ #### ReceiptReceivedEvent
1393
+
1394
+ | Prop | Type |
1395
+ | ------------ | ------------------- |
1396
+ | **`roomId`** | <code>string</code> |
1397
+
1398
+
1399
+ #### PresenceChangedEvent
1400
+
1401
+ | Prop | Type |
1402
+ | -------------- | ----------------------------------------------------- |
1403
+ | **`userId`** | <code>string</code> |
1404
+ | **`presence`** | <code><a href="#presenceinfo">PresenceInfo</a></code> |
1405
+
1406
+
1407
+ ### Type Aliases
1408
+
1409
+
1410
+ #### SyncState
1411
+
1412
+ <code>'INITIAL' | 'SYNCING' | 'ERROR' | 'STOPPED'</code>
1413
+
1414
+
1415
+ #### Record
1416
+
1417
+ Construct a type with a set of properties K of type T
1418
+
1419
+ <code>{
1420
  [P in K]: T;
1
1421
  }</code>
1422
+
1423
+ </docgen-api>
1424
+
1425
+ ## Development
1426
+
1427
+ ### Setup
1428
+
1429
+ ```bash
1430
+ npm install
1431
+ ```
1432
+
1433
+ ### Build
1434
+
1435
+ ```bash
1436
+ npm run build
1437
+ ```
1438
+
1439
+ ### Test
1440
+
1441
+ ```bash
1442
+ npm test # run once
1443
+ npm run test:watch # watch mode
1444
+ ```
1445
+
1446
+ The test suite covers the web layer (~98 tests) using Vitest with jsdom, mocking `matrix-js-sdk` at the module level.
1447
+
1448
+ ### Verify All Platforms
1449
+
1450
+ ```bash
1451
+ npm run verify # builds + tests web, builds Android, builds iOS
1452
+ npm run verify:web # web only
1453
+ npm run verify:android
1454
+ npm run verify:ios
1455
+ ```
1456
+
1457
+ ### Lint & Format
1458
+
1459
+ ```bash
1460
+ npm run lint # check
1461
+ npm run fmt # auto-fix
1462
+ ```
1463
+
1464
+ ### Example App
1465
+
1466
+ An example app is included in `example-app/` for manual testing against a local homeserver:
1467
+
1468
+ ```bash
1469
+ cd example-app
1470
+ npm install
1471
+ npm run dev
1472
+ ```
1473
+
1474
+ ## License
1475
+
1476
+ MIT