Skip to content

Commit

Permalink
A channel augmenter that encodes and decodes messages as JSON
Browse files Browse the repository at this point in the history
  • Loading branch information
steveluscher committed Oct 4, 2024
1 parent 7e8d6ca commit fd5fc49
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 1 deletion.
8 changes: 7 additions & 1 deletion packages/rpc-subscriptions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,10 @@

# @solana/rpc-subscriptions

TODO
This package contains types that implement RPC subscriptions as required by the Solana RPC. Additionally, it incorporates some useful defaults that make working with subscriptions easier, more performant, and more reliable. It can be used standalone, but it is also exported as part of the Solana JavaScript SDK [`@solana/web3.js@rc`](https://github.com/solana-labs/solana-web3.js/tree/master/packages/library).

## Functions

### `getRpcSubscriptionsChannelWithJSONSerialization(channel)`

Given an `RpcSubscriptionsChannel`, will return a new channel that parses data published to the `'message'` channel as JSON, and JSON-stringifies messages sent via the `send(message)` method.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { RpcSubscriptionsChannel } from '@solana/rpc-subscriptions-spec';

import { getRpcSubscriptionsChannelWithJSONSerialization } from '../rpc-subscriptions-json';

describe('getRpcSubscriptionsChannelWithJSONSerialization', () => {
let mockOn: jest.Mock;
let channel: RpcSubscriptionsChannel<string, string>;
function receiveMessage(message: unknown) {
mockOn.mock.calls.filter(([type]) => type === 'message').forEach(([_, listener]) => listener(message));
}
beforeEach(() => {
mockOn = jest.fn();
channel = {
on: mockOn,
send: jest.fn(),
};
});
it('forwards JSON-serialized messages to the underlying channel', () => {
const channelWithJSONSerialization = getRpcSubscriptionsChannelWithJSONSerialization(channel);
channelWithJSONSerialization.send('hello');
expect(channel.send).toHaveBeenCalledWith(JSON.stringify('hello'));
});
it('deserializes messages received from the underlying channel as JSON', () => {
const channelWithJSONSerialization = getRpcSubscriptionsChannelWithJSONSerialization(channel);
const messageListener = jest.fn();
channelWithJSONSerialization.on('message', messageListener);
receiveMessage(JSON.stringify('hello'));
expect(messageListener).toHaveBeenCalledWith('hello');
});
});
26 changes: 26 additions & 0 deletions packages/rpc-subscriptions/src/rpc-subscriptions-json.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { RpcSubscriptionsChannel } from '@solana/rpc-subscriptions-spec';

export function getRpcSubscriptionsChannelWithJSONSerialization(
channel: RpcSubscriptionsChannel<string, string>,
): RpcSubscriptionsChannel<unknown, unknown> {
return {
...channel,
on(type, listener, options) {
if (type !== 'message') {
return channel.on(type, listener, options);
}
return channel.on(
'message',
function deserializingListener(message: string) {
const deserializedMessage = JSON.parse(message);
listener(deserializedMessage);
},
options,
);
},
send(message) {
const serializedMessage = JSON.stringify(message);
return channel.send(serializedMessage);
},
};
}

0 comments on commit fd5fc49

Please sign in to comment.