@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 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
@@ -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
+ }
@@ -0,0 +1,12 @@
1
+
2
+ export class SekiroLogger {
3
+
4
+ static info(...args) {
5
+ console.info("[I] [" + new Date().toLocaleString() + "]", ...args)
6
+ }
7
+
8
+ static warn(...args) {
9
+ console.warn("[W] [" + new Date().toLocaleString() + "]", ...args)
10
+ }
11
+
12
+ }
@@ -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
+ }
package/test.js ADDED
@@ -0,0 +1,8 @@
1
+ import { SekiroClient } from "./SekiroClient.js"
2
+
3
+ const client = new SekiroClient("demo")
4
+ client.registerAction("testAction", async request => {
5
+ return {
6
+ a: 1
7
+ }
8
+ })