├── .editorconfig
├── .github
├── pull_request_template.md
└── workflows
│ ├── lock.yml
│ └── publish.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── HISTORY.md
├── LICENSE.md
├── README.md
├── package-lock.json
├── package.json
└── spec.html
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | insert_final_newline = true
6 | trim_trailing_whitespace = true
7 | charset = utf-8
8 | indent_style = space
9 | indent_size = 2
10 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | Thank you for taking the time to contribute to this proposal!
2 | We’re so happy you’re helping out.
3 |
4 | 1. Please take a look at the [contributing guidelines][]
5 | and the resources to which it links.
6 | 2. Please include the purpose of the pull request. For example:
7 | * “This adds…”
8 | * “This simplifies…”
9 | * “This fixes…”
10 | 3. Please be explicit about what feedback, if any, you want:
11 | a quick pair of eyes, discussion or critique of its approach,
12 | a review of its copywriting, and so on.
13 | 4. Please mark the pull request as a Draft if it is still unfinished.
14 |
15 | All text in this repository is under the
16 | [same BSD license as Ecma-262][LICENSE.md].
17 | As is the norm in open source, by contributing to this GitHub repository,
18 | you are licensing your contribution under the same license,
19 | as per the
20 | [GitHub terms of service][ToS].
21 |
22 | [contributing guidelines]: https://github.com/tc39/proposal-pipeline-operator/blob/main/CONTRIBUTING.md
23 | [LICENSE.md]: https://github.com/tc39/proposal-pipeline-operator/blob/main/LICENSE.md
24 | [ToS]: https://help.github.com/en/github/site-policy/github-terms-of-service
25 |
--------------------------------------------------------------------------------
/.github/workflows/lock.yml:
--------------------------------------------------------------------------------
1 | name: 'Lock Threads'
2 |
3 | on:
4 | schedule:
5 | - cron: '0 0 * * *'
6 |
7 | workflow_dispatch:
8 |
9 | permissions:
10 | issues: write
11 | pull-requests: write
12 |
13 | concurrency:
14 | group: lock
15 |
16 | jobs:
17 | action:
18 | runs-on: ubuntu-latest
19 | steps:
20 | - uses: dessant/lock-threads@v2
21 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Build and Deploy to GitHub Pages
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | workflow_dispatch:
8 |
9 | jobs:
10 | build-and-deploy:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - name: Checkout 🛎️
14 | uses: actions/checkout@v2
15 | with:
16 | persist-credentials: false
17 |
18 | - name: Setup Node
19 | uses: actions/setup-node@v1
20 | with:
21 | node-version: '18'
22 |
23 | - name: Install and Build 🔧
24 | run: |
25 | npm install
26 | npm run build
27 |
28 | - name: Deploy 🚀
29 | uses: peaceiris/actions-gh-pages@v3
30 | with:
31 | github_token: ${{ secrets.GITHUB_TOKEN }}
32 | publish_dir: ./dist
33 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | dist
4 | npm-debug.log
5 | deploy_key
6 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of conduct
2 | This repository is a TC39 project, and it therefore subscribes to its [code of
3 | conduct][CoC]. It is available at .
4 |
5 | We all should strive here to be respectful, friendly and patient, inclusive,
6 | considerate, and careful in the words we choose. When we disagree, we should try
7 | to understand why.
8 |
9 | To ask a question or report an issue, please follow the [CoC]’s directions,
10 | e.g., emailing [tc39-conduct-reports@googlegroups.com][].
11 |
12 | More information about contributing is also available in [CONTRIBUTING.md][].
13 |
14 | [CoC]: https://tc39.es/code-of-conduct/
15 | [tc39-conduct-reports@googlegroups.com]: mailto:tc39-conduct-reports@googlegroups.com
16 | [CONTRIBUTING.md]: https://github.com/tc39/proposal-pipeline-operator/blob/main/CONTRIBUTING.md
17 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to this proposal
2 | First off, thank you for taking the time to contribute! 🎉
3 |
4 | Here are some suggestions to contributing to this proposal.
5 |
6 | 1. The general [TC39 Process][], which summarizes
7 | how TC39’s “consensus” and “Stages” work.
8 | 2. The guide on [contributing to TC39 proposals][contributing guide].
9 | 3. The [TC39 Code of Conduct][CoC]:
10 | It has important information about how we’re all expected to act
11 | and what to do when we feel like someone’s conduct does not meet the Code.
12 | We all want to maintain a friendly, productive working environment!
13 | 4. The [TC39 How to Give Feedback][feedback] article.
14 | 5. The [proposal explainer][] to make sure that it is
15 | not already addressed there.
16 | 6. The [TC39 Matrix guide][] (if you want to chat with TC39 members on Matrix,
17 | which is a real-time chat platform).
18 | 7. If the explainer does not already explain your topic adequately,
19 | then please [search the GitHub repository’s issues][issues]
20 | to see if any issues match the topic you had in mind.
21 | This proposal is more than four years old,
22 | and it is likely that the topic has already been raised and thoroughly discussed.
23 |
24 | You can leave a comment on an [existing GitHub issue][issues],
25 | create a new issue (but do try to [find an existing GitHub issue][issues] first),
26 | or [participate on Matrix][TC39 Matrix guide].
27 |
28 | Please try to keep any existing GitHub issues on their original topic.
29 |
30 | If you feel that someone’s conduct is not meeting the [TC39 Code of Conduct][CoC],
31 | whether in this GitHub repository or in a [TC39 Matrix room][TC39 Matrix guide],
32 | then please follow the [Code of Conduct][CoC]’s directions for reporting the violation,
33 | including emailing [tc39-conduct-reports@googlegroups.com][].
34 |
35 | Thank you again for taking the time to contribute!
36 |
37 | [CoC]: https://tc39.es/code-of-conduct/
38 | [TC39 process]: https://tc39.es/process-document/
39 | [contributing guide]: https://github.com/tc39/ecma262/blob/master/CONTRIBUTING.md#new-feature-proposals
40 | [feedback]: https://github.com/tc39/how-we-work/blob/master/feedback.md
41 | [proposal explainer]: https://github.com/tc39/proposal-array-from-async/blob/main/README.md
42 | [TC39 Matrix guide]: https://github.com/tc39/how-we-work/blob/master/matrix-guide.md
43 | [issues]: https://github.com/tc39/proposal-array-from-async/issues?q=is%3Aissue+
44 | [tc39-conduct-reports@googlegroups.com]: mailto:tc39-conduct-reports@googlegroups.com
45 |
--------------------------------------------------------------------------------
/HISTORY.md:
--------------------------------------------------------------------------------
1 | # 2021-08
2 | Presented to [plenary meeting for Stage 2 on 2021-08-31][2021-08-31]. Was accepted.
3 |
4 | # 2021-10
5 | Presented to [plenary meeting as an update on 2021-10-26][2021-10-26].
6 |
7 | # 2021-12
8 | Presented to [plenary meeting for Stage 2 on 2021-12-14][2021-12-14].
9 | Was rejected due to need to clarify `await`ing semantics
10 | with and without mapping-function arguments.
11 |
12 | # 2022-07
13 | Discussion occurred about `await`ing semantics and mapping functions in [issue
14 | #19][]. It was eventually decided to match `for await` and the proposed
15 | [AsyncIterator.prototype.toArray][iterator-helpers] by `await`ing values from
16 | input sync iterators once, `await`ing values from input async iterators not at
17 | all, and `await`ing results returned by mapping functions once.
18 |
19 | # 2022-09
20 | The [plenary advances this proposal to Stage 3][2022-09], conditional on editor review.
21 |
22 | # 2023-05
23 | The [plenary discusses double construction of the `this` value][2023-05] ([pull request #41][]) and resolves to merge the pull request that fixes it.
24 |
25 | [2021-08-31]: https://github.com/tc39/notes/blob/HEAD/meetings/2021-08/aug-31.md
26 | [2021-10-26]: https://github.com/tc39/notes/blob/HEAD/meetings/2021-10/oct-26.md#arrayfromasync-update
27 | [2021-12-14]: https://github.com/tc39/notes/blob/HEAD/meetings/2021-12/dec-14.md#arrayfromasync-for-stage-2
28 | [issue #19]: https://github.com/tc39/proposal-array-from-async/issues/19
29 | [iterator-helpers]: https://github.com/tc39/proposal-iterator-helpers
30 | [iterator-helpers#168]: https://github.com/tc39/proposal-iterator-helpers/issues/168
31 | [2022-09]: https://github.com/tc39/notes/blob/HEAD/meetings/2022-09/sep-14.md#conclusionresolution-1
32 | [2023-05]: https://github.com/tc39/notes/blob/main/meetings/2023-05/may-15.md#arrayfromasync-41-avoid-double-construction-of-this-value
33 | [pull request #41]: https://github.com/tc39/proposal-array-from-async/pull/41
34 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright 2021 J. S. Choi
2 |
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright
8 | notice, this list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder nor the names of its
15 | contributors may be used to endorse or promote products derived from
16 | this software without specific prior written permission.
17 |
18 | **This software is provided by the copyright holders and contributors
19 | “as is” and any express or implied warranties, including, but not
20 | limited to, the implied warranties of merchantability and fitness for a
21 | particular purpose are disclaimed. In no event shall the copyright
22 | holder or contributors be liable for any direct, indirect, incidental,
23 | special, exemplary, or consequential damages (including, but not limited
24 | to, procurement of substitute goods or services; loss of use, data, or
25 | profits; or business interruption) however caused and on any theory of
26 | liability, whether in contract, strict liability, or tort (including
27 | negligence or otherwise) arising in any way out of the use of this
28 | software, even if advised of the possibility of such damage.**
29 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Array.fromAsync for JavaScript
2 | ECMAScript Stage-3 (conditional on editor review) Proposal. J. S. Choi, 2021.
3 |
4 | * **[Specification][]** available
5 | * **Experimental polyfills** (do **not** use in production code yet):
6 | * **[array-from-async][]**
7 | * **[core-js][]**
8 |
9 | [specification]: https://tc39.es/proposal-array-from-async/
10 | [core-js]: https://github.com/zloirock/core-js#arrayfromasync
11 | [array-from-async]: https://www.npmjs.com/package/array-from-async
12 | [§ Errors]: #errors
13 | [§ Sync-iterable inputs]: #sync-iterable-inputs
14 |
15 | ## Why an Array.fromAsync method
16 | Since its standardization in JavaScript, **[Array.from][]** has become one of
17 | `Array`’s most frequently used built-in methods. However, no similar
18 | functionality exists for async iterators.
19 |
20 | ```js
21 | const arr = [];
22 | for (const v of iterable) {
23 | arr.push(v);
24 | }
25 |
26 | // This does the same thing.
27 | const arr = Array.from(iterable);
28 | ```
29 |
30 | [Array.from]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from
31 |
32 | Such functionality would also be useful for **dumping** the entirety of an
33 | **async iterator** into a **single data structure**, especially in **unit
34 | tests** or in **command-line** interfaces. (Several real-world examples are
35 | included in a following section.)
36 |
37 | ```js
38 | const arr = [];
39 | for await (const v of asyncIterable) {
40 | arr.push(v);
41 | }
42 |
43 | // We should add something that does the same thing.
44 | const arr = await ??????????(asyncIterable);
45 | ```
46 |
47 | There is an [it-all][] NPM library that performs only this task
48 | and which gets about 50,000 weekly downloads.
49 | This of course does **not** include any code
50 | that uses ad-hoc `for await`–`of` loops with empty arrays.
51 | Further demonstrating the demand for such functionality,
52 | several [Stack Overflow questions][Stack Overflow] have been asked
53 | by various developers, asking how to convert async iterators to arrays.
54 |
55 | There are several [real-world examples](#real-world-examples) listed
56 | later in this explainer.
57 |
58 | [it-all]: https://www.npmjs.com/package/it-all
59 | [Stack Overflow]: https://stackoverflow.com/questions/58668361/how-can-i-convert-an-async-iterator-to-an-array
60 |
61 | ## Description
62 | (A [formal draft specification][specification] is available.)
63 |
64 | **Array.fromAsync is to `for await`**\
65 | as **Array.from is to `for`.**
66 |
67 | Similarly to [Array.from][], Array.fromAsync would be a static method of the
68 | `Array` built-in class, with one required argument and two optional arguments:
69 | `(items, mapfn, thisArg)`.
70 |
71 | ### Async-iterable inputs
72 | But, instead of converting a sync iterable to an array, Array.fromAsync can
73 | convert an async iterable to a **promise** that (if everything goes well) will
74 | resolve to a new array. Before the promise resolves, it will create an async
75 | iterator from the input, lazily iterate over it, and add each yielded value to
76 | the new array. (The promise is immediately returned after the Array.fromAsync
77 | function call, no matter what.)
78 |
79 | ```js
80 | async function * asyncGen (n) {
81 | for (let i = 0; i < n; i++)
82 | yield i * 2;
83 | }
84 |
85 | // `arr` will be `[0, 2, 4, 6]`.
86 | const arr = [];
87 | for await (const v of asyncGen(4)) {
88 | arr.push(v);
89 | }
90 |
91 | // This is equivalent.
92 | const arr = await Array.fromAsync(asyncGen(4));
93 | ```
94 |
95 | ### Sync-iterable inputs
96 | If the argument is a sync iterable (and not an async iterable), then the return
97 | value is still a promise that will resolve to an array. If the sync iterator
98 | yields promises, then each yielded promise is awaited before its value is added
99 | to the new array. (Values that are not promises are also awaited to
100 | [prevent Zalgo][Zalgo].) All of this matches the behavior of `for await`.
101 |
102 | [Zalgo]: https://blog.izs.me/2013/08/designing-apis-for-asynchrony/
103 |
104 | ```js
105 | function * genPromises (n) {
106 | for (let i = 0; i < n; i++)
107 | yield Promise.resolve(i * 2);
108 | }
109 |
110 | // `arr` will be `[ 0, 2, 4, 6 ]`.
111 | const arr = [];
112 | for await (const v of genPromises(4)) {
113 | arr.push(v);
114 | }
115 |
116 | // This is equivalent.
117 | const arr = await Array.fromAsync(genPromises(4));
118 | ```
119 |
120 | Like `for await`, Array.fromAsync **lazily** iterates over a sync-but-not-async
121 | input. Whenever a developer needs to dump a synchronous input that yields
122 | promises into an array, the developer needs to choose carefully between
123 | Array.fromAsync and Promise.all, which have complementary control flows:
124 |
125 |
126 |
127 |
128 | |
129 | Parallel awaiting |
130 | Sequential awaiting |
131 |
132 |
133 |
134 |
135 | Lazy iteration |
136 | Impossible |
137 | await Array.fromAsync(input) |
138 |
139 |
140 | Eager iteration |
141 | await Promise.all(Array.from(input)) |
142 | Useless |
143 |
144 |
145 |
146 |
147 | Also like `for await`, when given a sync-but-not-async iterable input, then
148 | Array.fromAsync will catch **only** the first rejection that its iteration
149 | reaches, and only if that rejection does **not** occur in a microtask before
150 | the iteration reaches and awaits for it. For more information, see
151 | [§ Errors][].
152 |
153 | ```js
154 | // `arr` will be `[ 0, 2, 4, 6 ]`.
155 | // `genPromises(4)` is lazily iterated,
156 | // and its four yielded promises are awaited in sequence.
157 | const arr = await Array.fromAsync(genPromises(4));
158 |
159 | // `arr` will also be `[ 0, 2, 4, 6 ]`.
160 | // However, `genPromises(4)` is eagerly iterated
161 | // (into an array of four promises),
162 | // and the four promises are awaited in parallel.
163 | const arr = await Promise.all(Array.from(genPromises(4)));
164 | ```
165 |
166 | ### Non-iterable array-like inputs
167 | Array.fromAsync’s valid inputs are a superset of Array.from’s valid inputs.
168 | This includes non-iterable array-likes: objects that have a length property as
169 | well as indexed elements (similarly to Array.prototype.values). The return
170 | value is still a promise that will resolve to an array. If the array-like
171 | object’s elements are promises, then each accessed promise is awaited before
172 | its value is added to the new array.
173 |
174 | One [TC39 representative’s opinion][issue #7 comment]: “[Array-likes are] very
175 | much not obsolete, and it’s very nice that things aren’t forced to implement
176 | the iterator protocol to be transformable into an Array.”
177 |
178 | [issue #7 comment]: https://github.com/tc39/proposal-array-from-async/issues/7#issuecomment-920299880
179 |
180 | ```js
181 | const arrLike = {
182 | length: 4,
183 | 0: Promise.resolve(0),
184 | 1: Promise.resolve(2),
185 | 2: Promise.resolve(4),
186 | 3: Promise.resolve(6),
187 | }
188 |
189 | // `arr` will be `[ 0, 2, 4, 6 ]`.
190 | const arr = [];
191 | for await (const v of Array.from(arrLike)) {
192 | arr.push(v);
193 | }
194 |
195 | // This is equivalent.
196 | const arr = await Array.fromAsync(arrLike);
197 | ```
198 |
199 | As it does with sync-but-not-async iterable inputs, Array.fromAsync lazily
200 | iterates over the values of array-like inputs, and it awaits each value.
201 | The developer must choose between using Array.fromAsync and Promise.all (see
202 | [§ Sync-iterable inputs](#sync-iterable-inputs) and [§ Errors][]).
203 |
204 | ### Generic factory method
205 | Array.fromAsync is a generic factory method. It does not require that its this
206 | receiver be the Array constructor. fromAsync can be transferred to or inherited
207 | by any other constructor. In that case, the final result will be the data
208 | structure created by that constructor (with no arguments), and with each value
209 | yielded by the input being assigned to the data structure’s numeric properties.
210 | (Symbol.species is not involved at all.) If the this receiver is not a
211 | constructor, then fromAsync creates an array as usual. This matches the
212 | behavior of Array.from.
213 |
214 | ```js
215 | async function * asyncGen (n) {
216 | for (let i = 0; i < n; i++)
217 | yield i * 2;
218 | }
219 | function Data (n) {}
220 | Data.from = Array.from;
221 | Data.fromAsync = Array.fromAsync;
222 |
223 | // d will be a `new Data(0)`, with its `0` property assigned to `0`, its `1`
224 | // property assigned to `2`, etc.
225 | const d = new Data(0); let i = 0;
226 | for await (const v of asyncGen(4)) {
227 | d[i++] = v;
228 | }
229 |
230 | // This is equivalent.
231 | const d = await Data.fromAsync(asyncGen(4));
232 | ```
233 |
234 | ### Optional parameters
235 | Array.fromAsync has two optional parameters: `mapfn` and `thisArg`.
236 |
237 | #### Mapping function
238 | `mapfn` is an optional mapping callback, which is called on each value yielded from the input,
239 | along with its index integer (starting from 0).
240 | Each result of the mapping callback is, in turn, awaited then added to the array.
241 |
242 | However, when `mapfn` is given and the input is a sync iterable (or non-iterable array-like),
243 | then each value from the input is awaited before being given to `mapfn`.
244 | (The values from the input are *not* awaited if the input is an async iterable.)
245 | This matches the behavior of `for await`.
246 |
247 | When `mapfn` is not given, each value yielded from asynchronous
248 | inputs is not awaited, and each value yielded from synchronous inputs is
249 | awaited only once, before the value is added to the result array.
250 | This also matches the behavior of `for await`.
251 |
252 | This means that:
253 | ```js
254 | Array.fromAsync(input)
255 | ```
256 | …is not equivalent to:
257 | ```js
258 | Array.fromAsync(input, x => x)
259 | ```
260 | …at least when `input` is an async iterable.
261 |
262 | This is because, whenever input is an async iterable that yields promise items,
263 | `Array.fromAsync(input)` will not resolve those promise items,
264 | but `Array.fromAsync(input, x => x)` will resolve them
265 | because the result of the `x => x` mapping function is awaited.
266 |
267 | For example:
268 |
269 | ```js
270 | function createAsyncIter () {
271 | let i = 0;
272 | return {
273 | [Symbol.asyncIterator]() {
274 | return {
275 | async next() {
276 | if (i > 2) return { done: true };
277 | i++;
278 | return { value: Promise.resolve(i), done: false }
279 | }
280 | }
281 | }
282 | };
283 | }
284 |
285 | // This prints `[Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)]`:
286 | console.log(await Array.fromAsync(createAsyncIter()));
287 |
288 | // This prints `[1, 2, 3]`:
289 | console.log(await Array.fromAsync(createAsyncIter(), x => x));
290 | ```
291 |
292 | See also [issue #19](https://github.com/tc39/proposal-array-from-async/issues/19).
293 |
294 | #### `this` argument
295 | `thisArg` is a `this`-binding receiver value for the mapping callback. By
296 | default, this is undefined. These optional parameters match the behavior of
297 | Array.from. Their exclusion would be surprising to developers who are already
298 | used to Array.from.
299 |
300 | ```js
301 | async function * asyncGen (n) {
302 | for (let i = 0; i < n; i++)
303 | yield i * 2;
304 | }
305 |
306 | // `arr` will be `[ 0, 4, 16, 36 ]`.
307 | const arr = [];
308 | for await (const v of asyncGen(4)) {
309 | arr.push(await (v ** 2));
310 | }
311 |
312 | // This is equivalent.
313 | const arr = await Array.fromAsync(asyncGen(4), v =>
314 | v ** 2);
315 | ```
316 |
317 | ### Errors
318 | Like other promise-based APIs, Array.fromAsync will always immediately return a
319 | promise. Array.fromAsync will never synchronously throw an error and [summon
320 | Zalgo][Zalgo].
321 |
322 | When Array.fromAsync’s input throws an error while creating its async or sync
323 | iterator, then Array.fromAsync’s returned promise will reject with that error.
324 |
325 | ```js
326 | const err = new Error;
327 | const badIterable = { [Symbol.iterator] () { throw err; } };
328 |
329 | // This returns a promise that will reject with `err`.
330 | Array.fromAsync(badIterable);
331 | ```
332 |
333 | When Array.fromAsync’s input is iterable but the input’s iterator throws while
334 | iterating, then Array.fromAsync’s returned promise will reject with that error.
335 |
336 | ```js
337 | const err = new Error;
338 | async function * genErrorAsync () { throw err; }
339 |
340 | // This returns a promise that will reject with `err`.
341 | Array.fromAsync(genErrorAsync());
342 | ```
343 |
344 | ```js
345 | const err = new Error;
346 | function * genError () { throw err; }
347 |
348 | // This returns a promise that will reject with `err`.
349 | Array.fromAsync(genError());
350 | ```
351 |
352 | When Array.fromAsync’s input is synchronous only (i.e., the input is not an
353 | async iterable), and when one of the input’s values is a promise that
354 | eventually rejects or has rejected, then iteration stops and Array.fromAsync’s
355 | returned promise will reject with the first such error.
356 |
357 | In this case, Array.fromAsync will catch and handle that first input rejection
358 | **only if** that rejection does **not** occur in a microtask before the
359 | iteration reaches and awaits for it.
360 |
361 | ```js
362 | const err = new Error;
363 | function * genRejection () {
364 | yield Promise.reject(err);
365 | }
366 |
367 | // This returns a promise that will reject with `err`. There is **no**
368 | // unhandled promise rejection, because the rejection occurs in the same
369 | // microtask.
370 | Array.fromAsync(genZeroThenRejection());
371 | ```
372 |
373 | Just like with `for await`, Array.fromAsync will **not** catch any rejections
374 | by the input’s promises whenever those rejections occur **before** the ticks in
375 | which Array.fromAsync’s iteration reaches those promises.
376 |
377 | This is because – like `for await` – Array.fromAsync **lazily** iterates over
378 | its input and **sequentially** awaits each yielded value. Whenever a developer
379 | needs to dump a synchronous input that yields promises into an array, the
380 | developer needs to choose carefully between Array.fromAsync and Promise.all,
381 | which have complementary control flows (see [§ Sync-iterable
382 | inputs](#sync-iterable-inputs)).
383 |
384 | For example, when a synchronous input contains two promises, the latter of
385 | which will reject before the former promise resolves, then Array.fromAsync will
386 | not catch that rejection, because it lazily reaches the rejecting promise only
387 | after it already has rejected.
388 |
389 | ```js
390 | const numOfMillisecondsPerSecond = 1000;
391 | const slowError = new Error;
392 | const fastError = new Error;
393 |
394 | function waitThenReject (value) {
395 | return new Promise((resolve, reject) => {
396 | setTimeout(() => reject(value), numOfMillisecondsPerSecond);
397 | });
398 | }
399 |
400 | function * genRejections () {
401 | // Slow promise.
402 | yield waitAndReject(slowError);
403 | // Fast promise.
404 | yield Promise.reject(fastError);
405 | }
406 |
407 | // This returns a promise that will reject with `slowError`. There is **no**
408 | // unhandled promise rejection: the iteration is lazy and will stop early at the
409 | // slow promise, so the fast promise will never be created.
410 | Array.fromAsync(genSlowRejectThenFastReject());
411 |
412 | // This returns a promise that will reject with `slowError`. There **is** an
413 | // unhandled promise rejection with `fastError`: the iteration eagerly creates
414 | // and dumps both promises into an array, but Array.fromAsync will
415 | // **sequentially** handle only the slow promise.
416 | Array.fromAsync([ ...genSlowRejectThenFastReject() ]);
417 |
418 | // This returns a promise that will reject with `fastError`. There is **no**
419 | // unhandled promise rejection: the iteration eagerly creates and dumps both
420 | // promises into an array, but Promise.all will handle both promises **in
421 | // parallel**.
422 | Promise.all([ ...genSlowRejectThenFastReject() ]);
423 | ```
424 |
425 | When Array.fromAsync’s input has at least one value, and when Array.fromAsync’s
426 | mapping callback throws an error when given any of those values, then
427 | Array.fromAsync’s returned promise will reject with the first such error.
428 |
429 | ```js
430 | const err = new Error;
431 | function badCallback () { throw err; }
432 |
433 | // This returns a promise that will reject with `err`.
434 | Array.fromAsync([ 0 ], badCallback);
435 | ```
436 |
437 | When Array.fromAsync’s input is null or undefined, or when Array.fromAsync’s
438 | mapping callback is neither undefined nor callable, then Array.fromAsync’s
439 | returned promise will reject with a TypeError.
440 |
441 | ```js
442 | // These return promises that will reject with TypeErrors.
443 | Array.fromAsync(null);
444 | Array.fromAsync([], 1);
445 | ```
446 |
447 | ### Closing sync iterables?
448 | Array.fromAsync tries to match `for await`’s behavior as much as possible.
449 |
450 | Previously, `for await` did not close sync iterables when it
451 | yields a rejected promise.
452 |
453 |
454 | Old code example
455 |
456 | ```js
457 | function * createIter() {
458 | try {
459 | yield Promise.resolve(console.log("a"));
460 | yield Promise.reject("x");
461 | } finally {
462 | console.log("finalized");
463 | }
464 | }
465 |
466 | // Prints "a" and then prints "finalized".
467 | // There is an uncaught "x" rejection.
468 | for (const x of createIter()) {
469 | console.log(await x);
470 | }
471 |
472 | // Prints "a" and then prints "finalized".
473 | // There is an uncaught "x" rejection.
474 | Array.from(createIter());
475 |
476 | // Prints "a" and does *not* print "finalized".
477 | // There is an uncaught "x" rejection.
478 | for await (const x of createIter()) {
479 | console.log(x);
480 | }
481 |
482 | // Prints "a" and does *not* print "finalized".
483 | // There is an uncaught "x" rejection.
484 | Array.fromAsync(createIter());
485 | ```
486 |
487 |
488 |
489 | TC39 has recently changed `for await`’s behavior here.
490 | In the latest version of the language,
491 | `for await` now will close sync iterators when async wrappers yield rejections (see [tc39/ecma262#2600][]).
492 | All of the JavaScript engines are already updating to this new behavior.
493 |
494 | [tc39/ecma262#2600]: https://github.com/tc39/ecma262/pull/2600
495 |
496 | `Array.fromAsync` matches this new behavior of `for await`.
497 | Both will close any given sync iterator
498 | when the sync iterator yields a rejected promise as its next value.
499 |
500 | ## Other proposals
501 |
502 | ### Relationship with iterator-helpers
503 | The [iterator-helpers][] and [async-iterator-helpers][] proposals define
504 | Iterator.toArray and AsyncIterator.toArray. The following pairs of lines are
505 | equivalent:
506 |
507 | [iterator-helpers]: https://github.com/tc39/proposal-iterator-helpers
508 | [async-iterator-helpers]: https://github.com/tc39/proposal-async-iterator-helpers
509 |
510 | ```js
511 | // Array.from
512 |
513 | Array.from(iterable)
514 | Iterator(iterable).toArray()
515 |
516 | Array.from(iterable, mapfn)
517 | Iterator(iterable).map(mapfn).toArray()
518 |
519 | // Array.fromAsync
520 |
521 | Array.fromAsync(asyncIterable)
522 | AsyncIterator(asyncIterable).toArray()
523 |
524 | Array.fromAsync(asyncIterable, mapfn)
525 | AsyncIterator(asyncIterable).map(mapfn).toArray()
526 | ```
527 |
528 | Iterator.toArray overlaps with Array.from, and AsyncIterator.toArray overlaps
529 | with Array.fromAsync. This is okay: they all can coexist.
530 |
531 | A [co-champion of iterable-helpers agrees][tc39/proposal-iterator-helpers#156]
532 | that we should have both or that we should prefer Array.fromAsync: “I
533 | remembered why it’s better for a buildable structure to consume an iterable
534 | than for an iterable to consume a buildable protocol. Sometimes building
535 | something one element at a time is the same as building it [more than one]
536 | element at a time, but sometimes it could be slow to build that way or produce
537 | a structure with equivalent semantics but different performance properties.”
538 |
539 | [tc39/proposal-iterator-helpers#156]: https://github.com/tc39/proposal-iterator-helpers/issues/156.
540 |
541 | ### TypedArray.fromAsync, Set.fromAsync, Object.fromEntriesAsync, etc.
542 | The following built-ins also resemble Array.from:
543 | ```js
544 | TypedArray.from()
545 | new Set
546 | Object.fromEntries()
547 | new Map
548 | ```
549 | We are deferring any async versions of these methods to future proposals.
550 | See [issue #8][] and [proposal-setmap-offrom][].
551 |
552 | [issue #8]: https://github.com/tc39/proposal-array-from-async/issues/8
553 | [proposal-setmap-offrom]: https://github.com/tc39/proposal-setmap-offrom
554 |
555 | ### Async spread operator
556 | In the future, standardizing an async spread operator (like `[ 0, await ...v
557 | ]`) may be useful. This proposal leaves that idea to a **separate** proposal.
558 |
559 | ### Records and tuples
560 | The **[record/tuple] proposal** puts forward two new data types with APIs that
561 | respectively **resemble** those of **`Array` and `Object`**. The `Tuple`
562 | constructor, too, would probably need an `fromAsync` method. Whether the
563 | `Record` constructor gets a `fromEntriesAsync` method will depend on whether
564 | `Object.fromEntriesAsync` will also be added in a separate proposal.
565 |
566 | [record/tuple]: https://github.com/tc39/proposal-record-tuple
567 |
568 | ## Real-world examples
569 | Only minor formatting changes have been made to the status-quo examples.
570 |
571 |
572 |
573 |
574 | Status quo
575 | | With Array.fromAsync
576 |
577 | |
578 |
579 |
580 |
581 | ```js
582 | const all = require('it-all');
583 |
584 | // Add the default assets to the repo.
585 | const results = await all(
586 | addAll(
587 | globSource(initDocsPath, {
588 | recursive: true,
589 | }),
590 | { preload: false },
591 | ),
592 | );
593 | const dir = results
594 | .filter(file =>
595 | file.path === 'init-docs')
596 | .pop()
597 | print('to get started, enter:\n');
598 | print(
599 | `\tjsipfs cat` +
600 | `/ipfs/${dir.cid}/readme\n`,
601 | );
602 | ```
603 | From [ipfs-core/src/runtime/init-assets-nodejs.js][].
604 |
605 | |
606 |
607 | ```js
608 | // Add the default assets to the repo.
609 | const results = await Array.fromAsync(
610 | addAll(
611 | globSource(initDocsPath, {
612 | recursive: true,
613 | }),
614 | { preload: false },
615 | ),
616 | );
617 | const dir = results
618 | .filter(file =>
619 | file.path === 'init-docs')
620 | .pop()
621 | print('to get started, enter:\n');
622 | print(
623 | `\tjsipfs cat` +
624 | `/ipfs/${dir.cid}/readme\n`,
625 | );
626 | ```
627 |
628 | |
629 |
630 |
631 | ```js
632 | const all = require('it-all');
633 |
634 | const results = await all(
635 | node.contentRouting
636 | .findProviders('a cid'),
637 | );
638 | expect(results)
639 | .to.be.an('array')
640 | .with.lengthOf(1)
641 | .that.deep.equals([result]);
642 | ```
643 | From [js-libp2p/test/content-routing/content-routing.node.js][].
644 |
645 | |
646 |
647 | ```js
648 | const results = await Array.fromAsync(
649 | node.contentRouting
650 | .findProviders('a cid'),
651 | );
652 | expect(results)
653 | .to.be.an('array')
654 | .with.lengthOf(1)
655 | .that.deep.equals([result]);
656 | ```
657 |
658 | |
659 |
660 |
661 | ```js
662 | async function toArray(items) {
663 | const result = [];
664 | for await (const item of items) {
665 | result.push(item);
666 | }
667 | return result;
668 | }
669 |
670 | it('empty-pipeline', async () => {
671 | const pipeline = new Pipeline();
672 | const result = await toArray(
673 | pipeline.execute(
674 | [ 1, 2, 3, 4, 5 ]));
675 | assert.deepStrictEqual(
676 | result,
677 | [ 1, 2, 3, 4, 5 ],
678 | );
679 | });
680 | ```
681 |
682 | From [node-httptransfer/test/generator/pipeline.test.js][].
683 |
684 | |
685 |
686 | ```js
687 | it('empty-pipeline', async () => {
688 | const pipeline = new Pipeline();
689 | const result = await Array.fromAsync(
690 | pipeline.execute(
691 | [ 1, 2, 3, 4, 5 ]));
692 | assert.deepStrictEqual(
693 | result,
694 | [ 1, 2, 3, 4, 5 ],
695 | );
696 | });
697 | ```
698 |
699 | |
700 |
701 | [ipfs-core/src/runtime/init-assets-nodejs.js]: https://github.com/ipfs/js-ipfs/blob/release/v0.54.x/packages/ipfs-core/src/runtime/init-assets-nodejs.js
702 | [js-libp2p/test/content-routing/content-routing.node.js]: https://github.com/libp2p/js-libp2p/blob/13cf4761489d59b22924bb8ec2ec6dbe207b280c/test/content-routing/content-routing.node.js
703 | [node-httptransfer/test/generator/pipeline.test.js]: https://github.com/adobe/node-httptransfer/blob/22a32e72df89ce40e77a1dae5575a07654a0851f/test/generator/pipeline.test.js
704 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "proposal-array-from-async",
3 | "lockfileVersion": 3,
4 | "requires": true,
5 | "packages": {
6 | "": {
7 | "name": "proposal-array-from-async",
8 | "license": "BSD-3-Clause",
9 | "devDependencies": {
10 | "@tc39/ecma262-biblio": "2.1.2869",
11 | "ecmarkup": "^21.2.0"
12 | }
13 | },
14 | "node_modules/@asamuzakjp/css-color": {
15 | "version": "3.1.1",
16 | "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.1.1.tgz",
17 | "integrity": "sha512-hpRD68SV2OMcZCsrbdkccTw5FXjNDLo5OuqSHyHZfwweGsDWZwDJ2+gONyNAbazZclobMirACLw0lk8WVxIqxA==",
18 | "dev": true,
19 | "license": "MIT",
20 | "dependencies": {
21 | "@csstools/css-calc": "^2.1.2",
22 | "@csstools/css-color-parser": "^3.0.8",
23 | "@csstools/css-parser-algorithms": "^3.0.4",
24 | "@csstools/css-tokenizer": "^3.0.3",
25 | "lru-cache": "^10.4.3"
26 | }
27 | },
28 | "node_modules/@babel/code-frame": {
29 | "version": "7.12.11",
30 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
31 | "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==",
32 | "dev": true,
33 | "license": "MIT",
34 | "dependencies": {
35 | "@babel/highlight": "^7.10.4"
36 | }
37 | },
38 | "node_modules/@babel/helper-validator-identifier": {
39 | "version": "7.25.9",
40 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
41 | "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
42 | "dev": true,
43 | "license": "MIT",
44 | "engines": {
45 | "node": ">=6.9.0"
46 | }
47 | },
48 | "node_modules/@babel/highlight": {
49 | "version": "7.25.9",
50 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.9.tgz",
51 | "integrity": "sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==",
52 | "dev": true,
53 | "license": "MIT",
54 | "dependencies": {
55 | "@babel/helper-validator-identifier": "^7.25.9",
56 | "chalk": "^2.4.2",
57 | "js-tokens": "^4.0.0",
58 | "picocolors": "^1.0.0"
59 | },
60 | "engines": {
61 | "node": ">=6.9.0"
62 | }
63 | },
64 | "node_modules/@babel/highlight/node_modules/ansi-styles": {
65 | "version": "3.2.1",
66 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
67 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
68 | "dev": true,
69 | "license": "MIT",
70 | "dependencies": {
71 | "color-convert": "^1.9.0"
72 | },
73 | "engines": {
74 | "node": ">=4"
75 | }
76 | },
77 | "node_modules/@babel/highlight/node_modules/chalk": {
78 | "version": "2.4.2",
79 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
80 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
81 | "dev": true,
82 | "license": "MIT",
83 | "dependencies": {
84 | "ansi-styles": "^3.2.1",
85 | "escape-string-regexp": "^1.0.5",
86 | "supports-color": "^5.3.0"
87 | },
88 | "engines": {
89 | "node": ">=4"
90 | }
91 | },
92 | "node_modules/@babel/highlight/node_modules/color-convert": {
93 | "version": "1.9.3",
94 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
95 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
96 | "dev": true,
97 | "license": "MIT",
98 | "dependencies": {
99 | "color-name": "1.1.3"
100 | }
101 | },
102 | "node_modules/@babel/highlight/node_modules/color-name": {
103 | "version": "1.1.3",
104 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
105 | "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
106 | "dev": true,
107 | "license": "MIT"
108 | },
109 | "node_modules/@babel/highlight/node_modules/has-flag": {
110 | "version": "3.0.0",
111 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
112 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
113 | "dev": true,
114 | "license": "MIT",
115 | "engines": {
116 | "node": ">=4"
117 | }
118 | },
119 | "node_modules/@babel/highlight/node_modules/supports-color": {
120 | "version": "5.5.0",
121 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
122 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
123 | "dev": true,
124 | "license": "MIT",
125 | "dependencies": {
126 | "has-flag": "^3.0.0"
127 | },
128 | "engines": {
129 | "node": ">=4"
130 | }
131 | },
132 | "node_modules/@csstools/color-helpers": {
133 | "version": "5.0.2",
134 | "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz",
135 | "integrity": "sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==",
136 | "dev": true,
137 | "funding": [
138 | {
139 | "type": "github",
140 | "url": "https://github.com/sponsors/csstools"
141 | },
142 | {
143 | "type": "opencollective",
144 | "url": "https://opencollective.com/csstools"
145 | }
146 | ],
147 | "license": "MIT-0",
148 | "engines": {
149 | "node": ">=18"
150 | }
151 | },
152 | "node_modules/@csstools/css-calc": {
153 | "version": "2.1.2",
154 | "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.2.tgz",
155 | "integrity": "sha512-TklMyb3uBB28b5uQdxjReG4L80NxAqgrECqLZFQbyLekwwlcDDS8r3f07DKqeo8C4926Br0gf/ZDe17Zv4wIuw==",
156 | "dev": true,
157 | "funding": [
158 | {
159 | "type": "github",
160 | "url": "https://github.com/sponsors/csstools"
161 | },
162 | {
163 | "type": "opencollective",
164 | "url": "https://opencollective.com/csstools"
165 | }
166 | ],
167 | "license": "MIT",
168 | "engines": {
169 | "node": ">=18"
170 | },
171 | "peerDependencies": {
172 | "@csstools/css-parser-algorithms": "^3.0.4",
173 | "@csstools/css-tokenizer": "^3.0.3"
174 | }
175 | },
176 | "node_modules/@csstools/css-color-parser": {
177 | "version": "3.0.8",
178 | "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.8.tgz",
179 | "integrity": "sha512-pdwotQjCCnRPuNi06jFuP68cykU1f3ZWExLe/8MQ1LOs8Xq+fTkYgd+2V8mWUWMrOn9iS2HftPVaMZDaXzGbhQ==",
180 | "dev": true,
181 | "funding": [
182 | {
183 | "type": "github",
184 | "url": "https://github.com/sponsors/csstools"
185 | },
186 | {
187 | "type": "opencollective",
188 | "url": "https://opencollective.com/csstools"
189 | }
190 | ],
191 | "license": "MIT",
192 | "dependencies": {
193 | "@csstools/color-helpers": "^5.0.2",
194 | "@csstools/css-calc": "^2.1.2"
195 | },
196 | "engines": {
197 | "node": ">=18"
198 | },
199 | "peerDependencies": {
200 | "@csstools/css-parser-algorithms": "^3.0.4",
201 | "@csstools/css-tokenizer": "^3.0.3"
202 | }
203 | },
204 | "node_modules/@csstools/css-parser-algorithms": {
205 | "version": "3.0.4",
206 | "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz",
207 | "integrity": "sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==",
208 | "dev": true,
209 | "funding": [
210 | {
211 | "type": "github",
212 | "url": "https://github.com/sponsors/csstools"
213 | },
214 | {
215 | "type": "opencollective",
216 | "url": "https://opencollective.com/csstools"
217 | }
218 | ],
219 | "license": "MIT",
220 | "engines": {
221 | "node": ">=18"
222 | },
223 | "peerDependencies": {
224 | "@csstools/css-tokenizer": "^3.0.3"
225 | }
226 | },
227 | "node_modules/@csstools/css-tokenizer": {
228 | "version": "3.0.3",
229 | "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.3.tgz",
230 | "integrity": "sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==",
231 | "dev": true,
232 | "funding": [
233 | {
234 | "type": "github",
235 | "url": "https://github.com/sponsors/csstools"
236 | },
237 | {
238 | "type": "opencollective",
239 | "url": "https://opencollective.com/csstools"
240 | }
241 | ],
242 | "license": "MIT",
243 | "engines": {
244 | "node": ">=18"
245 | }
246 | },
247 | "node_modules/@esfx/async-canceltoken": {
248 | "version": "1.0.0",
249 | "resolved": "https://registry.npmjs.org/@esfx/async-canceltoken/-/async-canceltoken-1.0.0.tgz",
250 | "integrity": "sha512-3Ps/4NPd7qFltmHL+CYXCjZtNXcQGV9BZmpzu8Rt3/0SZMtbQve0gtX0uJDJGvAWa6w3IB4HrKVP12VPoFONmA==",
251 | "dev": true,
252 | "license": "Apache-2.0",
253 | "dependencies": {
254 | "@esfx/cancelable": "^1.0.0",
255 | "@esfx/canceltoken": "^1.0.0",
256 | "@esfx/disposable": "^1.0.0",
257 | "tslib": "^2.4.0"
258 | }
259 | },
260 | "node_modules/@esfx/cancelable": {
261 | "version": "1.0.0",
262 | "resolved": "https://registry.npmjs.org/@esfx/cancelable/-/cancelable-1.0.0.tgz",
263 | "integrity": "sha512-2dry/TuOT9ydpw86f396v09cyi/gLeGPIZSH4Gx+V/qKQaS/OXCRurCY+Cn8zkBfTAgFsjk9NE15d+LPo2kt9A==",
264 | "dev": true,
265 | "license": "Apache-2.0",
266 | "dependencies": {
267 | "@esfx/disposable": "^1.0.0"
268 | }
269 | },
270 | "node_modules/@esfx/canceltoken": {
271 | "version": "1.0.0",
272 | "resolved": "https://registry.npmjs.org/@esfx/canceltoken/-/canceltoken-1.0.0.tgz",
273 | "integrity": "sha512-/TgdzC5O89w5v0TgwE2wcdtampWNAFOxzurCtb4RxYVr3m72yk3Bg82vMdznx+H9nnf28zVDR0PtpZO9FxmOkw==",
274 | "dev": true,
275 | "license": "Apache-2.0",
276 | "dependencies": {
277 | "@esfx/cancelable": "^1.0.0",
278 | "@esfx/disposable": "^1.0.0",
279 | "tslib": "^2.4.0"
280 | }
281 | },
282 | "node_modules/@esfx/disposable": {
283 | "version": "1.0.0",
284 | "resolved": "https://registry.npmjs.org/@esfx/disposable/-/disposable-1.0.0.tgz",
285 | "integrity": "sha512-hu7EI+YxlEWEKrb2himbS13HNaq5mlUePASf99KeQqkiNeqiAZbKqG4w59uDcLZs8JrV3qJqS/NYib5ZMhbfTQ==",
286 | "dev": true,
287 | "license": "Apache-2.0"
288 | },
289 | "node_modules/@nodelib/fs.scandir": {
290 | "version": "2.1.5",
291 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
292 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
293 | "dev": true,
294 | "license": "MIT",
295 | "dependencies": {
296 | "@nodelib/fs.stat": "2.0.5",
297 | "run-parallel": "^1.1.9"
298 | },
299 | "engines": {
300 | "node": ">= 8"
301 | }
302 | },
303 | "node_modules/@nodelib/fs.stat": {
304 | "version": "2.0.5",
305 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
306 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
307 | "dev": true,
308 | "license": "MIT",
309 | "engines": {
310 | "node": ">= 8"
311 | }
312 | },
313 | "node_modules/@nodelib/fs.walk": {
314 | "version": "1.2.8",
315 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
316 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
317 | "dev": true,
318 | "license": "MIT",
319 | "dependencies": {
320 | "@nodelib/fs.scandir": "2.1.5",
321 | "fastq": "^1.6.0"
322 | },
323 | "engines": {
324 | "node": ">= 8"
325 | }
326 | },
327 | "node_modules/@tc39/ecma262-biblio": {
328 | "version": "2.1.2869",
329 | "resolved": "https://registry.npmjs.org/@tc39/ecma262-biblio/-/ecma262-biblio-2.1.2869.tgz",
330 | "integrity": "sha512-D1l255hoiQhXEt4vusbIcifdztz73gOPoSt/wKoBI5Ng+8y1G6ZrhgGbdbbGoigjicEEmvfBYzZUUBlPlHeGYg==",
331 | "dev": true,
332 | "license": "SEE LICENSE IN LICENSE.md"
333 | },
334 | "node_modules/agent-base": {
335 | "version": "7.1.3",
336 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
337 | "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
338 | "dev": true,
339 | "license": "MIT",
340 | "engines": {
341 | "node": ">= 14"
342 | }
343 | },
344 | "node_modules/ansi-styles": {
345 | "version": "4.3.0",
346 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
347 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
348 | "dev": true,
349 | "license": "MIT",
350 | "dependencies": {
351 | "color-convert": "^2.0.1"
352 | },
353 | "engines": {
354 | "node": ">=8"
355 | },
356 | "funding": {
357 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
358 | }
359 | },
360 | "node_modules/argparse": {
361 | "version": "1.0.10",
362 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
363 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
364 | "dev": true,
365 | "license": "MIT",
366 | "dependencies": {
367 | "sprintf-js": "~1.0.2"
368 | }
369 | },
370 | "node_modules/array-back": {
371 | "version": "3.1.0",
372 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
373 | "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
374 | "dev": true,
375 | "license": "MIT",
376 | "engines": {
377 | "node": ">=6"
378 | }
379 | },
380 | "node_modules/asynckit": {
381 | "version": "0.4.0",
382 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
383 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
384 | "dev": true,
385 | "license": "MIT"
386 | },
387 | "node_modules/braces": {
388 | "version": "3.0.3",
389 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
390 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
391 | "dev": true,
392 | "license": "MIT",
393 | "dependencies": {
394 | "fill-range": "^7.1.1"
395 | },
396 | "engines": {
397 | "node": ">=8"
398 | }
399 | },
400 | "node_modules/call-bind-apply-helpers": {
401 | "version": "1.0.2",
402 | "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
403 | "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
404 | "dev": true,
405 | "license": "MIT",
406 | "dependencies": {
407 | "es-errors": "^1.3.0",
408 | "function-bind": "^1.1.2"
409 | },
410 | "engines": {
411 | "node": ">= 0.4"
412 | }
413 | },
414 | "node_modules/chalk": {
415 | "version": "4.1.2",
416 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
417 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
418 | "dev": true,
419 | "license": "MIT",
420 | "dependencies": {
421 | "ansi-styles": "^4.1.0",
422 | "supports-color": "^7.1.0"
423 | },
424 | "engines": {
425 | "node": ">=10"
426 | },
427 | "funding": {
428 | "url": "https://github.com/chalk/chalk?sponsor=1"
429 | }
430 | },
431 | "node_modules/color-convert": {
432 | "version": "2.0.1",
433 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
434 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
435 | "dev": true,
436 | "license": "MIT",
437 | "dependencies": {
438 | "color-name": "~1.1.4"
439 | },
440 | "engines": {
441 | "node": ">=7.0.0"
442 | }
443 | },
444 | "node_modules/color-name": {
445 | "version": "1.1.4",
446 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
447 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
448 | "dev": true,
449 | "license": "MIT"
450 | },
451 | "node_modules/combined-stream": {
452 | "version": "1.0.8",
453 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
454 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
455 | "dev": true,
456 | "license": "MIT",
457 | "dependencies": {
458 | "delayed-stream": "~1.0.0"
459 | },
460 | "engines": {
461 | "node": ">= 0.8"
462 | }
463 | },
464 | "node_modules/command-line-args": {
465 | "version": "5.2.1",
466 | "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz",
467 | "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==",
468 | "dev": true,
469 | "license": "MIT",
470 | "dependencies": {
471 | "array-back": "^3.1.0",
472 | "find-replace": "^3.0.0",
473 | "lodash.camelcase": "^4.3.0",
474 | "typical": "^4.0.0"
475 | },
476 | "engines": {
477 | "node": ">=4.0.0"
478 | }
479 | },
480 | "node_modules/command-line-usage": {
481 | "version": "6.1.3",
482 | "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz",
483 | "integrity": "sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==",
484 | "dev": true,
485 | "license": "MIT",
486 | "dependencies": {
487 | "array-back": "^4.0.2",
488 | "chalk": "^2.4.2",
489 | "table-layout": "^1.0.2",
490 | "typical": "^5.2.0"
491 | },
492 | "engines": {
493 | "node": ">=8.0.0"
494 | }
495 | },
496 | "node_modules/command-line-usage/node_modules/ansi-styles": {
497 | "version": "3.2.1",
498 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
499 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
500 | "dev": true,
501 | "license": "MIT",
502 | "dependencies": {
503 | "color-convert": "^1.9.0"
504 | },
505 | "engines": {
506 | "node": ">=4"
507 | }
508 | },
509 | "node_modules/command-line-usage/node_modules/array-back": {
510 | "version": "4.0.2",
511 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz",
512 | "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==",
513 | "dev": true,
514 | "license": "MIT",
515 | "engines": {
516 | "node": ">=8"
517 | }
518 | },
519 | "node_modules/command-line-usage/node_modules/chalk": {
520 | "version": "2.4.2",
521 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
522 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
523 | "dev": true,
524 | "license": "MIT",
525 | "dependencies": {
526 | "ansi-styles": "^3.2.1",
527 | "escape-string-regexp": "^1.0.5",
528 | "supports-color": "^5.3.0"
529 | },
530 | "engines": {
531 | "node": ">=4"
532 | }
533 | },
534 | "node_modules/command-line-usage/node_modules/color-convert": {
535 | "version": "1.9.3",
536 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
537 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
538 | "dev": true,
539 | "license": "MIT",
540 | "dependencies": {
541 | "color-name": "1.1.3"
542 | }
543 | },
544 | "node_modules/command-line-usage/node_modules/color-name": {
545 | "version": "1.1.3",
546 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
547 | "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
548 | "dev": true,
549 | "license": "MIT"
550 | },
551 | "node_modules/command-line-usage/node_modules/has-flag": {
552 | "version": "3.0.0",
553 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
554 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
555 | "dev": true,
556 | "license": "MIT",
557 | "engines": {
558 | "node": ">=4"
559 | }
560 | },
561 | "node_modules/command-line-usage/node_modules/supports-color": {
562 | "version": "5.5.0",
563 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
564 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
565 | "dev": true,
566 | "license": "MIT",
567 | "dependencies": {
568 | "has-flag": "^3.0.0"
569 | },
570 | "engines": {
571 | "node": ">=4"
572 | }
573 | },
574 | "node_modules/command-line-usage/node_modules/typical": {
575 | "version": "5.2.0",
576 | "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz",
577 | "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==",
578 | "dev": true,
579 | "license": "MIT",
580 | "engines": {
581 | "node": ">=8"
582 | }
583 | },
584 | "node_modules/cssstyle": {
585 | "version": "4.3.0",
586 | "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.3.0.tgz",
587 | "integrity": "sha512-6r0NiY0xizYqfBvWp1G7WXJ06/bZyrk7Dc6PHql82C/pKGUTKu4yAX4Y8JPamb1ob9nBKuxWzCGTRuGwU3yxJQ==",
588 | "dev": true,
589 | "license": "MIT",
590 | "dependencies": {
591 | "@asamuzakjp/css-color": "^3.1.1",
592 | "rrweb-cssom": "^0.8.0"
593 | },
594 | "engines": {
595 | "node": ">=18"
596 | }
597 | },
598 | "node_modules/cssstyle/node_modules/rrweb-cssom": {
599 | "version": "0.8.0",
600 | "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz",
601 | "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==",
602 | "dev": true,
603 | "license": "MIT"
604 | },
605 | "node_modules/data-urls": {
606 | "version": "5.0.0",
607 | "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz",
608 | "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==",
609 | "dev": true,
610 | "license": "MIT",
611 | "dependencies": {
612 | "whatwg-mimetype": "^4.0.0",
613 | "whatwg-url": "^14.0.0"
614 | },
615 | "engines": {
616 | "node": ">=18"
617 | }
618 | },
619 | "node_modules/debug": {
620 | "version": "4.4.0",
621 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
622 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
623 | "dev": true,
624 | "license": "MIT",
625 | "dependencies": {
626 | "ms": "^2.1.3"
627 | },
628 | "engines": {
629 | "node": ">=6.0"
630 | },
631 | "peerDependenciesMeta": {
632 | "supports-color": {
633 | "optional": true
634 | }
635 | }
636 | },
637 | "node_modules/decimal.js": {
638 | "version": "10.5.0",
639 | "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz",
640 | "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==",
641 | "dev": true,
642 | "license": "MIT"
643 | },
644 | "node_modules/dedent-js": {
645 | "version": "1.0.1",
646 | "resolved": "https://registry.npmjs.org/dedent-js/-/dedent-js-1.0.1.tgz",
647 | "integrity": "sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ==",
648 | "dev": true,
649 | "license": "MIT"
650 | },
651 | "node_modules/deep-extend": {
652 | "version": "0.6.0",
653 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
654 | "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
655 | "dev": true,
656 | "license": "MIT",
657 | "engines": {
658 | "node": ">=4.0.0"
659 | }
660 | },
661 | "node_modules/delayed-stream": {
662 | "version": "1.0.0",
663 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
664 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
665 | "dev": true,
666 | "license": "MIT",
667 | "engines": {
668 | "node": ">=0.4.0"
669 | }
670 | },
671 | "node_modules/dunder-proto": {
672 | "version": "1.0.1",
673 | "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
674 | "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
675 | "dev": true,
676 | "license": "MIT",
677 | "dependencies": {
678 | "call-bind-apply-helpers": "^1.0.1",
679 | "es-errors": "^1.3.0",
680 | "gopd": "^1.2.0"
681 | },
682 | "engines": {
683 | "node": ">= 0.4"
684 | }
685 | },
686 | "node_modules/ecmarkdown": {
687 | "version": "8.1.0",
688 | "resolved": "https://registry.npmjs.org/ecmarkdown/-/ecmarkdown-8.1.0.tgz",
689 | "integrity": "sha512-dx6cM6RFjzAXkWr2KQRikED4gy70NFQ0vTI4XUQM/LWcjUYRJUbGdd7nd++trXi5az1JSe49TeeCIVMKDXOtcQ==",
690 | "dev": true,
691 | "license": "WTFPL",
692 | "dependencies": {
693 | "escape-html": "^1.0.1"
694 | }
695 | },
696 | "node_modules/ecmarkup": {
697 | "version": "21.2.0",
698 | "resolved": "https://registry.npmjs.org/ecmarkup/-/ecmarkup-21.2.0.tgz",
699 | "integrity": "sha512-d7FvzQiPGYVukzyd8z4a9HxjEPxi4X1u0VhETSCcLudzc5T8aGmJBw0wNGlf+sekfpFy6SJC9Nco/Fn8I09FHg==",
700 | "dev": true,
701 | "license": "MIT",
702 | "dependencies": {
703 | "chalk": "^4.1.2",
704 | "command-line-args": "^5.2.0",
705 | "command-line-usage": "^6.1.1",
706 | "dedent-js": "^1.0.1",
707 | "ecmarkdown": "^8.1.0",
708 | "eslint-formatter-codeframe": "^7.32.1",
709 | "fast-glob": "^3.2.7",
710 | "grammarkdown": "^3.3.2",
711 | "highlight.js": "11.0.1",
712 | "html-escape": "^1.0.2",
713 | "js-yaml": "^3.13.1",
714 | "jsdom": "^25.0.1",
715 | "nwsapi": "2.2.0",
716 | "parse5": "^6.0.1",
717 | "prex": "^0.4.7",
718 | "promise-debounce": "^1.0.1"
719 | },
720 | "bin": {
721 | "ecmarkup": "bin/ecmarkup.js",
722 | "emu-format": "bin/emu-format.js"
723 | },
724 | "engines": {
725 | "node": ">= 18"
726 | }
727 | },
728 | "node_modules/entities": {
729 | "version": "4.5.0",
730 | "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
731 | "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
732 | "dev": true,
733 | "license": "BSD-2-Clause",
734 | "engines": {
735 | "node": ">=0.12"
736 | },
737 | "funding": {
738 | "url": "https://github.com/fb55/entities?sponsor=1"
739 | }
740 | },
741 | "node_modules/es-define-property": {
742 | "version": "1.0.1",
743 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
744 | "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
745 | "dev": true,
746 | "license": "MIT",
747 | "engines": {
748 | "node": ">= 0.4"
749 | }
750 | },
751 | "node_modules/es-errors": {
752 | "version": "1.3.0",
753 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
754 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
755 | "dev": true,
756 | "license": "MIT",
757 | "engines": {
758 | "node": ">= 0.4"
759 | }
760 | },
761 | "node_modules/es-object-atoms": {
762 | "version": "1.1.1",
763 | "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
764 | "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
765 | "dev": true,
766 | "license": "MIT",
767 | "dependencies": {
768 | "es-errors": "^1.3.0"
769 | },
770 | "engines": {
771 | "node": ">= 0.4"
772 | }
773 | },
774 | "node_modules/es-set-tostringtag": {
775 | "version": "2.1.0",
776 | "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
777 | "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
778 | "dev": true,
779 | "license": "MIT",
780 | "dependencies": {
781 | "es-errors": "^1.3.0",
782 | "get-intrinsic": "^1.2.6",
783 | "has-tostringtag": "^1.0.2",
784 | "hasown": "^2.0.2"
785 | },
786 | "engines": {
787 | "node": ">= 0.4"
788 | }
789 | },
790 | "node_modules/escape-html": {
791 | "version": "1.0.3",
792 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
793 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
794 | "dev": true,
795 | "license": "MIT"
796 | },
797 | "node_modules/escape-string-regexp": {
798 | "version": "1.0.5",
799 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
800 | "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
801 | "dev": true,
802 | "license": "MIT",
803 | "engines": {
804 | "node": ">=0.8.0"
805 | }
806 | },
807 | "node_modules/eslint-formatter-codeframe": {
808 | "version": "7.32.1",
809 | "resolved": "https://registry.npmjs.org/eslint-formatter-codeframe/-/eslint-formatter-codeframe-7.32.1.tgz",
810 | "integrity": "sha512-DK/3Q3+zVKq/7PdSYiCxPrsDF8H/TRMK5n8Hziwr4IMkMy+XiKSwbpj25AdajS63I/B61Snetq4uVvX9fOLyAg==",
811 | "dev": true,
812 | "license": "MIT",
813 | "dependencies": {
814 | "@babel/code-frame": "7.12.11",
815 | "chalk": "^4.0.0"
816 | },
817 | "engines": {
818 | "node": "^10.12.0 || >=12.0.0"
819 | }
820 | },
821 | "node_modules/esprima": {
822 | "version": "4.0.1",
823 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
824 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
825 | "dev": true,
826 | "license": "BSD-2-Clause",
827 | "bin": {
828 | "esparse": "bin/esparse.js",
829 | "esvalidate": "bin/esvalidate.js"
830 | },
831 | "engines": {
832 | "node": ">=4"
833 | }
834 | },
835 | "node_modules/fast-glob": {
836 | "version": "3.3.3",
837 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
838 | "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
839 | "dev": true,
840 | "license": "MIT",
841 | "dependencies": {
842 | "@nodelib/fs.stat": "^2.0.2",
843 | "@nodelib/fs.walk": "^1.2.3",
844 | "glob-parent": "^5.1.2",
845 | "merge2": "^1.3.0",
846 | "micromatch": "^4.0.8"
847 | },
848 | "engines": {
849 | "node": ">=8.6.0"
850 | }
851 | },
852 | "node_modules/fastq": {
853 | "version": "1.19.1",
854 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
855 | "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
856 | "dev": true,
857 | "license": "ISC",
858 | "dependencies": {
859 | "reusify": "^1.0.4"
860 | }
861 | },
862 | "node_modules/fill-range": {
863 | "version": "7.1.1",
864 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
865 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
866 | "dev": true,
867 | "license": "MIT",
868 | "dependencies": {
869 | "to-regex-range": "^5.0.1"
870 | },
871 | "engines": {
872 | "node": ">=8"
873 | }
874 | },
875 | "node_modules/find-replace": {
876 | "version": "3.0.0",
877 | "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz",
878 | "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==",
879 | "dev": true,
880 | "license": "MIT",
881 | "dependencies": {
882 | "array-back": "^3.0.1"
883 | },
884 | "engines": {
885 | "node": ">=4.0.0"
886 | }
887 | },
888 | "node_modules/form-data": {
889 | "version": "4.0.2",
890 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz",
891 | "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==",
892 | "dev": true,
893 | "license": "MIT",
894 | "dependencies": {
895 | "asynckit": "^0.4.0",
896 | "combined-stream": "^1.0.8",
897 | "es-set-tostringtag": "^2.1.0",
898 | "mime-types": "^2.1.12"
899 | },
900 | "engines": {
901 | "node": ">= 6"
902 | }
903 | },
904 | "node_modules/function-bind": {
905 | "version": "1.1.2",
906 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
907 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
908 | "dev": true,
909 | "license": "MIT",
910 | "funding": {
911 | "url": "https://github.com/sponsors/ljharb"
912 | }
913 | },
914 | "node_modules/get-intrinsic": {
915 | "version": "1.3.0",
916 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
917 | "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
918 | "dev": true,
919 | "license": "MIT",
920 | "dependencies": {
921 | "call-bind-apply-helpers": "^1.0.2",
922 | "es-define-property": "^1.0.1",
923 | "es-errors": "^1.3.0",
924 | "es-object-atoms": "^1.1.1",
925 | "function-bind": "^1.1.2",
926 | "get-proto": "^1.0.1",
927 | "gopd": "^1.2.0",
928 | "has-symbols": "^1.1.0",
929 | "hasown": "^2.0.2",
930 | "math-intrinsics": "^1.1.0"
931 | },
932 | "engines": {
933 | "node": ">= 0.4"
934 | },
935 | "funding": {
936 | "url": "https://github.com/sponsors/ljharb"
937 | }
938 | },
939 | "node_modules/get-proto": {
940 | "version": "1.0.1",
941 | "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
942 | "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
943 | "dev": true,
944 | "license": "MIT",
945 | "dependencies": {
946 | "dunder-proto": "^1.0.1",
947 | "es-object-atoms": "^1.0.0"
948 | },
949 | "engines": {
950 | "node": ">= 0.4"
951 | }
952 | },
953 | "node_modules/glob-parent": {
954 | "version": "5.1.2",
955 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
956 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
957 | "dev": true,
958 | "license": "ISC",
959 | "dependencies": {
960 | "is-glob": "^4.0.1"
961 | },
962 | "engines": {
963 | "node": ">= 6"
964 | }
965 | },
966 | "node_modules/gopd": {
967 | "version": "1.2.0",
968 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
969 | "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
970 | "dev": true,
971 | "license": "MIT",
972 | "engines": {
973 | "node": ">= 0.4"
974 | },
975 | "funding": {
976 | "url": "https://github.com/sponsors/ljharb"
977 | }
978 | },
979 | "node_modules/grammarkdown": {
980 | "version": "3.3.2",
981 | "resolved": "https://registry.npmjs.org/grammarkdown/-/grammarkdown-3.3.2.tgz",
982 | "integrity": "sha512-inNbeEotDr7MENqoZlms3x4gBzvK73wR2NGpNVnw4oEZcsq2METUbAh0J3VWtEqd9t2+U3poEqiJ9CDgBXr5Tg==",
983 | "dev": true,
984 | "license": "MIT",
985 | "dependencies": {
986 | "@esfx/async-canceltoken": "^1.0.0-pre.13",
987 | "@esfx/cancelable": "^1.0.0-pre.13",
988 | "@esfx/disposable": "^1.0.0-pre.13"
989 | },
990 | "bin": {
991 | "grammarkdown": "bin/grammarkdown"
992 | }
993 | },
994 | "node_modules/has-flag": {
995 | "version": "4.0.0",
996 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
997 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
998 | "dev": true,
999 | "license": "MIT",
1000 | "engines": {
1001 | "node": ">=8"
1002 | }
1003 | },
1004 | "node_modules/has-symbols": {
1005 | "version": "1.1.0",
1006 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
1007 | "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
1008 | "dev": true,
1009 | "license": "MIT",
1010 | "engines": {
1011 | "node": ">= 0.4"
1012 | },
1013 | "funding": {
1014 | "url": "https://github.com/sponsors/ljharb"
1015 | }
1016 | },
1017 | "node_modules/has-tostringtag": {
1018 | "version": "1.0.2",
1019 | "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
1020 | "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
1021 | "dev": true,
1022 | "license": "MIT",
1023 | "dependencies": {
1024 | "has-symbols": "^1.0.3"
1025 | },
1026 | "engines": {
1027 | "node": ">= 0.4"
1028 | },
1029 | "funding": {
1030 | "url": "https://github.com/sponsors/ljharb"
1031 | }
1032 | },
1033 | "node_modules/hasown": {
1034 | "version": "2.0.2",
1035 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
1036 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
1037 | "dev": true,
1038 | "license": "MIT",
1039 | "dependencies": {
1040 | "function-bind": "^1.1.2"
1041 | },
1042 | "engines": {
1043 | "node": ">= 0.4"
1044 | }
1045 | },
1046 | "node_modules/highlight.js": {
1047 | "version": "11.0.1",
1048 | "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.0.1.tgz",
1049 | "integrity": "sha512-EqYpWyTF2s8nMfttfBA2yLKPNoZCO33pLS4MnbXQ4hECf1TKujCt1Kq7QAdrio7roL4+CqsfjqwYj4tYgq0pJQ==",
1050 | "dev": true,
1051 | "license": "BSD-3-Clause",
1052 | "engines": {
1053 | "node": ">=12.0.0"
1054 | }
1055 | },
1056 | "node_modules/html-encoding-sniffer": {
1057 | "version": "4.0.0",
1058 | "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz",
1059 | "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==",
1060 | "dev": true,
1061 | "license": "MIT",
1062 | "dependencies": {
1063 | "whatwg-encoding": "^3.1.1"
1064 | },
1065 | "engines": {
1066 | "node": ">=18"
1067 | }
1068 | },
1069 | "node_modules/html-escape": {
1070 | "version": "1.0.2",
1071 | "resolved": "https://registry.npmjs.org/html-escape/-/html-escape-1.0.2.tgz",
1072 | "integrity": "sha512-r4cqVc7QAX1/jpPsW9OJNsTTtFhcf+ZBqoA3rWOddMg/y+n6ElKfz+IGKbvV2RTeECDzyrQXa2rpo3IFFrANWg==",
1073 | "dev": true,
1074 | "license": "Public Domain"
1075 | },
1076 | "node_modules/http-proxy-agent": {
1077 | "version": "7.0.2",
1078 | "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
1079 | "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
1080 | "dev": true,
1081 | "license": "MIT",
1082 | "dependencies": {
1083 | "agent-base": "^7.1.0",
1084 | "debug": "^4.3.4"
1085 | },
1086 | "engines": {
1087 | "node": ">= 14"
1088 | }
1089 | },
1090 | "node_modules/https-proxy-agent": {
1091 | "version": "7.0.6",
1092 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
1093 | "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
1094 | "dev": true,
1095 | "license": "MIT",
1096 | "dependencies": {
1097 | "agent-base": "^7.1.2",
1098 | "debug": "4"
1099 | },
1100 | "engines": {
1101 | "node": ">= 14"
1102 | }
1103 | },
1104 | "node_modules/iconv-lite": {
1105 | "version": "0.6.3",
1106 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
1107 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
1108 | "dev": true,
1109 | "license": "MIT",
1110 | "dependencies": {
1111 | "safer-buffer": ">= 2.1.2 < 3.0.0"
1112 | },
1113 | "engines": {
1114 | "node": ">=0.10.0"
1115 | }
1116 | },
1117 | "node_modules/is-extglob": {
1118 | "version": "2.1.1",
1119 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
1120 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
1121 | "dev": true,
1122 | "license": "MIT",
1123 | "engines": {
1124 | "node": ">=0.10.0"
1125 | }
1126 | },
1127 | "node_modules/is-glob": {
1128 | "version": "4.0.3",
1129 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
1130 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
1131 | "dev": true,
1132 | "license": "MIT",
1133 | "dependencies": {
1134 | "is-extglob": "^2.1.1"
1135 | },
1136 | "engines": {
1137 | "node": ">=0.10.0"
1138 | }
1139 | },
1140 | "node_modules/is-number": {
1141 | "version": "7.0.0",
1142 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
1143 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
1144 | "dev": true,
1145 | "license": "MIT",
1146 | "engines": {
1147 | "node": ">=0.12.0"
1148 | }
1149 | },
1150 | "node_modules/is-potential-custom-element-name": {
1151 | "version": "1.0.1",
1152 | "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
1153 | "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
1154 | "dev": true,
1155 | "license": "MIT"
1156 | },
1157 | "node_modules/js-tokens": {
1158 | "version": "4.0.0",
1159 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
1160 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
1161 | "dev": true,
1162 | "license": "MIT"
1163 | },
1164 | "node_modules/js-yaml": {
1165 | "version": "3.14.1",
1166 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
1167 | "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
1168 | "dev": true,
1169 | "license": "MIT",
1170 | "dependencies": {
1171 | "argparse": "^1.0.7",
1172 | "esprima": "^4.0.0"
1173 | },
1174 | "bin": {
1175 | "js-yaml": "bin/js-yaml.js"
1176 | }
1177 | },
1178 | "node_modules/jsdom": {
1179 | "version": "25.0.1",
1180 | "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz",
1181 | "integrity": "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==",
1182 | "dev": true,
1183 | "license": "MIT",
1184 | "dependencies": {
1185 | "cssstyle": "^4.1.0",
1186 | "data-urls": "^5.0.0",
1187 | "decimal.js": "^10.4.3",
1188 | "form-data": "^4.0.0",
1189 | "html-encoding-sniffer": "^4.0.0",
1190 | "http-proxy-agent": "^7.0.2",
1191 | "https-proxy-agent": "^7.0.5",
1192 | "is-potential-custom-element-name": "^1.0.1",
1193 | "nwsapi": "^2.2.12",
1194 | "parse5": "^7.1.2",
1195 | "rrweb-cssom": "^0.7.1",
1196 | "saxes": "^6.0.0",
1197 | "symbol-tree": "^3.2.4",
1198 | "tough-cookie": "^5.0.0",
1199 | "w3c-xmlserializer": "^5.0.0",
1200 | "webidl-conversions": "^7.0.0",
1201 | "whatwg-encoding": "^3.1.1",
1202 | "whatwg-mimetype": "^4.0.0",
1203 | "whatwg-url": "^14.0.0",
1204 | "ws": "^8.18.0",
1205 | "xml-name-validator": "^5.0.0"
1206 | },
1207 | "engines": {
1208 | "node": ">=18"
1209 | },
1210 | "peerDependencies": {
1211 | "canvas": "^2.11.2"
1212 | },
1213 | "peerDependenciesMeta": {
1214 | "canvas": {
1215 | "optional": true
1216 | }
1217 | }
1218 | },
1219 | "node_modules/jsdom/node_modules/nwsapi": {
1220 | "version": "2.2.20",
1221 | "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.20.tgz",
1222 | "integrity": "sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==",
1223 | "dev": true,
1224 | "license": "MIT"
1225 | },
1226 | "node_modules/jsdom/node_modules/parse5": {
1227 | "version": "7.2.1",
1228 | "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz",
1229 | "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==",
1230 | "dev": true,
1231 | "license": "MIT",
1232 | "dependencies": {
1233 | "entities": "^4.5.0"
1234 | },
1235 | "funding": {
1236 | "url": "https://github.com/inikulin/parse5?sponsor=1"
1237 | }
1238 | },
1239 | "node_modules/lodash.camelcase": {
1240 | "version": "4.3.0",
1241 | "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
1242 | "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
1243 | "dev": true,
1244 | "license": "MIT"
1245 | },
1246 | "node_modules/lru-cache": {
1247 | "version": "10.4.3",
1248 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
1249 | "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
1250 | "dev": true,
1251 | "license": "ISC"
1252 | },
1253 | "node_modules/math-intrinsics": {
1254 | "version": "1.1.0",
1255 | "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
1256 | "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
1257 | "dev": true,
1258 | "license": "MIT",
1259 | "engines": {
1260 | "node": ">= 0.4"
1261 | }
1262 | },
1263 | "node_modules/merge2": {
1264 | "version": "1.4.1",
1265 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
1266 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
1267 | "dev": true,
1268 | "license": "MIT",
1269 | "engines": {
1270 | "node": ">= 8"
1271 | }
1272 | },
1273 | "node_modules/micromatch": {
1274 | "version": "4.0.8",
1275 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
1276 | "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
1277 | "dev": true,
1278 | "license": "MIT",
1279 | "dependencies": {
1280 | "braces": "^3.0.3",
1281 | "picomatch": "^2.3.1"
1282 | },
1283 | "engines": {
1284 | "node": ">=8.6"
1285 | }
1286 | },
1287 | "node_modules/mime-db": {
1288 | "version": "1.52.0",
1289 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
1290 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
1291 | "dev": true,
1292 | "license": "MIT",
1293 | "engines": {
1294 | "node": ">= 0.6"
1295 | }
1296 | },
1297 | "node_modules/mime-types": {
1298 | "version": "2.1.35",
1299 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
1300 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
1301 | "dev": true,
1302 | "license": "MIT",
1303 | "dependencies": {
1304 | "mime-db": "1.52.0"
1305 | },
1306 | "engines": {
1307 | "node": ">= 0.6"
1308 | }
1309 | },
1310 | "node_modules/ms": {
1311 | "version": "2.1.3",
1312 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1313 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
1314 | "dev": true,
1315 | "license": "MIT"
1316 | },
1317 | "node_modules/nwsapi": {
1318 | "version": "2.2.0",
1319 | "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
1320 | "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==",
1321 | "dev": true,
1322 | "license": "MIT"
1323 | },
1324 | "node_modules/parse5": {
1325 | "version": "6.0.1",
1326 | "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
1327 | "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
1328 | "dev": true,
1329 | "license": "MIT"
1330 | },
1331 | "node_modules/picocolors": {
1332 | "version": "1.1.1",
1333 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
1334 | "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
1335 | "dev": true,
1336 | "license": "ISC"
1337 | },
1338 | "node_modules/picomatch": {
1339 | "version": "2.3.1",
1340 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
1341 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
1342 | "dev": true,
1343 | "license": "MIT",
1344 | "engines": {
1345 | "node": ">=8.6"
1346 | },
1347 | "funding": {
1348 | "url": "https://github.com/sponsors/jonschlinkert"
1349 | }
1350 | },
1351 | "node_modules/prex": {
1352 | "version": "0.4.9",
1353 | "resolved": "https://registry.npmjs.org/prex/-/prex-0.4.9.tgz",
1354 | "integrity": "sha512-pQCB9AH8MXQRBaelDkhnTkqY6GRiXt1xWlx2hBReZYZwVA0m7EQcnF/K55zr87cCADDHmdD+qq7G6a8Pu+BRFA==",
1355 | "deprecated": "This package has been deprecated in favor of several '@esfx/*' packages that replace it. Please see the README for more information",
1356 | "dev": true,
1357 | "license": "Apache-2.0",
1358 | "dependencies": {
1359 | "@esfx/cancelable": "^1.0.0 || >=1.0.0-pre.13",
1360 | "@esfx/disposable": "^1.0.0 || >=1.0.0-pre.13"
1361 | }
1362 | },
1363 | "node_modules/promise-debounce": {
1364 | "version": "1.0.1",
1365 | "resolved": "https://registry.npmjs.org/promise-debounce/-/promise-debounce-1.0.1.tgz",
1366 | "integrity": "sha512-jq3Crngf1DaaOXQIOUkPr7LsW4UsWyn0KW1MJ+yMn5njTJ+F1AuHmjjwJhod9HuoNSSMspSLS9PS3V7BrexwjQ==",
1367 | "dev": true,
1368 | "license": "ISC"
1369 | },
1370 | "node_modules/punycode": {
1371 | "version": "2.3.1",
1372 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
1373 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
1374 | "dev": true,
1375 | "license": "MIT",
1376 | "engines": {
1377 | "node": ">=6"
1378 | }
1379 | },
1380 | "node_modules/queue-microtask": {
1381 | "version": "1.2.3",
1382 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
1383 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
1384 | "dev": true,
1385 | "funding": [
1386 | {
1387 | "type": "github",
1388 | "url": "https://github.com/sponsors/feross"
1389 | },
1390 | {
1391 | "type": "patreon",
1392 | "url": "https://www.patreon.com/feross"
1393 | },
1394 | {
1395 | "type": "consulting",
1396 | "url": "https://feross.org/support"
1397 | }
1398 | ],
1399 | "license": "MIT"
1400 | },
1401 | "node_modules/reduce-flatten": {
1402 | "version": "2.0.0",
1403 | "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz",
1404 | "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==",
1405 | "dev": true,
1406 | "license": "MIT",
1407 | "engines": {
1408 | "node": ">=6"
1409 | }
1410 | },
1411 | "node_modules/reusify": {
1412 | "version": "1.1.0",
1413 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
1414 | "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
1415 | "dev": true,
1416 | "license": "MIT",
1417 | "engines": {
1418 | "iojs": ">=1.0.0",
1419 | "node": ">=0.10.0"
1420 | }
1421 | },
1422 | "node_modules/rrweb-cssom": {
1423 | "version": "0.7.1",
1424 | "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz",
1425 | "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==",
1426 | "dev": true,
1427 | "license": "MIT"
1428 | },
1429 | "node_modules/run-parallel": {
1430 | "version": "1.2.0",
1431 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
1432 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
1433 | "dev": true,
1434 | "funding": [
1435 | {
1436 | "type": "github",
1437 | "url": "https://github.com/sponsors/feross"
1438 | },
1439 | {
1440 | "type": "patreon",
1441 | "url": "https://www.patreon.com/feross"
1442 | },
1443 | {
1444 | "type": "consulting",
1445 | "url": "https://feross.org/support"
1446 | }
1447 | ],
1448 | "license": "MIT",
1449 | "dependencies": {
1450 | "queue-microtask": "^1.2.2"
1451 | }
1452 | },
1453 | "node_modules/safer-buffer": {
1454 | "version": "2.1.2",
1455 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1456 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
1457 | "dev": true,
1458 | "license": "MIT"
1459 | },
1460 | "node_modules/saxes": {
1461 | "version": "6.0.0",
1462 | "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
1463 | "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
1464 | "dev": true,
1465 | "license": "ISC",
1466 | "dependencies": {
1467 | "xmlchars": "^2.2.0"
1468 | },
1469 | "engines": {
1470 | "node": ">=v12.22.7"
1471 | }
1472 | },
1473 | "node_modules/sprintf-js": {
1474 | "version": "1.0.3",
1475 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
1476 | "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
1477 | "dev": true,
1478 | "license": "BSD-3-Clause"
1479 | },
1480 | "node_modules/supports-color": {
1481 | "version": "7.2.0",
1482 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
1483 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
1484 | "dev": true,
1485 | "license": "MIT",
1486 | "dependencies": {
1487 | "has-flag": "^4.0.0"
1488 | },
1489 | "engines": {
1490 | "node": ">=8"
1491 | }
1492 | },
1493 | "node_modules/symbol-tree": {
1494 | "version": "3.2.4",
1495 | "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
1496 | "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
1497 | "dev": true,
1498 | "license": "MIT"
1499 | },
1500 | "node_modules/table-layout": {
1501 | "version": "1.0.2",
1502 | "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz",
1503 | "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==",
1504 | "dev": true,
1505 | "license": "MIT",
1506 | "dependencies": {
1507 | "array-back": "^4.0.1",
1508 | "deep-extend": "~0.6.0",
1509 | "typical": "^5.2.0",
1510 | "wordwrapjs": "^4.0.0"
1511 | },
1512 | "engines": {
1513 | "node": ">=8.0.0"
1514 | }
1515 | },
1516 | "node_modules/table-layout/node_modules/array-back": {
1517 | "version": "4.0.2",
1518 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz",
1519 | "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==",
1520 | "dev": true,
1521 | "license": "MIT",
1522 | "engines": {
1523 | "node": ">=8"
1524 | }
1525 | },
1526 | "node_modules/table-layout/node_modules/typical": {
1527 | "version": "5.2.0",
1528 | "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz",
1529 | "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==",
1530 | "dev": true,
1531 | "license": "MIT",
1532 | "engines": {
1533 | "node": ">=8"
1534 | }
1535 | },
1536 | "node_modules/tldts": {
1537 | "version": "6.1.85",
1538 | "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.85.tgz",
1539 | "integrity": "sha512-gBdZ1RjCSevRPFix/hpaUWeak2/RNUZB4/8frF1r5uYMHjFptkiT0JXIebWvgI/0ZHXvxaUDDJshiA0j6GdL3w==",
1540 | "dev": true,
1541 | "license": "MIT",
1542 | "dependencies": {
1543 | "tldts-core": "^6.1.85"
1544 | },
1545 | "bin": {
1546 | "tldts": "bin/cli.js"
1547 | }
1548 | },
1549 | "node_modules/tldts-core": {
1550 | "version": "6.1.85",
1551 | "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.85.tgz",
1552 | "integrity": "sha512-DTjUVvxckL1fIoPSb3KE7ISNtkWSawZdpfxGxwiIrZoO6EbHVDXXUIlIuWympPaeS+BLGyggozX/HTMsRAdsoA==",
1553 | "dev": true,
1554 | "license": "MIT"
1555 | },
1556 | "node_modules/to-regex-range": {
1557 | "version": "5.0.1",
1558 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
1559 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
1560 | "dev": true,
1561 | "license": "MIT",
1562 | "dependencies": {
1563 | "is-number": "^7.0.0"
1564 | },
1565 | "engines": {
1566 | "node": ">=8.0"
1567 | }
1568 | },
1569 | "node_modules/tough-cookie": {
1570 | "version": "5.1.2",
1571 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz",
1572 | "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==",
1573 | "dev": true,
1574 | "license": "BSD-3-Clause",
1575 | "dependencies": {
1576 | "tldts": "^6.1.32"
1577 | },
1578 | "engines": {
1579 | "node": ">=16"
1580 | }
1581 | },
1582 | "node_modules/tr46": {
1583 | "version": "5.1.0",
1584 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.0.tgz",
1585 | "integrity": "sha512-IUWnUK7ADYR5Sl1fZlO1INDUhVhatWl7BtJWsIhwJ0UAK7ilzzIa8uIqOO/aYVWHZPJkKbEL+362wrzoeRF7bw==",
1586 | "dev": true,
1587 | "license": "MIT",
1588 | "dependencies": {
1589 | "punycode": "^2.3.1"
1590 | },
1591 | "engines": {
1592 | "node": ">=18"
1593 | }
1594 | },
1595 | "node_modules/tslib": {
1596 | "version": "2.8.1",
1597 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
1598 | "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
1599 | "dev": true,
1600 | "license": "0BSD"
1601 | },
1602 | "node_modules/typical": {
1603 | "version": "4.0.0",
1604 | "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz",
1605 | "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==",
1606 | "dev": true,
1607 | "license": "MIT",
1608 | "engines": {
1609 | "node": ">=8"
1610 | }
1611 | },
1612 | "node_modules/w3c-xmlserializer": {
1613 | "version": "5.0.0",
1614 | "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
1615 | "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==",
1616 | "dev": true,
1617 | "license": "MIT",
1618 | "dependencies": {
1619 | "xml-name-validator": "^5.0.0"
1620 | },
1621 | "engines": {
1622 | "node": ">=18"
1623 | }
1624 | },
1625 | "node_modules/webidl-conversions": {
1626 | "version": "7.0.0",
1627 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
1628 | "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
1629 | "dev": true,
1630 | "license": "BSD-2-Clause",
1631 | "engines": {
1632 | "node": ">=12"
1633 | }
1634 | },
1635 | "node_modules/whatwg-encoding": {
1636 | "version": "3.1.1",
1637 | "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
1638 | "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
1639 | "dev": true,
1640 | "license": "MIT",
1641 | "dependencies": {
1642 | "iconv-lite": "0.6.3"
1643 | },
1644 | "engines": {
1645 | "node": ">=18"
1646 | }
1647 | },
1648 | "node_modules/whatwg-mimetype": {
1649 | "version": "4.0.0",
1650 | "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
1651 | "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
1652 | "dev": true,
1653 | "license": "MIT",
1654 | "engines": {
1655 | "node": ">=18"
1656 | }
1657 | },
1658 | "node_modules/whatwg-url": {
1659 | "version": "14.2.0",
1660 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
1661 | "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
1662 | "dev": true,
1663 | "license": "MIT",
1664 | "dependencies": {
1665 | "tr46": "^5.1.0",
1666 | "webidl-conversions": "^7.0.0"
1667 | },
1668 | "engines": {
1669 | "node": ">=18"
1670 | }
1671 | },
1672 | "node_modules/wordwrapjs": {
1673 | "version": "4.0.1",
1674 | "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz",
1675 | "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==",
1676 | "dev": true,
1677 | "license": "MIT",
1678 | "dependencies": {
1679 | "reduce-flatten": "^2.0.0",
1680 | "typical": "^5.2.0"
1681 | },
1682 | "engines": {
1683 | "node": ">=8.0.0"
1684 | }
1685 | },
1686 | "node_modules/wordwrapjs/node_modules/typical": {
1687 | "version": "5.2.0",
1688 | "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz",
1689 | "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==",
1690 | "dev": true,
1691 | "license": "MIT",
1692 | "engines": {
1693 | "node": ">=8"
1694 | }
1695 | },
1696 | "node_modules/ws": {
1697 | "version": "8.18.1",
1698 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz",
1699 | "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==",
1700 | "dev": true,
1701 | "license": "MIT",
1702 | "engines": {
1703 | "node": ">=10.0.0"
1704 | },
1705 | "peerDependencies": {
1706 | "bufferutil": "^4.0.1",
1707 | "utf-8-validate": ">=5.0.2"
1708 | },
1709 | "peerDependenciesMeta": {
1710 | "bufferutil": {
1711 | "optional": true
1712 | },
1713 | "utf-8-validate": {
1714 | "optional": true
1715 | }
1716 | }
1717 | },
1718 | "node_modules/xml-name-validator": {
1719 | "version": "5.0.0",
1720 | "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
1721 | "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
1722 | "dev": true,
1723 | "license": "Apache-2.0",
1724 | "engines": {
1725 | "node": ">=18"
1726 | }
1727 | },
1728 | "node_modules/xmlchars": {
1729 | "version": "2.2.0",
1730 | "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
1731 | "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
1732 | "dev": true,
1733 | "license": "MIT"
1734 | }
1735 | }
1736 | }
1737 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "proposal-array-from-async",
3 | "private": true,
4 | "description": "A TC39 proposal and specification for an Array.fromAsync method.",
5 | "author": "J. S. Choi (https://jschoi.org/)",
6 | "license": "BSD-3-Clause",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/tc39/proposal-array-async-from.git"
10 | },
11 | "keywords": [
12 | "proposal",
13 | "tc39",
14 | "array",
15 | "async",
16 | "iterator",
17 | "iterator",
18 | "stream",
19 | "Array.fromAsync",
20 | "Array.asyncFrom"
21 | ],
22 | "scripts": {
23 | "prebuild": "mkdir -p dist",
24 | "build": "ecmarkup --load-biblio @tc39/ecma262-biblio --verbose spec.html dist/index.html --assets-dir dist/",
25 | "watch": "npm run build -- --watch"
26 | },
27 | "devDependencies": {
28 | "@tc39/ecma262-biblio": "2.1.2869",
29 | "ecmarkup": "^21.2.0"
30 | },
31 | "homepage": "https://github.com/tc39/proposal-array-async-from"
32 | }
33 |
--------------------------------------------------------------------------------
/spec.html:
--------------------------------------------------------------------------------
1 |
2 | title: ES Array.fromAsync
3 | status: proposal
4 | stage: 3 (Conditional on Editor Review)
5 | location: https://github.com/js-choi/proposal-array-async-from
6 | copyright: false
7 | contributors: J. S. Choi
8 |
9 |
10 |
11 | Introduction
12 | This is the formal specification for a proposed `Array.fromAsync` factory method
13 | in JavaScript. It modifies the original ECMAScript specification with
15 | several new or revised clauses. See the proposal's
17 | explainer for the proposal's background, motivation, and usage examples.
18 | This proposal depends on the pull request tc39/ecma262#2942: “support built-in async functions”.
19 |
20 |
21 |
22 | Abstract Operations
23 |
24 |
25 | Operations on Iterator Objects
26 |
27 |
28 | IfAbruptCloseAsyncIterator ( _value_, _iteratorRecord_ )
29 | IfAbruptCloseAsyncIterator is a shorthand for a sequence of algorithm steps that use an Iterator Record. An algorithm step of the form:
30 |
31 | 1. IfAbruptCloseAsyncIterator(_value_, _iteratorRecord_).
32 |
33 | means the same thing as:
34 |
35 | 1. Assert: _value_ is a Completion Record.
36 | 1. If _value_ is an abrupt completion, return ? AsyncIteratorClose(_iteratorRecord_, _value_).
37 | 1. Else, set _value_ to ! _value_.
38 |
39 |
40 |
41 |
42 |
43 |
44 | Indexed Collections
45 |
46 |
47 | Array Objects
48 |
49 |
50 | Properties of the Array Constructor
51 |
52 |
53 | Array.fromAsync ( _asyncItems_ [ , _mapper_ [ , _thisArg_ ] ] )
54 |
55 |
56 | This section is a wholly new subsection of the original
58 | Properties of the Array Constructor clause, to be inserted before the Array.from
60 | clause.
61 |
62 |
63 | This async method performs the following steps when called:
64 |
65 | 1. Let _C_ be the *this* value.
66 | 1. If _mapper_ is *undefined*, then
67 | 1. Let _mapping_ be *false*.
68 | 1. Else,
69 | 1. If IsCallable(_mapper_) is *false*, throw a *TypeError* exception.
70 | 1. Let _mapping_ be *true*.
71 | 1. Let _usingAsyncIterator_ be ? GetMethod(_asyncItems_, %Symbol.asyncIterator%).
72 | 1. If _usingAsyncIterator_ is *undefined*, then
73 | 1. Let _usingSyncIterator_ be ? GetMethod(_asyncItems_, %Symbol.iterator%).
74 | 1. Let _iteratorRecord_ be *undefined*.
75 | 1. If _usingAsyncIterator_ is not *undefined*, then
76 | 1. Set _iteratorRecord_ to ? GetIteratorFromMethod(_asyncItems_, _usingAsyncIterator_).
77 | 1. Else if _usingSyncIterator_ is not *undefined*, then
78 | 1. Set _iteratorRecord_ to CreateAsyncFromSyncIterator(? GetIteratorFromMethod(_asyncItems_, _usingSyncIterator_)).
79 | 1. If _iteratorRecord_ is not *undefined*, then
80 | 1. If IsConstructor(_C_) is *true*, then
81 | 1. Let _A_ be ? Construct(_C_).
82 | 1. Else,
83 | 1. Let _A_ be ! ArrayCreate(0).
84 | 1. Let _k_ be 0.
85 | 1. Repeat,
86 | 1. If _k_ ≥ 253 - 1, then
87 | 1. Let _error_ be ThrowCompletion(a newly created *TypeError* object).
88 | 1. Return ? AsyncIteratorClose(_iteratorRecord_, _error_).
89 | 1. Let _Pk_ be ! ToString(𝔽(_k_)).
90 | 1. Let _nextResult_ be ? Call(_iteratorRecord_.[[NextMethod]], _iteratorRecord_.[[Iterator]]).
91 | 1. Set _nextResult_ to ? Await(_nextResult_).
92 | 1. If _nextResult_ is not an Object, throw a *TypeError* exception.
93 | 1. Let _done_ be ? IteratorComplete(_nextResult_).
94 | 1. If _done_ is *true*, then
95 | 1. Perform ? Set(_A_, *"length"*, 𝔽(_k_), *true*).
96 | 1. Return _A_.
97 | 1. Let _nextValue_ be ? IteratorValue(_nextResult_).
98 | 1. If _mapping_ is *true*, then
99 | 1. Let _mappedValue_ be Completion(Call(_mapper_, _thisArg_, « _nextValue_, 𝔽(_k_) »)).
100 | 1. IfAbruptCloseAsyncIterator(_mappedValue_, _iteratorRecord_).
101 | 1. Set _mappedValue_ to Completion(Await(_mappedValue_)).
102 | 1. IfAbruptCloseAsyncIterator(_mappedValue_, _iteratorRecord_).
103 | 1. Else,
104 | 1. Let _mappedValue_ be _nextValue_.
105 | 1. Let _defineStatus_ be Completion(CreateDataPropertyOrThrow(_A_, _Pk_, _mappedValue_)).
106 | 1. IfAbruptCloseAsyncIterator(_defineStatus_, _iteratorRecord_).
107 | 1. Set _k_ to _k_ + 1.
108 | 1. Else,
109 | 1. NOTE: _asyncItems_ is neither an AsyncIterable nor an Iterable so assume it is an array-like object.
110 | 1. Let _arrayLike_ be ! ToObject(_asyncItems_).
111 | 1. Let _len_ be ? LengthOfArrayLike(_arrayLike_).
112 | 1. If IsConstructor(_C_) is *true*, then
113 | 1. Let _A_ be ? Construct(_C_, « 𝔽(_len_) »).
114 | 1. Else,
115 | 1. Let _A_ be ? ArrayCreate(_len_).
116 | 1. Let _k_ be 0.
117 | 1. Repeat, while _k_ < _len_,
118 | 1. Let _Pk_ be ! ToString(𝔽(_k_)).
119 | 1. Let _kValue_ be ? Get(_arrayLike_, _Pk_).
120 | 1. Set _kValue_ to ? Await(_kValue_).
121 | 1. If _mapping_ is *true*, then
122 | 1. Let _mappedValue_ be ? Call(_mapper_, _thisArg_, « _kValue_, 𝔽(_k_) »).
123 | 1. Set _mappedValue_ to ? Await(_mappedValue_).
124 | 1. Else,
125 | 1. Let _mappedValue_ be _kValue_.
126 | 1. Perform ? CreateDataPropertyOrThrow(_A_, _Pk_, _mappedValue_).
127 | 1. Set _k_ to _k_ + 1.
128 | 1. Perform ? Set(_A_, *"length"*, 𝔽(_len_), *true*).
129 | 1. Return _A_.
130 |
131 |
132 | This method is an intentionally generic factory method; it does not require that its *this* value be the Array constructor. Therefore it can be transferred to or inherited by any other constructors that may be called with a single numeric argument.
133 |
134 |
135 |
136 |
137 |
138 |
--------------------------------------------------------------------------------