@remix_labs/hub-client 1.1937.0-dev → 2.1838.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 }
@@ -0,0 +1 @@
1
+ (()=>{var e={361:function(e,t,s){var n;n=function(){var e=function(e){var t,s=e.localStorage||(t={},{setItem:function(e,s){t[e]=s},getItem:function(e){return t[e]},removeItem:function(e){delete t[e]}}),n=function(e,t){for(var s in e)if(e.hasOwnProperty(s)){if(!t.hasOwnProperty(s)){var n="Unknown property, "+s+". Valid properties are:";for(var i in t)t.hasOwnProperty(i)&&(n=n+" "+i);throw new Error(n)}if(typeof e[s]!==t[s])throw new Error(a(o.INVALID_TYPE,[typeof e[s],s]))}},i=function(e,t){return function(){return e.apply(t,arguments)}},o={OK:{code:0,text:"AMQJSC0000I OK."},CONNECT_TIMEOUT:{code:1,text:"AMQJSC0001E Connect timed out."},SUBSCRIBE_TIMEOUT:{code:2,text:"AMQJS0002E Subscribe timed out."},UNSUBSCRIBE_TIMEOUT:{code:3,text:"AMQJS0003E Unsubscribe timed out."},PING_TIMEOUT:{code:4,text:"AMQJS0004E Ping timed out."},INTERNAL_ERROR:{code:5,text:"AMQJS0005E Internal error. Error Message: {0}, Stack trace: {1}"},CONNACK_RETURNCODE:{code:6,text:"AMQJS0006E Bad Connack return code:{0} {1}."},SOCKET_ERROR:{code:7,text:"AMQJS0007E Socket error:{0}."},SOCKET_CLOSE:{code:8,text:"AMQJS0008I Socket closed."},MALFORMED_UTF:{code:9,text:"AMQJS0009E Malformed UTF data:{0} {1} {2}."},UNSUPPORTED:{code:10,text:"AMQJS0010E {0} is not supported by this browser."},INVALID_STATE:{code:11,text:"AMQJS0011E Invalid state {0}."},INVALID_TYPE:{code:12,text:"AMQJS0012E Invalid type {0} for {1}."},INVALID_ARGUMENT:{code:13,text:"AMQJS0013E Invalid argument {0} for {1}."},UNSUPPORTED_OPERATION:{code:14,text:"AMQJS0014E Unsupported operation."},INVALID_STORED_DATA:{code:15,text:"AMQJS0015E Invalid data in local storage key={0} value={1}."},INVALID_MQTT_MESSAGE_TYPE:{code:16,text:"AMQJS0016E Invalid MQTT message type {0}."},MALFORMED_UNICODE:{code:17,text:"AMQJS0017E Malformed Unicode string:{0} {1}."},BUFFER_FULL:{code:18,text:"AMQJS0018E Message buffer is full, maximum buffer size: {0}."}},r={0:"Connection Accepted",1:"Connection Refused: unacceptable protocol version",2:"Connection Refused: identifier rejected",3:"Connection Refused: server unavailable",4:"Connection Refused: bad user name or password",5:"Connection Refused: not authorized"},a=function(e,t){var s=e.text;if(t)for(var n,i,o=0;o<t.length;o++)if(n="{"+o+"}",(i=s.indexOf(n))>0){var r=s.substring(0,i),a=s.substring(i+n.length);s=r+t[o]+a}return s},c=[0,6,77,81,73,115,100,112,3],h=[0,4,77,81,84,84,4],u=function(e,t){for(var s in this.type=e,t)t.hasOwnProperty(s)&&(this[s]=t[s])};function l(e,t){var s,n=t,i=e[t],o=i>>4,r=i&=15;t+=1;var a=0,c=1;do{if(t==e.length)return[null,n];a+=(127&(s=e[t++]))*c,c*=128}while(0!=(128&s));var h=t+a;if(h>e.length)return[null,n];var l=new u(o);switch(o){case 2:1&e[t++]&&(l.sessionPresent=!0),l.returnCode=e[t++];break;case 3:var d=r>>1&3,p=g(e,t),f=m(e,t+=2,p);t+=p,d>0&&(l.messageIdentifier=g(e,t),t+=2);var _=new w(e.subarray(t,h));1==(1&r)&&(_.retained=!0),8==(8&r)&&(_.duplicate=!0),_.qos=d,_.destinationName=f,l.payloadMessage=_;break;case 4:case 5:case 6:case 7:case 11:l.messageIdentifier=g(e,t);break;case 9:l.messageIdentifier=g(e,t),t+=2,l.returnCode=e.subarray(t,h)}return[l,h]}function d(e,t,s){return t[s++]=e>>8,t[s++]=e%256,s}function p(e,t,s,n){return _(e,s,n=d(t,s,n)),n+t}function g(e,t){return 256*e[t]+e[t+1]}function f(e){for(var t=0,s=0;s<e.length;s++){var n=e.charCodeAt(s);n>2047?(55296<=n&&n<=56319&&(s++,t++),t+=3):n>127?t+=2:t++}return t}function _(e,t,s){for(var n=s,i=0;i<e.length;i++){var r=e.charCodeAt(i);if(55296<=r&&r<=56319){var c=e.charCodeAt(++i);if(isNaN(c))throw new Error(a(o.MALFORMED_UNICODE,[r,c]));r=c-56320+(r-55296<<10)+65536}r<=127?t[n++]=r:r<=2047?(t[n++]=r>>6&31|192,t[n++]=63&r|128):r<=65535?(t[n++]=r>>12&15|224,t[n++]=r>>6&63|128,t[n++]=63&r|128):(t[n++]=r>>18&7|240,t[n++]=r>>12&63|128,t[n++]=r>>6&63|128,t[n++]=63&r|128)}return t}function m(e,t,s){for(var n,i="",r=t;r<t+s;){var c=e[r++];if(c<128)n=c;else{var h=e[r++]-128;if(h<0)throw new Error(a(o.MALFORMED_UTF,[c.toString(16),h.toString(16),""]));if(c<224)n=64*(c-192)+h;else{var u=e[r++]-128;if(u<0)throw new Error(a(o.MALFORMED_UTF,[c.toString(16),h.toString(16),u.toString(16)]));if(c<240)n=4096*(c-224)+64*h+u;else{var l=e[r++]-128;if(l<0)throw new Error(a(o.MALFORMED_UTF,[c.toString(16),h.toString(16),u.toString(16),l.toString(16)]));if(!(c<248))throw new Error(a(o.MALFORMED_UTF,[c.toString(16),h.toString(16),u.toString(16),l.toString(16)]));n=262144*(c-240)+4096*h+64*u+l}}}n>65535&&(n-=65536,i+=String.fromCharCode(55296+(n>>10)),n=56320+(1023&n)),i+=String.fromCharCode(n)}return i}u.prototype.encode=function(){var e,t=(15&this.type)<<4,s=0,n=[],i=0;switch(void 0!==this.messageIdentifier&&(s+=2),this.type){case 1:switch(this.mqttVersion){case 3:s+=c.length+3;break;case 4:s+=h.length+3}s+=f(this.clientId)+2,void 0!==this.willMessage&&(s+=f(this.willMessage.destinationName)+2,(e=this.willMessage.payloadBytes)instanceof Uint8Array||(e=new Uint8Array(r)),s+=e.byteLength+2),void 0!==this.userName&&(s+=f(this.userName)+2),void 0!==this.password&&(s+=f(this.password)+2);break;case 8:t|=2;for(var o=0;o<this.topics.length;o++)n[o]=f(this.topics[o]),s+=n[o]+2;s+=this.requestedQos.length;break;case 10:for(t|=2,o=0;o<this.topics.length;o++)n[o]=f(this.topics[o]),s+=n[o]+2;break;case 6:t|=2;break;case 3:this.payloadMessage.duplicate&&(t|=8),t=t|=this.payloadMessage.qos<<1,this.payloadMessage.retained&&(t|=1),s+=(i=f(this.payloadMessage.destinationName))+2;var r=this.payloadMessage.payloadBytes;s+=r.byteLength,r instanceof ArrayBuffer?r=new Uint8Array(r):r instanceof Uint8Array||(r=new Uint8Array(r.buffer))}var a=function(e){var t=new Array(1),s=0;do{var n=e%128;(e>>=7)>0&&(n|=128),t[s++]=n}while(e>0&&s<4);return t}(s),u=a.length+1,l=new ArrayBuffer(s+u),g=new Uint8Array(l);if(g[0]=t,g.set(a,1),3==this.type)u=p(this.payloadMessage.destinationName,i,g,u);else if(1==this.type){switch(this.mqttVersion){case 3:g.set(c,u),u+=c.length;break;case 4:g.set(h,u),u+=h.length}var _=0;this.cleanSession&&(_=2),void 0!==this.willMessage&&(_|=4,_|=this.willMessage.qos<<3,this.willMessage.retained&&(_|=32)),void 0!==this.userName&&(_|=128),void 0!==this.password&&(_|=64),g[u++]=_,u=d(this.keepAliveInterval,g,u)}switch(void 0!==this.messageIdentifier&&(u=d(this.messageIdentifier,g,u)),this.type){case 1:u=p(this.clientId,f(this.clientId),g,u),void 0!==this.willMessage&&(u=p(this.willMessage.destinationName,f(this.willMessage.destinationName),g,u),u=d(e.byteLength,g,u),g.set(e,u),u+=e.byteLength),void 0!==this.userName&&(u=p(this.userName,f(this.userName),g,u)),void 0!==this.password&&(u=p(this.password,f(this.password),g,u));break;case 3:g.set(r,u);break;case 8:for(o=0;o<this.topics.length;o++)u=p(this.topics[o],n[o],g,u),g[u++]=this.requestedQos[o];break;case 10:for(o=0;o<this.topics.length;o++)u=p(this.topics[o],n[o],g,u)}return l};var b=function(e,t){this._client=e,this._keepAliveInterval=1e3*t,this.isReset=!1;var s=new u(12).encode(),n=function(e){return function(){return i.apply(e)}},i=function(){this.isReset?(this.isReset=!1,this._client._trace("Pinger.doPing","send PINGREQ"),this._client.socket.send(s),this.timeout=setTimeout(n(this),this._keepAliveInterval)):(this._client._trace("Pinger.doPing","Timed out"),this._client._disconnected(o.PING_TIMEOUT.code,a(o.PING_TIMEOUT)))};this.reset=function(){this.isReset=!0,clearTimeout(this.timeout),this._keepAliveInterval>0&&(this.timeout=setTimeout(n(this),this._keepAliveInterval))},this.cancel=function(){clearTimeout(this.timeout)}},y=function(e,t,s,n){t||(t=30),this.timeout=setTimeout(function(e,t,s){return function(){return e.apply(t,s)}}(s,e,n),1e3*t),this.cancel=function(){clearTimeout(this.timeout)}},v=function(t,n,i,r,c){if(!("WebSocket"in e)||null===e.WebSocket)throw new Error(a(o.UNSUPPORTED,["WebSocket"]));if(!("ArrayBuffer"in e)||null===e.ArrayBuffer)throw new Error(a(o.UNSUPPORTED,["ArrayBuffer"]));for(var h in this._trace("Paho.Client",t,n,i,r,c),this.host=n,this.port=i,this.path=r,this.uri=t,this.clientId=c,this._wsuri=null,this._localKey=n+":"+i+("/mqtt"!=r?":"+r:"")+":"+c+":",this._msg_queue=[],this._buffered_msg_queue=[],this._sentMessages={},this._receivedMessages={},this._notify_msg_sent={},this._message_identifier=1,this._sequence=0,s)0!==h.indexOf("Sent:"+this._localKey)&&0!==h.indexOf("Received:"+this._localKey)||this.restore(h)};v.prototype.host=null,v.prototype.port=null,v.prototype.path=null,v.prototype.uri=null,v.prototype.clientId=null,v.prototype.socket=null,v.prototype.connected=!1,v.prototype.maxMessageIdentifier=65536,v.prototype.connectOptions=null,v.prototype.hostIndex=null,v.prototype.onConnected=null,v.prototype.onConnectionLost=null,v.prototype.onMessageDelivered=null,v.prototype.onMessageArrived=null,v.prototype.traceFunction=null,v.prototype._msg_queue=null,v.prototype._buffered_msg_queue=null,v.prototype._connectTimeout=null,v.prototype.sendPinger=null,v.prototype.receivePinger=null,v.prototype._reconnectInterval=1,v.prototype._reconnecting=!1,v.prototype._reconnectTimeout=null,v.prototype.disconnectedPublishing=!1,v.prototype.disconnectedBufferSize=5e3,v.prototype.receiveBuffer=null,v.prototype._traceBuffer=null,v.prototype._MAX_TRACE_ENTRIES=100,v.prototype.connect=function(e){var t=this._traceMask(e,"password");if(this._trace("Client.connect",t,this.socket,this.connected),this.connected)throw new Error(a(o.INVALID_STATE,["already connected"]));if(this.socket)throw new Error(a(o.INVALID_STATE,["already connected"]));this._reconnecting&&(this._reconnectTimeout.cancel(),this._reconnectTimeout=null,this._reconnecting=!1),this.connectOptions=e,this._reconnectInterval=1,this._reconnecting=!1,e.uris?(this.hostIndex=0,this._doConnect(e.uris[0])):this._doConnect(this.uri)},v.prototype.subscribe=function(e,t){if(this._trace("Client.subscribe",e,t),!this.connected)throw new Error(a(o.INVALID_STATE,["not connected"]));var s=new u(8);s.topics=e.constructor===Array?e:[e],void 0===t.qos&&(t.qos=0),s.requestedQos=[];for(var n=0;n<s.topics.length;n++)s.requestedQos[n]=t.qos;t.onSuccess&&(s.onSuccess=function(e){t.onSuccess({invocationContext:t.invocationContext,grantedQos:e})}),t.onFailure&&(s.onFailure=function(e){t.onFailure({invocationContext:t.invocationContext,errorCode:e,errorMessage:a(e)})}),t.timeout&&(s.timeOut=new y(this,t.timeout,t.onFailure,[{invocationContext:t.invocationContext,errorCode:o.SUBSCRIBE_TIMEOUT.code,errorMessage:a(o.SUBSCRIBE_TIMEOUT)}])),this._requires_ack(s),this._schedule_message(s)},v.prototype.unsubscribe=function(e,t){if(this._trace("Client.unsubscribe",e,t),!this.connected)throw new Error(a(o.INVALID_STATE,["not connected"]));var s=new u(10);s.topics=e.constructor===Array?e:[e],t.onSuccess&&(s.callback=function(){t.onSuccess({invocationContext:t.invocationContext})}),t.timeout&&(s.timeOut=new y(this,t.timeout,t.onFailure,[{invocationContext:t.invocationContext,errorCode:o.UNSUBSCRIBE_TIMEOUT.code,errorMessage:a(o.UNSUBSCRIBE_TIMEOUT)}])),this._requires_ack(s),this._schedule_message(s)},v.prototype.send=function(e){this._trace("Client.send",e);var t=new u(3);if(t.payloadMessage=e,this.connected)e.qos>0?this._requires_ack(t):this.onMessageDelivered&&(this._notify_msg_sent[t]=this.onMessageDelivered(t.payloadMessage)),this._schedule_message(t);else{if(!this._reconnecting||!this.disconnectedPublishing)throw new Error(a(o.INVALID_STATE,["not connected"]));if(Object.keys(this._sentMessages).length+this._buffered_msg_queue.length>this.disconnectedBufferSize)throw new Error(a(o.BUFFER_FULL,[this.disconnectedBufferSize]));e.qos>0?this._requires_ack(t):(t.sequence=++this._sequence,this._buffered_msg_queue.unshift(t))}},v.prototype.disconnect=function(){if(this._trace("Client.disconnect"),this._reconnecting&&(this._reconnectTimeout.cancel(),this._reconnectTimeout=null,this._reconnecting=!1),!this.socket)throw new Error(a(o.INVALID_STATE,["not connecting or connected"]));var e=new u(14);this._notify_msg_sent[e]=i(this._disconnected,this),this._schedule_message(e)},v.prototype.getTraceLog=function(){if(null!==this._traceBuffer){for(var e in this._trace("Client.getTraceLog",new Date),this._trace("Client.getTraceLog in flight messages",this._sentMessages.length),this._sentMessages)this._trace("_sentMessages ",e,this._sentMessages[e]);for(var e in this._receivedMessages)this._trace("_receivedMessages ",e,this._receivedMessages[e]);return this._traceBuffer}},v.prototype.startTrace=function(){null===this._traceBuffer&&(this._traceBuffer=[]),this._trace("Client.startTrace",new Date,"@VERSION@-@BUILDLEVEL@")},v.prototype.stopTrace=function(){delete this._traceBuffer},v.prototype._doConnect=function(e){if(this.connectOptions.useSSL){var t=e.split(":");t[0]="wss",e=t.join(":")}this._wsuri=e,this.connected=!1,this.connectOptions.mqttVersion<4?this.socket=new WebSocket(e,["mqttv3.1"]):this.socket=new WebSocket(e,["mqtt"]),this.socket.binaryType="arraybuffer",this.socket.onopen=i(this._on_socket_open,this),this.socket.onmessage=i(this._on_socket_message,this),this.socket.onerror=i(this._on_socket_error,this),this.socket.onclose=i(this._on_socket_close,this),this.sendPinger=new b(this,this.connectOptions.keepAliveInterval),this.receivePinger=new b(this,this.connectOptions.keepAliveInterval),this._connectTimeout&&(this._connectTimeout.cancel(),this._connectTimeout=null),this._connectTimeout=new y(this,this.connectOptions.timeout,this._disconnected,[o.CONNECT_TIMEOUT.code,a(o.CONNECT_TIMEOUT)])},v.prototype._schedule_message=function(e){this._msg_queue.unshift(e),this.connected&&this._process_queue()},v.prototype.store=function(e,t){var n={type:t.type,messageIdentifier:t.messageIdentifier,version:1};if(3!==t.type)throw Error(a(o.INVALID_STORED_DATA,[e+this._localKey+t.messageIdentifier,n]));t.pubRecReceived&&(n.pubRecReceived=!0),n.payloadMessage={};for(var i="",r=t.payloadMessage.payloadBytes,c=0;c<r.length;c++)r[c]<=15?i=i+"0"+r[c].toString(16):i+=r[c].toString(16);n.payloadMessage.payloadHex=i,n.payloadMessage.qos=t.payloadMessage.qos,n.payloadMessage.destinationName=t.payloadMessage.destinationName,t.payloadMessage.duplicate&&(n.payloadMessage.duplicate=!0),t.payloadMessage.retained&&(n.payloadMessage.retained=!0),0===e.indexOf("Sent:")&&(void 0===t.sequence&&(t.sequence=++this._sequence),n.sequence=t.sequence),s.setItem(e+this._localKey+t.messageIdentifier,JSON.stringify(n))},v.prototype.restore=function(e){var t=s.getItem(e),n=JSON.parse(t),i=new u(n.type,n);if(3!==n.type)throw Error(a(o.INVALID_STORED_DATA,[e,t]));for(var r=n.payloadMessage.payloadHex,c=new ArrayBuffer(r.length/2),h=new Uint8Array(c),l=0;r.length>=2;){var d=parseInt(r.substring(0,2),16);r=r.substring(2,r.length),h[l++]=d}var p=new w(h);p.qos=n.payloadMessage.qos,p.destinationName=n.payloadMessage.destinationName,n.payloadMessage.duplicate&&(p.duplicate=!0),n.payloadMessage.retained&&(p.retained=!0),i.payloadMessage=p,0===e.indexOf("Sent:"+this._localKey)?(i.payloadMessage.duplicate=!0,this._sentMessages[i.messageIdentifier]=i):0===e.indexOf("Received:"+this._localKey)&&(this._receivedMessages[i.messageIdentifier]=i)},v.prototype._process_queue=function(){for(var e=null;e=this._msg_queue.pop();)this._socket_send(e),this._notify_msg_sent[e]&&(this._notify_msg_sent[e](),delete this._notify_msg_sent[e])},v.prototype._requires_ack=function(e){var t=Object.keys(this._sentMessages).length;if(t>this.maxMessageIdentifier)throw Error("Too many messages:"+t);for(;void 0!==this._sentMessages[this._message_identifier];)this._message_identifier++;e.messageIdentifier=this._message_identifier,this._sentMessages[e.messageIdentifier]=e,3===e.type&&this.store("Sent:",e),this._message_identifier===this.maxMessageIdentifier&&(this._message_identifier=1)},v.prototype._on_socket_open=function(){var e=new u(1,this.connectOptions);e.clientId=this.clientId,this._socket_send(e)},v.prototype._on_socket_message=function(e){this._trace("Client._on_socket_message",e.data);for(var t=this._deframeMessages(e.data),s=0;s<t.length;s+=1)this._handleMessage(t[s])},v.prototype._deframeMessages=function(e){var t=new Uint8Array(e),s=[];if(this.receiveBuffer){var n=new Uint8Array(this.receiveBuffer.length+t.length);n.set(this.receiveBuffer),n.set(t,this.receiveBuffer.length),t=n,delete this.receiveBuffer}try{for(var i=0;i<t.length;){var r=l(t,i),c=r[0];if(i=r[1],null===c)break;s.push(c)}i<t.length&&(this.receiveBuffer=t.subarray(i))}catch(e){var h="undefined"==e.hasOwnProperty("stack")?e.stack.toString():"No Error Stack Available";return void this._disconnected(o.INTERNAL_ERROR.code,a(o.INTERNAL_ERROR,[e.message,h]))}return s},v.prototype._handleMessage=function(e){this._trace("Client._handleMessage",e);try{switch(e.type){case 2:if(this._connectTimeout.cancel(),this._reconnectTimeout&&this._reconnectTimeout.cancel(),this.connectOptions.cleanSession){for(var t in this._sentMessages){var n=this._sentMessages[t];s.removeItem("Sent:"+this._localKey+n.messageIdentifier)}for(var t in this._sentMessages={},this._receivedMessages){var i=this._receivedMessages[t];s.removeItem("Received:"+this._localKey+i.messageIdentifier)}this._receivedMessages={}}if(0!==e.returnCode){this._disconnected(o.CONNACK_RETURNCODE.code,a(o.CONNACK_RETURNCODE,[e.returnCode,r[e.returnCode]]));break}this.connected=!0,this.connectOptions.uris&&(this.hostIndex=this.connectOptions.uris.length);var c=[];for(var h in this._sentMessages)this._sentMessages.hasOwnProperty(h)&&c.push(this._sentMessages[h]);if(this._buffered_msg_queue.length>0)for(var l=null;l=this._buffered_msg_queue.pop();)c.push(l),this.onMessageDelivered&&(this._notify_msg_sent[l]=this.onMessageDelivered(l.payloadMessage));c=c.sort((function(e,t){return e.sequence-t.sequence}));for(var d=0,p=c.length;d<p;d++)if(3==(n=c[d]).type&&n.pubRecReceived){var g=new u(6,{messageIdentifier:n.messageIdentifier});this._schedule_message(g)}else this._schedule_message(n);this.connectOptions.onSuccess&&this.connectOptions.onSuccess({invocationContext:this.connectOptions.invocationContext});var f=!1;this._reconnecting&&(f=!0,this._reconnectInterval=1,this._reconnecting=!1),this._connected(f,this._wsuri),this._process_queue();break;case 3:this._receivePublish(e);break;case 4:(n=this._sentMessages[e.messageIdentifier])&&(delete this._sentMessages[e.messageIdentifier],s.removeItem("Sent:"+this._localKey+e.messageIdentifier),this.onMessageDelivered&&this.onMessageDelivered(n.payloadMessage));break;case 5:(n=this._sentMessages[e.messageIdentifier])&&(n.pubRecReceived=!0,g=new u(6,{messageIdentifier:e.messageIdentifier}),this.store("Sent:",n),this._schedule_message(g));break;case 6:i=this._receivedMessages[e.messageIdentifier],s.removeItem("Received:"+this._localKey+e.messageIdentifier),i&&(this._receiveMessage(i),delete this._receivedMessages[e.messageIdentifier]);var _=new u(7,{messageIdentifier:e.messageIdentifier});this._schedule_message(_);break;case 7:n=this._sentMessages[e.messageIdentifier],delete this._sentMessages[e.messageIdentifier],s.removeItem("Sent:"+this._localKey+e.messageIdentifier),this.onMessageDelivered&&this.onMessageDelivered(n.payloadMessage);break;case 9:(n=this._sentMessages[e.messageIdentifier])&&(n.timeOut&&n.timeOut.cancel(),128===e.returnCode[0]?n.onFailure&&n.onFailure(e.returnCode):n.onSuccess&&n.onSuccess(e.returnCode),delete this._sentMessages[e.messageIdentifier]);break;case 11:(n=this._sentMessages[e.messageIdentifier])&&(n.timeOut&&n.timeOut.cancel(),n.callback&&n.callback(),delete this._sentMessages[e.messageIdentifier]);break;case 13:this.sendPinger.reset();break;default:this._disconnected(o.INVALID_MQTT_MESSAGE_TYPE.code,a(o.INVALID_MQTT_MESSAGE_TYPE,[e.type]))}}catch(e){var m="undefined"==e.hasOwnProperty("stack")?e.stack.toString():"No Error Stack Available";return void this._disconnected(o.INTERNAL_ERROR.code,a(o.INTERNAL_ERROR,[e.message,m]))}},v.prototype._on_socket_error=function(e){this._reconnecting||this._disconnected(o.SOCKET_ERROR.code,a(o.SOCKET_ERROR,[e.data]))},v.prototype._on_socket_close=function(){this._reconnecting||this._disconnected(o.SOCKET_CLOSE.code,a(o.SOCKET_CLOSE))},v.prototype._socket_send=function(e){if(1==e.type){var t=this._traceMask(e,"password");this._trace("Client._socket_send",t)}else this._trace("Client._socket_send",e);this.socket.send(e.encode()),this.sendPinger.reset()},v.prototype._receivePublish=function(e){switch(e.payloadMessage.qos){case"undefined":case 0:this._receiveMessage(e);break;case 1:var t=new u(4,{messageIdentifier:e.messageIdentifier});this._schedule_message(t),this._receiveMessage(e);break;case 2:this._receivedMessages[e.messageIdentifier]=e,this.store("Received:",e);var s=new u(5,{messageIdentifier:e.messageIdentifier});this._schedule_message(s);break;default:throw Error("Invaild qos="+e.payloadMessage.qos)}},v.prototype._receiveMessage=function(e){this.onMessageArrived&&this.onMessageArrived(e.payloadMessage)},v.prototype._connected=function(e,t){this.onConnected&&this.onConnected(e,t)},v.prototype._reconnect=function(){this._trace("Client._reconnect"),this.connected||(this._reconnecting=!0,this.sendPinger.cancel(),this.receivePinger.cancel(),this._reconnectInterval<128&&(this._reconnectInterval=2*this._reconnectInterval),this.connectOptions.uris?(this.hostIndex=0,this._doConnect(this.connectOptions.uris[0])):this._doConnect(this.uri))},v.prototype._disconnected=function(e,t){if(this._trace("Client._disconnected",e,t),void 0!==e&&this._reconnecting)this._reconnectTimeout=new y(this,this._reconnectInterval,this._reconnect);else if(this.sendPinger.cancel(),this.receivePinger.cancel(),this._connectTimeout&&(this._connectTimeout.cancel(),this._connectTimeout=null),this._msg_queue=[],this._buffered_msg_queue=[],this._notify_msg_sent={},this.socket&&(this.socket.onopen=null,this.socket.onmessage=null,this.socket.onerror=null,this.socket.onclose=null,1===this.socket.readyState&&this.socket.close(),delete this.socket),this.connectOptions.uris&&this.hostIndex<this.connectOptions.uris.length-1)this.hostIndex++,this._doConnect(this.connectOptions.uris[this.hostIndex]);else if(void 0===e&&(e=o.OK.code,t=a(o.OK)),this.connected){if(this.connected=!1,this.onConnectionLost&&this.onConnectionLost({errorCode:e,errorMessage:t,reconnect:this.connectOptions.reconnect,uri:this._wsuri}),e!==o.OK.code&&this.connectOptions.reconnect)return this._reconnectInterval=1,void this._reconnect()}else 4===this.connectOptions.mqttVersion&&!1===this.connectOptions.mqttVersionExplicit?(this._trace("Failed to connect V4, dropping back to V3"),this.connectOptions.mqttVersion=3,this.connectOptions.uris?(this.hostIndex=0,this._doConnect(this.connectOptions.uris[0])):this._doConnect(this.uri)):this.connectOptions.onFailure&&this.connectOptions.onFailure({invocationContext:this.connectOptions.invocationContext,errorCode:e,errorMessage:t})},v.prototype._trace=function(){if(this.traceFunction){var e=Array.prototype.slice.call(arguments);for(var t in e)void 0!==e[t]&&e.splice(t,1,JSON.stringify(e[t]));var s=e.join("");this.traceFunction({severity:"Debug",message:s})}if(null!==this._traceBuffer){t=0;for(var n=arguments.length;t<n;t++)this._traceBuffer.length==this._MAX_TRACE_ENTRIES&&this._traceBuffer.shift(),0===t||void 0===arguments[t]?this._traceBuffer.push(arguments[t]):this._traceBuffer.push(" "+JSON.stringify(arguments[t]))}},v.prototype._traceMask=function(e,t){var s={};for(var n in e)e.hasOwnProperty(n)&&(s[n]=n==t?"******":e[n]);return s};var w=function(e){var t,s;if(!("string"==typeof e||e instanceof ArrayBuffer||ArrayBuffer.isView(e)&&!(e instanceof DataView)))throw a(o.INVALID_ARGUMENT,[e,"newPayload"]);t=e;var n=0,i=!1,r=!1;Object.defineProperties(this,{payloadString:{enumerable:!0,get:function(){return"string"==typeof t?t:m(t,0,t.length)}},payloadBytes:{enumerable:!0,get:function(){if("string"==typeof t){var e=new ArrayBuffer(f(t)),s=new Uint8Array(e);return _(t,s,0),s}return t}},destinationName:{enumerable:!0,get:function(){return s},set:function(e){if("string"!=typeof e)throw new Error(a(o.INVALID_ARGUMENT,[e,"newDestinationName"]));s=e}},qos:{enumerable:!0,get:function(){return n},set:function(e){if(0!==e&&1!==e&&2!==e)throw new Error("Invalid argument:"+e);n=e}},retained:{enumerable:!0,get:function(){return i},set:function(e){if("boolean"!=typeof e)throw new Error(a(o.INVALID_ARGUMENT,[e,"newRetained"]));i=e}},topic:{enumerable:!0,get:function(){return s},set:function(e){s=e}},duplicate:{enumerable:!0,get:function(){return r},set:function(e){r=e}}})};return{Client:function(e,t,s,i){var r;if("string"!=typeof e)throw new Error(a(o.INVALID_TYPE,[typeof e,"host"]));if(2==arguments.length){i=t;var c=(r=e).match(/^(wss?):\/\/((\[(.+)\])|([^\/]+?))(:(\d+))?(\/.*)$/);if(!c)throw new Error(a(o.INVALID_ARGUMENT,[e,"host"]));e=c[4]||c[2],t=parseInt(c[7]),s=c[8]}else{if(3==arguments.length&&(i=s,s="/mqtt"),"number"!=typeof t||t<0)throw new Error(a(o.INVALID_TYPE,[typeof t,"port"]));if("string"!=typeof s)throw new Error(a(o.INVALID_TYPE,[typeof s,"path"]));var h=-1!==e.indexOf(":")&&"["!==e.slice(0,1)&&"]"!==e.slice(-1);r="ws://"+(h?"["+e+"]":e)+":"+t+s}for(var u=0,l=0;l<i.length;l++){var d=i.charCodeAt(l);55296<=d&&d<=56319&&l++,u++}if("string"!=typeof i||u>65535)throw new Error(a(o.INVALID_ARGUMENT,[i,"clientId"]));var p=new v(r,e,t,s,i);Object.defineProperties(this,{host:{get:function(){return e},set:function(){throw new Error(a(o.UNSUPPORTED_OPERATION))}},port:{get:function(){return t},set:function(){throw new Error(a(o.UNSUPPORTED_OPERATION))}},path:{get:function(){return s},set:function(){throw new Error(a(o.UNSUPPORTED_OPERATION))}},uri:{get:function(){return r},set:function(){throw new Error(a(o.UNSUPPORTED_OPERATION))}},clientId:{get:function(){return p.clientId},set:function(){throw new Error(a(o.UNSUPPORTED_OPERATION))}},onConnected:{get:function(){return p.onConnected},set:function(e){if("function"!=typeof e)throw new Error(a(o.INVALID_TYPE,[typeof e,"onConnected"]));p.onConnected=e}},disconnectedPublishing:{get:function(){return p.disconnectedPublishing},set:function(e){p.disconnectedPublishing=e}},disconnectedBufferSize:{get:function(){return p.disconnectedBufferSize},set:function(e){p.disconnectedBufferSize=e}},onConnectionLost:{get:function(){return p.onConnectionLost},set:function(e){if("function"!=typeof e)throw new Error(a(o.INVALID_TYPE,[typeof e,"onConnectionLost"]));p.onConnectionLost=e}},onMessageDelivered:{get:function(){return p.onMessageDelivered},set:function(e){if("function"!=typeof e)throw new Error(a(o.INVALID_TYPE,[typeof e,"onMessageDelivered"]));p.onMessageDelivered=e}},onMessageArrived:{get:function(){return p.onMessageArrived},set:function(e){if("function"!=typeof e)throw new Error(a(o.INVALID_TYPE,[typeof e,"onMessageArrived"]));p.onMessageArrived=e}},trace:{get:function(){return p.traceFunction},set:function(e){if("function"!=typeof e)throw new Error(a(o.INVALID_TYPE,[typeof e,"onTrace"]));p.traceFunction=e}}}),this.connect=function(e){if(n(e=e||{},{timeout:"number",userName:"string",password:"string",willMessage:"object",keepAliveInterval:"number",cleanSession:"boolean",useSSL:"boolean",invocationContext:"object",onSuccess:"function",onFailure:"function",hosts:"object",ports:"object",reconnect:"boolean",mqttVersion:"number",mqttVersionExplicit:"boolean",uris:"object"}),void 0===e.keepAliveInterval&&(e.keepAliveInterval=60),e.mqttVersion>4||e.mqttVersion<3)throw new Error(a(o.INVALID_ARGUMENT,[e.mqttVersion,"connectOptions.mqttVersion"]));if(void 0===e.mqttVersion?(e.mqttVersionExplicit=!1,e.mqttVersion=4):e.mqttVersionExplicit=!0,void 0!==e.password&&void 0===e.userName)throw new Error(a(o.INVALID_ARGUMENT,[e.password,"connectOptions.password"]));if(e.willMessage){if(!(e.willMessage instanceof w))throw new Error(a(o.INVALID_TYPE,[e.willMessage,"connectOptions.willMessage"]));if(e.willMessage.stringPayload=null,void 0===e.willMessage.destinationName)throw new Error(a(o.INVALID_TYPE,[typeof e.willMessage.destinationName,"connectOptions.willMessage.destinationName"]))}if(void 0===e.cleanSession&&(e.cleanSession=!0),e.hosts){if(!(e.hosts instanceof Array))throw new Error(a(o.INVALID_ARGUMENT,[e.hosts,"connectOptions.hosts"]));if(e.hosts.length<1)throw new Error(a(o.INVALID_ARGUMENT,[e.hosts,"connectOptions.hosts"]));for(var t=!1,i=0;i<e.hosts.length;i++){if("string"!=typeof e.hosts[i])throw new Error(a(o.INVALID_TYPE,[typeof e.hosts[i],"connectOptions.hosts["+i+"]"]));if(/^(wss?):\/\/((\[(.+)\])|([^\/]+?))(:(\d+))?(\/.*)$/.test(e.hosts[i])){if(0===i)t=!0;else if(!t)throw new Error(a(o.INVALID_ARGUMENT,[e.hosts[i],"connectOptions.hosts["+i+"]"]))}else if(t)throw new Error(a(o.INVALID_ARGUMENT,[e.hosts[i],"connectOptions.hosts["+i+"]"]))}if(t)e.uris=e.hosts;else{if(!e.ports)throw new Error(a(o.INVALID_ARGUMENT,[e.ports,"connectOptions.ports"]));if(!(e.ports instanceof Array))throw new Error(a(o.INVALID_ARGUMENT,[e.ports,"connectOptions.ports"]));if(e.hosts.length!==e.ports.length)throw new Error(a(o.INVALID_ARGUMENT,[e.ports,"connectOptions.ports"]));for(e.uris=[],i=0;i<e.hosts.length;i++){if("number"!=typeof e.ports[i]||e.ports[i]<0)throw new Error(a(o.INVALID_TYPE,[typeof e.ports[i],"connectOptions.ports["+i+"]"]));var c=e.hosts[i],h=e.ports[i],u=-1!==c.indexOf(":");r="ws://"+(u?"["+c+"]":c)+":"+h+s,e.uris.push(r)}}}p.connect(e)},this.subscribe=function(e,t){if("string"!=typeof e&&e.constructor!==Array)throw new Error("Invalid argument:"+e);if(n(t=t||{},{qos:"number",invocationContext:"object",onSuccess:"function",onFailure:"function",timeout:"number"}),t.timeout&&!t.onFailure)throw new Error("subscribeOptions.timeout specified with no onFailure callback.");if(void 0!==t.qos&&0!==t.qos&&1!==t.qos&&2!==t.qos)throw new Error(a(o.INVALID_ARGUMENT,[t.qos,"subscribeOptions.qos"]));p.subscribe(e,t)},this.unsubscribe=function(e,t){if("string"!=typeof e&&e.constructor!==Array)throw new Error("Invalid argument:"+e);if(n(t=t||{},{invocationContext:"object",onSuccess:"function",onFailure:"function",timeout:"number"}),t.timeout&&!t.onFailure)throw new Error("unsubscribeOptions.timeout specified with no onFailure callback.");p.unsubscribe(e,t)},this.send=function(e,t,s,n){var i;if(0===arguments.length)throw new Error("Invalid argument.length");if(1==arguments.length){if(!(e instanceof w)&&"string"!=typeof e)throw new Error("Invalid argument:"+typeof e);if(void 0===(i=e).destinationName)throw new Error(a(o.INVALID_ARGUMENT,[i.destinationName,"Message.destinationName"]));p.send(i)}else(i=new w(t)).destinationName=e,arguments.length>=3&&(i.qos=s),arguments.length>=4&&(i.retained=n),p.send(i)},this.publish=function(e,t,s,n){var i;if(0===arguments.length)throw new Error("Invalid argument.length");if(1==arguments.length){if(!(e instanceof w)&&"string"!=typeof e)throw new Error("Invalid argument:"+typeof e);if(void 0===(i=e).destinationName)throw new Error(a(o.INVALID_ARGUMENT,[i.destinationName,"Message.destinationName"]));p.send(i)}else(i=new w(t)).destinationName=e,arguments.length>=3&&(i.qos=s),arguments.length>=4&&(i.retained=n),p.send(i)},this.disconnect=function(){p.disconnect()},this.getTraceLog=function(){return p.getTraceLog()},this.startTrace=function(){p.startTrace()},this.stopTrace=function(){p.stopTrace()},this.isConnected=function(){return p.connected}},Message:w}}(void 0!==s.g?s.g:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{});return e},e.exports=n()},25:(e,t,s)=>{const n=s(361),i=s(78),o="/brokerStatus";e.exports=class{constructor(e){this.postMessage=e,this.state={paho:null,config:{},buffer:[],connected:!1,nextStatus:"virgin",lastStatus:"virgin",subscriptions:new Map,subStatus:new Map,localPubTopics:new Map,localSubTopics:new Map,retained:new Map},this.state.localPubTopics.set(o,!0),this.state.localSubTopics.set(o,!0),console.log("messaging hub: worker started")}onmessage(e){let t=e.data;switch(t._rmx_type){case"msg_hub_configure":this.on_msg_configure(t);break;case"msg_hub_newChannel":this.on_msg_newChannel(this,t);break;case"msg_hub_logStatus":this.logStatus();break;default:console.error("messaging hub: unknown message type: "+t._rmx_type)}}on_msg_configure(e){this.state.config.user=e.user,this.state.config.token=e.token;let t=e.wsURL,s=!1;if(void 0===t&&(t=e.baseURL,s=!0),!0===e.standalone)return console.log("messaging hub: standalone mode"),this.state.paho=null,void this.postMessage({error:null});let o=!1;t.startsWith("http://")?t="ws://"+t.substr(7):t.startsWith("https://")?(t="wss://"+t.substr(8),o=!0):t.startsWith("ws://")||t.startsWith("wss://")||console.error("messaging hub: bad baseURL: "+e.baseURL),s&&(t.endsWith("/")||(t+="/"),t+="x/broker.ws");let r=i.nanoid();console.log("messaging hub: connecting to broker at "+t),this.state.paho=new n.Client(t,r),this.state.paho.onMessageArrived=e=>{this.on_paho_messageArrived(e)};let a=!0;this.state.paho.onConnected=(e,t)=>{for(this.state.connected=!0,this.state.nextStatus=e?"reconnected":"connected",this.logStatus(),a&&this.postMessage({error:null}),a=!1;this.state.buffer.length>0;){let e=this.state.buffer.shift();try{e()}catch(e){console.error(e)}}this.state.subscriptions.forEach(((e,t)=>{this.broker_subscribe(t,void 0,void 0,!0)})),this.are_all_subscriptions_made()&&this.deliverStatus(this.state.nextStatus)},this.state.paho.onConnectionLost=e=>{console.error("messaging hub: connection lost, code "+e.errorCode+" "+e.errorMessage),this.state.connected=!1,this.state.nextStatus="disconnected",this.state.subStatus=new Map,this.deliverStatus("disconnected")};let c={userName:e.user,password:"Bearer "+e.token,useSSL:o,onFailure:(e,t,s)=>{this.state.connected=!1,console.error("messaging hub: connect failure, code "+t+" "+s),this.logStatus(),a&&this.postMessage({error:s}),a=!1},reconnect:!0,keepAliveInterval:15,mqttVersion:4};this.state.paho.connect(c)}logStatus(){console.info("messaging hub: "+(this.state.connected?"connected to ":"disconnected from ")+this.state.paho.host+":"+this.state.paho.port)}on_msg_newChannel(e){let t=new MessageChannel;t.port1.onmessage=e=>this.chan_onmessage(t.port1,e),this.postMessage({error:null,port:t.port2,reqId:e.reqId},[t.port2])}chan_onmessage(e,t){let s=t.data;switch(s._rmx_type){case"msg_hub_publish":this.on_chan_publish(e,s);break;case"msg_hub_get":this.on_chan_get(e,s);break;case"msg_hub_subscribe":this.on_chan_subscribe(e,s);break;case"msg_hub_unsubscribe":this.on_chan_unsubscribe(e,s);break;case"msg_hub_setLocalPubTopic":this.on_chan_setLocalPubTopic(e,s);break;case"msg_hub_setLocalSubTopic":this.on_chan_setLocalSubTopic(e,s);break;case"msg_hub_newChannel":this.on_msg_newChannel(e,s);break;default:console.error("messaging hub: unknown message type: "+s._rmx_type)}}on_chan_setLocalPubTopic(e,t){this.state.localPubTopics.set(t.topic,!0);let s={error:null,reqId:t.reqId};e.postMessage(s)}on_chan_setLocalSubTopic(e,t){this.state.localSubTopics.set(t.topic,!0);let s={error:null,reqId:t.reqId};e.postMessage(s)}isLocalPubTopic(e){let t=e.split("/");for(let e=t.length;e>=2;e--){let s=t.slice(0,e).join("/");if(this.state.localPubTopics.has(s))return!0}return!!this.state.localPubTopics.has("/")}isLocalSubTopic(e){let t=e.split("/");for(let e=t.length;e>=2;e--){let s=t.slice(0,e).join("/");if(this.state.localSubTopics.has(s))return!0}return!!this.state.localSubTopics.has("/")}when_connected(e){this.state.connected?e():this.state.buffer.push(e)}on_chan_publish(e,t){if(t.topic==o){let s={error:"cannot publish on restricted topic",reqId:t.reqId};return void e.postMessage(s)}if(t.retained&&this.state.retained.set(t.topic,t),this.deliver(t),null===this.state.paho||t.localOnly||this.isLocalPubTopic(t.topic)){let s={error:null,reqId:t.reqId};return void e.postMessage(s)}let s,n="_rmx_type="+t.header._rmx_type+",_rmx_encoding="+t.header._rmx_encoding+",_rmx_sender="+t.header._rmx_sender+",_rmx_route="+this.state.paho.clientId+"\n",i=(new TextEncoder).encode(n);switch(t.header._rmx_encoding){case"text":s=(new TextEncoder).encode(t.payload);break;case"json":JSON.stringify(t.payload),s=(new TextEncoder).encode(t.payload);break;case"binary":s=new Uint8Array(t.payload);break;default:console.error("bad encoding: "+t.header._rmx_encoding)}let r=new Uint8Array(i.length+s.length);r.set(i,0),r.set(s,i.length),this.when_connected((()=>{this.state.paho.publish(t.topic,r.buffer,0,t.retained)}));let a={error:null,reqId:t.reqId};e.postMessage(a)}on_chan_get(e,t){let s=this.state.retained.get(t.topic),n={error:null,reqId:t.reqId,payload:s};e.postMessage(n)}are_all_subscriptions_made(){let e=!0;return this.state.subscriptions.forEach(((t,s)=>{this.isLocalSubTopic(s)||this.state.subStatus.get(s)||(e=!1)})),e}broker_subscribe(e,t,s,n){if(!this.state.connected)return;if(this.state.subStatus.has(e))return;if(this.isLocalSubTopic(e))return;this.state.subStatus.set(e,!1);let i={qos:0,onSuccess:n=>{if(console.log("messaging hub: subscribed to "+e),this.state.subStatus.set(e,!0),void 0!==t&&void 0!==s){let e={error:null,reqId:s};t.postMessage(e)}this.are_all_subscriptions_made()&&this.deliverStatus(this.state.nextStatus)},onFailure:(i,o,r)=>{let a="subscription to "+e+" failed - code: "+o+" - text: "+r;if(console.error("messaging hub: "+a),void 0!==t&&void 0!==s){let e={error:a,reqId:s};t.postMessage(e)}n&&setTimeout((i=>{this.broker_subscribe(e,t,s,n)}),1e3)}};this.state.paho.subscribe(e,i)}on_chan_subscribe(e,t){let s={port:e,subId:t.subId};if(this.state.subscriptions.has(t.topic))return this.state.subscriptions.get(t.topic).push(s),e.postMessage({error:null,reqId:t.reqId}),void(this.state.retained.has(t.topic)&&this.deliver(this.state.retained.get(t.topic)));let n=new Array;if(n.push(s),this.state.subscriptions.set(t.topic,n),null===this.state.paho||this.isLocalSubTopic(t.topic)){let s={error:null,reqId:t.reqId};return e.postMessage(s),this.state.retained.has(t.topic)&&this.deliver(this.state.retained.get(t.topic)),void console.log("messaging hub: locally subscribed to "+t.topic)}this.when_connected((()=>{this.broker_subscribe(t.topic,e,t.reqId,!1)}))}on_chan_unsubscribe(e,t){if(!this.state.subscriptions.has(t.topic)){let s={error:null,reqId:t.reqId};return void e.postMessage(s)}let s=this.state.subscriptions.get(t.topic).filter((e=>e.subId!=t.subId));if(s.length>0){this.state.subscriptions.set(t.topic,s);let n={error:null,reqId:t.reqId};e.postMessage(n)}else if(this.state.subscriptions.delete(t.topic),null===this.state.paho||this.isLocalSubTopic(t.topic)||!this.state.connected){console.log("messaging hub: locally unsubscribed from "+t.topic);let s={error:null,reqId:t.reqId};e.postMessage(s)}else{let s={onSuccess:s=>{console.log("messaging hub: unsubscribed from "+t.topic);let n={error:null,reqId:t.reqId};e.postMessage(n)},onFailure:(s,n,i)=>{let o="unsubscribe from "+t.topic+" failed - code: "+n+" - text: "+i;console.error("messaging hub: "+o);let r={error:o,reqId:t.reqId};e.postMessage(r)}};this.state.paho.unsubscribe(t.topic,s)}let n={header:{_rmx_type:"",_rmx_encoding:"",_rmx_sender:""},eof:!0,payload:null,reqId:t.subId};e.postMessage(n)}on_paho_messageArrived(e){let t=new Uint8Array(e.payloadBytes),s=t.indexOf(10);if(s<0)return void console.error("messaging hub: Got undecodable MQTT message");let n,i=(new TextDecoder).decode(t.subarray(0,s)).split(","),o={};for(let e of i){let t=e.split("=",2);if(!(t.length<2))switch(t[0]){case"_rmx_type":o._rmx_type=t[1];break;case"_rmx_encoding":o._rmx_encoding=t[1];break;case"_rmx_sender":o._rmx_sender=t[1];break;case"_rmx_route":if(t[1].split(";").includes(this.state.paho.clientId))return void console.log("messaging hub: dropping duplicate message")}}switch(o._rmx_encoding){case"text":case"json":n=(new TextDecoder).decode(t.subarray(s+1));break;case"binary":n=t.slice(s+1);break;default:console.log("messaging hub: dropping message with bad _rmx_encoding")}let r={header:o,payload:n,topic:e.destinationName,retained:e.retained};r.retained&&this.state.retained.set(r.topic,r),this.deliver(r)}deliver(e){if(this.state.subscriptions.has(e.topic)){let t=this.state.subscriptions.get(e.topic),s=Object.fromEntries(Object.entries(e));for(let e of t)try{s.reqId=e.subId,e.port.postMessage(s)}catch(e){}}}deliverStatus(e){if(e==this.state.lastStatus)return;this.state.lastStatus=e;let t=o,s={_rmx_type:"msg_hub_publish",header:{_rmx_type:"msg_hub_status",_rmx_encoding:"json",_rmx_sender:"hub-worker"},topic:t,payload:JSON.stringify(e),retained:!0,localOnly:!0};this.state.retained.set(t,s),console.debug("messaging hub: "+o+" = "+e),this.deliver(s)}}},78:(e,t,s)=>{"use strict";s.r(t),s.d(t,{customAlphabet:()=>r,customRandom:()=>o,nanoid:()=>a,random:()=>i,urlAlphabet:()=>n});let n="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict",i=e=>crypto.getRandomValues(new Uint8Array(e)),o=(e,t,s)=>{let n=(2<<Math.log(e.length-1)/Math.LN2)-1,i=-~(1.6*n*t/e.length);return(o=t)=>{let r="";for(;;){let t=s(i),a=i;for(;a--;)if(r+=e[t[a]&n]||"",r.length===o)return r}}},r=(e,t=21)=>o(e,t,i),a=(e=21)=>crypto.getRandomValues(new Uint8Array(e)).reduce(((e,t)=>e+((t&=63)<36?t.toString(36):t<62?(t-26).toString(36).toUpperCase():t>62?"-":"_")),"")}},t={};function s(n){var i=t[n];if(void 0!==i)return i.exports;var o=t[n]={exports:{}};return e[n].call(o.exports,o,o.exports,s),o.exports}s.d=(e,t)=>{for(var n in t)s.o(t,n)&&!s.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},s.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),s.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),s.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{"use strict";const e=new(s(25))(((e,t)=>{self.postMessage({data:e},t)}));onmessage=e.onmessage.bind(e)})()})();
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.1937.0-dev",
3
+ "version": "2.1838.0-dev",
4
4
  "description": "talk to the Hub web worker",
5
5
  "main": "node.js",
6
6
  "browser": "index.js",
@@ -10,8 +10,5 @@
10
10
  },
11
11
  "author": "Remixlabs staff",
12
12
  "license": "ISC",
13
- "dependencies": {
14
- "@remix_labs/web-worker-onlymain": "1.1937.0-dev"
15
- },
16
13
  "repository": "https://github.com/remixlabs/groovebox.git"
17
14
  }
package/package_pub.json CHANGED
@@ -10,8 +10,5 @@
10
10
  },
11
11
  "author": "Remixlabs staff",
12
12
  "license": "ISC",
13
- "dependencies": {
14
- "@remix_labs/web-worker-onlymain": "_FULLVERSION_"
15
- },
16
13
  "repository": "https://github.com/remixlabs/groovebox.git"
17
14
  }
@@ -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
+ ]