Skip to content

Commit 3ec9a47

Browse files
authored
Merge pull request #2766 from ably/chat/move-to-pv4
Chat: Move to V4 Message Structure
2 parents cac14dc + 8c65e07 commit 3ec9a47

File tree

7 files changed

+90
-124
lines changed

7 files changed

+90
-124
lines changed

examples/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@
100100
"spaces-member-location-react": "yarn workspace spaces-member-location-react dev"
101101
},
102102
"dependencies": {
103-
"@ably/chat": "^0.13.0",
104-
"@ably/chat-react-ui-components": "^0.1.1",
103+
"@ably/chat": "^0.14.0",
104+
"@ably/chat-react-ui-components": "^0.1.2",
105105
"@ably/spaces": "^0.4.0",
106106
"ably": "^2.9.0",
107107
"cors": "^2.8.5",

examples/yarn.lock

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22
# yarn lockfile v1
33

44

5-
"@ably/chat-react-ui-components@^0.1.1":
6-
version "0.1.1"
7-
resolved "https://registry.yarnpkg.com/@ably/chat-react-ui-components/-/chat-react-ui-components-0.1.1.tgz#102c20c00b110fa26e3663a92eb6767fa9336783"
8-
integrity sha512-OqpKp2kXKNqkfpSYVomU5R1TIoc/k+HDxQzbtAJtYuH67DEp7JgNi8Xqidv0wwuFfaVPzNIlWwyhbcwIVJY/LQ==
5+
"@ably/chat-react-ui-components@^0.1.2":
6+
version "0.1.2"
7+
resolved "https://registry.yarnpkg.com/@ably/chat-react-ui-components/-/chat-react-ui-components-0.1.2.tgz#692919b0d1e66a0b6267057918a4fd6f4354bd1d"
8+
integrity sha512-WEEFburLyNieOb3Fvu/KXO1h/M93cUiAo8hsp3EoJOT1y0rFcVLdnDKDm+BPIHCT0PIVMr1sWZJQ9anuqT0y6A==
99
dependencies:
1010
clsx "^2.1.1"
1111

12-
"@ably/chat@^0.13.0":
13-
version "0.13.0"
14-
resolved "https://registry.yarnpkg.com/@ably/chat/-/chat-0.13.0.tgz#5b6391fd22b684c3ce896dac3d1b821de14f1de8"
15-
integrity sha512-YbTzSn6H821qP6XkqQZwUe4+3IclHuLn15hXBl+fFnu0bHeh9hT4JQyB7t/nGlv4gvCCQpHIRhkksxqGLWiTBg==
12+
"@ably/chat@^0.14.0":
13+
version "0.14.0"
14+
resolved "https://registry.yarnpkg.com/@ably/chat/-/chat-0.14.0.tgz#8a7d7be46301977bd2cbd01021f67be8980d0370"
15+
integrity sha512-9QsJdHVcyYDP0cTHXh7towHI9tM+SbmEMMVK10+0y1N1epl6FBSEeBDMn1fH5i73nxbKleUxjBltWiXlQz4InA==
1616
dependencies:
1717
async-mutex "^0.5.0"
1818
dequal "^2.0.3"

src/components/Examples/ExamplesRenderer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const getDependencies = (id: string, products: string[], activeLanguage: Languag
4242
minifaker: '1.34.1',
4343
...(products.includes('auth') ? { cors: '^2.8.5' } : {}),
4444
...(products.includes('chat')
45-
? { '@ably/chat': '^0.13.0', '@ably/chat-react-ui-components': '^0.1.1', clsx: '^2.1.1' }
45+
? { '@ably/chat': '^0.14.0', '@ably/chat-react-ui-components': '^0.1.2', clsx: '^2.1.1' }
4646
: {}),
4747
...(products.includes('spaces') ? { '@ably/spaces': '^0.4.0' } : {}),
4848
...(id === 'spaces-component-locking' ? { 'usehooks-ts': '^3.1.0' } : {}),

src/data/languages/languageData.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ export default {
2424
laravel: '1.0',
2525
},
2626
chat: {
27-
javascript: '0.13',
28-
react: '0.13',
27+
javascript: '0.14',
28+
react: '0.14',
2929
swift: '0.6',
3030
kotlin: '0.7',
3131
},

src/pages/docs/chat/rooms/media.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ Use a function or component to display the message and its media:
187187
function createMessageDOM(message) {
188188
const container = document.createElement("div");
189189
container.setAttribute('data-message-serial', message.serial)
190-
container.setAttribute('data-message-version', message.version)
190+
container.setAttribute('data-message-version', message.version?.serial)
191191

192192
const text = document.createElement("div");
193193
text.innerText = message.text;

src/pages/docs/chat/rooms/messages.mdx

Lines changed: 47 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,12 @@ The following is the structure of a message:
6767
"text": "What a shot!",
6868
"headers": {},
6969
"metadata": {},
70-
"createdAt": new Date("2024-06-12T11:37:59.988Z"),
71-
"action": "message.create",
72-
"version": "01826232498871-001@abcdefghij:001",
7370
"timestamp": new Date("2024-06-12T11:37:59.988Z"),
74-
"operation": {},
71+
"action": "message.create",
72+
"version": {
73+
"serial": "01826232498871-001@abcdefghij:001",
74+
"timestamp": new Date("2024-06-12T11:37:59.988Z")
75+
}
7576
}
7677
```
7778
</Code>
@@ -85,14 +86,14 @@ The following are the properties of a message:
8586
| text | The message contents. | String |
8687
| headers | Optional headers for adding additional information to a message, such as the relative timestamp of a livestream video, or flagging a message as important. Do not use the headers for authoritative information. There is no server-side validation. When reading headers treat them like user input. | Object |
8788
| metadata | Optional additional metadata about the message, such as animations, effects or links to other resources such as images. This information is not read by Ably. Do not use metadata for authoritative information. There is no server-side validation. When reading metadata treat it like user input. | Object |
88-
| createdAt | The time the message was created. | Date |
89+
| timestamp | The time the message was created. | Date |
8990
| action | The latest action performed on this message, such as `message.create`, `message.update` or `message.delete`. | String |
90-
| version | An Ably-generated ID used to uniquely identify the version of the message. It provides a deterministic global ordering of message versions. The `version` is identical to `serial` if the action is `message.create`. | String |
91-
| timestamp | The time the action was performed. It will be identical to `createdAt` if the action is a `message.create`. | Date |
92-
| operation | For updates and deletions, this provides additional details about the action. It may contain the following properties: | Object or undefined |
93-
| | `clientId`: The client identifier of the user associated with the action. | String or undefined |
94-
| | `description`: Optional description for the action. | String or undefined |
95-
| | `metadata`: Optional additional metadata about the action. | Object or undefined |
91+
| version | Contains information about the current version of the message. For `message.create` actions, only `serial` and `timestamp` are set. For `message.update` and `message.delete` actions, additional fields are included. | Object |
92+
| | `serial`: An Ably-generated ID used to uniquely identify the version of the message. It provides a deterministic global ordering of message versions. The `version.serial` is identical to `serial` if the action is `message.create`. | String |
93+
| | `timestamp`: The time the action was performed. It will be identical to `timestamp` if the action is a `message.create`. | Date |
94+
| | `clientId`: The client identifier of the user that created this version of the message. Only set for `message.update` and `message.delete` actions. | String or undefined |
95+
| | `description`: Optional description provided by the client that created this message version. Only set for `message.update` and `message.delete` actions. | String or undefined |
96+
| | `metadata`: Optional description provided by the client that created this message version. Only set for `message.update` and `message.delete` actions. | Object or undefined |
9697

9798
See [below](#global-ordering) for more information on how to apply deterministic global ordering to the chat messages in your application.
9899

@@ -390,27 +391,30 @@ The following is the structure of an updated message:
390391
"text": "What a shot! Edit: I meant to say 'What a dunk!'",
391392
"headers": {},
392393
"metadata": {},
393-
"createdAt": new Date("2024-06-12T11:37:59.988Z")S,
394+
"timestamp": new Date("2024-06-12T11:37:59.988Z"),
394395
"action": "message.update",
395-
"version": "01826232498871-001@abcdefghij:001",
396-
"timestamp": new Date("2024-11-21T15:49:25.425Z"),
397-
"operation": {
396+
"version": {
397+
"serial": "01826232498871-001@abcdefghij:001",
398+
"timestamp": new Date("2024-11-21T15:49:25.425Z"),
398399
"clientId": "basketLover014",
399400
"description": "Message updated by client",
400401
"metadata": {}
401-
},
402+
}
402403
}
403404
```
404405
</Code>
405406

406407
The updated message response is identical to the structure of a message, with the following differences:
407408

408-
| Property | Description |
409-
| -------- | ----------- |
410-
| action | Set to `message.update`. |
411-
| version | Set to the serial of the update action. |
412-
| timestamp | Set to the time the message was updated. |
413-
| operation | Set to the details the actioning client provided in the request. |
409+
| Property | Description | Type |
410+
| -------- | ----------- | ---- |
411+
| action | Set to `message.update`. | string |
412+
| version | Contains additional fields compared to `message.create` action: | object |
413+
| | `serial`: Set to the serial of the update action. | string |
414+
| | `timestamp`: Set to the time the message was updated. | Date |
415+
| | `clientId`: The client identifier of the user who performed the update. | String or undefined |
416+
| | `description`: Optional description provided in the update request. | String or undefined |
417+
| | `metadata`: Optional metadata provided in the update request. | Object or undefined |
414418

415419
## Delete a message <a id="delete"/>
416420

@@ -489,7 +493,6 @@ Use the [`useMessages`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typed
489493
<Code>
490494
```javascript
491495
import { ChatMessageEventType } from '@ably/chat';
492-
493496
const {unsubscribe} = room.messages.subscribe((event) => {
494497
switch (event.type) {
495498
case ChatMessageEventType.Created:
@@ -586,36 +589,39 @@ The following is the structure of a deleted message:
586589
"text": "",
587590
"headers": {},
588591
"metadata": {},
589-
"createdAt": new Date("2024-06-12T11:37:59.988Z"),
592+
"timestamp": new Date("2024-06-12T11:37:59.988Z"),
590593
"action": "message.delete",
591-
"version": "01826232498871-001@abcdefghij:001",
592-
"timestamp": new Date("2024-11-21T15:49:25.425Z"),
593-
"operation": {
594+
"version": {
595+
"serial": "01826232498871-001@abcdefghij:001",
596+
"timestamp": new Date("2024-11-21T15:49:25.425Z"),
594597
"clientId": "basketLover014",
595598
"description": "Message deleted by client",
596599
"metadata": {}
597-
},
600+
}
598601
}
599602
```
600603
</Code>
601604

602605
The deleted message response is identical to the structure of a message, with the following differences:
603606

604-
| Property | Description |
605-
| -------- | ----------- |
606-
| action | Set to `message.delete`. |
607-
| version | Set to the serial of the deletion action. |
608-
| timestamp | Set to the time the message was deleted. |
609-
| operation | Set to the details the actioning client provided in the request. |
610-
| text | Set to the empty string. |
611-
| metadata | Set to the empty object. |
612-
| headers | Set to the empty object. |
607+
| Property | Description | Type |
608+
| -------- | ----------- | ---- |
609+
| action | Set to `message.delete`. | string |
610+
| version | Contains additional fields compared to `message.create` action: | object |
611+
| | `serial`: Set to the serial of the deletion action. | string |
612+
| | `timestamp`: Set to the time the message was deleted. | Date |
613+
| | `clientId`: The client identifier of the user who performed the deletion. | String or undefined |
614+
| | `description`: Optional description provided in the delete request. | String or undefined |
615+
| | `metadata`: Optional metadata provided in the delete request. | Object or undefined |
616+
| text | Set to the empty string. | string |
617+
| metadata | Set to the empty object. | Object |
618+
| headers | Set to the empty object. | Object |
613619

614620
## Ordering chat message events <a id="global-ordering"/>
615621

616622
Chat messages and update events are delivered in realtime to clients connected to a particular region in the order in which that region receives them. The order in which a given region receives these events may be different from the "global" order of events, i.e. the true time-based order in which events happened.
617623

618-
Chat messages are uniquely identified by their `serial` and may have multiple `versions` as a result of edit and delete operations. Both `serial` and `version` are lexicographically sortable strings. This means they can be used to enforce a deterministic global ordering based on string comparison.
624+
Chat messages are uniquely identified by their `serial` and may have multiple `versions` as a result of edit and delete operations. Both `serial` and `version.serial` are lexicographically sortable strings. This means they can be used to enforce a deterministic global ordering based on string comparison.
619625

620626
### Ordering new messages <a id="ordering-new"/>
621627

@@ -625,15 +631,15 @@ The `Message` object also has convenience methods [`before`](https://sdk.ably.co
625631

626632
### Ordering updates and deletes <a id="ordering-update-delete"/>
627633

628-
Applying an action to a message produces a new version, which is uniquely identified by the `version` property. When two message instances share the same `serial` they represent the same chat message, but they can represent different versions. Lexicographically sorting the two message instances by the `version` property gives the global order of the message versions: the message instance with a greater `version` is newer, the message instance with a lower `version` is older, and if their `version` is equal then they are the same version.
634+
Applying an action to a message produces a new version, which is uniquely identified by the `version.serial` property. When two message instances share the same `serial` they represent the same chat message, but they can represent different versions. Lexicographically sorting the two message instances by the `version.serial` property gives the global order of the message versions: the message instance with a greater `version.serial` is newer, the message instance with a lower `version.serial` is older, and if their `version.serial` is equal then they are the same version.
629635

630-
The `Message` object also has convenience methods [`isOlderVersionOf`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Message.html#isolderversionof), [`isNewerVersionOf`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Message.html#isnewerversionof) and [`isSameVersionAs`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Message.html#issameversionas) which provide the same comparison.
636+
The `Message` object also has convenience methods [`isOlderVersionOf`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Message.html#isolderversionof), [`isNewerVersionOf`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Message.html#isnewerversionof) and [`isSameVersionAs`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Message.html#issameversionas) which provide the same comparison by comparing the `version.serial` values internally.
631637

632638
Update and Delete events provide the message payload without message reactions. To correctly use message reactions, always use the [`with()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Message.html#with) method to apply the event to the message instance.
633639

634640
## Keep messages updated using with() <a id="keep-messages-updated"/>
635641

636-
The [`Message`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Message.html) object has a method [`with`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Message.html#with) that takes a [`MessageEvent`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.MessageEvent.html), automatically compares versions, and returns the newest `Message` instance. For updates and deletes, if `with` is called with an event that is older than the message, the message is returned. If it is called with a newer event, the message from the event is returned. For message reaction events, the reactions will be correctly applied to the returned message.
642+
The [`Message`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Message.html) object has a method [`with`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Message.html#with) that takes a [`MessageEvent`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.MessageEvent.html), automatically compares version serials, and returns the newest `Message` instance. For updates and deletes, if `message.with(event)` is called with an `event` that has an older `version.serial` than the `message`, then the `message` is returned unchanged. If it is called with a newer event (greater `version.serial`), then the message from the event is returned. For message reaction events, the reactions will be correctly applied to the returned message.
637643

638644
`Message.with()` also ensures that reactions from existing messages are copied over to the new message instance in the case of UPDATEs or DELETEs.
639645

0 commit comments

Comments
 (0)