Skip to content

Commit

Permalink
Remove PresenceMessage-related static things in tree-shakable library
Browse files Browse the repository at this point in the history
As in cd015e1.

Resolves #1427.
  • Loading branch information
lawrence-forooghian committed Oct 26, 2023
1 parent c80ea79 commit ca58b56
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 16 deletions.
2 changes: 2 additions & 0 deletions scripts/moduleReport.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const functions = [
{ name: 'decodeEncryptedMessage', transitiveImports: ['Crypto'] },
{ name: 'decodeMessages', transitiveImports: [] },
{ name: 'decodeEncryptedMessages', transitiveImports: ['Crypto'] },
{ name: 'decodePresenceMessage', transitiveImports: [] },
{ name: 'decodePresenceMessages', transitiveImports: [] },
];

function formatBytes(bytes) {
Expand Down
2 changes: 0 additions & 2 deletions src/common/lib/client/baseclient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { IHttp, RequestParams } from '../../types/http';
import ClientOptions, { NormalisedClientOptions } from '../../types/ClientOptions';

import Platform from '../../platform';
import PresenceMessage from '../types/presencemessage';
import { ModulesMap } from './modulesmap';
import { Rest } from './rest';
import { IUntypedCryptoStatic } from 'common/types/ICryptoStatic';
Expand Down Expand Up @@ -133,7 +132,6 @@ class BaseClient {
}

static Platform = Platform;
static PresenceMessage = PresenceMessage;
}

export default BaseClient;
2 changes: 2 additions & 0 deletions src/common/lib/client/defaultrealtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Platform from 'common/platform';
import { DefaultMessage } from '../types/defaultmessage';
import { MsgPack } from 'common/types/msgpack';
import RealtimePresence from './realtimepresence';
import { DefaultPresenceMessage } from '../types/defaultpresencemessage';

/**
`DefaultRealtime` is the class that the non tree-shakable version of the SDK exports as `Realtime`. It ensures that this version of the SDK includes all of the functionality which is optionally available in the tree-shakable version.
Expand Down Expand Up @@ -39,6 +40,7 @@ export class DefaultRealtime extends BaseRealtime {
}

static Message = DefaultMessage;
static PresenceMessage = DefaultPresenceMessage;

static _MsgPack: MsgPack | null = null;
}
2 changes: 2 additions & 0 deletions src/common/lib/client/defaultrest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { allCommonModules } from './modulesmap';
import Platform from 'common/platform';
import { DefaultMessage } from '../types/defaultmessage';
import { MsgPack } from 'common/types/msgpack';
import { DefaultPresenceMessage } from '../types/defaultpresencemessage';

/**
`DefaultRest` is the class that the non tree-shakable version of the SDK exports as `Rest`. It ensures that this version of the SDK includes all of the functionality which is optionally available in the tree-shakable version.
Expand Down Expand Up @@ -35,6 +36,7 @@ export class DefaultRest extends BaseRest {
}

static Message = DefaultMessage;
static PresenceMessage = DefaultPresenceMessage;

static _MsgPack: MsgPack | null = null;
}
18 changes: 18 additions & 0 deletions src/common/lib/types/defaultpresencemessage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import * as API from '../../../../ably';
import PresenceMessage, { fromEncoded, fromEncodedArray } from './presencemessage';

/**
`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.Types.ChannelOptions): Promise<PresenceMessage> {
return fromEncoded(encoded, inputOptions);
}

static async fromEncodedArray(
encodedArray: Array<unknown>,
options?: API.Types.ChannelOptions
): Promise<PresenceMessage[]> {
return fromEncodedArray(encodedArray, options);
}
}
39 changes: 25 additions & 14 deletions src/common/lib/types/presencemessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,29 @@ function toActionValue(actionString: string) {
return PresenceMessage.Actions.indexOf(actionString);
}

export async function fromEncoded(encoded: unknown, options?: API.Types.ChannelOptions): Promise<PresenceMessage> {
const msg = PresenceMessage.fromValues(encoded as PresenceMessage | Record<string, unknown>, true);
/* if decoding fails at any point, catch and return the message decoded to
* the fullest extent possible */
try {
await PresenceMessage.decode(msg, options ?? {});
} catch (e) {
Logger.logAction(Logger.LOG_ERROR, 'PresenceMessage.fromEncoded()', (e as Error).toString());
}
return msg;
}

