Skip to content

Commit

Permalink
Implement TM2p,k,o (new mutable-message fields)
Browse files Browse the repository at this point in the history
Tests for TM2p pending serverside implementation of field name changes
being deployed
  • Loading branch information
SimonWoolf committed Nov 26, 2024
1 parent 2674359 commit 18cd170
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 16 deletions.
22 changes: 14 additions & 8 deletions ably.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2332,34 +2332,40 @@ export interface Message {
name?: string;
/**
* Timestamp of when the message was received by Ably, as milliseconds since the Unix epoch.
* (This is the timestamp of the current version of the message)
*/
timestamp?: number;
/**
* The action type of the message, one of the {@link MessageAction} enum values.
*/
action?: MessageAction;
/**
* This message's unique serial.
* This message's unique serial (an identifier that will be the same in all future
* updates of this message).
*/
serial?: string;
/**
* The serial of the message that this message is a reference to.
* If this message references another, the serial of that message.
*/
refSerial?: string;
/**
* The type of reference this message is, in relation to the message it references.
* If this message references another, the type of reference that is.
*/
refType?: string;
/**
* If an `update` operation was applied to this message, this will be the timestamp the update occurred.
* The timestamp of the very first version of a given message (will differ from
* createdAt only if the message has been updated or deleted).
*/
updatedAt?: number;
createdAt?: number;
/**
* The serial of the operation that updated this message.
* The version of the message, lexicographically-comparable with other versions (that
* share the same serial) Will differ from the serial only if the message has been
* updated or deleted.
*/
updateSerial?: string;
version?: string;
/**
* If this message resulted from an operation, this will contain the operation details.
* In the case of an updated or deleted message, this will contain metadata about the
* update or delete operation.
*/
operation?: Operation;
}
Expand Down
8 changes: 7 additions & 1 deletion src/common/lib/client/realtimechannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,7 @@ class RealtimeChannel extends EventEmitter {
firstMessage = messages[0],
lastMessage = messages[messages.length - 1],
id = message.id,
channelSerial = message.channelSerial,
connectionId = message.connectionId,
timestamp = message.timestamp;

Expand Down Expand Up @@ -670,9 +671,14 @@ class RealtimeChannel extends EventEmitter {
if (!msg.connectionId) msg.connectionId = connectionId;
if (!msg.timestamp) msg.timestamp = timestamp;
if (!msg.id) msg.id = id + ':' + i;
if (!msg.version) msg.version = channelSerial + ':' + i.toString().padStart(3, '0');

// already done in fromWireProtocol -- but for realtime messages the source
// fields might be copied from the protocolmessage, so need to do it again
msg.expandFields();
}
this._lastPayload.messageId = lastMessage.id;
this._lastPayload.protocolMessageChannelSerial = message.channelSerial;
this._lastPayload.protocolMessageChannelSerial = channelSerial;
this.onEvent(messages);
break;
}
Expand Down
29 changes: 22 additions & 7 deletions src/common/lib/types/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,9 @@ export function fromValues(values: Properties<Message>): Message {

export function fromWireProtocol(values: WireProtocolMessage): Message {
const action = toMessageActionString(values.action as number) || values.action;
return Object.assign(new Message(), { ...values, action });
const res = Object.assign(new Message(), { ...values, action });
res.expandFields();
return res;
}

export function fromValuesArray(values: Properties<Message>[]): Message[] {
Expand Down Expand Up @@ -315,8 +317,8 @@ class Message {
serial?: string;
refSerial?: string;
refType?: string;
updatedAt?: number;
updateSerial?: string;
createdAt?: number;
version?: string;
operation?: API.Operation;

/**
Expand Down Expand Up @@ -352,14 +354,27 @@ class Message {
action: toMessageActionNumber(this.action as API.MessageAction) || this.action,
refSerial: this.refSerial,
refType: this.refType,
updatedAt: this.updatedAt,
updateSerial: this.updateSerial,
createdAt: this.createdAt,
version: this.version,
operation: this.operation,
encoding,
data,
};
}

expandFields() {
if (this.action === 'message.create') {
// TM2k
if (this.version && !this.serial) {
this.serial = this.version;
}
// TM2o
if (this.timestamp && !this.createdAt) {
this.createdAt = this.timestamp;
}
}
}

toString(): string {
let result = '[Message';
if (this.name) result += '; name=' + this.name;
Expand All @@ -379,10 +394,10 @@ class Message {

if (this.action) result += '; action=' + this.action;
if (this.serial) result += '; serial=' + this.serial;
if (this.version) result += '; version=' + this.version;
if (this.refSerial) result += '; refSerial=' + this.refSerial;
if (this.refType) result += '; refType=' + this.refType;
if (this.updatedAt) result += '; updatedAt=' + this.updatedAt;
if (this.updateSerial) result += '; updateSerial=' + this.updateSerial;
if (this.createdAt) result += '; createdAt=' + this.createdAt;
if (this.operation) result += '; operation=' + JSON.stringify(this.operation);
result += ']';
return result;
Expand Down
19 changes: 19 additions & 0 deletions test/realtime/message.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1310,6 +1310,25 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, Helper, async
expect(message.toJSON()).to.deep.contains(expectedJSON);
});
});

/**
* @spec TM2k
* @spec TM2o
*/
it('create message should fill out serial and createdAt from version/timestamp', function () {
const values = { action: 1, timestamp: 12345, version: 'foo' };
const message = Message.fromWireProtocol(values);
expect(message.timestamp).to.equal(12345);
expect(message.createdAt).to.equal(12345);
expect(message.version).to.equal('foo');
expect(message.serial).to.equal('foo');

// should only apply to creates
const update = { action: 2, timestamp: 12345, version: 'foo' };
const updateMessage = Message.fromWireProtocol(update);
expect(updateMessage.createdAt).to.equal(undefined);
expect(updateMessage.serial).to.equal(undefined);
});
});

/**
Expand Down

0 comments on commit 18cd170

Please sign in to comment.