@sapphire/async-queue 1.6.0-pr-589.aa473f9.0 → 1.6.0-pr-935.7da5c8bb

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/CHANGELOG.md CHANGED
@@ -2,6 +2,69 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ # [@sapphire/async-queue@1.5.4](https://github.com/sapphiredev/utilities/compare/@sapphire/async-queue@1.5.3...@sapphire/async-queue@1.5.4) - (2024-11-02)
6
+
7
+ ## 🏠 Refactor
8
+
9
+ - Resolve several sonar issues ([ba915f9](https://github.com/sapphiredev/utilities/commit/ba915f93ce0907828ba17b2d5ae009631ceb860d)) ([#823](https://github.com/sapphiredev/utilities/pull/823) by @favna)
10
+
11
+ ## 🐛 Bug Fixes
12
+
13
+ - Move browser imports ([100ffb0](https://github.com/sapphiredev/utilities/commit/100ffb0a2471bb9f74cc580d282d11059e1a0a68)) ([#826](https://github.com/sapphiredev/utilities/pull/826) by @kyranet)
14
+
15
+ # [@sapphire/async-queue@1.5.3](https://github.com/sapphiredev/utilities/compare/@sapphire/async-queue@1.5.2...@sapphire/async-queue@1.5.3) - (2024-07-23)
16
+
17
+ ## 🐛 Bug Fixes
18
+
19
+ - **deps:** Update all non-major dependencies ([083376a](https://github.com/sapphiredev/utilities/commit/083376aac55094dbeddb5194e8a8f0d794b8cceb)) ([#763](https://github.com/sapphiredev/utilities/pull/763) by @renovate[bot])
20
+ - **deps:** Update all non-major dependencies ([e7fdc5d](https://github.com/sapphiredev/utilities/commit/e7fdc5db3632a7f90292ef3978898da32730343a)) ([#752](https://github.com/sapphiredev/utilities/pull/752) by @renovate[bot])
21
+
22
+ ## 📝 Documentation
23
+
24
+ - Add usage example in README ([3815167](https://github.com/sapphiredev/utilities/commit/38151673cac048ccccf4fb00c3c9cc98bbb3c452)) ([#777](https://github.com/sapphiredev/utilities/pull/777) by @kyranet)
25
+
26
+ # [@sapphire/async-queue@1.5.2](https://github.com/sapphiredev/utilities/compare/@sapphire/async-queue@1.5.2...@sapphire/async-queue@1.5.2) - (2024-01-19)
27
+
28
+ ## 🐛 Bug Fixes
29
+
30
+ - Fixed commonjs typings export mapping (#707) ([216ff02](https://github.com/sapphiredev/utilities/commit/216ff0260d63a9590357f9a5069f1ae2b34eaf5d))
31
+
32
+ # [@sapphire/async-queue@1.5.1](https://github.com/sapphiredev/utilities/compare/@sapphire/async-queue@1.5.1...@sapphire/async-queue@1.5.1) - (2023-12-04)
33
+
34
+ ## 🏠 Refactor
35
+
36
+ - Split `@sapphire/time-utilities` into 4 sub-packages (#462) ([574299a](https://github.com/sapphiredev/utilities/commit/574299a99e658f6500a2a7efa587a0919b2d1313))
37
+
38
+ ## 🐛 Bug Fixes
39
+
40
+ - **async-queue:** Properly split CJS, ESM and IIFE ([75f215c](https://github.com/sapphiredev/utilities/commit/75f215cd8b42b3c57a92f2fe01dff59b7edb02d6))
41
+ - Update export mapping for proper ESM/CJS split ([dd0cff8](https://github.com/sapphiredev/utilities/commit/dd0cff8e9b03a15812f25f7a1180501a92422629))
42
+ - **deps:** Update all non-major dependencies (#607) ([9cc8bd0](https://github.com/sapphiredev/utilities/commit/9cc8bd0d4b5d650deab2c913e6c3d713861bae28))
43
+ - **deps:** Update all non-major dependencies (#577) ([291dd67](https://github.com/sapphiredev/utilities/commit/291dd6783e57d8f075ce566218ba076ef6c4bbbd))
44
+ - **deps:** Update all non-major dependencies (#545) ([40ca040](https://github.com/sapphiredev/utilities/commit/40ca040a21d8a0949682051a3a974538183a400e))
45
+ - **deps:** Update all non-major dependencies (#544) ([cc78f17](https://github.com/sapphiredev/utilities/commit/cc78f17390c7f3db08af92bf46a5a70a9c11dd5f))
46
+ - **deps:** Update all non-major dependencies (#532) ([8033d1f](https://github.com/sapphiredev/utilities/commit/8033d1ff7a5a1974134c61f424f171cccb2915e1))
47
+ - **deps:** Update all non-major dependencies (#514) ([21b07d5](https://github.com/sapphiredev/utilities/commit/21b07d5db529a0d982647a60de98e46f36f1ac93))
48
+ - **deps:** Update all non-major dependencies (#505) ([6178296](https://github.com/sapphiredev/utilities/commit/617829649e1e4deeee02b14533b5377cd5bc1fb3))
49
+ - **deps:** Update all non-major dependencies (#466) ([dc08606](https://github.com/sapphiredev/utilities/commit/dc08606a97154e47c65536123ac5f8b1262f7bd2))
50
+ - **deps:** Update all non-major dependencies ([e20f299](https://github.com/sapphiredev/utilities/commit/e20f29906e83cee000aaba9c6827e3bec5173d28))
51
+
52
+ ## 📝 Documentation
53
+
54
+ - Add @06000208 as a contributor ([fa3349e](https://github.com/sapphiredev/utilities/commit/fa3349e55ce4ad008785211dec7bf8e2b5d933df))
55
+ - Add @didinele as a contributor ([42ef7b6](https://github.com/sapphiredev/utilities/commit/42ef7b656c48fd0e720119db1d622c8bba2791e9))
56
+ - Add @goestav as a contributor ([0e56a92](https://github.com/sapphiredev/utilities/commit/0e56a92a4e2d0942bfa207f81a8cb03b32312034))
57
+ - Add @CitTheDev as a contributor ([34169ea](https://github.com/sapphiredev/utilities/commit/34169eae1dc0476ccf5a6c4f36e28602a204829e))
58
+ - Add @legendhimslef as a contributor ([059b6f1](https://github.com/sapphiredev/utilities/commit/059b6f1ab5362d46d58624d06c1aa39192b0716f))
59
+ - Add @r-priyam as a contributor ([fb278ba](https://github.com/sapphiredev/utilities/commit/fb278bacf627ec6fc88752eafeb12df5f3177a2c))
60
+ - Change name of @kyranet (#451) ([df4fdef](https://github.com/sapphiredev/utilities/commit/df4fdefce18659975a4ebc224723638507d02d35))
61
+ - Update @RealShadowNova as a contributor ([a869ba0](https://github.com/sapphiredev/utilities/commit/a869ba0abfad041610b9115187d426aebe671af6))
62
+
63
+ ## 🧪 Testing
64
+
65
+ - Update vitest to coverage v8 ([a4bc6e4](https://github.com/sapphiredev/utilities/commit/a4bc6e4f24ea60143a150ecc76fda6484f172ab9))
66
+ - Cleanup tests ([aec1bb2](https://github.com/sapphiredev/utilities/commit/aec1bb290d0f3c00a1ae4f4c86302ebbb161d348))
67
+
5
68
  # [@sapphire/async-queue@1.5.0](https://github.com/sapphiredev/utilities/compare/@sapphire/async-queue@1.4.0...@sapphire/async-queue@1.5.0) - (2022-08-16)
6
69
 
7
70
  ## 🐛 Bug Fixes
package/README.md CHANGED
@@ -7,21 +7,24 @@
7
7
  **Sequential asynchronous lock-based queue for promises.**
8
8
 
9
9
  [![GitHub](https://img.shields.io/github/license/sapphiredev/utilities)](https://github.com/sapphiredev/utilities/blob/main/LICENSE.md)
10
- [![codecov](https://codecov.io/gh/sapphiredev/utilities/branch/main/graph/badge.svg?token=OEGIV6RFDO)](https://codecov.io/gh/sapphiredev/utilities)
11
10
  [![npm bundle size](https://img.shields.io/bundlephobia/min/@sapphire/async-queue?logo=webpack&style=flat-square)](https://bundlephobia.com/result?p=@sapphire/async-queue)
12
11
  [![npm](https://img.shields.io/npm/v/@sapphire/async-queue?color=crimson&logo=npm&style=flat-square)](https://www.npmjs.com/package/@sapphire/async-queue)
13
12
 
14
13
  </div>
15
14
 
16
- ## Description
15
+ **Table of Contents**
17
16
 
18
- Ever needed a queue for a set of promises? This is the package for you.
17
+ - [Features](#features)
18
+ - [Installation](#installation)
19
+ - [Usage](#usage)
20
+ - [Buy us some doughnuts](#buy-us-some-doughnuts)
21
+ - [Contributors](#contributors)
19
22
 
20
23
  ## Features
21
24
 
22
25
  - Written in TypeScript
23
26
  - Bundled with esbuild so it can be used in NodeJS and browsers
24
- - Offers CommonJS, ESM and UMD bundles
27
+ - Offers CommonJS, ESM, and UMD bundles
25
28
  - Fully tested
26
29
 
27
30
  ## Installation
@@ -32,13 +35,46 @@ You can use the following command to install this package, or replace `npm insta
32
35
  npm install @sapphire/async-queue
33
36
  ```
34
37
 
38
+ ## Usage
39
+
40
+ **Note**: While this section uses `require`, the imports match 1:1 with ESM imports. For example `const { AsyncQueue } = require('@sapphire/async-queue')` equals `import { AsyncQueue } from '@sapphire/async-queue'`.
41
+
42
+ ```typescript
43
+ // Require the AsyncQueue class
44
+ const { AsyncQueue } = require('@sapphire/async-queue');
45
+
46
+ const queue = new AsyncQueue();
47
+
48
+ async function request(url, options) {
49
+ // Wait and lock the queue
50
+ await queue.wait();
51
+
52
+ try {
53
+ // Perform the operation sequentially
54
+ return await fetch(url, options);
55
+ } finally {
56
+ // Unlock the next promise in the queue
57
+ queue.shift();
58
+ }
59
+ }
60
+
61
+ request(someUrl1, someOptions1);
62
+ // Will call fetch() immediately
63
+
64
+ request(someUrl2, someOptions2);
65
+ // Will call fetch() after the first finished
66
+
67
+ request(someUrl3, someOptions3);
68
+ // Will call fetch() after the second finished
69
+ ```
70
+
35
71
  ---
36
72
 
37
73
  ## Buy us some doughnuts
38
74
 
39
75
  Sapphire Community is and always will be open source, even if we don't get donations. That being said, we know there are amazing people who may still want to donate just to show their appreciation. Thank you very much in advance!
40
76
 
41
- We accept donations through Open Collective, Ko-fi, PayPal, Patreon and GitHub Sponsorships. You can use the buttons below to donate through your method of choice.
77
+ We accept donations through Open Collective, Ko-fi, PayPal, Patreon, and GitHub Sponsorships. You can use the buttons below to donate through your method of choice.
42
78
 
43
79
  | Donate With | Address |
44
80
  | :-------------: | :-------------------------------------------------: |
@@ -3,13 +3,10 @@
3
3
  var __defProp = Object.defineProperty;
4
4
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
5
5
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
6
- var __publicField = (obj, key, value) => {
7
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
8
- return value;
9
- };
6
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
10
7
 
11
- // src/lib/AsyncQueueEntry.ts
12
- var AsyncQueueEntry = class {
8
+ // src/lib/_AsyncQueueEntry.ts
9
+ var _AsyncQueueEntry = class _AsyncQueueEntry {
13
10
  constructor(queue) {
14
11
  __publicField(this, "promise");
15
12
  __publicField(this, "resolve");
@@ -24,13 +21,11 @@ var AsyncQueueEntry = class {
24
21
  });
25
22
  }
26
23
  setSignal(signal) {
27
- if (signal.aborted)
28
- return this;
24
+ if (signal.aborted) return this;
29
25
  this.signal = signal;
30
26
  this.signalListener = () => {
31
27
  const index = this.queue["promises"].indexOf(this);
32
- if (index !== -1)
33
- this.queue["promises"].splice(index, 1);
28
+ if (index !== -1) this.queue["promises"].splice(index, 1);
34
29
  this.reject(new Error("Request aborted manually"));
35
30
  };
36
31
  this.signal.addEventListener("abort", this.signalListener);
@@ -54,10 +49,11 @@ var AsyncQueueEntry = class {
54
49
  }
55
50
  }
56
51
  };
57
- __name(AsyncQueueEntry, "AsyncQueueEntry");
52
+ __name(_AsyncQueueEntry, "AsyncQueueEntry");
53
+ var AsyncQueueEntry = _AsyncQueueEntry;
58
54
 
59
55
  // src/lib/AsyncQueue.ts
60
- var AsyncQueue = class {
56
+ var _AsyncQueue = class _AsyncQueue {
61
57
  constructor() {
62
58
  /**
63
59
  * The promises array
@@ -106,16 +102,14 @@ var AsyncQueue = class {
106
102
  return Promise.resolve();
107
103
  }
108
104
  this.promises.push(entry);
109
- if (options?.signal)
110
- entry.setSignal(options.signal);
105
+ if (options?.signal) entry.setSignal(options.signal);
111
106
  return entry.promise;
112
107
  }
113
108
  /**
114
109
  * Unlocks the head lock and transfers the next lock (if any) to the head.
115
110
  */
116
111
  shift() {
117
- if (this.promises.length === 0)
118
- return;
112
+ if (this.promises.length === 0) return;
119
113
  if (this.promises.length === 1) {
120
114
  this.promises.shift();
121
115
  return;
@@ -128,16 +122,16 @@ var AsyncQueue = class {
128
122
  * @note To avoid race conditions, this does **not** unlock the head lock.
129
123
  */
130
124
  abortAll() {
131
- if (this.queued === 0)
132
- return;
125
+ if (this.queued === 0) return;
133
126
  for (let i = 1; i < this.promises.length; ++i) {
134
127
  this.promises[i].abort();
135
128
  }
136
129
  this.promises.length = 1;
137
130
  }
138
131
  };
139
- __name(AsyncQueue, "AsyncQueue");
132
+ __name(_AsyncQueue, "AsyncQueue");
133
+ var AsyncQueue = _AsyncQueue;
140
134
 
141
135
  exports.AsyncQueue = AsyncQueue;
142
- //# sourceMappingURL=out.js.map
143
- //# sourceMappingURL=index.js.map
136
+ //# sourceMappingURL=index.cjs.map
137
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lib/_AsyncQueueEntry.ts","../../src/lib/AsyncQueue.ts"],"names":[],"mappings":";;;;;;;;AAKO,IAAM,gBAAA,GAAN,MAAM,gBAAA,CAAgB;AAAA,EAQrB,YAAY,KAAA,EAAmB;AAPtC,IAAA,aAAA,CAAA,IAAA,EAAgB,SAAA,CAAA;AAChB,IAAA,aAAA,CAAA,IAAA,EAAQ,SAAA,CAAA;AACR,IAAA,aAAA,CAAA,IAAA,EAAQ,QAAA,CAAA;AACR,IAAA,aAAA,CAAA,IAAA,EAAiB,OAAA,CAAA;AACjB,IAAA,aAAA,CAAA,IAAA,EAAQ,QAAA,EAAqC,IAAA,CAAA;AAC7C,IAAA,aAAA,CAAA,IAAA,EAAQ,gBAAA,EAAsC,IAAA,CAAA;AAG7C,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AACb,IAAA,IAAA,CAAK,OAAA,GAAU,IAAI,OAAA,CAAQ,CAAC,SAAS,MAAA,KAAW;AAC/C,MAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AACf,MAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,IACf,CAAC,CAAA;AAAA,EACF;AAAA,EAEO,UAAU,MAAA,EAAqB;AACrC,IAAA,IAAI,MAAA,CAAO,SAAS,OAAO,IAAA;AAE3B,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,iBAAiB,MAAM;AAC3B,MAAA,MAAM,QAAQ,IAAA,CAAK,KAAA,CAAM,UAAU,CAAA,CAAE,QAAQ,IAAI,CAAA;AACjD,MAAA,IAAI,KAAA,KAAU,IAAI,IAAA,CAAK,KAAA,CAAM,UAAU,CAAA,CAAE,MAAA,CAAO,OAAO,CAAC,CAAA;AAExD,MAAA,IAAA,CAAK,MAAA,CAAO,IAAI,KAAA,CAAM,0BAA0B,CAAC,CAAA;AAAA,IAClD,CAAA;AACA,IAAA,IAAA,CAAK,MAAA,CAAO,gBAAA,CAAiB,OAAA,EAAS,IAAA,CAAK,cAAc,CAAA;AACzD,IAAA,OAAO,IAAA;AAAA,EACR;AAAA,EAEO,GAAA,GAAM;AACZ,IAAA,IAAA,CAAK,OAAA,EAAQ;AACb,IAAA,IAAA,CAAK,OAAA,EAAQ;AACb,IAAA,OAAO,IAAA;AAAA,EACR;AAAA,EAEO,KAAA,GAAQ;AACd,IAAA,IAAA,CAAK,OAAA,EAAQ;AACb,IAAA,IAAA,CAAK,MAAA,CAAO,IAAI,KAAA,CAAM,0BAA0B,CAAC,CAAA;AACjD,IAAA,OAAO,IAAA;AAAA,EACR;AAAA,EAEQ,OAAA,GAAU;AACjB,IAAA,IAAI,KAAK,MAAA,EAAQ;AAChB,MAAA,IAAA,CAAK,MAAA,CAAO,mBAAA,CAAoB,OAAA,EAAS,IAAA,CAAK,cAAe,CAAA;AAC7D,MAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AACd,MAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AAAA,IACvB;AAAA,EACD;AACD,CAAA;AAjD6B,MAAA,CAAA,gBAAA,EAAA,iBAAA,CAAA;AAAtB,IAAM,eAAA,GAAN,gBAAA;;;ACAA,IAAM,WAAA,GAAN,MAAM,WAAA,CAAW;AAAA,EAAjB,WAAA,GAAA;AAoBN;AAAA;AAAA;AAAA,IAAA,aAAA,CAAA,IAAA,EAAiB,YAA8B,EAAC,CAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAfhD,IAAW,SAAA,GAAoB;AAC9B,IAAA,OAAO,KAAK,QAAA,CAAS,MAAA;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAW,MAAA,GAAiB;AAC3B,IAAA,OAAO,IAAA,CAAK,SAAA,KAAc,CAAA,GAAI,CAAA,GAAI,KAAK,SAAA,GAAY,CAAA;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA4BO,KAAK,OAAA,EAA0D;AACrE,IAAA,MAAM,KAAA,GAAQ,IAAI,eAAA,CAAgB,IAAI,CAAA;AAEtC,IAAA,IAAI,IAAA,CAAK,QAAA,CAAS,MAAA,KAAW,CAAA,EAAG;AAC/B,MAAA,IAAA,CAAK,QAAA,CAAS,KAAK,KAAK,CAAA;AACxB,MAAA,OAAO,QAAQ,OAAA,EAAQ;AAAA,IACxB;AAEA,IAAA,IAAA,CAAK,QAAA,CAAS,KAAK,KAAK,CAAA;AACxB,IAAA,IAAI,OAAA,EAAS,MAAA,EAAQ,KAAA,CAAM,SAAA,CAAU,QAAQ,MAAM,CAAA;AACnD,IAAA,OAAO,KAAA,CAAM,OAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKO,KAAA,GAAc;AACpB,IAAA,IAAI,IAAA,CAAK,QAAA,CAAS,MAAA,KAAW,CAAA,EAAG;AAChC,IAAA,IAAI,IAAA,CAAK,QAAA,CAAS,MAAA,KAAW,CAAA,EAAG;AAE/B,MAAA,IAAA,CAAK,SAAS,KAAA,EAAM;AACpB,MAAA;AAAA,IACD;AAIA,IAAA,IAAA,CAAK,SAAS,KAAA,EAAM;AACpB,IAAA,IAAA,CAAK,QAAA,CAAS,CAAC,CAAA,CAAE,GAAA,EAAI;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,QAAA,GAAiB;AAEvB,IAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AAIvB,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,KAAK,QAAA,CAAS,MAAA,EAAQ,EAAE,CAAA,EAAG;AAC9C,MAAA,IAAA,CAAK,QAAA,CAAS,CAAC,CAAA,CAAE,KAAA,EAAM;AAAA,IACxB;AAEA,IAAA,IAAA,CAAK,SAAS,MAAA,GAAS,CAAA;AAAA,EACxB;AACD,CAAA;AAzFwB,MAAA,CAAA,WAAA,EAAA,YAAA,CAAA;AAAjB,IAAM,UAAA,GAAN","file":"index.cjs","sourcesContent":["import type { AsyncQueue } from './AsyncQueue';\n\n/**\n * @internal\n */\nexport class AsyncQueueEntry {\n\tpublic readonly promise: Promise<void>;\n\tprivate resolve!: () => void;\n\tprivate reject!: (error: Error) => void;\n\tprivate readonly queue: AsyncQueue;\n\tprivate signal: PolyFillAbortSignal | null = null;\n\tprivate signalListener: (() => void) | null = null;\n\n\tpublic constructor(queue: AsyncQueue) {\n\t\tthis.queue = queue;\n\t\tthis.promise = new Promise((resolve, reject) => {\n\t\t\tthis.resolve = resolve;\n\t\t\tthis.reject = reject;\n\t\t});\n\t}\n\n\tpublic setSignal(signal: AbortSignal) {\n\t\tif (signal.aborted) return this;\n\n\t\tthis.signal = signal as PolyFillAbortSignal;\n\t\tthis.signalListener = () => {\n\t\t\tconst index = this.queue['promises'].indexOf(this);\n\t\t\tif (index !== -1) this.queue['promises'].splice(index, 1);\n\n\t\t\tthis.reject(new Error('Request aborted manually'));\n\t\t};\n\t\tthis.signal.addEventListener('abort', this.signalListener);\n\t\treturn this;\n\t}\n\n\tpublic use() {\n\t\tthis.dispose();\n\t\tthis.resolve();\n\t\treturn this;\n\t}\n\n\tpublic abort() {\n\t\tthis.dispose();\n\t\tthis.reject(new Error('Request aborted manually'));\n\t\treturn this;\n\t}\n\n\tprivate dispose() {\n\t\tif (this.signal) {\n\t\t\tthis.signal.removeEventListener('abort', this.signalListener!);\n\t\t\tthis.signal = null;\n\t\t\tthis.signalListener = null;\n\t\t}\n\t}\n}\n\ninterface PolyFillAbortSignal {\n\treadonly aborted: boolean;\n\taddEventListener(type: 'abort', listener: () => void): void;\n\tremoveEventListener(type: 'abort', listener: () => void): void;\n}\n","import { AsyncQueueEntry } from './_AsyncQueueEntry';\n\n/**\n * The AsyncQueue class used to sequentialize burst requests\n */\nexport class AsyncQueue {\n\t/**\n\t * The amount of entries in the queue, including the head.\n\t * @seealso {@link queued} for the queued count.\n\t */\n\tpublic get remaining(): number {\n\t\treturn this.promises.length;\n\t}\n\n\t/**\n\t * The amount of queued entries.\n\t * @seealso {@link remaining} for the count with the head.\n\t */\n\tpublic get queued(): number {\n\t\treturn this.remaining === 0 ? 0 : this.remaining - 1;\n\t}\n\n\t/**\n\t * The promises array\n\t */\n\tprivate readonly promises: AsyncQueueEntry[] = [];\n\n\t/**\n\t * Waits for last promise and queues a new one\n\t * @example\n\t * ```typescript\n\t * const queue = new AsyncQueue();\n\t * async function request(url, options) {\n\t * await queue.wait({ signal: options.signal });\n\t * try {\n\t * const result = await fetch(url, options);\n\t * // Do some operations with 'result'\n\t * } finally {\n\t * // Remove first entry from the queue and resolve for the next entry\n\t * queue.shift();\n\t * }\n\t * }\n\t *\n\t * request(someUrl1, someOptions1); // Will call fetch() immediately\n\t * request(someUrl2, someOptions2); // Will call fetch() after the first finished\n\t * request(someUrl3, someOptions3); // Will call fetch() after the second finished\n\t * ```\n\t */\n\tpublic wait(options?: Readonly<AsyncQueueWaitOptions>): Promise<void> {\n\t\tconst entry = new AsyncQueueEntry(this);\n\n\t\tif (this.promises.length === 0) {\n\t\t\tthis.promises.push(entry);\n\t\t\treturn Promise.resolve();\n\t\t}\n\n\t\tthis.promises.push(entry);\n\t\tif (options?.signal) entry.setSignal(options.signal);\n\t\treturn entry.promise;\n\t}\n\n\t/**\n\t * Unlocks the head lock and transfers the next lock (if any) to the head.\n\t */\n\tpublic shift(): void {\n\t\tif (this.promises.length === 0) return;\n\t\tif (this.promises.length === 1) {\n\t\t\t// Remove the head entry.\n\t\t\tthis.promises.shift();\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove the head entry, making the 2nd entry the new one.\n\t\t// Then use the head entry, which will unlock the promise.\n\t\tthis.promises.shift();\n\t\tthis.promises[0].use();\n\t}\n\n\t/**\n\t * Aborts all the pending promises.\n\t * @note To avoid race conditions, this does **not** unlock the head lock.\n\t */\n\tpublic abortAll(): void {\n\t\t// If there are no queued entries, skip early.\n\t\tif (this.queued === 0) return;\n\n\t\t// Abort all the entries except the head, that is why the loop starts at\n\t\t// 1 and not at 0.\n\t\tfor (let i = 1; i < this.promises.length; ++i) {\n\t\t\tthis.promises[i].abort();\n\t\t}\n\n\t\tthis.promises.length = 1;\n\t}\n}\n\nexport interface AsyncQueueWaitOptions {\n\tsignal?: AbortSignal | undefined | null;\n}\n"]}
@@ -15,7 +15,7 @@ declare class AsyncQueue {
15
15
  /**
16
16
  * The promises array
17
17
  */
18
- private promises;
18
+ private readonly promises;
19
19
  /**
20
20
  * Waits for last promise and queues a new one
21
21
  * @example
@@ -52,4 +52,4 @@ interface AsyncQueueWaitOptions {
52
52
  signal?: AbortSignal | undefined | null;
53
53
  }
54
54
 
55
- export { AsyncQueue, AsyncQueueWaitOptions };
55
+ export { AsyncQueue, type AsyncQueueWaitOptions };
@@ -0,0 +1,55 @@
1
+ /**
2
+ * The AsyncQueue class used to sequentialize burst requests
3
+ */
4
+ declare class AsyncQueue {
5
+ /**
6
+ * The amount of entries in the queue, including the head.
7
+ * @seealso {@link queued} for the queued count.
8
+ */
9
+ get remaining(): number;
10
+ /**
11
+ * The amount of queued entries.
12
+ * @seealso {@link remaining} for the count with the head.
13
+ */
14
+ get queued(): number;
15
+ /**
16
+ * The promises array
17
+ */
18
+ private readonly promises;
19
+ /**
20
+ * Waits for last promise and queues a new one
21
+ * @example
22
+ * ```typescript
23
+ * const queue = new AsyncQueue();
24
+ * async function request(url, options) {
25
+ * await queue.wait({ signal: options.signal });
26
+ * try {
27
+ * const result = await fetch(url, options);
28
+ * // Do some operations with 'result'
29
+ * } finally {
30
+ * // Remove first entry from the queue and resolve for the next entry
31
+ * queue.shift();
32
+ * }
33
+ * }
34
+ *
35
+ * request(someUrl1, someOptions1); // Will call fetch() immediately
36
+ * request(someUrl2, someOptions2); // Will call fetch() after the first finished
37
+ * request(someUrl3, someOptions3); // Will call fetch() after the second finished
38
+ * ```
39
+ */
40
+ wait(options?: Readonly<AsyncQueueWaitOptions>): Promise<void>;
41
+ /**
42
+ * Unlocks the head lock and transfers the next lock (if any) to the head.
43
+ */
44
+ shift(): void;
45
+ /**
46
+ * Aborts all the pending promises.
47
+ * @note To avoid race conditions, this does **not** unlock the head lock.
48
+ */
49
+ abortAll(): void;
50
+ }
51
+ interface AsyncQueueWaitOptions {
52
+ signal?: AbortSignal | undefined | null;
53
+ }
54
+
55
+ export { AsyncQueue, type AsyncQueueWaitOptions };
@@ -1,13 +1,10 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
4
- var __publicField = (obj, key, value) => {
5
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
6
- return value;
7
- };
4
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
8
5
 
9
- // src/lib/AsyncQueueEntry.ts
10
- var AsyncQueueEntry = class {
6
+ // src/lib/_AsyncQueueEntry.ts
7
+ var _AsyncQueueEntry = class _AsyncQueueEntry {
11
8
  constructor(queue) {
12
9
  __publicField(this, "promise");
13
10
  __publicField(this, "resolve");
@@ -22,13 +19,11 @@ var AsyncQueueEntry = class {
22
19
  });
23
20
  }
24
21
  setSignal(signal) {
25
- if (signal.aborted)
26
- return this;
22
+ if (signal.aborted) return this;
27
23
  this.signal = signal;
28
24
  this.signalListener = () => {
29
25
  const index = this.queue["promises"].indexOf(this);
30
- if (index !== -1)
31
- this.queue["promises"].splice(index, 1);
26
+ if (index !== -1) this.queue["promises"].splice(index, 1);
32
27
  this.reject(new Error("Request aborted manually"));
33
28
  };
34
29
  this.signal.addEventListener("abort", this.signalListener);
@@ -52,10 +47,11 @@ var AsyncQueueEntry = class {
52
47
  }
53
48
  }
54
49
  };
55
- __name(AsyncQueueEntry, "AsyncQueueEntry");
50
+ __name(_AsyncQueueEntry, "AsyncQueueEntry");
51
+ var AsyncQueueEntry = _AsyncQueueEntry;
56
52
 
57
53
  // src/lib/AsyncQueue.ts
58
- var AsyncQueue = class {
54
+ var _AsyncQueue = class _AsyncQueue {
59
55
  constructor() {
60
56
  /**
61
57
  * The promises array
@@ -104,16 +100,14 @@ var AsyncQueue = class {
104
100
  return Promise.resolve();
105
101
  }
106
102
  this.promises.push(entry);
107
- if (options?.signal)
108
- entry.setSignal(options.signal);
103
+ if (options?.signal) entry.setSignal(options.signal);
109
104
  return entry.promise;
110
105
  }
111
106
  /**
112
107
  * Unlocks the head lock and transfers the next lock (if any) to the head.
113
108
  */
114
109
  shift() {
115
- if (this.promises.length === 0)
116
- return;
110
+ if (this.promises.length === 0) return;
117
111
  if (this.promises.length === 1) {
118
112
  this.promises.shift();
119
113
  return;
@@ -126,16 +120,16 @@ var AsyncQueue = class {
126
120
  * @note To avoid race conditions, this does **not** unlock the head lock.
127
121
  */
128
122
  abortAll() {
129
- if (this.queued === 0)
130
- return;
123
+ if (this.queued === 0) return;
131
124
  for (let i = 1; i < this.promises.length; ++i) {
132
125
  this.promises[i].abort();
133
126
  }
134
127
  this.promises.length = 1;
135
128
  }
136
129
  };
137
- __name(AsyncQueue, "AsyncQueue");
130
+ __name(_AsyncQueue, "AsyncQueue");
131
+ var AsyncQueue = _AsyncQueue;
138
132
 
139
133
  export { AsyncQueue };
140
- //# sourceMappingURL=out.js.map
134
+ //# sourceMappingURL=index.mjs.map
141
135
  //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lib/_AsyncQueueEntry.ts","../../src/lib/AsyncQueue.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import type { AsyncQueue } from './AsyncQueue';\n\n/**\n * @internal\n */\nexport class AsyncQueueEntry {\n\tpublic readonly promise: Promise<void>;\n\tprivate resolve!: () => void;\n\tprivate reject!: (error: Error) => void;\n\tprivate readonly queue: AsyncQueue;\n\tprivate signal: PolyFillAbortSignal | null = null;\n\tprivate signalListener: (() => void) | null = null;\n\n\tpublic constructor(queue: AsyncQueue) {\n\t\tthis.queue = queue;\n\t\tthis.promise = new Promise((resolve, reject) => {\n\t\t\tthis.resolve = resolve;\n\t\t\tthis.reject = reject;\n\t\t});\n\t}\n\n\tpublic setSignal(signal: AbortSignal) {\n\t\tif (signal.aborted) return this;\n\n\t\tthis.signal = signal as PolyFillAbortSignal;\n\t\tthis.signalListener = () => {\n\t\t\tconst index = this.queue['promises'].indexOf(this);\n\t\t\tif (index !== -1) this.queue['promises'].splice(index, 1);\n\n\t\t\tthis.reject(new Error('Request aborted manually'));\n\t\t};\n\t\tthis.signal.addEventListener('abort', this.signalListener);\n\t\treturn this;\n\t}\n\n\tpublic use() {\n\t\tthis.dispose();\n\t\tthis.resolve();\n\t\treturn this;\n\t}\n\n\tpublic abort() {\n\t\tthis.dispose();\n\t\tthis.reject(new Error('Request aborted manually'));\n\t\treturn this;\n\t}\n\n\tprivate dispose() {\n\t\tif (this.signal) {\n\t\t\tthis.signal.removeEventListener('abort', this.signalListener!);\n\t\t\tthis.signal = null;\n\t\t\tthis.signalListener = null;\n\t\t}\n\t}\n}\n\ninterface PolyFillAbortSignal {\n\treadonly aborted: boolean;\n\taddEventListener(type: 'abort', listener: () => void): void;\n\tremoveEventListener(type: 'abort', listener: () => void): void;\n}\n","import { AsyncQueueEntry } from './_AsyncQueueEntry';\n\n/**\n * The AsyncQueue class used to sequentialize burst requests\n */\nexport class AsyncQueue {\n\t/**\n\t * The amount of entries in the queue, including the head.\n\t * @seealso {@link queued} for the queued count.\n\t */\n\tpublic get remaining(): number {\n\t\treturn this.promises.length;\n\t}\n\n\t/**\n\t * The amount of queued entries.\n\t * @seealso {@link remaining} for the count with the head.\n\t */\n\tpublic get queued(): number {\n\t\treturn this.remaining === 0 ? 0 : this.remaining - 1;\n\t}\n\n\t/**\n\t * The promises array\n\t */\n\tprivate readonly promises: AsyncQueueEntry[] = [];\n\n\t/**\n\t * Waits for last promise and queues a new one\n\t * @example\n\t * ```typescript\n\t * const queue = new AsyncQueue();\n\t * async function request(url, options) {\n\t * await queue.wait({ signal: options.signal });\n\t * try {\n\t * const result = await fetch(url, options);\n\t * // Do some operations with 'result'\n\t * } finally {\n\t * // Remove first entry from the queue and resolve for the next entry\n\t * queue.shift();\n\t * }\n\t * }\n\t *\n\t * request(someUrl1, someOptions1); // Will call fetch() immediately\n\t * request(someUrl2, someOptions2); // Will call fetch() after the first finished\n\t * request(someUrl3, someOptions3); // Will call fetch() after the second finished\n\t * ```\n\t */\n\tpublic wait(options?: Readonly<AsyncQueueWaitOptions>): Promise<void> {\n\t\tconst entry = new AsyncQueueEntry(this);\n\n\t\tif (this.promises.length === 0) {\n\t\t\tthis.promises.push(entry);\n\t\t\treturn Promise.resolve();\n\t\t}\n\n\t\tthis.promises.push(entry);\n\t\tif (options?.signal) entry.setSignal(options.signal);\n\t\treturn entry.promise;\n\t}\n\n\t/**\n\t * Unlocks the head lock and transfers the next lock (if any) to the head.\n\t */\n\tpublic shift(): void {\n\t\tif (this.promises.length === 0) return;\n\t\tif (this.promises.length === 1) {\n\t\t\t// Remove the head entry.\n\t\t\tthis.promises.shift();\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove the head entry, making the 2nd entry the new one.\n\t\t// Then use the head entry, which will unlock the promise.\n\t\tthis.promises.shift();\n\t\tthis.promises[0].use();\n\t}\n\n\t/**\n\t * Aborts all the pending promises.\n\t * @note To avoid race conditions, this does **not** unlock the head lock.\n\t */\n\tpublic abortAll(): void {\n\t\t// If there are no queued entries, skip early.\n\t\tif (this.queued === 0) return;\n\n\t\t// Abort all the entries except the head, that is why the loop starts at\n\t\t// 1 and not at 0.\n\t\tfor (let i = 1; i < this.promises.length; ++i) {\n\t\t\tthis.promises[i].abort();\n\t\t}\n\n\t\tthis.promises.length = 1;\n\t}\n}\n\nexport interface AsyncQueueWaitOptions {\n\tsignal?: AbortSignal | undefined | null;\n}\n"]}
@@ -4,13 +4,10 @@ var SapphireAsyncQueue = (function (exports) {
4
4
  var __defProp = Object.defineProperty;
5
5
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
6
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
- var __publicField = (obj, key, value) => {
8
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
9
- return value;
10
- };
7
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
11
8
 
12
- // src/lib/AsyncQueueEntry.ts
13
- var AsyncQueueEntry = class {
9
+ // src/lib/_AsyncQueueEntry.ts
10
+ var _AsyncQueueEntry = class _AsyncQueueEntry {
14
11
  constructor(queue) {
15
12
  __publicField(this, "promise");
16
13
  __publicField(this, "resolve");
@@ -25,13 +22,11 @@ var SapphireAsyncQueue = (function (exports) {
25
22
  });
26
23
  }
27
24
  setSignal(signal) {
28
- if (signal.aborted)
29
- return this;
25
+ if (signal.aborted) return this;
30
26
  this.signal = signal;
31
27
  this.signalListener = () => {
32
28
  const index = this.queue["promises"].indexOf(this);
33
- if (index !== -1)
34
- this.queue["promises"].splice(index, 1);
29
+ if (index !== -1) this.queue["promises"].splice(index, 1);
35
30
  this.reject(new Error("Request aborted manually"));
36
31
  };
37
32
  this.signal.addEventListener("abort", this.signalListener);
@@ -55,10 +50,11 @@ var SapphireAsyncQueue = (function (exports) {
55
50
  }
56
51
  }
57
52
  };
58
- __name(AsyncQueueEntry, "AsyncQueueEntry");
53
+ __name(_AsyncQueueEntry, "AsyncQueueEntry");
54
+ var AsyncQueueEntry = _AsyncQueueEntry;
59
55
 
60
56
  // src/lib/AsyncQueue.ts
61
- var AsyncQueue = class {
57
+ var _AsyncQueue = class _AsyncQueue {
62
58
  constructor() {
63
59
  /**
64
60
  * The promises array
@@ -107,16 +103,14 @@ var SapphireAsyncQueue = (function (exports) {
107
103
  return Promise.resolve();
108
104
  }
109
105
  this.promises.push(entry);
110
- if (options?.signal)
111
- entry.setSignal(options.signal);
106
+ if (options?.signal) entry.setSignal(options.signal);
112
107
  return entry.promise;
113
108
  }
114
109
  /**
115
110
  * Unlocks the head lock and transfers the next lock (if any) to the head.
116
111
  */
117
112
  shift() {
118
- if (this.promises.length === 0)
119
- return;
113
+ if (this.promises.length === 0) return;
120
114
  if (this.promises.length === 1) {
121
115
  this.promises.shift();
122
116
  return;
@@ -129,20 +123,20 @@ var SapphireAsyncQueue = (function (exports) {
129
123
  * @note To avoid race conditions, this does **not** unlock the head lock.
130
124
  */
131
125
  abortAll() {
132
- if (this.queued === 0)
133
- return;
126
+ if (this.queued === 0) return;
134
127
  for (let i = 1; i < this.promises.length; ++i) {
135
128
  this.promises[i].abort();
136
129
  }
137
130
  this.promises.length = 1;
138
131
  }
139
132
  };
140
- __name(AsyncQueue, "AsyncQueue");
133
+ __name(_AsyncQueue, "AsyncQueue");
134
+ var AsyncQueue = _AsyncQueue;
141
135
 
142
136
  exports.AsyncQueue = AsyncQueue;
143
137
 
144
138
  return exports;
145
139
 
146
140
  })({});
147
- //# sourceMappingURL=out.js.map
141
+ //# sourceMappingURL=index.global.js.map
148
142
  //# sourceMappingURL=index.global.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lib/_AsyncQueueEntry.ts","../../src/lib/AsyncQueue.ts"],"names":[],"mappings":"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","file":"index.global.js","sourcesContent":["import type { AsyncQueue } from './AsyncQueue';\n\n/**\n * @internal\n */\nexport class AsyncQueueEntry {\n\tpublic readonly promise: Promise<void>;\n\tprivate resolve!: () => void;\n\tprivate reject!: (error: Error) => void;\n\tprivate readonly queue: AsyncQueue;\n\tprivate signal: PolyFillAbortSignal | null = null;\n\tprivate signalListener: (() => void) | null = null;\n\n\tpublic constructor(queue: AsyncQueue) {\n\t\tthis.queue = queue;\n\t\tthis.promise = new Promise((resolve, reject) => {\n\t\t\tthis.resolve = resolve;\n\t\t\tthis.reject = reject;\n\t\t});\n\t}\n\n\tpublic setSignal(signal: AbortSignal) {\n\t\tif (signal.aborted) return this;\n\n\t\tthis.signal = signal as PolyFillAbortSignal;\n\t\tthis.signalListener = () => {\n\t\t\tconst index = this.queue['promises'].indexOf(this);\n\t\t\tif (index !== -1) this.queue['promises'].splice(index, 1);\n\n\t\t\tthis.reject(new Error('Request aborted manually'));\n\t\t};\n\t\tthis.signal.addEventListener('abort', this.signalListener);\n\t\treturn this;\n\t}\n\n\tpublic use() {\n\t\tthis.dispose();\n\t\tthis.resolve();\n\t\treturn this;\n\t}\n\n\tpublic abort() {\n\t\tthis.dispose();\n\t\tthis.reject(new Error('Request aborted manually'));\n\t\treturn this;\n\t}\n\n\tprivate dispose() {\n\t\tif (this.signal) {\n\t\t\tthis.signal.removeEventListener('abort', this.signalListener!);\n\t\t\tthis.signal = null;\n\t\t\tthis.signalListener = null;\n\t\t}\n\t}\n}\n\ninterface PolyFillAbortSignal {\n\treadonly aborted: boolean;\n\taddEventListener(type: 'abort', listener: () => void): void;\n\tremoveEventListener(type: 'abort', listener: () => void): void;\n}\n","import { AsyncQueueEntry } from './_AsyncQueueEntry';\n\n/**\n * The AsyncQueue class used to sequentialize burst requests\n */\nexport class AsyncQueue {\n\t/**\n\t * The amount of entries in the queue, including the head.\n\t * @seealso {@link queued} for the queued count.\n\t */\n\tpublic get remaining(): number {\n\t\treturn this.promises.length;\n\t}\n\n\t/**\n\t * The amount of queued entries.\n\t * @seealso {@link remaining} for the count with the head.\n\t */\n\tpublic get queued(): number {\n\t\treturn this.remaining === 0 ? 0 : this.remaining - 1;\n\t}\n\n\t/**\n\t * The promises array\n\t */\n\tprivate readonly promises: AsyncQueueEntry[] = [];\n\n\t/**\n\t * Waits for last promise and queues a new one\n\t * @example\n\t * ```typescript\n\t * const queue = new AsyncQueue();\n\t * async function request(url, options) {\n\t * await queue.wait({ signal: options.signal });\n\t * try {\n\t * const result = await fetch(url, options);\n\t * // Do some operations with 'result'\n\t * } finally {\n\t * // Remove first entry from the queue and resolve for the next entry\n\t * queue.shift();\n\t * }\n\t * }\n\t *\n\t * request(someUrl1, someOptions1); // Will call fetch() immediately\n\t * request(someUrl2, someOptions2); // Will call fetch() after the first finished\n\t * request(someUrl3, someOptions3); // Will call fetch() after the second finished\n\t * ```\n\t */\n\tpublic wait(options?: Readonly<AsyncQueueWaitOptions>): Promise<void> {\n\t\tconst entry = new AsyncQueueEntry(this);\n\n\t\tif (this.promises.length === 0) {\n\t\t\tthis.promises.push(entry);\n\t\t\treturn Promise.resolve();\n\t\t}\n\n\t\tthis.promises.push(entry);\n\t\tif (options?.signal) entry.setSignal(options.signal);\n\t\treturn entry.promise;\n\t}\n\n\t/**\n\t * Unlocks the head lock and transfers the next lock (if any) to the head.\n\t */\n\tpublic shift(): void {\n\t\tif (this.promises.length === 0) return;\n\t\tif (this.promises.length === 1) {\n\t\t\t// Remove the head entry.\n\t\t\tthis.promises.shift();\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove the head entry, making the 2nd entry the new one.\n\t\t// Then use the head entry, which will unlock the promise.\n\t\tthis.promises.shift();\n\t\tthis.promises[0].use();\n\t}\n\n\t/**\n\t * Aborts all the pending promises.\n\t * @note To avoid race conditions, this does **not** unlock the head lock.\n\t */\n\tpublic abortAll(): void {\n\t\t// If there are no queued entries, skip early.\n\t\tif (this.queued === 0) return;\n\n\t\t// Abort all the entries except the head, that is why the loop starts at\n\t\t// 1 and not at 0.\n\t\tfor (let i = 1; i < this.promises.length; ++i) {\n\t\t\tthis.promises[i].abort();\n\t\t}\n\n\t\tthis.promises.length = 1;\n\t}\n}\n\nexport interface AsyncQueueWaitOptions {\n\tsignal?: AbortSignal | undefined | null;\n}\n"]}
package/package.json CHANGED
@@ -1,18 +1,24 @@
1
1
  {
2
2
  "name": "@sapphire/async-queue",
3
- "version": "1.6.0-pr-589.aa473f9.0",
3
+ "version": "1.6.0-pr-935.7da5c8bb",
4
4
  "description": "Sequential asynchronous lock-based queue for promises",
5
5
  "author": "@sapphire",
6
6
  "license": "MIT",
7
- "main": "dist/index.js",
8
- "module": "dist/index.mjs",
9
- "browser": "dist/index.global.js",
10
- "unpkg": "dist/index.global.js",
11
- "types": "dist/index.d.ts",
7
+ "main": "dist/cjs/index.cjs",
8
+ "module": "dist/esm/index.mjs",
9
+ "browser": "dist/iife/index.global.js",
10
+ "unpkg": "dist/iife/index.global.js",
11
+ "types": "dist/cjs/index.d.cts",
12
12
  "exports": {
13
- "import": "./dist/index.mjs",
14
- "require": "./dist/index.js",
15
- "types": "./dist/index.d.ts"
13
+ "import": {
14
+ "types": "./dist/esm/index.d.mts",
15
+ "default": "./dist/esm/index.mjs"
16
+ },
17
+ "require": {
18
+ "types": "./dist/cjs/index.d.cts",
19
+ "default": "./dist/cjs/index.cjs"
20
+ },
21
+ "browser": "./dist/iife/index.global.js"
16
22
  },
17
23
  "sideEffects": false,
18
24
  "homepage": "https://github.com/sapphiredev/utilities/tree/main/packages/async-queue",
@@ -20,10 +26,12 @@
20
26
  "test": "vitest run",
21
27
  "lint": "eslint src tests --ext ts --fix -c ../../.eslintrc",
22
28
  "docs": "typedoc-json-parser",
23
- "build": "tsup",
29
+ "build": "yarn gen-index && tsup && yarn build:rename-cjs-index",
30
+ "build:rename-cjs-index": "tsx ../../scripts/rename-cjs-index.cts",
24
31
  "prepack": "yarn build",
25
32
  "bump": "cliff-jumper",
26
- "check-update": "cliff-jumper --dry-run"
33
+ "check-update": "cliff-jumper --dry-run",
34
+ "gen-index": "tsx ../../scripts/gen-index.cts async-queue --write"
27
35
  },
28
36
  "repository": {
29
37
  "type": "git",
@@ -31,9 +39,7 @@
31
39
  "directory": "packages/async-queue"
32
40
  },
33
41
  "files": [
34
- "dist/**/*.js*",
35
- "dist/**/*.mjs*",
36
- "dist/**/*.d*"
42
+ "dist/"
37
43
  ],
38
44
  "engines": {
39
45
  "node": ">=v14.0.0",
@@ -56,12 +62,13 @@
56
62
  "access": "public"
57
63
  },
58
64
  "devDependencies": {
59
- "@favware/cliff-jumper": "^2.0.0",
60
- "@vitest/coverage-c8": "^0.30.1",
61
- "tsup": "^6.7.0",
62
- "typedoc": "^0.24.6",
63
- "typedoc-json-parser": "^7.3.2",
64
- "typescript": "^5.0.4",
65
- "vitest": "^0.30.1"
65
+ "@favware/cliff-jumper": "^6.0.0",
66
+ "@vitest/coverage-v8": "^3.2.4",
67
+ "tsup": "^8.5.0",
68
+ "tsx": "^4.20.6",
69
+ "typedoc": "^0.26.11",
70
+ "typedoc-json-parser": "^10.2.0",
71
+ "typescript": "~5.4.5",
72
+ "vitest": "^3.2.4"
66
73
  }
67
74
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/lib/AsyncQueueEntry.ts","../src/lib/AsyncQueue.ts"],"names":[],"mappings":";;;;;;;;;AAKO,IAAM,kBAAN,MAAsB;AAAA,EAQrB,YAAY,OAAmB;AAPtC,wBAAgB;AAChB,wBAAQ;AACR,wBAAQ;AACR,wBAAiB;AACjB,wBAAQ,UAAqC;AAC7C,wBAAQ,kBAAsC;AAG7C,SAAK,QAAQ;AACb,SAAK,UAAU,IAAI,QAAQ,CAAC,SAAS,WAAW;AAC/C,WAAK,UAAU;AACf,WAAK,SAAS;AAAA,IACf,CAAC;AAAA,EACF;AAAA,EAEO,UAAU,QAAqB;AACrC,QAAI,OAAO;AAAS,aAAO;AAE3B,SAAK,SAAS;AACd,SAAK,iBAAiB,MAAM;AAC3B,YAAM,QAAQ,KAAK,MAAM,UAAU,EAAE,QAAQ,IAAI;AACjD,UAAI,UAAU;AAAI,aAAK,MAAM,UAAU,EAAE,OAAO,OAAO,CAAC;AAExD,WAAK,OAAO,IAAI,MAAM,0BAA0B,CAAC;AAAA,IAClD;AACA,SAAK,OAAO,iBAAiB,SAAS,KAAK,cAAc;AACzD,WAAO;AAAA,EACR;AAAA,EAEO,MAAM;AACZ,SAAK,QAAQ;AACb,SAAK,QAAQ;AACb,WAAO;AAAA,EACR;AAAA,EAEO,QAAQ;AACd,SAAK,QAAQ;AACb,SAAK,OAAO,IAAI,MAAM,0BAA0B,CAAC;AACjD,WAAO;AAAA,EACR;AAAA,EAEQ,UAAU;AACjB,QAAI,KAAK,QAAQ;AAChB,WAAK,OAAO,oBAAoB,SAAS,KAAK,cAAe;AAC7D,WAAK,SAAS;AACd,WAAK,iBAAiB;AAAA,IACvB;AAAA,EACD;AACD;AAjDa;;;ACAN,IAAM,aAAN,MAAiB;AAAA,EAAjB;AAoBN;AAAA;AAAA;AAAA,wBAAQ,YAA8B,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAfvC,IAAW,YAAoB;AAC9B,WAAO,KAAK,SAAS;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAW,SAAiB;AAC3B,WAAO,KAAK,cAAc,IAAI,IAAI,KAAK,YAAY;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA4BO,KAAK,SAA0D;AACrE,UAAM,QAAQ,IAAI,gBAAgB,IAAI;AAEtC,QAAI,KAAK,SAAS,WAAW,GAAG;AAC/B,WAAK,SAAS,KAAK,KAAK;AACxB,aAAO,QAAQ,QAAQ;AAAA,IACxB;AAEA,SAAK,SAAS,KAAK,KAAK;AACxB,QAAI,SAAS;AAAQ,YAAM,UAAU,QAAQ,MAAM;AACnD,WAAO,MAAM;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKO,QAAc;AACpB,QAAI,KAAK,SAAS,WAAW;AAAG;AAChC,QAAI,KAAK,SAAS,WAAW,GAAG;AAE/B,WAAK,SAAS,MAAM;AACpB;AAAA,IACD;AAIA,SAAK,SAAS,MAAM;AACpB,SAAK,SAAS,CAAC,EAAE,IAAI;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,WAAiB;AAEvB,QAAI,KAAK,WAAW;AAAG;AAIvB,aAAS,IAAI,GAAG,IAAI,KAAK,SAAS,QAAQ,EAAE,GAAG;AAC9C,WAAK,SAAS,CAAC,EAAE,MAAM;AAAA,IACxB;AAEA,SAAK,SAAS,SAAS;AAAA,EACxB;AACD;AAzFa","sourcesContent":["import type { AsyncQueue } from './AsyncQueue';\n\n/**\n * @internal\n */\nexport class AsyncQueueEntry {\n\tpublic readonly promise: Promise<void>;\n\tprivate resolve!: () => void;\n\tprivate reject!: (error: Error) => void;\n\tprivate readonly queue: AsyncQueue;\n\tprivate signal: PolyFillAbortSignal | null = null;\n\tprivate signalListener: (() => void) | null = null;\n\n\tpublic constructor(queue: AsyncQueue) {\n\t\tthis.queue = queue;\n\t\tthis.promise = new Promise((resolve, reject) => {\n\t\t\tthis.resolve = resolve;\n\t\t\tthis.reject = reject;\n\t\t});\n\t}\n\n\tpublic setSignal(signal: AbortSignal) {\n\t\tif (signal.aborted) return this;\n\n\t\tthis.signal = signal as PolyFillAbortSignal;\n\t\tthis.signalListener = () => {\n\t\t\tconst index = this.queue['promises'].indexOf(this);\n\t\t\tif (index !== -1) this.queue['promises'].splice(index, 1);\n\n\t\t\tthis.reject(new Error('Request aborted manually'));\n\t\t};\n\t\tthis.signal.addEventListener('abort', this.signalListener);\n\t\treturn this;\n\t}\n\n\tpublic use() {\n\t\tthis.dispose();\n\t\tthis.resolve();\n\t\treturn this;\n\t}\n\n\tpublic abort() {\n\t\tthis.dispose();\n\t\tthis.reject(new Error('Request aborted manually'));\n\t\treturn this;\n\t}\n\n\tprivate dispose() {\n\t\tif (this.signal) {\n\t\t\tthis.signal.removeEventListener('abort', this.signalListener!);\n\t\t\tthis.signal = null;\n\t\t\tthis.signalListener = null;\n\t\t}\n\t}\n}\n\ninterface PolyFillAbortSignal {\n\treadonly aborted: boolean;\n\taddEventListener(type: 'abort', listener: () => void): void;\n\tremoveEventListener(type: 'abort', listener: () => void): void;\n}\n","import { AsyncQueueEntry } from './AsyncQueueEntry';\n\n/**\n * The AsyncQueue class used to sequentialize burst requests\n */\nexport class AsyncQueue {\n\t/**\n\t * The amount of entries in the queue, including the head.\n\t * @seealso {@link queued} for the queued count.\n\t */\n\tpublic get remaining(): number {\n\t\treturn this.promises.length;\n\t}\n\n\t/**\n\t * The amount of queued entries.\n\t * @seealso {@link remaining} for the count with the head.\n\t */\n\tpublic get queued(): number {\n\t\treturn this.remaining === 0 ? 0 : this.remaining - 1;\n\t}\n\n\t/**\n\t * The promises array\n\t */\n\tprivate promises: AsyncQueueEntry[] = [];\n\n\t/**\n\t * Waits for last promise and queues a new one\n\t * @example\n\t * ```typescript\n\t * const queue = new AsyncQueue();\n\t * async function request(url, options) {\n\t * await queue.wait({ signal: options.signal });\n\t * try {\n\t * const result = await fetch(url, options);\n\t * // Do some operations with 'result'\n\t * } finally {\n\t * // Remove first entry from the queue and resolve for the next entry\n\t * queue.shift();\n\t * }\n\t * }\n\t *\n\t * request(someUrl1, someOptions1); // Will call fetch() immediately\n\t * request(someUrl2, someOptions2); // Will call fetch() after the first finished\n\t * request(someUrl3, someOptions3); // Will call fetch() after the second finished\n\t * ```\n\t */\n\tpublic wait(options?: Readonly<AsyncQueueWaitOptions>): Promise<void> {\n\t\tconst entry = new AsyncQueueEntry(this);\n\n\t\tif (this.promises.length === 0) {\n\t\t\tthis.promises.push(entry);\n\t\t\treturn Promise.resolve();\n\t\t}\n\n\t\tthis.promises.push(entry);\n\t\tif (options?.signal) entry.setSignal(options.signal);\n\t\treturn entry.promise;\n\t}\n\n\t/**\n\t * Unlocks the head lock and transfers the next lock (if any) to the head.\n\t */\n\tpublic shift(): void {\n\t\tif (this.promises.length === 0) return;\n\t\tif (this.promises.length === 1) {\n\t\t\t// Remove the head entry.\n\t\t\tthis.promises.shift();\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove the head entry, making the 2nd entry the new one.\n\t\t// Then use the head entry, which will unlock the promise.\n\t\tthis.promises.shift();\n\t\tthis.promises[0].use();\n\t}\n\n\t/**\n\t * Aborts all the pending promises.\n\t * @note To avoid race conditions, this does **not** unlock the head lock.\n\t */\n\tpublic abortAll(): void {\n\t\t// If there are no queued entries, skip early.\n\t\tif (this.queued === 0) return;\n\n\t\t// Abort all the entries except the head, that is why the loop starts at\n\t\t// 1 and not at 0.\n\t\tfor (let i = 1; i < this.promises.length; ++i) {\n\t\t\tthis.promises[i].abort();\n\t\t}\n\n\t\tthis.promises.length = 1;\n\t}\n}\n\nexport interface AsyncQueueWaitOptions {\n\tsignal?: AbortSignal | undefined | null;\n}\n"]}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/lib/AsyncQueueEntry.ts","../src/lib/AsyncQueue.ts"],"names":[],"mappings":";;;;;;;;;AAKO,IAAM,kBAAN,MAAsB;AAAA,EAQrB,YAAY,OAAmB;AAPtC,wBAAgB;AAChB,wBAAQ;AACR,wBAAQ;AACR,wBAAiB;AACjB,wBAAQ,UAAqC;AAC7C,wBAAQ,kBAAsC;AAG7C,SAAK,QAAQ;AACb,SAAK,UAAU,IAAI,QAAQ,CAAC,SAAS,WAAW;AAC/C,WAAK,UAAU;AACf,WAAK,SAAS;AAAA,IACf,CAAC;AAAA,EACF;AAAA,EAEO,UAAU,QAAqB;AACrC,QAAI,OAAO;AAAS,aAAO;AAE3B,SAAK,SAAS;AACd,SAAK,iBAAiB,MAAM;AAC3B,YAAM,QAAQ,KAAK,MAAM,UAAU,EAAE,QAAQ,IAAI;AACjD,UAAI,UAAU;AAAI,aAAK,MAAM,UAAU,EAAE,OAAO,OAAO,CAAC;AAExD,WAAK,OAAO,IAAI,MAAM,0BAA0B,CAAC;AAAA,IAClD;AACA,SAAK,OAAO,iBAAiB,SAAS,KAAK,cAAc;AACzD,WAAO;AAAA,EACR;AAAA,EAEO,MAAM;AACZ,SAAK,QAAQ;AACb,SAAK,QAAQ;AACb,WAAO;AAAA,EACR;AAAA,EAEO,QAAQ;AACd,SAAK,QAAQ;AACb,SAAK,OAAO,IAAI,MAAM,0BAA0B,CAAC;AACjD,WAAO;AAAA,EACR;AAAA,EAEQ,UAAU;AACjB,QAAI,KAAK,QAAQ;AAChB,WAAK,OAAO,oBAAoB,SAAS,KAAK,cAAe;AAC7D,WAAK,SAAS;AACd,WAAK,iBAAiB;AAAA,IACvB;AAAA,EACD;AACD;AAjDa;;;ACAN,IAAM,aAAN,MAAiB;AAAA,EAAjB;AAoBN;AAAA;AAAA;AAAA,wBAAQ,YAA8B,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAfvC,IAAW,YAAoB;AAC9B,WAAO,KAAK,SAAS;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAW,SAAiB;AAC3B,WAAO,KAAK,cAAc,IAAI,IAAI,KAAK,YAAY;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA4BO,KAAK,SAA0D;AACrE,UAAM,QAAQ,IAAI,gBAAgB,IAAI;AAEtC,QAAI,KAAK,SAAS,WAAW,GAAG;AAC/B,WAAK,SAAS,KAAK,KAAK;AACxB,aAAO,QAAQ,QAAQ;AAAA,IACxB;AAEA,SAAK,SAAS,KAAK,KAAK;AACxB,QAAI,SAAS;AAAQ,YAAM,UAAU,QAAQ,MAAM;AACnD,WAAO,MAAM;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKO,QAAc;AACpB,QAAI,KAAK,SAAS,WAAW;AAAG;AAChC,QAAI,KAAK,SAAS,WAAW,GAAG;AAE/B,WAAK,SAAS,MAAM;AACpB;AAAA,IACD;AAIA,SAAK,SAAS,MAAM;AACpB,SAAK,SAAS,CAAC,EAAE,IAAI;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,WAAiB;AAEvB,QAAI,KAAK,WAAW;AAAG;AAIvB,aAAS,IAAI,GAAG,IAAI,KAAK,SAAS,QAAQ,EAAE,GAAG;AAC9C,WAAK,SAAS,CAAC,EAAE,MAAM;AAAA,IACxB;AAEA,SAAK,SAAS,SAAS;AAAA,EACxB;AACD;AAzFa","sourcesContent":["import type { AsyncQueue } from './AsyncQueue';\n\n/**\n * @internal\n */\nexport class AsyncQueueEntry {\n\tpublic readonly promise: Promise<void>;\n\tprivate resolve!: () => void;\n\tprivate reject!: (error: Error) => void;\n\tprivate readonly queue: AsyncQueue;\n\tprivate signal: PolyFillAbortSignal | null = null;\n\tprivate signalListener: (() => void) | null = null;\n\n\tpublic constructor(queue: AsyncQueue) {\n\t\tthis.queue = queue;\n\t\tthis.promise = new Promise((resolve, reject) => {\n\t\t\tthis.resolve = resolve;\n\t\t\tthis.reject = reject;\n\t\t});\n\t}\n\n\tpublic setSignal(signal: AbortSignal) {\n\t\tif (signal.aborted) return this;\n\n\t\tthis.signal = signal as PolyFillAbortSignal;\n\t\tthis.signalListener = () => {\n\t\t\tconst index = this.queue['promises'].indexOf(this);\n\t\t\tif (index !== -1) this.queue['promises'].splice(index, 1);\n\n\t\t\tthis.reject(new Error('Request aborted manually'));\n\t\t};\n\t\tthis.signal.addEventListener('abort', this.signalListener);\n\t\treturn this;\n\t}\n\n\tpublic use() {\n\t\tthis.dispose();\n\t\tthis.resolve();\n\t\treturn this;\n\t}\n\n\tpublic abort() {\n\t\tthis.dispose();\n\t\tthis.reject(new Error('Request aborted manually'));\n\t\treturn this;\n\t}\n\n\tprivate dispose() {\n\t\tif (this.signal) {\n\t\t\tthis.signal.removeEventListener('abort', this.signalListener!);\n\t\t\tthis.signal = null;\n\t\t\tthis.signalListener = null;\n\t\t}\n\t}\n}\n\ninterface PolyFillAbortSignal {\n\treadonly aborted: boolean;\n\taddEventListener(type: 'abort', listener: () => void): void;\n\tremoveEventListener(type: 'abort', listener: () => void): void;\n}\n","import { AsyncQueueEntry } from './AsyncQueueEntry';\n\n/**\n * The AsyncQueue class used to sequentialize burst requests\n */\nexport class AsyncQueue {\n\t/**\n\t * The amount of entries in the queue, including the head.\n\t * @seealso {@link queued} for the queued count.\n\t */\n\tpublic get remaining(): number {\n\t\treturn this.promises.length;\n\t}\n\n\t/**\n\t * The amount of queued entries.\n\t * @seealso {@link remaining} for the count with the head.\n\t */\n\tpublic get queued(): number {\n\t\treturn this.remaining === 0 ? 0 : this.remaining - 1;\n\t}\n\n\t/**\n\t * The promises array\n\t */\n\tprivate promises: AsyncQueueEntry[] = [];\n\n\t/**\n\t * Waits for last promise and queues a new one\n\t * @example\n\t * ```typescript\n\t * const queue = new AsyncQueue();\n\t * async function request(url, options) {\n\t * await queue.wait({ signal: options.signal });\n\t * try {\n\t * const result = await fetch(url, options);\n\t * // Do some operations with 'result'\n\t * } finally {\n\t * // Remove first entry from the queue and resolve for the next entry\n\t * queue.shift();\n\t * }\n\t * }\n\t *\n\t * request(someUrl1, someOptions1); // Will call fetch() immediately\n\t * request(someUrl2, someOptions2); // Will call fetch() after the first finished\n\t * request(someUrl3, someOptions3); // Will call fetch() after the second finished\n\t * ```\n\t */\n\tpublic wait(options?: Readonly<AsyncQueueWaitOptions>): Promise<void> {\n\t\tconst entry = new AsyncQueueEntry(this);\n\n\t\tif (this.promises.length === 0) {\n\t\t\tthis.promises.push(entry);\n\t\t\treturn Promise.resolve();\n\t\t}\n\n\t\tthis.promises.push(entry);\n\t\tif (options?.signal) entry.setSignal(options.signal);\n\t\treturn entry.promise;\n\t}\n\n\t/**\n\t * Unlocks the head lock and transfers the next lock (if any) to the head.\n\t */\n\tpublic shift(): void {\n\t\tif (this.promises.length === 0) return;\n\t\tif (this.promises.length === 1) {\n\t\t\t// Remove the head entry.\n\t\t\tthis.promises.shift();\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove the head entry, making the 2nd entry the new one.\n\t\t// Then use the head entry, which will unlock the promise.\n\t\tthis.promises.shift();\n\t\tthis.promises[0].use();\n\t}\n\n\t/**\n\t * Aborts all the pending promises.\n\t * @note To avoid race conditions, this does **not** unlock the head lock.\n\t */\n\tpublic abortAll(): void {\n\t\t// If there are no queued entries, skip early.\n\t\tif (this.queued === 0) return;\n\n\t\t// Abort all the entries except the head, that is why the loop starts at\n\t\t// 1 and not at 0.\n\t\tfor (let i = 1; i < this.promises.length; ++i) {\n\t\t\tthis.promises[i].abort();\n\t\t}\n\n\t\tthis.promises.length = 1;\n\t}\n}\n\nexport interface AsyncQueueWaitOptions {\n\tsignal?: AbortSignal | undefined | null;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/lib/AsyncQueueEntry.ts","../src/lib/AsyncQueue.ts"],"names":[],"mappings":";;;;;;;;;AAKO,IAAM,kBAAN,MAAsB;AAAA,EAQrB,YAAY,OAAmB;AAPtC,wBAAgB;AAChB,wBAAQ;AACR,wBAAQ;AACR,wBAAiB;AACjB,wBAAQ,UAAqC;AAC7C,wBAAQ,kBAAsC;AAG7C,SAAK,QAAQ;AACb,SAAK,UAAU,IAAI,QAAQ,CAAC,SAAS,WAAW;AAC/C,WAAK,UAAU;AACf,WAAK,SAAS;AAAA,IACf,CAAC;AAAA,EACF;AAAA,EAEO,UAAU,QAAqB;AACrC,QAAI,OAAO;AAAS,aAAO;AAE3B,SAAK,SAAS;AACd,SAAK,iBAAiB,MAAM;AAC3B,YAAM,QAAQ,KAAK,MAAM,UAAU,EAAE,QAAQ,IAAI;AACjD,UAAI,UAAU;AAAI,aAAK,MAAM,UAAU,EAAE,OAAO,OAAO,CAAC;AAExD,WAAK,OAAO,IAAI,MAAM,0BAA0B,CAAC;AAAA,IAClD;AACA,SAAK,OAAO,iBAAiB,SAAS,KAAK,cAAc;AACzD,WAAO;AAAA,EACR;AAAA,EAEO,MAAM;AACZ,SAAK,QAAQ;AACb,SAAK,QAAQ;AACb,WAAO;AAAA,EACR;AAAA,EAEO,QAAQ;AACd,SAAK,QAAQ;AACb,SAAK,OAAO,IAAI,MAAM,0BAA0B,CAAC;AACjD,WAAO;AAAA,EACR;AAAA,EAEQ,UAAU;AACjB,QAAI,KAAK,QAAQ;AAChB,WAAK,OAAO,oBAAoB,SAAS,KAAK,cAAe;AAC7D,WAAK,SAAS;AACd,WAAK,iBAAiB;AAAA,IACvB;AAAA,EACD;AACD;AAjDa;;;ACAN,IAAM,aAAN,MAAiB;AAAA,EAAjB;AAoBN;AAAA;AAAA;AAAA,wBAAQ,YAA8B,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAfvC,IAAW,YAAoB;AAC9B,WAAO,KAAK,SAAS;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAW,SAAiB;AAC3B,WAAO,KAAK,cAAc,IAAI,IAAI,KAAK,YAAY;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA4BO,KAAK,SAA0D;AACrE,UAAM,QAAQ,IAAI,gBAAgB,IAAI;AAEtC,QAAI,KAAK,SAAS,WAAW,GAAG;AAC/B,WAAK,SAAS,KAAK,KAAK;AACxB,aAAO,QAAQ,QAAQ;AAAA,IACxB;AAEA,SAAK,SAAS,KAAK,KAAK;AACxB,QAAI,SAAS;AAAQ,YAAM,UAAU,QAAQ,MAAM;AACnD,WAAO,MAAM;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKO,QAAc;AACpB,QAAI,KAAK,SAAS,WAAW;AAAG;AAChC,QAAI,KAAK,SAAS,WAAW,GAAG;AAE/B,WAAK,SAAS,MAAM;AACpB;AAAA,IACD;AAIA,SAAK,SAAS,MAAM;AACpB,SAAK,SAAS,CAAC,EAAE,IAAI;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,WAAiB;AAEvB,QAAI,KAAK,WAAW;AAAG;AAIvB,aAAS,IAAI,GAAG,IAAI,KAAK,SAAS,QAAQ,EAAE,GAAG;AAC9C,WAAK,SAAS,CAAC,EAAE,MAAM;AAAA,IACxB;AAEA,SAAK,SAAS,SAAS;AAAA,EACxB;AACD;AAzFa","sourcesContent":["import type { AsyncQueue } from './AsyncQueue';\n\n/**\n * @internal\n */\nexport class AsyncQueueEntry {\n\tpublic readonly promise: Promise<void>;\n\tprivate resolve!: () => void;\n\tprivate reject!: (error: Error) => void;\n\tprivate readonly queue: AsyncQueue;\n\tprivate signal: PolyFillAbortSignal | null = null;\n\tprivate signalListener: (() => void) | null = null;\n\n\tpublic constructor(queue: AsyncQueue) {\n\t\tthis.queue = queue;\n\t\tthis.promise = new Promise((resolve, reject) => {\n\t\t\tthis.resolve = resolve;\n\t\t\tthis.reject = reject;\n\t\t});\n\t}\n\n\tpublic setSignal(signal: AbortSignal) {\n\t\tif (signal.aborted) return this;\n\n\t\tthis.signal = signal as PolyFillAbortSignal;\n\t\tthis.signalListener = () => {\n\t\t\tconst index = this.queue['promises'].indexOf(this);\n\t\t\tif (index !== -1) this.queue['promises'].splice(index, 1);\n\n\t\t\tthis.reject(new Error('Request aborted manually'));\n\t\t};\n\t\tthis.signal.addEventListener('abort', this.signalListener);\n\t\treturn this;\n\t}\n\n\tpublic use() {\n\t\tthis.dispose();\n\t\tthis.resolve();\n\t\treturn this;\n\t}\n\n\tpublic abort() {\n\t\tthis.dispose();\n\t\tthis.reject(new Error('Request aborted manually'));\n\t\treturn this;\n\t}\n\n\tprivate dispose() {\n\t\tif (this.signal) {\n\t\t\tthis.signal.removeEventListener('abort', this.signalListener!);\n\t\t\tthis.signal = null;\n\t\t\tthis.signalListener = null;\n\t\t}\n\t}\n}\n\ninterface PolyFillAbortSignal {\n\treadonly aborted: boolean;\n\taddEventListener(type: 'abort', listener: () => void): void;\n\tremoveEventListener(type: 'abort', listener: () => void): void;\n}\n","import { AsyncQueueEntry } from './AsyncQueueEntry';\n\n/**\n * The AsyncQueue class used to sequentialize burst requests\n */\nexport class AsyncQueue {\n\t/**\n\t * The amount of entries in the queue, including the head.\n\t * @seealso {@link queued} for the queued count.\n\t */\n\tpublic get remaining(): number {\n\t\treturn this.promises.length;\n\t}\n\n\t/**\n\t * The amount of queued entries.\n\t * @seealso {@link remaining} for the count with the head.\n\t */\n\tpublic get queued(): number {\n\t\treturn this.remaining === 0 ? 0 : this.remaining - 1;\n\t}\n\n\t/**\n\t * The promises array\n\t */\n\tprivate promises: AsyncQueueEntry[] = [];\n\n\t/**\n\t * Waits for last promise and queues a new one\n\t * @example\n\t * ```typescript\n\t * const queue = new AsyncQueue();\n\t * async function request(url, options) {\n\t * await queue.wait({ signal: options.signal });\n\t * try {\n\t * const result = await fetch(url, options);\n\t * // Do some operations with 'result'\n\t * } finally {\n\t * // Remove first entry from the queue and resolve for the next entry\n\t * queue.shift();\n\t * }\n\t * }\n\t *\n\t * request(someUrl1, someOptions1); // Will call fetch() immediately\n\t * request(someUrl2, someOptions2); // Will call fetch() after the first finished\n\t * request(someUrl3, someOptions3); // Will call fetch() after the second finished\n\t * ```\n\t */\n\tpublic wait(options?: Readonly<AsyncQueueWaitOptions>): Promise<void> {\n\t\tconst entry = new AsyncQueueEntry(this);\n\n\t\tif (this.promises.length === 0) {\n\t\t\tthis.promises.push(entry);\n\t\t\treturn Promise.resolve();\n\t\t}\n\n\t\tthis.promises.push(entry);\n\t\tif (options?.signal) entry.setSignal(options.signal);\n\t\treturn entry.promise;\n\t}\n\n\t/**\n\t * Unlocks the head lock and transfers the next lock (if any) to the head.\n\t */\n\tpublic shift(): void {\n\t\tif (this.promises.length === 0) return;\n\t\tif (this.promises.length === 1) {\n\t\t\t// Remove the head entry.\n\t\t\tthis.promises.shift();\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove the head entry, making the 2nd entry the new one.\n\t\t// Then use the head entry, which will unlock the promise.\n\t\tthis.promises.shift();\n\t\tthis.promises[0].use();\n\t}\n\n\t/**\n\t * Aborts all the pending promises.\n\t * @note To avoid race conditions, this does **not** unlock the head lock.\n\t */\n\tpublic abortAll(): void {\n\t\t// If there are no queued entries, skip early.\n\t\tif (this.queued === 0) return;\n\n\t\t// Abort all the entries except the head, that is why the loop starts at\n\t\t// 1 and not at 0.\n\t\tfor (let i = 1; i < this.promises.length; ++i) {\n\t\t\tthis.promises[i].abort();\n\t\t}\n\n\t\tthis.promises.length = 1;\n\t}\n}\n\nexport interface AsyncQueueWaitOptions {\n\tsignal?: AbortSignal | undefined | null;\n}\n"]}