@ekhein/sekiro-node-client 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 +57 -0
- package/SekiroClient.js +106 -0
- package/SekiroLogger.js +12 -0
- package/SekiroResult.js +15 -0
- package/package.json +16 -0
- package/test.js +8 -0
package/README.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Sekiro Node.js Client
|
|
2
|
+
|
|
3
|
+
A Node.js client for the Sekiro WebSocket API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install sekiro-node-client
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
import SekiroClient from 'sekiro-node-client';
|
|
15
|
+
|
|
16
|
+
// Create client instance
|
|
17
|
+
const client = new SekiroClient('ws://your-sekiro-server:port', {
|
|
18
|
+
reconnectInterval: 2000,
|
|
19
|
+
maxReconnectAttempts: 10
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// Register action handlers
|
|
23
|
+
client.registerAction('test', (request, success, failure) => {
|
|
24
|
+
try {
|
|
25
|
+
// Process request
|
|
26
|
+
success({ result: 'ok', data: request });
|
|
27
|
+
} catch (error) {
|
|
28
|
+
failure(error.message);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Graceful shutdown
|
|
33
|
+
process.on('SIGINT', () => {
|
|
34
|
+
client.close();
|
|
35
|
+
process.exit();
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## API
|
|
40
|
+
|
|
41
|
+
### `new SekiroClient(wsURL, [options])`
|
|
42
|
+
Creates a new SekiroClient instance.
|
|
43
|
+
|
|
44
|
+
**Parameters:**
|
|
45
|
+
- `wsURL`: WebSocket server URL (required)
|
|
46
|
+
- `options`: Configuration options (optional)
|
|
47
|
+
- `reconnectInterval`: Base reconnect interval in ms (default: 2000)
|
|
48
|
+
- `maxReconnectAttempts`: Maximum reconnect attempts (default: 10)
|
|
49
|
+
- `wsOptions`: Additional WebSocket options
|
|
50
|
+
|
|
51
|
+
### Methods:
|
|
52
|
+
- `registerAction(action, handler)`: Register a handler for an action
|
|
53
|
+
- `close()`: Close the WebSocket connection
|
|
54
|
+
|
|
55
|
+
## License
|
|
56
|
+
|
|
57
|
+
MIT
|
package/SekiroClient.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { randomUUID } from 'crypto';
|
|
2
|
+
import { WebSocket } from 'partysocket';
|
|
3
|
+
import { WebSocket as Client } from 'ws';
|
|
4
|
+
import { SekiroResult } from './SekiroResult.js';
|
|
5
|
+
import { SekiroLogger } from './SekiroLogger.js';
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Sekiro Client for Node.js
|
|
10
|
+
* @class
|
|
11
|
+
*/
|
|
12
|
+
export class SekiroClient extends WebSocket {
|
|
13
|
+
|
|
14
|
+
_handlers = new Map([])
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Create a SekiroClient instance
|
|
18
|
+
* @param {string} wsURL - WebSocket server URL
|
|
19
|
+
* @param {object} [options] - Configuration options
|
|
20
|
+
* @param {number} [options.reconnectInterval=2000] - Base reconnect interval in ms
|
|
21
|
+
* @param {number} [options.maxReconnectAttempts=10] - Maximum reconnect attempts
|
|
22
|
+
* @param {object} [options.wsOptions] - Additional WebSocket options
|
|
23
|
+
*/
|
|
24
|
+
constructor(
|
|
25
|
+
scope,
|
|
26
|
+
host = "192.168.2.102",
|
|
27
|
+
prot = 5612,
|
|
28
|
+
clientId = randomUUID().replace(/-/g, ""),
|
|
29
|
+
) {
|
|
30
|
+
super("wss://", [], {
|
|
31
|
+
debug: false,
|
|
32
|
+
maxEnqueuedMessages: -1,
|
|
33
|
+
WebSocket: class extends Client {
|
|
34
|
+
constructor() {
|
|
35
|
+
const site = String("ws://").concat(host, ":", prot)
|
|
36
|
+
const wsURL = new URL("/business-demo/register", site)
|
|
37
|
+
wsURL.searchParams.append("group", scope)
|
|
38
|
+
wsURL.searchParams.append("clientId", clientId)
|
|
39
|
+
super(wsURL)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
super.addEventListener("open", this.onOpen.bind(this))
|
|
45
|
+
super.addEventListener("message", this.onData.bind(this))
|
|
46
|
+
super.addEventListener("close", this.onClose.bind(this))
|
|
47
|
+
super.addEventListener("error", this.onError.bind(this))
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Handle WebSocket open event
|
|
52
|
+
* @private
|
|
53
|
+
*/
|
|
54
|
+
async onOpen() {
|
|
55
|
+
SekiroLogger.info("Connection established");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Handle WebSocket message event
|
|
60
|
+
* @private
|
|
61
|
+
* @param {string|Buffer} data - Received data
|
|
62
|
+
*/
|
|
63
|
+
async onData(event) {
|
|
64
|
+
SekiroLogger.info("Received request", event.data)
|
|
65
|
+
const request = JSON.parse(event.data)
|
|
66
|
+
const handler = this._handlers.get(request.action)
|
|
67
|
+
try {
|
|
68
|
+
if (!request.action) throw new Error("Request parameter {action} is required")
|
|
69
|
+
if (!handler) throw new Error("No handler registered for action: " + request.action)
|
|
70
|
+
const data = await handler(request)
|
|
71
|
+
this.send(
|
|
72
|
+
SekiroResult.success(request, data)
|
|
73
|
+
)
|
|
74
|
+
} catch (error) {
|
|
75
|
+
this.send(
|
|
76
|
+
SekiroResult.unknown(request, error.message)
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Handle WebSocket close event
|
|
83
|
+
* @private
|
|
84
|
+
*/
|
|
85
|
+
async onClose() {
|
|
86
|
+
SekiroLogger.warn("Connection closed");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Handle WebSocket error event
|
|
91
|
+
* @private
|
|
92
|
+
* @param {Error} error - Error object
|
|
93
|
+
*/
|
|
94
|
+
async onError(error) {
|
|
95
|
+
SekiroLogger.warn("WebSocket error:", error);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Register action handler
|
|
100
|
+
* @param {string} action - Action name
|
|
101
|
+
* @param {function} handler - Handler function
|
|
102
|
+
*/
|
|
103
|
+
async registerAction(action, handler) {
|
|
104
|
+
this._handlers.set(action, handler)
|
|
105
|
+
}
|
|
106
|
+
}
|
package/SekiroLogger.js
ADDED
package/SekiroResult.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export class SekiroResult {
|
|
2
|
+
|
|
3
|
+
static success({__sekiro_seq__}, data) {
|
|
4
|
+
return (
|
|
5
|
+
JSON.stringify({__sekiro_seq__, data, status: 0})
|
|
6
|
+
)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
static unknown({__sekiro_seq__}, message) {
|
|
10
|
+
return (
|
|
11
|
+
JSON.stringify({__sekiro_seq__, message, status: -1})
|
|
12
|
+
)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ekhein/sekiro-node-client",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "src/index.js",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"author": "ekhein",
|
|
7
|
+
"license": "ISC",
|
|
8
|
+
"description": "",
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": ">=18.0.0"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"partysocket": "^1.1.4",
|
|
14
|
+
"ws": "^8.18.2"
|
|
15
|
+
}
|
|
16
|
+
}
|