@syncar/server 1.0.0-alpha.1
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 +140 -0
- package/dist/index.d.ts +3602 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +57 -0
package/README.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# @synca/server
|
|
2
|
+
|
|
3
|
+
> Node.js WebSocket server for real-time synchronization with pub/sub broadcasting and composable middleware.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@synca/server)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Real-time WebSocket Communication** - Fast, bidirectional messaging powered by `ws`.
|
|
11
|
+
- **Composable Middleware** - Hono-style middleware for auth, logging, rate limiting, and more.
|
|
12
|
+
- **Broadcast & Multicast Channels** - Topic-based messaging patterns with automatic chunking.
|
|
13
|
+
- **Handshake Authentication** - Dedicated hook for authenticating clients during connection.
|
|
14
|
+
- **Type-Safe API** - Full TypeScript support for messages, context, and state.
|
|
15
|
+
- **Automatic Chunking** - Handles high-volume broadcasts without blocking the event loop.
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @synca/server
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { createSyncaServer } from '@synca/server'
|
|
27
|
+
|
|
28
|
+
const server = createSyncaServer({ port: 3000 })
|
|
29
|
+
|
|
30
|
+
// 1. Add Middleware
|
|
31
|
+
server.use(async (c, next) => {
|
|
32
|
+
console.log(`[${c.req.action}] client:${c.req.client?.id}`)
|
|
33
|
+
await next()
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
// 2. Create Channels
|
|
37
|
+
const chat = server.createMulticast<string>('chat')
|
|
38
|
+
|
|
39
|
+
// Optional: Custom message handling (disables auto-relay)
|
|
40
|
+
chat.onMessage((data, client) => {
|
|
41
|
+
console.log(`Received: ${data}`)
|
|
42
|
+
chat.publish(`User said: ${data}`, { exclude: [client.id] })
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
// 3. Start Server
|
|
46
|
+
await server.start()
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Middleware
|
|
50
|
+
|
|
51
|
+
Synca uses a powerful middleware system inspired by Hono. Middleware can intercept `connect`, `disconnect`, `message`, `subscribe`, and `unsubscribe` actions.
|
|
52
|
+
|
|
53
|
+
### Built-in Middleware
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import {
|
|
57
|
+
createAuthMiddleware,
|
|
58
|
+
createLoggingMiddleware,
|
|
59
|
+
createRateLimitMiddleware
|
|
60
|
+
} from '@synca/server'
|
|
61
|
+
|
|
62
|
+
// Global Auth
|
|
63
|
+
server.use(createAuthMiddleware({
|
|
64
|
+
verifyToken: async (token) => ({ id: '123', name: 'User' })
|
|
65
|
+
}))
|
|
66
|
+
|
|
67
|
+
// Channel-specific Middleware
|
|
68
|
+
const adminChannel = server.createMulticast('admin')
|
|
69
|
+
adminChannel.use(async (c, next) => {
|
|
70
|
+
if (c.get('user')?.role !== 'admin') {
|
|
71
|
+
return c.reject('Unauthorized')
|
|
72
|
+
}
|
|
73
|
+
await next()
|
|
74
|
+
})
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Handshake Authentication
|
|
78
|
+
|
|
79
|
+
Validate clients before the WebSocket connection is even established.
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
server.authenticate(async (request) => {
|
|
83
|
+
const token = request.headers['authorization']
|
|
84
|
+
if (!token) throw new Error('Missing token')
|
|
85
|
+
|
|
86
|
+
const userId = await verify(token)
|
|
87
|
+
return userId // This becomes the client.id
|
|
88
|
+
})
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Channels
|
|
92
|
+
|
|
93
|
+
### Broadcast Channel
|
|
94
|
+
Sends messages to **all** connected clients. No subscription needed.
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
const broadcast = server.createBroadcast<string>()
|
|
98
|
+
broadcast.publish('Global alert!')
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Multicast Channel
|
|
102
|
+
Topic-based messaging for **subscribed** clients.
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
const room = server.createMulticast<string>('room-1')
|
|
106
|
+
|
|
107
|
+
// Manual subscription
|
|
108
|
+
room.subscribe('client-id')
|
|
109
|
+
|
|
110
|
+
// Message handling (with auto-relay if no handler is set)
|
|
111
|
+
room.onMessage((data, client) => {
|
|
112
|
+
// data is typed
|
|
113
|
+
})
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## API Reference
|
|
117
|
+
|
|
118
|
+
### Server API
|
|
119
|
+
| Method | Description |
|
|
120
|
+
| :--- | :--- |
|
|
121
|
+
| `start()` | Starts the server. |
|
|
122
|
+
| `stop()` | Stops the server. |
|
|
123
|
+
| `use(middleware)` | Registers global middleware. |
|
|
124
|
+
| `authenticate(hook)` | Sets the handshake authentication hook. |
|
|
125
|
+
| `createBroadcast<T>()` | Gets/creates the global broadcast channel. |
|
|
126
|
+
| `createMulticast<T>(name)` | Gets/creates a named multicast channel. |
|
|
127
|
+
| `getStats()` | Returns active clients, channels, and subscriptions. |
|
|
128
|
+
|
|
129
|
+
### Channel API
|
|
130
|
+
| Method | Description |
|
|
131
|
+
| :--- | :--- |
|
|
132
|
+
| `publish(data, options?)` | Sends message to subscribers. |
|
|
133
|
+
| `onMessage(handler)` | Registers a custom message handler. |
|
|
134
|
+
| `use(middleware)` | Registers channel-specific middleware. |
|
|
135
|
+
| `subscribe(clientId)` | Manually subscribes a client. |
|
|
136
|
+
| `unsubscribe(clientId)` | Manually unsubscribes a client. |
|
|
137
|
+
|
|
138
|
+
## License
|
|
139
|
+
|
|
140
|
+
MIT
|