Skip to content

Commit

Permalink
Fix Channel type being erased and custom message handling (#154)
Browse files Browse the repository at this point in the history
* Fix Channel type being erased on update
* fix: custom events sending/receiving in JS
* PubNub js 0.9.6 release.

---------

Co-authored-by: PubNub Release Bot <[email protected]>
  • Loading branch information
wkal-pubnub and pubnub-release-bot authored Jan 2, 2025
1 parent 03aeb48 commit 1ba266d
Show file tree
Hide file tree
Showing 23 changed files with 155 additions and 52 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ build/
**/*.podspec
node_modules
js-chat/dist
js-chat/dist-test
test.properties

### IntelliJ IDEA ###
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ SONATYPE_HOST=DEFAULT
SONATYPE_AUTOMATIC_RELEASE=false
GROUP=com.pubnub
POM_PACKAGING=jar
VERSION_NAME=0.9.5
VERSION_NAME=0.9.6

POM_NAME=PubNub Chat SDK
POM_DESCRIPTION=This SDK offers a set of handy methods to create your own feature-rich chat or add a chat to your existing application.
Expand Down
9 changes: 8 additions & 1 deletion js-chat/.pubnub.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
---
name: pubnub-js-chat
version: 0.9.5
version: 0.9.6
scm: github.com/pubnub/js-chat
schema: 1
files:
- lib/dist/index.js
changelog:
- date: 2025-01-02
version: 0.9.6
changes:
- type: bug
text: "Channel type was erased (set to `null`) on edits to other Channel fields."
- type: bug
text: "Custom events sending/receiving in JS."
- date: 2024-12-20
version: 0.9.5
changes:
Expand Down
2 changes: 1 addition & 1 deletion js-chat/jest.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module.exports = {
bail: false,
reporters: [["jest-silent-reporter", { "useDots": true }], "jest-junit", "summary"],
reporters: ["default", "jest-junit", "summary"],
testTimeout: 10000
}
6 changes: 3 additions & 3 deletions js-chat/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"NOTICE"
],
"scripts": {
"test": "jest --forceExit",
"test": "cp -r dist/ dist-test && rollup --config rollup-test.config.mjs && jest --forceExit",
"build": "rollup -c",
"dev": "tsc -w"
},
Expand All @@ -41,10 +41,10 @@
"module": "dist/index.es.js",
"types": "dist/index.d.ts",
"react-native": "dist/index.es.js",
"version": "0.9.5",
"version": "0.9.6",
"name": "@pubnub/chat",
"dependencies": {
"pubnub": "8.2.8",
"pubnub": "8.3.1",
"format-util": "^1.0.5"
}
}
2 changes: 1 addition & 1 deletion js-chat/package_template.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"dist", "NOTICE"
],
"scripts": {
"test": "jest --forceExit",
"test": "cp -r dist/ dist-test && rollup --config rollup-test.config.mjs && jest --forceExit",
"build": "rollup -c",
"dev": "tsc -w"
},
Expand Down
20 changes: 20 additions & 0 deletions js-chat/rollup-test.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import pkg from "./package.json" assert { type: "json" }

export default [
{
input: "./main.mjs",
external: ["pubnub", "format-util"],
output: [
{
file: "dist-test/index.js",
format: "cjs",
},
{
file: "dist-test/index.es.js",
format: "esm",
},
],
plugins: [
],
},
]
36 changes: 34 additions & 2 deletions js-chat/tests/channel.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
MessageDraft,
INTERNAL_MODERATION_PREFIX,
Membership,
} from "../dist"
} from "../dist-test"
import {
sleep,
extractMentionedUserIds,
Expand Down Expand Up @@ -350,6 +350,7 @@ describe("Channel test", () => {

test("should stream channel updates and invoke the callback", async () => {
let updatedChannel
channel = await channel.update({ type: "public" })
const name = "Updated Channel"
const callback = jest.fn((chanel) => (updatedChannel = chanel))

Expand All @@ -360,7 +361,7 @@ describe("Channel test", () => {
expect(callback).toHaveBeenCalled()
expect(callback).toHaveBeenCalledWith(updatedChannel)
expect(updatedChannel.name).toEqual(name)

expect(updatedChannel.type).toEqual(channel.type)
stopUpdates()
})

Expand Down Expand Up @@ -1229,4 +1230,35 @@ describe("Channel test", () => {
let result = await chat.getChannels({ limit: 2, filter: `type == 'public'` })
expect(result.channels.length).toBe(2)
})

test("send custom event", async () => {
const inviteCallback = jest.fn()
const unsubscribe = chat.listenForEvents({
channel: channel.id,
type: "custom",
method: "publish",
callback: inviteCallback,
})

await sleep(1000)
await chat.emitEvent({
channel: channel.id,
type: 'custom',
method: 'publish',
payload: {
action: "action",
body: "payload"
}
})
await sleep(2000)
expect(inviteCallback).toHaveBeenCalledTimes(1)
expect(inviteCallback).toHaveBeenCalledWith(
expect.objectContaining({
payload: expect.objectContaining({
action: "action",
body: "payload"
}),
})
)
})
})
2 changes: 1 addition & 1 deletion js-chat/tests/message-draft-v2.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Channel, Chat, MessageDraftV2, MixedTextTypedElement } from "../dist"
import { Channel, Chat, MessageDraftV2, MixedTextTypedElement } from "../dist-test"
import {
createChatInstance,
createRandomChannel,
Expand Down
2 changes: 1 addition & 1 deletion js-chat/tests/message-draft.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Channel, Chat } from "../dist"
import { Channel, Chat } from "../dist-test"
import {
createChatInstance,
createRandomChannel,
Expand Down
2 changes: 1 addition & 1 deletion js-chat/tests/message.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
CryptoUtils,
CryptoModule,
MessageDTOParams,
} from "../dist"
} from "../dist-test"
import {
createChatInstance,
createRandomChannel,
Expand Down
6 changes: 3 additions & 3 deletions js-chat/tests/testUtils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// lib/tests/testUtils.ts
import { Chat } from "../dist"
import { Channel } from "../dist"
import { Chat } from "../dist-test"
import { Channel } from "../dist-test"
import * as dotenv from "dotenv"
import { nanoid } from "nanoid"
import { User } from "../dist"
import { User } from "../dist-test"

dotenv.config()

Expand Down
2 changes: 1 addition & 1 deletion js-chat/tests/timetoken.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TimetokenUtils } from "../dist"
import { TimetokenUtils } from "../dist-test"

describe("Channel test", () => {
test("should convert unix timestamp to PubNub timetoken", () => {
Expand Down
2 changes: 1 addition & 1 deletion js-chat/tests/typing-indicator.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Channel, Chat } from "../dist"
import { Channel, Chat } from "../dist-test"
import { createChatInstance, createRandomChannel, sleep } from "./utils"

describe("Typing indicator test", () => {
Expand Down
4 changes: 2 additions & 2 deletions js-chat/tests/user.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Chat, INTERNAL_MODERATION_PREFIX, User } from "../dist"
import { Chat, INTERNAL_MODERATION_PREFIX, User } from "../dist-test"
import { createChatInstance, createRandomUser, sleep } from "./utils"
import { INTERNAL_ADMIN_CHANNEL } from "../dist"
import { INTERNAL_ADMIN_CHANNEL } from "../dist-test"

describe("User test", () => {
let chat: Chat
Expand Down
6 changes: 3 additions & 3 deletions js-chat/tests/utils.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// lib/tests/testUtils.ts
import { Chat, MessageDraft, Channel, Message, ChatConfig } from "../dist"
import { Chat, MessageDraft, Channel, Message, ChatConfig } from "../dist-test"
import * as dotenv from "dotenv"
import { User } from "../dist"
import { MixedTextTypedElement } from "../dist"
import { User } from "../dist-test"
import { MixedTextTypedElement } from "../dist-test"
import PubNub from "pubnub"

dotenv.config()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import com.pubnub.chat.internal.TYPE_OF_MESSAGE
import com.pubnub.chat.internal.TYPE_OF_MESSAGE_IS_CUSTOM
import com.pubnub.chat.internal.defaultGetMessagePublishBody
import com.pubnub.chat.internal.serialization.PNDataEncoder
import com.pubnub.chat.types.EventContent
Expand Down Expand Up @@ -53,7 +55,7 @@ internal fun EventContent.encodeForSending(
var finalMessage = if (this is EventContent.Custom) {
buildMap<String, Any?> {
putAll(data)
put("type", "custom")
put(TYPE_OF_MESSAGE, TYPE_OF_MESSAGE_IS_CUSTOM)
}
} else {
PNDataEncoder.encode(this) as Map<String, Any?>
Expand Down
4 changes: 2 additions & 2 deletions pubnub-chat-impl/src/jsMain/kotlin/ChannelJs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ open class ChannelJs internal constructor(internal val channel: Channel, interna
fun update(data: ChannelFields): Promise<ChannelJs> {
return channel.update(
data.name,
convertToCustomObject(data.custom),
data.custom?.let { convertToCustomObject(it) },
data.description,
data.status,
ChannelType.from(data.type)
data.type?.let { ChannelType.from(it) }
).then {
it.asJs(chatJs)
}.asPromise()
Expand Down
50 changes: 36 additions & 14 deletions pubnub-chat-impl/src/jsMain/kotlin/ChatJs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.pubnub.api.createJsonElement
import com.pubnub.chat.internal.ChatImpl
import com.pubnub.chat.internal.ChatInternal
import com.pubnub.chat.internal.PUBNUB_CHAT_VERSION
import com.pubnub.chat.internal.TYPE_OF_MESSAGE_IS_CUSTOM
import com.pubnub.chat.internal.serialization.PNDataEncoder
import com.pubnub.chat.restrictions.Restriction
import com.pubnub.chat.types.ChannelMentionData
Expand All @@ -14,8 +15,10 @@ import com.pubnub.chat.types.CreateGroupConversationResult
import com.pubnub.chat.types.EmitEventMethod
import com.pubnub.chat.types.EventContent
import com.pubnub.chat.types.ThreadMentionData
import com.pubnub.kmp.JsMap
import com.pubnub.kmp.createJsObject
import com.pubnub.kmp.then
import com.pubnub.kmp.toMap
import kotlin.js.Json
import kotlin.js.Promise
import kotlin.js.json
Expand All @@ -31,26 +34,39 @@ class ChatJs internal constructor(val chat: ChatInternal, val config: ChatConfig
val channel: String = event.channel ?: event.user
val type = event.type
val payload = event.payload
payload.type = type

val method = if (event.method == EmitEventMethod.SIGNAL.toJs()) {
EmitEventMethod.SIGNAL
} else {
EmitEventMethod.PUBLISH
}

val eventContent = if (type == TYPE_OF_MESSAGE_IS_CUSTOM) {
EventContent.Custom((payload as JsMap<Any?>).toMap(), method)
} else {
payload.type = type
PNDataEncoder.decode(createJsonElement(payload))
}
return chat.emitEvent(
channel,
PNDataEncoder.decode(createJsonElement(payload))
eventContent
).then { it.toPublishResponse() }.asPromise()
}

fun listenForEvents(event: ListenForEventsParams): () -> Unit {
val klass = when (event.type) {
"typing" -> EventContent.Typing::class
"report" -> EventContent.Report::class
"receipt" -> EventContent.Receipt::class
"mention" -> EventContent.Mention::class
"invite" -> EventContent.Invite::class
"custom" -> EventContent.Custom::class
"moderation" -> EventContent.Moderation::class
EventContent.Typing.serializer().descriptor.serialName -> EventContent.Typing::class
EventContent.Report.serializer().descriptor.serialName -> EventContent.Report::class
EventContent.Receipt.serializer().descriptor.serialName -> EventContent.Receipt::class
EventContent.Mention.serializer().descriptor.serialName -> EventContent.Mention::class
EventContent.Invite.serializer().descriptor.serialName -> EventContent.Invite::class
TYPE_OF_MESSAGE_IS_CUSTOM -> EventContent.Custom::class
EventContent.Moderation.serializer().descriptor.serialName -> EventContent.Moderation::class
EventContent.TextMessageContent.serializer().descriptor.serialName -> EventContent.TextMessageContent::class
else -> throw IllegalArgumentException("Unknown event type ${event.type}")
}
val channel: String = event.channel ?: event.user!!
val method = if (event.method == "signal") {
val method = if (event.method == EmitEventMethod.SIGNAL.toJs()) {
EmitEventMethod.SIGNAL
} else {
EmitEventMethod.PUBLISH
Expand Down Expand Up @@ -89,7 +105,7 @@ class ChatJs internal constructor(val chat: ChatInternal, val config: ChatConfig
data.externalId,
data.profileUrl,
data.email,
convertToCustomObject(data.custom),
data.custom?.let { convertToCustomObject(data.custom) },
data.status,
data.type
).then { it.asJs(this@ChatJs) }.asPromise()
Expand All @@ -102,7 +118,7 @@ class ChatJs internal constructor(val chat: ChatInternal, val config: ChatConfig
data.externalId,
data.profileUrl,
data.email,
convertToCustomObject(data.custom),
data.custom?.let { convertToCustomObject(data.custom) },
data.status,
data.type
).then { it.asJs(this@ChatJs) }.asPromise()
Expand Down Expand Up @@ -142,10 +158,10 @@ class ChatJs internal constructor(val chat: ChatInternal, val config: ChatConfig
return chat.updateChannel(
id,
data.name,
convertToCustomObject(data.custom),
data.custom?.let { convertToCustomObject(it) },
data.description,
data.status,
ChannelType.from(data.type)
data.type?.let { ChannelType.from(data.type) }
).then { it.asJs(this@ChatJs) }.asPromise()
}

Expand Down Expand Up @@ -391,3 +407,9 @@ class ChatJs internal constructor(val chat: ChatInternal, val config: ChatConfig
}
}
}

private fun EmitEventMethod.toJs() = if (this == EmitEventMethod.SIGNAL) {
"signal"
} else {
"publish"
}
4 changes: 2 additions & 2 deletions pubnub-chat-impl/src/jsMain/kotlin/MembershipJs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ class MembershipJs internal constructor(internal val membership: Membership, int

val lastReadMessageTimetoken: String? get() = membership.lastReadMessageTimetoken?.toString()

fun update(custom: dynamic): Promise<MembershipJs> {
return membership.update(convertToCustomObject(custom?.custom))
fun update(custom: UpdateMembershipParams?): Promise<MembershipJs> {
return membership.update(custom?.custom?.let { convertToCustomObject(it) })
.then { it.asJs(chatJs) }
.asPromise()
}
Expand Down
Loading

0 comments on commit 1ba266d

Please sign in to comment.