Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/xmtp/xmtp-react-native into…
Browse files Browse the repository at this point in the history
… noe/fix-group-streams-issues
  • Loading branch information
nplasterer committed Sep 29, 2024
2 parents 9a30400 + d2374af commit 510bf6b
Show file tree
Hide file tree
Showing 13 changed files with 156 additions and 144 deletions.
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ repositories {
dependencies {
implementation project(':expo-modules-core')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
implementation "org.xmtp:android:0.15.10"
implementation "org.xmtp:android:0.15.11"
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'com.facebook.react:react-native:0.71.3'
implementation "com.daveanthonythomas.moshipack:moshipack:1.0.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import org.xmtp.android.library.Conversation
class ConversationContainerWrapper {

companion object {
fun encodeToObj(client: Client, conversation: Conversation): Map<String, Any?> {
suspend fun encodeToObj(client: Client, conversation: Conversation): Map<String, Any?> {
when (conversation.version) {
Conversation.Version.GROUP -> {
val group = (conversation as Conversation.Group).group
Expand All @@ -20,7 +20,7 @@ class ConversationContainerWrapper {
}
}

fun encode(client: Client, conversation: Conversation): String {
suspend fun encode(client: Client, conversation: Conversation): String {
val gson = GsonBuilder().create()
val obj = ConversationContainerWrapper.encodeToObj(client, conversation)
return gson.toJson(obj)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import org.xmtp.android.library.toHex
class GroupWrapper {

companion object {
fun encodeToObj(client: Client, group: Group): Map<String, Any> {
suspend fun encodeToObj(client: Client, group: Group): Map<String, Any> {
return mapOf(
"clientAddress" to client.address,
"id" to group.id,
Expand All @@ -26,7 +26,7 @@ class GroupWrapper {
)
}

fun encode(client: Client, group: Group): String {
suspend fun encode(client: Client, group: Group): String {
val gson = GsonBuilder().create()
val obj = encodeToObj(client, group)
return gson.toJson(obj)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
package expo.modules.xmtpreactnativesdk.wrappers

import com.google.gson.Gson
import com.google.gson.GsonBuilder
import uniffi.xmtpv3.org.xmtp.android.library.libxmtp.InboxState

class InboxStateWrapper {
companion object {
val gson: Gson = GsonBuilder().create()
fun encodeToObj(inboxState: InboxState): Map<String, Any> {
return mapOf(
"inboxId" to inboxState.inboxId,
"addresses" to inboxState.addresses,
"installationIds" to inboxState.installationIds,
"installations" to inboxState.installations.map {
gson.toJson(
mapOf(
"id" to it.installationId,
"createdAt" to it.createdAt?.time
)
)
},
"recoveryAddress" to inboxState.recoveryAddress
)
}

fun encode(inboxState: InboxState): String {
val gson = GsonBuilder().create()
val obj = encodeToObj(inboxState)
return gson.toJson(obj)
}
Expand Down
14 changes: 7 additions & 7 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ PODS:
- hermes-engine/Pre-built (= 0.71.14)
- hermes-engine/Pre-built (0.71.14)
- libevent (2.1.12)
- LibXMTP (0.5.8-beta6)
- LibXMTP (0.5.8-beta7)
- Logging (1.0.0)
- MessagePacker (0.4.7)
- MMKV (1.3.9):
Expand Down Expand Up @@ -449,16 +449,16 @@ PODS:
- GenericJSON (~> 2.0)
- Logging (~> 1.0.0)
- secp256k1.swift (~> 0.1)
- XMTP (0.14.14):
- XMTP (0.14.17):
- Connect-Swift (= 0.12.0)
- GzipSwift
- LibXMTP (= 0.5.8-beta6)
- LibXMTP (= 0.5.8-beta7)
- web3.swift
- XMTPReactNative (0.1.0):
- ExpoModulesCore
- MessagePacker
- secp256k1.swift
- XMTP (= 0.14.14)
- XMTP (= 0.14.17)
- Yoga (1.14.0)

DEPENDENCIES:
Expand Down Expand Up @@ -711,7 +711,7 @@ SPEC CHECKSUMS:
GzipSwift: 893f3e48e597a1a4f62fafcb6514220fcf8287fa
hermes-engine: d7cc127932c89c53374452d6f93473f1970d8e88
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
LibXMTP: c7338cace222bed90f950579300725325a2c0bfd
LibXMTP: 693447f2c1242dd2f5b2146828c52dbb2bd92d6f
Logging: 9ef4ecb546ad3169398d5a723bc9bea1c46bef26
MessagePacker: ab2fe250e86ea7aedd1a9ee47a37083edd41fd02
MMKV: 817ba1eea17421547e01e087285606eb270a8dcb
Expand Down Expand Up @@ -763,8 +763,8 @@ SPEC CHECKSUMS:
secp256k1.swift: a7e7a214f6db6ce5db32cc6b2b45e5c4dd633634
SwiftProtobuf: 407a385e97fd206c4fbe880cc84123989167e0d1
web3.swift: 2263d1e12e121b2c42ffb63a5a7beb1acaf33959
XMTP: 37621f1258b12629af305e6697414ccb2fbd4ea8
XMTPReactNative: 7bec275ed26997e6a73f06a678c328e6ba852cd5
XMTP: 64600a3216ef8bfb074a128cffe37458b23c52fd
XMTPReactNative: 39e85c5215efa8cb7900285dc95319402758d85b
Yoga: e71803b4c1fff832ccf9b92541e00f9b873119b9

PODFILE CHECKSUM: 0e6fe50018f34e575d38dc6a1fdf1f99c9596cdd
Expand Down
165 changes: 60 additions & 105 deletions example/src/tests/groupTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Platform } from 'expo-modules-core'
import RNFS from 'react-native-fs'
import { DecodedMessage } from 'xmtp-react-native-sdk/lib/DecodedMessage'

import { Test, assert, createClients, delayToPropogate } from './test-utils'
import { Test, assert, createClients, createGroups, delayToPropogate } from './test-utils'

Check warning on line 6 in example/src/tests/groupTests.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `·Test,·assert,·createClients,·createGroups,·delayToPropogate·` with `⏎··Test,⏎··assert,⏎··createClients,⏎··createGroups,⏎··delayToPropogate,⏎`
import {
Client,
Conversation,
Expand All @@ -21,28 +21,6 @@ function test(name: string, perform: () => Promise<boolean>) {
groupTests.push({ name: String(counter++) + '. ' + name, run: perform })
}

async function createGroups(
client: Client,
peers: Client[],
numGroups: number,
numMessages: number
): Promise<Group[]> {
const groups = []
const addresses: string[] = peers.map((client) => client.address)
for (let i = 0; i < numGroups; i++) {
const group = await client.conversations.newGroup(addresses, {
name: `group ${i}`,
imageUrlSquare: `www.group${i}.com`,
description: `group ${i}`,
})
groups.push(group)
for (let i = 0; i < numMessages; i++) {
await group.send({ text: `Message ${i}` })
}
}
return groups
}

test('can make a MLS V3 client', async () => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const keyBytes = new Uint8Array([
Expand Down Expand Up @@ -91,16 +69,21 @@ test('can revoke all other installations', async () => {

const inboxState = await alix2.inboxState(true)
assert(
inboxState.installationIds.length === 2,
`installationIds length should be 2 but was ${inboxState.installationIds.length}`
inboxState.installations.length === 2,
`installations length should be 2 but was ${inboxState.installations.length}`
)

await alix2.revokeAllOtherInstallations(alixWallet)

const inboxState2 = await alix2.inboxState(true)
assert(
inboxState2.installationIds.length === 1,
`installationIds length should be 1 but was ${inboxState2.installationIds.length}`
inboxState2.installations.length === 1,
`installations length should be 1 but was ${inboxState2.installations.length}`
)

assert(
inboxState2.installations[0].createdAt !== undefined,
`installations createdAt should not be undefined`
)
return true
})
Expand Down Expand Up @@ -240,34 +223,6 @@ test('can make a MLS V3 client with encryption key and database directory', asyn
return true
})

test('testing large group listing with metadata performance', async () => {
const [alixClient, boClient] = await createClients(2)

await createGroups(alixClient, [boClient], 50, 10)

let start = Date.now()
let groups = await alixClient.conversations.listGroups()
let end = Date.now()
console.log(`Alix loaded ${groups.length} groups in ${end - start}ms`)

start = Date.now()
await alixClient.conversations.syncGroups()
end = Date.now()
console.log(`Alix synced ${groups.length} groups in ${end - start}ms`)

start = Date.now()
await boClient.conversations.syncGroups()
end = Date.now()
console.log(`Bo synced ${groups.length} groups in ${end - start}ms`)

start = Date.now()
groups = await boClient.conversations.listGroups()
end = Date.now()
console.log(`Bo loaded ${groups.length} groups in ${end - start}ms`)

return true
})

test('can drop a local database', async () => {
const [client, anotherClient] = await createClients(2)

Expand Down Expand Up @@ -405,6 +360,54 @@ test('production MLS V3 client creation does not error', async () => {
return true
})

test('can cancel streams', async () => {
const [alix, bo] = await createClients(2)
let messageCallbacks = 0

await bo.conversations.streamAllMessages(async () => {
messageCallbacks++
}, true)

const group = await alix.conversations.newGroup([bo.address])
await group.send('hello')
await delayToPropogate()

assert(
messageCallbacks === 1,
'message stream should have received 1 message'
)

await bo.conversations.cancelStreamAllMessages()
await delayToPropogate()

await group.send('hello')
await group.send('hello')
await group.send('hello')

await delayToPropogate()

assert(
messageCallbacks === 1,
'message stream should still only received 1 message'
)

await bo.conversations.streamAllMessages(async () => {
messageCallbacks++
}, true)

await delayToPropogate()

await group.send('hello')
await delayToPropogate()

assert(
messageCallbacks === 2,
'message stream should have received 2 message'
)

return true
})

test('group message delivery status', async () => {
const [alixClient, boClient] = await createClients(2)
const alixGroup = await alixClient.conversations.newGroup([boClient.address])
Expand Down Expand Up @@ -958,54 +961,6 @@ test('can remove and add members from a group by inbox id', async () => {
return true
})

test('can cancel streams', async () => {
const [alix, bo] = await createClients(2)
let messageCallbacks = 0

await bo.conversations.streamAllMessages(async () => {
messageCallbacks++
}, true)

const group = await alix.conversations.newGroup([bo.address])
await group.send('hello')
await delayToPropogate()

assert(
messageCallbacks === 1,
'message stream should have received 1 message'
)

await bo.conversations.cancelStreamAllMessages()
await delayToPropogate()

await group.send('hello')
await group.send('hello')
await group.send('hello')

await delayToPropogate()

assert(
messageCallbacks === 1,
'message stream should still only received 1 message'
)

await bo.conversations.streamAllMessages(async () => {
messageCallbacks++
}, true)

await delayToPropogate()

await group.send('hello')
await delayToPropogate()

assert(
messageCallbacks === 2,
'message stream should have received 2 message'
)

return true
})

test('can stream both groups and messages at same time', async () => {
const [alix, bo] = await createClients(2)

Expand Down Expand Up @@ -2218,7 +2173,7 @@ test('can create new installation without breaking group', async () => {

test('can list many groups members in parallel', async () => {
const [alix, bo] = await createClients(2)
const groups: Group[] = await createGroups(alix, [bo], 20, 0)
const groups: Group[] = await createGroups(alix, [bo], 20)

try {
await Promise.all(groups.slice(0, 10).map((g) => g.membersList()))
Expand All @@ -2237,7 +2192,7 @@ test('can list many groups members in parallel', async () => {

test('can sync all groups', async () => {
const [alix, bo] = await createClients(2)
const groups: Group[] = await createGroups(alix, [bo], 50, 0)
const groups: Group[] = await createGroups(alix, [bo], 50)

const alixGroup = groups[0]
await bo.conversations.syncGroups()
Expand Down
20 changes: 19 additions & 1 deletion example/src/tests/test-utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Platform } from 'expo-modules-core'
import { Client, GroupUpdatedCodec } from 'xmtp-react-native-sdk'
import { Client, GroupUpdatedCodec, Group } from 'xmtp-react-native-sdk'

export type Test = {
name: string
Expand Down Expand Up @@ -65,3 +65,21 @@ export async function createV3TestingClients(): Promise<Client[]> {
clients.push(alix, bo, caro)
return clients
}

export async function createGroups(
client: Client,
peers: Client[],
numGroups: number
): Promise<Group[]> {
const groups = []
const addresses: string[] = peers.map((client) => client.address)
for (let i = 0; i < numGroups; i++) {
const group = await client.conversations.newGroup(addresses, {
name: `group ${i}`,
imageUrlSquare: `www.group${i}.com`,
description: `group ${i}`,
})
groups.push(group)
}
return groups
}
Loading

0 comments on commit 510bf6b

Please sign in to comment.