From 26743593482c927c93b52265c243008a54497031 Mon Sep 17 00:00:00 2001 From: Simon Woolf Date: Thu, 21 Nov 2024 18:08:34 +0000 Subject: [PATCH] Refactor Message/PresenceMessage.fromValues and related Previously, fromValues() took an options object with a 'stringifyAction' bool property. If that was false, then it acted as a normal fromValues; if true, then it was effectively doing a partial fromDeserialized, parsing a wire protocol message into a message but without decoding the message.data. This seemed a bit silly. Removed the options object and replaced it with an explicit Message.fromWireProtocol. Also while doing that ended up changing a bunch of other things that seemed broken: - unnecessary type-assertions due to not having a wire-protocol type, or unnecessary use of any & unknown - channeloptions being type-asserted as cipheroptions, then type-assert back to channeloptions, which made no sense - crypto not being passed-in to history calls, so not getting decrypted --- ably.d.ts | 3 +- src/common/lib/client/defaultrealtime.ts | 2 + src/common/lib/client/modularplugins.ts | 2 + src/common/lib/client/restchannelmixin.ts | 15 ++-- src/common/lib/client/restpresence.ts | 16 ++--- src/common/lib/client/restpresencemixin.ts | 28 ++++---- src/common/lib/types/defaultmessage.ts | 16 +++-- .../lib/types/defaultpresencemessage.ts | 22 ++++-- src/common/lib/types/message.ts | 61 +++++----------- src/common/lib/types/presencemessage.ts | 69 +++++++------------ src/common/lib/types/protocolmessage.ts | 36 ++++++---- src/common/lib/util/utils.ts | 3 + src/platform/web/modular/presencemessage.ts | 5 +- src/platform/web/modular/realtimepresence.ts | 2 + test/realtime/crypto.test.js | 6 +- test/realtime/message.test.js | 15 +--- 16 files changed, 137 insertions(+), 164 deletions(-) diff --git a/ably.d.ts b/ably.d.ts index cbe1df3ddd..be483f1c55 100644 --- a/ably.d.ts +++ b/ably.d.ts @@ -2516,9 +2516,8 @@ export interface PresenceMessageStatic { * Initialises a `PresenceMessage` from a `PresenceMessage`-like object. * * @param values - The values to intialise the `PresenceMessage` from. - * @param stringifyAction - Whether to convert the `action` field from a number to a string. */ - fromValues(values: PresenceMessage | Record, stringifyAction?: boolean): PresenceMessage; + fromValues(values: Partial>): PresenceMessage; } /** diff --git a/src/common/lib/client/defaultrealtime.ts b/src/common/lib/client/defaultrealtime.ts index 77e3eca413..467f916624 100644 --- a/src/common/lib/client/defaultrealtime.ts +++ b/src/common/lib/client/defaultrealtime.ts @@ -14,6 +14,7 @@ import { FilteredSubscriptions } from './filteredsubscriptions'; import { fromValues as presenceMessageFromValues, fromValuesArray as presenceMessagesFromValuesArray, + fromWireProtocol as presenceMessageFromWireProtocol, } from '../types/presencemessage'; import { Http } from 'common/types/http'; import Defaults from '../util/defaults'; @@ -39,6 +40,7 @@ export class DefaultRealtime extends BaseRealtime { RealtimePresence, presenceMessageFromValues, presenceMessagesFromValuesArray, + presenceMessageFromWireProtocol, }, WebSocketTransport, MessageInteractions: FilteredSubscriptions, diff --git a/src/common/lib/client/modularplugins.ts b/src/common/lib/client/modularplugins.ts index 7bb05e30b5..c3bdf1ea02 100644 --- a/src/common/lib/client/modularplugins.ts +++ b/src/common/lib/client/modularplugins.ts @@ -8,6 +8,7 @@ import { FilteredSubscriptions } from './filteredsubscriptions'; import { fromValues as presenceMessageFromValues, fromValuesArray as presenceMessagesFromValuesArray, + fromWireProtocol as presenceMessageFromWireProtocol, } from '../types/presencemessage'; import { TransportCtor } from '../transport/transport'; import * as PushPlugin from 'plugins/push'; @@ -15,6 +16,7 @@ import * as PushPlugin from 'plugins/push'; export interface PresenceMessagePlugin { presenceMessageFromValues: typeof presenceMessageFromValues; presenceMessagesFromValuesArray: typeof presenceMessagesFromValuesArray; + presenceMessageFromWireProtocol: typeof presenceMessageFromWireProtocol; } export type RealtimePresencePlugin = PresenceMessagePlugin & { diff --git a/src/common/lib/client/restchannelmixin.ts b/src/common/lib/client/restchannelmixin.ts index c104d66be7..a19bc78e83 100644 --- a/src/common/lib/client/restchannelmixin.ts +++ b/src/common/lib/client/restchannelmixin.ts @@ -2,7 +2,8 @@ import * as API from '../../../../ably'; import RestChannel from './restchannel'; import RealtimeChannel from './realtimechannel'; import * as Utils from '../util/utils'; -import Message, { fromResponseBody as messageFromResponseBody } from '../types/message'; +import Platform from '../../platform'; +import Message, { WireProtocolMessage, fromEncodedArray } from '../types/message'; import Defaults from '../util/defaults'; import PaginatedResource, { PaginatedResult } from './paginatedresource'; import Resource from './resource'; @@ -36,13 +37,11 @@ export class RestChannelMixin { headers, unpacked, ) { - return await messageFromResponseBody( - body as Message[], - options, - channel.logger, - client._MsgPack, - unpacked ? undefined : format, - ); + const decoded: WireProtocolMessage[] = unpacked + ? (body as WireProtocolMessage[]) + : Utils.decodeBody(body, client._MsgPack, format); + + return fromEncodedArray(channel.logger, Platform.Crypto, decoded, options); }).get(params as Record); } diff --git a/src/common/lib/client/restpresence.ts b/src/common/lib/client/restpresence.ts index 3ce4e142ac..fc3ea91d3e 100644 --- a/src/common/lib/client/restpresence.ts +++ b/src/common/lib/client/restpresence.ts @@ -1,8 +1,8 @@ import * as Utils from '../util/utils'; import Logger from '../util/logger'; import PaginatedResource, { PaginatedResult } from './paginatedresource'; -import PresenceMessage, { fromResponseBody as presenceMessageFromResponseBody } from '../types/presencemessage'; -import { CipherOptions } from '../types/message'; +import PresenceMessage, { WireProtocolPresenceMessage, fromEncodedArray } from '../types/presencemessage'; +import Platform from '../../platform'; import RestChannel from './restchannel'; import Defaults from '../util/defaults'; @@ -33,13 +33,11 @@ class RestPresence { headers, envelope, async (body, headers, unpacked) => { - return await presenceMessageFromResponseBody( - body as Record[], - options as CipherOptions, - this.logger, - client._MsgPack, - unpacked ? undefined : format, - ); + const decoded: WireProtocolPresenceMessage[] = unpacked + ? (body as WireProtocolPresenceMessage[]) + : Utils.decodeBody(body, client._MsgPack, format); + + return fromEncodedArray(this.logger, Platform.Crypto, decoded, options); }, ).get(params); } diff --git a/src/common/lib/client/restpresencemixin.ts b/src/common/lib/client/restpresencemixin.ts index f0b2cca379..a769e2705e 100644 --- a/src/common/lib/client/restpresencemixin.ts +++ b/src/common/lib/client/restpresencemixin.ts @@ -3,8 +3,8 @@ import RealtimePresence from './realtimepresence'; import * as Utils from '../util/utils'; import Defaults from '../util/defaults'; import PaginatedResource, { PaginatedResult } from './paginatedresource'; -import PresenceMessage, { fromResponseBody as presenceMessageFromResponseBody } from '../types/presencemessage'; -import { CipherOptions } from '../types/message'; +import PresenceMessage, { WireProtocolPresenceMessage, fromEncodedArray } from '../types/presencemessage'; +import Platform from '../../platform'; import { RestChannelMixin } from './restchannelmixin'; export class RestPresenceMixin { @@ -24,18 +24,18 @@ export class RestPresenceMixin { Utils.mixin(headers, client.options.headers); const options = presence.channel.channelOptions; - return new PaginatedResource(client, this.basePath(presence) + '/history', headers, envelope, async function ( - body, + return new PaginatedResource( + client, + this.basePath(presence) + '/history', headers, - unpacked, - ) { - return await presenceMessageFromResponseBody( - body as Record[], - options as CipherOptions, - presence.logger, - client._MsgPack, - unpacked ? undefined : format, - ); - }).get(params); + envelope, + async (body, headers, unpacked) => { + const decoded: WireProtocolPresenceMessage[] = unpacked + ? (body as WireProtocolPresenceMessage[]) + : Utils.decodeBody(body, client._MsgPack, format); + + return fromEncodedArray(presence.logger, Platform.Crypto, decoded, options); + }, + ).get(params); } } diff --git a/src/common/lib/types/defaultmessage.ts b/src/common/lib/types/defaultmessage.ts index 79fffccf5a..1161e909c7 100644 --- a/src/common/lib/types/defaultmessage.ts +++ b/src/common/lib/types/defaultmessage.ts @@ -1,4 +1,5 @@ import Message, { + WireProtocolMessage, CipherOptions, decode, encode, @@ -6,28 +7,35 @@ import Message, { fromEncoded, fromEncodedArray, fromValues, + fromWireProtocol, } from './message'; import * as API from '../../../../ably'; import Platform from 'common/platform'; import PresenceMessage from './presencemessage'; import { ChannelOptions } from 'common/types/channel'; import Logger from '../util/logger'; +import type { Properties } from '../util/utils'; /** `DefaultMessage` is the class returned by `DefaultRest` and `DefaultRealtime`’s `Message` static property. It introduces the static methods described in the `MessageStatic` interface of the public API of the non tree-shakable version of the library. */ export class DefaultMessage extends Message { static async fromEncoded(encoded: unknown, inputOptions?: API.ChannelOptions): Promise { - return fromEncoded(Logger.defaultLogger, Platform.Crypto, encoded, inputOptions); + return fromEncoded(Logger.defaultLogger, Platform.Crypto, encoded as WireProtocolMessage, inputOptions); } static async fromEncodedArray(encodedArray: Array, options?: API.ChannelOptions): Promise { - return fromEncodedArray(Logger.defaultLogger, Platform.Crypto, encodedArray, options); + return fromEncodedArray(Logger.defaultLogger, Platform.Crypto, encodedArray as WireProtocolMessage[], options); } // Used by tests - static fromValues(values: Message | Record, options?: { stringifyAction?: boolean }): Message { - return fromValues(values, options); + static fromValues(values: Properties): Message { + return fromValues(values); + } + + // Used by tests + static fromWireProtocol(values: WireProtocolMessage): Message { + return fromWireProtocol(values); } // Used by tests diff --git a/src/common/lib/types/defaultpresencemessage.ts b/src/common/lib/types/defaultpresencemessage.ts index 1b8592c3e1..a5ef3877d1 100644 --- a/src/common/lib/types/defaultpresencemessage.ts +++ b/src/common/lib/types/defaultpresencemessage.ts @@ -1,23 +1,35 @@ import * as API from '../../../../ably'; import Logger from '../util/logger'; -import PresenceMessage, { fromEncoded, fromEncodedArray, fromValues } from './presencemessage'; +import PresenceMessage, { + fromEncoded, + fromEncodedArray, + fromValues, + WireProtocolPresenceMessage, +} from './presencemessage'; +import Platform from 'common/platform'; +import type { Properties } from '../util/utils'; /** `DefaultPresenceMessage` is the class returned by `DefaultRest` and `DefaultRealtime`’s `PresenceMessage` static property. It introduces the static methods described in the `PresenceMessageStatic` interface of the public API of the non tree-shakable version of the library. */ export class DefaultPresenceMessage extends PresenceMessage { static async fromEncoded(encoded: unknown, inputOptions?: API.ChannelOptions): Promise { - return fromEncoded(Logger.defaultLogger, encoded, inputOptions); + return fromEncoded(Logger.defaultLogger, Platform.Crypto, encoded as WireProtocolPresenceMessage, inputOptions); } static async fromEncodedArray( encodedArray: Array, options?: API.ChannelOptions, ): Promise { - return fromEncodedArray(Logger.defaultLogger, encodedArray, options); + return fromEncodedArray( + Logger.defaultLogger, + Platform.Crypto, + encodedArray as WireProtocolPresenceMessage[], + options, + ); } - static fromValues(values: PresenceMessage | Record, stringifyAction?: boolean): PresenceMessage { - return fromValues(values, stringifyAction); + static fromValues(values: Properties): PresenceMessage { + return fromValues(values); } } diff --git a/src/common/lib/types/message.ts b/src/common/lib/types/message.ts index 0a9f0d4190..3e522c7b2c 100644 --- a/src/common/lib/types/message.ts +++ b/src/common/lib/types/message.ts @@ -1,13 +1,14 @@ import Platform from 'common/platform'; import Logger from '../util/logger'; import ErrorInfo from './errorinfo'; -import { ChannelOptions } from '../../types/channel'; import PresenceMessage from './presencemessage'; import * as Utils from '../util/utils'; import { Bufferlike as BrowserBufferlike } from '../../../platform/web/lib/util/bufferutils'; import * as API from '../../../../ably'; -import { IUntypedCryptoStatic } from 'common/types/ICryptoStatic'; -import { MsgPack } from 'common/types/msgpack'; + +import type { IUntypedCryptoStatic } from 'common/types/ICryptoStatic'; +import type { ChannelOptions } from '../../types/channel'; +import type { Properties } from '../util/utils'; const MessageActionArray: API.MessageAction[] = [ 'message.unset', @@ -56,6 +57,8 @@ export type EncodingDecodingContext = { baseEncodedPreviousPayload?: Buffer | BrowserBufferlike; }; +export type WireProtocolMessage = Omit & { action: number }; + function normaliseContext(context: CipherOptions | EncodingDecodingContext | ChannelOptions): EncodingDecodingContext { if (!context || !(context as EncodingDecodingContext).channelOptions) { return { @@ -67,7 +70,7 @@ function normaliseContext(context: CipherOptions | EncodingDecodingContext | Cha return context as EncodingDecodingContext; } -function normalizeCipherOptions( +export function normalizeCipherOptions( Crypto: IUntypedCryptoStatic | null, logger: Logger, options: API.ChannelOptions | null, @@ -103,10 +106,10 @@ function getMessageSize(msg: Message) { export async function fromEncoded( logger: Logger, Crypto: IUntypedCryptoStatic | null, - encoded: unknown, + encoded: WireProtocolMessage, inputOptions?: API.ChannelOptions, ): Promise { - const msg = fromValues(encoded as Message | Record, { stringifyAction: true }); + const msg = fromWireProtocol(encoded); const options = normalizeCipherOptions(Crypto, logger, inputOptions ?? null); /* if decoding fails at any point, catch and return the message decoded to * the fullest extent possible */ @@ -121,7 +124,7 @@ export async function fromEncoded( export async function fromEncodedArray( logger: Logger, Crypto: IUntypedCryptoStatic | null, - encodedArray: Array, + encodedArray: Array, options?: API.ChannelOptions, ): Promise { return Promise.all( @@ -272,45 +275,17 @@ export async function decode( context.baseEncodedPreviousPayload = lastPayload; } -export async function fromResponseBody( - body: Array, - options: ChannelOptions | EncodingDecodingContext, - logger: Logger, - MsgPack: MsgPack | null, - format?: Utils.Format, -): Promise { - if (format) { - body = Utils.decodeBody(body, MsgPack, format); - } - - for (let i = 0; i < body.length; i++) { - const msg = (body[i] = fromValues(body[i], { stringifyAction: true })); - try { - await decode(msg, options); - } catch (e) { - Logger.logAction(logger, Logger.LOG_ERROR, 'Message.fromResponseBody()', (e as Error).toString()); - } - } - return body; +export function fromValues(values: Properties): Message { + return Object.assign(new Message(), values); } -export function fromValues( - values: Message | Record, - options?: { stringifyAction?: boolean }, -): Message { - const stringifyAction = options?.stringifyAction; - if (stringifyAction) { - const action = toMessageActionString(values.action as number) || values.action; - return Object.assign(new Message(), { ...values, action }); - } - return Object.assign(new Message(), values); +export function fromWireProtocol(values: WireProtocolMessage): Message { + const action = toMessageActionString(values.action as number) || values.action; + return Object.assign(new Message(), { ...values, action }); } -export function fromValuesArray(values: unknown[]): Message[] { - const count = values.length, - result = new Array(count); - for (let i = 0; i < count; i++) result[i] = fromValues(values[i] as Record); - return result; +export function fromValuesArray(values: Properties[]): Message[] { + return values.map(fromValues); } /* This should be called on encode()d (and encrypt()d) Messages (as it @@ -336,7 +311,7 @@ class Message { encoding?: string | null; extras?: any; size?: number; - action?: API.MessageAction | number; + action?: API.MessageAction; serial?: string; refSerial?: string; refType?: string; diff --git a/src/common/lib/types/presencemessage.ts b/src/common/lib/types/presencemessage.ts index 34e0d2d06d..6e1f78ff2c 100644 --- a/src/common/lib/types/presencemessage.ts +++ b/src/common/lib/types/presencemessage.ts @@ -1,22 +1,27 @@ import Logger from '../util/logger'; import Platform from 'common/platform'; -import { encode as encodeMessage, decode as decodeMessage, getMessagesSize, CipherOptions } from './message'; -import * as Utils from '../util/utils'; +import { normalizeCipherOptions, encode as encodeMessage, decode as decodeMessage, getMessagesSize } from './message'; import * as API from '../../../../ably'; -import { MsgPack } from 'common/types/msgpack'; + +import type { IUntypedCryptoStatic } from 'common/types/ICryptoStatic'; +import type { Properties } from '../util/utils'; const actions = ['absent', 'present', 'enter', 'leave', 'update']; +export type WireProtocolPresenceMessage = Omit & { action: number }; + function toActionValue(actionString: string) { return actions.indexOf(actionString); } export async function fromEncoded( logger: Logger, - encoded: unknown, - options?: API.ChannelOptions, + Crypto: IUntypedCryptoStatic | null, + encoded: WireProtocolPresenceMessage, + inputOptions?: API.ChannelOptions, ): Promise { - const msg = fromValues(encoded as PresenceMessage | Record, true); + const msg = fromWireProtocol(encoded); + const options = normalizeCipherOptions(Crypto, logger, inputOptions ?? null); /* if decoding fails at any point, catch and return the message decoded to * the fullest extent possible */ try { @@ -29,60 +34,34 @@ export async function fromEncoded( export async function fromEncodedArray( logger: Logger, - encodedArray: unknown[], + Crypto: IUntypedCryptoStatic | null, + encodedArray: WireProtocolPresenceMessage[], options?: API.ChannelOptions, ): Promise { return Promise.all( encodedArray.map(function (encoded) { - return fromEncoded(logger, encoded, options); + return fromEncoded(logger, Crypto, encoded, options); }), ); } -export function fromValues( - values: PresenceMessage | Record, - stringifyAction?: boolean, -): PresenceMessage { - if (stringifyAction) { - values.action = actions[values.action as number]; - } +export function fromValues(values: Properties): PresenceMessage { return Object.assign(new PresenceMessage(), values); } +export function fromWireProtocol(values: WireProtocolPresenceMessage): PresenceMessage { + const action = actions[values.action]; + return Object.assign(new PresenceMessage(), { ...values, action }); +} + export { encodeMessage as encode }; export const decode = decodeMessage; -export async function fromResponseBody( - body: Record[], - options: CipherOptions, - logger: Logger, - MsgPack: MsgPack | null, - format?: Utils.Format, -): Promise { - const messages: PresenceMessage[] = []; - if (format) { - body = Utils.decodeBody(body, MsgPack, format); - } - - for (let i = 0; i < body.length; i++) { - const msg = (messages[i] = fromValues(body[i], true)); - try { - await decode(msg, options); - } catch (e) { - Logger.logAction(logger, Logger.LOG_ERROR, 'PresenceMessage.fromResponseBody()', (e as Error).toString()); - } - } - return messages; -} - -export function fromValuesArray(values: unknown[]): PresenceMessage[] { - const count = values.length, - result = new Array(count); - for (let i = 0; i < count; i++) result[i] = fromValues(values[i] as Record); - return result; +export function fromValuesArray(values: Properties[]): PresenceMessage[] { + return values.map(fromValues); } -export function fromData(data: unknown): PresenceMessage { +export function fromData(data: any): PresenceMessage { if (data instanceof PresenceMessage) { return data; } @@ -94,7 +73,7 @@ export function fromData(data: unknown): PresenceMessage { export { getMessagesSize }; class PresenceMessage { - action?: string | number; + action?: string; id?: string; timestamp?: number; clientId?: string; diff --git a/src/common/lib/types/protocolmessage.ts b/src/common/lib/types/protocolmessage.ts index ccb15841fe..449cd5b9c2 100644 --- a/src/common/lib/types/protocolmessage.ts +++ b/src/common/lib/types/protocolmessage.ts @@ -3,10 +3,16 @@ import * as API from '../../../../ably'; import { PresenceMessagePlugin } from '../client/modularplugins'; import * as Utils from '../util/utils'; import ErrorInfo from './errorinfo'; -import Message, { fromValues as messageFromValues, fromValuesArray as messagesFromValuesArray } from './message'; +import Message, { + fromWireProtocol as messageFromWireProtocol, + fromValuesArray as messagesFromValuesArray, + WireProtocolMessage, +} from './message'; import PresenceMessage, { + fromWireProtocol as presenceMessageFromWireProtocol, fromValues as presenceMessageFromValues, fromValuesArray as presenceMessagesFromValuesArray, + WireProtocolPresenceMessage, } from './presencemessage'; export const actions = { @@ -85,30 +91,30 @@ export function fromDeserialized( deserialized.error = ErrorInfo.fromValues(error as ErrorInfo); } - const messages = deserialized.messages as Message[]; - if (messages) { - for (let i = 0; i < messages.length; i++) { - messages[i] = messageFromValues(messages[i], { stringifyAction: true }); - } + let messages: Message[] | undefined; + if (deserialized.messages) { + const dm = deserialized.messages as WireProtocolMessage[]; + messages = dm.map((m) => messageFromWireProtocol(m)); } - const presence = presenceMessagePlugin ? (deserialized.presence as PresenceMessage[]) : undefined; - if (presenceMessagePlugin) { - if (presence && presenceMessagePlugin) { - for (let i = 0; i < presence.length; i++) { - presence[i] = presenceMessagePlugin.presenceMessageFromValues(presence[i], true); - } - } + let presence: PresenceMessage[] | undefined; + if (presenceMessagePlugin && deserialized.presence) { + const dp = deserialized.presence as WireProtocolPresenceMessage[]; + presence = dp.map((pm) => presenceMessagePlugin.presenceMessageFromWireProtocol(pm)); } - return Object.assign(new ProtocolMessage(), { ...deserialized, presence }); + return Object.assign(new ProtocolMessage(), { ...deserialized, presence, messages }); } /** * Used by the tests. */ export function fromDeserializedIncludingDependencies(deserialized: Record): ProtocolMessage { - return fromDeserialized(deserialized, { presenceMessageFromValues, presenceMessagesFromValuesArray }); + return fromDeserialized(deserialized, { + presenceMessageFromValues, + presenceMessagesFromValuesArray, + presenceMessageFromWireProtocol, + }); } export function fromValues(values: unknown): ProtocolMessage { diff --git a/src/common/lib/util/utils.ts b/src/common/lib/util/utils.ts index f1af5ff363..ef2a6ccf10 100644 --- a/src/common/lib/util/utils.ts +++ b/src/common/lib/util/utils.ts @@ -467,3 +467,6 @@ export async function withTimeoutAsync(promise: Promise, timeout = 5000, e const e = new ErrorInfo(err, 50000, 500); return Promise.race([promise, new Promise((_resolve, reject) => setTimeout(() => reject(e), timeout))]); } + +type NonFunctionKeyNames = { [P in keyof A]: A[P] extends Function ? never : P }[keyof A]; +export type Properties = Pick>; diff --git a/src/platform/web/modular/presencemessage.ts b/src/platform/web/modular/presencemessage.ts index 6c9b891a02..3ce2c1cf59 100644 --- a/src/platform/web/modular/presencemessage.ts +++ b/src/platform/web/modular/presencemessage.ts @@ -1,15 +1,16 @@ import * as API from '../../../../ably'; import { fromEncoded, fromEncodedArray, fromValues } from '../../../common/lib/types/presencemessage'; +import Platform from 'common/platform'; import Logger from '../../../common/lib/util/logger'; // The type assertions for the functions below are due to https://github.com/ably/ably-js/issues/1421 export const decodePresenceMessage = ((obj, options) => { - return fromEncoded(Logger.defaultLogger, obj, options); + return fromEncoded(Logger.defaultLogger, Platform.Crypto, obj, options); }) as API.PresenceMessageStatic['fromEncoded']; export const decodePresenceMessages = ((obj, options) => { - return fromEncodedArray(Logger.defaultLogger, obj, options); + return fromEncodedArray(Logger.defaultLogger, Platform.Crypto, obj, options); }) as API.PresenceMessageStatic['fromEncodedArray']; export const constructPresenceMessage = fromValues as API.PresenceMessageStatic['fromValues']; diff --git a/src/platform/web/modular/realtimepresence.ts b/src/platform/web/modular/realtimepresence.ts index f4f138d720..4d42fd9322 100644 --- a/src/platform/web/modular/realtimepresence.ts +++ b/src/platform/web/modular/realtimepresence.ts @@ -3,12 +3,14 @@ import { default as realtimePresenceClass } from '../../../common/lib/client/rea import { fromValues as presenceMessageFromValues, fromValuesArray as presenceMessagesFromValuesArray, + fromWireProtocol as presenceMessageFromWireProtocol, } from '../../../common/lib/types/presencemessage'; const RealtimePresence: RealtimePresencePlugin = { RealtimePresence: realtimePresenceClass, presenceMessageFromValues, presenceMessagesFromValuesArray, + presenceMessageFromWireProtocol, }; export { RealtimePresence }; diff --git a/test/realtime/crypto.test.js b/test/realtime/crypto.test.js index 18df2f11e4..9eeca0eef6 100644 --- a/test/realtime/crypto.test.js +++ b/test/realtime/crypto.test.js @@ -393,9 +393,8 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, Helper, async var msgpackFromEncrypted = msgpack.encode(encryptedMessage); helper.recordPrivateApi('call.BufferUtils.base64Decode'); helper.recordPrivateApi('call.msgpack.decode'); - var messageFromMsgpack = Message.fromValues( + var messageFromMsgpack = Message.fromWireProtocol( msgpack.decode(BufferUtils.base64Decode(msgpackEncodedMessage)), - { stringifyAction: true }, ); try { @@ -438,9 +437,8 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, Helper, async var msgpackFromEncrypted = msgpack.encode(encryptedMessage); helper.recordPrivateApi('call.BufferUtils.base64Decode'); helper.recordPrivateApi('call.msgpack.decode'); - var messageFromMsgpack = Message.fromValues( + var messageFromMsgpack = Message.fromWireProtocol( msgpack.decode(BufferUtils.base64Decode(msgpackEncodedMessage)), - { stringifyAction: true }, ); try { diff --git a/test/realtime/message.test.js b/test/realtime/message.test.js index 6cb2cfd0a4..1490bdd7b1 100644 --- a/test/realtime/message.test.js +++ b/test/realtime/message.test.js @@ -1275,40 +1275,29 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, Helper, async /** * @spec TM2j */ - describe('DefaultMessage.fromValues stringify action', function () { + describe('DefaultMessage.fromWireProtocol', function () { const testCases = [ { description: 'should stringify the numeric action', action: 1, - options: { stringifyAction: true }, expectedString: '[Message; action=message.create]', expectedJSON: { action: 1 }, }, - { - description: 'should not stringify the numeric action', - action: 1, - options: { stringifyAction: false }, - expectedString: '[Message; action=1]', - expectedJSON: { action: 1 }, - }, { description: 'should accept an already stringified action', action: 'message.update', - options: { stringifyAction: true }, expectedString: '[Message; action=message.update]', expectedJSON: { action: 2 }, }, { description: 'should handle no action provided', action: undefined, - options: { stringifyAction: true }, expectedString: '[Message]', expectedJSON: { action: undefined }, }, { description: 'should handle unknown action provided', action: 10, - options: { stringifyAction: true }, expectedString: '[Message; action=10]', expectedJSON: { action: 10 }, }, @@ -1316,7 +1305,7 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, Helper, async testCases.forEach(({ description, action, options, expectedString, expectedJSON }) => { it(description, function () { const values = { action }; - const message = Message.fromValues(values, options); + const message = Message.fromWireProtocol(values); expect(message.toString()).to.equal(expectedString); expect(message.toJSON()).to.deep.contains(expectedJSON); });