@remix_labs/hub-client 1.1902.0-dev → 1.1909.0-dev

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/common.js ADDED
@@ -0,0 +1,531 @@
1
+ let terminate = function(f) {};
2
+ if (globalThis.ThisIsNode) {
3
+ terminate = function(f) {
4
+ Process.on("exit", () => {
5
+ console.log("terminating hub worker");
6
+ f()
7
+ })
8
+ }
9
+ };
10
+
11
+ class JSONMessage {
12
+ constructor(rmxType, sender, payload) {
13
+ this.rmxType = rmxType;
14
+ this.sender = sender;
15
+ this.payload = typeof(payload) === "string" ? JSON.parse(payload) : payload;
16
+ this.eof = false;
17
+ this.localOnly = false;
18
+ this.header = { _rmx_type: rmxType,
19
+ _rmx_encoding: "json",
20
+ _rmx_sender: sender
21
+ };
22
+ this.topic = "";
23
+ this.retained = false;
24
+ }
25
+
26
+ received(topic, retained) {
27
+ this.topic = topic;
28
+ this.retained = retained;
29
+ return this;
30
+ }
31
+
32
+ publish(reqId, topic, retained) {
33
+ this.topic = topic;
34
+ this.retained = retained;
35
+ return { _rmx_type: "msg_hub_publish",
36
+ header: this.header,
37
+ reqId: reqId,
38
+ topic: topic,
39
+ payload: JSON.stringify(this.payload),
40
+ retained: retained,
41
+ localOnly: false
42
+ }
43
+ }
44
+ }
45
+
46
+ class TextMessage {
47
+ constructor(rmxType, sender, payload) {
48
+ this.rmxType = rmxType;
49
+ this.sender = sender;
50
+ this.payload = payload;
51
+ this.eof = false;
52
+ this.localOnly = false;
53
+ this.header = { _rmx_type: rmxType,
54
+ _rmx_encoding: "text",
55
+ _rmx_sender: sender
56
+ };
57
+ this.topic = "";
58
+ this.retained = false;
59
+ }
60
+
61
+ received(topic, retained) {
62
+ this.topic = topic;
63
+ this.retained = retained;
64
+ return this;
65
+ }
66
+
67
+ publish(reqId, topic, retained) {
68
+ this.topic = topic;
69
+ this.retained = retained;
70
+ return { _rmx_type: "msg_hub_publish",
71
+ header: this.header,
72
+ reqId: reqId,
73
+ topic: topic,
74
+ payload: this.payload,
75
+ retained: retained,
76
+ localOnly: false
77
+ }
78
+ }
79
+ }
80
+
81
+ class BinaryMessage {
82
+ constructor(rmxType, sender, payload) {
83
+ this.rmxType = rmxType;
84
+ this.sender = sender;
85
+ this.payload = payload;
86
+ this.eof = false;
87
+ this.localOnly = false;
88
+ this.header = { _rmx_type: rmxType,
89
+ _rmx_encoding: "binary",
90
+ _rmx_sender: sender
91
+ };
92
+ this.topic = "";
93
+ this.retained = false;
94
+ }
95
+
96
+ received(topic, retained) {
97
+ this.topic = topic;
98
+ this.retained = retained;
99
+ return this;
100
+ }
101
+
102
+ publish(reqId, topic, retained) {
103
+ this.topic = topic;
104
+ this.retained = retained;
105
+ return { _rmx_type: "msg_hub_publish",
106
+ header: this.header,
107
+ reqId: reqId,
108
+ topic: topic,
109
+ payload: this.payload,
110
+ retained: retained,
111
+ localOnly: false
112
+ }
113
+ }
114
+ }
115
+
116
+ class LocalMessage {
117
+ constructor(rmxType, sender, payload) {
118
+ this.rmxType = rmxType;
119
+ this.sender = sender;
120
+ this.payload = payload;
121
+ this.eof = false;
122
+ this.localOnly = true;
123
+ this.header = { _rmx_type: rmxType,
124
+ _rmx_encoding: "local",
125
+ _rmx_sender: sender
126
+ };
127
+ this.topic = "";
128
+ this.retained = false;
129
+ }
130
+
131
+ received(topic, retained) {
132
+ this.topic = topic;
133
+ this.retained = retained;
134
+ return this;
135
+ }
136
+
137
+ publish(reqId, topic, retained) {
138
+ this.topic = topic;
139
+ this.retained = retained;
140
+ return { _rmx_type: "msg_hub_publish",
141
+ header: this.header,
142
+ reqId: reqId,
143
+ topic: topic,
144
+ payload: this.payload,
145
+ retained: retained,
146
+ localOnly: true
147
+ }
148
+ }
149
+ }
150
+
151
+ class EOF {
152
+ constructor() {
153
+ this.rmxType = "";
154
+ this.sender = "";
155
+ this.payload = null;
156
+ this.eof = true;
157
+ this.localOnly = false;
158
+ this.header = { _rmx_type: "",
159
+ _rmx_encoding: "eof",
160
+ _rmx_sender: ""
161
+ };
162
+ this.topic = "";
163
+ this.retained = false;
164
+ }
165
+ }
166
+
167
+ function decodeMessage(msg) {
168
+ if (msg.eof) {
169
+ return new EOF()
170
+ };
171
+ switch (msg.header._rmx_encoding) {
172
+ case "text":
173
+ return new TextMessage(msg.header._rmx_type,
174
+ msg.header._rmx_sender,
175
+ msg.payload).received(msg.topic, msg.retained)
176
+ case "json":
177
+ return new JSONMessage(msg.header._rmx_type,
178
+ msg.header._rmx_sender,
179
+ msg.payload).received(msg.topic, msg.retained)
180
+ case "binary":
181
+ return new BinaryMessage(msg.header._rmx_type,
182
+ msg.header._rmx_sender,
183
+ msg.payload).received(msg.topic, msg.retained)
184
+ case "local":
185
+ return new LocalMessage(msg.header._rmx_type,
186
+ msg.header._rmx_sender,
187
+ msg.payload).received(msg.topic, msg.retained)
188
+ default:
189
+ throw new Error("bad _rmx_encoding: " + msg.header._rmx_encoding)
190
+ }
191
+ }
192
+
193
+ class Subscription {
194
+ constructor(channel, topic, subId) {
195
+ this.channel = channel;
196
+ this.topic = topic;
197
+ this.subId = subId;
198
+ this.buffer = new Array();
199
+ this.eof = false;
200
+ this.notify = (() => null);
201
+ channel.expect.set(subId, (resp => {
202
+ if (resp.data.error != null) {
203
+ console.warn("got an unexpected error message: " + resp.data.error)
204
+ } else {
205
+ this.buffer.push(decodeMessage(resp.data));
206
+ this.eof = this.eof || resp.data.eof;
207
+ this.notify()
208
+ }
209
+ }))
210
+ }
211
+ next() {
212
+ return new Promise((resolve, reject) => {
213
+ if (this.buffer.length > 0) {
214
+ resolve(this.buffer.shift())
215
+ } else {
216
+ this.notify = (() => {
217
+ this.notify = (() => null);
218
+ if (this.buffer.length > 0) {
219
+ resolve(this.buffer.shift())
220
+ }
221
+ })
222
+ }
223
+ })
224
+ }
225
+
226
+ unsubscribe() {
227
+ return new Promise((resolve, reject) => {
228
+ let reqId = this.channel.reqId + 1;
229
+ this.channel.reqId = reqId;
230
+ this.channel.expect.set(reqId, (resp => {
231
+ this.channel.expect.delete(reqId);
232
+ if (resp.data.error == null) {
233
+ resolve(resp.data)
234
+ } else
235
+ reject(resp.data);
236
+ }));
237
+ let unsubMsg =
238
+ { _rmx_type: "msg_hub_unsubscribe",
239
+ topic: this.topic,
240
+ reqId: reqId,
241
+ subId: this.subId
242
+ };
243
+ this.channel.port.postMessage(unsubMsg)
244
+ })
245
+ }
246
+ }
247
+
248
+ // The class Channel connects to the web worker implementing the hub.
249
+ // If you want to send channels to further web workers, you can do so
250
+ // by sending the port as transferable object, e.g.
251
+ // otherWorker.postMessage(..., [ channel.port ])
252
+ // and in the implementation of onmessage of otherWorker restore the channel:
253
+ // onmessage(ev => { let channel = new Channel(ev.ports[0]) ... })
254
+ // The restored channel talks then to the same hub.
255
+ class Channel {
256
+ constructor(port) {
257
+ this.port = port;
258
+ this.expect = new Map();
259
+ this.reqId = 0;
260
+
261
+ this.port.onmessage = (ev => {
262
+ try {
263
+ let f = this.expect.get(ev.data.reqId);
264
+ if (ev.eof) {
265
+ this.expect.delete(ev.data.reqId);
266
+ };
267
+ f(ev);
268
+ } catch (e) {
269
+ console.error("Exception when receiving a message in hub-client: ", e);
270
+ }
271
+ })
272
+ }
273
+
274
+ publish(topic, msg, retained) {
275
+ return new Promise((resolve, reject) => {
276
+ let reqId = this.reqId + 1;
277
+ this.reqId = reqId;
278
+ this.expect.set(reqId, (resp => {
279
+ this.expect.delete(reqId);
280
+ if (resp.data.error == null)
281
+ resolve(null);
282
+ else
283
+ reject(resp.data);
284
+ }));
285
+ let publishMsg = msg.publish(reqId, topic, retained);
286
+ this.port.postMessage(publishMsg)
287
+ })
288
+ }
289
+
290
+ send(topic, msg) {
291
+ return this.publish(topic, msg, false);
292
+ }
293
+
294
+ set(topic, msg) {
295
+ return this.publish(topic, msg, true);
296
+ }
297
+
298
+ get(topic) {
299
+ // so far this only works for local topics
300
+ return new Promise((resolve, reject) => {
301
+ let reqId = this.reqId + 1;
302
+ this.reqId = reqId;
303
+ this.expect.set(reqId, (resp => {
304
+ this.expect.delete(reqId);
305
+ if (resp.data.error == null) {
306
+ if (resp.data.payload !== undefined) {
307
+ resolve(decodeMessage(resp.data.payload));
308
+ } else {
309
+ resolve(undefined);
310
+ }
311
+ } else
312
+ reject(resp.data);
313
+ }));
314
+ let getMsg =
315
+ { _rmx_type: "msg_hub_get",
316
+ header: { _rmx_type: "msg_hub_get",
317
+ _rmx_encoding: "json",
318
+ _rmx_sender: this.sender
319
+ },
320
+ reqId: reqId,
321
+ topic: topic,
322
+ payload: "null",
323
+ retained: false,
324
+ localOnly: true
325
+ };
326
+ this.port.postMessage(getMsg)
327
+ })
328
+ }
329
+
330
+ subscribe(topic) {
331
+ return new Promise((resolve, reject) => {
332
+ let reqId = this.reqId + 1;
333
+ let subId = reqId + 1;
334
+ this.reqId = subId;
335
+ let sub = new Subscription(this, topic, subId);
336
+ this.expect.set(reqId, (resp => {
337
+ this.expect.delete(reqId);
338
+ if (resp.data.error == null)
339
+ resolve(sub);
340
+ else
341
+ reject(resp.data);
342
+ }));
343
+ let subMsg =
344
+ { _rmx_type: "msg_hub_subscribe",
345
+ topic: topic,
346
+ reqId: reqId,
347
+ subId: subId
348
+ };
349
+ this.port.postMessage(subMsg)
350
+ })
351
+ }
352
+
353
+ setLocalPubTopic(topic) {
354
+ return new Promise((resolve, reject) => {
355
+ let reqId = this.reqId + 1;
356
+ this.reqId = reqId;
357
+ this.expect.set(reqId, (resp => {
358
+ this.expect.delete(reqId);
359
+ if (resp.data.error == null)
360
+ resolve(null);
361
+ else
362
+ reject(resp.data);
363
+ }));
364
+ let m = { _rmx_type:"msg_hub_setLocalPubTopic",
365
+ topic: topic,
366
+ reqId: reqId
367
+ };
368
+ this.port.postMessage(m)
369
+ })
370
+ }
371
+
372
+ setLocalSubTopic(topic) {
373
+ return new Promise((resolve, reject) => {
374
+ let reqId = this.reqId + 1;
375
+ this.reqId = reqId;
376
+ this.expect.set(reqId, (resp => {
377
+ this.expect.delete(reqId);
378
+ if (resp.data.error == null)
379
+ resolve(null);
380
+ else
381
+ reject(resp.data);
382
+ }));
383
+ let m = { _rmx_type:"msg_hub_setLocalSubTopic",
384
+ topic: topic,
385
+ reqId: reqId
386
+ };
387
+ this.port.postMessage(m)
388
+ })
389
+ }
390
+
391
+ newChannel() {
392
+ return new Promise((resolve, reject) => {
393
+ let reqId = this.reqId + 1;
394
+ this.reqId = reqId;
395
+ this.expect.set(reqId, (resp => {
396
+ this.expect.delete(reqId);
397
+ if (resp.data.error == null) {
398
+ let port = resp.ports !== undefined ? resp.ports[0] : resp.data.port;
399
+ let hubch = new Channel(port);
400
+ resolve(hubch);
401
+ } else
402
+ reject(resp.data)
403
+ }));
404
+ let msg =
405
+ { _rmx_type: "msg_hub_newChannel",
406
+ reqId: reqId
407
+ };
408
+ this.port.postMessage(msg);
409
+ })
410
+ }
411
+
412
+ newJSONMessage(rmxType, sender, payload) {
413
+ return new JSONMessage(rmxType, sender, payload);
414
+ }
415
+
416
+ newTextMessage(rmxType, sender, payload) {
417
+ return new TextMessage(rmxType, sender, payload);
418
+ }
419
+
420
+ newBinaryMessage(rmxType, sender, payload) {
421
+ return new BinaryMessage(rmxType, sender, payload);
422
+ }
423
+
424
+ newLocalMessage(rmxType, sender, payload) {
425
+ return new LocalMessage(rmxType, sender, payload);
426
+ }
427
+
428
+ newEOF(rmxType, sender, payload) {
429
+ return new EOF(rmxType, sender, payload);
430
+ }
431
+ }
432
+
433
+ // This class starts the web worker for the hub. Should only be instantiated
434
+ // once.
435
+ class Worker {
436
+ constructor() {
437
+ if (globalThis.RmxMessagingHub) {
438
+ this.worker = globalThis.RmxMessagingHub.worker;
439
+ this.expect = globalThis.RmxMessagingHub.expect;
440
+ this.noreconfigure = true;
441
+ return;
442
+ };
443
+
444
+ // injected by either index.js or node.js
445
+ this.worker = globalThis.GetHubWorker();
446
+
447
+ globalThis.RmxMessagingHub = this;
448
+ let thisworker = this;
449
+ this.expect = new Array(0);
450
+ // sigh, browser/node have a different API for this
451
+ if (this.worker.on) {
452
+ this.worker.on("message", (ev => {
453
+ let f = thisworker.expect.shift();
454
+ f(ev);
455
+ }));
456
+ } else {
457
+ this.worker.addEventListener("message", (ev => {
458
+ let f = thisworker.expect.shift();
459
+ f(ev);
460
+ }));
461
+ }
462
+
463
+ this.noreconfigure = false;
464
+ terminate(() => thisworker.worker.terminate());
465
+ }
466
+
467
+ configure(config_obj) {
468
+ if (this.noreconfigure) {
469
+ console.warn("The global hub-client is already configured");
470
+ return;
471
+ };
472
+ let thisworker = this;
473
+ return new Promise((resolve, reject) => {
474
+ thisworker.expect.push(resp => {
475
+ if (resp.data.error == null)
476
+ resolve(resp.data);
477
+ else
478
+ reject(resp.data)
479
+ });
480
+ let config_msg =
481
+ { "_rmx_type": "msg_hub_configure",
482
+ "baseURL": config_obj.baseURL,
483
+ "wsURL": config_obj.wsURL,
484
+ "user": config_obj.user,
485
+ "token": config_obj.token,
486
+ "standalone": config_obj.standalone === true
487
+ };
488
+ thisworker.worker.postMessage(config_msg);
489
+ })
490
+ }
491
+
492
+ newChannel() {
493
+ let thisworker = this;
494
+ return new Promise((resolve, reject) => {
495
+ thisworker.expect.push(resp => {
496
+ if (resp.data.error == null) {
497
+ let port = resp.ports !== undefined ? resp.ports[0] : resp.data.port;
498
+ let hubch = new Channel(port);
499
+ resolve(hubch);
500
+ } else
501
+ reject(resp.data)
502
+ });
503
+ let msg =
504
+ { "_rmx_type": "msg_hub_newChannel" };
505
+ thisworker.worker.postMessage(msg);
506
+ })
507
+ }
508
+
509
+ newJSONMessage(rmxType, sender, payload) {
510
+ return new JSONMessage(rmxType, sender, payload);
511
+ }
512
+
513
+ newTextMessage(rmxType, sender, payload) {
514
+ return new TextMessage(rmxType, sender, payload);
515
+ }
516
+
517
+ newBinaryMessage(rmxType, sender, payload) {
518
+ return new BinaryMessage(rmxType, sender, payload);
519
+ }
520
+
521
+ newLocalMessage(rmxType, sender, payload) {
522
+ return new LocalMessage(rmxType, sender, payload);
523
+ }
524
+
525
+ newEOF(rmxType, sender, payload) {
526
+ return new EOF(rmxType, sender, payload);
527
+ }
528
+ }
529
+
530
+ export { Worker, Channel, JSONMessage, TextMessage, BinaryMessage, LocalMessage,
531
+ EOF }
package/index.js CHANGED
@@ -1,528 +1,14 @@
1
- let terminate = function(f) {};
2
- if (globalThis.ThisIsNode) {
3
- terminate = function(f) {
4
- Process.on("exit", () => {
5
- console.log("terminating hub worker");
6
- f()
7
- })
8
- }
9
- };
10
-
11
- class JSONMessage {
12
- constructor(rmxType, sender, payload) {
13
- this.rmxType = rmxType;
14
- this.sender = sender;
15
- this.payload = typeof(payload) === "string" ? JSON.parse(payload) : payload;
16
- this.eof = false;
17
- this.localOnly = false;
18
- this.header = { _rmx_type: rmxType,
19
- _rmx_encoding: "json",
20
- _rmx_sender: sender
21
- };
22
- this.topic = "";
23
- this.retained = false;
24
- }
25
-
26
- received(topic, retained) {
27
- this.topic = topic;
28
- this.retained = retained;
29
- return this;
30
- }
31
-
32
- publish(reqId, topic, retained) {
33
- this.topic = topic;
34
- this.retained = retained;
35
- return { _rmx_type: "msg_hub_publish",
36
- header: this.header,
37
- reqId: reqId,
38
- topic: topic,
39
- payload: JSON.stringify(this.payload),
40
- retained: retained,
41
- localOnly: false
42
- }
43
- }
44
- }
45
-
46
- class TextMessage {
47
- constructor(rmxType, sender, payload) {
48
- this.rmxType = rmxType;
49
- this.sender = sender;
50
- this.payload = payload;
51
- this.eof = false;
52
- this.localOnly = false;
53
- this.header = { _rmx_type: rmxType,
54
- _rmx_encoding: "text",
55
- _rmx_sender: sender
56
- };
57
- this.topic = "";
58
- this.retained = false;
59
- }
60
-
61
- received(topic, retained) {
62
- this.topic = topic;
63
- this.retained = retained;
64
- return this;
65
- }
66
-
67
- publish(reqId, topic, retained) {
68
- this.topic = topic;
69
- this.retained = retained;
70
- return { _rmx_type: "msg_hub_publish",
71
- header: this.header,
72
- reqId: reqId,
73
- topic: topic,
74
- payload: this.payload,
75
- retained: retained,
76
- localOnly: false
77
- }
78
- }
79
- }
80
-
81
- class BinaryMessage {
82
- constructor(rmxType, sender, payload) {
83
- this.rmxType = rmxType;
84
- this.sender = sender;
85
- this.payload = payload;
86
- this.eof = false;
87
- this.localOnly = false;
88
- this.header = { _rmx_type: rmxType,
89
- _rmx_encoding: "binary",
90
- _rmx_sender: sender
91
- };
92
- this.topic = "";
93
- this.retained = false;
94
- }
95
-
96
- received(topic, retained) {
97
- this.topic = topic;
98
- this.retained = retained;
99
- return this;
100
- }
101
-
102
- publish(reqId, topic, retained) {
103
- this.topic = topic;
104
- this.retained = retained;
105
- return { _rmx_type: "msg_hub_publish",
106
- header: this.header,
107
- reqId: reqId,
108
- topic: topic,
109
- payload: this.payload,
110
- retained: retained,
111
- localOnly: false
112
- }
113
- }
1
+ function workerify(code) {
2
+ let blob = new Blob([code], {type: 'application/javascript'});
3
+ return new globalThis.Worker(URL.createObjectURL(blob));
114
4
  }
115
5
 
116
- class LocalMessage {
117
- constructor(rmxType, sender, payload) {
118
- this.rmxType = rmxType;
119
- this.sender = sender;
120
- this.payload = payload;
121
- this.eof = false;
122
- this.localOnly = true;
123
- this.header = { _rmx_type: rmxType,
124
- _rmx_encoding: "local",
125
- _rmx_sender: sender
126
- };
127
- this.topic = "";
128
- this.retained = false;
129
- }
6
+ import HubWorker from './hub-worker.worker.js';
130
7
 
131
- received(topic, retained) {
132
- this.topic = topic;
133
- this.retained = retained;
134
- return this;
135
- }
136
-
137
- publish(reqId, topic, retained) {
138
- this.topic = topic;
139
- this.retained = retained;
140
- return { _rmx_type: "msg_hub_publish",
141
- header: this.header,
142
- reqId: reqId,
143
- topic: topic,
144
- payload: this.payload,
145
- retained: retained,
146
- localOnly: true
147
- }
148
- }
149
- }
150
-
151
- class EOF {
152
- constructor() {
153
- this.rmxType = "";
154
- this.sender = "";
155
- this.payload = null;
156
- this.eof = true;
157
- this.localOnly = false;
158
- this.header = { _rmx_type: "",
159
- _rmx_encoding: "eof",
160
- _rmx_sender: ""
161
- };
162
- this.topic = "";
163
- this.retained = false;
164
- }
8
+ function GetHubWorker() {
9
+ return workerify(HubWorker);
165
10
  }
166
11
 
167
- function decodeMessage(msg) {
168
- if (msg.eof) {
169
- return new EOF()
170
- };
171
- switch (msg.header._rmx_encoding) {
172
- case "text":
173
- return new TextMessage(msg.header._rmx_type,
174
- msg.header._rmx_sender,
175
- msg.payload).received(msg.topic, msg.retained)
176
- case "json":
177
- return new JSONMessage(msg.header._rmx_type,
178
- msg.header._rmx_sender,
179
- msg.payload).received(msg.topic, msg.retained)
180
- case "binary":
181
- return new BinaryMessage(msg.header._rmx_type,
182
- msg.header._rmx_sender,
183
- msg.payload).received(msg.topic, msg.retained)
184
- case "local":
185
- return new LocalMessage(msg.header._rmx_type,
186
- msg.header._rmx_sender,
187
- msg.payload).received(msg.topic, msg.retained)
188
- default:
189
- throw new Error("bad _rmx_encoding: " + msg.header._rmx_encoding)
190
- }
191
- }
192
-
193
- class Subscription {
194
- constructor(channel, topic, subId) {
195
- this.channel = channel;
196
- this.topic = topic;
197
- this.subId = subId;
198
- this.buffer = new Array();
199
- this.eof = false;
200
- this.notify = (() => null);
201
- channel.expect.set(subId, (resp => {
202
- if (resp.data.error != null) {
203
- console.warn("got an unexpected error message: " + resp.data.error)
204
- } else {
205
- this.buffer.push(decodeMessage(resp.data));
206
- this.eof = this.eof || resp.data.eof;
207
- this.notify()
208
- }
209
- }))
210
- }
211
- next() {
212
- return new Promise((resolve, reject) => {
213
- if (this.buffer.length > 0) {
214
- resolve(this.buffer.shift())
215
- } else {
216
- this.notify = (() => {
217
- this.notify = (() => null);
218
- if (this.buffer.length > 0) {
219
- resolve(this.buffer.shift())
220
- }
221
- })
222
- }
223
- })
224
- }
225
-
226
- unsubscribe() {
227
- return new Promise((resolve, reject) => {
228
- let reqId = this.channel.reqId + 1;
229
- this.channel.reqId = reqId;
230
- this.channel.expect.set(reqId, (resp => {
231
- this.channel.expect.delete(reqId);
232
- if (resp.data.error == null) {
233
- resolve(resp.data)
234
- } else
235
- reject(resp.data);
236
- }));
237
- let unsubMsg =
238
- { _rmx_type: "msg_hub_unsubscribe",
239
- topic: this.topic,
240
- reqId: reqId,
241
- subId: this.subId
242
- };
243
- this.channel.port.postMessage(unsubMsg)
244
- })
245
- }
246
- }
247
-
248
- // The class Channel connects to the web worker implementing the hub.
249
- // If you want to send channels to further web workers, you can do so
250
- // by sending the port as transferable object, e.g.
251
- // otherWorker.postMessage(..., [ channel.port ])
252
- // and in the implementation of onmessage of otherWorker restore the channel:
253
- // onmessage(ev => { let channel = new Channel(ev.ports[0]) ... })
254
- // The restored channel talks then to the same hub.
255
- class Channel {
256
- constructor(port) {
257
- this.port = port;
258
- this.expect = new Map();
259
- this.reqId = 0;
260
-
261
- this.port.onmessage = (ev => {
262
- try {
263
- let f = this.expect.get(ev.data.reqId);
264
- if (ev.eof) {
265
- this.expect.delete(ev.data.reqId);
266
- };
267
- f(ev);
268
- } catch (e) {
269
- console.error("Exception when receiving a message in hub-client: ", e);
270
- }
271
- })
272
- }
273
-
274
- publish(topic, msg, retained) {
275
- return new Promise((resolve, reject) => {
276
- let reqId = this.reqId + 1;
277
- this.reqId = reqId;
278
- this.expect.set(reqId, (resp => {
279
- this.expect.delete(reqId);
280
- if (resp.data.error == null)
281
- resolve(null);
282
- else
283
- reject(resp.data);
284
- }));
285
- let publishMsg = msg.publish(reqId, topic, retained);
286
- this.port.postMessage(publishMsg)
287
- })
288
- }
289
-
290
- send(topic, msg) {
291
- return this.publish(topic, msg, false);
292
- }
293
-
294
- set(topic, msg) {
295
- return this.publish(topic, msg, true);
296
- }
297
-
298
- get(topic) {
299
- // so far this only works for local topics
300
- return new Promise((resolve, reject) => {
301
- let reqId = this.reqId + 1;
302
- this.reqId = reqId;
303
- this.expect.set(reqId, (resp => {
304
- this.expect.delete(reqId);
305
- if (resp.data.error == null) {
306
- if (resp.data.payload !== undefined) {
307
- resolve(decodeMessage(resp.data.payload));
308
- } else {
309
- resolve(undefined);
310
- }
311
- } else
312
- reject(resp.data);
313
- }));
314
- let getMsg =
315
- { _rmx_type: "msg_hub_get",
316
- header: { _rmx_type: "msg_hub_get",
317
- _rmx_encoding: "json",
318
- _rmx_sender: this.sender
319
- },
320
- reqId: reqId,
321
- topic: topic,
322
- payload: "null",
323
- retained: false,
324
- localOnly: true
325
- };
326
- this.port.postMessage(getMsg)
327
- })
328
- }
329
-
330
- subscribe(topic) {
331
- return new Promise((resolve, reject) => {
332
- let reqId = this.reqId + 1;
333
- let subId = reqId + 1;
334
- this.reqId = subId;
335
- let sub = new Subscription(this, topic, subId);
336
- this.expect.set(reqId, (resp => {
337
- this.expect.delete(reqId);
338
- if (resp.data.error == null)
339
- resolve(sub);
340
- else
341
- reject(resp.data);
342
- }));
343
- let subMsg =
344
- { _rmx_type: "msg_hub_subscribe",
345
- topic: topic,
346
- reqId: reqId,
347
- subId: subId
348
- };
349
- this.port.postMessage(subMsg)
350
- })
351
- }
352
-
353
- setLocalPubTopic(topic) {
354
- return new Promise((resolve, reject) => {
355
- let reqId = this.reqId + 1;
356
- this.reqId = reqId;
357
- this.expect.set(reqId, (resp => {
358
- this.expect.delete(reqId);
359
- if (resp.data.error == null)
360
- resolve(null);
361
- else
362
- reject(resp.data);
363
- }));
364
- let m = { _rmx_type:"msg_hub_setLocalPubTopic",
365
- topic: topic,
366
- reqId: reqId
367
- };
368
- this.port.postMessage(m)
369
- })
370
- }
371
-
372
- setLocalSubTopic(topic) {
373
- return new Promise((resolve, reject) => {
374
- let reqId = this.reqId + 1;
375
- this.reqId = reqId;
376
- this.expect.set(reqId, (resp => {
377
- this.expect.delete(reqId);
378
- if (resp.data.error == null)
379
- resolve(null);
380
- else
381
- reject(resp.data);
382
- }));
383
- let m = { _rmx_type:"msg_hub_setLocalSubTopic",
384
- topic: topic,
385
- reqId: reqId
386
- };
387
- this.port.postMessage(m)
388
- })
389
- }
390
-
391
- newChannel() {
392
- return new Promise((resolve, reject) => {
393
- let reqId = this.reqId + 1;
394
- this.reqId = reqId;
395
- this.expect.set(reqId, (resp => {
396
- this.expect.delete(reqId);
397
- if (resp.data.error == null) {
398
- let port = resp.ports !== undefined ? resp.ports[0] : resp.data.port;
399
- let hubch = new Channel(port);
400
- resolve(hubch);
401
- } else
402
- reject(resp.data)
403
- }));
404
- let msg =
405
- { _rmx_type: "msg_hub_newChannel",
406
- reqId: reqId
407
- };
408
- this.port.postMessage(msg);
409
- })
410
- }
411
-
412
- newJSONMessage(rmxType, sender, payload) {
413
- return new JSONMessage(rmxType, sender, payload);
414
- }
415
-
416
- newTextMessage(rmxType, sender, payload) {
417
- return new TextMessage(rmxType, sender, payload);
418
- }
419
-
420
- newBinaryMessage(rmxType, sender, payload) {
421
- return new BinaryMessage(rmxType, sender, payload);
422
- }
423
-
424
- newLocalMessage(rmxType, sender, payload) {
425
- return new LocalMessage(rmxType, sender, payload);
426
- }
427
-
428
- newEOF(rmxType, sender, payload) {
429
- return new EOF(rmxType, sender, payload);
430
- }
431
- }
432
-
433
- // This class starts the web worker for the hub. Should only be instantiated
434
- // once.
435
- class Worker {
436
- constructor() {
437
- if (globalThis.RmxMessagingHub) {
438
- this.worker = globalThis.RmxMessagingHub.worker;
439
- this.expect = globalThis.RmxMessagingHub.expect;
440
- this.noreconfigure = true;
441
- return;
442
- };
443
- let bundle;
444
- if (globalThis.ThisIsNode) {
445
- bundle = new URL("../../hub-worker/src/node.js", import.meta.url);
446
- } else if (globalThis.GROOVEBOX_URL_PREFIX) {
447
- // FIXME: Stopgap solution until we figure out a way to bundle groovebox correctly
448
- bundle = new URL(`${globalThis.GROOVEBOX_URL_PREFIX}/hub-worker.js`, window.location.href);
449
- } else {
450
- bundle = new URL("/g/hub-worker.js", window.location.href);
451
- }
452
- this.worker = new globalThis.Worker(bundle);
453
- globalThis.RmxMessagingHub = this;
454
- let thisworker = this;
455
- this.expect = new Array(0);
456
- this.worker.onmessage = (ev => {
457
- let f = thisworker.expect.shift();
458
- f(ev)
459
- });
460
- this.noreconfigure = false;
461
- terminate(() => thisworker.worker.terminate());
462
- }
463
-
464
- configure(config_obj) {
465
- if (this.noreconfigure) {
466
- console.warn("The global hub-client is already configured");
467
- return;
468
- };
469
- let thisworker = this;
470
- return new Promise((resolve, reject) => {
471
- thisworker.expect.push(resp => {
472
- if (resp.data.error == null)
473
- resolve(resp.data);
474
- else
475
- reject(resp.data)
476
- });
477
- let config_msg =
478
- { "_rmx_type": "msg_hub_configure",
479
- "baseURL": config_obj.baseURL,
480
- "wsURL": config_obj.wsURL,
481
- "user": config_obj.user,
482
- "token": config_obj.token,
483
- "standalone": config_obj.standalone === true
484
- };
485
- thisworker.worker.postMessage(config_msg);
486
- })
487
- }
488
-
489
- newChannel() {
490
- let thisworker = this;
491
- return new Promise((resolve, reject) => {
492
- thisworker.expect.push(resp => {
493
- if (resp.data.error == null) {
494
- let port = resp.ports !== undefined ? resp.ports[0] : resp.data.port;
495
- let hubch = new Channel(port);
496
- resolve(hubch);
497
- } else
498
- reject(resp.data)
499
- });
500
- let msg =
501
- { "_rmx_type": "msg_hub_newChannel" };
502
- thisworker.worker.postMessage(msg);
503
- })
504
- }
505
-
506
- newJSONMessage(rmxType, sender, payload) {
507
- return new JSONMessage(rmxType, sender, payload);
508
- }
509
-
510
- newTextMessage(rmxType, sender, payload) {
511
- return new TextMessage(rmxType, sender, payload);
512
- }
513
-
514
- newBinaryMessage(rmxType, sender, payload) {
515
- return new BinaryMessage(rmxType, sender, payload);
516
- }
517
-
518
- newLocalMessage(rmxType, sender, payload) {
519
- return new LocalMessage(rmxType, sender, payload);
520
- }
521
-
522
- newEOF(rmxType, sender, payload) {
523
- return new EOF(rmxType, sender, payload);
524
- }
525
- }
12
+ globalThis.GetHubWorker = GetHubWorker;
526
13
 
527
- export { Worker, Channel, JSONMessage, TextMessage, BinaryMessage, LocalMessage,
528
- EOF }
14
+ export * from './common.js';
package/node.js CHANGED
@@ -1,6 +1,11 @@
1
- globalThis.ThisIsNode = true;
2
- import Worker from "@remix_labs/web-worker-onlymain";
3
- globalThis.Worker = Worker;
1
+ global.ThisIsNode = true;
4
2
  import Process from "process";
5
- globalThis.Process = Process;
6
- export * from "./index.js";
3
+ global.Process = Process;
4
+
5
+ import { Worker } from "worker_threads";
6
+ function GetHubWorker() {
7
+ return new Worker(new URL("./hub-worker.mjs", import.meta.url));
8
+ }
9
+ global.GetHubWorker = GetHubWorker;
10
+
11
+ export * from "./common.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remix_labs/hub-client",
3
- "version": "1.1902.0-dev",
3
+ "version": "1.1909.0-dev",
4
4
  "description": "talk to the Hub web worker",
5
5
  "main": "node.js",
6
6
  "browser": "index.js",
@@ -11,7 +11,7 @@
11
11
  "author": "Remixlabs staff",
12
12
  "license": "ISC",
13
13
  "dependencies": {
14
- "@remix_labs/web-worker-onlymain": "1.1902.0-dev"
14
+ "@remix_labs/web-worker-onlymain": "1.1909.0-dev"
15
15
  },
16
16
  "repository": "https://github.com/remixlabs/groovebox.git"
17
17
  }
@@ -0,0 +1,34 @@
1
+ import path from 'path';
2
+
3
+ import {fileURLToPath} from 'url'
4
+ const __filename = fileURLToPath(import.meta.url);
5
+ const __dirname = path.dirname(__filename);
6
+
7
+ export default [
8
+ {
9
+ name: 'web',
10
+ entry: './index.js',
11
+ mode: "production",
12
+ output: {
13
+ filename: 'hub-client.js',
14
+ path: path.resolve(__dirname, '../dist')
15
+ },
16
+ optimization: {
17
+ minimize: false
18
+ },
19
+ module: {
20
+ rules: [
21
+ {
22
+ test: /\.worker.js$/,
23
+ type: 'asset/source'
24
+ },
25
+ {
26
+ // Needed for import.meta.url unless we bundle the web workers
27
+ // themselves as separate entries in this bundle.
28
+ test: /\.js$/,
29
+ loader: '@open-wc/webpack-import-meta-loader'
30
+ }
31
+ ]
32
+ }
33
+ }
34
+ ]