export async function fromEncodedArray(
encodedArray: unknown[],
options?: API.Types.ChannelOptions
): Promise<PresenceMessage[]> {
return Promise.all(
encodedArray.map(function (encoded) {
return PresenceMessage.fromEncoded(encoded, options);
})
);
}

class PresenceMessage {
action?: string | number;
id?: string;
Expand Down Expand Up @@ -140,26 +163,14 @@ class PresenceMessage {
}

static async fromEncoded(encoded: unknown, options?: API.Types.ChannelOptions): Promise<PresenceMessage> {
const msg = PresenceMessage.fromValues(encoded as PresenceMessage | Record<string, unknown>, true);
/* if decoding fails at any point, catch and return the message decoded to
* the fullest extent possible */
try {
await PresenceMessage.decode(msg, options ?? {});
} catch (e) {
Logger.logAction(Logger.LOG_ERROR, 'PresenceMessage.fromEncoded()', (e as Error).toString());
}
return msg;
return fromEncoded(encoded, options);
}

static async fromEncodedArray(
encodedArray: unknown[],
options?: API.Types.ChannelOptions
): Promise<PresenceMessage[]> {
return Promise.all(
encodedArray.map(function (encoded) {
return PresenceMessage.fromEncoded(encoded, options);
})
);
return fromEncodedArray(encodedArray, options);
}

static getMessagesSize = Message.getMessagesSize;
Expand Down
1 change: 1 addition & 0 deletions src/platform/web/modules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ if (Platform.Config.noUpgrade) {

export * from './modules/crypto';
export * from './modules/message';
export * from './modules/presencemessage';
export * from './modules/msgpack';
export * from './modules/realtimepresence';
export { Rest } from '../../common/lib/client/rest';
Expand Down
12 changes: 12 additions & 0 deletions src/platform/web/modules/presencemessage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import * as API from '../../../../ably';
import { fromEncoded, fromEncodedArray } from '../../../common/lib/types/presencemessage';

// The type assertions for the decode* functions below are due to https://github.com/ably/ably-js/issues/1421

export const decodePresenceMessage = ((obj, options) => {
return fromEncoded(obj, options);
}) as API.Types.PresenceMessageStatic['fromEncoded'];

export const decodePresenceMessages = ((obj, options) => {
return fromEncodedArray(obj, options);
}) as API.Types.PresenceMessageStatic['fromEncodedArray'];
35 changes: 35 additions & 0 deletions test/browser/modules.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {
Crypto,
MsgPack,
RealtimePresence,
decodePresenceMessage,
decodePresenceMessages,
} from '../../build/modules/index.js';

describe('browser/modules', function () {
Expand Down Expand Up @@ -351,4 +353,37 @@ describe('browser/modules', function () {
});
});
});

describe('PresenceMessage standalone functions', () => {
describe('decodePresenceMessage', () => {
it('decodes a presence message’s data', async () => {
const buffer = BufferUtils.utf8Encode('foo');
const encodedMessage = { data: BufferUtils.base64Encode(buffer), encoding: 'base64' };

const decodedMessage = await decodePresenceMessage(encodedMessage);

expect(BufferUtils.areBuffersEqual(decodedMessage.data, buffer)).to.be.true;
expect(decodedMessage.encoding).to.be.null;
});
});

describe('decodeMessages', () => {
it('decodes presence messages’ data', async () => {
const buffers = ['foo', 'bar'].map((data) => BufferUtils.utf8Encode(data));
const encodedMessages = buffers.map((buffer) => ({
data: BufferUtils.base64Encode(buffer),
encoding: 'base64',
}));

const decodedMessages = await decodePresenceMessages(encodedMessages);

for (let i = 0; i < decodedMessages.length; i++) {
const decodedMessage = decodedMessages[i];

expect(BufferUtils.areBuffersEqual(decodedMessage.data, buffers[i])).to.be.true;
expect(decodedMessage.encoding).to.be.null;
}
});
});
});
});

0 comments on commit ca58b56

Please sign in to comment.