@4players/odin-common 1.1.2 → 1.2.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/CHANGELOG.md +8 -0
- package/lib/cjs/utility/rpc.js +186 -1
- package/lib/cjs/utility/selector.js +5 -5
- package/lib/cjs/utility/strand.js +7 -7
- package/lib/esm/utility/rpc.js +183 -0
- package/lib/esm/utility/selector.js +5 -5
- package/lib/esm/utility/strand.js +7 -7
- package/lib/rpc/commands.d.ts +217 -2
- package/lib/rpc/notifications.d.ts +779 -2
- package/lib/utility/rpc.d.ts +39 -1
- package/lib/utility/selector.d.ts +3 -3
- package/lib/utility/strand.d.ts +2 -2
- package/package.json +1 -1
- package/lib/utility/base64.spec.d.ts +0 -4
- package/lib/utility/bytearray.spec.d.ts +0 -4
- package/lib/utility/environment.spec.d.ts +0 -4
- package/lib/utility/iterable.spec.d.ts +0 -4
- package/lib/utility/json.spec.d.ts +0 -7
- package/lib/utility/websocket.spec.d.ts +0 -6
package/CHANGELOG.md
CHANGED
package/lib/cjs/utility/rpc.js
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/* eslint-disable no-dupe-class-members */
|
|
3
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
4
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
5
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
6
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
7
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
8
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
9
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
10
|
+
});
|
|
11
|
+
};
|
|
2
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isKnownRpcMessage = exports.parseRpcMessage = exports.parseRpc = exports.msgpackDecode = exports.msgpackEncode = void 0;
|
|
13
|
+
exports.isKnownRpcMessage = exports.parseRpcMessage = exports.parseRpc = exports.TypedRpcConnection = exports.RpcConnection = exports.msgpackDecode = exports.msgpackEncode = void 0;
|
|
4
14
|
const msgpack = require("@msgpack/msgpack");
|
|
5
15
|
const serialization_1 = require("../schema/serialization");
|
|
6
16
|
const result_1 = require("./result");
|
|
@@ -12,6 +22,181 @@ function msgpackDecode(buffer) {
|
|
|
12
22
|
return msgpack.decode(buffer);
|
|
13
23
|
}
|
|
14
24
|
exports.msgpackDecode = msgpackDecode;
|
|
25
|
+
class RpcConnection {
|
|
26
|
+
get closed() {
|
|
27
|
+
return this._Close.signal.aborted;
|
|
28
|
+
}
|
|
29
|
+
get closeSignal() {
|
|
30
|
+
return this._Close.signal;
|
|
31
|
+
}
|
|
32
|
+
constructor(webSocket) {
|
|
33
|
+
this.webSocket = webSocket;
|
|
34
|
+
this._SendQueue = [];
|
|
35
|
+
this._RecvQueue = [];
|
|
36
|
+
this._Requests = new Map();
|
|
37
|
+
this._Close = new AbortController();
|
|
38
|
+
this._NextId = 1;
|
|
39
|
+
this.webSocket.addEventListener('open', this._OnWebSocketOpen.bind(this));
|
|
40
|
+
this.webSocket.addEventListener('close', this.close.bind(this));
|
|
41
|
+
this.webSocket.addEventListener('message', this._OnWebSocketMessage.bind(this));
|
|
42
|
+
this.webSocket.binaryType = 'arraybuffer';
|
|
43
|
+
this._Close.signal.addEventListener('abort', this._Cleanup.bind(this), {
|
|
44
|
+
once: true,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
request(name, properties, timeout) {
|
|
48
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
49
|
+
if (this.closed) {
|
|
50
|
+
return Promise.resolve('closed');
|
|
51
|
+
}
|
|
52
|
+
const id = this._NextId;
|
|
53
|
+
const timeoutId = timeout === undefined
|
|
54
|
+
? undefined
|
|
55
|
+
: setTimeout(() => this._TimeoutRequest(id), timeout);
|
|
56
|
+
this._Send([0, id, name, properties]);
|
|
57
|
+
return new Promise((resolve) => {
|
|
58
|
+
this._Requests.set(id, { resolve, timeoutId });
|
|
59
|
+
this._NextId += 1;
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
notify(name, properties) {
|
|
64
|
+
if (this.closed === false) {
|
|
65
|
+
this._Send([2, name, properties]);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
recv() {
|
|
69
|
+
if (this.closed === false) {
|
|
70
|
+
return new Promise((resolve) => this._RecvQueue.push(resolve));
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
return Promise.resolve('closed');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
close() {
|
|
77
|
+
this._Close.abort();
|
|
78
|
+
}
|
|
79
|
+
_TimeoutRequest(requestId) {
|
|
80
|
+
const request = this._Requests.get(requestId);
|
|
81
|
+
if (request === undefined)
|
|
82
|
+
return;
|
|
83
|
+
this._Requests.delete(requestId);
|
|
84
|
+
clearTimeout(request.timeoutId);
|
|
85
|
+
request.resolve('timeout');
|
|
86
|
+
}
|
|
87
|
+
_Send(message) {
|
|
88
|
+
this.webSocket.send(msgpack.encode(message));
|
|
89
|
+
}
|
|
90
|
+
_OnWebSocketOpen(ev) {
|
|
91
|
+
for (const data in this._SendQueue) {
|
|
92
|
+
this.webSocket.send(data);
|
|
93
|
+
}
|
|
94
|
+
this._SendQueue.length = 0;
|
|
95
|
+
}
|
|
96
|
+
_OnWebSocketMessage(ev) {
|
|
97
|
+
const rpc = parseRpc(ev.data);
|
|
98
|
+
if (rpc.type !== 'Success') {
|
|
99
|
+
this.webSocket.close();
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
switch (rpc.value[0]) {
|
|
103
|
+
case 0:
|
|
104
|
+
this._Send([1, rpc.value[1], 'not supported', undefined]);
|
|
105
|
+
break;
|
|
106
|
+
case 1:
|
|
107
|
+
this._OnResponse(rpc.value[1], rpc.value[2], rpc.value[3]);
|
|
108
|
+
break;
|
|
109
|
+
case 2:
|
|
110
|
+
this._OnEvent(rpc.value[1], rpc.value[2]);
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
_OnResponse(id, error, result) {
|
|
115
|
+
const request = this._Requests.get(id);
|
|
116
|
+
if (request === undefined)
|
|
117
|
+
return;
|
|
118
|
+
clearTimeout(request.timeoutId);
|
|
119
|
+
request.resolve(error === null ? (0, result_1.success)(result) : (0, result_1.failure)(error));
|
|
120
|
+
}
|
|
121
|
+
_OnEvent(name, properties) {
|
|
122
|
+
const receiver = this._RecvQueue.shift();
|
|
123
|
+
if (receiver !== undefined) {
|
|
124
|
+
receiver({ name, properties });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
_Cleanup() {
|
|
128
|
+
for (const request of this._Requests.values()) {
|
|
129
|
+
clearTimeout(request.timeoutId);
|
|
130
|
+
request.resolve('closed');
|
|
131
|
+
}
|
|
132
|
+
this._Requests.clear();
|
|
133
|
+
for (const accept of this._RecvQueue) {
|
|
134
|
+
accept('closed');
|
|
135
|
+
}
|
|
136
|
+
this._RecvQueue.length = 0;
|
|
137
|
+
this._SendQueue.length = 0;
|
|
138
|
+
this.webSocket.close();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
exports.RpcConnection = RpcConnection;
|
|
142
|
+
class TypedRpcConnection extends RpcConnection {
|
|
143
|
+
constructor(webSocket, _Commands, _Events) {
|
|
144
|
+
super(webSocket);
|
|
145
|
+
this._Commands = _Commands;
|
|
146
|
+
this._Events = _Events;
|
|
147
|
+
}
|
|
148
|
+
request(name, properties, timeout) {
|
|
149
|
+
const _super = Object.create(null, {
|
|
150
|
+
request: { get: () => super.request }
|
|
151
|
+
});
|
|
152
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
153
|
+
properties = this._Commands[name].request.parse(properties);
|
|
154
|
+
const response = yield (timeout !== undefined
|
|
155
|
+
? _super.request.call(this, name, properties, timeout)
|
|
156
|
+
: _super.request.call(this, name, properties));
|
|
157
|
+
if (response === 'closed' ||
|
|
158
|
+
response === 'timeout' ||
|
|
159
|
+
response.type === 'Failure') {
|
|
160
|
+
return response;
|
|
161
|
+
}
|
|
162
|
+
const parsed = this._Commands[name].response.safeParse(response.value);
|
|
163
|
+
if (parsed.success) {
|
|
164
|
+
response.value = parsed.data;
|
|
165
|
+
return response;
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
return (0, result_1.failure)(`response schema failed validation: ${parsed.error}`);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
notify(name, properties) {
|
|
173
|
+
properties = this._Commands[name].request.parse(properties);
|
|
174
|
+
super.notify(name, properties);
|
|
175
|
+
}
|
|
176
|
+
recv() {
|
|
177
|
+
const _super = Object.create(null, {
|
|
178
|
+
recv: { get: () => super.recv }
|
|
179
|
+
});
|
|
180
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
181
|
+
const event = yield _super.recv.call(this);
|
|
182
|
+
if (event === 'closed')
|
|
183
|
+
return event;
|
|
184
|
+
const parsed = parseRpcMessage(this._Events, event);
|
|
185
|
+
if (parsed !== undefined) {
|
|
186
|
+
return parsed;
|
|
187
|
+
}
|
|
188
|
+
if (!isKnownRpcMessage(this._Events, event.name)) {
|
|
189
|
+
console.warn(`dropping unknown event ${event.name}`);
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
console.error(`schema validation for ${event.name} failed; closing connection`);
|
|
193
|
+
this.close();
|
|
194
|
+
}
|
|
195
|
+
return 'closed';
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
exports.TypedRpcConnection = TypedRpcConnection;
|
|
15
200
|
function parseRpc(buffer) {
|
|
16
201
|
try {
|
|
17
202
|
return (0, result_1.success)(serialization_1.MessagePackRpcSchema.parse(msgpackDecode(buffer)));
|
|
@@ -11,14 +11,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.Selector = void 0;
|
|
13
13
|
class Selector {
|
|
14
|
-
constructor(
|
|
15
|
-
this.
|
|
16
|
-
this.
|
|
14
|
+
constructor(_Generators) {
|
|
15
|
+
this._Generators = _Generators;
|
|
16
|
+
this._Futures = _Generators.map(Selector.addIndex);
|
|
17
17
|
}
|
|
18
18
|
next() {
|
|
19
19
|
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
-
const [result, index] = yield Promise.race(this.
|
|
21
|
-
this.
|
|
20
|
+
const [result, index] = yield Promise.race(this._Futures);
|
|
21
|
+
this._Futures[index] = Selector.addIndex(this._Generators[index], index);
|
|
22
22
|
return result;
|
|
23
23
|
});
|
|
24
24
|
}
|
|
@@ -12,8 +12,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.Strand = void 0;
|
|
13
13
|
class Strand {
|
|
14
14
|
constructor() {
|
|
15
|
-
this.
|
|
16
|
-
this.
|
|
15
|
+
this._Tasks = [];
|
|
16
|
+
this._Running = false;
|
|
17
17
|
}
|
|
18
18
|
enqueue(task) {
|
|
19
19
|
return new Promise((resolve, reject) => {
|
|
@@ -26,22 +26,22 @@ class Strand {
|
|
|
26
26
|
reject(error);
|
|
27
27
|
}
|
|
28
28
|
});
|
|
29
|
-
this.
|
|
30
|
-
if (!this.
|
|
29
|
+
this._Tasks.push(wrapped);
|
|
30
|
+
if (!this._Running) {
|
|
31
31
|
this.execute();
|
|
32
32
|
}
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
35
|
execute() {
|
|
36
36
|
return __awaiter(this, void 0, void 0, function* () {
|
|
37
|
-
this.
|
|
37
|
+
this._Running = true;
|
|
38
38
|
while (true) {
|
|
39
|
-
const task = this.
|
|
39
|
+
const task = this._Tasks.shift();
|
|
40
40
|
if (task === undefined)
|
|
41
41
|
break;
|
|
42
42
|
yield task();
|
|
43
43
|
}
|
|
44
|
-
this.
|
|
44
|
+
this._Running = false;
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
47
|
}
|
package/lib/esm/utility/rpc.js
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/* eslint-disable no-dupe-class-members */
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
1
11
|
import * as msgpack from '@msgpack/msgpack';
|
|
2
12
|
import { MessagePackRpcSchema } from '../schema/serialization';
|
|
3
13
|
import { failure, success } from './result';
|
|
@@ -7,6 +17,179 @@ export function msgpackEncode(value) {
|
|
|
7
17
|
export function msgpackDecode(buffer) {
|
|
8
18
|
return msgpack.decode(buffer);
|
|
9
19
|
}
|
|
20
|
+
export class RpcConnection {
|
|
21
|
+
get closed() {
|
|
22
|
+
return this._Close.signal.aborted;
|
|
23
|
+
}
|
|
24
|
+
get closeSignal() {
|
|
25
|
+
return this._Close.signal;
|
|
26
|
+
}
|
|
27
|
+
constructor(webSocket) {
|
|
28
|
+
this.webSocket = webSocket;
|
|
29
|
+
this._SendQueue = [];
|
|
30
|
+
this._RecvQueue = [];
|
|
31
|
+
this._Requests = new Map();
|
|
32
|
+
this._Close = new AbortController();
|
|
33
|
+
this._NextId = 1;
|
|
34
|
+
this.webSocket.addEventListener('open', this._OnWebSocketOpen.bind(this));
|
|
35
|
+
this.webSocket.addEventListener('close', this.close.bind(this));
|
|
36
|
+
this.webSocket.addEventListener('message', this._OnWebSocketMessage.bind(this));
|
|
37
|
+
this.webSocket.binaryType = 'arraybuffer';
|
|
38
|
+
this._Close.signal.addEventListener('abort', this._Cleanup.bind(this), {
|
|
39
|
+
once: true,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
request(name, properties, timeout) {
|
|
43
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
44
|
+
if (this.closed) {
|
|
45
|
+
return Promise.resolve('closed');
|
|
46
|
+
}
|
|
47
|
+
const id = this._NextId;
|
|
48
|
+
const timeoutId = timeout === undefined
|
|
49
|
+
? undefined
|
|
50
|
+
: setTimeout(() => this._TimeoutRequest(id), timeout);
|
|
51
|
+
this._Send([0, id, name, properties]);
|
|
52
|
+
return new Promise((resolve) => {
|
|
53
|
+
this._Requests.set(id, { resolve, timeoutId });
|
|
54
|
+
this._NextId += 1;
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
notify(name, properties) {
|
|
59
|
+
if (this.closed === false) {
|
|
60
|
+
this._Send([2, name, properties]);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
recv() {
|
|
64
|
+
if (this.closed === false) {
|
|
65
|
+
return new Promise((resolve) => this._RecvQueue.push(resolve));
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
return Promise.resolve('closed');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
close() {
|
|
72
|
+
this._Close.abort();
|
|
73
|
+
}
|
|
74
|
+
_TimeoutRequest(requestId) {
|
|
75
|
+
const request = this._Requests.get(requestId);
|
|
76
|
+
if (request === undefined)
|
|
77
|
+
return;
|
|
78
|
+
this._Requests.delete(requestId);
|
|
79
|
+
clearTimeout(request.timeoutId);
|
|
80
|
+
request.resolve('timeout');
|
|
81
|
+
}
|
|
82
|
+
_Send(message) {
|
|
83
|
+
this.webSocket.send(msgpack.encode(message));
|
|
84
|
+
}
|
|
85
|
+
_OnWebSocketOpen(ev) {
|
|
86
|
+
for (const data in this._SendQueue) {
|
|
87
|
+
this.webSocket.send(data);
|
|
88
|
+
}
|
|
89
|
+
this._SendQueue.length = 0;
|
|
90
|
+
}
|
|
91
|
+
_OnWebSocketMessage(ev) {
|
|
92
|
+
const rpc = parseRpc(ev.data);
|
|
93
|
+
if (rpc.type !== 'Success') {
|
|
94
|
+
this.webSocket.close();
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
switch (rpc.value[0]) {
|
|
98
|
+
case 0:
|
|
99
|
+
this._Send([1, rpc.value[1], 'not supported', undefined]);
|
|
100
|
+
break;
|
|
101
|
+
case 1:
|
|
102
|
+
this._OnResponse(rpc.value[1], rpc.value[2], rpc.value[3]);
|
|
103
|
+
break;
|
|
104
|
+
case 2:
|
|
105
|
+
this._OnEvent(rpc.value[1], rpc.value[2]);
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
_OnResponse(id, error, result) {
|
|
110
|
+
const request = this._Requests.get(id);
|
|
111
|
+
if (request === undefined)
|
|
112
|
+
return;
|
|
113
|
+
clearTimeout(request.timeoutId);
|
|
114
|
+
request.resolve(error === null ? success(result) : failure(error));
|
|
115
|
+
}
|
|
116
|
+
_OnEvent(name, properties) {
|
|
117
|
+
const receiver = this._RecvQueue.shift();
|
|
118
|
+
if (receiver !== undefined) {
|
|
119
|
+
receiver({ name, properties });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
_Cleanup() {
|
|
123
|
+
for (const request of this._Requests.values()) {
|
|
124
|
+
clearTimeout(request.timeoutId);
|
|
125
|
+
request.resolve('closed');
|
|
126
|
+
}
|
|
127
|
+
this._Requests.clear();
|
|
128
|
+
for (const accept of this._RecvQueue) {
|
|
129
|
+
accept('closed');
|
|
130
|
+
}
|
|
131
|
+
this._RecvQueue.length = 0;
|
|
132
|
+
this._SendQueue.length = 0;
|
|
133
|
+
this.webSocket.close();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
export class TypedRpcConnection extends RpcConnection {
|
|
137
|
+
constructor(webSocket, _Commands, _Events) {
|
|
138
|
+
super(webSocket);
|
|
139
|
+
this._Commands = _Commands;
|
|
140
|
+
this._Events = _Events;
|
|
141
|
+
}
|
|
142
|
+
request(name, properties, timeout) {
|
|
143
|
+
const _super = Object.create(null, {
|
|
144
|
+
request: { get: () => super.request }
|
|
145
|
+
});
|
|
146
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
147
|
+
properties = this._Commands[name].request.parse(properties);
|
|
148
|
+
const response = yield (timeout !== undefined
|
|
149
|
+
? _super.request.call(this, name, properties, timeout)
|
|
150
|
+
: _super.request.call(this, name, properties));
|
|
151
|
+
if (response === 'closed' ||
|
|
152
|
+
response === 'timeout' ||
|
|
153
|
+
response.type === 'Failure') {
|
|
154
|
+
return response;
|
|
155
|
+
}
|
|
156
|
+
const parsed = this._Commands[name].response.safeParse(response.value);
|
|
157
|
+
if (parsed.success) {
|
|
158
|
+
response.value = parsed.data;
|
|
159
|
+
return response;
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
return failure(`response schema failed validation: ${parsed.error}`);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
notify(name, properties) {
|
|
167
|
+
properties = this._Commands[name].request.parse(properties);
|
|
168
|
+
super.notify(name, properties);
|
|
169
|
+
}
|
|
170
|
+
recv() {
|
|
171
|
+
const _super = Object.create(null, {
|
|
172
|
+
recv: { get: () => super.recv }
|
|
173
|
+
});
|
|
174
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
175
|
+
const event = yield _super.recv.call(this);
|
|
176
|
+
if (event === 'closed')
|
|
177
|
+
return event;
|
|
178
|
+
const parsed = parseRpcMessage(this._Events, event);
|
|
179
|
+
if (parsed !== undefined) {
|
|
180
|
+
return parsed;
|
|
181
|
+
}
|
|
182
|
+
if (!isKnownRpcMessage(this._Events, event.name)) {
|
|
183
|
+
console.warn(`dropping unknown event ${event.name}`);
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
console.error(`schema validation for ${event.name} failed; closing connection`);
|
|
187
|
+
this.close();
|
|
188
|
+
}
|
|
189
|
+
return 'closed';
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
10
193
|
export function parseRpc(buffer) {
|
|
11
194
|
try {
|
|
12
195
|
return success(MessagePackRpcSchema.parse(msgpackDecode(buffer)));
|
|
@@ -8,14 +8,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
export class Selector {
|
|
11
|
-
constructor(
|
|
12
|
-
this.
|
|
13
|
-
this.
|
|
11
|
+
constructor(_Generators) {
|
|
12
|
+
this._Generators = _Generators;
|
|
13
|
+
this._Futures = _Generators.map(Selector.addIndex);
|
|
14
14
|
}
|
|
15
15
|
next() {
|
|
16
16
|
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
-
const [result, index] = yield Promise.race(this.
|
|
18
|
-
this.
|
|
17
|
+
const [result, index] = yield Promise.race(this._Futures);
|
|
18
|
+
this._Futures[index] = Selector.addIndex(this._Generators[index], index);
|
|
19
19
|
return result;
|
|
20
20
|
});
|
|
21
21
|
}
|
|
@@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
export class Strand {
|
|
11
11
|
constructor() {
|
|
12
|
-
this.
|
|
13
|
-
this.
|
|
12
|
+
this._Tasks = [];
|
|
13
|
+
this._Running = false;
|
|
14
14
|
}
|
|
15
15
|
enqueue(task) {
|
|
16
16
|
return new Promise((resolve, reject) => {
|
|
@@ -23,22 +23,22 @@ export class Strand {
|
|
|
23
23
|
reject(error);
|
|
24
24
|
}
|
|
25
25
|
});
|
|
26
|
-
this.
|
|
27
|
-
if (!this.
|
|
26
|
+
this._Tasks.push(wrapped);
|
|
27
|
+
if (!this._Running) {
|
|
28
28
|
this.execute();
|
|
29
29
|
}
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
32
|
execute() {
|
|
33
33
|
return __awaiter(this, void 0, void 0, function* () {
|
|
34
|
-
this.
|
|
34
|
+
this._Running = true;
|
|
35
35
|
while (true) {
|
|
36
|
-
const task = this.
|
|
36
|
+
const task = this._Tasks.shift();
|
|
37
37
|
if (task === undefined)
|
|
38
38
|
break;
|
|
39
39
|
yield task();
|
|
40
40
|
}
|
|
41
|
-
this.
|
|
41
|
+
this._Running = false;
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
44
|
}
|