@zap-socket/server 0.0.22 → 0.0.24

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
@@ -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
- private wss;
22
- private backend;
20
+ wss: WebSocketServer;
23
21
  onconnect: (handler: (ctx: {
24
22
  id: string;
25
- ws: WebSocketAdapter;
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, backend, options }: ZapServerConstructorT, callback?: () => void);
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, WebSocketAdapter>;
45
+ get socketMap(): Map<string, WebSocket>;
48
46
  }
49
- export declare const createZapServer: <T extends EventMap>({ port, events, cors, backend, options }: ZapServerConstructorT, callback?: () => void) => ZapServer<T>;
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 = {}, backend = 'ws', options }, callback) {
17
- // Select backend
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 && messageStr === "OPEN") {
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 && messageStr === "heartbeat") {
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(messageStr);
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: messageStr.length,
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 primitive
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 primitive
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 Array.from(this.idToWs.keys());
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, backend = 'ws', options }, callback) => {
262
- const server = new ZapServer({ port, events, cors, backend, options }, callback);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zap-socket/server",
3
- "version": "0.0.22",
3
+ "version": "0.0.24",
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",
@@ -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
- }
@@ -1 +0,0 @@
1
- export {};
File without changes
@@ -1 +0,0 @@
1
- "use strict";
@@ -1,6 +0,0 @@
1
- import { WebSocketServerAdapter, WebSocketBackend } from "./types.js";
2
- export declare class WSBackend implements WebSocketBackend {
3
- createServer(options: {
4
- port: number;
5
- }): WebSocketServerAdapter;
6
- }
@@ -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 {};