@opra/socketio 1.20.0 → 1.22.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/package.json +12 -28
- package/{esm/socketio-adapter.js → socketio-adapter.js} +76 -49
- package/{esm/socketio-context.js → socketio-context.js} +3 -1
- package/cjs/index.js +0 -6
- package/cjs/package.json +0 -3
- package/cjs/socketio-adapter.js +0 -146
- package/cjs/socketio-context.js +0 -40
- package/esm/package.json +0 -3
- package/types/index.d.cts +0 -2
- /package/{types/index.d.ts → index.d.ts} +0 -0
- /package/{esm/index.js → index.js} +0 -0
- /package/{types/socketio-adapter.d.ts → socketio-adapter.d.ts} +0 -0
- /package/{types/socketio-context.d.ts → socketio-context.d.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opra/socketio",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.22.0",
|
|
4
4
|
"description": "Opra Socket.IO adapter",
|
|
5
5
|
"author": "Panates",
|
|
6
6
|
"license": "MIT",
|
|
@@ -8,50 +8,34 @@
|
|
|
8
8
|
"@jsopen/objects": "^2.0.2",
|
|
9
9
|
"@browsery/type-is": "^2.0.1",
|
|
10
10
|
"content-type": "^1.0.5",
|
|
11
|
-
"iconv-lite": "^0.7.
|
|
12
|
-
"node-events-async": "^1.
|
|
11
|
+
"iconv-lite": "^0.7.1",
|
|
12
|
+
"node-events-async": "^1.4.0",
|
|
13
13
|
"tslib": "^2.8.1",
|
|
14
14
|
"valgen": "^5.18.2"
|
|
15
15
|
},
|
|
16
16
|
"peerDependencies": {
|
|
17
|
-
"@opra/common": "^1.
|
|
18
|
-
"@opra/core": "^1.
|
|
17
|
+
"@opra/common": "^1.22.0",
|
|
18
|
+
"@opra/core": "^1.22.0",
|
|
19
19
|
"socket.io": ">=4.0.0"
|
|
20
20
|
},
|
|
21
21
|
"type": "module",
|
|
22
|
+
"module": "./index.js",
|
|
23
|
+
"types": "./index.d.ts",
|
|
22
24
|
"exports": {
|
|
23
25
|
".": {
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
"default": "./esm/index.js"
|
|
27
|
-
},
|
|
28
|
-
"require": {
|
|
29
|
-
"types": "./types/index.d.cts",
|
|
30
|
-
"default": "./cjs/index.js"
|
|
31
|
-
},
|
|
32
|
-
"default": "./esm/index.js"
|
|
26
|
+
"types": "./index.d.ts",
|
|
27
|
+
"default": "./index.js"
|
|
33
28
|
},
|
|
34
29
|
"./package.json": "./package.json"
|
|
35
30
|
},
|
|
36
|
-
"
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=20.0"
|
|
33
|
+
},
|
|
39
34
|
"repository": {
|
|
40
35
|
"type": "git",
|
|
41
36
|
"url": "git+https://github.com/panates/opra.git",
|
|
42
37
|
"directory": "packages/socketio"
|
|
43
38
|
},
|
|
44
|
-
"engines": {
|
|
45
|
-
"node": ">=16.0",
|
|
46
|
-
"npm": ">=7.0.0"
|
|
47
|
-
},
|
|
48
|
-
"files": [
|
|
49
|
-
"cjs/",
|
|
50
|
-
"esm/",
|
|
51
|
-
"types/",
|
|
52
|
-
"LICENSE",
|
|
53
|
-
"README.md"
|
|
54
|
-
],
|
|
55
39
|
"keywords": [
|
|
56
40
|
"opra",
|
|
57
41
|
"socketio",
|
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
import { OpraException, WSApi, } from '@opra/common';
|
|
2
2
|
import { PlatformAdapter } from '@opra/core';
|
|
3
3
|
import * as socketio from 'socket.io';
|
|
4
|
+
import { vg } from 'valgen';
|
|
4
5
|
import { SocketioContext } from './socketio-context.js';
|
|
5
6
|
/**
|
|
6
7
|
*
|
|
7
8
|
* @class SocketioAdapter
|
|
8
9
|
*/
|
|
9
10
|
export class SocketioAdapter extends PlatformAdapter {
|
|
11
|
+
static PlatformName = 'socketio';
|
|
12
|
+
_controllerInstances = new Map();
|
|
13
|
+
_eventsRegByName = new Map();
|
|
14
|
+
_eventsRegByPattern = [];
|
|
15
|
+
_scope;
|
|
16
|
+
transform = 'ws';
|
|
17
|
+
platform = SocketioAdapter.PlatformName;
|
|
18
|
+
interceptors;
|
|
19
|
+
server;
|
|
10
20
|
constructor(document, options) {
|
|
11
21
|
super(options);
|
|
12
|
-
this._controllerInstances = new Map();
|
|
13
|
-
this._eventsRegByName = new Map();
|
|
14
|
-
this._eventsRegByPattern = [];
|
|
15
|
-
this.transform = 'ws';
|
|
16
|
-
this.platform = SocketioAdapter.PlatformName;
|
|
17
22
|
this._document = document;
|
|
18
23
|
if (!(this.document.api instanceof WSApi)) {
|
|
19
24
|
throw new TypeError(`The document doesn't expose a WS Api`);
|
|
@@ -28,6 +33,32 @@ export class SocketioAdapter extends PlatformAdapter {
|
|
|
28
33
|
this._initSocket(socket);
|
|
29
34
|
this.emit('connection', socket, this);
|
|
30
35
|
});
|
|
36
|
+
}
|
|
37
|
+
get api() {
|
|
38
|
+
return this.document.getWsApi();
|
|
39
|
+
}
|
|
40
|
+
get scope() {
|
|
41
|
+
return this._scope;
|
|
42
|
+
}
|
|
43
|
+
async close() {
|
|
44
|
+
return this.server.close().finally(() => {
|
|
45
|
+
this._controllerInstances.clear();
|
|
46
|
+
this._eventsRegByName.clear();
|
|
47
|
+
this._eventsRegByPattern = [];
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Attaches socket.io to a server or port.
|
|
52
|
+
*
|
|
53
|
+
* @param srv - server or port
|
|
54
|
+
* @param opts - options passed to engine.io
|
|
55
|
+
* @return self
|
|
56
|
+
*/
|
|
57
|
+
listen(srv, opts) {
|
|
58
|
+
if (this.server.httpServer?.listening)
|
|
59
|
+
throw new Error('Server is already listening');
|
|
60
|
+
if (opts?.path)
|
|
61
|
+
this.server.path(opts?.path);
|
|
31
62
|
for (const contDef of this.api.controllers.values()) {
|
|
32
63
|
for (const oprDef of contDef.operations.values()) {
|
|
33
64
|
const fn = contDef.instance[oprDef.name];
|
|
@@ -46,11 +77,16 @@ export class SocketioAdapter extends PlatformAdapter {
|
|
|
46
77
|
this._eventsRegByPattern.push(reg);
|
|
47
78
|
/** Generate decoders */
|
|
48
79
|
if (oprDef.arguments?.length) {
|
|
49
|
-
for (const
|
|
50
|
-
|
|
80
|
+
for (const arg of oprDef.arguments) {
|
|
81
|
+
let fn2 = arg.type.generateCodec('decode', {
|
|
51
82
|
scope: this.scope,
|
|
52
83
|
ignoreReadonlyFields: true,
|
|
53
|
-
})
|
|
84
|
+
});
|
|
85
|
+
if (arg.required)
|
|
86
|
+
fn2 = vg.required(fn2);
|
|
87
|
+
else
|
|
88
|
+
fn2 = vg.optional(fn2);
|
|
89
|
+
reg.decoders.push(fn2);
|
|
54
90
|
}
|
|
55
91
|
}
|
|
56
92
|
/** Generate response encoder */
|
|
@@ -62,28 +98,6 @@ export class SocketioAdapter extends PlatformAdapter {
|
|
|
62
98
|
}
|
|
63
99
|
}
|
|
64
100
|
}
|
|
65
|
-
}
|
|
66
|
-
get api() {
|
|
67
|
-
return this.document.getWsApi();
|
|
68
|
-
}
|
|
69
|
-
get scope() {
|
|
70
|
-
return this._scope;
|
|
71
|
-
}
|
|
72
|
-
close() {
|
|
73
|
-
return this.server.close();
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Attaches socket.io to a server or port.
|
|
77
|
-
*
|
|
78
|
-
* @param srv - server or port
|
|
79
|
-
* @param opts - options passed to engine.io
|
|
80
|
-
* @return self
|
|
81
|
-
*/
|
|
82
|
-
listen(srv, opts) {
|
|
83
|
-
if (this.server.httpServer?.listening)
|
|
84
|
-
throw new Error('Server is already listening');
|
|
85
|
-
if (opts?.path)
|
|
86
|
-
this.server.path(opts?.path);
|
|
87
101
|
this.server.listen(srv, opts);
|
|
88
102
|
return this;
|
|
89
103
|
}
|
|
@@ -100,26 +114,40 @@ export class SocketioAdapter extends PlatformAdapter {
|
|
|
100
114
|
this._eventsRegByPattern.find(r => r.event.test(event));
|
|
101
115
|
if (!reg) {
|
|
102
116
|
if (callback)
|
|
103
|
-
callback(new
|
|
117
|
+
callback(new OpraException(`Unknown event "${event}"`));
|
|
104
118
|
return;
|
|
105
119
|
}
|
|
106
|
-
const parameters = callback ? args.slice(0, -1) : args;
|
|
107
120
|
Promise.resolve().then(async () => {
|
|
108
|
-
const ctx = new SocketioContext({
|
|
109
|
-
__adapter: this,
|
|
110
|
-
__contDef: reg.contDef,
|
|
111
|
-
__oprDef: reg.oprDef,
|
|
112
|
-
__controller: reg.contDef.instance,
|
|
113
|
-
__handler: reg.handler,
|
|
114
|
-
socket,
|
|
115
|
-
event,
|
|
116
|
-
parameters,
|
|
117
|
-
});
|
|
118
121
|
try {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
122
|
+
const inputParameters = callback ? args.slice(0, -1) : args;
|
|
123
|
+
const ctx = new SocketioContext({
|
|
124
|
+
__adapter: this,
|
|
125
|
+
__contDef: reg.contDef,
|
|
126
|
+
__oprDef: reg.oprDef,
|
|
127
|
+
__controller: reg.contDef.instance,
|
|
128
|
+
__handler: reg.handler,
|
|
129
|
+
socket,
|
|
130
|
+
event,
|
|
131
|
+
});
|
|
132
|
+
const callArgs = [ctx];
|
|
133
|
+
let i = 0;
|
|
134
|
+
for (const prm of inputParameters) {
|
|
135
|
+
try {
|
|
136
|
+
const v = reg.decoders[i](prm);
|
|
137
|
+
const arg = reg.oprDef.arguments[i];
|
|
138
|
+
ctx.parameters.push(v);
|
|
139
|
+
if (arg.parameterIndex != null)
|
|
140
|
+
callArgs[arg.parameterIndex] = v;
|
|
141
|
+
else
|
|
142
|
+
callArgs.push(v);
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
err.message = `Failed to decode parameter ${i} of event "${event}": ${err.message}`;
|
|
146
|
+
throw err;
|
|
147
|
+
}
|
|
148
|
+
i++;
|
|
149
|
+
}
|
|
150
|
+
let x = await reg.handler.apply(reg.contDef.instance, callArgs);
|
|
123
151
|
if (reg.encoder)
|
|
124
152
|
x = reg.encoder(x);
|
|
125
153
|
if (x != null && typeof x !== 'string')
|
|
@@ -127,8 +155,8 @@ export class SocketioAdapter extends PlatformAdapter {
|
|
|
127
155
|
callback(x);
|
|
128
156
|
}
|
|
129
157
|
catch (err) {
|
|
130
|
-
const error = new OpraException(err);
|
|
131
|
-
callback(error);
|
|
158
|
+
const error = err instanceof OpraException ? err : new OpraException(err);
|
|
159
|
+
callback({ error });
|
|
132
160
|
}
|
|
133
161
|
});
|
|
134
162
|
});
|
|
@@ -138,4 +166,3 @@ export class SocketioAdapter extends PlatformAdapter {
|
|
|
138
166
|
return controller && this._controllerInstances.get(controller);
|
|
139
167
|
}
|
|
140
168
|
}
|
|
141
|
-
SocketioAdapter.PlatformName = 'socketio';
|
|
@@ -4,6 +4,9 @@ import { ExecutionContext } from '@opra/core';
|
|
|
4
4
|
* It extends the ExecutionContext and implements the AsyncEventEmitter.
|
|
5
5
|
*/
|
|
6
6
|
export class SocketioContext extends ExecutionContext {
|
|
7
|
+
socket;
|
|
8
|
+
event;
|
|
9
|
+
parameters = [];
|
|
7
10
|
/**
|
|
8
11
|
* Constructor
|
|
9
12
|
* @param init the context options
|
|
@@ -17,7 +20,6 @@ export class SocketioContext extends ExecutionContext {
|
|
|
17
20
|
transport: 'ws',
|
|
18
21
|
platform: 'socketio',
|
|
19
22
|
});
|
|
20
|
-
this.parameters = [];
|
|
21
23
|
this.socket = init.socket;
|
|
22
24
|
this.event = init.event;
|
|
23
25
|
this.parameters = init.parameters || [];
|
package/cjs/index.js
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const tslib_1 = require("tslib");
|
|
4
|
-
// export * from './constants.js';
|
|
5
|
-
tslib_1.__exportStar(require("./socketio-adapter.js"), exports);
|
|
6
|
-
tslib_1.__exportStar(require("./socketio-context.js"), exports);
|
package/cjs/package.json
DELETED
package/cjs/socketio-adapter.js
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SocketioAdapter = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const common_1 = require("@opra/common");
|
|
6
|
-
const core_1 = require("@opra/core");
|
|
7
|
-
const socketio = tslib_1.__importStar(require("socket.io"));
|
|
8
|
-
const socketio_context_js_1 = require("./socketio-context.js");
|
|
9
|
-
/**
|
|
10
|
-
*
|
|
11
|
-
* @class SocketioAdapter
|
|
12
|
-
*/
|
|
13
|
-
class SocketioAdapter extends core_1.PlatformAdapter {
|
|
14
|
-
constructor(document, options) {
|
|
15
|
-
super(options);
|
|
16
|
-
this._controllerInstances = new Map();
|
|
17
|
-
this._eventsRegByName = new Map();
|
|
18
|
-
this._eventsRegByPattern = [];
|
|
19
|
-
this.transform = 'ws';
|
|
20
|
-
this.platform = SocketioAdapter.PlatformName;
|
|
21
|
-
this._document = document;
|
|
22
|
-
if (!(this.document.api instanceof common_1.WSApi)) {
|
|
23
|
-
throw new TypeError(`The document doesn't expose a WS Api`);
|
|
24
|
-
}
|
|
25
|
-
this.interceptors = [...(options?.interceptors || [])];
|
|
26
|
-
this._scope = options?.scope;
|
|
27
|
-
this.server = new socketio.Server();
|
|
28
|
-
this.server.on('error', error => {
|
|
29
|
-
this.emit('error', error, undefined, this);
|
|
30
|
-
});
|
|
31
|
-
this.server.on('connection', (socket) => {
|
|
32
|
-
this._initSocket(socket);
|
|
33
|
-
this.emit('connection', socket, this);
|
|
34
|
-
});
|
|
35
|
-
for (const contDef of this.api.controllers.values()) {
|
|
36
|
-
for (const oprDef of contDef.operations.values()) {
|
|
37
|
-
const fn = contDef.instance[oprDef.name];
|
|
38
|
-
if (typeof fn !== 'function')
|
|
39
|
-
continue;
|
|
40
|
-
const reg = {
|
|
41
|
-
event: oprDef.event,
|
|
42
|
-
contDef,
|
|
43
|
-
oprDef,
|
|
44
|
-
handler: fn,
|
|
45
|
-
decoders: [],
|
|
46
|
-
};
|
|
47
|
-
if (typeof reg.event === 'string')
|
|
48
|
-
this._eventsRegByName.set(reg.event, reg);
|
|
49
|
-
else
|
|
50
|
-
this._eventsRegByPattern.push(reg);
|
|
51
|
-
/** Generate decoders */
|
|
52
|
-
if (oprDef.arguments?.length) {
|
|
53
|
-
for (const dt of oprDef.arguments) {
|
|
54
|
-
reg.decoders.push(dt.generateCodec('decode', {
|
|
55
|
-
scope: this.scope,
|
|
56
|
-
ignoreReadonlyFields: true,
|
|
57
|
-
}));
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
/** Generate response encoder */
|
|
61
|
-
if (oprDef.response) {
|
|
62
|
-
reg.encoder = oprDef.response.generateCodec('encode', {
|
|
63
|
-
scope: this.scope,
|
|
64
|
-
ignoreWriteonlyFields: true,
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
get api() {
|
|
71
|
-
return this.document.getWsApi();
|
|
72
|
-
}
|
|
73
|
-
get scope() {
|
|
74
|
-
return this._scope;
|
|
75
|
-
}
|
|
76
|
-
close() {
|
|
77
|
-
return this.server.close();
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Attaches socket.io to a server or port.
|
|
81
|
-
*
|
|
82
|
-
* @param srv - server or port
|
|
83
|
-
* @param opts - options passed to engine.io
|
|
84
|
-
* @return self
|
|
85
|
-
*/
|
|
86
|
-
listen(srv, opts) {
|
|
87
|
-
if (this.server.httpServer?.listening)
|
|
88
|
-
throw new Error('Server is already listening');
|
|
89
|
-
if (opts?.path)
|
|
90
|
-
this.server.path(opts?.path);
|
|
91
|
-
this.server.listen(srv, opts);
|
|
92
|
-
return this;
|
|
93
|
-
}
|
|
94
|
-
_initSocket(socket) {
|
|
95
|
-
socket.on('close', () => {
|
|
96
|
-
this.emit('close', socket, this);
|
|
97
|
-
});
|
|
98
|
-
socket.on('error', error => {
|
|
99
|
-
this.emit('error', error, socket, this);
|
|
100
|
-
});
|
|
101
|
-
socket.onAny((event, ...args) => {
|
|
102
|
-
const callback = args.length > 0 ? args[args.length - 1] : null;
|
|
103
|
-
const reg = this._eventsRegByName.get(event) ||
|
|
104
|
-
this._eventsRegByPattern.find(r => r.event.test(event));
|
|
105
|
-
if (!reg) {
|
|
106
|
-
if (callback)
|
|
107
|
-
callback(new Error(`Unknown event "${event}"`));
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
const parameters = callback ? args.slice(0, -1) : args;
|
|
111
|
-
Promise.resolve().then(async () => {
|
|
112
|
-
const ctx = new socketio_context_js_1.SocketioContext({
|
|
113
|
-
__adapter: this,
|
|
114
|
-
__contDef: reg.contDef,
|
|
115
|
-
__oprDef: reg.oprDef,
|
|
116
|
-
__controller: reg.contDef.instance,
|
|
117
|
-
__handler: reg.handler,
|
|
118
|
-
socket,
|
|
119
|
-
event,
|
|
120
|
-
parameters,
|
|
121
|
-
});
|
|
122
|
-
try {
|
|
123
|
-
let x = await reg.handler.apply(reg.contDef.instance, [
|
|
124
|
-
ctx,
|
|
125
|
-
...parameters,
|
|
126
|
-
]);
|
|
127
|
-
if (reg.encoder)
|
|
128
|
-
x = reg.encoder(x);
|
|
129
|
-
if (x != null && typeof x !== 'string')
|
|
130
|
-
x = JSON.stringify(x);
|
|
131
|
-
callback(x);
|
|
132
|
-
}
|
|
133
|
-
catch (err) {
|
|
134
|
-
const error = new common_1.OpraException(err);
|
|
135
|
-
callback(error);
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
getControllerInstance(controllerPath) {
|
|
141
|
-
const controller = this.api.findController(controllerPath);
|
|
142
|
-
return controller && this._controllerInstances.get(controller);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
exports.SocketioAdapter = SocketioAdapter;
|
|
146
|
-
SocketioAdapter.PlatformName = 'socketio';
|
package/cjs/socketio-context.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SocketioContext = void 0;
|
|
4
|
-
const core_1 = require("@opra/core");
|
|
5
|
-
/**
|
|
6
|
-
* Provides the context for handling messages.
|
|
7
|
-
* It extends the ExecutionContext and implements the AsyncEventEmitter.
|
|
8
|
-
*/
|
|
9
|
-
class SocketioContext extends core_1.ExecutionContext {
|
|
10
|
-
/**
|
|
11
|
-
* Constructor
|
|
12
|
-
* @param init the context options
|
|
13
|
-
*/
|
|
14
|
-
constructor(init) {
|
|
15
|
-
super({
|
|
16
|
-
...init,
|
|
17
|
-
__docNode: init.__oprDef?.node ||
|
|
18
|
-
init.__contDef?.node ||
|
|
19
|
-
init.__adapter.document.node,
|
|
20
|
-
transport: 'ws',
|
|
21
|
-
platform: 'socketio',
|
|
22
|
-
});
|
|
23
|
-
this.parameters = [];
|
|
24
|
-
this.socket = init.socket;
|
|
25
|
-
this.event = init.event;
|
|
26
|
-
this.parameters = init.parameters || [];
|
|
27
|
-
if (init.__contDef)
|
|
28
|
-
this.__contDef = init.__contDef;
|
|
29
|
-
if (init.__controller)
|
|
30
|
-
this.__controller = init.__controller;
|
|
31
|
-
if (init.__oprDef)
|
|
32
|
-
this.__oprDef = init.__oprDef;
|
|
33
|
-
if (init.__handler)
|
|
34
|
-
this.__handler = init.__handler;
|
|
35
|
-
}
|
|
36
|
-
get server() {
|
|
37
|
-
return this.__adapter.server;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
exports.SocketioContext = SocketioContext;
|
package/esm/package.json
DELETED
package/types/index.d.cts
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|