Skip to content

Commit 467d4ea

Browse files
committed
feat: Response parser, structures to store hook/function/request handlers
1 parent 87209d9 commit 467d4ea

File tree

4 files changed

+227
-54
lines changed

4 files changed

+227
-54
lines changed

src/constants.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ export const constants = {
55
registerHook: 'registerHook',
66
triggerHook: 'triggerHook',
77
declareFunction: 'declareFunction',
8+
},
9+
responseType: {
10+
moduleRegistered: 'moduleRegistered',
11+
functionResponse: 'functionResponse',
12+
hookRegistered: 'hookRegistered',
13+
hookTriggered: 'hookTriggered',
14+
functionDeclared: 'functionDeclared'
815
}
916
};
1017

src/protocol.ts

Lines changed: 0 additions & 54 deletions
This file was deleted.

src/protocol/GothamConnection.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class GothamConnection {
2+
constructor() {
3+
// Connect to socket
4+
}
5+
6+
async send(_message: object) {
7+
// Send message over socket
8+
}
9+
10+
async receive() {
11+
// Receive a message from the socket
12+
}
13+
}

src/protocol/protocol.ts

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
import { constants } from "../constants";
2+
import { ConnectOpts } from 'net';
3+
import { ConnectionOptions } from 'tls';
4+
5+
interface Dependency {
6+
[type: string]: string;
7+
}
8+
9+
interface FnArgs {
10+
[type: string]: any;
11+
}
12+
13+
interface FnMappings {
14+
[type: string]: Function;
15+
}
16+
17+
interface HookMappings {
18+
[type: string]: Function[]
19+
}
20+
21+
interface ProtocolMessage {
22+
requestId: string;
23+
type: string;
24+
}
25+
26+
interface RegisterModuleRequest extends ProtocolMessage {
27+
type: 'moduleRegistration';
28+
moduleId: string;
29+
version: string;
30+
dependencies: Dependency;
31+
}
32+
33+
interface RegisterModuleResponse extends ProtocolMessage {
34+
type: 'moduleRegistered';
35+
}
36+
37+
interface FunctionCallRequest extends ProtocolMessage {
38+
type: 'functionCall';
39+
function: string;
40+
arguments: FnArgs;
41+
}
42+
43+
interface FunctionCallResponse extends ProtocolMessage {
44+
type: 'functionResponse';
45+
data: FnArgs;
46+
}
47+
48+
interface RegisterHookRequest extends ProtocolMessage {
49+
type: 'registerHook';
50+
hook: string;
51+
}
52+
53+
interface ListenHookResponse extends ProtocolMessage {
54+
type: 'hookRegistered';
55+
}
56+
57+
interface TriggerHookRequest extends ProtocolMessage {
58+
type: 'triggerHook';
59+
hook: string;
60+
}
61+
62+
interface TriggerHookResponse extends ProtocolMessage {
63+
type: 'hookTriggered';
64+
hook: string;
65+
}
66+
67+
interface CallHookResponse extends ProtocolMessage {
68+
type: 'hookTriggered';
69+
hook: string;
70+
}
71+
72+
interface DeclareFunctionRequest extends ProtocolMessage {
73+
type: 'declareFunction';
74+
function: string;
75+
}
76+
77+
interface DeclareFunctionResponse extends ProtocolMessage {
78+
type: 'functionDeclared';
79+
function: string;
80+
}
81+
82+
export class Protocol {
83+
private moduleId: string;
84+
private functions: FnMappings;
85+
private hookListeners: HookMappings;
86+
private requests: FnMappings;
87+
88+
private connection: GothamConnection;
89+
90+
private async sendRequest(obj: any, cb: Function) {
91+
await this.connection.send(obj);
92+
this.requests[obj.requestId] = cb;
93+
}
94+
95+
private generateRequestId() {
96+
return this.moduleId + Date.now();
97+
}
98+
99+
initialize(moduleId: string, version: string, deps: Dependency): RegisterModuleRequest {
100+
this.moduleId = moduleId;
101+
return {
102+
requestId: this.generateRequestId(),
103+
type: 'moduleRegistration',
104+
moduleId: moduleId,
105+
version: version,
106+
dependencies: deps
107+
}
108+
}
109+
110+
registerHook(moduleId: string, hook: string, cb: Function): RegisterHookRequest {
111+
if (this.hookListeners[hook]) {
112+
this.hookListeners[hook] = [cb];
113+
} else {
114+
this.hookListeners[hook].push(cb);
115+
}
116+
return {
117+
requestId: this.generateRequestId(),
118+
type: 'registerHook',
119+
hook: `${moduleId}-${hook}`,
120+
}
121+
}
122+
123+
triggerHook(hook: string): TriggerHookRequest {
124+
return {
125+
requestId: this.generateRequestId(),
126+
type: 'triggerHook',
127+
hook: hook,
128+
}
129+
}
130+
131+
declareFunction(functionName: string, fn: Function): DeclareFunctionRequest {
132+
this.functions[functionName] = fn;
133+
return {
134+
requestId: this.generateRequestId(),
135+
type: 'declareFunction',
136+
function: functionName,
137+
}
138+
}
139+
140+
callFunction(moduleId: string, functionName: string, ...args: FnArgs[]): FunctionCallRequest {
141+
return {
142+
requestId: this.generateRequestId(),
143+
type: 'functionCall',
144+
function: `${moduleId}.${functionName}`,
145+
arguments: args
146+
}
147+
}
148+
149+
hookCall(hook: string) {
150+
if (this.hookListeners[hook]) {
151+
for (const fn of this.hookListeners[hook]) {
152+
fn();
153+
}
154+
}
155+
}
156+
157+
functionCall(functionName: string, ...args: FnArgs[]) {
158+
if (this.functions[functionName]) {
159+
this.functions[functionName]();
160+
}
161+
}
162+
163+
async parseResponse(obj: ProtocolMessage) {
164+
let res;
165+
if (obj.type === constants.responseType.moduleRegistered) {
166+
res = true;
167+
} else if (obj.type === constants.requestType.functionCall) {
168+
res = await this.parseFunctionCall(obj as FunctionCallRequest);
169+
} else if (obj.type === constants.responseType.functionDeclared) {
170+
res = true;
171+
} else if (obj.type === constants.responseType.hookRegistered) {
172+
res = true;
173+
} else if (obj.type === constants.responseType.hookTriggered) {
174+
res = await this.parseHookTriggered(obj as TriggerHookRequest);
175+
} else {
176+
res = false;
177+
}
178+
179+
// Call the callback proviced while sending the request
180+
if (this.requests[obj.requestId]) {
181+
this.requests[obj.requestId](res);
182+
delete this.requests[obj.requestId];
183+
}
184+
}
185+
186+
async parseFunctionCall(obj: FunctionCallRequest) {
187+
if (this.functions[obj.function]) {
188+
let res = this.functions[obj.function]();
189+
if (res instanceof Promise) {
190+
res = await res;
191+
}
192+
await this.sendRequest({
193+
requestId: obj.requestId,
194+
type: 'functionResponse',
195+
data: res
196+
}, ()=>{});
197+
}
198+
}
199+
200+
async parseHookTriggered(obj: TriggerHookRequest) {
201+
if (this.hookListeners[obj.hook]) {
202+
for (const listener of this.hookListeners[obj.hook]) {
203+
listener();
204+
}
205+
}
206+
}
207+
}

0 commit comments

Comments
 (0)