Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(js-ts): Convert app/util/streams to TypeScript #11398

Closed
wants to merge 9 commits into from
3 changes: 3 additions & 0 deletions app/declarations/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ declare module 'react-native-fade-in-image';

declare module 'react-native-fast-crypto';

declare module 'through2';

declare module 'pump';
declare module 'react-native-minimizer';

declare module 'xhr2';
Expand Down
44 changes: 0 additions & 44 deletions app/util/streams.js
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C: It's a shame that it did not make it as a rename so that we could see both JS and TS side by side instead of delete and new.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, we're at the will of how Github diff analyzes the changes

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does it fine in https://github.com/MetaMask/metamask-mobile/pull/11335/files so not sure why here it doesn't see the renaming

This file was deleted.

88 changes: 88 additions & 0 deletions app/util/streams.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { jsonParseStream, jsonStringifyStream, setupMultiplex } from './streams';
import Through from 'through2';
import ObjectMultiplex from '@metamask/object-multiplex';
import pump from 'pump';

jest.mock('through2');
jest.mock('@metamask/object-multiplex');
jest.mock('pump');

describe('streams', () => {
beforeEach(() => {
jest.clearAllMocks();
});

describe('jsonParseStream', () => {
it('should parse JSON strings', (done) => {
const mockThrough = {
push: jest.fn(),
};
(Through.obj as jest.Mock).mockImplementation((callback) => {
callback.call(mockThrough, '{"key":"value"}', null, () => {});

Check failure on line 21 in app/util/streams.test.ts

View workflow job for this annotation

GitHub Actions / scripts (lint)

Unexpected empty arrow function
return mockThrough;
});

const stream = jsonParseStream();

Check failure on line 25 in app/util/streams.test.ts

View workflow job for this annotation

GitHub Actions / scripts (lint)

'stream' is assigned a value but never used
expect(Through.obj).toHaveBeenCalled();
expect(mockThrough.push).toHaveBeenCalledWith({ key: 'value' });
done();
});
});

describe('jsonStringifyStream', () => {
it('should stringify objects', (done) => {
const mockThrough = {
push: jest.fn(),
};
(Through.obj as jest.Mock).mockImplementation((callback) => {
callback.call(mockThrough, { key: 'value' }, null, () => {});

Check failure on line 38 in app/util/streams.test.ts

View workflow job for this annotation

GitHub Actions / scripts (lint)

Unexpected empty arrow function
return mockThrough;
});

const stream = jsonStringifyStream();

Check failure on line 42 in app/util/streams.test.ts

View workflow job for this annotation

GitHub Actions / scripts (lint)

'stream' is assigned a value but never used
expect(Through.obj).toHaveBeenCalled();
expect(mockThrough.push).toHaveBeenCalledWith('{"key":"value"}');
done();
});
});

describe('setupMultiplex', () => {
it('should set up stream multiplexing', () => {
const mockConnectionStream = {} as NodeJS.ReadWriteStream;
const mockMux = {} as NodeJS.ReadWriteStream;

(ObjectMultiplex as jest.Mock).mockReturnValue(mockMux);
(pump as jest.Mock).mockImplementation((stream1, stream2, stream3, callback) => {

Check failure on line 55 in app/util/streams.test.ts

View workflow job for this annotation

GitHub Actions / scripts (lint)

'stream1' is defined but never used. Allowed unused args must match /[_]+/u

Check failure on line 55 in app/util/streams.test.ts

View workflow job for this annotation

GitHub Actions / scripts (lint)

'stream2' is defined but never used. Allowed unused args must match /[_]+/u

Check failure on line 55 in app/util/streams.test.ts

View workflow job for this annotation

GitHub Actions / scripts (lint)

'stream3' is defined but never used. Allowed unused args must match /[_]+/u
callback(null);
});

const result = setupMultiplex(mockConnectionStream);

expect(ObjectMultiplex).toHaveBeenCalled();
expect(pump).toHaveBeenCalledWith(
mockConnectionStream,
mockMux,
mockConnectionStream,
expect.any(Function)
);
expect(result).toBe(mockMux);
});

it('should handle errors in pump', () => {
const mockConnectionStream = {} as NodeJS.ReadWriteStream;
const mockMux = {} as NodeJS.ReadWriteStream;
const mockError = new Error('Pump error');

(ObjectMultiplex as jest.Mock).mockReturnValue(mockMux);
(pump as jest.Mock).mockImplementation((stream1, stream2, stream3, callback) => {

Check failure on line 77 in app/util/streams.test.ts

View workflow job for this annotation

GitHub Actions / scripts (lint)

'stream1' is defined but never used. Allowed unused args must match /[_]+/u

Check failure on line 77 in app/util/streams.test.ts

View workflow job for this annotation

GitHub Actions / scripts (lint)

'stream2' is defined but never used. Allowed unused args must match /[_]+/u

Check failure on line 77 in app/util/streams.test.ts

View workflow job for this annotation

GitHub Actions / scripts (lint)

'stream3' is defined but never used. Allowed unused args must match /[_]+/u
callback(mockError);
});

console.warn = jest.fn();

setupMultiplex(mockConnectionStream);

expect(console.warn).toHaveBeenCalledWith(mockError);
});
});
});
59 changes: 59 additions & 0 deletions app/util/streams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import Through from 'through2';
import ObjectMultiplex from '@metamask/object-multiplex';
import pump from 'pump';

