aqualink 2.19.1 → 2.20.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.
@@ -150,7 +150,7 @@ class Rest {
150
150
  decodetracks: `${this._apiBase}/decodetracks`,
151
151
  stats: `${this._apiBase}/stats`,
152
152
  info: `${this._apiBase}/info`,
153
- version: `${this._apiBase}/version`,
153
+ version: `/version`,
154
154
  routeplanner: Object.freeze({
155
155
  status: `${this._apiBase}/routeplanner/status`,
156
156
  freeAddress: `${this._apiBase}/routeplanner/free/address`,
@@ -176,6 +176,7 @@ class Rest {
176
176
  this.useHttp2 = !!aqua?.options?.useHttp2
177
177
  this._h2 = null
178
178
  this._h2Timer = null
179
+ this.calls = 0
179
180
  }
180
181
 
181
182
  _setupAgent(node) {
@@ -256,6 +257,88 @@ class Rest {
256
257
  }
257
258
  }
258
259
 
260
+ _collectBody(stream, preallocSize = 0) {
261
+ return new Promise((resolve, reject) => {
262
+ let done = false
263
+ let size = 0
264
+ let prealloc =
265
+ preallocSize > 0 && preallocSize <= MAX_RESPONSE_SIZE
266
+ ? Buffer.allocUnsafe(preallocSize)
267
+ : null
268
+ let chunks = prealloc ? null : []
269
+
270
+ const finish = (ok, val) => {
271
+ if (done) return
272
+ done = true
273
+ prealloc = null
274
+ chunks = null
275
+ ok ? resolve(val) : reject(val)
276
+ }
277
+
278
+ stream.on('data', (chunk) => {
279
+ if (done) return
280
+ if (prealloc) {
281
+ if (size + chunk.length <= prealloc.length) {
282
+ chunk.copy(prealloc, size)
283
+ size += chunk.length
284
+ } else {
285
+ chunks = [prealloc.slice(0, size), chunk]
286
+ size += chunk.length
287
+ prealloc = null
288
+ }
289
+ } else {
290
+ size += chunk.length
291
+ chunks.push(chunk)
292
+ }
293
+ if (size > MAX_RESPONSE_SIZE) finish(false, ERRORS.RESPONSE_TOO_LARGE)
294
+ })
295
+
296
+ stream.once('error', (e) => finish(false, e))
297
+ stream.once('end', () => {
298
+ if (done) return
299
+ if (size === 0) return finish(true, null)
300
+ finish(
301
+ true,
302
+ prealloc
303
+ ? prealloc.slice(0, size)
304
+ : chunks.length === 1
305
+ ? chunks[0]
306
+ : Buffer.concat(chunks, size)
307
+ )
308
+ })
309
+ })
310
+ }
311
+
312
+ _parseResponseBuffer(
313
+ buffer,
314
+ status,
315
+ method,
316
+ url,
317
+ headers,
318
+ contentType,
319
+ statusMessage
320
+ ) {
321
+ if (!buffer) return null
322
+ if (buffer.length > MAX_RESPONSE_SIZE) throw ERRORS.RESPONSE_TOO_LARGE
323
+ let result
324
+ try {
325
+ result = _functions.parseBody(buffer, contentType, false)
326
+ } catch (e) {
327
+ throw new Error(`JSON parse error: ${e.message}`)
328
+ }
329
+ if (status >= 400) {
330
+ throw _functions.createHttpError(
331
+ status,
332
+ method,
333
+ url,
334
+ headers,
335
+ result,
336
+ statusMessage
337
+ )
338
+ }
339
+ return result
340
+ }
341
+
259
342
  async makeRequest(method, endpoint, body) {
260
343
  const url = `${this.baseUrl}${endpoint}`
261
344
  const payload =
@@ -266,6 +349,7 @@ class Rest {
266
349
  : JSON.stringify(body)
267
350
  const payloadLen = payload ? Buffer.byteLength(payload, UTF8) : 0
268
351
  const headers = this._buildHeaders(!!payload, payloadLen)
352
+ this.calls++
269
353
 
270
354
  try {
271
355
  const resp =
@@ -274,6 +358,7 @@ class Rest {
274
358
  : await this._h1Request(method, url, headers, payload)
275
359
  return resp
276
360
  } finally {
361
+ if (this.calls > 0) this.calls--
277
362
  this._returnHeaders(headers)
278
363
  }
279
364
  }
@@ -283,9 +368,6 @@ class Rest {
283
368
  let req,
284
369
  timer,
285
370
  done = false
286
- let chunks = null,
287
- size = 0,
288
- prealloc = null
289
371
 
290
372
  const finish = (ok, val) => {
291
373
  if (done) return
@@ -294,7 +376,6 @@ class Rest {
294
376
  clearTimeout(timer)
295
377
  timer = null
296
378
  }
297
- chunks = prealloc = null
298
379
  if (req && !ok) req.destroy()
299
380
  ok ? resolve(val) : reject(val)
300
381
  }
@@ -326,104 +407,63 @@ class Rest {
326
407
  const encoding = _functions.getEncodingType(
327
408
  res.headers['content-encoding']
328
409
  )
329
-
330
- const handleResponse = (buffer) => {
331
- if (buffer.length > MAX_RESPONSE_SIZE)
332
- return finish(false, ERRORS.RESPONSE_TOO_LARGE)
333
-
410
+ const finalize = (buffer) => {
334
411
  try {
335
- const result = _functions.parseBody(buffer, contentType, false)
336
- if (status >= 400) {
337
- finish(
338
- false,
339
- _functions.createHttpError(
340
- status,
341
- method,
342
- url,
343
- res.headers,
344
- result,
345
- res.statusMessage
346
- )
347
- )
348
- } else {
349
- finish(true, result)
350
- }
412
+ const result = this._parseResponseBuffer(
413
+ buffer,
414
+ status,
415
+ method,
416
+ url,
417
+ res.headers,
418
+ contentType,
419
+ res.statusMessage
420
+ )
421
+ finish(true, result)
351
422
  } catch (e) {
352
- finish(false, new Error(`JSON parse error: ${e.message}`))
423
+ finish(false, e)
353
424
  }
354
425
  }
355
426
 
427
+ res.once('aborted', () => finish(false, ERRORS.RESPONSE_ABORTED))
428
+ res.once('error', (e) => finish(false, e))
429
+
356
430
  if (
357
431
  encoding !== ENCODING_NONE &&
358
432
  clInt > 0 &&
359
433
  clInt < COMPRESSION_MIN_SIZE
360
434
  ) {
361
- const compressed = []
362
- let csize = 0
363
-
364
- res.on('data', (c) => {
365
- csize += c.length
366
- if (csize > MAX_RESPONSE_SIZE)
367
- return finish(false, ERRORS.RESPONSE_TOO_LARGE)
368
- compressed.push(c)
369
- })
370
- res.once('end', () => {
371
- try {
372
- handleResponse(
373
- _functions.decompressSync(Buffer.concat(compressed), encoding)
435
+ this._collectBody(res)
436
+ .then((compressed) => {
437
+ if (!compressed) return finish(true, null)
438
+ const decompressed = _functions.decompressSync(
439
+ compressed,
440
+ encoding
374
441
  )
375
- } catch (e) {
442
+ finalize(decompressed)
443
+ })
444
+ .catch((e) => {
376
445
  finish(false, e)
377
- }
378
- })
379
- res.once('aborted', () => finish(false, ERRORS.RESPONSE_ABORTED))
380
- res.once('error', (e) => finish(false, e))
446
+ })
381
447
  return
382
448
  }
383
449
 
384
- if (
385
- encoding === ENCODING_NONE &&
386
- clInt > 0 &&
387
- clInt <= MAX_RESPONSE_SIZE
388
- ) {
389
- prealloc = Buffer.allocUnsafe(clInt)
390
- } else {
391
- chunks = []
392
- }
393
-
394
450
  let stream = res
451
+ let preallocSize = 0
395
452
  if (encoding !== ENCODING_NONE) {
396
453
  const decomp = _functions.createDecompressor(encoding)
397
454
  decomp.once('error', (e) => finish(false, e))
398
455
  res.pipe(decomp)
399
456
  stream = decomp
457
+ } else if (clInt > 0 && clInt <= MAX_RESPONSE_SIZE) {
458
+ preallocSize = clInt
400
459
  }
401
460
 
402
- res.once('aborted', () => finish(false, ERRORS.RESPONSE_ABORTED))
403
- res.once('error', (e) => finish(false, e))
404
-
405
- stream.on('data', (chunk) => {
406
- if (prealloc) {
407
- chunk.copy(prealloc, size)
408
- size += chunk.length
409
- } else {
410
- size += chunk.length
411
- if (size > MAX_RESPONSE_SIZE)
412
- return finish(false, ERRORS.RESPONSE_TOO_LARGE)
413
- chunks.push(chunk)
414
- }
415
- })
416
-
417
- stream.once('end', () => {
418
- if (size === 0) return finish(true, null)
419
- handleResponse(
420
- prealloc
421
- ? prealloc.slice(0, size)
422
- : chunks.length === 1
423
- ? chunks[0]
424
- : Buffer.concat(chunks, size)
425
- )
426
- })
461
+ this._collectBody(stream, preallocSize)
462
+ .then((buffer) => {
463
+ if (!buffer) return finish(true, null)
464
+ finalize(buffer)
465
+ })
466
+ .catch((e) => finish(false, e))
427
467
  }
428
468
  )
429
469
 
@@ -490,9 +530,6 @@ class Rest {
490
530
  let req,
491
531
  timer,
492
532
  done = false
493
- let chunks = null,
494
- size = 0,
495
- prealloc = null
496
533
 
497
534
  const finish = (ok, val) => {
498
535
  if (done) return
@@ -501,7 +538,6 @@ class Rest {
501
538
  clearTimeout(timer)
502
539
  timer = null
503
540
  }
504
- chunks = prealloc = null
505
541
  if (req && !ok) req.close(http2.constants.NGHTTP2_CANCEL)
506
542
  ok ? resolve(val) : reject(val)
507
543
  }
@@ -543,15 +579,20 @@ class Rest {
543
579
  }
544
580
 
545
581
  const encoding = _functions.getEncodingType(rh['content-encoding'])
546
-
547
- if (
548
- encoding === ENCODING_NONE &&
549
- clInt > 0 &&
550
- clInt <= MAX_RESPONSE_SIZE
551
- ) {
552
- prealloc = Buffer.allocUnsafe(clInt)
553
- } else {
554
- chunks = []
582
+ const finalize = (buffer) => {
583
+ try {
584
+ const result = this._parseResponseBuffer(
585
+ buffer,
586
+ status,
587
+ method,
588
+ this.baseUrl + path,
589
+ rh,
590
+ contentType
591
+ )
592
+ finish(true, result)
593
+ } catch (e) {
594
+ finish(false, e)
595
+ }
555
596
  }
556
597
 
557
598
  const decomp =
@@ -559,51 +600,19 @@ class Rest {
559
600
  ? _functions.createDecompressor(encoding)
560
601
  : null
561
602
  const stream = decomp ? req.pipe(decomp) : req
603
+ const preallocSize =
604
+ encoding === ENCODING_NONE && clInt > 0 && clInt <= MAX_RESPONSE_SIZE
605
+ ? clInt
606
+ : 0
562
607
 
563
608
  if (decomp) decomp.once('error', (e) => finish(false, e))
564
609
  req.once('error', (e) => finish(false, e))
565
-
566
- stream.on('data', (chunk) => {
567
- if (prealloc) {
568
- chunk.copy(prealloc, size)
569
- size += chunk.length
570
- } else {
571
- size += chunk.length
572
- if (size > MAX_RESPONSE_SIZE)
573
- return finish(false, ERRORS.RESPONSE_TOO_LARGE)
574
- chunks.push(chunk)
575
- }
576
- })
577
-
578
- stream.once('end', () => {
579
- if (size === 0) return finish(true, null)
580
-
581
- const buffer = prealloc
582
- ? prealloc.slice(0, size)
583
- : chunks.length === 1
584
- ? chunks[0]
585
- : Buffer.concat(chunks, size)
586
-
587
- try {
588
- const result = _functions.parseBody(buffer, contentType, false)
589
- if (status >= 400) {
590
- finish(
591
- false,
592
- _functions.createHttpError(
593
- status,
594
- method,
595
- this.baseUrl + path,
596
- rh,
597
- result
598
- )
599
- )
600
- } else {
601
- finish(true, result)
602
- }
603
- } catch (e) {
604
- finish(false, new Error(`JSON parse error: ${e.message}`))
605
- }
606
- })
610
+ this._collectBody(stream, preallocSize)
611
+ .then((buffer) => {
612
+ if (!buffer) return finish(true, null)
613
+ finalize(buffer)
614
+ })
615
+ .catch((e) => finish(false, e))
607
616
  })
608
617
 
609
618
  timer = setTimeout(
@@ -851,7 +860,8 @@ class Rest {
851
860
  this.defaultHeaders =
852
861
  this._endpoints =
853
862
  null
863
+ this.calls = 0
854
864
  }
855
865
  }
856
866
 
857
- module.exports = Rest
867
+ module.exports = Rest
@@ -28,7 +28,7 @@ class Track {
28
28
  this.nodes = data.nodes || null
29
29
  this.requester = requester || null
30
30
  this._infoCache = null
31
- this._artworkCache = undefined // undefined = not computed, null = computed but no artwork
31
+ this._artworkCache = undefined // undefined = not computed, null = computed but no artwork
32
32
  }
33
33
 
34
34
  get info() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aqualink",
3
- "version": "2.19.1",
3
+ "version": "2.20.0",
4
4
  "description": "An Lavalink/Nodelink client, focused in pure performance and features",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",
@@ -45,8 +45,7 @@
45
45
  },
46
46
  "homepage": "https://aqualink-6006388d.mintlify.app/",
47
47
  "dependencies": {
48
- "ws": "^8.19.0",
49
- "tseep": "^1.3.1"
48
+ "ws": "^8.19.0"
50
49
  },
51
50
  "contributors": [
52
51
  {
@@ -68,4 +67,4 @@
68
67
  "url": "https://github.com/ToddyTheNoobDud"
69
68
  }
70
69
  ]
71
- }
70
+ }