u8-mqtt 0.1.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -55
- package/cjs/index.cjs +633 -558
- package/cjs/index.cjs.map +1 -1
- package/cjs/v4.cjs +480 -663
- package/cjs/v4.cjs.map +1 -1
- package/cjs/v5.cjs +632 -551
- package/cjs/v5.cjs.map +1 -1
- package/code/_conn.jsy +53 -54
- package/code/_router.jsy +15 -4
- package/code/base.jsy +36 -17
- package/code/core.jsy +78 -59
- package/code/index.mjs +4 -4
- package/code/v4.mjs +6 -6
- package/code/v5.mjs +14 -6
- package/esm/deno/index.js +636 -563
- package/esm/deno/index.js.map +1 -1
- package/esm/deno/v4.js +487 -670
- package/esm/deno/v4.js.map +1 -1
- package/esm/deno/v5.js +638 -559
- package/esm/deno/v5.js.map +1 -1
- package/esm/node/index.js +629 -556
- package/esm/node/index.js.map +1 -1
- package/esm/node/index.mjs +629 -556
- package/esm/node/index.mjs.map +1 -1
- package/esm/node/v4.js +480 -663
- package/esm/node/v4.js.map +1 -1
- package/esm/node/v4.mjs +480 -663
- package/esm/node/v4.mjs.map +1 -1
- package/esm/node/v5.js +631 -552
- package/esm/node/v5.js.map +1 -1
- package/esm/node/v5.mjs +631 -552
- package/esm/node/v5.mjs.map +1 -1
- package/esm/web/index.js +631 -558
- package/esm/web/index.js.map +1 -1
- package/esm/web/index.min.js +1 -0
- package/esm/web/index.min.js.br +0 -0
- package/esm/web/index.min.js.gz +0 -0
- package/esm/web/v4.js +482 -665
- package/esm/web/v4.js.map +1 -1
- package/esm/web/v4.min.js +1 -0
- package/esm/web/v4.min.js.br +0 -0
- package/esm/web/v4.min.js.gz +0 -0
- package/esm/web/v5.js +633 -554
- package/esm/web/v5.js.map +1 -1
- package/esm/web/v5.min.js +1 -0
- package/esm/web/v5.min.js.br +0 -0
- package/esm/web/v5.min.js.gz +0 -0
- package/package.json +23 -12
- package/code/session.mjs +0 -65
- package/esm/deno/index.mjs +0 -1502
- package/esm/deno/index.mjs.map +0 -1
- package/esm/deno/v4.mjs +0 -1496
- package/esm/deno/v4.mjs.map +0 -1
- package/esm/deno/v5.mjs +0 -1496
- package/esm/deno/v5.mjs.map +0 -1
- package/esm/web/index.min.mjs +0 -1
- package/esm/web/index.mjs +0 -1502
- package/esm/web/index.mjs.map +0 -1
- package/esm/web/v4.min.mjs +0 -1
- package/esm/web/v4.mjs +0 -1496
- package/esm/web/v4.mjs.map +0 -1
- package/esm/web/v5.min.mjs +0 -1
- package/esm/web/v5.mjs +0 -1496
- package/esm/web/v5.mjs.map +0 -1
package/esm/node/v4.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { connect } from 'net';
|
|
1
|
+
import { connect } from 'node:net';
|
|
2
2
|
|
|
3
3
|
function encode_varint(n, a=[]) {
|
|
4
4
|
do {
|
|
@@ -22,7 +22,7 @@ export function decode_varint_loop(u8, i=0) {
|
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
function decode_varint(u8, i=0) {
|
|
25
|
+
function decode_varint$1(u8, i=0) {
|
|
26
26
|
let i0 = i;
|
|
27
27
|
// unrolled for a max of 4 chains
|
|
28
28
|
let n = (u8[i] & 0x7f) << 0;
|
|
@@ -38,251 +38,202 @@ function decode_varint(u8, i=0) {
|
|
|
38
38
|
return [n, i, i0]
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const res = [];
|
|
48
|
-
while (1) {
|
|
49
|
-
const [len_body, len_vh] = decode_varint(u8, 1);
|
|
50
|
-
const len_pkt = len_body + len_vh;
|
|
51
|
-
|
|
52
|
-
if ( u8.byteLength < len_pkt )
|
|
53
|
-
return res
|
|
54
|
-
|
|
55
|
-
let b0 = u8[0];
|
|
56
|
-
let u8_body = 0 === len_body ? null
|
|
57
|
-
: u8.subarray(len_vh, len_pkt);
|
|
58
|
-
|
|
59
|
-
u8 = u8.subarray(len_pkt);
|
|
60
|
-
|
|
61
|
-
const pkt = decode_raw_pkt(b0, u8_body);
|
|
62
|
-
if (undefined !== pkt && null !== pkt)
|
|
63
|
-
res.push( pkt );
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function _u8_join(a, b) {
|
|
69
|
-
const alen = a.byteLength;
|
|
70
|
-
const r = new Uint8Array(alen + b.byteLength);
|
|
71
|
-
r.set(a, 0);
|
|
72
|
-
r.set(b, alen);
|
|
73
|
-
return r
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const mqtt_props = new Map();
|
|
77
|
-
|
|
78
|
-
{
|
|
79
|
-
const entries = [
|
|
80
|
-
[ 0x01, 'u8', 'payload_format_indicator'],
|
|
81
|
-
[ 0x02, 'u32', 'message_expiry_interval'],
|
|
82
|
-
[ 0x03, 'utf8', 'content_type'],
|
|
83
|
-
[ 0x08, 'utf8', 'response_topic'],
|
|
84
|
-
[ 0x09, 'bin', 'correlation_data'],
|
|
85
|
-
[ 0x0B, 'vint', 'subscription_identifier'],
|
|
86
|
-
[ 0x11, 'u32', 'session_expiry_interval'],
|
|
87
|
-
[ 0x12, 'utf8', 'assigned_client_identifier'],
|
|
88
|
-
[ 0x13, 'u16', 'server_keep_alive'],
|
|
89
|
-
[ 0x15, 'utf8', 'authentication_method'],
|
|
90
|
-
[ 0x16, 'bin', 'authentication_data'],
|
|
91
|
-
[ 0x17, 'u8', 'request_problem_information'],
|
|
92
|
-
[ 0x18, 'u32', 'will_delay_interval'],
|
|
93
|
-
[ 0x19, 'u8', 'request_response_information'],
|
|
94
|
-
[ 0x1A, 'utf8', 'response_information'],
|
|
95
|
-
[ 0x1C, 'utf8', 'server_reference'],
|
|
96
|
-
[ 0x1F, 'utf8', 'reason_string'],
|
|
97
|
-
[ 0x21, 'u16', 'receive_maximum'],
|
|
98
|
-
[ 0x22, 'u16', 'topic_alias_maximum'],
|
|
99
|
-
[ 0x23, 'u16', 'topic_alias'],
|
|
100
|
-
[ 0x24, 'u8', 'maximum_qo_s'],
|
|
101
|
-
[ 0x25, 'u8', 'retain_available'],
|
|
102
|
-
[ 0x26, 'pair', 'user_properties', true],
|
|
103
|
-
[ 0x27, 'u32', 'maximum_packet_size'],
|
|
104
|
-
[ 0x28, 'u8', 'wildcard_subscription_available'],
|
|
105
|
-
[ 0x29, 'u8', 'subscription_identifiers_available', true],
|
|
106
|
-
[ 0x2A, 'u8', 'shared_subscription_available'],
|
|
107
|
-
];
|
|
108
|
-
|
|
109
|
-
for (const [id, type, name, plural] of entries) {
|
|
110
|
-
const prop_obj = {id, type, name};
|
|
111
|
-
if (plural) prop_obj.plural = plural;
|
|
112
|
-
mqtt_props.set(prop_obj.id, prop_obj);
|
|
113
|
-
mqtt_props.set(prop_obj.name, prop_obj);
|
|
41
|
+
class U8_Reason extends Number {
|
|
42
|
+
static of(v, pkt_kind, by_kind) {
|
|
43
|
+
let self = new this(v);
|
|
44
|
+
self.reason = by_kind?.[pkt_kind]?.get(v) || pkt_kind;
|
|
45
|
+
return self
|
|
114
46
|
}
|
|
115
47
|
}
|
|
116
48
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
class mqtt_type_reader {
|
|
124
|
-
constructor(buf, idx=0) {
|
|
125
|
-
this.buf = buf;
|
|
126
|
-
this.step = step_from(idx);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
_fork(buf, idx) {
|
|
130
|
-
return { __proto__: this, buf, step: step_from(idx) }
|
|
49
|
+
class mqtt_reader_v4$1 {
|
|
50
|
+
static of(buf) { return this.prototype.of(buf) }
|
|
51
|
+
of(buf) {
|
|
52
|
+
let step = (width, k) => (k=0|step.k, step.k=k+width, k);
|
|
53
|
+
return {__proto__: this, buf, step}
|
|
131
54
|
}
|
|
132
55
|
|
|
133
56
|
has_more() {
|
|
134
|
-
|
|
135
|
-
return buf.byteLength > step(0)
|
|
57
|
+
return this.buf.byteLength > (this.step.k|0)
|
|
136
58
|
}
|
|
137
59
|
|
|
138
60
|
u8() {
|
|
139
|
-
|
|
140
|
-
return buf[step(1)]
|
|
61
|
+
return this.buf[this.step(1)]
|
|
141
62
|
}
|
|
142
63
|
|
|
143
64
|
u16() {
|
|
144
|
-
|
|
145
|
-
const i = step(2);
|
|
65
|
+
let {buf, step} = this, i = step(2);
|
|
146
66
|
return (buf[i]<<8) | buf[i+1]
|
|
147
67
|
}
|
|
148
68
|
|
|
149
69
|
u32() {
|
|
150
|
-
|
|
151
|
-
const i = step(4);
|
|
70
|
+
let {buf, step} = this, i = step(4);
|
|
152
71
|
return (buf[i]<<24) | (buf[i+1]<<16) | (buf[i+2]<<8) | buf[i+3]
|
|
153
72
|
}
|
|
154
73
|
|
|
155
74
|
vint() {
|
|
156
|
-
|
|
157
|
-
|
|
75
|
+
let {buf, step} = this;
|
|
76
|
+
let [n, vi, vi0] = decode_varint$1(buf, step.k|0);
|
|
158
77
|
step(vi - vi0);
|
|
159
78
|
return n
|
|
160
79
|
}
|
|
161
80
|
|
|
162
|
-
vbuf() {
|
|
163
|
-
const {buf, step} = this;
|
|
164
|
-
const [n, vi, vi0] = decode_varint(buf, step(0));
|
|
165
|
-
step(n + vi - vi0);
|
|
166
|
-
return 0 === n ? null
|
|
167
|
-
: buf.subarray(vi, step(0))
|
|
168
|
-
}
|
|
169
|
-
|
|
170
81
|
bin() {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
return buf.subarray(i0, i0+len)
|
|
82
|
+
let {buf, step} = this, i = step(2);
|
|
83
|
+
let len = (buf[i]<<8) | buf[i+1];
|
|
84
|
+
i = step(len);
|
|
85
|
+
return buf.subarray(i, i+len)
|
|
176
86
|
}
|
|
177
87
|
|
|
178
|
-
utf8() { return
|
|
179
|
-
pair() { return [
|
|
88
|
+
utf8() { return new TextDecoder('utf-8').decode(this.bin()) }
|
|
89
|
+
pair() { return [ this.utf8(), this.utf8() ] }
|
|
180
90
|
|
|
181
|
-
|
|
182
|
-
const {buf, step} = this;
|
|
183
|
-
return new FlagsType(buf[step(1)])
|
|
184
|
-
}
|
|
91
|
+
flags(FlagsType) { return new FlagsType(this.buf[this.step(1)]) }
|
|
185
92
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
93
|
+
reason(pkt_kind) {
|
|
94
|
+
let v = this.buf[this.step(1)];
|
|
95
|
+
if (null != v)
|
|
96
|
+
return U8_Reason.of(v, pkt_kind, this._reasons_by)
|
|
189
97
|
}
|
|
190
98
|
|
|
191
99
|
flush() {
|
|
192
|
-
|
|
100
|
+
let {buf, step} = this;
|
|
193
101
|
this.step = this.buf = null;
|
|
194
|
-
return buf.subarray(step
|
|
102
|
+
return buf.subarray(step.k|0)
|
|
195
103
|
}
|
|
196
104
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function mqtt_reader_info(mqtt_reader, ... info_fn_list) {
|
|
108
|
+
mqtt_reader = class extends mqtt_reader {
|
|
109
|
+
static reasons(pkt_type, ...reason_entries) {
|
|
110
|
+
let proto = this.prototype;
|
|
111
|
+
proto._reasons_by = {... proto._reasons_by};
|
|
202
112
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
lst.push([p.name, v]);
|
|
113
|
+
let lut = (proto._reasons_by[pkt_type] ||= new Map());
|
|
114
|
+
for (let [u8, reason] of reason_entries)
|
|
115
|
+
lut.set( u8, reason );
|
|
116
|
+
|
|
117
|
+
return this
|
|
209
118
|
}
|
|
210
|
-
|
|
211
|
-
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
for (let fn_info of info_fn_list)
|
|
122
|
+
fn_info(mqtt_reader);
|
|
123
|
+
|
|
124
|
+
return mqtt_reader
|
|
212
125
|
}
|
|
213
126
|
|
|
127
|
+
class mqtt_writer_v4 {
|
|
128
|
+
static of() { return this.prototype.of() }
|
|
129
|
+
of() { return {__proto__: this, $:[]} }
|
|
214
130
|
|
|
131
|
+
static init() { return this }
|
|
215
132
|
|
|
216
|
-
|
|
217
|
-
constructor(u8, reason) { super(u8); this.reason = reason; }
|
|
218
|
-
}
|
|
133
|
+
as_pkt(pkt_id) { return this.pack([pkt_id]) }
|
|
219
134
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
135
|
+
push(...z) { this.$.push(...z); }
|
|
136
|
+
pack(hdr) {
|
|
137
|
+
let z, i, n=0, parts = this.$;
|
|
138
|
+
this.$ = false;
|
|
139
|
+
for (z of parts) n += z.length;
|
|
224
140
|
|
|
225
|
-
|
|
226
|
-
|
|
141
|
+
hdr = encode_varint(n, hdr);
|
|
142
|
+
i = hdr.length;
|
|
227
143
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
144
|
+
let pkt = new Uint8Array(i + n);
|
|
145
|
+
pkt.set(hdr, 0);
|
|
146
|
+
for (z of parts) {
|
|
147
|
+
pkt.set(z, i);
|
|
148
|
+
i += z.length;
|
|
149
|
+
}
|
|
150
|
+
return pkt
|
|
231
151
|
}
|
|
232
152
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
[ 0x02, 'Connection refused, identifier rejected'],
|
|
238
|
-
[ 0x03, 'Connection refused, server unavailable'],
|
|
239
|
-
[ 0x04, 'Connection refused, bad user name or password'],
|
|
240
|
-
[ 0x05, 'Connection refused, not authorized'],
|
|
153
|
+
u8(v) { this.push([ v & 0xff ]); }
|
|
154
|
+
u16(v) { this.push([ (v>>>8) & 0xff, v & 0xff ]); }
|
|
155
|
+
u32(v) { this.push([ (v>>>24) & 0xff, (v>>>16) & 0xff, (v>>>8) & 0xff, v & 0xff ]); }
|
|
156
|
+
vint(v) { this.push( encode_varint(v) );}
|
|
241
157
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
[ 0x84, 'Unsupported Protocol Version'],
|
|
247
|
-
[ 0x85, 'Client Identifier not valid'],
|
|
248
|
-
[ 0x86, 'Bad User Name or Password'],
|
|
249
|
-
[ 0x87, 'Not authorized'],
|
|
250
|
-
[ 0x88, 'Server unavailable'],
|
|
251
|
-
[ 0x89, 'Server busy'],
|
|
252
|
-
[ 0x8A, 'Banned'],
|
|
253
|
-
[ 0x8C, 'Bad authentication method'],
|
|
254
|
-
[ 0x90, 'Topic Name invalid'],
|
|
255
|
-
[ 0x95, 'Packet too large'],
|
|
256
|
-
[ 0x97, 'Quota exceeded'],
|
|
257
|
-
[ 0x99, 'Payload format invalid'],
|
|
258
|
-
[ 0x9A, 'Retain not supported'],
|
|
259
|
-
[ 0x9B, 'QoS not supported'],
|
|
260
|
-
[ 0x9C, 'Use another server'],
|
|
261
|
-
[ 0x9D, 'Server moved'],
|
|
262
|
-
[ 0x9F, 'Connection rate exceeded'],
|
|
263
|
-
]);
|
|
158
|
+
bin(u8_buf) {
|
|
159
|
+
if (! u8_buf) return this.u16(0)
|
|
160
|
+
if ('string' === typeof u8_buf)
|
|
161
|
+
return this.utf8(u8_buf)
|
|
264
162
|
|
|
163
|
+
if (u8_buf.length !== u8_buf.byteLength)
|
|
164
|
+
u8_buf = new Uint8Array(u8_buf);
|
|
165
|
+
|
|
166
|
+
this.u16(u8_buf.byteLength);
|
|
167
|
+
this.push(u8_buf);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
utf8(v) {
|
|
171
|
+
let u8_buf = new TextEncoder('utf-8').encode(v);
|
|
172
|
+
this.u16(u8_buf.byteLength);
|
|
173
|
+
this.push(u8_buf);
|
|
174
|
+
}
|
|
175
|
+
pair(k,v) { this.utf8(k); this.utf8(v); }
|
|
176
|
+
|
|
177
|
+
flags(v, enc_flags, b0=0) {
|
|
178
|
+
if (undefined !== v && isNaN(+v))
|
|
179
|
+
v = enc_flags(v, 0);
|
|
180
|
+
|
|
181
|
+
v |= b0;
|
|
182
|
+
this.push([v]);
|
|
183
|
+
return v
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
reason(v) { this.push([v | 0]); }
|
|
187
|
+
|
|
188
|
+
flush(buf) {
|
|
189
|
+
if (null != buf)
|
|
190
|
+
this.push(
|
|
191
|
+
'string' === typeof buf
|
|
192
|
+
? new TextEncoder('utf-8').encode(buf)
|
|
193
|
+
: buf );
|
|
194
|
+
|
|
195
|
+
this.push = false;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function mqtt_decode_connack(ns, mqtt_reader) {
|
|
200
|
+
class _connack_flags_ extends Number {
|
|
201
|
+
get session_present() { return this & 0x01 !== 0 }
|
|
202
|
+
}
|
|
265
203
|
|
|
266
204
|
return ns[0x2] = (pkt, u8_body) => {
|
|
267
|
-
|
|
205
|
+
let rdr = mqtt_reader.of(u8_body);
|
|
268
206
|
|
|
269
207
|
pkt.flags =
|
|
270
|
-
rdr.
|
|
208
|
+
rdr.flags(_connack_flags_);
|
|
271
209
|
|
|
272
|
-
pkt.reason = rdr.
|
|
210
|
+
pkt.reason = rdr.reason(pkt.type);
|
|
273
211
|
if (5 <= pkt.mqtt_level)
|
|
274
212
|
pkt.props = rdr.props();
|
|
275
213
|
return pkt }
|
|
276
214
|
}
|
|
277
215
|
|
|
278
|
-
|
|
216
|
+
|
|
217
|
+
function _connack_v4(mqtt_reader) {
|
|
218
|
+
mqtt_reader.reasons('connack',
|
|
219
|
+
// MQTT 3.1.1
|
|
220
|
+
[ 0x00, 'Success'],
|
|
221
|
+
[ 0x01, 'Connection refused, unacceptable protocol version'],
|
|
222
|
+
[ 0x02, 'Connection refused, identifier rejected'],
|
|
223
|
+
[ 0x03, 'Connection refused, server unavailable'],
|
|
224
|
+
[ 0x04, 'Connection refused, bad user name or password'],
|
|
225
|
+
[ 0x05, 'Connection refused, not authorized'],
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function mqtt_decode_publish(ns, mqtt_reader) {
|
|
279
230
|
return ns[0x3] = (pkt, u8_body) => {
|
|
280
|
-
|
|
231
|
+
let {hdr} = pkt;
|
|
281
232
|
pkt.dup = Boolean(hdr & 0x8);
|
|
282
233
|
pkt.retain = Boolean(hdr & 0x1);
|
|
283
|
-
|
|
234
|
+
let qos = pkt.qos = (hdr>>1) & 0x3;
|
|
284
235
|
|
|
285
|
-
|
|
236
|
+
let rdr = mqtt_reader.of(u8_body);
|
|
286
237
|
pkt.topic = rdr.utf8();
|
|
287
238
|
if (0 !== qos)
|
|
288
239
|
pkt.pkt_id = rdr.u16();
|
|
@@ -294,90 +245,55 @@ function mqtt_decode_publish(ns) {
|
|
|
294
245
|
return pkt }
|
|
295
246
|
}
|
|
296
247
|
|
|
297
|
-
function mqtt_decode_puback(ns) {
|
|
298
|
-
const _puback_reason_ = bind_reason_lookup([
|
|
299
|
-
[ 0x00, 'Success'],
|
|
300
|
-
|
|
301
|
-
// MQTT 5.0
|
|
302
|
-
[ 0x10, 'No matching subscribers'],
|
|
303
|
-
[ 0x80, 'Unspecified error'],
|
|
304
|
-
[ 0x83, 'Implementation specific error'],
|
|
305
|
-
[ 0x87, 'Not authorized'],
|
|
306
|
-
[ 0x90, 'Topic Name invalid'],
|
|
307
|
-
[ 0x91, 'Packet identifier in use'],
|
|
308
|
-
[ 0x97, 'Quota exceeded'],
|
|
309
|
-
[ 0x99, 'Payload format invalid'],
|
|
310
|
-
]);
|
|
311
|
-
|
|
312
|
-
|
|
248
|
+
function mqtt_decode_puback(ns, mqtt_reader) {
|
|
313
249
|
return ns[0x4] = (pkt, u8_body) => {
|
|
314
|
-
|
|
250
|
+
let rdr = mqtt_reader.of(u8_body);
|
|
315
251
|
|
|
316
252
|
pkt.pkt_id = rdr.u16();
|
|
317
253
|
if (5 <= pkt.mqtt_level) {
|
|
318
|
-
pkt.reason = rdr.
|
|
254
|
+
pkt.reason = rdr.reason(pkt.type);
|
|
319
255
|
pkt.props = rdr.props();
|
|
320
256
|
}
|
|
321
257
|
|
|
322
258
|
return pkt }
|
|
323
259
|
}
|
|
324
260
|
|
|
325
|
-
function
|
|
326
|
-
const _pubxxx_reason_ = bind_reason_lookup([
|
|
327
|
-
[ 0x00, 'Success' ],
|
|
328
|
-
[ 0x92, 'Packet Identifier not found' ],
|
|
329
|
-
]);
|
|
330
|
-
|
|
331
|
-
return ns[0x5] = ns[0x6] = ns[0x7] = (pkt, u8_body) => {
|
|
332
|
-
const rdr = new mqtt_type_reader(u8_body, 0);
|
|
333
|
-
|
|
334
|
-
pkt.pkt_id = rdr.u16();
|
|
335
|
-
pkt.reason = rdr.u8_reason(_pubxxx_reason_);
|
|
336
|
-
if (5 <= pkt.mqtt_level)
|
|
337
|
-
pkt.props = rdr.props();
|
|
338
|
-
return pkt }
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
function _mqtt_decode_suback(_ack_reason_) {
|
|
261
|
+
function _mqtt_decode_suback(mqtt_reader) {
|
|
342
262
|
return (pkt, u8_body) => {
|
|
343
|
-
|
|
263
|
+
let rdr = mqtt_reader.of(u8_body);
|
|
344
264
|
|
|
345
265
|
pkt.pkt_id = rdr.u16();
|
|
346
266
|
if (5 <= pkt.mqtt_level)
|
|
347
267
|
pkt.props = rdr.props();
|
|
348
268
|
|
|
349
|
-
|
|
269
|
+
let answers = pkt.answers = [];
|
|
350
270
|
while (rdr.has_more())
|
|
351
271
|
answers.push(
|
|
352
|
-
rdr.
|
|
272
|
+
rdr.reason(pkt.type) );
|
|
353
273
|
|
|
354
274
|
return pkt }
|
|
355
275
|
}
|
|
356
276
|
|
|
357
|
-
function mqtt_decode_suback(ns) {
|
|
358
|
-
|
|
277
|
+
function mqtt_decode_suback(ns, mqtt_reader) {
|
|
278
|
+
return ns[0x9] = _mqtt_decode_suback(mqtt_reader)
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function _suback_v4(mqtt_reader) {
|
|
282
|
+
mqtt_reader.reasons('suback',
|
|
359
283
|
// MQTT 3.1.1
|
|
360
284
|
[ 0x00, 'Granted QoS 0'],
|
|
361
285
|
[ 0x01, 'Granted QoS 1'],
|
|
362
286
|
[ 0x02, 'Granted QoS 2'],
|
|
287
|
+
);
|
|
288
|
+
}
|
|
363
289
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
[ 0x83, 'Implementation specific error'],
|
|
367
|
-
[ 0x87, 'Not authorized'],
|
|
368
|
-
[ 0x8F, 'Topic Filter invalid'],
|
|
369
|
-
[ 0x91, 'Packet Identifier in use'],
|
|
370
|
-
[ 0x97, 'Quota exceeded'],
|
|
371
|
-
[ 0x9E, 'Shared Subscriptions not supported'],
|
|
372
|
-
[ 0xA1, 'Subscription Identifiers not supported'],
|
|
373
|
-
[ 0xA2, 'Wildcard Subscriptions not supported'],
|
|
374
|
-
]);
|
|
375
|
-
|
|
376
|
-
return ns[0x9] = _mqtt_decode_suback(_suback_reason_)
|
|
290
|
+
function mqtt_decode_unsuback(ns, mqtt_reader) {
|
|
291
|
+
return ns[0xb] = _mqtt_decode_suback(mqtt_reader)
|
|
377
292
|
}
|
|
378
293
|
|
|
379
|
-
function
|
|
380
|
-
|
|
294
|
+
function _unsuback_v4(mqtt_reader) {
|
|
295
|
+
mqtt_reader.reasons('unsuback',
|
|
296
|
+
// MQTT 3.1.1
|
|
381
297
|
[ 0x00, 'Success'],
|
|
382
298
|
[ 0x11, 'No subscription existed'],
|
|
383
299
|
[ 0x80, 'Unspecified error'],
|
|
@@ -385,222 +301,27 @@ function mqtt_decode_unsuback(ns) {
|
|
|
385
301
|
[ 0x87, 'Not authorized'],
|
|
386
302
|
[ 0x8F, 'Topic Filter invalid'],
|
|
387
303
|
[ 0x91, 'Packet Identifier in use'],
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
return ns[0xb] = _mqtt_decode_suback(_unsuback_reason_)
|
|
304
|
+
);
|
|
391
305
|
}
|
|
392
306
|
|
|
393
307
|
function mqtt_decode_pingxxx(ns) {
|
|
394
308
|
return ns[0xc] = ns[0xd] = pkt => pkt
|
|
395
309
|
}
|
|
396
310
|
|
|
397
|
-
function mqtt_decode_disconnect(ns) {
|
|
398
|
-
const _disconnect_reason_ = bind_reason_lookup([
|
|
399
|
-
// MQTT 5.0
|
|
400
|
-
[ 0x00, 'Normal disconnection'],
|
|
401
|
-
[ 0x04, 'Disconnect with Will Message'],
|
|
402
|
-
[ 0x80, 'Unspecified error'],
|
|
403
|
-
[ 0x81, 'Malformed Packet'],
|
|
404
|
-
[ 0x82, 'Protocol Error'],
|
|
405
|
-
[ 0x83, 'Implementation specific error'],
|
|
406
|
-
[ 0x87, 'Not authorized'],
|
|
407
|
-
[ 0x89, 'Server busy'],
|
|
408
|
-
[ 0x8B, 'Server shutting down'],
|
|
409
|
-
[ 0x8D, 'Keep Alive timeout'],
|
|
410
|
-
[ 0x8E, 'Session taken over'],
|
|
411
|
-
[ 0x8F, 'Topic Filter invalid'],
|
|
412
|
-
[ 0x90, 'Topic Name invalid'],
|
|
413
|
-
[ 0x93, 'Receive Maximum exceeded'],
|
|
414
|
-
[ 0x94, 'Topic Alias invalid'],
|
|
415
|
-
[ 0x95, 'Packet too large'],
|
|
416
|
-
[ 0x96, 'Message rate too high'],
|
|
417
|
-
[ 0x97, 'Quota exceeded'],
|
|
418
|
-
[ 0x98, 'Administrative action'],
|
|
419
|
-
[ 0x99, 'Payload format invalid'],
|
|
420
|
-
[ 0x9A, 'Retain not supported'],
|
|
421
|
-
[ 0x9B, 'QoS not supported'],
|
|
422
|
-
[ 0x9C, 'Use another server'],
|
|
423
|
-
[ 0x9D, 'Server moved'],
|
|
424
|
-
[ 0x9E, 'Shared Subscriptions not supported'],
|
|
425
|
-
[ 0x9F, 'Connection rate exceeded'],
|
|
426
|
-
[ 0xA0, 'Maximum connect time'],
|
|
427
|
-
[ 0xA1, 'Subscription Identifiers not supported'],
|
|
428
|
-
[ 0xA2, 'Wildcard Subscriptions not supported'],
|
|
429
|
-
]);
|
|
430
|
-
|
|
431
|
-
|
|
311
|
+
function mqtt_decode_disconnect(ns, mqtt_reader) {
|
|
432
312
|
return ns[0xe] = (pkt, u8_body) => {
|
|
433
313
|
if (u8_body && 5 <= pkt.mqtt_level) {
|
|
434
|
-
|
|
435
|
-
pkt.reason = rdr.
|
|
436
|
-
pkt.props = rdr.props();
|
|
437
|
-
}
|
|
438
|
-
return pkt }
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
function mqtt_decode_auth(ns) {
|
|
442
|
-
const _auth_reason_ = bind_reason_lookup([
|
|
443
|
-
// MQTT 5.0
|
|
444
|
-
[ 0x00, 'Success' ],
|
|
445
|
-
[ 0x18, 'Continue authentication' ],
|
|
446
|
-
[ 0x19, 'Re-authenticate' ],
|
|
447
|
-
]);
|
|
448
|
-
|
|
449
|
-
return ns[0xf] = (pkt, u8_body) => {
|
|
450
|
-
if ( 5 <= pkt.mqtt_level ) {
|
|
451
|
-
const rdr = new mqtt_type_reader(u8_body, 0);
|
|
452
|
-
pkt.reason = rdr.u8_reason(_auth_reason_);
|
|
314
|
+
let rdr = mqtt_reader.of(u8_body);
|
|
315
|
+
pkt.reason = rdr.reason(pkt.type);
|
|
453
316
|
pkt.props = rdr.props();
|
|
454
317
|
}
|
|
455
318
|
return pkt }
|
|
456
319
|
}
|
|
457
320
|
|
|
458
|
-
function
|
|
459
|
-
const
|
|
460
|
-
|
|
461
|
-
0 === _pool_.length
|
|
462
|
-
? mqtt_pkt_writer(host, _pool_)
|
|
463
|
-
: _pool_.pop()(host)
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
function mqtt_pkt_writer(host, _pool_) {
|
|
467
|
-
// avoid GCing push/pull when they can be reused
|
|
468
|
-
let n=0, rope=[];
|
|
469
|
-
return install(host)
|
|
470
|
-
|
|
471
|
-
function install(_host) {
|
|
472
|
-
host = _host;
|
|
473
|
-
host.push = push;
|
|
474
|
-
host.pack = pack;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
function push(u8) {
|
|
478
|
-
rope.push(u8);
|
|
479
|
-
n += u8.length;
|
|
480
|
-
}
|
|
321
|
+
function mqtt_encode_connect(ns, mqtt_writer) {
|
|
322
|
+
const _c_mqtt_proto = new Uint8Array([
|
|
323
|
+
0, 4, 0x4d, 0x51, 0x54, 0x54 ]);
|
|
481
324
|
|
|
482
|
-
function pack(hdr) {
|
|
483
|
-
host = host.push = host.pack = null;
|
|
484
|
-
|
|
485
|
-
const res = _mqtt_pkt_rope(hdr, n, rope);
|
|
486
|
-
n=0; rope=[];
|
|
487
|
-
if (undefined !== _pool_)
|
|
488
|
-
_pool_.push(install);
|
|
489
|
-
|
|
490
|
-
return res
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
function _mqtt_pkt_rope(hdr, n, rope) {
|
|
496
|
-
const header = encode_varint(n, hdr);
|
|
497
|
-
let i = header.length;
|
|
498
|
-
|
|
499
|
-
const pkt = new Uint8Array(n + i);
|
|
500
|
-
pkt.set(header, 0);
|
|
501
|
-
for (const vec of rope) {
|
|
502
|
-
pkt.set(vec, i);
|
|
503
|
-
i += vec.length;
|
|
504
|
-
}
|
|
505
|
-
return pkt
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
const _is_array = Array.isArray;
|
|
509
|
-
const pack_utf8 = v => new TextEncoder('utf-8').encode(v);
|
|
510
|
-
const pack_u16 = v => [ (v>>>8) & 0xff, v & 0xff ];
|
|
511
|
-
const pack_u32 = v => [ (v>>>24) & 0xff, (v>>>16) & 0xff, (v>>>8) & 0xff, v & 0xff ];
|
|
512
|
-
|
|
513
|
-
class mqtt_type_writer {
|
|
514
|
-
constructor() {
|
|
515
|
-
this._pkt_writer(this);
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
as_pkt(hdr) { return this.pack([hdr]) }
|
|
519
|
-
|
|
520
|
-
u8(v) { this.push([ v & 0xff ]);}
|
|
521
|
-
u16(v) { this.push( pack_u16(v) );}
|
|
522
|
-
u32(v) { this.push( pack_u32(v) );}
|
|
523
|
-
vint(v) { this.push( encode_varint(v) );}
|
|
524
|
-
|
|
525
|
-
_u16_bin(u8_buf) {
|
|
526
|
-
const {push} = this;
|
|
527
|
-
push( pack_u16( u8_buf.byteLength ));
|
|
528
|
-
push( u8_buf );
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
flush(buf) {
|
|
532
|
-
if (null != buf)
|
|
533
|
-
this.push(
|
|
534
|
-
'string' === typeof buf
|
|
535
|
-
? pack_utf8(buf) : buf );
|
|
536
|
-
|
|
537
|
-
this.push = false;
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
bin(u8_buf) {
|
|
541
|
-
if (! u8_buf) return this.u16(0)
|
|
542
|
-
if ('string' === typeof u8_buf)
|
|
543
|
-
return this.utf8(u8_buf)
|
|
544
|
-
|
|
545
|
-
if (u8_buf.length !== u8_buf.byteLength)
|
|
546
|
-
u8_buf = new Uint8Array(u8_buf);
|
|
547
|
-
this._u16_bin(u8_buf);
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
utf8(v) { this._u16_bin( new TextEncoder('utf-8').encode(v) ); }
|
|
551
|
-
|
|
552
|
-
pair(k,v) {
|
|
553
|
-
this.utf8(k);
|
|
554
|
-
this.utf8(v);
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
u8_flags(v, enc_flags, b0=0) {
|
|
558
|
-
if (undefined !== v && isNaN(+v))
|
|
559
|
-
v = enc_flags(v, 0);
|
|
560
|
-
|
|
561
|
-
v |= b0;
|
|
562
|
-
this.push([v]);
|
|
563
|
-
return v
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
u8_reason(v) { this.push([v | 0]); }
|
|
567
|
-
|
|
568
|
-
props(props) {
|
|
569
|
-
if (! props)
|
|
570
|
-
return this.u8(0)
|
|
571
|
-
|
|
572
|
-
if (! _is_array(props))
|
|
573
|
-
props = props.entries
|
|
574
|
-
? Array.from(props.entries())
|
|
575
|
-
: Object.entries(props);
|
|
576
|
-
|
|
577
|
-
if (0 === props.length)
|
|
578
|
-
return this.u8(0)
|
|
579
|
-
|
|
580
|
-
const wrt = this._fork();
|
|
581
|
-
for (const [name, value] of props) {
|
|
582
|
-
const {id, type} = mqtt_props.get(name);
|
|
583
|
-
wrt.u8(id);
|
|
584
|
-
wrt[type](value);
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
this.push(wrt.pack([]));
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
_fork() {
|
|
591
|
-
let self = { __proto__: this };
|
|
592
|
-
this._pkt_writer(self);
|
|
593
|
-
return self
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
mqtt_type_writer.prototype._pkt_writer =
|
|
598
|
-
mqtt_pkt_writer_pool();
|
|
599
|
-
|
|
600
|
-
const _c_mqtt_proto = new Uint8Array([
|
|
601
|
-
0, 4, 0x4d, 0x51, 0x54, 0x54 ]);
|
|
602
|
-
|
|
603
|
-
function mqtt_encode_connect(ns) {
|
|
604
325
|
const _enc_flags_connect = flags => 0
|
|
605
326
|
| ( flags.reserved ? 0x01 : 0 )
|
|
606
327
|
| ( (flags.will_qos & 0x3) << 3 )
|
|
@@ -615,13 +336,13 @@ function mqtt_encode_connect(ns) {
|
|
|
615
336
|
| ( will.retain ? 0x20 : 0 );
|
|
616
337
|
|
|
617
338
|
return ns.connect = ( mqtt_level, pkt ) => {
|
|
618
|
-
|
|
339
|
+
let wrt = mqtt_writer.of(pkt);
|
|
619
340
|
|
|
620
341
|
wrt.push(_c_mqtt_proto);
|
|
621
342
|
wrt.u8( mqtt_level );
|
|
622
343
|
|
|
623
|
-
|
|
624
|
-
|
|
344
|
+
let {will, username, password} = pkt;
|
|
345
|
+
let flags = wrt.flags(
|
|
625
346
|
pkt.flags,
|
|
626
347
|
_enc_flags_connect,
|
|
627
348
|
0 | (username ? 0x80 : 0)
|
|
@@ -653,10 +374,10 @@ function mqtt_encode_connect(ns) {
|
|
|
653
374
|
}
|
|
654
375
|
}
|
|
655
376
|
|
|
656
|
-
function mqtt_encode_publish(ns) {
|
|
377
|
+
function mqtt_encode_publish(ns, mqtt_writer) {
|
|
657
378
|
return ns.publish = ( mqtt_level, pkt ) => {
|
|
658
|
-
|
|
659
|
-
|
|
379
|
+
let qos = (pkt.qos & 0x3) << 1;
|
|
380
|
+
let wrt = mqtt_writer.of(pkt);
|
|
660
381
|
|
|
661
382
|
wrt.utf8(pkt.topic);
|
|
662
383
|
if (0 !== qos)
|
|
@@ -674,13 +395,13 @@ function mqtt_encode_publish(ns) {
|
|
|
674
395
|
}
|
|
675
396
|
}
|
|
676
397
|
|
|
677
|
-
function mqtt_encode_puback(ns) {
|
|
398
|
+
function mqtt_encode_puback(ns, mqtt_writer) {
|
|
678
399
|
return ns.puback = ( mqtt_level, pkt ) => {
|
|
679
|
-
|
|
400
|
+
let wrt = mqtt_writer.of(pkt);
|
|
680
401
|
|
|
681
402
|
wrt.u16(pkt.pkt_id);
|
|
682
403
|
if (5 <= mqtt_level) {
|
|
683
|
-
wrt.
|
|
404
|
+
wrt.reason(pkt.reason);
|
|
684
405
|
wrt.props(pkt.props);
|
|
685
406
|
}
|
|
686
407
|
|
|
@@ -688,32 +409,32 @@ function mqtt_encode_puback(ns) {
|
|
|
688
409
|
}
|
|
689
410
|
}
|
|
690
411
|
|
|
691
|
-
function mqtt_encode_subscribe(ns) {
|
|
412
|
+
function mqtt_encode_subscribe(ns, mqtt_writer) {
|
|
692
413
|
const _enc_subscribe_flags = opts => 0
|
|
693
414
|
| ( opts.qos & 0x3 )
|
|
694
415
|
| ( opts.retain ? 0x4 : 0 )
|
|
695
416
|
| ( (opts.retain_handling & 0x3) << 2 );
|
|
696
417
|
|
|
697
418
|
return ns.subscribe = ( mqtt_level, pkt ) => {
|
|
698
|
-
|
|
419
|
+
let wrt = mqtt_writer.of(pkt);
|
|
699
420
|
|
|
700
421
|
wrt.u16(pkt.pkt_id);
|
|
701
422
|
if (5 <= mqtt_level)
|
|
702
423
|
wrt.props(pkt.props);
|
|
703
424
|
|
|
704
|
-
|
|
705
|
-
for (
|
|
425
|
+
let f0 = _enc_subscribe_flags(pkt);
|
|
426
|
+
for (let each of pkt.topics) {
|
|
706
427
|
if ('string' === typeof each) {
|
|
707
428
|
wrt.utf8(each);
|
|
708
429
|
wrt.u8(f0);
|
|
709
430
|
} else {
|
|
710
431
|
let [topic, opts] =
|
|
711
|
-
|
|
432
|
+
Array.isArray(each) ? each
|
|
712
433
|
: [each.topic, each.opts];
|
|
713
434
|
|
|
714
435
|
wrt.utf8(topic);
|
|
715
436
|
if (undefined === opts) wrt.u8(f0);
|
|
716
|
-
else wrt.
|
|
437
|
+
else wrt.flags(opts, _enc_subscribe_flags);
|
|
717
438
|
}
|
|
718
439
|
}
|
|
719
440
|
|
|
@@ -721,15 +442,15 @@ function mqtt_encode_subscribe(ns) {
|
|
|
721
442
|
}
|
|
722
443
|
}
|
|
723
444
|
|
|
724
|
-
function mqtt_encode_unsubscribe(ns) {
|
|
445
|
+
function mqtt_encode_unsubscribe(ns, mqtt_writer) {
|
|
725
446
|
return ns.unsubscribe = ( mqtt_level, pkt ) => {
|
|
726
|
-
|
|
447
|
+
let wrt = mqtt_writer.of(pkt);
|
|
727
448
|
|
|
728
449
|
wrt.u16(pkt.pkt_id);
|
|
729
450
|
if (5 <= mqtt_level)
|
|
730
451
|
wrt.props(pkt.props);
|
|
731
452
|
|
|
732
|
-
for (
|
|
453
|
+
for (let topic of pkt.topics)
|
|
733
454
|
wrt.utf8(topic);
|
|
734
455
|
|
|
735
456
|
return wrt.as_pkt(0xa2)
|
|
@@ -741,13 +462,13 @@ function mqtt_encode_pingxxx(ns) {
|
|
|
741
462
|
ns.pingresp = () => new Uint8Array([ 0xd0, 0 ]);
|
|
742
463
|
}
|
|
743
464
|
|
|
744
|
-
function mqtt_encode_disconnect(ns) {
|
|
465
|
+
function mqtt_encode_disconnect(ns, mqtt_writer) {
|
|
745
466
|
return ns.disconnect = ( mqtt_level, pkt ) => {
|
|
746
|
-
|
|
467
|
+
let wrt = mqtt_writer.of(pkt);
|
|
747
468
|
|
|
748
469
|
if (pkt && 5 <= mqtt_level) {
|
|
749
470
|
if (pkt.reason || pkt.props) {
|
|
750
|
-
wrt.
|
|
471
|
+
wrt.reason(pkt.reason);
|
|
751
472
|
wrt.props(pkt.props);
|
|
752
473
|
}
|
|
753
474
|
}
|
|
@@ -756,185 +477,233 @@ function mqtt_encode_disconnect(ns) {
|
|
|
756
477
|
}
|
|
757
478
|
}
|
|
758
479
|
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
480
|
+
// not a v4 packet: import { mqtt_encode_auth } from './encode/auth.mjs'
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
const mqtt_decode_v4 = [
|
|
484
|
+
mqtt_decode_connack,
|
|
485
|
+
mqtt_decode_publish,
|
|
486
|
+
mqtt_decode_puback,
|
|
487
|
+
mqtt_decode_suback,
|
|
488
|
+
mqtt_decode_unsuback,
|
|
489
|
+
mqtt_decode_pingxxx,
|
|
490
|
+
mqtt_decode_disconnect,
|
|
491
|
+
];
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
const mqtt_encode_v4 = [
|
|
495
|
+
mqtt_encode_connect,
|
|
496
|
+
mqtt_encode_puback,
|
|
497
|
+
mqtt_encode_publish,
|
|
498
|
+
mqtt_encode_subscribe,
|
|
499
|
+
mqtt_encode_unsubscribe,
|
|
500
|
+
mqtt_encode_pingxxx,
|
|
501
|
+
mqtt_encode_disconnect,
|
|
502
|
+
];
|
|
503
|
+
|
|
504
|
+
const mqtt_reader_v4 = /* #__PURE__ */
|
|
505
|
+
mqtt_reader_info(
|
|
506
|
+
mqtt_reader_v4$1,
|
|
507
|
+
_connack_v4,
|
|
508
|
+
_suback_v4,
|
|
509
|
+
_unsuback_v4,
|
|
510
|
+
);
|
|
511
|
+
|
|
512
|
+
const mqtt_opts_v4 =
|
|
513
|
+
{ decode_fns: mqtt_decode_v4,
|
|
514
|
+
mqtt_reader: mqtt_reader_v4,
|
|
515
|
+
encode_fns: mqtt_encode_v4,
|
|
516
|
+
mqtt_writer: mqtt_writer_v4, };
|
|
517
|
+
|
|
518
|
+
/*
|
|
519
|
+
export function decode_varint_loop(u8, i=0) {
|
|
520
|
+
let i0 = i
|
|
521
|
+
let shift = 0, n = (u8[i] & 0x7f)
|
|
522
|
+
while ( 0x80 & u8[i++] )
|
|
523
|
+
n |= (u8[i] & 0x7f) << (shift += 7)
|
|
763
524
|
|
|
764
|
-
|
|
525
|
+
return [n, i, i0]
|
|
526
|
+
}
|
|
527
|
+
*/
|
|
765
528
|
|
|
766
|
-
wrt.u8_reason(pkt.reason);
|
|
767
|
-
wrt.props(pkt.props);
|
|
768
529
|
|
|
769
|
-
|
|
530
|
+
function decode_varint(u8, i=0) {
|
|
531
|
+
let i0 = i;
|
|
532
|
+
// unrolled for a max of 4 chains
|
|
533
|
+
let n = (u8[i] & 0x7f) << 0;
|
|
534
|
+
if ( 0x80 & u8[i++] ) {
|
|
535
|
+
n |= (u8[i] & 0x7f) << 7;
|
|
536
|
+
if ( 0x80 & u8[i++] ) {
|
|
537
|
+
n |= (u8[i] & 0x7f) << 14;
|
|
538
|
+
if ( 0x80 & u8[i++] ) {
|
|
539
|
+
n |= (u8[i] & 0x7f) << 21;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
770
542
|
}
|
|
543
|
+
return [n, i, i0]
|
|
771
544
|
}
|
|
772
545
|
|
|
546
|
+
function mqtt_raw_dispatch(opt) {
|
|
547
|
+
let u8 = new Uint8Array(0);
|
|
548
|
+
return u8_buf => {
|
|
549
|
+
u8 = 0 === u8.byteLength
|
|
550
|
+
? u8_buf : _u8_join(u8, u8_buf);
|
|
773
551
|
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
552
|
+
let res = [];
|
|
553
|
+
while (1) {
|
|
554
|
+
let [len_body, len_vh] = decode_varint(u8, 1);
|
|
555
|
+
let len_pkt = len_body + len_vh;
|
|
777
556
|
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
const decode_pkt = by_id[b0>>>4] || by_id[0];
|
|
781
|
-
if (undefined !== decode_pkt)
|
|
782
|
-
return decode_pkt({__proto__: _pkt_ctx_, b0}, u8_body)
|
|
783
|
-
})
|
|
784
|
-
}
|
|
557
|
+
if ( u8.byteLength < len_pkt )
|
|
558
|
+
return res
|
|
785
559
|
|
|
560
|
+
let b0 = u8[0];
|
|
561
|
+
let u8_body = 0 === len_body ? null
|
|
562
|
+
: u8.subarray(len_vh, len_pkt);
|
|
786
563
|
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
564
|
+
u8 = u8.subarray(len_pkt);
|
|
565
|
+
|
|
566
|
+
let pkt = opt.decode_pkt(b0, u8_body, opt);
|
|
567
|
+
if (null != pkt)
|
|
568
|
+
res.push( pkt );
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
790
572
|
|
|
791
|
-
|
|
792
|
-
|
|
573
|
+
function _u8_join(a, b) {
|
|
574
|
+
let alen = a.byteLength, r = new Uint8Array(alen + b.byteLength);
|
|
575
|
+
r.set(a, 0);
|
|
576
|
+
r.set(b, alen);
|
|
577
|
+
return r
|
|
793
578
|
}
|
|
794
579
|
|
|
580
|
+
const _pkt_types = ['~', 'connect', 'connack', 'publish', 'puback', 'pubrec', 'pubrel', 'pubcomp', 'subscribe', 'suback', 'unsubscribe', 'unsuback', 'pingreq', 'pingresp', 'disconnect', 'auth'];
|
|
795
581
|
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
582
|
+
function mqtt_pkt_ctx(mqtt_level, opts, pkt_ctx) {
|
|
583
|
+
pkt_ctx = {
|
|
584
|
+
__proto__: pkt_ctx || opts.pkt_ctx,
|
|
585
|
+
mqtt_level,
|
|
586
|
+
get hdr() { return this.b0 & 0xf },
|
|
587
|
+
get id() { return this.b0 >>> 4 },
|
|
588
|
+
get type() { return _pkt_types[this.b0 >>> 4] },
|
|
589
|
+
};
|
|
803
590
|
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
591
|
+
let op, _decode_by_id=[], _encode_by_type={};
|
|
592
|
+
for (op of opts.encode_fns)
|
|
593
|
+
op(_encode_by_type, opts.mqtt_writer);
|
|
594
|
+
for (op of opts.decode_fns)
|
|
595
|
+
op(_decode_by_id, opts.mqtt_reader);
|
|
808
596
|
|
|
809
|
-
return
|
|
810
|
-
|
|
811
|
-
return [ sess_decode(_base_), sess_encode(_base_), _base_ ] }
|
|
812
|
-
}
|
|
597
|
+
return {
|
|
598
|
+
pkt_ctx,
|
|
813
599
|
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
let std_pkt_api = {
|
|
821
|
-
utf8(u8) { return as_utf8( u8 || this.payload ) },
|
|
822
|
-
json(u8) { return JSON.parse( this.utf8(u8) || null ) },
|
|
823
|
-
text(u8) { return this.utf8(u8) },
|
|
824
|
-
};
|
|
825
|
-
|
|
826
|
-
mqtt_session_ctx.ctx = ctx =
|
|
827
|
-
_bind_mqtt_session_ctx(
|
|
828
|
-
[ // lst_decode_ops
|
|
829
|
-
mqtt_decode_connack,
|
|
830
|
-
mqtt_decode_disconnect,
|
|
831
|
-
mqtt_decode_publish,
|
|
832
|
-
mqtt_decode_puback,
|
|
833
|
-
mqtt_decode_pubxxx,
|
|
834
|
-
mqtt_decode_pingxxx,
|
|
835
|
-
mqtt_decode_suback,
|
|
836
|
-
mqtt_decode_unsuback,
|
|
837
|
-
mqtt_decode_auth, ],
|
|
838
|
-
|
|
839
|
-
[ // lst_encode_ops
|
|
840
|
-
mqtt_encode_connect,
|
|
841
|
-
mqtt_encode_disconnect,
|
|
842
|
-
mqtt_encode_publish,
|
|
843
|
-
mqtt_encode_puback,
|
|
844
|
-
mqtt_encode_pingxxx,
|
|
845
|
-
mqtt_encode_subscribe,
|
|
846
|
-
mqtt_encode_unsubscribe,
|
|
847
|
-
mqtt_encode_auth, ],
|
|
848
|
-
|
|
849
|
-
std_pkt_api );
|
|
850
|
-
}
|
|
600
|
+
encode_pkt(type, pkt) {
|
|
601
|
+
return _encode_by_type[type]( mqtt_level, pkt ) },
|
|
602
|
+
|
|
603
|
+
decode_pkt(b0, u8_body) {
|
|
604
|
+
let fn_decode = _decode_by_id[b0>>>4] || _decode_by_id[0];
|
|
605
|
+
return fn_decode?.({__proto__: this.pkt_ctx, b0}, u8_body) },
|
|
851
606
|
|
|
852
|
-
|
|
607
|
+
mqtt_stream() {
|
|
608
|
+
let self = { __proto__: this, pkt_ctx: { __proto__: pkt_ctx } };
|
|
609
|
+
self.pkt_ctx._base_ = self.pkt_ctx;
|
|
610
|
+
self.decode = mqtt_raw_dispatch(self);
|
|
611
|
+
return self
|
|
612
|
+
},
|
|
613
|
+
}
|
|
853
614
|
}
|
|
854
615
|
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
616
|
+
Object.freeze({ao_done: true});
|
|
617
|
+
|
|
618
|
+
function ao_defer_ctx(as_res = (...args) => args) {
|
|
619
|
+
let y,n,_pset = (a,b) => { y=a, n=b; };
|
|
620
|
+
return p =>(
|
|
621
|
+
p = new Promise(_pset)
|
|
622
|
+
, as_res(p, y, n)) }
|
|
858
623
|
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
let _send = client._send = _asy_send;
|
|
624
|
+
const ao_defer_v = /* #__PURE__ */
|
|
625
|
+
ao_defer_ctx();
|
|
862
626
|
|
|
863
|
-
|
|
864
|
-
|
|
627
|
+
Promise.resolve({type:'init'});
|
|
628
|
+
|
|
629
|
+
function _mqtt_conn(client, [on_mqtt, pkt_future]) {
|
|
630
|
+
let _q_init = ao_defer_v(), _q_ready = ao_defer_v();
|
|
631
|
+
let _send_ready = async (...args) => (await _q_ready[0])(...args);
|
|
632
|
+
let _send_mqtt_pkt, _has_connected;
|
|
633
|
+
client._send = _send_ready;
|
|
865
634
|
|
|
866
635
|
return {
|
|
867
|
-
|
|
868
|
-
, is_set: (() =>_is_set)
|
|
636
|
+
async when_ready() {await _q_ready[0];}
|
|
869
637
|
|
|
870
|
-
,
|
|
871
|
-
tid_ping = clearInterval(tid_ping);
|
|
872
|
-
client._send = _send = _asy_send;
|
|
873
|
-
_is_set = false;
|
|
638
|
+
, ping: _ping_interval (() =>_send_mqtt_pkt?.('pingreq'))
|
|
874
639
|
|
|
875
|
-
|
|
876
|
-
|
|
640
|
+
, reset(err) {
|
|
641
|
+
if (! _send_mqtt_pkt) {return}
|
|
877
642
|
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
643
|
+
if (err) {
|
|
644
|
+
_q_init[2](err);}
|
|
645
|
+
|
|
646
|
+
_send_mqtt_pkt = null;
|
|
647
|
+
_q_init = ao_defer_v();
|
|
648
|
+
client._send = _send_ready;
|
|
649
|
+
|
|
650
|
+
// call client.on_conn_reset in next promise microtask
|
|
651
|
+
client.conn_emit('on_disconnect', false===err, err);}
|
|
884
652
|
|
|
885
653
|
, async send_connect(... args) {
|
|
886
|
-
if (
|
|
887
|
-
|
|
654
|
+
if (! _send_mqtt_pkt) {
|
|
655
|
+
await _q_init[0]; }// _send_mqtt_pkt is set before fulfilled
|
|
888
656
|
|
|
889
657
|
// await connack response
|
|
890
|
-
let res = await
|
|
658
|
+
let res = await _send_mqtt_pkt(...args);
|
|
659
|
+
if (0 == res[0].reason) {
|
|
660
|
+
_has_connected = true;
|
|
661
|
+
// resolve _q_ready[0] with _send_mqtt_pkt closure
|
|
662
|
+
_q_ready[1](client._send = _send_mqtt_pkt);
|
|
663
|
+
_q_ready = ao_defer_v();
|
|
664
|
+
client.conn_emit('on_ready');}
|
|
891
665
|
|
|
892
|
-
client._send = _send;
|
|
893
|
-
q.notify(_send);
|
|
894
666
|
return res}
|
|
895
667
|
|
|
896
|
-
,
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
668
|
+
, is_set: (() =>!! _send_mqtt_pkt)
|
|
669
|
+
, set(mqtt_ctx, send_u8_pkt) {
|
|
670
|
+
if (_send_mqtt_pkt) {
|
|
671
|
+
throw new Error('Already connected')}
|
|
900
672
|
|
|
673
|
+
mqtt_ctx = mqtt_ctx.mqtt_stream();
|
|
674
|
+
let sess_ctx = {mqtt: client};
|
|
901
675
|
let on_mqtt_chunk = u8_buf =>
|
|
902
|
-
on_mqtt(
|
|
903
|
-
mqtt_decode(u8_buf),
|
|
904
|
-
{mqtt: client});
|
|
676
|
+
on_mqtt(mqtt_ctx.decode(u8_buf), sess_ctx);
|
|
905
677
|
|
|
906
|
-
|
|
678
|
+
_send_mqtt_pkt = async (type, pkt, key) => {
|
|
907
679
|
let res = undefined !== key
|
|
908
680
|
? pkt_future(key) : true;
|
|
909
681
|
|
|
910
682
|
await send_u8_pkt(
|
|
911
|
-
|
|
683
|
+
mqtt_ctx.encode_pkt(type, pkt));
|
|
912
684
|
|
|
913
685
|
return res};
|
|
914
686
|
|
|
915
|
-
|
|
916
|
-
q0.notify(_send);
|
|
687
|
+
_q_init[1](_send_mqtt_pkt); // resolve _q_init with _send_mqtt_pkt closure
|
|
917
688
|
|
|
918
689
|
// call client.on_live in next promise microtask
|
|
919
|
-
|
|
920
|
-
|
|
690
|
+
client.conn_emit('on_live', _has_connected);
|
|
921
691
|
return on_mqtt_chunk} } }
|
|
922
692
|
|
|
923
693
|
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
}
|
|
694
|
+
function _ping_interval(send_ping) {
|
|
695
|
+
let tid;
|
|
696
|
+
return (( td ) => {
|
|
697
|
+
tid = clearInterval(tid);
|
|
698
|
+
if (td) {
|
|
699
|
+
tid = setInterval(send_ping, 1000 * td);
|
|
700
|
+
|
|
701
|
+
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
// ensure the interval allows the NodeJS event loop to exit
|
|
705
|
+
tid.unref?.();
|
|
706
|
+
return true} }) }
|
|
938
707
|
|
|
939
708
|
function parse(str, loose) {
|
|
940
709
|
if (str instanceof RegExp) return { keys:false, pattern:str };
|
|
@@ -968,7 +737,7 @@ function parse(str, loose) {
|
|
|
968
737
|
function _ignore(pkt, params, ctx) {ctx.done = true;}
|
|
969
738
|
|
|
970
739
|
function _mqtt_topic_router() {
|
|
971
|
-
let pri_lsts = [[],[]];
|
|
740
|
+
let pri_lsts = [[],[]], rm = Symbol();
|
|
972
741
|
let find = topic => _mqtt_routes_iter(pri_lsts, topic);
|
|
973
742
|
|
|
974
743
|
return {find,
|
|
@@ -992,8 +761,7 @@ function _mqtt_topic_router() {
|
|
|
992
761
|
|
|
993
762
|
, remove(topic_route, priority) {
|
|
994
763
|
let lst = pri_lsts[priority ? 0 : 1];
|
|
995
|
-
|
|
996
|
-
pri_lsts[priority ? 0 : 1] = lst;}
|
|
764
|
+
return _mqtt_route_remove([lst], topic_route)}
|
|
997
765
|
|
|
998
766
|
, clear(priority) {
|
|
999
767
|
pri_lsts[priority ? 0 : 1] = [];
|
|
@@ -1002,9 +770,13 @@ function _mqtt_topic_router() {
|
|
|
1002
770
|
|
|
1003
771
|
, async invoke(pkt, ctx) {
|
|
1004
772
|
ctx.idx = 0;
|
|
773
|
+
ctx.rm = rm;
|
|
1005
774
|
|
|
1006
775
|
for (let [fn, params] of find(pkt.topic)) {
|
|
1007
|
-
await fn(pkt, params, ctx);
|
|
776
|
+
let res = await fn(pkt, params, ctx);
|
|
777
|
+
|
|
778
|
+
if (rm === res) {
|
|
779
|
+
_mqtt_route_remove(pri_lsts, fn);}
|
|
1008
780
|
|
|
1009
781
|
if (ctx.done) {
|
|
1010
782
|
break}
|
|
@@ -1050,6 +822,14 @@ function _mqtt_route_match_one(topic, {keys, pattern, tgt}) {
|
|
|
1050
822
|
params[ keys[i] ] = match[1+i];}
|
|
1051
823
|
return [tgt, params]}
|
|
1052
824
|
|
|
825
|
+
|
|
826
|
+
function _mqtt_route_remove(all_route_lists, query) {
|
|
827
|
+
let match = route => route===query || route.tgt===query || route.key===query;
|
|
828
|
+
for (let lst of all_route_lists) {
|
|
829
|
+
let i = lst.findIndex(match);
|
|
830
|
+
if (0 <= i) {return !! lst.splice(i,1)} }
|
|
831
|
+
return false}
|
|
832
|
+
|
|
1053
833
|
const _mqtt_cmdid_dispatch ={
|
|
1054
834
|
create(target) {
|
|
1055
835
|
return {__proto__: this, target, hashbelt: [new Map()]} }
|
|
@@ -1142,20 +922,38 @@ function _mqtt_dispatch(opt, target) {
|
|
|
1142
922
|
_disp_.rotate_belt(rotate_n);
|
|
1143
923
|
rotate_ts = rotate_td + Date.now();} } }
|
|
1144
924
|
|
|
1145
|
-
class
|
|
925
|
+
class MQTTError extends Error {
|
|
926
|
+
constructor(mqtt_pkt, reason=mqtt_pkt.reason) {
|
|
927
|
+
super(`[0x${reason.toString(16)}] ${reason.reason}`);
|
|
928
|
+
this.mqtt_pkt = mqtt_pkt;
|
|
929
|
+
this.reason = reason;} }
|
|
930
|
+
|
|
931
|
+
class MQTTBase {
|
|
1146
932
|
constructor(opt={}) {
|
|
1147
933
|
this._conn_ = _mqtt_conn(this,
|
|
1148
934
|
this._init_dispatch(opt, this)); }
|
|
1149
935
|
|
|
936
|
+
async conn_emit(evt, arg, err_arg) {
|
|
937
|
+
this.log_conn?.(evt, arg, err_arg);
|
|
938
|
+
try {
|
|
939
|
+
let fn_evt = this[await evt]; // microtask break
|
|
940
|
+
if (fn_evt) {
|
|
941
|
+
await fn_evt.call(this, this, arg, err_arg);}
|
|
942
|
+
else if (err_arg) {
|
|
943
|
+
await this.on_error(err_arg, evt);} }
|
|
944
|
+
catch (err) {
|
|
945
|
+
this.on_error(err, evt);} }
|
|
946
|
+
|
|
947
|
+
on_error(err, err_path) {
|
|
948
|
+
console.warn('[[u8-mqtt error: %s]]', err_path, err); }
|
|
949
|
+
|
|
1150
950
|
// Handshaking Packets
|
|
1151
951
|
|
|
1152
952
|
async connect(pkt={}) {
|
|
1153
|
-
let
|
|
1154
|
-
if (
|
|
1155
|
-
pkt.client_id = cid = this.init_client_id(['u8-mqtt--', '']);}
|
|
1156
|
-
else if (Array.isArray(cid)) {
|
|
953
|
+
let cid = pkt.client_id || ['u8-mqtt--', ''];
|
|
954
|
+
if (Array.isArray(cid)) {
|
|
1157
955
|
pkt.client_id = cid = this.init_client_id(cid);}
|
|
1158
|
-
|
|
956
|
+
this.client_id = cid;
|
|
1159
957
|
|
|
1160
958
|
if (null == pkt.keep_alive) {
|
|
1161
959
|
pkt.keep_alive = 60;}
|
|
@@ -1163,13 +961,16 @@ class MQTTBaseClient {
|
|
|
1163
961
|
let res = await this._conn_
|
|
1164
962
|
.send_connect('connect', pkt, 'connack');
|
|
1165
963
|
|
|
964
|
+
if (0 != res[0].reason) {
|
|
965
|
+
throw new this.MQTTError(res[0])}
|
|
966
|
+
|
|
1166
967
|
// TODO: merge with server's keep_alive frequency
|
|
1167
968
|
this._conn_.ping(pkt.keep_alive);
|
|
1168
969
|
return res}
|
|
1169
970
|
|
|
1170
971
|
async disconnect(pkt={}) {
|
|
1171
972
|
let res = await this._send('disconnect', pkt);
|
|
1172
|
-
this._conn_.reset();
|
|
973
|
+
this._conn_.reset(false);
|
|
1173
974
|
return res}
|
|
1174
975
|
|
|
1175
976
|
auth(pkt={}) {
|
|
@@ -1183,8 +984,9 @@ class MQTTBaseClient {
|
|
|
1183
984
|
pkt = _as_topics(pkt, ex);
|
|
1184
985
|
return this._send('subscribe', pkt, pkt)}
|
|
1185
986
|
_sub_chain(topic, ex) {
|
|
987
|
+
let res = this.subscribe([[ topic ]], ex);
|
|
1186
988
|
let subs = this.subs ||(this.subs = new Map());
|
|
1187
|
-
subs.set(topic,
|
|
989
|
+
subs.set((res.topic = topic), (subs.last = res));
|
|
1188
990
|
return this }// fluent api -- return this and track side effects
|
|
1189
991
|
|
|
1190
992
|
// alias: unsub
|
|
@@ -1278,22 +1080,19 @@ class MQTTBaseClient {
|
|
|
1278
1080
|
return this.router = _mqtt_topic_router()}
|
|
1279
1081
|
|
|
1280
1082
|
_init_dispatch(opt) {
|
|
1281
|
-
let router = this._init_router(opt, this);
|
|
1282
|
-
|
|
1283
1083
|
let tgt ={
|
|
1284
1084
|
__proto__: opt.on_mqtt_type || {}
|
|
1285
|
-
, router};
|
|
1286
|
-
|
|
1287
|
-
if (! tgt.mqtt_publish) {
|
|
1288
|
-
tgt.mqtt_publish = router.invoke;}
|
|
1085
|
+
, router: this._init_router(opt, this)};
|
|
1289
1086
|
|
|
1087
|
+
tgt.mqtt_publish ||= tgt.router.invoke;
|
|
1290
1088
|
return _mqtt_dispatch(this, tgt)} }
|
|
1291
1089
|
|
|
1292
1090
|
|
|
1293
1091
|
{
|
|
1294
|
-
let p =
|
|
1092
|
+
let p = MQTTBase.prototype;
|
|
1295
1093
|
Object.assign(p,{
|
|
1296
|
-
|
|
1094
|
+
MQTTError
|
|
1095
|
+
, pub: p.publish
|
|
1297
1096
|
, sub: p.subscribe
|
|
1298
1097
|
, unsub: p.unsubscribe
|
|
1299
1098
|
, sub_topic: p.subscribe_topic
|
|
@@ -1349,7 +1148,7 @@ async function _pub(self, pkt, pub_opt) {
|
|
|
1349
1148
|
|
|
1350
1149
|
if (pub_opt) {
|
|
1351
1150
|
if (pub_opt.props) {
|
|
1352
|
-
pkt.props = props;}
|
|
1151
|
+
pkt.props = pub_opt.props;}
|
|
1353
1152
|
if (pub_opt.xform) {
|
|
1354
1153
|
pkt = pub_opt.xform(pkt) || pkt;} }
|
|
1355
1154
|
|
|
@@ -1372,45 +1171,67 @@ async function _pub(self, pkt, pub_opt) {
|
|
|
1372
1171
|
, oqr: (self, topic, msg, pub_opt) =>
|
|
1373
1172
|
_pub(self, {topic, msg, arg: 'msg', qos:1, retain: 1}, pub_opt)} ); }
|
|
1374
1173
|
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1174
|
+
const pkt_api = {
|
|
1175
|
+
utf8(u8) { return new TextDecoder('utf-8').decode(u8 || this.payload ) },
|
|
1176
|
+
json(u8) { return JSON.parse( this.utf8(u8) || null ) },
|
|
1177
|
+
text(u8) { return this.utf8(u8) },
|
|
1178
|
+
};
|
|
1378
1179
|
|
|
1180
|
+
class MQTTCore extends MQTTBase {
|
|
1379
1181
|
constructor(opt={}) {
|
|
1380
1182
|
super(opt);
|
|
1381
|
-
this.
|
|
1382
|
-
this.with_reconnect(opt.on_reconnect);}
|
|
1383
|
-
|
|
1183
|
+
this.with(opt);}
|
|
1384
1184
|
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1185
|
+
static mqtt_ctx(mqtt_level, mqtt_opts, pkt_ctx=pkt_api) {
|
|
1186
|
+
let self = class extends this {};
|
|
1187
|
+
self.prototype.mqtt_ctx =
|
|
1188
|
+
mqtt_pkt_ctx(mqtt_level, mqtt_opts, pkt_ctx);
|
|
1189
|
+
return self}
|
|
1389
1190
|
|
|
1191
|
+
with(fns_ns) {
|
|
1192
|
+
for (let [k,v] of Object.entries(fns_ns)) {
|
|
1193
|
+
if ('function' === typeof v) {this[k] = v;} }
|
|
1390
1194
|
return this}
|
|
1391
1195
|
|
|
1392
|
-
//
|
|
1393
|
-
|
|
1394
|
-
if (on_reconnect) {
|
|
1395
|
-
this.on_reconnect = on_reconnect;
|
|
1196
|
+
//log_conn(evt, arg, err_arg) ::
|
|
1197
|
+
//console.info @ '[[u8-mqtt log: %s]]', evt, arg, err_arg
|
|
1396
1198
|
|
|
1397
|
-
|
|
1398
|
-
|
|
1199
|
+
on_live(client, is_reconnect) {
|
|
1200
|
+
if (is_reconnect) {
|
|
1201
|
+
return client.connect()} }
|
|
1399
1202
|
|
|
1400
|
-
|
|
1203
|
+
//on_reconnect(client) ::
|
|
1204
|
+
|
|
1205
|
+
_use_conn(fn_reconnect) {
|
|
1206
|
+
return (this.reconnect = fn_reconnect)?.()}
|
|
1207
|
+
with_autoreconnect(opt=2000) {
|
|
1208
|
+
if (opt.toFixed) {opt ={delay: opt};}
|
|
1209
|
+
return this.with({
|
|
1210
|
+
on_reconnect() {
|
|
1211
|
+
this.delay(opt.delay || 2000)
|
|
1212
|
+
.then(this.reconnect)
|
|
1213
|
+
.then(opt.reconnect, opt.error);} }) }
|
|
1401
1214
|
|
|
1215
|
+
on_disconnect(client, intentional) {
|
|
1216
|
+
if (! intentional) {
|
|
1217
|
+
return client.on_reconnect?.()} }
|
|
1218
|
+
|
|
1219
|
+
delay(ms) {
|
|
1220
|
+
return new Promise(done => setTimeout(done, ms)) }
|
|
1402
1221
|
|
|
1403
1222
|
with_async_iter(async_iter, write_u8_pkt) {
|
|
1404
1223
|
let on_mqtt_chunk = this._conn_.set(
|
|
1405
|
-
this.
|
|
1224
|
+
this.mqtt_ctx,
|
|
1406
1225
|
write_u8_pkt);
|
|
1407
1226
|
|
|
1408
1227
|
this._msg_loop = ((async () => {
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1228
|
+
try {
|
|
1229
|
+
async_iter = await async_iter;
|
|
1230
|
+
for await (let chunk of async_iter)
|
|
1231
|
+
on_mqtt_chunk(chunk);
|
|
1232
|
+
this._conn_.reset();}
|
|
1233
|
+
catch (err) {
|
|
1234
|
+
this._conn_.reset(err);} })());
|
|
1414
1235
|
|
|
1415
1236
|
return this}
|
|
1416
1237
|
|
|
@@ -1430,16 +1251,17 @@ class MQTTCoreClient extends MQTTBaseClient {
|
|
|
1430
1251
|
|
|
1431
1252
|
|
|
1432
1253
|
|
|
1254
|
+
|
|
1433
1255
|
|
|
1434
1256
|
with_tcp(port, hostname) {
|
|
1435
1257
|
if (!Number.isFinite(port)) {
|
|
1436
1258
|
({port, hostname} = new URL(port));}
|
|
1437
1259
|
|
|
1438
|
-
|
|
1439
|
-
|
|
1260
|
+
return this._use_conn (() =>
|
|
1261
|
+
this.with_stream(
|
|
1262
|
+
connect(port, hostname)) ) }
|
|
1440
1263
|
|
|
1441
1264
|
|
|
1442
|
-
|
|
1443
1265
|
with_stream(read_stream, write_stream) {
|
|
1444
1266
|
if (undefined === write_stream) {
|
|
1445
1267
|
write_stream = read_stream;}
|
|
@@ -1448,14 +1270,12 @@ class MQTTCoreClient extends MQTTBaseClient {
|
|
|
1448
1270
|
u8_pkt => write_stream.write(u8_pkt)) }
|
|
1449
1271
|
|
|
1450
1272
|
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
1273
|
with_websock(websock) {
|
|
1454
|
-
if (
|
|
1455
|
-
websock = 'ws://127.0.0.1:9001';
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1274
|
+
if (! websock?.send) {
|
|
1275
|
+
websock = new URL(websock || 'ws://127.0.0.1:9001');
|
|
1276
|
+
return this._use_conn (() =>
|
|
1277
|
+
this.with_websock(
|
|
1278
|
+
new WebSocket(websock, ['mqtt'])) ) }
|
|
1459
1279
|
|
|
1460
1280
|
websock.binaryType = 'arraybuffer';
|
|
1461
1281
|
|
|
@@ -1464,35 +1284,32 @@ class MQTTCoreClient extends MQTTBaseClient {
|
|
|
1464
1284
|
if (0 !== readyState) {
|
|
1465
1285
|
throw new Error('Invalid WebSocket readyState') }
|
|
1466
1286
|
|
|
1467
|
-
ready = new Promise(
|
|
1468
|
-
websock.addEventListener('open', y, {once: true}));}
|
|
1287
|
+
ready = new Promise(fn => websock.onopen = fn); }
|
|
1469
1288
|
|
|
1470
1289
|
|
|
1471
1290
|
let {_conn_} = this;
|
|
1472
1291
|
let on_mqtt_chunk = _conn_.set(
|
|
1473
|
-
this.
|
|
1292
|
+
this.mqtt_ctx,
|
|
1474
1293
|
async u8_pkt =>(
|
|
1475
1294
|
await ready
|
|
1476
1295
|
, websock.send(u8_pkt)) );
|
|
1477
1296
|
|
|
1478
|
-
websock.
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1297
|
+
websock.onmessage = evt =>(on_mqtt_chunk(new Uint8Array(evt.data)));
|
|
1298
|
+
websock.onclose = evt => {
|
|
1299
|
+
if (! evt.wasClean) {
|
|
1300
|
+
var err = new Error('websocket connection close');
|
|
1301
|
+
err.code = evt.code;
|
|
1302
|
+
err.reason = evt.reason;}
|
|
1482
1303
|
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
websock.onmessage = evt =>
|
|
1486
|
-
on_mqtt_chunk(
|
|
1487
|
-
new Uint8Array(evt.data));
|
|
1304
|
+
_conn_.reset(err);};
|
|
1488
1305
|
|
|
1489
1306
|
return this} }
|
|
1490
1307
|
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
}
|
|
1308
|
+
const MQTTClient_v4 = /* #__PURE__ */
|
|
1309
|
+
MQTTCore.mqtt_ctx(4, mqtt_opts_v4);
|
|
1494
1310
|
|
|
1495
|
-
const mqtt_v4 = opt =>
|
|
1311
|
+
const mqtt_v4 = opt =>
|
|
1312
|
+
new MQTTClient_v4(opt);
|
|
1496
1313
|
|
|
1497
1314
|
export { MQTTClient_v4 as MQTTClient, MQTTClient_v4, mqtt_v4 as default, mqtt_v4 as mqtt, mqtt_v4 };
|
|
1498
1315
|
//# sourceMappingURL=v4.js.map
|