diff --git a/.gitignore b/.gitignore index 07e6e47..8777577 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /node_modules +.vscode/ diff --git a/README.md b/README.md index e5d2a1f..4aea79b 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,49 @@ # node-mentoring-introduction -Task 1 +Task 3 +https://d17btkcdsmqrmh.cloudfront.net/node-gmp/docs/event-emitter-vs-buffers-vs-streams/Homework + +## Subtask 1 +Write your own EventEmitter class. +It must contain +- on / addEventListener method, +- off / removeEventListener method, +- once method, +- emit method, +- rawListeners method, +- listenerCount method. +This basic features are sufficient to implement a full system using the eventing model. + +Test result: + +2023-09-14_22h43_54 + +## Subtask 2 +Write a class WithTime which should extend your own class EventEmitter. + +WithTime must execute some Async function with arguments and compute the time taken by this function. + +Execution must emit event start and end of execute and console.log of result data. This data must be gotten from Async function. + +Test result: + +![2023-09-15_20h27_13](https://github.com/kandalova/node-mentoring-introduction/assets/26093763/953a3aae-04fb-4f63-a231-b045a5febb96) + +## Subtask 3 + +Write a program which should do the following: +- Read the content of csvfile from./csvdirectory +- Use the csvtojson package to convert csvfile to json object +- Write the csvfile content to a new txtfile. +- Do not load all the content of the csvfile into RAM via stream (read/write file content line by line). +- In case of read/write errors, log them in the console. +- The program should be started via npm script using nodemon(i.e. npm run task2). + +Test result + +Parsed csv strings + +2023-09-15_22h50_54 + +Generated file + +2023-09-15_22h52_06 diff --git a/csvdirectory/nodejs-hw1-ex1.csv b/csvdirectory/nodejs-hw1-ex1.csv new file mode 100644 index 0000000..2521a60 --- /dev/null +++ b/csvdirectory/nodejs-hw1-ex1.csv @@ -0,0 +1,6 @@ +Book,Author,Amount,Price +The Compound Effect,Darren Hardy,5,9.48 +The 7 Habits of Highly Effective People,Stephen R. Covey,4,23.48 +The Miracle Morning,Hal Elrod,10,21.34 +Influence: The Psychology of Persuasion,Robert B. Cialdini,4,12.99 +The ONE Thing,Gary Keller,1,11.18 diff --git a/index.js b/index.js new file mode 100644 index 0000000..e4cac83 --- /dev/null +++ b/index.js @@ -0,0 +1,49 @@ +import EventEmitter from "./utils/EventEmitter.js"; + +const myEmitter = new EventEmitter(); + +function c1() { + console.log('an event occurred!'); +} + +function c2() { + console.log('yet another event occurred!'); +} + +myEmitter.on('eventOne', c1); // Register for eventOne +myEmitter.on('eventOne', c2); // Register for eventOne + +// Register eventOnce for one time execution +myEmitter.once('eventOnce', () => console.log('eventOnce once fired')); +myEmitter.once('init', () => console.log('init once fired')); + +// Register for 'status' event with parameters +myEmitter.on('status', (code, msg)=> console.log(`Got ${code} and ${msg}`)); + + +myEmitter.emit('eventOne'); + +// Emit 'eventOnce' -> After this the eventOnce will be +// removed/unregistered automatically +myEmitter.emit('eventOnce'); + + +myEmitter.emit('eventOne'); +myEmitter.emit('init'); +myEmitter.emit('init'); // Will not be fired +myEmitter.emit('eventOne'); +myEmitter.emit('status', 200, 'ok'); + +// Get listener's count +console.log(myEmitter.listenerCount('eventOne')); + +// Get array of rawListeners// +// Event registered with 'once()' will not be available here after the +// emit has been called +console.log(myEmitter.rawListeners('eventOne')); + +// Get listener's count after remove one or all listeners of 'eventOne' +myEmitter.off('eventOne', c1); +console.log(myEmitter.listenerCount('eventOne')); +myEmitter.off('eventOne', c2); +console.log(myEmitter.listenerCount('eventOne')); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..9b8887a --- /dev/null +++ b/package-lock.json @@ -0,0 +1,425 @@ +{ + "name": "mentoring-introduction", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "mentoring-introduction", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "abbrev": "^1.1.1", + "anymatch": "^3.1.3", + "balanced-match": "^1.0.2", + "binary-extensions": "^2.2.0", + "brace-expansion": "^1.1.11", + "braces": "^3.0.2", + "chokidar": "^3.5.3", + "concat-map": "^0.0.1", + "csvtojson": "^2.0.10", + "debug": "^3.2.7", + "fill-range": "^7.0.1", + "glob-parent": "^5.1.2", + "has-flag": "^3.0.0", + "ignore-by-default": "^1.0.1", + "is-binary-path": "^2.1.0", + "is-extglob": "^2.1.1", + "is-glob": "^4.0.3", + "is-number": "^7.0.0", + "lru-cache": "^6.0.0", + "minimatch": "^3.1.2", + "ms": "^2.1.3", + "nodemon": "^3.0.1", + "nopt": "^1.0.10", + "normalize-path": "^3.0.0", + "picomatch": "^2.3.1", + "pstree.remy": "^1.1.8", + "readdirp": "^3.6.0", + "semver": "^7.5.4", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "to-regex-range": "^5.0.1", + "touch": "^3.1.0", + "undefsafe": "^2.0.5", + "yallist": "^4.0.0" + }, + "devDependencies": {} + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/csvtojson": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/csvtojson/-/csvtojson-2.0.10.tgz", + "integrity": "sha512-lUWFxGKyhraKCW8Qghz6Z0f2l/PqB1W3AO0HKJzGIQ5JRSlR651ekJDiGJbBT4sRNNv5ddnSGVEnsxP9XRCVpQ==", + "dependencies": { + "bluebird": "^3.5.1", + "lodash": "^4.17.3", + "strip-bom": "^2.0.0" + }, + "bin": { + "csvtojson": "bin/csvtojson" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==" + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/nodemon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.1.tgz", + "integrity": "sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..607b18a --- /dev/null +++ b/package.json @@ -0,0 +1,52 @@ +{ + "name": "mentoring-introduction", + "version": "1.0.0", + "description": "Task 3", + "main": "index.js", + "type": "module", + "dependencies": { + "abbrev": "^1.1.1", + "anymatch": "^3.1.3", + "balanced-match": "^1.0.2", + "binary-extensions": "^2.2.0", + "brace-expansion": "^1.1.11", + "braces": "^3.0.2", + "chokidar": "^3.5.3", + "concat-map": "^0.0.1", + "csvtojson": "^2.0.10", + "debug": "^3.2.7", + "fill-range": "^7.0.1", + "glob-parent": "^5.1.2", + "has-flag": "^3.0.0", + "ignore-by-default": "^1.0.1", + "is-binary-path": "^2.1.0", + "is-extglob": "^2.1.1", + "is-glob": "^4.0.3", + "is-number": "^7.0.0", + "lru-cache": "^6.0.0", + "minimatch": "^3.1.2", + "ms": "^2.1.3", + "nodemon": "^3.0.1", + "nopt": "^1.0.10", + "normalize-path": "^3.0.0", + "picomatch": "^2.3.1", + "pstree.remy": "^1.1.8", + "readdirp": "^3.6.0", + "semver": "^7.5.4", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "to-regex-range": "^5.0.1", + "touch": "^3.1.0", + "undefsafe": "^2.0.5", + "yallist": "^4.0.0" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "nodemon index.js", + "task2": "nodemon ./utils/withTime.js", + "task3": "nodemon ./utils/MyCSVFormatter.js" + }, + "keywords": [], + "author": "", + "license": "ISC" +} diff --git a/utils/EventEmitter.js b/utils/EventEmitter.js new file mode 100644 index 0000000..eab759a --- /dev/null +++ b/utils/EventEmitter.js @@ -0,0 +1,67 @@ +export default class EventEmitter { + listeners = {}; // key-value pair + + addListener(eventName, fn) { + this._pushListener(eventName, fn); + } + + on(eventName, fn) { + this._pushListener(eventName, fn); + } + + removeListener(eventName, fn) { + this._filterListeners(eventName, fn); + } + + off(eventName, fn) { + this._filterListeners(eventName, fn); + } + + once(eventName, fn) { + const onceWrapper = (...args)=>{ + fn(...args); + this.off(eventName, onceWrapper); + } + this._pushListener(eventName, onceWrapper); + } + + emit(eventName, ...args) { + if(this.listeners[eventName]){ + this.listeners[eventName].forEach(listener => { + listener(...args); + }); + } + } + + listenerCount(eventName) { + return this.listeners[eventName] ? this.listeners[eventName].length : 0; + } + + rawListeners(eventName) { + if(!this.listeners[eventName]){ + throw new Error("There is no such eventName!") + } + return [...this.listeners[eventName]]; + } + + _pushListener(eventName, fn){ + if(typeof fn !== "function") { + throw new Error("Listener must be a function!") + } + + if(!this.listeners[eventName]){ + this.listeners[eventName] = []; + } + this.listeners[eventName].push(fn); + } + + _filterListeners(eventName, fn){ + if(!this.listeners[eventName]){ + throw new Error("There is no such eventName!") + } + this.listeners[eventName] = this.listeners[eventName].filter((currFn)=>currFn !== fn); + if(this.listeners[eventName].length === 0){ + delete this.listeners[eventName]; + } + } + } diff --git a/utils/MyCSVFormatter.js b/utils/MyCSVFormatter.js new file mode 100644 index 0000000..7335648 --- /dev/null +++ b/utils/MyCSVFormatter.js @@ -0,0 +1,44 @@ +import { open, writeFile, appendFile } from 'node:fs/promises'; +import csv from "csvtojson" + +async function csvToJson(path){ + try { + const newFilePath='./csvdirectory/nodejs-hw1-ex1.txt'; + const file = await open(path); + let headers; + writeFile(newFilePath, ''); + + for await (const line of file.readLines()) { + console.log(line); + csv() + .fromString(line) + .on('header', (headerLine) => { + //header=> [header1, header2, header3] + if (!headers) { + headers = headerLine + } + else { + const formatLine = getFormatLine(headers, headerLine); + appendFile(newFilePath, `${formatLine}\n`); + } + }) + .on('error', (err) => { + console.log(err) + }) + } + } + catch(err){ + console.log(err); + } +} + +function getFormatLine(headers, fields){ + const resultObj = {}; + fields.forEach((field, idx) => { + const key = headers[idx] || `field${idx+1}`; + resultObj[key] = field; + }); + return JSON.stringify(resultObj); +} + +csvToJson('./csvdirectory/nodejs-hw1-ex1.csv'); diff --git a/utils/withTime.js b/utils/withTime.js new file mode 100644 index 0000000..2f125c7 --- /dev/null +++ b/utils/withTime.js @@ -0,0 +1,42 @@ +import EventEmitter from "./EventEmitter.js"; + +class WithTime extends EventEmitter { + + constructor(){ + super(); + } + + async execute(asyncFunc, ...args) { + try{ + const start = new Date().getTime(); + this.emit('begin'); + + const endHandler = (time, data)=>{ + console.log(`Time: ${time}\nData:\n${data}`); + } + this.on('end', endHandler); + + const response = await asyncFunc(...args); + const data = await response.json(); + const result = JSON.stringify(data, null, " ") + const end = new Date().getTime(); + const time = (end - start)/1000; + + this.emit('end', time, result); + + } + catch(err){ + console.log(err); + } + + } +} + +const withTime = new WithTime(); + +withTime.on('begin', () => console.log('About to execute')); +withTime.on('end', () => console.log('Done with execute')); + +await withTime.execute(fetch, 'https://jsonplaceholder.typicode.com/posts/1'); + +console.log(withTime.rawListeners("end"));