@ooneex/socket 0.16.0 → 1.0.0
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/README.md +7 -27
- package/package.json +5 -14
- package/dist/client/index.d.ts +0 -43
- package/dist/client/index.js +0 -4
- package/dist/client/index.js.map +0 -10
package/README.md
CHANGED
|
@@ -1,51 +1,31 @@
|
|
|
1
1
|
# @ooneex/socket
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
WebSocket server implementation with room management, event broadcasting, client tracking, and middleware integration for real-time applications.
|
|
4
4
|
|
|
5
5
|

|
|
6
|
-

|
|
7
|
-

|
|
8
6
|

|
|
9
7
|

|
|
10
8
|
|
|
11
9
|
## Features
|
|
12
10
|
|
|
13
|
-
✅ **
|
|
11
|
+
✅ **IController Interface** - Standard interface for WebSocket controller implementations with typed context
|
|
14
12
|
|
|
15
|
-
✅ **Channel Management** - Subscribe, publish, and
|
|
13
|
+
✅ **Channel Management** - Subscribe, unsubscribe, publish, and send messages through typed channel API
|
|
16
14
|
|
|
17
|
-
✅ **Pub/Sub Support** - Built-in publish/subscribe pattern
|
|
15
|
+
✅ **Pub/Sub Support** - Built-in publish/subscribe pattern with `channel.publish()` and `channel.subscribe()`
|
|
18
16
|
|
|
19
|
-
✅ **Type-Safe** -
|
|
17
|
+
✅ **Type-Safe Context** - Generic `ContextType` extending the HTTP controller context with WebSocket channel operations
|
|
20
18
|
|
|
21
|
-
✅ **
|
|
19
|
+
✅ **Connection Lifecycle** - Close connections with status codes and reasons via `channel.close()`
|
|
22
20
|
|
|
23
|
-
✅ **
|
|
24
|
-
|
|
25
|
-
✅ **Client Library** - Separate client export for frontend applications
|
|
21
|
+
✅ **Framework Integration** - Extends `@ooneex/controller` context and works with `@ooneex/routing` socket decorators
|
|
26
22
|
|
|
27
23
|
## Installation
|
|
28
24
|
|
|
29
|
-
### Bun
|
|
30
25
|
```bash
|
|
31
26
|
bun add @ooneex/socket
|
|
32
27
|
```
|
|
33
28
|
|
|
34
|
-
### pnpm
|
|
35
|
-
```bash
|
|
36
|
-
pnpm add @ooneex/socket
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
### Yarn
|
|
40
|
-
```bash
|
|
41
|
-
yarn add @ooneex/socket
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
### npm
|
|
45
|
-
```bash
|
|
46
|
-
npm install @ooneex/socket
|
|
47
|
-
```
|
|
48
|
-
|
|
49
29
|
## Usage
|
|
50
30
|
|
|
51
31
|
### Basic WebSocket Controller
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ooneex/socket",
|
|
3
|
-
"description": "WebSocket server
|
|
4
|
-
"version": "0.
|
|
3
|
+
"description": "WebSocket server implementation with room management, event broadcasting, client tracking, and middleware integration for real-time applications",
|
|
4
|
+
"version": "1.0.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist",
|
|
@@ -18,27 +18,18 @@
|
|
|
18
18
|
"default": "./dist/index.js"
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
|
-
"./client": {
|
|
22
|
-
"import": {
|
|
23
|
-
"types": "./dist/client/index.d.ts",
|
|
24
|
-
"default": "./dist/client/index.js"
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
21
|
"./package.json": "./package.json"
|
|
28
22
|
},
|
|
29
23
|
"license": "MIT",
|
|
30
24
|
"scripts": {
|
|
31
|
-
"test": "bun test tests",
|
|
32
25
|
"build": "bunup",
|
|
33
26
|
"lint": "tsgo --noEmit && bunx biome lint",
|
|
34
27
|
"npm:publish": "bun publish --tolerate-republish --access public"
|
|
35
28
|
},
|
|
36
29
|
"devDependencies": {
|
|
37
|
-
"@ooneex/
|
|
38
|
-
"@ooneex/
|
|
39
|
-
"@ooneex/http-
|
|
40
|
-
"@ooneex/http-response": "0.15.0",
|
|
41
|
-
"@ooneex/translation": "0.0.16"
|
|
30
|
+
"@ooneex/controller": "0.17.1",
|
|
31
|
+
"@ooneex/http-request": "0.17.0",
|
|
32
|
+
"@ooneex/http-response": "0.17.0"
|
|
42
33
|
},
|
|
43
34
|
"keywords": [
|
|
44
35
|
"bun",
|
package/dist/client/index.d.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { ResponseDataType as ResponseDataType2 } from "@ooneex/http-response";
|
|
2
|
-
import { ResponseDataType } from "@ooneex/http-response";
|
|
3
|
-
import { LocaleInfoType } from "@ooneex/translation";
|
|
4
|
-
type RequestDataType = {
|
|
5
|
-
payload?: Record<string, unknown>;
|
|
6
|
-
queries?: Record<string, boolean | number | bigint | string>;
|
|
7
|
-
language?: LocaleInfoType;
|
|
8
|
-
};
|
|
9
|
-
interface ISocket<
|
|
10
|
-
SendData extends RequestDataType = RequestDataType,
|
|
11
|
-
Response extends Record<string, unknown> = Record<string, unknown>
|
|
12
|
-
> {
|
|
13
|
-
close: (code?: number, reason?: string) => void;
|
|
14
|
-
send: (data: SendData) => void;
|
|
15
|
-
onMessage: (handler: (response: ResponseDataType<Response>) => void) => void;
|
|
16
|
-
onOpen: (handler: (event: Event) => void) => void;
|
|
17
|
-
onClose: (handler: (event: CloseEvent) => void) => void;
|
|
18
|
-
onError: (handler: (event: Event, response?: ResponseDataType<Response>) => void) => void;
|
|
19
|
-
}
|
|
20
|
-
declare class Socket<
|
|
21
|
-
SendData extends RequestDataType = RequestDataType,
|
|
22
|
-
Response extends Record<string, unknown> = Record<string, unknown>
|
|
23
|
-
> implements ISocket<SendData, Response> {
|
|
24
|
-
private readonly url;
|
|
25
|
-
private ws;
|
|
26
|
-
private messageHandler?;
|
|
27
|
-
private openHandler?;
|
|
28
|
-
private errorHandler?;
|
|
29
|
-
private closeHandler?;
|
|
30
|
-
private queuedMessages;
|
|
31
|
-
constructor(url: string);
|
|
32
|
-
close(code?: number, reason?: string): void;
|
|
33
|
-
send(data: SendData): void;
|
|
34
|
-
private sendRaw;
|
|
35
|
-
onMessage(handler: (response: ResponseDataType2<Response>) => void): void;
|
|
36
|
-
onOpen(handler: (event: Event) => void): void;
|
|
37
|
-
onClose(handler: (event: CloseEvent) => void): void;
|
|
38
|
-
onError(handler: (event: Event, response?: ResponseDataType2<Response>) => void): void;
|
|
39
|
-
private buildURL;
|
|
40
|
-
private setupEventHandlers;
|
|
41
|
-
private flushQueuedMessages;
|
|
42
|
-
}
|
|
43
|
-
export { Socket, RequestDataType, ISocket };
|
package/dist/client/index.js
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
class n{url;ws;messageHandler;openHandler;errorHandler;closeHandler;queuedMessages=[];constructor(e){this.url=e;let o=this.buildURL(this.url);this.ws=new WebSocket(o),this.setupEventHandlers()}close(e,o){this.ws.close(e,o)}send(e){let o=JSON.stringify(e);this.sendRaw(o)}sendRaw(e){if(this.ws&&this.ws.readyState===WebSocket.OPEN)this.ws.send(e);else this.queuedMessages.push(e)}onMessage(e){this.messageHandler=e}onOpen(e){this.openHandler=e}onClose(e){this.closeHandler=e}onError(e){this.errorHandler=e}buildURL(e){if(e.startsWith("ws://")||e.startsWith("wss://"))return e;if(e.startsWith("http://"))e=e.replace("http://","ws://");else if(e.startsWith("https://"))e=e.replace("https://","wss://");else if(!e.startsWith("ws://")&&!e.startsWith("wss://"))e=`wss://${e}`;return e}setupEventHandlers(){this.ws.onmessage=(e)=>{if(this.messageHandler){let o=JSON.parse(e.data);if(o.done)this.ws.close();if(o.success){this.messageHandler(o);return}if(this.errorHandler)this.errorHandler(e,o)}},this.ws.onopen=(e)=>{if(this.flushQueuedMessages(),this.openHandler)this.openHandler(e)},this.ws.onerror=(e)=>{if(this.errorHandler)this.errorHandler(e)},this.ws.onclose=(e)=>{if(this.closeHandler)this.closeHandler(e)}}flushQueuedMessages(){while(this.queuedMessages.length>0){let e=this.queuedMessages.shift();if(e!==void 0&&this.ws.readyState===WebSocket.OPEN)this.ws.send(e)}}}export{n as Socket};
|
|
3
|
-
|
|
4
|
-
//# debugId=DDC4BBAA6B121D9B64756E2164756E21
|
package/dist/client/index.js.map
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["src/client/Socket.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"import type { ResponseDataType } from \"@ooneex/http-response\";\nimport type { ISocket, RequestDataType } from \"./types\";\n\nexport class Socket<\n SendData extends RequestDataType = RequestDataType,\n Response extends Record<string, unknown> = Record<string, unknown>,\n> implements ISocket<SendData, Response>\n{\n private ws: WebSocket;\n private messageHandler?: (response: ResponseDataType<Response>) => void;\n private openHandler?: (event: Event) => void;\n private errorHandler?: (event: Event, response?: ResponseDataType<Response>) => void;\n private closeHandler?: (event: CloseEvent) => void;\n private queuedMessages: (string | ArrayBufferLike | Blob | ArrayBufferView)[] = [];\n\n constructor(private readonly url: string) {\n const fullURL = this.buildURL(this.url);\n this.ws = new WebSocket(fullURL);\n this.setupEventHandlers();\n }\n\n public close(code?: number, reason?: string): void {\n this.ws.close(code, reason);\n }\n\n public send(data: SendData): void {\n const text = JSON.stringify(data);\n this.sendRaw(text);\n }\n\n private sendRaw(payload: string | ArrayBufferLike | Blob | ArrayBufferView): void {\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n this.ws.send(payload);\n } else {\n this.queuedMessages.push(payload);\n }\n }\n\n public onMessage(handler: (response: ResponseDataType<Response>) => void): void {\n this.messageHandler = handler;\n }\n\n public onOpen(handler: (event: Event) => void): void {\n this.openHandler = handler;\n }\n\n public onClose(handler: (event: CloseEvent) => void): void {\n this.closeHandler = handler;\n }\n\n public onError(handler: (event: Event, response?: ResponseDataType<Response>) => void): void {\n this.errorHandler = handler;\n }\n\n private buildURL(url: string): string {\n if (url.startsWith(\"ws://\") || url.startsWith(\"wss://\")) {\n return url;\n }\n\n // Convert HTTP(S) to WebSocket protocol\n if (url.startsWith(\"http://\")) {\n url = url.replace(\"http://\", \"ws://\");\n } else if (url.startsWith(\"https://\")) {\n url = url.replace(\"https://\", \"wss://\");\n } else if (!url.startsWith(\"ws://\") && !url.startsWith(\"wss://\")) {\n url = `wss://${url}`;\n }\n\n return url;\n }\n\n private setupEventHandlers(): void {\n this.ws.onmessage = (event: MessageEvent) => {\n if (this.messageHandler) {\n const data = JSON.parse(event.data) as ResponseDataType<Response>;\n\n if (data.done) {\n this.ws.close();\n }\n\n if (data.success) {\n this.messageHandler(data);\n\n return;\n }\n\n if (this.errorHandler) {\n this.errorHandler(event, data);\n }\n }\n };\n\n this.ws.onopen = (event: Event) => {\n this.flushQueuedMessages();\n if (this.openHandler) {\n this.openHandler(event);\n }\n };\n\n this.ws.onerror = (event: Event) => {\n if (this.errorHandler) {\n this.errorHandler(event);\n }\n };\n\n this.ws.onclose = (event: CloseEvent) => {\n if (this.closeHandler) {\n this.closeHandler(event);\n }\n };\n }\n\n private flushQueuedMessages(): void {\n while (this.queuedMessages.length > 0) {\n const message = this.queuedMessages.shift();\n if (message !== undefined && this.ws.readyState === WebSocket.OPEN) {\n this.ws.send(message);\n }\n }\n }\n}\n"
|
|
6
|
-
],
|
|
7
|
-
"mappings": ";AAGO,MAAM,CAIb,CAQ+B,IAPrB,GACA,eACA,YACA,aACA,aACA,eAAwE,CAAC,EAEjF,WAAW,CAAkB,EAAa,CAAb,WAC3B,IAAM,EAAU,KAAK,SAAS,KAAK,GAAG,EACtC,KAAK,GAAK,IAAI,UAAU,CAAO,EAC/B,KAAK,mBAAmB,EAGnB,KAAK,CAAC,EAAe,EAAuB,CACjD,KAAK,GAAG,MAAM,EAAM,CAAM,EAGrB,IAAI,CAAC,EAAsB,CAChC,IAAM,EAAO,KAAK,UAAU,CAAI,EAChC,KAAK,QAAQ,CAAI,EAGX,OAAO,CAAC,EAAkE,CAChF,GAAI,KAAK,IAAM,KAAK,GAAG,aAAe,UAAU,KAC9C,KAAK,GAAG,KAAK,CAAO,EAEpB,UAAK,eAAe,KAAK,CAAO,EAI7B,SAAS,CAAC,EAA+D,CAC9E,KAAK,eAAiB,EAGjB,MAAM,CAAC,EAAuC,CACnD,KAAK,YAAc,EAGd,OAAO,CAAC,EAA4C,CACzD,KAAK,aAAe,EAGf,OAAO,CAAC,EAA8E,CAC3F,KAAK,aAAe,EAGd,QAAQ,CAAC,EAAqB,CACpC,GAAI,EAAI,WAAW,OAAO,GAAK,EAAI,WAAW,QAAQ,EACpD,OAAO,EAIT,GAAI,EAAI,WAAW,SAAS,EAC1B,EAAM,EAAI,QAAQ,UAAW,OAAO,EAC/B,QAAI,EAAI,WAAW,UAAU,EAClC,EAAM,EAAI,QAAQ,WAAY,QAAQ,EACjC,QAAI,CAAC,EAAI,WAAW,OAAO,GAAK,CAAC,EAAI,WAAW,QAAQ,EAC7D,EAAM,SAAS,IAGjB,OAAO,EAGD,kBAAkB,EAAS,CACjC,KAAK,GAAG,UAAY,CAAC,IAAwB,CAC3C,GAAI,KAAK,eAAgB,CACvB,IAAM,EAAO,KAAK,MAAM,EAAM,IAAI,EAElC,GAAI,EAAK,KACP,KAAK,GAAG,MAAM,EAGhB,GAAI,EAAK,QAAS,CAChB,KAAK,eAAe,CAAI,EAExB,OAGF,GAAI,KAAK,aACP,KAAK,aAAa,EAAO,CAAI,IAKnC,KAAK,GAAG,OAAS,CAAC,IAAiB,CAEjC,GADA,KAAK,oBAAoB,EACrB,KAAK,YACP,KAAK,YAAY,CAAK,GAI1B,KAAK,GAAG,QAAU,CAAC,IAAiB,CAClC,GAAI,KAAK,aACP,KAAK,aAAa,CAAK,GAI3B,KAAK,GAAG,QAAU,CAAC,IAAsB,CACvC,GAAI,KAAK,aACP,KAAK,aAAa,CAAK,GAKrB,mBAAmB,EAAS,CAClC,MAAO,KAAK,eAAe,OAAS,EAAG,CACrC,IAAM,EAAU,KAAK,eAAe,MAAM,EAC1C,GAAI,IAAY,QAAa,KAAK,GAAG,aAAe,UAAU,KAC5D,KAAK,GAAG,KAAK,CAAO,GAI5B",
|
|
8
|
-
"debugId": "DDC4BBAA6B121D9B64756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|