@zap-socket/server 0.0.17 → 0.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/server.d.ts CHANGED
@@ -30,6 +30,7 @@ export declare class ZapServer<T extends EventMap> {
30
30
  constructor({ port, events, options }: ZapServerConstructorT, callback?: () => void);
31
31
  private removeClient;
32
32
  private heartbeat;
33
+ private handleMessage;
33
34
  sendMessageRaw(clientId: string, data: any): void;
34
35
  sendMessage(event: keyof T, clientId: string, data: any): void;
35
36
  broadcastRaw(data: any): void;
package/dist/server.js CHANGED
@@ -13,35 +13,6 @@ export class ZapServer {
13
13
  _events = {};
14
14
  heartbeatMiss = new Map();
15
15
  constructor({ port, events = {}, options }, callback) {
16
- // this.server = http.createServer((req, res) => {
17
- //
18
- // if (cors) {
19
- // const origin = req.headers.origin;
20
- //
21
- // if (origin && cors.origin && (cors.origin.includes(origin) || cors.origin.includes("*"))) {
22
- // res.setHeader('Access-Control-Allow-Origin', origin);
23
- // }
24
- // if (cors.methods) {
25
- // res.setHeader("Access-Control-Allow-Methods", cors.methods.join(", "));
26
- // }
27
- // if (cors.headers) {
28
- // res.setHeader("Access-Control-Allow-Headers", cors.headers.join(", "));
29
- // }
30
- // if (cors.credentials !== undefined) {
31
- // res.setHeader("Access-Control-Allow-Credentials", cors.credentials ? "true" : "false");
32
- // }
33
- // }
34
- //
35
- // // pre-flight response
36
- // if (req.method === "OPTIONS") {
37
- // res.writeHead(204);
38
- // res.end();
39
- // return;
40
- // }
41
- //
42
- // res.writeHead(404);
43
- // res.end();
44
- // });
45
16
  this.wss = new WebSocketServer({ port });
46
17
  this.wsToId = new Map();
47
18
  this.idToWs = new Map();
@@ -58,95 +29,8 @@ export class ZapServer {
58
29
  callback();
59
30
  });
60
31
  this.wss.on("connection", (ws, req) => {
61
- ws.on("message", async (message) => {
62
- const id = this.wsToId.get(ws);
63
- // setting up socket id
64
- if (!id && message.toString() === "OPEN") {
65
- const id = generateId();
66
- this.wsToId.set(ws, id);
67
- this.idToWs.set(id, ws);
68
- ws.send("ID " + id);
69
- this.onconnectHandler({
70
- id,
71
- ws
72
- });
73
- return;
74
- }
75
- else if (id && message.toString() === "heartbeat") {
76
- this.heartbeatMiss.set(id, 0);
77
- }
78
- const clientId = this.wsToId.get(ws);
79
- const parsedMessage = deserialize(message.toString());
80
- if (!parsedMessage)
81
- return;
82
- const { event, stream, data, requestId, streamId, batch } = parsedMessage;
83
- const key = event || stream;
84
- const eventObj = this._events[key];
85
- if (!eventObj || !isClientEvent(eventObj))
86
- return;
87
- // Type validation.
88
- const inputType = eventObj.input;
89
- const { success, error } = inputType.safeParse(data);
90
- if (!success && error) {
91
- // check if the message is of req-res
92
- if (requestId) {
93
- }
94
- return;
95
- }
96
- const { process, middleware } = eventObj;
97
- // Setup middleware context
98
- const ctx = {};
99
- if (middleware) {
100
- for (const m of middleware) {
101
- const metadata = {
102
- id: clientId,
103
- ip: req.socket.remoteAddress,
104
- timestamp: Date.now(),
105
- size: message.toString().length,
106
- };
107
- const msg = {
108
- event: key,
109
- data: parsedMessage,
110
- metadata,
111
- };
112
- let shouldPass = m(ctx, msg);
113
- shouldPass = shouldPass instanceof Promise ? await shouldPass : shouldPass;
114
- if (!shouldPass)
115
- return;
116
- }
117
- }
118
- // All middleware passed
119
- const context = { server: this, id: this.wsToId.get(ws), buffer: ctx };
120
- if (requestId) { // req-res premitive
121
- let result;
122
- if (batch) {
123
- result = data.map((part) => process(part, context));
124
- }
125
- else {
126
- result = process(data, context);
127
- if (result instanceof Promise) {
128
- result = await result;
129
- }
130
- }
131
- if (result === undefined) { // just ACK the request process returns nothing
132
- ws.send("ACK " + requestId);
133
- return;
134
- }
135
- const serialized = serialize({ requestId, event: key, data: result });
136
- if (!serialized)
137
- return;
138
- ws.send(serialized);
139
- }
140
- else if (streamId) { // stream premitive
141
- const consumeStream = async () => {
142
- const result = process(data, context);
143
- for await (const fragment of result) {
144
- this.sendMessageRaw(clientId, { streamId, fragment });
145
- }
146
- this.sendMessageRaw(clientId, { streamId, done: true });
147
- };
148
- consumeStream();
149
- }
32
+ ws.on("message", (message) => {
33
+ this.handleMessage(ws, req, message);
150
34
  });
151
35
  ws.on("close", () => {
152
36
  this.removeClient(ws);
@@ -178,6 +62,96 @@ export class ZapServer {
178
62
  });
179
63
  this.broadcastRaw("heartbeat");
180
64
  }
65
+ async handleMessage(ws, req, message) {
66
+ const id = this.wsToId.get(ws);
67
+ // setting up socket id
68
+ if (!id && message.toString() === "OPEN") {
69
+ const id = generateId();
70
+ this.wsToId.set(ws, id);
71
+ this.idToWs.set(id, ws);
72
+ ws.send("ID " + id);
73
+ this.onconnectHandler({
74
+ id,
75
+ ws
76
+ });
77
+ return;
78
+ }
79
+ else if (id && message.toString() === "heartbeat") {
80
+ this.heartbeatMiss.set(id, 0);
81
+ }
82
+ const clientId = this.wsToId.get(ws);
83
+ const parsedMessage = deserialize(message.toString());
84
+ if (!parsedMessage)
85
+ return;
86
+ const { event, stream, data, requestId, streamId, batch } = parsedMessage;
87
+ const key = event || stream;
88
+ const eventObj = this._events[key];
89
+ if (!eventObj || !isClientEvent(eventObj))
90
+ return;
91
+ // Type validation.
92
+ const inputType = eventObj.input;
93
+ const { success, error } = inputType.safeParse(data);
94
+ if (!success && error) {
95
+ // check if the message is of req-res
96
+ if (requestId) {
97
+ }
98
+ return;
99
+ }
100
+ const { process, middleware } = eventObj;
101
+ // Setup middleware context
102
+ const ctx = {};
103
+ if (middleware) {
104
+ for (const m of middleware) {
105
+ const metadata = {
106
+ id: clientId,
107
+ ip: req.socket.remoteAddress,
108
+ timestamp: Date.now(),
109
+ size: message.toString().length,
110
+ };
111
+ const msg = {
112
+ event: key,
113
+ data: parsedMessage,
114
+ metadata,
115
+ };
116
+ let shouldPass = m(ctx, msg);
117
+ shouldPass = shouldPass instanceof Promise ? await shouldPass : shouldPass;
118
+ if (!shouldPass)
119
+ return;
120
+ }
121
+ }
122
+ // All middleware passed
123
+ const context = { server: this, id: this.wsToId.get(ws), buffer: ctx };
124
+ if (requestId) { // req-res premitive
125
+ let result;
126
+ if (batch) {
127
+ result = data.map((part) => process(part, context));
128
+ }
129
+ else {
130
+ result = process(data, context);
131
+ if (result instanceof Promise) {
132
+ result = await result;
133
+ }
134
+ }
135
+ if (result === undefined) { // just ACK the request process returns nothing
136
+ ws.send("ACK " + requestId);
137
+ return;
138
+ }
139
+ const serialized = serialize({ requestId, event: key, data: result });
140
+ if (!serialized)
141
+ return;
142
+ ws.send(serialized);
143
+ }
144
+ else if (streamId) { // stream premitive
145
+ const consumeStream = async () => {
146
+ const result = process(data, context);
147
+ for await (const fragment of result) {
148
+ this.sendMessageRaw(clientId, { streamId, fragment });
149
+ }
150
+ this.sendMessageRaw(clientId, { streamId, done: true });
151
+ };
152
+ consumeStream();
153
+ }
154
+ }
181
155
  sendMessageRaw(clientId, data) {
182
156
  const ws = this.idToWs.get(clientId);
183
157
  // TODO: throw a nice error
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zap-socket/server",
3
- "version": "0.0.17",
3
+ "version": "0.0.18",
4
4
  "description": "A fully typesafe tRPC-inspired WebSocket library with Zod validation, req-res model, and native subscriptions.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -24,6 +24,7 @@
24
24
  },
25
25
  "dependencies": {
26
26
  "@zap-socket/types": "^0.0.9",
27
+ "uWebSockets.js": "uNetworking/uWebSockets.js#v20.51.0",
27
28
  "zod": "^3.24.2"
28
29
  }
29
30
  }