├── .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 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 |
Parallel awaitingSequential awaiting
Lazy iterationImpossibleawait Array.fromAsync(input)
Eager iterationawait Promise.all(Array.from(input))Useless
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 | 578 | 579 | 629 | 659 |
Status quo 575 | With Array.fromAsync 576 | 577 |
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 |
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 |
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 | 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 | --------------------------------------------------------------------------------