@remix_labs/hub-client 1.1888.0-dev → 1.1895.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,532 +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
- }
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
- }
1
+ function workerify(code) {
2
+ let blob = new Blob([code], {type: 'application/javascript'});
3
+ return new globalThis.Worker(URL.createObjectURL(blob));
246
4
  }
247
5
 
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;
6
+ import HubWorker from './hub-worker.worker.js';
260
7
 
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
- }
8
+ function GetHubWorker() {
9
+ return workerify(HubWorker);
431
10
  }
432
11
 
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
- if (globalThis.ThisIsNode) {
444
- this.worker = globalThis.getHubWorker();
445
- //this.worker = new globalThis.Worker(new URL("./hub-worker.js", import.meta.url));
446
- } else {
447
- let bundle;
448
- if (globalThis.GROOVEBOX_URL_PREFIX) {
449
- // FIXME: Stopgap solution until we figure out a way to bundle groovebox correctly
450
- bundle = new URL(`${globalThis.GROOVEBOX_URL_PREFIX}/hub-worker.js`, window.location.href);
451
- } else {
452
- bundle = new URL("/g/hub-worker.js", window.location.href);
453
- }
454
- this.worker = new globalThis.Worker(bundle);
455
- }
456
- globalThis.RmxMessagingHub = this;
457
- let thisworker = this;
458
- this.expect = new Array(0);
459
- this.worker.on("message", (ev => {
460
- let f = thisworker.expect.shift();
461
- f(ev);
462
- }));
463
-
464
- this.noreconfigure = false;
465
- terminate(() => thisworker.worker.terminate());
466
- }
467
-
468
- configure(config_obj) {
469
- if (this.noreconfigure) {
470
- console.warn("The global hub-client is already configured");
471
- return;
472
- };
473
- let thisworker = this;
474
- return new Promise((resolve, reject) => {
475
- thisworker.expect.push(resp => {
476
- if (resp.data.error == null)
477
- resolve(resp.data);
478
- else
479
- reject(resp.data)
480
- });
481
- let config_msg =
482
- { "_rmx_type": "msg_hub_configure",
483
- "baseURL": config_obj.baseURL,
484
- "wsURL": config_obj.wsURL,
485
- "user": config_obj.user,
486
- "token": config_obj.token,
487
- "standalone": config_obj.standalone === true
488
- };
489
- thisworker.worker.postMessage(config_msg);
490
- })
491
- }
492
-
493
- newChannel() {
494
- let thisworker = this;
495
- return new Promise((resolve, reject) => {
496
- thisworker.expect.push(resp => {
497
- if (resp.data.error == null) {
498
- let port = resp.ports !== undefined ? resp.ports[0] : resp.data.port;
499
- let hubch = new Channel(port);
500
- resolve(hubch);
501
- } else
502
- reject(resp.data)
503
- });
504
- let msg =
505
- { "_rmx_type": "msg_hub_newChannel" };
506
- thisworker.worker.postMessage(msg);
507
- })
508
- }
509
-
510
- newJSONMessage(rmxType, sender, payload) {
511
- return new JSONMessage(rmxType, sender, payload);
512
- }
513
-
514
- newTextMessage(rmxType, sender, payload) {
515
- return new TextMessage(rmxType, sender, payload);
516
- }
517
-
518
- newBinaryMessage(rmxType, sender, payload) {
519
- return new BinaryMessage(rmxType, sender, payload);
520
- }
521
-
522
- newLocalMessage(rmxType, sender, payload) {
523
- return new LocalMessage(rmxType, sender, payload);
524
- }
525
-
526
- newEOF(rmxType, sender, payload) {
527
- return new EOF(rmxType, sender, payload);
528
- }
529
- }
12
+ globalThis.GetHubWorker = GetHubWorker;
530
13
 
531
- export { Worker, Channel, JSONMessage, TextMessage, BinaryMessage, LocalMessage,
532
- EOF }
14
+ export * from './common.js';
package/node.js CHANGED
@@ -1,6 +1,10 @@
1
1
  globalThis.ThisIsNode = true;
2
- import Worker from "@remix_labs/web-worker-onlymain";
3
- globalThis.Worker = Worker;
4
2
  import Process from "process";
5
3
  globalThis.Process = Process;
6
- export * from "./index.js";
4
+
5
+ import Worker from "@remix_labs/web-worker-onlymain";
6
+ function GetHubWorker() {
7
+ return new Worker(new URL("./hub-worker.mjs", import.meta.url));
8
+ }
9
+
10
+ export * from "./common.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remix_labs/hub-client",
3
- "version": "1.1888.0-dev",
3
+ "version": "1.1895.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.1888.0-dev"
14
+ "@remix_labs/web-worker-onlymain": "1.1895.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
+ ]