├── .gitignore ├── .prettierignore ├── .prettierrc.js ├── README.md ├── demos ├── 01-synchronous.js ├── 02-synchronous-for-loop.js ├── 03-call-stack.js ├── 04-synchronous-callback.js ├── 05-set-timeout.js ├── 06-set-timeout-0ms.js ├── 07-set-timeout-blocked.js ├── 08-set-interval.js ├── 09-set-interval-0ms.js ├── 10-set-timeout-multiple.js ├── 11-set-immediate.js ├── 12-set-immediate-vs-set-timeout-0ms.js ├── 13-set-immediate-vs-set-timeout-0ms-2.js ├── 14-set-immediate-vs-set-timeout-0ms-grouping.js ├── 15-set-immediate-vs-set-timeout-io.js ├── 16-process-next-tick.js ├── 17-process-next-tick-vs-set-timeout.js ├── 18-process-next-tick-vs-set-immediate.js ├── 19-process-next-tick-vs-set-timeout-vs-set-immediate.js ├── 20-process-next-tick-vs-set-timeout-vs-set-immediate-io.js ├── 21-process-next-tick-microtask.js ├── 22-promise.js ├── 23-promise-vs-process-next-tick.js ├── 24-promise-vs-process-next-tick-grouping.js └── 25-promise-with-process-next-tick-inside.js ├── package.json ├── slides ├── 01 Talk Title (Deep Dive).png ├── 01 Talk Title (UtahJS).png ├── 01 Talk Title.png ├── 02 Speaker Bio.png ├── 03 JavaScript Event Loop (Browser).png ├── 04 JavaScript Event Loop (Browser) (Example).png ├── 05 Node.js Event Loop Phases.png ├── 06 Phases Overview.png ├── 07 Node.js Event Loop.png ├── 08 Node.js Event Loop (Example).png └── 09 Main Takeaways.png └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | build 2 | coverage 3 | node_modules 4 | .insomnia 5 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | trailingComma: 'es5', 3 | tabWidth: 2, 4 | semi: true, 5 | singleQuote: true, 6 | }; 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Node.js Event Loop Presentation 2 | 3 | This repo contains slides and demo examples for my talk "Understanding the Node.js Event Loop" that I presented at the [Node.js Global Summit 2022](https://www.youtube.com/watch?v=RYpivX9P8-I&t=32415s&ab_channel=GeekleOfficial) on May 18, 2022. 4 | 5 | I'll also be presenting this at UtahJS on September 23, 2022 with the talk title "A Deep Dive Into the Node.js Event Loop." 6 | 7 | ![Node.js Event Loop](<./slides/08%20Node.js%20Event%20Loop%20(Example).png>) 8 | 9 | ## Using This Repo 10 | 11 | The `demos` directory contains several files. Each file is an independent demo that you can run with Node.js. For example: 12 | 13 | ``` 14 | node demos/01-synchronous.js 15 | ``` 16 | 17 | Try to guess the order in which the functions will be executed before running each example. 18 | 19 | ## Resources 20 | 21 | ### Node.js Docs 22 | 23 | - [Introduction to Node.js](https://nodejs.dev/learn) 24 | - [Blocking vs. Non-Blocking Code in Node.js](https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/) 25 | - [Timers in Node.js](https://nodejs.org/en/docs/guides/timers-in-node/) 26 | - [The Node.js Event Loop](https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/) 27 | - [Don't Block the Event Loop](https://nodejs.org/en/docs/guides/dont-block-the-event-loop/) 28 | 29 | ### Articles 30 | 31 | - [Understanding the Node.js Event Loop](https://betterprogramming.pub/understanding-the-node-js-event-loop-a4030f4b0716) 32 | - [Understanding the Node.js event loop phases and how it executes the JavaScript code](https://dev.to/lunaticmonk/understanding-the-node-js-event-loop-phases-and-how-it-executes-the-javascript-code-1j9) 33 | - [Node.js Event Loop (Geeks for Geeks)](https://www.geeksforgeeks.org/node-js-event-loop/) 34 | - [JavaScript Event Loop (JavaScript Tutorial)](https://www.javascripttutorial.net/javascript-event-loop/) 35 | - [The event loop (MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop) 36 | - [Microtasks](https://javascript.info/microtask-queue) 37 | - [Promises, Next-Ticks, and Immediates](https://blog.insiderattack.net/promises-next-ticks-and-immediates-nodejs-event-loop-part-3-9226cbe7a6aa) 38 | 39 | ### Talks 40 | 41 | - [What the heck is the event loop anyway?](https://www.youtube.com/watch?v=8aGhZQkoFbQ&ab_channel=JSConf) 42 | - [Further Adventures of the Event Loop](https://www.youtube.com/watch?v=u1kqx6AenYw&ab_channel=JSConf) 43 | -------------------------------------------------------------------------------- /demos/01-synchronous.js: -------------------------------------------------------------------------------- 1 | const first = () => console.log('first'); 2 | const second = () => console.log('second'); 3 | const third = () => console.log('third'); 4 | 5 | first(); 6 | second(); 7 | third(); 8 | -------------------------------------------------------------------------------- /demos/02-synchronous-for-loop.js: -------------------------------------------------------------------------------- 1 | const first = () => console.log('first'); 2 | const second = () => console.log('second (for loop)'); 3 | const third = () => console.log('third'); 4 | 5 | first(); 6 | 7 | for (let i = 0; i < 5; i++) { 8 | second(); 9 | } 10 | 11 | third(); 12 | -------------------------------------------------------------------------------- /demos/03-call-stack.js: -------------------------------------------------------------------------------- 1 | const first = () => console.log('first'); 2 | const second = () => { 3 | console.log('second'); 4 | third(); 5 | }; 6 | const third = () => console.log('third (called by second)'); 7 | const fourth = () => console.log('fourth'); 8 | 9 | first(); 10 | second(); 11 | fourth(); 12 | -------------------------------------------------------------------------------- /demos/04-synchronous-callback.js: -------------------------------------------------------------------------------- 1 | const first = () => console.log('first'); 2 | const second = (callback) => { 3 | console.log('second'); 4 | callback(); 5 | }; 6 | const third = () => console.log('third (called by second)'); 7 | const fourth = () => console.log('fourth'); 8 | 9 | first(); 10 | second(third); 11 | fourth(); 12 | -------------------------------------------------------------------------------- /demos/05-set-timeout.js: -------------------------------------------------------------------------------- 1 | const first = () => console.log('first'); 2 | const second = () => console.log('second (setTimeout)'); 3 | const third = () => console.log('third'); 4 | 5 | first(); 6 | setTimeout(second, 1000); 7 | third(); 8 | -------------------------------------------------------------------------------- /demos/06-set-timeout-0ms.js: -------------------------------------------------------------------------------- 1 | const first = () => console.log('first'); 2 | const second = () => console.log('second (setTimeout)'); 3 | const third = () => console.log('third'); 4 | 5 | first(); 6 | setTimeout(second, 0); 7 | third(); 8 | -------------------------------------------------------------------------------- /demos/07-set-timeout-blocked.js: -------------------------------------------------------------------------------- 1 | const first = () => console.log('first'); 2 | const second = () => console.log('second (setTimeout)'); 3 | const third = () => console.log('third (in a blocking loop)'); 4 | 5 | first(); 6 | setTimeout(second, 0); 7 | 8 | const startTime = new Date(); 9 | const fiveMoreSeconds = 5000; 10 | const endTime = new Date(startTime.getTime() + fiveMoreSeconds); 11 | 12 | while (new Date() < endTime) { 13 | third(); 14 | } 15 | -------------------------------------------------------------------------------- /demos/08-set-interval.js: -------------------------------------------------------------------------------- 1 | const first = () => console.log('first'); 2 | 3 | let count = 0; 4 | 5 | const second = () => { 6 | console.log('second (setInterval)'); 7 | count++; 8 | 9 | if (count >= 5) { 10 | clearInterval(myInterval); 11 | } 12 | }; 13 | 14 | const third = () => console.log('third'); 15 | 16 | first(); 17 | const myInterval = setInterval(second, 500); 18 | third(); 19 | -------------------------------------------------------------------------------- /demos/09-set-interval-0ms.js: -------------------------------------------------------------------------------- 1 | const first = () => console.log('first'); 2 | 3 | let count = 0; 4 | 5 | const second = () => { 6 | console.log('second (setInterval)'); 7 | count++; 8 | 9 | if (count >= 5) { 10 | clearInterval(myInterval); 11 | } 12 | }; 13 | 14 | const third = () => console.log('third'); 15 | 16 | first(); 17 | const myInterval = setInterval(second, 0); 18 | third(); 19 | -------------------------------------------------------------------------------- /demos/10-set-timeout-multiple.js: -------------------------------------------------------------------------------- 1 | const first = () => console.log('first (setTimeout)'); 2 | const second = () => console.log('second (setTimeout)'); 3 | const third = () => console.log('third (setTimeout)'); 4 | 5 | setTimeout(first, 500); 6 | setTimeout(second, 500); 7 | setTimeout(third, 500); 8 | -------------------------------------------------------------------------------- /demos/11-set-immediate.js: -------------------------------------------------------------------------------- 1 | const first = () => console.log('first'); 2 | const second = () => console.log('second (setImmediate)'); 3 | const third = () => console.log('third'); 4 | 5 | first(); 6 | setImmediate(second); 7 | third(); 8 | -------------------------------------------------------------------------------- /demos/12-set-immediate-vs-set-timeout-0ms.js: -------------------------------------------------------------------------------- 1 | const first = () => console.log('first (setTimeout)'); 2 | const second = () => console.log('second (setImmediate)'); 3 | const third = () => console.log('third'); 4 | 5 | setTimeout(first, 0); 6 | setImmediate(second); 7 | third(); 8 | -------------------------------------------------------------------------------- /demos/13-set-immediate-vs-set-timeout-0ms-2.js: -------------------------------------------------------------------------------- 1 | const first = () => console.log('first (setImmediate)'); 2 | const second = () => console.log('second (setTimeout)'); 3 | const third = () => console.log('third'); 4 | 5 | setImmediate(first); 6 | setTimeout(second, 0); 7 | third(); 8 | -------------------------------------------------------------------------------- /demos/14-set-immediate-vs-set-timeout-0ms-grouping.js: -------------------------------------------------------------------------------- 1 | const firstSetImmediate = () => console.log('setImmediate 1'); 2 | const secondSetImmediate = () => console.log('setImmediate 2'); 3 | const thirdSetImmediate = () => console.log('setImmediate 3'); 4 | const fourthSetImmediate = () => console.log('setImmediate 4'); 5 | 6 | const firstSetTimeout = () => console.log('setTimeout 1'); 7 | const secondSetTimeout = () => console.log('setTimeout 2'); 8 | const thirdSetTimeout = () => console.log('setTimeout 3'); 9 | const fourthSetTimeout = () => console.log('setTimeout 4'); 10 | 11 | setImmediate(firstSetImmediate); 12 | setTimeout(firstSetTimeout, 0); 13 | setImmediate(secondSetImmediate); 14 | setTimeout(secondSetTimeout, 0); 15 | setTimeout(thirdSetTimeout, 0); 16 | setImmediate(thirdSetImmediate); 17 | setImmediate(fourthSetImmediate); 18 | setTimeout(fourthSetTimeout, 0); 19 | -------------------------------------------------------------------------------- /demos/15-set-immediate-vs-set-timeout-io.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | const firstSetImmediate = () => console.log('setImmediate 1'); 4 | const secondSetImmediate = () => console.log('setImmediate 2'); 5 | const thirdSetImmediate = () => console.log('setImmediate 3'); 6 | const fourthSetImmediate = () => console.log('setImmediate 4'); 7 | 8 | const firstSetTimeout = () => console.log('setTimeout 1'); 9 | const secondSetTimeout = () => console.log('setTimeout 2'); 10 | const thirdSetTimeout = () => console.log('setTimeout 3'); 11 | const fourthSetTimeout = () => console.log('setTimeout 4'); 12 | 13 | fs.readFile('package.json', 'utf8', (err, data) => { 14 | if (err) { 15 | return console.log(err); 16 | } 17 | 18 | setImmediate(firstSetImmediate); 19 | setTimeout(firstSetTimeout, 0); 20 | setImmediate(secondSetImmediate); 21 | setTimeout(secondSetTimeout, 0); 22 | setTimeout(thirdSetTimeout, 0); 23 | setImmediate(thirdSetImmediate); 24 | setImmediate(fourthSetImmediate); 25 | setTimeout(fourthSetTimeout, 0); 26 | }); 27 | -------------------------------------------------------------------------------- /demos/16-process-next-tick.js: -------------------------------------------------------------------------------- 1 | const first = () => console.log('first'); 2 | const second = () => console.log('second (process.nextTick)'); 3 | const third = () => console.log('third'); 4 | 5 | first(); 6 | process.nextTick(second); 7 | third(); 8 | -------------------------------------------------------------------------------- /demos/17-process-next-tick-vs-set-timeout.js: -------------------------------------------------------------------------------- 1 | const first = () => console.log('first (setTimeout)'); 2 | const second = () => console.log('second (process.nextTick)'); 3 | const third = () => console.log('third'); 4 | 5 | setTimeout(first, 0); 6 | process.nextTick(second); 7 | third(); 8 | -------------------------------------------------------------------------------- /demos/18-process-next-tick-vs-set-immediate.js: -------------------------------------------------------------------------------- 1 | const first = () => console.log('first (setImmediate)'); 2 | const second = () => console.log('second (process.nextTick)'); 3 | const third = () => console.log('third'); 4 | 5 | setImmediate(first); 6 | process.nextTick(second); 7 | third(); 8 | -------------------------------------------------------------------------------- /demos/19-process-next-tick-vs-set-timeout-vs-set-immediate.js: -------------------------------------------------------------------------------- 1 | const first = () => console.log('first (setImmediate)'); 2 | const second = () => console.log('second (setTimeout)'); 3 | const third = () => console.log('third (process.nextTick)'); 4 | const fourth = () => console.log('fourth'); 5 | 6 | setImmediate(first); 7 | setTimeout(second, 0); 8 | process.nextTick(third); 9 | fourth(); 10 | -------------------------------------------------------------------------------- /demos/20-process-next-tick-vs-set-timeout-vs-set-immediate-io.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | const first = () => console.log('first (setImmediate)'); 4 | const second = () => console.log('second (setTimeout)'); 5 | const third = () => console.log('third (process.nextTick)'); 6 | const fourth = () => console.log('fourth'); 7 | 8 | fs.readFile('package.json', 'utf8', (err, data) => { 9 | if (err) { 10 | return console.log(err); 11 | } 12 | 13 | setImmediate(first); 14 | setTimeout(second, 0); 15 | process.nextTick(third); 16 | fourth(); 17 | }); 18 | -------------------------------------------------------------------------------- /demos/21-process-next-tick-microtask.js: -------------------------------------------------------------------------------- 1 | const firstSetTimeout = () => console.log('setTimeout 1'); 2 | 3 | const secondSetTimeout = () => { 4 | console.log('setTimeout 2'); 5 | process.nextTick(firstProcessNextTick); 6 | process.nextTick(secondProcessNextTick); 7 | }; 8 | 9 | const thirdSetTimeout = () => console.log('setTimeout 3'); 10 | 11 | const firstProcessNextTick = () => console.log('process.nextTick 1'); 12 | const secondProcessNextTick = () => console.log('process.nextTick 2'); 13 | const thirdProcessNextTick = () => console.log('process.nextTick 3'); 14 | 15 | setTimeout(firstSetTimeout, 0); 16 | setTimeout(secondSetTimeout, 0); 17 | setTimeout(thirdSetTimeout, 0); 18 | process.nextTick(thirdProcessNextTick); 19 | -------------------------------------------------------------------------------- /demos/22-promise.js: -------------------------------------------------------------------------------- 1 | const firstThen = () => console.log('promise callback 1'); 2 | const secondThen = () => console.log('promise callback 2'); 3 | const third = () => console.log('third'); 4 | 5 | Promise 6 | .resolve() 7 | .then(firstThen) 8 | .then(secondThen); 9 | 10 | third(); 11 | -------------------------------------------------------------------------------- /demos/23-promise-vs-process-next-tick.js: -------------------------------------------------------------------------------- 1 | const firstThen = () => console.log('promise callback 1'); 2 | const secondThen = () => console.log('promise callback 2'); 3 | const third = () => console.log('process.nextTick'); 4 | 5 | Promise 6 | .resolve() 7 | .then(firstThen) 8 | .then(secondThen); 9 | 10 | process.nextTick(third); 11 | -------------------------------------------------------------------------------- /demos/24-promise-vs-process-next-tick-grouping.js: -------------------------------------------------------------------------------- 1 | const firstPromiseCallback = () => console.log('promise callback 1'); 2 | const secondPromiseCallback = () => console.log('promise callback 2'); 3 | const thirdPromiseCallback = () => console.log('promise callback 3'); 4 | const fourthPromiseCallback = () => console.log('promise callback 4'); 5 | 6 | const firstProcessNextTickCallback = () => console.log('process.nextTick 1'); 7 | const secondProcessNextTickCallback = () => console.log('process.nextTick 2'); 8 | const thirdProcessNextTickCallback = () => console.log('process.nextTick 3'); 9 | const fourthProcessNextTickCallback = () => console.log('process.nextTick 4'); 10 | 11 | Promise.resolve().then(firstPromiseCallback); 12 | process.nextTick(firstProcessNextTickCallback); 13 | process.nextTick(secondProcessNextTickCallback); 14 | Promise.resolve().then(secondPromiseCallback); 15 | Promise.resolve().then(thirdPromiseCallback); 16 | process.nextTick(thirdProcessNextTickCallback); 17 | process.nextTick(fourthProcessNextTickCallback); 18 | Promise.resolve().then(fourthPromiseCallback); 19 | -------------------------------------------------------------------------------- /demos/25-promise-with-process-next-tick-inside.js: -------------------------------------------------------------------------------- 1 | const promiseCallback1 = () => console.log('promise callback 1'); 2 | const promiseCallback2 = () => console.log('promise callback 2'); 3 | const promiseCallback3 = () => console.log('promise callback 3'); 4 | 5 | const processNextTickCallback1 = () => console.log('process.nextTick 1'); 6 | const processNextTickCallback2 = () => console.log('process.nextTick 2'); 7 | const processNextTickCallback3 = () => console.log('process.nextTick 3'); 8 | 9 | Promise.resolve().then(promiseCallback1); 10 | Promise.resolve().then(promiseCallback2); 11 | Promise.resolve().then(() => process.nextTick(processNextTickCallback2)); 12 | Promise.resolve().then(() => process.nextTick(processNextTickCallback3)); 13 | Promise.resolve().then(promiseCallback3); 14 | 15 | process.nextTick(processNextTickCallback1); 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodejs-event-loop-presentation", 3 | "version": "1.0.0", 4 | "description": "Presentation slides and demo examples for the Node.js event loop", 5 | "main": "index.js", 6 | "scripts": { 7 | "format": "prettier --write .", 8 | "format-watch": "onchange . -- prettier --write {{changed}}", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "keywords": [ 12 | "nodejs", 13 | "javascript", 14 | "event", 15 | "loop", 16 | "tutorial" 17 | ], 18 | "author": "Tyler Hawkins", 19 | "license": "ISC", 20 | "devDependencies": { 21 | "onchange": "^7.1.0", 22 | "prettier": "^2.6.2" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /slides/01 Talk Title (Deep Dive).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thawkin3/nodejs-event-loop-presentation/962d07f730c3ab4f9f984f1e73084d37172d90bb/slides/01 Talk Title (Deep Dive).png -------------------------------------------------------------------------------- /slides/01 Talk Title (UtahJS).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thawkin3/nodejs-event-loop-presentation/962d07f730c3ab4f9f984f1e73084d37172d90bb/slides/01 Talk Title (UtahJS).png -------------------------------------------------------------------------------- /slides/01 Talk Title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thawkin3/nodejs-event-loop-presentation/962d07f730c3ab4f9f984f1e73084d37172d90bb/slides/01 Talk Title.png -------------------------------------------------------------------------------- /slides/02 Speaker Bio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thawkin3/nodejs-event-loop-presentation/962d07f730c3ab4f9f984f1e73084d37172d90bb/slides/02 Speaker Bio.png -------------------------------------------------------------------------------- /slides/03 JavaScript Event Loop (Browser).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thawkin3/nodejs-event-loop-presentation/962d07f730c3ab4f9f984f1e73084d37172d90bb/slides/03 JavaScript Event Loop (Browser).png -------------------------------------------------------------------------------- /slides/04 JavaScript Event Loop (Browser) (Example).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thawkin3/nodejs-event-loop-presentation/962d07f730c3ab4f9f984f1e73084d37172d90bb/slides/04 JavaScript Event Loop (Browser) (Example).png -------------------------------------------------------------------------------- /slides/05 Node.js Event Loop Phases.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thawkin3/nodejs-event-loop-presentation/962d07f730c3ab4f9f984f1e73084d37172d90bb/slides/05 Node.js Event Loop Phases.png -------------------------------------------------------------------------------- /slides/06 Phases Overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thawkin3/nodejs-event-loop-presentation/962d07f730c3ab4f9f984f1e73084d37172d90bb/slides/06 Phases Overview.png -------------------------------------------------------------------------------- /slides/07 Node.js Event Loop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thawkin3/nodejs-event-loop-presentation/962d07f730c3ab4f9f984f1e73084d37172d90bb/slides/07 Node.js Event Loop.png -------------------------------------------------------------------------------- /slides/08 Node.js Event Loop (Example).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thawkin3/nodejs-event-loop-presentation/962d07f730c3ab4f9f984f1e73084d37172d90bb/slides/08 Node.js Event Loop (Example).png -------------------------------------------------------------------------------- /slides/09 Main Takeaways.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thawkin3/nodejs-event-loop-presentation/962d07f730c3ab4f9f984f1e73084d37172d90bb/slides/09 Main Takeaways.png -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@blakeembrey/deque@^1.0.5": 6 | version "1.0.5" 7 | resolved "https://registry.yarnpkg.com/@blakeembrey/deque/-/deque-1.0.5.tgz#f4fa17fc5ee18317ec01a763d355782c7b395eaf" 8 | integrity sha512-6xnwtvp9DY1EINIKdTfvfeAtCYw4OqBZJhtiqkT3ivjnEfa25VQ3TsKvaFfKm8MyGIEfE95qLe+bNEt3nB0Ylg== 9 | 10 | "@blakeembrey/template@^1.0.0": 11 | version "1.1.0" 12 | resolved "https://registry.yarnpkg.com/@blakeembrey/template/-/template-1.1.0.tgz#fbea7a688ffedf0763085b2cda8efe6fdd54d4c4" 13 | integrity sha512-iZf+UWfL+DogJVpd/xMQyP6X6McYd6ArdYoPMiv/zlOTzeXXfQbYxBNJJBF6tThvsjLMbA8tLjkCdm9RWMFCCw== 14 | 15 | anymatch@~3.1.2: 16 | version "3.1.2" 17 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" 18 | integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== 19 | dependencies: 20 | normalize-path "^3.0.0" 21 | picomatch "^2.0.4" 22 | 23 | arg@^4.1.3: 24 | version "4.1.3" 25 | resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" 26 | integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== 27 | 28 | binary-extensions@^2.0.0: 29 | version "2.2.0" 30 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" 31 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== 32 | 33 | braces@~3.0.2: 34 | version "3.0.2" 35 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 36 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 37 | dependencies: 38 | fill-range "^7.0.1" 39 | 40 | chokidar@^3.3.1: 41 | version "3.5.3" 42 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" 43 | integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== 44 | dependencies: 45 | anymatch "~3.1.2" 46 | braces "~3.0.2" 47 | glob-parent "~5.1.2" 48 | is-binary-path "~2.1.0" 49 | is-glob "~4.0.1" 50 | normalize-path "~3.0.0" 51 | readdirp "~3.6.0" 52 | optionalDependencies: 53 | fsevents "~2.3.2" 54 | 55 | cross-spawn@^7.0.1: 56 | version "7.0.3" 57 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" 58 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 59 | dependencies: 60 | path-key "^3.1.0" 61 | shebang-command "^2.0.0" 62 | which "^2.0.1" 63 | 64 | fill-range@^7.0.1: 65 | version "7.0.1" 66 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 67 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 68 | dependencies: 69 | to-regex-range "^5.0.1" 70 | 71 | fsevents@~2.3.2: 72 | version "2.3.2" 73 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" 74 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== 75 | 76 | glob-parent@~5.1.2: 77 | version "5.1.2" 78 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 79 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 80 | dependencies: 81 | is-glob "^4.0.1" 82 | 83 | ignore@^5.1.4: 84 | version "5.2.0" 85 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" 86 | integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== 87 | 88 | is-binary-path@~2.1.0: 89 | version "2.1.0" 90 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" 91 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 92 | dependencies: 93 | binary-extensions "^2.0.0" 94 | 95 | is-extglob@^2.1.1: 96 | version "2.1.1" 97 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 98 | integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= 99 | 100 | is-glob@^4.0.1, is-glob@~4.0.1: 101 | version "4.0.3" 102 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" 103 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 104 | dependencies: 105 | is-extglob "^2.1.1" 106 | 107 | is-number@^7.0.0: 108 | version "7.0.0" 109 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 110 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 111 | 112 | isexe@^2.0.0: 113 | version "2.0.0" 114 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 115 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= 116 | 117 | normalize-path@^3.0.0, normalize-path@~3.0.0: 118 | version "3.0.0" 119 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 120 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 121 | 122 | onchange@^7.1.0: 123 | version "7.1.0" 124 | resolved "https://registry.yarnpkg.com/onchange/-/onchange-7.1.0.tgz#a6f0f7733e4d47014b4cd70aa1ad36c2b4cf3804" 125 | integrity sha512-ZJcqsPiWUAUpvmnJri5TPBooqJOPmC0ttN65juhN15Q8xA+Nbg3BaxBHXQ45EistKKlKElb0edmbPWnKSBkvMg== 126 | dependencies: 127 | "@blakeembrey/deque" "^1.0.5" 128 | "@blakeembrey/template" "^1.0.0" 129 | arg "^4.1.3" 130 | chokidar "^3.3.1" 131 | cross-spawn "^7.0.1" 132 | ignore "^5.1.4" 133 | tree-kill "^1.2.2" 134 | 135 | path-key@^3.1.0: 136 | version "3.1.1" 137 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" 138 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 139 | 140 | picomatch@^2.0.4, picomatch@^2.2.1: 141 | version "2.3.1" 142 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" 143 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 144 | 145 | prettier@^2.6.2: 146 | version "2.6.2" 147 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.2.tgz#e26d71a18a74c3d0f0597f55f01fb6c06c206032" 148 | integrity sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew== 149 | 150 | readdirp@~3.6.0: 151 | version "3.6.0" 152 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" 153 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== 154 | dependencies: 155 | picomatch "^2.2.1" 156 | 157 | shebang-command@^2.0.0: 158 | version "2.0.0" 159 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" 160 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 161 | dependencies: 162 | shebang-regex "^3.0.0" 163 | 164 | shebang-regex@^3.0.0: 165 | version "3.0.0" 166 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 167 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 168 | 169 | to-regex-range@^5.0.1: 170 | version "5.0.1" 171 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 172 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 173 | dependencies: 174 | is-number "^7.0.0" 175 | 176 | tree-kill@^1.2.2: 177 | version "1.2.2" 178 | resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" 179 | integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== 180 | 181 | which@^2.0.1: 182 | version "2.0.2" 183 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 184 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 185 | dependencies: 186 | isexe "^2.0.0" 187 | --------------------------------------------------------------------------------