@zap-socket/server 0.0.21 → 0.0.23
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 +6 -8
- package/dist/server.js +26 -27
- package/package.json +1 -1
- package/dist/adapters/types.d.ts +0 -18
- package/dist/adapters/types.js +0 -1
- package/dist/adapters/uWebSocketAdapter.d.ts +0 -0
- package/dist/adapters/uWebSocketAdapter.js +0 -1
- package/dist/adapters/wsAdapter.d.ts +0 -6
- package/dist/adapters/wsAdapter.js +0 -48
- package/dist/types.d.ts +0 -52
- package/dist/types.js +0 -1
package/dist/server.d.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
+
import { WebSocketServer, WebSocket } from "ws";
|
1
2
|
import type { EventMap, ZapEvent, ZapServerEvent } from "@zap-socket/types";
|
2
3
|
import { ZodType, z } from "zod";
|
3
|
-
import { WebSocketAdapter } from "./adapters/types.js";
|
4
4
|
type CorsOptions = {
|
5
5
|
origin: string[];
|
6
6
|
methods: string[];
|
@@ -11,18 +11,16 @@ type ZapServerConstructorT = {
|
|
11
11
|
port: number;
|
12
12
|
events?: EventMap;
|
13
13
|
cors?: CorsOptions;
|
14
|
-
backend?: 'ws' | 'uws';
|
15
14
|
options?: {
|
16
15
|
heartbeatPingFrequency: number;
|
17
16
|
};
|
18
17
|
};
|
19
18
|
type ExtractSendData<T, K extends keyof T> = T[K] extends ZapServerEvent<any> ? T[K]['data'] : T[K] extends ZapEvent<any, any> ? T[K]['emitType'] extends ZodType<any, any, any> ? z.infer<T[K]['emitType']> : ReturnType<T[K]['process']> extends undefined ? undefined : ReturnType<T[K]['process']> : never;
|
20
19
|
export declare class ZapServer<T extends EventMap> {
|
21
|
-
|
22
|
-
private backend;
|
20
|
+
wss: WebSocketServer;
|
23
21
|
onconnect: (handler: (ctx: {
|
24
22
|
id: string;
|
25
|
-
ws:
|
23
|
+
ws: WebSocket;
|
26
24
|
}) => void) => void;
|
27
25
|
private onconnectHandler;
|
28
26
|
private wsToId;
|
@@ -30,7 +28,7 @@ export declare class ZapServer<T extends EventMap> {
|
|
30
28
|
private persistantContext;
|
31
29
|
private _events;
|
32
30
|
private heartbeatMiss;
|
33
|
-
constructor({ port, events,
|
31
|
+
constructor({ port, events, options }: ZapServerConstructorT, callback?: () => void);
|
34
32
|
private removeClient;
|
35
33
|
private heartbeat;
|
36
34
|
private handleMessage;
|
@@ -44,7 +42,7 @@ export declare class ZapServer<T extends EventMap> {
|
|
44
42
|
broadcast: (data?: ExtractSendData<T, K>) => void;
|
45
43
|
}; };
|
46
44
|
get clients(): string[];
|
47
|
-
get socketMap(): Map<string,
|
45
|
+
get socketMap(): Map<string, WebSocket>;
|
48
46
|
}
|
49
|
-
export declare const createZapServer: <T extends EventMap>({ port, events, cors,
|
47
|
+
export declare const createZapServer: <T extends EventMap>({ port, events, cors, options }: ZapServerConstructorT, callback?: () => void) => ZapServer<T>;
|
50
48
|
export {};
|
package/dist/server.js
CHANGED
@@ -1,11 +1,15 @@
|
|
1
|
+
import { WebSocketServer } from "ws";
|
1
2
|
import { serialize, deserialize, generateId } from "./utils.js";
|
2
|
-
import { WSBackend } from "./adapters/wsAdapter.js";
|
3
3
|
const isClientEvent = (event) => {
|
4
|
-
return "process" in event;
|
4
|
+
return "process" in event; // both zapEvent and zapStream have process in them.
|
5
5
|
};
|
6
|
+
// make the server class abstracted away
|
7
|
+
// or atleast the ws interactions
|
8
|
+
// so that we can change the backends
|
9
|
+
// with ease (ws & uWebSocket).
|
6
10
|
export class ZapServer {
|
11
|
+
// public server: http.Server;
|
7
12
|
wss;
|
8
|
-
backend;
|
9
13
|
onconnect;
|
10
14
|
onconnectHandler;
|
11
15
|
wsToId;
|
@@ -13,18 +17,8 @@ export class ZapServer {
|
|
13
17
|
persistantContext;
|
14
18
|
_events = {};
|
15
19
|
heartbeatMiss = new Map();
|
16
|
-
constructor({ port, events = {},
|
17
|
-
|
18
|
-
switch (backend) {
|
19
|
-
// case 'uws':
|
20
|
-
// this.backend = new UWSBackend();
|
21
|
-
// break;
|
22
|
-
case 'ws':
|
23
|
-
default:
|
24
|
-
this.backend = new WSBackend();
|
25
|
-
break;
|
26
|
-
}
|
27
|
-
this.wss = this.backend.createServer({ port });
|
20
|
+
constructor({ port, events = {}, options }, callback) {
|
21
|
+
this.wss = new WebSocketServer({ port });
|
28
22
|
this.wsToId = new Map();
|
29
23
|
this.idToWs = new Map();
|
30
24
|
this.persistantContext = new Map();
|
@@ -75,10 +69,9 @@ export class ZapServer {
|
|
75
69
|
this.broadcastRaw("heartbeat");
|
76
70
|
}
|
77
71
|
async handleMessage(ws, req, message) {
|
78
|
-
const messageStr = message.toString();
|
79
72
|
const id = this.wsToId.get(ws);
|
80
73
|
// setting up socket id
|
81
|
-
if (!id &&
|
74
|
+
if (!id && message.toString() === "OPEN") {
|
82
75
|
const id = generateId();
|
83
76
|
this.wsToId.set(ws, id);
|
84
77
|
this.idToWs.set(id, ws);
|
@@ -89,11 +82,11 @@ export class ZapServer {
|
|
89
82
|
});
|
90
83
|
return;
|
91
84
|
}
|
92
|
-
else if (id &&
|
85
|
+
else if (id && message.toString() === "heartbeat") {
|
93
86
|
this.heartbeatMiss.set(id, 0);
|
94
87
|
}
|
95
88
|
const clientId = this.wsToId.get(ws);
|
96
|
-
const parsedMessage = deserialize(
|
89
|
+
const parsedMessage = deserialize(message.toString());
|
97
90
|
if (!parsedMessage)
|
98
91
|
return;
|
99
92
|
const { event, stream, data, requestId, streamId, batch } = parsedMessage;
|
@@ -105,8 +98,8 @@ export class ZapServer {
|
|
105
98
|
const inputType = eventObj.input;
|
106
99
|
const { success, error } = inputType.safeParse(data);
|
107
100
|
if (!success && error) {
|
101
|
+
// check if the message is of req-res
|
108
102
|
if (requestId) {
|
109
|
-
// Handle validation error response
|
110
103
|
}
|
111
104
|
return;
|
112
105
|
}
|
@@ -123,7 +116,7 @@ export class ZapServer {
|
|
123
116
|
id: clientId,
|
124
117
|
ip: req.socket.remoteAddress,
|
125
118
|
timestamp: Date.now(),
|
126
|
-
size:
|
119
|
+
size: message.toString().length,
|
127
120
|
};
|
128
121
|
const msg = {
|
129
122
|
event: key,
|
@@ -138,7 +131,7 @@ export class ZapServer {
|
|
138
131
|
}
|
139
132
|
// All middleware passed
|
140
133
|
const context = { server: this, id: this.wsToId.get(ws), buffer: ctx };
|
141
|
-
if (requestId) { // req-res
|
134
|
+
if (requestId) { // req-res premitive
|
142
135
|
let result;
|
143
136
|
if (batch) {
|
144
137
|
result = data.map((part) => process(part, context));
|
@@ -158,7 +151,7 @@ export class ZapServer {
|
|
158
151
|
return;
|
159
152
|
ws.send(serialized);
|
160
153
|
}
|
161
|
-
else if (streamId) { // stream
|
154
|
+
else if (streamId) { // stream premitive
|
162
155
|
const consumeStream = async () => {
|
163
156
|
const result = process(data, context);
|
164
157
|
for await (const fragment of result) {
|
@@ -171,15 +164,18 @@ export class ZapServer {
|
|
171
164
|
}
|
172
165
|
sendMessageRaw(clientId, data) {
|
173
166
|
const ws = this.idToWs.get(clientId);
|
167
|
+
// TODO: throw a nice error
|
174
168
|
if (!ws)
|
175
169
|
return;
|
176
170
|
const serializedData = serialize(data);
|
171
|
+
// TODO: throw a nice error
|
177
172
|
if (!serializedData)
|
178
173
|
return;
|
179
174
|
ws.send(serializedData);
|
180
175
|
}
|
181
176
|
sendMessage(event, clientId, data) {
|
182
177
|
const ws = this.idToWs.get(clientId);
|
178
|
+
// TODO: throw a nice error
|
183
179
|
if (!ws)
|
184
180
|
return;
|
185
181
|
const packet = {
|
@@ -187,6 +183,7 @@ export class ZapServer {
|
|
187
183
|
data
|
188
184
|
};
|
189
185
|
const serializedPacket = serialize(packet);
|
186
|
+
// TODO: throw a nice error
|
190
187
|
if (!serializedPacket)
|
191
188
|
return;
|
192
189
|
ws.send(serializedPacket);
|
@@ -194,6 +191,7 @@ export class ZapServer {
|
|
194
191
|
broadcastRaw(data) {
|
195
192
|
const serializedData = serialize(data);
|
196
193
|
if (!serializedData) {
|
194
|
+
// TODO: throw a nice error
|
197
195
|
return;
|
198
196
|
}
|
199
197
|
this.idToWs.forEach((ws) => {
|
@@ -215,13 +213,14 @@ export class ZapServer {
|
|
215
213
|
selectiveBroascast(event, data, connections) {
|
216
214
|
const serialized = serialize(data);
|
217
215
|
if (!serialized) {
|
216
|
+
// TODO: throw a nice error
|
218
217
|
return;
|
219
218
|
}
|
220
219
|
const packet = {
|
221
220
|
event,
|
222
221
|
data
|
223
222
|
};
|
224
|
-
const serializedPacket = serialize(packet);
|
223
|
+
const serializedPacket = serialize(packet); // if data is serializable then packet is too, so no need to check
|
225
224
|
connections
|
226
225
|
.flatMap(x => this.idToWs.get(x) ?? [])
|
227
226
|
.forEach((ws) => {
|
@@ -252,13 +251,13 @@ export class ZapServer {
|
|
252
251
|
}));
|
253
252
|
}
|
254
253
|
get clients() {
|
255
|
-
return
|
254
|
+
return this.idToWs.keys().toArray();
|
256
255
|
}
|
257
256
|
get socketMap() {
|
258
257
|
return this.idToWs;
|
259
258
|
}
|
260
259
|
}
|
261
|
-
export const createZapServer = ({ port, events, cors,
|
262
|
-
const server = new ZapServer({ port, events, cors,
|
260
|
+
export const createZapServer = ({ port, events, cors, options }, callback) => {
|
261
|
+
const server = new ZapServer({ port, events, cors, options }, callback);
|
263
262
|
return server;
|
264
263
|
};
|
package/package.json
CHANGED
package/dist/adapters/types.d.ts
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
import { IncomingMessage } from "http";
|
2
|
-
export interface WebSocketAdapter {
|
3
|
-
send(data: string): void;
|
4
|
-
close(): void;
|
5
|
-
on(event: 'message', listener: (data: Buffer | string) => void): void;
|
6
|
-
on(event: 'close', listener: () => void): void;
|
7
|
-
on(event: 'error', listener: (err: Error) => void): void;
|
8
|
-
}
|
9
|
-
export interface WebSocketServerAdapter {
|
10
|
-
on(event: 'listening', listener: () => void): void;
|
11
|
-
on(event: 'connection', listener: (ws: WebSocketAdapter, req: IncomingMessage) => void): void;
|
12
|
-
close(): void;
|
13
|
-
}
|
14
|
-
export interface WebSocketBackend {
|
15
|
-
createServer(options: {
|
16
|
-
port: number;
|
17
|
-
}): WebSocketServerAdapter;
|
18
|
-
}
|
package/dist/adapters/types.js
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
export {};
|
File without changes
|
@@ -1 +0,0 @@
|
|
1
|
-
"use strict";
|
@@ -1,48 +0,0 @@
|
|
1
|
-
import { WebSocketServer } from "ws";
|
2
|
-
class WSAdapter {
|
3
|
-
ws;
|
4
|
-
constructor(ws) {
|
5
|
-
this.ws = ws;
|
6
|
-
}
|
7
|
-
send(data) {
|
8
|
-
this.ws.send(data);
|
9
|
-
}
|
10
|
-
close() {
|
11
|
-
this.ws.close();
|
12
|
-
}
|
13
|
-
on(event, listener) {
|
14
|
-
if (event === 'message') {
|
15
|
-
this.ws.on('message', (data) => {
|
16
|
-
listener(data.toString());
|
17
|
-
});
|
18
|
-
}
|
19
|
-
else {
|
20
|
-
this.ws.on(event, listener);
|
21
|
-
}
|
22
|
-
}
|
23
|
-
}
|
24
|
-
class WSServerAdapter {
|
25
|
-
wss;
|
26
|
-
constructor(wss) {
|
27
|
-
this.wss = wss;
|
28
|
-
}
|
29
|
-
on(event, listener) {
|
30
|
-
if (event === 'connection') {
|
31
|
-
this.wss.on('connection', (ws, req) => {
|
32
|
-
listener(new WSAdapter(ws), req);
|
33
|
-
});
|
34
|
-
}
|
35
|
-
else {
|
36
|
-
this.wss.on(event, listener);
|
37
|
-
}
|
38
|
-
}
|
39
|
-
close() {
|
40
|
-
this.wss.close();
|
41
|
-
}
|
42
|
-
}
|
43
|
-
export class WSBackend {
|
44
|
-
createServer(options) {
|
45
|
-
const wss = new WebSocketServer(options);
|
46
|
-
return new WSServerAdapter(wss);
|
47
|
-
}
|
48
|
-
}
|
package/dist/types.d.ts
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
import { z } from 'zod';
|
2
|
-
export type ZapServerType<T extends EventMap> = {
|
3
|
-
sendMessageRaw: (clientId: string, data: any) => void;
|
4
|
-
event: {
|
5
|
-
[K in keyof T as T[K] extends (ZapServerEvent<any> | ZapEvent<any, any>) ? K : never]: {
|
6
|
-
send: (clientId: string, data?: (T[K] extends ZapServerEvent<any> ? T[K]["data"] : T[K] extends ZapEvent<any, any> ? ReturnType<T[K]["process"]> : never)) => void;
|
7
|
-
};
|
8
|
-
};
|
9
|
-
};
|
10
|
-
export type Context = {
|
11
|
-
server: any;
|
12
|
-
id: string;
|
13
|
-
buffer: MiddlwareContext;
|
14
|
-
};
|
15
|
-
export type MiddlwareContext = Record<string, any>;
|
16
|
-
export type MiddlewareMetadata = {
|
17
|
-
id: string;
|
18
|
-
ip: string;
|
19
|
-
timestamp: number;
|
20
|
-
size: number;
|
21
|
-
};
|
22
|
-
export type MiddlwareMsg = {
|
23
|
-
event: string;
|
24
|
-
data: any;
|
25
|
-
metadata: MiddlewareMetadata;
|
26
|
-
};
|
27
|
-
export type MiddlewareType = (ctx: MiddlwareContext, msg: MiddlwareMsg) => boolean;
|
28
|
-
export type EventInput = z.ZodTypeAny | undefined;
|
29
|
-
export type ZapEvent<T extends EventInput, R = any, E = unknown> = T extends z.ZodTypeAny ? {
|
30
|
-
input: T;
|
31
|
-
middleware?: MiddlewareType[];
|
32
|
-
process: (input: z.infer<T>, ctx: Context) => R;
|
33
|
-
emitType?: E;
|
34
|
-
} : {
|
35
|
-
input: z.ZodVoid;
|
36
|
-
middleware?: MiddlewareType[];
|
37
|
-
process: (ctx: Context) => R;
|
38
|
-
emitType?: E;
|
39
|
-
};
|
40
|
-
export type ZapStream<T extends EventInput, R> = T extends z.ZodTypeAny ? {
|
41
|
-
input: T;
|
42
|
-
middleware?: MiddlewareType[];
|
43
|
-
process: (input: z.infer<T>, ctx: Context) => AsyncGenerator<R, void, unknown>;
|
44
|
-
} : {
|
45
|
-
input: z.ZodVoid;
|
46
|
-
middleware?: MiddlewareType[];
|
47
|
-
process: (ctx: Context) => AsyncGenerator<R, void, unknown>;
|
48
|
-
};
|
49
|
-
export type ZapServerEvent<T extends z.ZodTypeAny> = {
|
50
|
-
data: z.infer<T>;
|
51
|
-
};
|
52
|
-
export type EventMap = Record<string, ZapEvent<any, any> | ZapServerEvent<any> | ZapStream<any, any>>;
|
package/dist/types.js
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
export {};
|