├── .DS_Store
├── .gitignore
├── algo
├── animate-right.html
├── common-ancestor.html
├── dom-store.html
├── fibonacci-using-closure.js
├── find-node-in-another-similar-tree.html
├── mirror-dom.js
└── print-dom.html
├── browser
├── check-user-activity-on-page
│ ├── focus.html
│ └── visibility.html
├── cookies
│ ├── client-credentials-grant.png
│ ├── cookies-local-session.md
│ ├── cookies-session.md
│ └── security.md
├── dom-properties-methods
│ └── readme.md
├── dom
│ └── readme.md
├── event-delegation
│ ├── bubble-up.png
│ ├── event-bubbling.gif
│ ├── event-capturing-bubbling.png
│ └── readme.md
├── js
│ └── security.md
├── oauth
│ └── readme.md
├── render
│ ├── browser.png
│ ├── cssom-timeline.png
│ ├── dom-timeline.png
│ ├── gecko.jpg
│ ├── layout-viewport.png
│ ├── readme.md
│ ├── render-cssom.png
│ ├── render-dom.png
│ ├── render.png
│ └── webkit.png
├── scroll
│ ├── infinite.html
│ ├── nested.html
│ ├── readme.md
│ └── simple.html
├── tcp-handshake
│ └── readme.md
└── what-happens-when
│ └── readme.md
├── css
├── box-model
│ ├── box-model.png
│ └── readme.md
├── flex-box
│ └── readme.md
└── priority
│ ├── css-priority.jpg
│ └── readme.md
├── implementation
├── LWWElementSet
│ ├── index.js
│ ├── index.test.js
│ ├── package.json
│ └── yarn.lock
├── array
│ ├── filter.js
│ ├── flatten.js
│ ├── forEach.js
│ ├── map.js
│ └── reduce.js
├── binary-indexed-tree
│ └── index.js
├── bind
│ └── index.js
├── clearAllTimeouts
│ └── index.js
├── debounce-vs-throttle
│ ├── debouncing-vs-throttling.gif
│ ├── index.html
│ └── index.js
├── event-emitter
│ ├── advanced.js
│ ├── advanced.ts
│ ├── basic.js
│ ├── event.jpg
│ ├── readme.md
│ ├── simple-subclass.js
│ └── standard.js
├── fetch-timeout
│ └── index.js
├── fetch
│ ├── index.html
│ └── index.js
├── heap
│ └── index.js
├── lfu-cache
│ └── index.js
├── lru-cache
│ ├── use_linked_list_hashtable.js
│ └── use_map.js
├── min-queue
│ ├── advanced.js
│ └── easy.js
├── objects-merge
│ └── index.js
├── observable
│ └── simple.js
├── promise.all
│ └── index.js
├── promise.pool
│ └── index.js
├── promise
│ └── simple.js
├── promisify
│ └── index.js
├── pubsub-vs-observer
│ ├── observer.png
│ ├── pubsub.gif
│ ├── readme.md
│ └── vs.jpeg
├── pubsub
│ └── index.js
├── server-sent-events
│ ├── client
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── public
│ │ │ ├── favicon.ico
│ │ │ ├── index.html
│ │ │ ├── logo192.png
│ │ │ ├── logo512.png
│ │ │ ├── manifest.json
│ │ │ └── robots.txt
│ │ ├── src
│ │ │ ├── App.css
│ │ │ ├── App.js
│ │ │ ├── App.test.js
│ │ │ ├── index.css
│ │ │ ├── index.js
│ │ │ ├── logo.svg
│ │ │ ├── reportWebVitals.js
│ │ │ └── setupTests.js
│ │ └── yarn.lock
│ ├── demo.png
│ ├── readme.md
│ └── server
│ │ ├── package.json
│ │ └── server.js
├── sleep
│ └── index.js
└── virtual-dom
│ ├── .DS_Store
│ └── prototype
│ ├── main.html
│ └── main.js
├── js-knowledge
├── .DS_Store
├── amd-vs-common-es
│ └── readme.md
├── apply-call-bind
│ ├── apply.js
│ ├── bind.js
│ └── call.js
├── call-stack-overflow
│ └── index.js
├── callback-promise-generator-asyncwait
│ ├── async-await.js
│ ├── generator.js
│ ├── promise.js
│ └── readme.md
├── child-process
│ ├── child.js
│ ├── parent.js
│ └── readme.md
├── chrome-profile-template
│ ├── index.html
│ └── script.js
├── class-vs-prototype
│ ├── class.js
│ └── prototype.js
├── closure
│ └── index.js
├── const-let-var
│ └── readme.md
├── currying
│ ├── index.js
│ └── readme.md
├── equal
│ └── index.js
├── event-loop
│ ├── event-loop.png
│ └── readme.md
├── hoist
│ └── index.js
├── memory-object-life
│ └── index.js
├── memory-profile-on-web
│ ├── .DS_Store
│ ├── 1a.png
│ ├── 1b.png
│ ├── index.html
│ ├── js-memory-management.md
│ └── script.js
├── middleware
│ └── readme.md
├── mixins
│ └── readme.md
├── node-cluster
│ └── index.js
├── prototype
│ ├── basic.js
│ └── chain.js
├── react
│ └── readme.md
├── referencing
│ ├── array.js
│ ├── object.js
│ ├── primitive.js
│ └── readme.md
├── self-invoking
│ └── index.js
├── singleton
│ ├── God.js
│ └── index.js
└── this
│ ├── 1_constructor.js
│ ├── 2_apply_call_bind.js
│ ├── 3_method.js
│ ├── 4_global.js
│ ├── 6_arrow.js
│ └── sample_quesiton.js
├── optimization
├── backend.md
└── frontend.md
├── react-widgets-implementation
├── books-paginated-search
│ ├── .gitignore
│ ├── README.md
│ ├── jsconfig.json
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ ├── src
│ │ ├── App.js
│ │ ├── App.module.css
│ │ ├── App.test.js
│ │ ├── api.js
│ │ ├── components
│ │ │ └── BookList
│ │ │ │ └── index.js
│ │ ├── hooks
│ │ │ └── useDebounce.js
│ │ ├── index.css
│ │ ├── index.js
│ │ ├── logo.svg
│ │ ├── reducers
│ │ │ └── appReducer.js
│ │ ├── reportWebVitals.js
│ │ └── setupTests.js
│ └── yarn.lock
├── context-counter
│ ├── README.md
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ ├── src
│ │ ├── App.css
│ │ ├── App.js
│ │ ├── App.test.js
│ │ ├── components
│ │ │ └── Coordinate.js
│ │ ├── contexts
│ │ │ └── AppContext.js
│ │ ├── index.css
│ │ ├── index.js
│ │ ├── logo.svg
│ │ ├── reportWebVitals.js
│ │ └── setupTests.js
│ └── yarn.lock
├── credit-card
│ ├── README.md
│ ├── Screenshot 2023-04-26 at 15.53.49.png
│ ├── Screenshot 2023-04-26 at 15.54.01.png
│ ├── Screenshot 2023-04-29 at 01.06.18.png
│ ├── Screenshot 2023-04-29 at 01.06.23.png
│ ├── Screenshot 2023-04-29 at 01.06.34.png
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ ├── robots.txt
│ │ └── visa_logo.png
│ └── src
│ │ ├── App.css
│ │ ├── App.js
│ │ ├── App.test.js
│ │ ├── index.css
│ │ ├── index.js
│ │ ├── logo.svg
│ │ ├── reportWebVitals.js
│ │ └── setupTests.js
├── debounced-pokemon-search
│ ├── .eslintrc.json
│ ├── README.md
│ ├── app
│ │ ├── api
│ │ │ └── pokemon
│ │ │ │ └── route.js
│ │ ├── favicon.ico
│ │ ├── globals.css
│ │ ├── layout.js
│ │ ├── page.js
│ │ └── page.module.css
│ ├── components
│ │ ├── PokemonList
│ │ │ └── index.js
│ │ └── SearchInput
│ │ │ └── index.js
│ ├── hooks
│ │ └── useDebounce.js
│ ├── jsconfig.json
│ ├── mock-db
│ │ └── index.js
│ ├── next.config.js
│ ├── package-lock.json
│ ├── package.json
│ └── public
│ │ ├── next.svg
│ │ └── vercel.svg
├── debounced-search
│ ├── .gitignore
│ ├── README.md
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ └── src
│ │ ├── App.css
│ │ ├── App.js
│ │ ├── App.test.js
│ │ ├── components
│ │ └── NewsCell
│ │ │ ├── index.js
│ │ │ └── style.css
│ │ ├── index.css
│ │ ├── index.js
│ │ ├── reportWebVitals.js
│ │ ├── setupTests.js
│ │ └── utils
│ │ └── useDebounce.js
├── game-of-life
│ ├── .gitignore
│ ├── README.md
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ └── src
│ │ ├── App.css
│ │ ├── App.js
│ │ ├── App.test.js
│ │ ├── index.css
│ │ ├── index.js
│ │ ├── logo.svg
│ │ ├── reportWebVitals.js
│ │ └── setupTests.js
├── pokemon-search
│ ├── .gitignore
│ ├── CODEOWNERS
│ ├── README.md
│ ├── example.png
│ ├── lerna.json
│ ├── package.json
│ ├── packages
│ │ ├── poke-search-js
│ │ │ ├── .eslintrc.json
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── components
│ │ │ │ └── PokeCard
│ │ │ │ │ └── index.js
│ │ │ ├── next.config.js
│ │ │ ├── package.json
│ │ │ ├── pages
│ │ │ │ ├── _app.js
│ │ │ │ └── index.js
│ │ │ ├── public
│ │ │ │ ├── favicon.ico
│ │ │ │ └── pokeapi.png
│ │ │ ├── styles
│ │ │ │ ├── Card.modue.css
│ │ │ │ ├── Home.module.css
│ │ │ │ └── globals.css
│ │ │ └── yarn.lock
│ │ └── poke-search-ts
│ │ │ ├── .eslintrc.json
│ │ │ ├── README.md
│ │ │ ├── next-env.d.ts
│ │ │ ├── next.config.js
│ │ │ ├── package.json
│ │ │ ├── pages
│ │ │ ├── _app.tsx
│ │ │ └── index.tsx
│ │ │ ├── public
│ │ │ ├── favicon.ico
│ │ │ └── pokeapi.png
│ │ │ ├── styles
│ │ │ ├── Home.module.css
│ │ │ └── globals.css
│ │ │ └── tsconfig.json
│ └── yarn.lock
├── question-list
│ ├── README.md
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ ├── result.png
│ └── src
│ │ ├── App.css
│ │ ├── App.js
│ │ ├── App.test.js
│ │ ├── index.css
│ │ ├── index.js
│ │ ├── logo.svg
│ │ ├── mock_questions.json
│ │ ├── mock_submissions.json
│ │ ├── reportWebVitals.js
│ │ └── setupTests.js
├── random-users
│ ├── .eslintrc.json
│ ├── .gitignore
│ ├── README.md
│ ├── jsconfig.json
│ ├── next.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ │ ├── next.svg
│ │ └── vercel.svg
│ └── src
│ │ ├── app
│ │ ├── globals.css
│ │ ├── layout.js
│ │ ├── page.js
│ │ └── page.module.css
│ │ ├── components
│ │ └── UserCell
│ │ │ └── index.js
│ │ └── utils
│ │ ├── debounceFn.js
│ │ └── useDebounce.js
├── react-debounce-vs-throttle
│ ├── README.md
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ └── src
│ │ ├── App.css
│ │ ├── App.js
│ │ ├── App.test.js
│ │ ├── hooks
│ │ ├── useDebounce.js
│ │ └── useThrottle.js
│ │ ├── index.css
│ │ ├── index.js
│ │ ├── react-debounce-vs-throttle.gif
│ │ ├── reportWebVitals.js
│ │ └── setupTests.js
├── react-fetch-hook
│ ├── README.md
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ └── src
│ │ ├── App.css
│ │ ├── App.js
│ │ ├── App.test.js
│ │ ├── hooks
│ │ ├── useFetch.js
│ │ └── useFeteches.js
│ │ ├── index.css
│ │ ├── index.js
│ │ ├── reportWebVitals.js
│ │ └── setupTests.js
├── react-reducer
│ ├── README.md
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ └── src
│ │ ├── App.css
│ │ ├── App.js
│ │ ├── App.test.js
│ │ ├── index.css
│ │ ├── index.js
│ │ ├── reducers
│ │ └── countReducer.js
│ │ ├── reportWebVitals.js
│ │ └── setupTests.js
├── recent-trades
│ ├── .gitignore
│ ├── README.md
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ └── src
│ │ ├── App.css
│ │ ├── App.js
│ │ ├── App.test.js
│ │ ├── index.css
│ │ ├── index.js
│ │ ├── logo.svg
│ │ ├── reportWebVitals.js
│ │ └── setupTests.js
├── stock-prices
│ ├── .eslintrc.json
│ ├── .gitignore
│ ├── README.md
│ ├── jsconfig.json
│ ├── next.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ │ ├── next.svg
│ │ └── vercel.svg
│ └── src
│ │ ├── app
│ │ ├── StockList
│ │ │ ├── index.js
│ │ │ └── index.module.css
│ │ ├── favicon.ico
│ │ ├── globals.css
│ │ ├── layout.js
│ │ ├── page.js
│ │ └── page.module.css
│ │ └── hooks
│ │ └── useFetch.js
├── suspense-playground
│ ├── .gitignore
│ ├── README.md
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ └── src
│ │ ├── App.css
│ │ ├── App.js
│ │ ├── App.test.js
│ │ ├── components
│ │ ├── LoadingIndicator.js
│ │ └── Posts.js
│ │ ├── index.css
│ │ ├── index.js
│ │ ├── logo.svg
│ │ ├── reportWebVitals.js
│ │ ├── setupTests.js
│ │ └── utils
│ │ └── genFetch.js
├── tip-calculator
│ ├── README.md
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ └── src
│ │ ├── App.css
│ │ ├── App.js
│ │ ├── App.test.js
│ │ ├── index.css
│ │ ├── index.js
│ │ ├── logo.svg
│ │ ├── reportWebVitals.js
│ │ └── setupTests.js
└── todo-list
│ ├── README.md
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
│ └── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── reportWebVitals.js
│ └── setupTests.js
├── readme.md
└── vanilla-widgets-implementation
├── 2048
├── index.html
├── index.js
└── style.css
├── DOMRenderer
├── index.html
└── index.js
├── accordion
├── index.html
└── src
│ ├── index.js
│ └── styles.css
├── analog-clock
├── index.html
├── index.js
└── style.css
├── carousel
├── index.html
└── src
│ ├── index.js
│ └── styles.css
├── csv-viewer
├── index.html
├── src
│ ├── index.js
│ └── styles.css
└── test.csv
├── debounce-and-throttle
├── debouncing-vs-throttling.gif
├── index.html
└── index.js
├── debounced-searchbar
├── index.html
└── src
│ ├── index.js
│ └── styles.css
├── draggable-box
├── draggable.js
├── index.html
└── style.css
├── game-of-life
├── index.html
├── index.js
└── styles.css
├── images-at-corners
├── images
│ ├── 0.png
│ ├── 1.png
│ ├── 2.png
│ └── 3.png
├── index.html
└── src
│ ├── index.js
│ └── styles.css
├── instagram-create-poll
├── index.html
└── src
│ ├── index.js
│ └── styles.css
├── query
├── index.html
└── src
│ └── index.js
├── simple-sudoku
├── README.md
├── index.html
├── widget.css
└── widget.js
├── snake-game
├── index.html
├── index.js
└── style.css
├── stock-prices
├── index.html
└── src
│ ├── index.js
│ └── styles.css
├── tableview
├── index.html
└── src
│ ├── index.js
│ └── styles.css
└── tic-tac-toe
├── index.html
├── index.js
└── styles.css
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/.DS_Store
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode/
2 | .DS_Store
3 | node_modules/
4 | .next/
--------------------------------------------------------------------------------
/algo/animate-right.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ` is green because the score is higher
23 |
24 | Example2
25 | ---
26 | ```css
27 | /*00020*/
28 | .a .b
29 | {
30 | color: red;
31 | }
32 |
33 | /*00010*/
34 | .b
35 | {
36 | /*now becomes 10010*/
37 | color: yellow !important;
38 | }
39 | ```
40 |
41 | Example3
42 | ---
43 | ```html
44 | // supposed: green, result: green
45 |
Hello
46 |
47 | // supposed: red, result: green
48 |
Hello
49 | ```
50 | ```css
51 | .red
52 | {
53 | color: red;
54 | }
55 |
56 | .green
57 | {
58 | color: green;
59 | }
60 | ```
61 | The result of `
Hello
` is GREEN, why?
62 | - class attribute in your HTML doesn't care about order of classes
63 | - BUT the order of declaration of your CSS classess in your CSS files
64 |
65 | ref:
66 | https://teamtreehouse.com/community/priority-of-a-class-when-there-are-two-classes-in-the-same-element
--------------------------------------------------------------------------------
/implementation/LWWElementSet/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "LWWElementSet",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "author": "calvinchankf",
6 | "license": "MIT",
7 | "devDependencies": {
8 | "jest": "^26.6.1"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/implementation/array/filter.js:
--------------------------------------------------------------------------------
1 | /*
2 | classic interivew question
3 | Implementation the Array Filter
4 | here is my least implementation to extend the Array class using protoype
5 | */
6 | if (!Array.prototype.myFilter) {
7 | Array.prototype.myFilter = function (callback) {
8 | if (typeof callback !== "function") {
9 | throw new Error(callback + " is not a function");
10 | }
11 | const result = [];
12 | let i = 0;
13 | for (i; i < this.length; i++) {
14 | const temp = callback(this[i], i);
15 | if (typeof temp !== "boolean") {
16 | throw new Error(callback + " is not a boolean");
17 | }
18 | if (temp == true) {
19 | result.push(this[i]);
20 | }
21 | }
22 | return result;
23 | };
24 | }
25 |
26 | const a = [1, 2, 3, 4];
27 | const result = a.myFilter((item, idx) => {
28 | return item % 2 == 0;
29 | });
30 |
31 | console.log(result);
32 |
--------------------------------------------------------------------------------
/implementation/array/flatten.js:
--------------------------------------------------------------------------------
1 | /*
2 | Classic interivew question: implement `flatten`
3 | */
4 |
5 | // 1st: recursion
6 | Array.prototype.flatten1 = function() {
7 | const res = [];
8 | for (let x of this) {
9 | if (Array.isArray(x)) {
10 | res.push(...x.flatten1())
11 | } else {
12 | res.push(x)
13 | }
14 | }
15 | return res
16 | }
17 |
18 | let a = [
19 | 1,
20 | [2, 3, 4],
21 | [
22 | [5, 6],
23 | [7, 8],
24 | ],
25 | 9,
26 | ];
27 | console.log(a.flatten1());
28 | console.log("---");
29 |
30 | // 2nd: iterative
31 | Array.prototype.flatten2 = function() {
32 | const res = [];
33 | let q = [this];
34 | while (q.length > 0) {
35 | const head = q.shift();
36 | if (Array.isArray(head)) {
37 | q = [...head, ...q];
38 | } else {
39 | res.push(head);
40 | }
41 | }
42 | return res;
43 | }
44 |
45 | a = [
46 | 1,
47 | [2, 3, 4],
48 | [
49 | [5, 6],
50 | [7, 8],
51 | ],
52 | 9,
53 | ];
54 | console.log(a.flatten2());
55 |
56 | /*
57 | followup: object
58 | */
59 |
--------------------------------------------------------------------------------
/implementation/array/forEach.js:
--------------------------------------------------------------------------------
1 | /*
2 | classic interivew question
3 | Implementation the Array Map
4 | here is my least implementation to extend the Array class using protoype
5 | */
6 | if (!Array.prototype.myForEach) {
7 | Array.prototype.myForEach = function (callback) {
8 | if (typeof callback !== "function") {
9 | throw new Error(callback + " is not a function");
10 | }
11 | for (let i = 0; i < this.length; i++) {
12 | callback(this[i], i);
13 | }
14 | };
15 | }
16 |
17 | const a = [1, 2, 3];
18 | a.myForEach((item, idx) => {
19 | console.log(item, idx);
20 | });
21 |
--------------------------------------------------------------------------------
/implementation/array/map.js:
--------------------------------------------------------------------------------
1 | /*
2 | classic interivew question
3 | Implementation the Array Map
4 | here is my least implementation to extend the Array class using protoype
5 | */
6 | if (!Array.prototype.myMap) {
7 | Array.prototype.myMap = function (callback) {
8 | if (typeof callback !== "function") {
9 | throw new Error(callback + " is not a function");
10 | }
11 | const result = [];
12 | for (let i = 0; i < this.length; i++) {
13 | const temp = callback(this[i], i);
14 | result.push(temp);
15 | }
16 | return result;
17 | };
18 | }
19 |
20 | const a = [1, 2, 3];
21 | const result = a.myMap((item, idx) => {
22 | return item * 2;
23 | });
24 |
25 | console.log(result);
26 |
--------------------------------------------------------------------------------
/implementation/bind/index.js:
--------------------------------------------------------------------------------
1 | Function.prototype.bindPolyfill = function(obj) {
2 | const context = this;
3 | return function(...args){
4 | return context.call(obj, ...args)
5 | }
6 | }
--------------------------------------------------------------------------------
/implementation/debounce-vs-throttle/debouncing-vs-throttling.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/implementation/debounce-vs-throttle/debouncing-vs-throttling.gif
--------------------------------------------------------------------------------
/implementation/debounce-vs-throttle/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
Document
8 |
9 |
10 |
11 |
12 |
13 | Default:
14 |
15 |
16 |
17 | Debounce:
18 |
19 |
20 |
21 | Throttle:
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/implementation/event-emitter/basic.js:
--------------------------------------------------------------------------------
1 | const EventEmitter = require("events");
2 |
3 | // init an emitter object
4 | const myEmitter = new EventEmitter();
5 |
6 | // event listener
7 | myEmitter.on("event", () => {
8 | console.log("an event occurred!");
9 | });
10 |
11 | // emit an event
12 | myEmitter.emit("event");
13 |
--------------------------------------------------------------------------------
/implementation/event-emitter/event.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/implementation/event-emitter/event.jpg
--------------------------------------------------------------------------------
/implementation/event-emitter/simple-subclass.js:
--------------------------------------------------------------------------------
1 | const EventEmitter = require("events");
2 |
3 | // extend the class
4 | class MyEmitter extends EventEmitter {}
5 |
6 | // init an emitter object
7 | const myEmitter = new MyEmitter();
8 |
9 | // event listener
10 | myEmitter.on("event", () => {
11 | console.log("an event occurred!");
12 | });
13 |
14 | // emit an event
15 | myEmitter.emit("event");
16 |
--------------------------------------------------------------------------------
/implementation/fetch/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Browser Fetch Implementation
5 |
6 |
7 |
8 |
9 |
10 |
Here is an implementation of Browser fetch from scatch
11 |
12 | Hacker News url
13 | Invalid url
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/implementation/lru-cache/use_map.js:
--------------------------------------------------------------------------------
1 | // leetcode146
2 | class DLLNode {
3 | constructor(key = -1, val = -1) {
4 | this.key = key
5 | this.val = val
6 | this.prev = null
7 | this.next = null
8 | }
9 | }
10 | class LRUCache {
11 | constructor(capacity) {
12 | this.cap = capacity
13 | this.map = new Map()
14 | }
15 | get(key) {
16 | if (this.map.has(key) === false) {
17 | return -1
18 | }
19 | const value = this.map.get(key)
20 | this.map.delete(key)
21 | this.map.set(key, value)
22 | return value
23 | }
24 | put(key, value) {
25 | if (this.map.has(key)) {
26 | this.map.delete(key)
27 | }
28 | this.map.set(key, value)
29 | if (this.map.size > this.cap) {
30 | const oldest = this.map.keys().next().value
31 | this.map.delete(oldest)
32 | }
33 | }
34 | }
35 |
36 | const c = new LRUCache(2)
37 | c.put("c", 123)
38 | c.put("a", 456)
39 | c.put("b", 789)
40 | console.log(c.get("c"))
41 | console.log(c.get("a"))
42 | c.put("d", 123)
43 | console.log(c.get("c"))
44 | console.log(c.get("a"))
45 | console.log(c.get("d"))
--------------------------------------------------------------------------------
/implementation/promise.all/index.js:
--------------------------------------------------------------------------------
1 | var promiseAll = async function(functions) {
2 | const n = functions.length
3 | const res = Array(n).fill(null)
4 | let cnt = 0
5 | return new Promise((resolve, reject) => {
6 | for (let i = 0; i < n; i++) {
7 | const f = functions[i]
8 | f().then(val => {
9 | res[i] = val
10 | cnt += 1
11 |
12 | if (cnt === n) {
13 | resolve(res)
14 | }
15 | }).catch(error => reject(error))
16 | }
17 | });
18 | };
19 |
20 | const promise = promiseAll([
21 | () => new Promise(res => res(42)),
22 | () => new Promise(res => res(1)),
23 | () => new Promise(res => res(2)),
24 | ])
25 | promise.then(console.log); // [42, 1, 2]
--------------------------------------------------------------------------------
/implementation/promise.pool/index.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | var promisePool = async function(functions, n) {
4 | const res = []
5 | const worker = async () => {
6 | if (functions.length === 0) {
7 | return
8 | }
9 | const fn = functions.shift()
10 | const temp = await fn()
11 | res.push(temp)
12 | await worker()
13 | }
14 | const nPromises = []
15 | for (let i = 0; i < n; i++) {
16 | nPromises.push(worker())
17 | }
18 | await Promise.all(nPromises)
19 | return res
20 | };
21 |
22 | const start = performance.now()
23 |
24 | promisePool([
25 | () => new Promise((resolve, _rej) => setTimeout(() => resolve(1), 3000)),
26 | () => new Promise((resolve, _rej) => setTimeout(() => resolve(2), 200)),
27 | () => new Promise((resolve, _rej) => setTimeout(() => resolve(3), 3000)),
28 | ], 2).then((data) => {
29 | const end = performance.now()
30 | console.log(`Executed functions and return ${JSON.stringify(data)} within ${end - start}ms`)
31 | })
32 | // Executed functions and return [2,1,3] within 3207.1921259984374ms
--------------------------------------------------------------------------------
/implementation/promisify/index.js:
--------------------------------------------------------------------------------
1 | const promisify = fn => {
2 | return async function(...args) {
3 | return new Promise((resolve, reject) => {
4 |
5 | const callback = (value, error) => {
6 | if (error) {
7 | reject(error)
8 | } else {
9 | resolve(value)
10 | }
11 | }
12 |
13 | fn(...args, callback)
14 | })
15 | }
16 | };
17 |
18 | // test
19 | function do_something(...args) {
20 | const callback = args.pop()
21 | if (args.filter(x => typeof x === 'number').length !== args.length) {
22 | const err = new Error('every input must be a number');
23 | callback(null, err);
24 | } else {
25 | const total = args.reduce((acc, cur) => acc + cur, 0) // my do_something is to sum all inputs
26 | callback(total);
27 | }
28 | }
29 |
30 | const promisified_do_something = promisify(do_something)
31 |
32 | promisified_do_something(100, 99).then((res) => console.log(res))
33 |
34 | promisified_do_something(1,10,100,1000,10000).then((res) => console.log(res))
35 |
36 | promisified_do_something('a',10,100,1000,10000).then((res) => console.log(res))
--------------------------------------------------------------------------------
/implementation/pubsub-vs-observer/observer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/implementation/pubsub-vs-observer/observer.png
--------------------------------------------------------------------------------
/implementation/pubsub-vs-observer/pubsub.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/implementation/pubsub-vs-observer/pubsub.gif
--------------------------------------------------------------------------------
/implementation/pubsub-vs-observer/vs.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/implementation/pubsub-vs-observer/vs.jpeg
--------------------------------------------------------------------------------
/implementation/server-sent-events/client/.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 |
--------------------------------------------------------------------------------
/implementation/server-sent-events/client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.11.4",
7 | "@testing-library/react": "^11.1.0",
8 | "@testing-library/user-event": "^12.1.10",
9 | "react": "^17.0.1",
10 | "react-dom": "^17.0.1",
11 | "react-scripts": "4.0.2",
12 | "web-vitals": "^1.0.1"
13 | },
14 | "scripts": {
15 | "start": "react-scripts start",
16 | "build": "react-scripts build",
17 | "test": "react-scripts test",
18 | "eject": "react-scripts eject"
19 | },
20 | "eslintConfig": {
21 | "extends": [
22 | "react-app",
23 | "react-app/jest"
24 | ]
25 | },
26 | "browserslist": {
27 | "production": [
28 | ">0.2%",
29 | "not dead",
30 | "not op_mini all"
31 | ],
32 | "development": [
33 | "last 1 chrome version",
34 | "last 1 firefox version",
35 | "last 1 safari version"
36 | ]
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/implementation/server-sent-events/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/implementation/server-sent-events/client/public/favicon.ico
--------------------------------------------------------------------------------
/implementation/server-sent-events/client/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/implementation/server-sent-events/client/public/logo192.png
--------------------------------------------------------------------------------
/implementation/server-sent-events/client/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/implementation/server-sent-events/client/public/logo512.png
--------------------------------------------------------------------------------
/implementation/server-sent-events/client/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/implementation/server-sent-events/client/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/implementation/server-sent-events/client/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | font-size: xx-large;
4 | }
5 |
6 | .App-logo {
7 | height: 40vmin;
8 | pointer-events: none;
9 | }
10 |
11 | @media (prefers-reduced-motion: no-preference) {
12 | .App-logo {
13 | animation: App-logo-spin infinite 20s linear;
14 | }
15 | }
16 |
17 | .App-link {
18 | color: #61dafb;
19 | }
20 |
21 | @keyframes App-logo-spin {
22 | from {
23 | transform: rotate(0deg);
24 | }
25 | to {
26 | transform: rotate(360deg);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/implementation/server-sent-events/client/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render(
);
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/implementation/server-sent-events/client/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/implementation/server-sent-events/client/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | ReactDOM.render(
8 |
9 |
10 | ,
11 | document.getElementById('root')
12 | );
13 |
14 | // If you want to start measuring performance in your app, pass a function
15 | // to log results (for example: reportWebVitals(console.log))
16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17 | reportWebVitals();
18 |
--------------------------------------------------------------------------------
/implementation/server-sent-events/client/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/implementation/server-sent-events/client/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/implementation/server-sent-events/demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/implementation/server-sent-events/demo.png
--------------------------------------------------------------------------------
/implementation/server-sent-events/readme.md:
--------------------------------------------------------------------------------
1 | # Hello World to Server-Sent Events
2 |
3 | Run the server
4 |
5 | ```
6 | cd ./server
7 | node server.js
8 | ```
9 |
10 | Run the client
11 |
12 | ```
13 | cd ./client
14 | yarn start
15 | ```
16 |
17 | Then you would see the RBG numbers and color of text being update for every 2 seconds
18 |
19 | 
20 |
21 | Don't forget to npm install in both folders
22 |
--------------------------------------------------------------------------------
/implementation/server-sent-events/server/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "hello-world-to-sse",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "server.js",
6 | "scripts": {
7 | "start": "node server.js"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC"
12 | }
13 |
--------------------------------------------------------------------------------
/implementation/sleep/index.js:
--------------------------------------------------------------------------------
1 | const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
2 | module.exports = sleep;
3 |
--------------------------------------------------------------------------------
/implementation/virtual-dom/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/implementation/virtual-dom/.DS_Store
--------------------------------------------------------------------------------
/implementation/virtual-dom/prototype/main.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Virtual DOM Prototype
4 |
5 |
6 |
7 |
8 | Let's build a simple Virtual DOM from scratch with vanilla
9 | Javascript
10 |
11 |
12 |
refresh random
13 |
14 | 👆🏻the gif doesnt reload even random number is being reloaded, our
15 | virtual dom works 🎉
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/js-knowledge/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/js-knowledge/.DS_Store
--------------------------------------------------------------------------------
/js-knowledge/apply-call-bind/apply.js:
--------------------------------------------------------------------------------
1 | // apply: call the function with an array(u can put arguments into it)
2 |
3 | let customer1 = {
4 | name: 'Leo',
5 | email: 'leo@gmail.com'
6 | };
7 | let customer2 = {
8 | name: 'Nat',
9 | email: 'nat@hotmail.com'
10 | };
11 |
12 | function greeting(text, text2) {
13 | console.log(`${text} ${this.name}, ${text2}`);
14 | }
15 | greeting.apply(customer1, ['Hello', 'How are you?']); // Hello Leo, How are you?
16 | greeting.apply(customer2, ['Hello', 'How are you?']); // Hello Natm How are you?
17 |
18 | greeting.apply(customer1, []); // undefined Leo, undefined
19 | greeting.apply(customer1, 'Hello'); // this will crash because only an array is allowed to be passed as an argument
--------------------------------------------------------------------------------
/js-knowledge/apply-call-bind/call.js:
--------------------------------------------------------------------------------
1 | // call: call the function with arguments
2 |
3 | let customer1 = {
4 | name: 'Leo',
5 | email: 'leo@gmail.com'
6 | };
7 | let customer2 = {
8 | name: 'Nat',
9 | email: 'nat@hotmail.com'
10 | };
11 |
12 | function greeting(text) {
13 | console.log(`${text} ${this.name}`);
14 | }
15 |
16 | greeting.call(customer1, 'Hello'); // Hello Leo
17 | greeting.call(customer2, 'Hello'); // Hello Nat
18 |
19 | // greeting() just is just declared with one argument, only Hello will be printed
20 | greeting.call(customer1, 'Hello', 'How are you?'); // Hello Leo
21 |
22 | greeting.call(customer1, ['Hello', 'How are you?']); // Hello,How are you? Leo
23 |
24 | greeting.call(customer1, {
25 | a: 1,
26 | b: 2
27 | }); // [object Object] Leo
--------------------------------------------------------------------------------
/js-knowledge/call-stack-overflow/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | RangeError: Maximum call stack size exceeded
3 | 9136
4 | */
5 | const f = (num) => {
6 | try {
7 | f(num+1)
8 | } catch (error) {
9 | console.log(error)
10 | console.log(num)
11 | }
12 | }
13 | f(0)
--------------------------------------------------------------------------------
/js-knowledge/callback-promise-generator-asyncwait/async-await.js:
--------------------------------------------------------------------------------
1 | const fetchData = () => {
2 |
3 | // e.g. 1
4 | // return Promise.resolve('hi, i am from promise')
5 |
6 | // e.g. 2
7 | return new Promise((resolve, reject) => {
8 | setTimeout(() => {
9 | resolve("hi, i am from promise");
10 | }, 250);
11 | });
12 | }
13 |
14 | const runit = async () => {
15 | try {
16 | const result = await fetchData()
17 | console.log(result)
18 | } catch (error) {
19 | console.error(error)
20 | }
21 | }
22 |
23 | runit()
--------------------------------------------------------------------------------
/js-knowledge/callback-promise-generator-asyncwait/generator.js:
--------------------------------------------------------------------------------
1 | function* gen(param) {
2 | for (let i = 0; i < 3; i++) {
3 | yield (i + 1) * param
4 | }
5 | return 4 * param
6 | }
7 |
8 | var g = gen(2); // "Generator { }"
9 | console.log(g.next()) // 2 false
10 | console.log(g.next()) // 4 false
11 | console.log(g.next()) // 6 false
12 | console.log(g.next()) // 8 true
--------------------------------------------------------------------------------
/js-knowledge/callback-promise-generator-asyncwait/promise.js:
--------------------------------------------------------------------------------
1 | let p = new Promise((resolve, reject) => {
2 | // We call resolve(...) when what we were doing asynchronously was successful, and reject(...) when it failed.
3 | // In this example, we use setTimeout(...) to simulate async code.
4 | // In reality, you will probably be using something like XHR or an HTML5 API.
5 | setTimeout(function () {
6 | resolve("Success!"); // Yay! Everything went well!
7 | }, 250);
8 | });
9 |
10 | p.then((successMessage) => {
11 | // successMessage is whatever we passed in the resolve(...) function above.
12 | // It doesn't have to be a string, but if it is only a succeed message, it probably will be.
13 | console.log("Yay! " + successMessage);
14 | }, (errorMessage) => {
15 | console.log("OH... " + errorMessage);
16 | });
17 |
18 | console.log(p);
--------------------------------------------------------------------------------
/js-knowledge/child-process/child.js:
--------------------------------------------------------------------------------
1 | process.on('message', function (m) {
2 | console.log('message from parent: ' + JSON.stringify(m));
3 | });
4 |
5 | process.send({
6 | from: 'child'
7 | });
--------------------------------------------------------------------------------
/js-knowledge/child-process/parent.js:
--------------------------------------------------------------------------------
1 | var child_process = require('child_process');
2 |
3 | var child = child_process.fork('./child.js');
4 |
5 | child.on('message', function (m) {
6 | console.log('message from child: ' + JSON.stringify(m));
7 | });
8 |
9 | child.send({
10 | from: 'parent'
11 | });
--------------------------------------------------------------------------------
/js-knowledge/child-process/readme.md:
--------------------------------------------------------------------------------
1 | Child Prcocess
2 | ===
3 | Node is single-threaded. If we want to work on tasks parallelly, we can try to use child_process. Which helps us to 'spawn' a new process in our machine, and the processes can communicate through IPC(Inter Process Communication)
4 |
5 | Some commands
6 | ---
7 | create an instance of node with IPC support
8 | ```
9 | child_process.fork()
10 | ```
11 |
12 | run any command and creat IPC channel
13 | ```
14 | child_process.spawn()
15 | ```
16 |
17 | run any command in the child process
18 | ```
19 | child_process.exec()
20 | ```
21 |
22 | ...i am no gonna include all
23 |
24 | example
25 | ---
26 | ```
27 | node parent.js
28 | ```
--------------------------------------------------------------------------------
/js-knowledge/chrome-profile-template/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
Demo: Get Started Debugging JavaScript with Chrome DevTools
7 |
8 |
30 |
31 |
32 |
33 |
Demo: Get Started Debugging JavaScript with Chrome DevTools
34 |
Number 1
35 |
36 |
Number 2
37 |
38 |
Add Number 1 and Number 2
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/js-knowledge/chrome-profile-template/script.js:
--------------------------------------------------------------------------------
1 | function onClick() {
2 | if (inputsAreEmpty()) {
3 | label.textContent = 'Error: one or both inputs are empty.';
4 | return;
5 | }
6 | updateLabel();
7 | }
8 |
9 | function inputsAreEmpty() {
10 | if (getNumber1() === '' || getNumber2() === '') {
11 | return true;
12 | } else {
13 | return false;
14 | }
15 | }
16 |
17 | function updateLabel() {
18 | var addend1 = getNumber1();
19 | var addend2 = getNumber2();
20 | var sum = addend1 + addend2;
21 | label.textContent = addend1 + ' + ' + addend2 + ' = ' + sum;
22 | }
23 |
24 | function getNumber1() {
25 | return inputs[0].value;
26 | }
27 |
28 | function getNumber2() {
29 | return inputs[1].value;
30 | }
31 | var inputs = document.querySelectorAll('input');
32 | var label = document.querySelector('p');
33 | var button = document.querySelector('button');
34 | button.addEventListener('click', onClick);
--------------------------------------------------------------------------------
/js-knowledge/class-vs-prototype/prototype.js:
--------------------------------------------------------------------------------
1 | // declaration
2 | function Vehicle(make, model, color) {
3 | this.make = make;
4 | this.model = model;
5 | this.color = color;
6 | this.getName = function () {
7 | return this.make + " " + this.model;
8 | }
9 | }
10 |
11 | // problem 1
12 | let car = new Vehicle("Toyota", "Corolla", "Black");
13 | car.year = 2012
14 | let car2 = new Vehicle("Benz", "ggsget", "White");
15 | console.log(car); // car has 'year'
16 | console.log(car2); // but car2 instance doesn't have 'year'
17 |
18 | // problem 2
19 | // all instances share the same values of the new variable. in this case, all instances share 2 as 'month'
20 | Vehicle.prototype.month = 2
21 | console.log(car) // cant see month in the car object
22 | console.log(car2) // cant see month in the car2 object
23 | console.log(car.month); // 2012
24 | console.log(car2.month); // 2012 WTF
25 |
26 | // That's why we want class, make js more OOP
--------------------------------------------------------------------------------
/js-knowledge/currying/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | e.g.1
3 | */
4 | var add = function (a) {
5 | return function (b) {
6 | return a + b
7 | }
8 | }
9 |
10 | var addToFive = add(5)
11 | console.log(addToFive)
12 | /*
13 | it prints a function. it just consumed the outer function, so it becomes
14 | function (b) {
15 | return 5 + b
16 | }
17 | */
18 | var result = addToFive(2)
19 | console.log(result)
20 |
21 | /*
22 | e.g.2
23 | */
24 | var saySomething = function (a) {
25 | return function (b) {
26 | return function (c) {
27 | return "Say " + a + " to " + b + " from " + c
28 | }
29 | }
30 | }
31 | console.log(saySomething("Hi"))
32 | /*
33 | the above function:
34 | function (b) {
35 | return function (c) {
36 | return "Say " + 'Hi' + " to " + b + " from " + c
37 | }
38 | }
39 | */
40 | console.log(saySomething("Hi")("Bob"))
41 | /*
42 | the above function:
43 | return function (c) {
44 | return "Say " + "Hi" + " to " + "Bob" + " from " + c
45 | }
46 | */
47 | console.log(saySomething("Hi")("Bob")("Hong Kong"))
--------------------------------------------------------------------------------
/js-knowledge/event-loop/event-loop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/js-knowledge/event-loop/event-loop.png
--------------------------------------------------------------------------------
/js-knowledge/event-loop/readme.md:
--------------------------------------------------------------------------------
1 | Event Loop
2 | ===
3 |
4 | 1 sentence
5 | ---
6 |
7 | Basically, it helps NodeJS to run async actions given that NodeJS is single-thread
8 |
9 | Detail
10 | ---
11 |
12 | Node is single-threaded, it executes the code line by line, so how does it run async actions?
13 |
14 | **Event Loop**
15 |
16 | 1. When the EventEmitter object emits an event, the events will be first enqueued into the event queue.
17 | 1. The event loop periodically checks if the queue has events, if yes then it dequeues the head event from the queue and calls the listeners.
18 | 1. All of the functions attached to that specific event are called synchronously.
19 | 1. Any values returned by the called listeners are ignored and will be discarded.
20 | 1. unlike callbacks/promise/aync&await, events are synchronous
21 |
22 | 
23 |
24 | Reference:
25 |
26 | - [Video Explanation](https://www.youtube.com/watch?v=8aGhZQkoFbQ)
27 |
--------------------------------------------------------------------------------
/js-knowledge/hoist/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | Hoisting in javascript is behavior in which
3 | all the declarations are automatically moved on top of the current scope before execution,
4 | so we can use a variable or a function before its declaration
5 |
6 | e.g. we can call a() and b() before a() and b() are declared
7 | */
8 | a()
9 | b()
10 |
11 | function a() {
12 | console.log('a')
13 | }
14 |
15 | function b() {
16 | console.log('b')
17 | }
18 |
19 | /*
20 | Even for prototype, we can new an instance before its declaration e.g.
21 | */
22 | let p = new Person("Calvin", 28)
23 |
24 | function Person(name, age) {
25 | this.name = name;
26 | this.age = age;
27 | }
28 | console.log(p);
29 |
30 | /*
31 | However, in a class, therefore we can't new an instance before its declaration e.g.
32 | */
33 | let car = new Car("Toytota", "Black")
34 | class Car {
35 | constructor(brand, color) {
36 | this.brand = brand;
37 | this.color = color;
38 | }
39 | }
40 | console.log(car);
--------------------------------------------------------------------------------
/js-knowledge/memory-profile-on-web/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/js-knowledge/memory-profile-on-web/.DS_Store
--------------------------------------------------------------------------------
/js-knowledge/memory-profile-on-web/1a.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/js-knowledge/memory-profile-on-web/1a.png
--------------------------------------------------------------------------------
/js-knowledge/memory-profile-on-web/1b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/js-knowledge/memory-profile-on-web/1b.png
--------------------------------------------------------------------------------
/js-knowledge/memory-profile-on-web/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
Demo: Get Started Debugging JavaScript with Chrome DevTools
7 |
8 |
30 |
31 |
32 |
33 |
Memory Leak
34 |
Hey
35 |
Yo
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/js-knowledge/memory-profile-on-web/script.js:
--------------------------------------------------------------------------------
1 | // e.g. 1 from https://gist.github.com/kepta/0ac2636f86c0f4cee80de12821e4ef34
2 | // memory leak in a closure
3 | // in the sayHi() closure, since 'allNames' persists, the engine will quickly run out of memory when we call the function periodically
4 | function sayHi() {
5 | var allNames = [];
6 | return name => {
7 | allNames.push(allNames.join() + name);
8 | return allNames;
9 | }
10 | }
11 |
12 | // assign closure to a variable
13 | var hello = sayHi();
14 |
15 | // setInterval(() => {
16 | // hello('Gandhi');
17 | // }, 1);
18 |
19 | // e.g. 2
20 | // in this case, 'detachedNodes' is retained
21 | var detachedNodes;
22 |
23 | function create() {
24 | var ul = document.createElement('ul');
25 | for (var i = 0; i < 1337; i++) {
26 | var li = document.createElement('li');
27 | ul.appendChild(li);
28 | }
29 | detachedNodes = ul;
30 | }
31 |
32 | setInterval(() => {
33 | create();
34 | }, 100);
--------------------------------------------------------------------------------
/js-knowledge/mixins/readme.md:
--------------------------------------------------------------------------------
1 | # What is Mixins
2 |
3 | Mixins are a form of object **composition**, where component features get mixed into a composite object so that properties of each mixin become properties of the composite object.
4 |
5 | ```js
6 | class Vegetables {
7 | veggies() {
8 | return "Choose Veggies";
9 | }
10 | }
11 | class Meat {
12 | meat() {
13 | return "Choose Meat";
14 | }
15 | }
16 |
17 | class Sauces {
18 | choosingSauces() {
19 | return "Choose Sauces";
20 | }
21 | }
22 |
23 | function combineClasses(dest, ...src) {
24 | for (let _dest of src) {
25 | for (var key of Object.getOwnPropertyNames(_dest.prototype)) {
26 | dest.prototype[key] = _dest.prototype[key];
27 | }
28 | }
29 | }
30 |
31 | class Burger {}
32 |
33 | //adding a new class
34 | class Cheese {
35 | addingCheese() {
36 | return "Add Cheese";
37 | }
38 | }
39 |
40 | combineClasses(Burger, Vegetables, Meat, Sauces, Cheese);
41 |
42 | var burger = new Burger();
43 | console.log(burger.veggies());
44 | console.log(burger.meat());
45 | console.log(burger.choosingSauces());
46 | console.log(burger.addingCheese());
47 | ```
48 |
--------------------------------------------------------------------------------
/js-knowledge/prototype/basic.js:
--------------------------------------------------------------------------------
1 | function Dog(name) {
2 | this.name = name
3 | }
4 |
5 | // here is how we use prototype to extend functionalities
6 | Dog.prototype.bark = function () {
7 | console.log(this.name, 'bark') // btw, 'this' here refers to the dog instance
8 | }
9 |
10 | var dog = new Dog('gg')
11 | dog.bark()
--------------------------------------------------------------------------------
/js-knowledge/prototype/chain.js:
--------------------------------------------------------------------------------
1 | function Dog(name) {
2 | this.name = name
3 | }
4 |
5 | // here is how we use prototype to extend functionalities
6 | Dog.prototype.bark = function () {
7 | console.log(this.name, 'bark') // btw, 'this' here refers to the dog instance
8 | }
9 |
10 | function SuperDog(name, lang) {
11 | Dog.call(this, name, lang)
12 | this.lang = lang
13 | }
14 |
15 | // to inherit dog's prototype
16 | // when we call the functions,
17 | // this "chain" goes all the way back until it reaches an object that has no prototype
18 | SuperDog.prototype = Object.create(Dog.prototype);
19 |
20 | SuperDog.prototype.speak = function () {
21 | console.log(this.name, 'i speak' + this.lang)
22 | }
23 |
24 | var dog = new Dog('gigi')
25 | dog.bark()
26 | // dog.speak() // it will crash
27 |
28 | var superdog = new SuperDog('momo', 'french')
29 | superdog.bark()
30 | superdog.speak()
--------------------------------------------------------------------------------
/js-knowledge/referencing/primitive.js:
--------------------------------------------------------------------------------
1 | /*
2 | as mentioned, a variable is always pass by value unless it is a reference(object/array)
3 | */
4 |
5 | // number
6 | let a = 1
7 | function add(n) {
8 | n++
9 | console.log(n)
10 | }
11 | add(a)
12 | console.log(a)
13 |
14 | // string
15 | let b = 'abc'
16 | function addChar(s) {
17 | s += "d"
18 | console.log(s)
19 | }
20 | addChar(b)
21 | console.log(b)
22 |
23 | // boolean
24 | let c = true
25 | function invert(bool) {
26 | bool = !bool
27 | console.log(bool)
28 | }
29 | invert(c)
30 | console.log(c)
--------------------------------------------------------------------------------
/js-knowledge/referencing/readme.md:
--------------------------------------------------------------------------------
1 | Referencing
2 | ===
3 |
4 | In Javascript, a variable is always pass by value, but when a variable refers to an object (including arrays), the "value" is a reference to the object.
5 |
6 | [Example of passing primitive types](./primitive.js)
7 | [Example of passing an array](./array.js)
8 | [Example of passing an object](./object.js)
--------------------------------------------------------------------------------
/js-knowledge/self-invoking/index.js:
--------------------------------------------------------------------------------
1 | // An immediate function is one that executes as soon as it is defined.
2 | // Creating an immediate function is simple:
3 | // you add the open/close parentheses after the closing curly bracket,
4 | // and then wrap the entire function in parentheses. That's it
5 | let temp = (function () {
6 | var x = "Hello!!"; // I will invoke myself
7 | return x
8 | })();
9 | console.log(temp)
--------------------------------------------------------------------------------
/js-knowledge/singleton/God.js:
--------------------------------------------------------------------------------
1 | class God {
2 | constructor() {
3 | if (God.instance) {
4 | return God.instance;
5 | }
6 | // set singleton
7 | God.instance = this
8 | }
9 | static getInstance() {
10 | if (God.instance) {
11 | return God.instance
12 | }
13 | throw new Error("Please init first")
14 | }
15 | }
16 | // declare singleton
17 | God.instance = null
18 |
19 | module.exports = God
--------------------------------------------------------------------------------
/js-knowledge/singleton/index.js:
--------------------------------------------------------------------------------
1 | const God = require('./God')
2 | const g1 = new God()
3 | const g2 = new God()
4 | console.log(g1 == g2)
5 | console.log(God.getInstance() == g1)
6 | console.log(God.getInstance() == g2)
--------------------------------------------------------------------------------
/js-knowledge/this/1_constructor.js:
--------------------------------------------------------------------------------
1 | // it prints { value: 10}
2 | // it means that 'this' is refering to the 'ConstructorExample'
3 | function ConstructorExample() {
4 | console.log(this);
5 | this.value = 10;
6 | console.log(this);
7 | }
8 |
9 | new ConstructorExample();
10 |
11 | // for example, it is how leetcode defines a Binary Tree
12 | function TreeNode(val) {
13 | this.val = val;
14 | this.left = this.right = null;
15 | }
--------------------------------------------------------------------------------
/js-knowledge/this/2_apply_call_bind.js:
--------------------------------------------------------------------------------
1 | /*
2 | If apply, call, or bind are used to call a function,
3 | 'this' inside the function is the object that is passed in as the argument.
4 | */
5 | function fn() {
6 | console.log(this);
7 | }
8 |
9 | var obj = {
10 | value: 5
11 | };
12 |
13 | var boundFn = fn.bind(obj);
14 |
15 | boundFn(); // -> { value: 5 }
16 | fn.call(obj); // -> { value: 5 }
17 | fn.apply(obj); // -> { value: 5 }
--------------------------------------------------------------------------------
/js-knowledge/this/3_method.js:
--------------------------------------------------------------------------------
1 | // If a function is called as a method,
2 | // this is the object that the function is a property of
3 | var obj = {
4 | value: 5,
5 | printThis: function () {
6 | console.log(this);
7 | }
8 | };
9 |
10 | obj.printThis(); // { value: 5, printThis: [Function: printThis] }
--------------------------------------------------------------------------------
/js-knowledge/this/4_global.js:
--------------------------------------------------------------------------------
1 | function fn() {
2 | console.log(this);
3 | }
4 | // If called in browser:
5 | fn(); // it prints the node contextd because node executes it
--------------------------------------------------------------------------------
/js-knowledge/this/6_arrow.js:
--------------------------------------------------------------------------------
1 | /*
2 | If the function is an ES2015 arrow function,
3 | it ignores all the rules above
4 | and receives the this value of its surrounding scope at the time it’s created
5 | */
6 |
7 | // e.g. 1
8 | let obj = {
9 | value: 'abc',
10 | createArrowFn: () => {
11 | console.log(this);
12 | }
13 | };
14 | let arrowFn = obj.createArrowFn(); // {}
15 |
16 | // e.g. 2
17 | obj = {
18 | value: 'abc',
19 | createArrowFn: function () {
20 | return () => console.log(this);
21 | }
22 | };
23 | arrowFn = obj.createArrowFn();
24 | arrowFn(); // -> { value: 'abc', createArrowFn: ƒ }
--------------------------------------------------------------------------------
/optimization/backend.md:
--------------------------------------------------------------------------------
1 | How to optimize performance? [WIP]
2 | ----
3 | - memory leak:
4 | - Profile/monitor your app, find and fix memory leaks by capturing snapshots of your app while it is running, to see if there is any memory leak. If the memory usage keeps piling up and not going down after a certain period of time(after several mark&sweep), it means that there is a memory leak.
5 | - memory leaks usually happen with Global Variables, Multiple References, Closures
6 | - Tools: node-inspector, node-memwatch, chrome-devtools(browser)
7 | - check the time&space complexity of your algorithms
8 | - testcases: corner cases caught? any crash?
9 | - compress your source code(build) for production
--------------------------------------------------------------------------------
/react-widgets-implementation/books-paginated-search/.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 |
--------------------------------------------------------------------------------
/react-widgets-implementation/books-paginated-search/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": "src"
4 | },
5 | "include": ["src"]
6 | }
7 |
--------------------------------------------------------------------------------
/react-widgets-implementation/books-paginated-search/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/react-widgets-implementation/books-paginated-search/public/favicon.ico
--------------------------------------------------------------------------------
/react-widgets-implementation/books-paginated-search/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/react-widgets-implementation/books-paginated-search/public/logo192.png
--------------------------------------------------------------------------------
/react-widgets-implementation/books-paginated-search/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/react-widgets-implementation/books-paginated-search/public/logo512.png
--------------------------------------------------------------------------------
/react-widgets-implementation/books-paginated-search/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/react-widgets-implementation/books-paginated-search/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/react-widgets-implementation/books-paginated-search/src/App.module.css:
--------------------------------------------------------------------------------
1 | .app {
2 | text-align: center;
3 | }
--------------------------------------------------------------------------------
/react-widgets-implementation/books-paginated-search/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from "@testing-library/react";
2 | import App from "./App";
3 |
4 | describe("App tests", () => {
5 | test("should render", () => {
6 | const view = render(
);
7 | expect(view).toBeTruthy();
8 | const onlyElementForNow = screen.getByText(/Boilerplate/i);
9 | expect(onlyElementForNow).toBeInTheDocument();
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/react-widgets-implementation/books-paginated-search/src/components/BookList/index.js:
--------------------------------------------------------------------------------
1 | const BookList = ({ books }) => {
2 | return (
3 |
4 | {books.map((obj) => (
5 |
8 | ))}
9 |
10 | );
11 | };
12 |
13 | export default BookList;
14 |
--------------------------------------------------------------------------------
/react-widgets-implementation/books-paginated-search/src/hooks/useDebounce.js:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react";
2 |
3 | export const useDebounce = (value, delay) => {
4 | const [dbValue, setDbValue] = useState(value);
5 |
6 | useEffect(() => {
7 | const tid = setTimeout(() => {
8 | setDbValue(value);
9 | }, delay);
10 |
11 | return () => clearTimeout(tid);
12 | }, [value, delay]);
13 |
14 | return dbValue;
15 | };
16 |
--------------------------------------------------------------------------------
/react-widgets-implementation/books-paginated-search/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | }
4 |
--------------------------------------------------------------------------------
/react-widgets-implementation/books-paginated-search/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom/client";
3 | import "./index.css";
4 | import App from "./App";
5 | import reportWebVitals from "./reportWebVitals";
6 |
7 | const root = ReactDOM.createRoot(document.getElementById("root"));
8 | root.render(
9 |
10 |
11 |
12 | );
13 |
14 | // If you want to start measuring performance in your app, pass a function
15 | // to log results (for example: reportWebVitals(console.log))
16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17 | reportWebVitals();
18 |
--------------------------------------------------------------------------------
/react-widgets-implementation/books-paginated-search/src/reducers/appReducer.js:
--------------------------------------------------------------------------------
1 | export const BOOKS_ACTIONS = {
2 | SET_BOOKS: "SET_BOOKS",
3 | SET_QUERY: "SET_QUERY",
4 | SET_PAGE: "SET_PAGE",
5 | SET_MAX_PAGES: "SET_MAX_PAGES",
6 | };
7 |
8 | export const booksInitStates = {
9 | books: [],
10 | query: "",
11 | page: 1,
12 | maxPages: 1,
13 | };
14 |
15 | export const booksReducer = (state, action) => {
16 | switch (action.type) {
17 | case BOOKS_ACTIONS.SET_BOOKS:
18 | return { ...state, books: action.payload };
19 | case BOOKS_ACTIONS.SET_QUERY:
20 | return { ...state, query: action.payload };
21 | case BOOKS_ACTIONS.SET_PAGE:
22 | return { ...state, page: action.payload };
23 | case BOOKS_ACTIONS.SET_MAX_PAGES:
24 | return { ...state, maxPages: action.payload };
25 | default:
26 | return state;
27 | }
28 | };
29 |
--------------------------------------------------------------------------------
/react-widgets-implementation/books-paginated-search/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/react-widgets-implementation/books-paginated-search/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/react-widgets-implementation/context-counter/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "context-counter",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.17.0",
7 | "@testing-library/react": "^13.4.0",
8 | "@testing-library/user-event": "^13.5.0",
9 | "react": "^18.2.0",
10 | "react-dom": "^18.2.0",
11 | "react-scripts": "5.0.1",
12 | "web-vitals": "^2.1.4"
13 | },
14 | "scripts": {
15 | "start": "react-scripts start",
16 | "build": "react-scripts build",
17 | "test": "react-scripts test",
18 | "eject": "react-scripts eject"
19 | },
20 | "eslintConfig": {
21 | "extends": [
22 | "react-app",
23 | "react-app/jest"
24 | ]
25 | },
26 | "browserslist": {
27 | "production": [
28 | ">0.2%",
29 | "not dead",
30 | "not op_mini all"
31 | ],
32 | "development": [
33 | "last 1 chrome version",
34 | "last 1 firefox version",
35 | "last 1 safari version"
36 | ]
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/react-widgets-implementation/context-counter/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/react-widgets-implementation/context-counter/public/favicon.ico
--------------------------------------------------------------------------------
/react-widgets-implementation/context-counter/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/react-widgets-implementation/context-counter/public/logo192.png
--------------------------------------------------------------------------------
/react-widgets-implementation/context-counter/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/react-widgets-implementation/context-counter/public/logo512.png
--------------------------------------------------------------------------------
/react-widgets-implementation/context-counter/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/react-widgets-implementation/context-counter/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/react-widgets-implementation/context-counter/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | }
3 |
4 | .App-logo {
5 | height: 40vmin;
6 | pointer-events: none;
7 | }
8 |
9 | @media (prefers-reduced-motion: no-preference) {
10 | .App-logo {
11 | animation: App-logo-spin infinite 20s linear;
12 | }
13 | }
14 |
15 | .App-header {
16 | background-color: #282c34;
17 | min-height: 50px;
18 | display: flex;
19 | flex-direction: column;
20 | align-items: center;
21 | justify-content: center;
22 | font-size: calc(10px + 2vmin);
23 | color: white;
24 | }
25 |
26 | .App-link {
27 | color: #61dafb;
28 | }
29 |
30 | @keyframes App-logo-spin {
31 | from {
32 | transform: rotate(0deg);
33 | }
34 | to {
35 | transform: rotate(360deg);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/react-widgets-implementation/context-counter/src/App.js:
--------------------------------------------------------------------------------
1 | import logo from './logo.svg';
2 | import './App.css';
3 |
4 | import { AppContext } from './contexts/AppContext';
5 | import { useState } from 'react';
6 | import Coordinate from './components/Coordinate';
7 |
8 | function App() {
9 | const [xy, setXY] = useState({ x: 0, y: 0 })
10 |
11 | return (
12 |
20 | );
21 | }
22 |
23 | export default App;
24 |
--------------------------------------------------------------------------------
/react-widgets-implementation/context-counter/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render(
);
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/react-widgets-implementation/context-counter/src/components/Coordinate.js:
--------------------------------------------------------------------------------
1 | import { useContext } from 'react';
2 | import { AppContext } from "../contexts/AppContext";
3 |
4 | function Coordinate() {
5 | const { xy, setXY } = useContext(AppContext);
6 |
7 | const onClickX = (delta) => {
8 | setXY((v) => ({
9 | x: v.x+delta, y: v.y
10 | }))
11 | }
12 |
13 | const onClickY = (delta) => {
14 | setXY((v) => ({
15 | x: v.x, y: v.y+delta
16 | }))
17 | }
18 |
19 | return (
20 |
21 | onClickX(-1)}> X oordinate -
22 | x = {xy.x}
23 | onClickX(1)}> X oordinate +
24 |
25 | onClickY(-1)}> Y oordinate -
26 | y = {xy.y}
27 | onClickY(1)}> Y oordinate +
28 |
29 | );
30 | }
31 |
32 | export default Coordinate;
--------------------------------------------------------------------------------
/react-widgets-implementation/context-counter/src/contexts/AppContext.js:
--------------------------------------------------------------------------------
1 | import { createContext } from "react";
2 |
3 | export const AppContext = createContext(null);
4 |
--------------------------------------------------------------------------------
/react-widgets-implementation/context-counter/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/react-widgets-implementation/context-counter/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | const root = ReactDOM.createRoot(document.getElementById('root'));
8 | root.render(
9 |
10 |
11 |
12 | );
13 |
14 | // If you want to start measuring performance in your app, pass a function
15 | // to log results (for example: reportWebVitals(console.log))
16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17 | reportWebVitals();
18 |
--------------------------------------------------------------------------------
/react-widgets-implementation/context-counter/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/react-widgets-implementation/context-counter/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/react-widgets-implementation/credit-card/Screenshot 2023-04-26 at 15.53.49.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/react-widgets-implementation/credit-card/Screenshot 2023-04-26 at 15.53.49.png
--------------------------------------------------------------------------------
/react-widgets-implementation/credit-card/Screenshot 2023-04-26 at 15.54.01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/react-widgets-implementation/credit-card/Screenshot 2023-04-26 at 15.54.01.png
--------------------------------------------------------------------------------
/react-widgets-implementation/credit-card/Screenshot 2023-04-29 at 01.06.18.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/react-widgets-implementation/credit-card/Screenshot 2023-04-29 at 01.06.18.png
--------------------------------------------------------------------------------
/react-widgets-implementation/credit-card/Screenshot 2023-04-29 at 01.06.23.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/react-widgets-implementation/credit-card/Screenshot 2023-04-29 at 01.06.23.png
--------------------------------------------------------------------------------
/react-widgets-implementation/credit-card/Screenshot 2023-04-29 at 01.06.34.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/react-widgets-implementation/credit-card/Screenshot 2023-04-29 at 01.06.34.png
--------------------------------------------------------------------------------
/react-widgets-implementation/credit-card/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "credit-card-component",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.16.5",
7 | "@testing-library/react": "^13.4.0",
8 | "@testing-library/user-event": "^13.5.0",
9 | "react": "^18.2.0",
10 | "react-dom": "^18.2.0",
11 | "react-scripts": "5.0.1",
12 | "web-vitals": "^2.1.4"
13 | },
14 | "scripts": {
15 | "start": "react-scripts start",
16 | "build": "react-scripts build",
17 | "test": "react-scripts test",
18 | "eject": "react-scripts eject"
19 | },
20 | "eslintConfig": {
21 | "extends": [
22 | "react-app",
23 | "react-app/jest"
24 | ]
25 | },
26 | "browserslist": {
27 | "production": [
28 | ">0.2%",
29 | "not dead",
30 | "not op_mini all"
31 | ],
32 | "development": [
33 | "last 1 chrome version",
34 | "last 1 firefox version",
35 | "last 1 safari version"
36 | ]
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/react-widgets-implementation/credit-card/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/react-widgets-implementation/credit-card/public/favicon.ico
--------------------------------------------------------------------------------
/react-widgets-implementation/credit-card/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/react-widgets-implementation/credit-card/public/logo192.png
--------------------------------------------------------------------------------
/react-widgets-implementation/credit-card/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/react-widgets-implementation/credit-card/public/logo512.png
--------------------------------------------------------------------------------
/react-widgets-implementation/credit-card/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/react-widgets-implementation/credit-card/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/react-widgets-implementation/credit-card/public/visa_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/react-widgets-implementation/credit-card/public/visa_logo.png
--------------------------------------------------------------------------------
/react-widgets-implementation/credit-card/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render(
);
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/react-widgets-implementation/credit-card/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/react-widgets-implementation/credit-card/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | const root = ReactDOM.createRoot(document.getElementById('root'));
8 | root.render(
9 |
10 |
11 |
12 | );
13 |
14 | // If you want to start measuring performance in your app, pass a function
15 | // to log results (for example: reportWebVitals(console.log))
16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17 | reportWebVitals();
18 |
--------------------------------------------------------------------------------
/react-widgets-implementation/credit-card/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/react-widgets-implementation/credit-card/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/react-widgets-implementation/debounced-pokemon-search/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/react-widgets-implementation/debounced-pokemon-search/app/api/pokemon/route.js:
--------------------------------------------------------------------------------
1 | import { NextResponse } from 'next/server'
2 | import { pokemons } from '@/mock-db/index'
3 |
4 | export async function GET(request) {
5 | try {
6 | const searchParams = request.nextUrl.searchParams
7 | const query = searchParams.get('query')
8 |
9 | const results = pokemons.filter(x => x.name.toLowerCase().includes(query?.toLowerCase())).slice(0, 500)
10 |
11 | return NextResponse.json({ pokemons: results })
12 | } catch (error) {
13 | return NextResponse.json({ error: error.message }, { status: 500 })
14 | }
15 | }
--------------------------------------------------------------------------------
/react-widgets-implementation/debounced-pokemon-search/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/react-widgets-implementation/debounced-pokemon-search/app/favicon.ico
--------------------------------------------------------------------------------
/react-widgets-implementation/debounced-pokemon-search/app/globals.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinchankf/JSConcepts/f313d26386c78ccc51bfbf2c7f0f05bb63b5ef7a/react-widgets-implementation/debounced-pokemon-search/app/globals.css
--------------------------------------------------------------------------------
/react-widgets-implementation/debounced-pokemon-search/app/layout.js:
--------------------------------------------------------------------------------
1 | import { Inter } from 'next/font/google'
2 | import './globals.css'
3 |
4 | const inter = Inter({ subsets: ['latin'] })
5 |
6 | export const metadata = {
7 | title: 'Create Next App',
8 | description: 'Generated by create next app',
9 | }
10 |
11 | export default function RootLayout({ children }) {
12 | return (
13 |
14 | {children}
15 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/react-widgets-implementation/debounced-pokemon-search/app/page.js:
--------------------------------------------------------------------------------
1 | import { Suspense } from 'react'
2 | import styles from './page.module.css'
3 | import PokemonList from '@/components/PokemonList'
4 | import SearchInput from "@/components/SearchInput"
5 |
6 | export default function Home({ searchParams }) {
7 | const query = searchParams?.q ?? ''
8 | return (
9 |
10 |
11 | Loading feed... }>
12 |