Skip to content

Commit 22f8272

Browse files
thebongysauravhiremathrakshith-ravi
authored
Pass data along with hooks (#18)
* feat #4: TCP sockets support added * feat #4: Error handling for socket path * fix #7: Import destructuring and minor fixes * fix #7: fs renamed to fsPromises * Update github repo link * fix: Don't fail build if just version check fails if not publishing release * 0.1.0 beta test release (#11) * fix: Correct downloaded atrifact name * Test staging release * Update build.yml * fix: Bump version in package.json on staging * fix: bump version * fix: rename tar file * fix: Rename tar only if doesn't exist * fix * Removed unnecessarry await * fix: Support passing data along with hook Closes #16 Co-authored-by: Saurav M. H <[email protected]> Co-authored-by: Rakshith Ravi <[email protected]>
1 parent fb81e9b commit 22f8272

File tree

8 files changed

+129
-22
lines changed

8 files changed

+129
-22
lines changed

.github/workflows/build.yml

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,13 @@ jobs:
2424
uses: thebongy/version-check@v1
2525
with:
2626
file: package.json
27+
failBuild: false
2728
id: version_check
2829

30+
- name: Bump package.json version (staging)
31+
if: github.ref == 'refs/heads/staging'
32+
run: npm -no-git-tag-version version v${{ steps.version_check.outputs.rawVersion }}-beta
33+
2934
- name: Install dependencies
3035
run: npm ci
3136

@@ -36,12 +41,18 @@ jobs:
3641
run: npm run build
3742

3843
- name: Create tarball
39-
run: npm pack
44+
run: |
45+
npm pack
46+
47+
- name: Rename tar (staging)
48+
if: github.ref == 'refs/heads/staging'
49+
run: mv *.tgz juno-node-${{ steps.version_check.outputs.rawVersion }}.tgz
50+
4051

4152
- name: Upload Artifact
4253
uses: actions/upload-artifact@v2
4354
with:
44-
name: juno-node-${{ steps.version_check.outputs.releaseVersion }}
55+
name: juno-node-${{ steps.version_check.outputs.rawVersion }}
4556
path: ./juno-node-${{ steps.version_check.outputs.rawVersion }}.tgz
4657

4758
# Publish release on push to master
@@ -71,7 +82,7 @@ jobs:
7182
uses: actions/create-release@latest
7283
with:
7384
tag_name: ${{ steps.version_check.outputs.releaseVersion }}
74-
release_name: juno-node-${{ steps.version_check.outputs.releaseVersion }}
85+
release_name: ${{ steps.version_check.outputs.releaseVersion }}
7586
prerelease: false
7687
env:
7788
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -120,14 +131,14 @@ jobs:
120131
- name: Download Artifact
121132
uses: actions/download-artifact@v2
122133
with:
123-
name: juno-node-${{ steps.version_check.outputs.releaseVersion }}
134+
name: juno-node-${{ steps.version_check.outputs.rawVersion }}
124135

125136
- name: Publish Release
126137
id: create_release
127138
uses: actions/create-release@latest
128139
with:
129140
tag_name: ${{ steps.version_check.outputs.releaseVersion }}
130-
release_name: juno-node-${{ steps.version_check.outputs.releaseVersion }}
141+
release_name: ${{ steps.version_check.outputs.releaseVersion }}
131142
prerelease: true
132143
env:
133144
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "juno-node",
3-
"version": "0.0.3",
3+
"version": "0.1.1",
44
"description": "",
55
"keywords": [],
66
"main": "dist/juno-node.cjs.js",
@@ -12,7 +12,7 @@
1212
"author": "thebongy <[email protected]>",
1313
"repository": {
1414
"type": "git",
15-
"url": ""
15+
"url": "https://github.com/bytesonus/juno-node"
1616
},
1717
"license": "MIT",
1818
"engines": {
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { Socket, createConnection } from 'net';
2+
import BaseConnection from './base-connection';
3+
4+
export default class InetSocketConnection extends BaseConnection {
5+
client?: Socket;
6+
host: string;
7+
port: number;
8+
9+
constructor(host: string, port: number) {
10+
super();
11+
this.host = host;
12+
this.port = port;
13+
}
14+
15+
setupConnection(): Promise<void> {
16+
return new Promise(resolve => {
17+
this.client = createConnection(this.port, this.host);
18+
this.client.on('data', (data) => {
19+
const dataLines = data.toString().split(/\r?\n/);
20+
dataLines.map((data) => {
21+
if (data) {
22+
this.onData(Buffer.from(data))
23+
}
24+
});
25+
});
26+
this.client.on('connect', () => {
27+
resolve();
28+
});
29+
});
30+
}
31+
32+
async closeConnection() {
33+
this.client?.destroy();
34+
}
35+
36+
send(message: Buffer): Promise<void> {
37+
return new Promise(resolve => {
38+
this.client?.write(message, () => {
39+
resolve();
40+
});
41+
});
42+
}
43+
}

src/connection/unix-socket-connection.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import * as net from 'net';
1+
import { Socket, createConnection } from 'net';
22
import BaseConnection from './base-connection';
33

4-
export default class SocketConnection extends BaseConnection {
5-
client?: net.Socket;
4+
export default class UnixSocketConnection extends BaseConnection {
5+
client?: Socket;
66
sockPath: string;
77

88
constructor(sockPath: string) {
@@ -12,7 +12,7 @@ export default class SocketConnection extends BaseConnection {
1212

1313
setupConnection(): Promise<void> {
1414
return new Promise(resolve => {
15-
this.client = net.createConnection(this.sockPath);
15+
this.client = createConnection(this.sockPath);
1616
this.client.on('data', (data) => {
1717
const dataLines = data.toString().split(/\r?\n/);
1818
dataLines.map((data) => {

src/juno-node.ts

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { isIP } from 'net';
2+
import { promises as fsPromises } from 'fs';
13
import { BaseProtocol } from './protocol/base-protocol';
24
import BaseConnection from './connection/base-connection';
35
import { JsonProtocol } from './protocol/json-protocol';
@@ -8,7 +10,8 @@ import {
810
TriggerHookRequest,
911
JunoMessage
1012
} from './models/messages';
11-
import SocketConnection from './connection/unix-socket-connection';
13+
import UnixSocketConnection from './connection/unix-socket-connection';
14+
import InetSocketConnection from './connection/inet-socket-connection';
1215

1316
export default class JunoModule {
1417

@@ -27,8 +30,38 @@ export default class JunoModule {
2730
// this.connection.setOnDataListener(this.onDataHandler);
2831
}
2932

30-
public static default(socketPath: string): JunoModule {
31-
return new JunoModule(new SocketConnection(socketPath), new JsonProtocol());
33+
public static async default(socketPath: string) {
34+
const [ host, port ] = socketPath.split(':');
35+
36+
if (isIP(host) && !isNaN(Number(port))) {
37+
return this.fromInetSocket(host, Number(port));
38+
}
39+
if ( (await fsPromises.lstat(socketPath)).isSocket() ) {
40+
return this.fromUnixSocket(socketPath);
41+
}
42+
43+
throw new Error('Invalid socket object. Only unix domain sockets and Inet sockets are allowed');
44+
45+
}
46+
47+
public static async fromUnixSocket(path: string) {
48+
// Return Error if invoked from windows
49+
if (process.platform == 'win32') {
50+
throw new Error('Unix sockets are not supported on windows');
51+
}
52+
if ( (await fsPromises.lstat(path)).isSocket() ) {
53+
return new JunoModule(new UnixSocketConnection(path), new JsonProtocol());
54+
}
55+
56+
throw new Error('Invalid unix socket path');
57+
}
58+
59+
public static async fromInetSocket(host: string, port: number) {
60+
if (isIP(host) && !isNaN(Number(port))) {
61+
return new JunoModule(new InetSocketConnection(host, port), new JsonProtocol());
62+
}
63+
64+
throw new Error('Invalid Inet socket address. Use the format `{host}:{port}`')
3265
}
3366

3467
public async initialize(
@@ -77,9 +110,9 @@ export default class JunoModule {
77110
);
78111
}
79112

80-
public async triggerHook(hook: string) {
113+
public async triggerHook(hook: string, data: any = {}) {
81114
return this.sendRequest(
82-
this.protocol.triggerHook(hook)
115+
this.protocol.triggerHook(hook, data)
83116
);
84117
}
85118

@@ -125,7 +158,7 @@ export default class JunoModule {
125158
break;
126159
}
127160
case ResponseTypes.FunctionResponse: {
128-
value = await (response as FunctionCallResponse).data;
161+
value = (response as FunctionCallResponse).data;
129162
break;
130163
}
131164
case ResponseTypes.FunctionDeclared: {
@@ -186,7 +219,7 @@ export default class JunoModule {
186219
}
187220
} else if (this.hookListeners[request.hook]) {
188221
for (const listener of this.hookListeners[request.hook]) {
189-
listener();
222+
listener(request.data || {});
190223
}
191224
}
192225
return true;

src/models/messages.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ export interface RegisterHookRequest extends BaseMessage {
2828

2929
export interface TriggerHookRequest extends BaseMessage {
3030
hook: string;
31+
data: {
32+
[type: string]: any
33+
};
3134
}
3235

3336
export interface RegisterModuleResponse extends BaseMessage {
@@ -43,7 +46,6 @@ export interface ListenHookResponse extends BaseMessage {
4346

4447
export interface TriggerHookResponse extends BaseMessage {
4548
hook: string;
46-
data?: any;
4749
}
4850

4951
export interface DeclareFunctionResponse extends BaseMessage {

src/protocol/base-protocol.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,12 @@ export abstract class BaseProtocol {
4242
};
4343
}
4444

45-
public triggerHook(hook: string): TriggerHookRequest {
45+
public triggerHook(hook: string, data: any): TriggerHookRequest {
4646
return {
4747
requestId: this.generateRequestId(),
4848
type: RequestTypes.TriggerHook,
49-
hook
49+
hook,
50+
data
5051
};
5152
}
5253

test/juno-node.test.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,29 @@ makeConnectionTests('Test if requests constructed correctly', function () {
106106
});
107107
});
108108

109-
it('triggerHook', function () {
109+
it('triggerHook with no args', function () {
110110
this.test.module.triggerHook('test_hook');
111111
const message = this.test.getLatestSent();
112112
expect(message).excluding('requestId').to.deep.equal({
113113
type: 7,
114114
hook: 'test_hook',
115+
data: {},
116+
});
117+
});
118+
119+
it('triggerHook with args', function () {
120+
this.test.module.triggerHook('test_hook', {
121+
a:1,
122+
b:2,
123+
});
124+
const message = this.test.getLatestSent();
125+
expect(message).excluding('requestId').to.deep.equal({
126+
type: 7,
127+
hook: 'test_hook',
128+
data: {
129+
a: 1,
130+
b: 2,
131+
}
115132
});
116133
});
117134
});

0 commit comments

Comments
 (0)