type TransformCallback = (error?: Error | null, data?: unknown) => void;

interface TransformStream extends NodeJS.ReadWriteStream {
push(chunk: unknown, encoding?: BufferEncoding): boolean;
}

/**
* Returns a stream transform that parses JSON strings passing through
* @return {NodeJS.ReadWriteStream}
*/
function jsonParseStream(): NodeJS.ReadWriteStream {
return Through.obj(function (
this: TransformStream,
serialized: string,
_: string,
cb: TransformCallback
) {
this.push(JSON.parse(serialized));
cb();
});
}

/**
* Returns a stream transform that calls {@code JSON.stringify}
* on objects passing through
* @return {NodeJS.ReadWriteStream} the stream transform
*/
function jsonStringifyStream(): NodeJS.ReadWriteStream {
return Through.obj(function (
this: TransformStream,
obj: unknown,
_: string,
cb: TransformCallback
) {
this.push(JSON.stringify(obj));
cb();
});
}

/**
* Sets up stream multiplexing for the given stream
* @param {NodeJS.ReadWriteStream} connectionStream - the stream to mux
* @return {NodeJS.ReadWriteStream} the multiplexed stream
*/
function setupMultiplex(connectionStream: NodeJS.ReadWriteStream): NodeJS.ReadWriteStream {
const mux = new ObjectMultiplex();
pump(connectionStream, mux, connectionStream, (err: Error | null) => {
if (err) {
console.warn(err);
}
});
return mux as unknown as NodeJS.ReadWriteStream;
}

export { jsonParseStream, jsonStringifyStream, setupMultiplex };
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@
"@types/jest": "^29.5.12",
"@types/lodash": "^4.14.184",
"@types/node": "^20.12.8",
"@types/pump": "^1.1.3",
"@types/qs": "^6.9.15",
"@types/react": "^17.0.11",
"@types/react-native": "^0.64.10",
Expand All @@ -427,6 +428,7 @@
"@types/react-native-vector-icons": "^6.4.13",
"@types/react-native-video": "^5.0.14",
"@types/redux-mock-store": "^1.0.3",
"@types/through2": "^2.0.41",
"@types/url-parse": "^1.4.8",
"@types/valid-url": "^1.0.4",
"@typescript-eslint/eslint-plugin": "^7.10.0",
Expand Down
14 changes: 14 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9814,6 +9814,13 @@
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11"
integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==

"@types/pump@^1.1.3":
version "1.1.3"
resolved "https://registry.yarnpkg.com/@types/pump/-/pump-1.1.3.tgz#127eeed2f416f89ef60697003486ae27c7f0b49e"
integrity sha512-ZyooTTivmOwPfOwLVaszkF8Zq6mvavgjuHYitZhrIjfQAJDH+kIP3N+MzpG1zDAslsHvVz6Q8ECfivix3qLJaQ==
dependencies:
"@types/node" "*"

"@types/punycode@^2.1.0":
version "2.1.4"
resolved "https://registry.yarnpkg.com/@types/punycode/-/punycode-2.1.4.tgz#96f8a47f1ee9fb0d0def5557fe80fac532f966fa"
Expand Down Expand Up @@ -10087,6 +10094,13 @@
dependencies:
"@types/node" "*"

"@types/through2@^2.0.41":
version "2.0.41"
resolved "https://registry.yarnpkg.com/@types/through2/-/through2-2.0.41.tgz#3e5e1720d71ffdfa03c22f2aad6593d12a47034f"
integrity sha512-ryQ0tidWkb1O1JuYvWKyMLYEtOWDqF5mHerJzKz/gQpoAaJq2l/dsMPBF0B5BNVT34rbARYJ5/tsZwLfUi2kwQ==
dependencies:
"@types/node" "*"

"@types/through@*":
version "0.0.30"
resolved "https://registry.yarnpkg.com/@types/through/-/through-0.0.30.tgz#e0e42ce77e897bd6aead6f6ea62aeb135b8a3895"
Expand Down
Loading