├── .editorconfig ├── .gitignore ├── README.md ├── articles ├── angular │ ├── exploring-formsmodule.md │ └── exploring-httpclientmodule.md ├── ngrx │ ├── ngrx-effects.md │ └── ngrx-store.md └── rxjs │ ├── combination-operators.md │ ├── concepts.md │ ├── exploring-rxjs.md │ ├── knowledge-pills.md │ ├── multicasting.md │ └── window.md ├── bash-scripts └── generate-boilerplate │ ├── main.sh │ └── readme.md ├── notebooks ├── concepts.md ├── css.md ├── db.md ├── docker.md ├── exploring-docker.md ├── express.md ├── git.md ├── go.md ├── graphql.md ├── javascript.md ├── linux.md ├── mongoose.md ├── networking.md ├── ng │ ├── angular-testing.md │ ├── angular.md │ └── router │ │ ├── demystifying-angular-router.md │ │ ├── directives.md │ │ ├── in-depth-overview.md │ │ ├── interesting-facts.md │ │ ├── process.md │ │ ├── redirecting.md │ │ ├── router-scroller.md │ │ └── urltree.md ├── ngrx │ ├── ngrx-store.md │ └── ngrx-testing.md ├── node.md ├── regex.md ├── rollup │ ├── findings.md │ ├── modules.md │ └── plugins.md ├── rxjs.md ├── testing.md ├── typescript.md └── vscode.md └── screenshots ├── articles ├── exploring-httpclientmodule │ ├── canLoad.png │ ├── httpbackend.png │ ├── httpclient.png │ ├── httpevents.png │ ├── httpintercepting.png │ ├── httpinterceptor.png │ ├── httpinterceptors.jpg │ ├── img1.png │ └── img2.png └── ngrx-effects │ ├── effects-set-up.png │ ├── effects-setup.gif │ ├── effects-setup.mp4 │ ├── ngrx-flow.gif │ └── ngrx-flow.mp4 ├── basic.jpg ├── high-order.jpg ├── routerscroller-state.jpg ├── routerstate.jpg └── scroller-example.gif /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | .vscode 3 | 4 | algos.js 5 | main.go -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # My dev notes 2 | 3 | ## Notebooks 4 | 5 | * [Angular](https://github.com/Andrei0872/my-dev-notes/blob/master/notebooks/angular.md) 6 | * [Concepts](https://github.com/Andrei0872/my-dev-notes/blob/master/notebooks/concepts.md) 7 | * [CSS](https://github.com/Andrei0872/my-dev-notes/blob/master/notebooks/css.md) 8 | * [Database](https://github.com/Andrei0872/my-dev-notes/blob/master/notebooks/db.md) 9 | * [Docker](https://github.com/Andrei0872/my-dev-notes/blob/master/notebooks/docker.md) 10 | * [Git](https://github.com/Andrei0872/my-dev-notes/blob/master/notebooks/git.md) 11 | * [Go](https://github.com/Andrei0872/my-dev-notes/blob/master/notebooks/go.md) 12 | * [GraphQL](https://github.com/Andrei0872/my-dev-notes/blob/master/notebooks/graphql.md) 13 | * [JavaScript](https://github.com/Andrei0872/my-dev-notes/blob/master/notebooks/javascript.md) 14 | * [Linux](https://github.com/Andrei0872/my-dev-notes/blob/master/notebooks/linux.md) 15 | * [Mongoose](https://github.com/Andrei0872/my-dev-notes/blob/master/notebooks/mongoose.md) 16 | * [Networking](https://github.com/Andrei0872/my-dev-notes/blob/master/notebooks/networking.md) 17 | * [Node](https://github.com/Andrei0872/my-dev-notes/blob/master/notebooks/node.md) 18 | * [Regex](https://github.com/Andrei0872/my-dev-notes/blob/master/notebooks/regex.md) 19 | * [RxJS](https://github.com/Andrei0872/my-dev-notes/blob/master/notebooks/rxjs.md) 20 | * [TypeScript](https://github.com/Andrei0872/my-dev-notes/blob/master/notebooks/typescript.md) 21 | * [VS Code](https://github.com/Andrei0872/my-dev-notes/blob/master/notebooks/vscode.md) 22 | -------------------------------------------------------------------------------- /articles/rxjs/combination-operators.md: -------------------------------------------------------------------------------- 1 | ## zip 2 | 3 | `zip(observable|iterators, resultSelector?)` 4 | 5 | * uses `formArray` -> meaning that after all the inputs have been sent, it will `complete`, which will cause the `observables` to be `subscribed` 6 | * the observables store their inner values; when all have emitted at least once, the outer subscriber would receive an array composed of the **oldest values** of each observable 7 | * when one observable **completes** 8 | * if its **buffer**(where inner values are stored) is **not empty**, it becomes **inactive**; if there are **no more active** observables, the **outer subscriber** will `complete` as well 9 | 10 | ```ts 11 | notifyInactive() { 12 | this.active--; 13 | if (this.active === 0) { 14 | this.destination.complete(); 15 | } 16 | } 17 | ``` 18 | 19 | * if the **buffer** is **empty**, the outer subscriber will emit the `complete` notification to its destination subscriber 20 | * the input can be an `observable` or any other `iterable`(array, custom iterable structure) 21 | 22 | ```ts 23 | zip( 24 | fromEvent(b1, 'click').pipe(map((_, idx) => `btn1, click: ${idx}`), take(2)), 25 | fromEvent(b2, 'click').pipe(map((_, idx) => `btn2, click: ${idx}`)), 26 | // [1, 2, 3], 27 | (function * () { const a = [1, 2, 3]; yield * a })(), 28 | ) 29 | .subscribe(console.warn) 30 | ``` 31 | 32 | ### zipWith 33 | 34 | ```ts 35 | src$.pipe( 36 | a(), 37 | zipWith(/* ... */), 38 | b(), 39 | ) 40 | ``` 41 | 42 | * `ZipOperator`'s destination is `bSubscriber` 43 | * `bSubscriber` is destination for each `ZipBufferIterator`(what's inside `zipWith()`) and for each of their `InnerSubscriber` 44 | 45 | ```ts 46 | src$.pipe( 47 | zipWith(a$, b$) 48 | ) 49 | 50 | // === 51 | 52 | zip(src$, a$, b$); 53 | ``` 54 | 55 | ### zipAll 56 | 57 | * must make sure the source completes ❗️ 58 | 59 | ```ts 60 | new Observable(s => { 61 | s.next(of(1)); 62 | 63 | s.next(of(2)); 64 | 65 | // Nothing will happen without this 66 | s.complete(); 67 | }).pipe( 68 | zipAll() 69 | ).subscribe(console.log); 70 | ``` 71 | 72 | --- 73 | 74 | ## combineLatest 75 | 76 | * `combineLatest(observables)` === `from(observables).lift(new CombineLatestOperator(resultSelector?))` 77 | * will keep track of `N` observables and values, where `N = observables.length` 78 | * will emit an array of values collected from all the stored `observables`; the array will be emitted to the destination subscriber when `toRespond === 0`, where `toRespond` **decreases** when one observable(which is being tracked) **emits** for the **first time**; thus, `toRespond === 0` when all the observables have **emitted** at **least once** 79 | * if one tracked obs `completes` 80 | * if it is the only active observable left, the `complete notification` will be sent to the destination subscriber 81 | * its **last emitted value** will **not** be **removed** 82 | * if one tracked obs `errors` 83 | * the `error notif` will be passed along to the destination subscriber 84 | 85 | * differs from `zip` in the way tracked `observable`'s values are used 86 | * `zip`: each inner obs has its own buffer 87 | * `combineLatest`: only the **last emitted value** is **stored** & eventually emitted to the dest subscriber 88 | 89 | ### combineLatestWith 90 | 91 | * `combineLatestWith(observables) === from([source, ...observables])` 92 | 93 | ### combineAll 94 | 95 | `combineAll(projectFn)` 96 | 97 | * `from(...)` is no longer used 98 | * it only applies the `CombineLatestOperator(resultSelector?)` to the source -> in order for the observables(/promises/iterables) emitted from source to be subscribed, the **source must complete** 99 | 100 | ```ts 101 | new Observable(s => { 102 | s.next(of(1)); 103 | s.next(of(1, 2)); 104 | 105 | setTimeout(() => { 106 | s.next(of(10)); 107 | }, 500) 108 | 109 | setTimeout(() => { 110 | s.complete(); 111 | }, 700); 112 | }).pipe( 113 | combineAll() 114 | ).subscribe(console.log) 115 | ``` 116 | 117 | --- 118 | 119 | ## forkJoin 120 | 121 | _Note: `Subscribable` = `Observable` | `Iterable` | `Array` | `Promise`_ 122 | 123 | `forkJoin(arrayOfSubscribables | { [k]: Subscribable })`(_non deprecated_) 124 | 125 | * all the observables must complete in order for the `ForkJoinSubscriber` to emit at least the `complete` notification 126 | * otherwise, no `value`/`complete notification` will be sent to the destination subscriber 127 | * assuming all the observables completed 128 | * if **at least one** did not emit any values, the destination subscriber will only receive the `complete` notification 129 | ```ts 130 | if (completed === len || !hasValue) { 131 | if (emitted === len) { 132 | subscriber.next(keys ? 133 | keys.reduce((result, key, i) => ((result as any)[key] = values[i], result), {}) : 134 | values); 135 | } 136 | subscriber.complete(); 137 | } 138 | ``` 139 | * in order to send an array with the latest arrived values of each observable, then each obs must emit at least once 140 | ```ts 141 | next: value => { 142 | if (!hasValue) { 143 | hasValue = true; 144 | emitted++; 145 | } 146 | // Storing the last arrived value 147 | values[i] = value; 148 | }, 149 | ``` 150 | 151 | after the array has been sent, it would then emit a `complete` notification 152 | 153 | ```ts 154 | forkJoin([ 155 | of(1), of(2), of(3), /* EMPTY, */ /* NEVER */ 156 | ]) 157 | .subscribe(console.log, null, () => console.warn('COMPLETED')) 158 | ``` 159 | -------------------------------------------------------------------------------- /articles/rxjs/concepts.md: -------------------------------------------------------------------------------- 1 | # RxJs Concepts 2 | 3 | ## Operator 4 | 5 | * returns a function whose `inputs` and `outputs` are both `Observables` 6 | Examples: `map()`, `filter()`, `take()` 7 | 8 | ## Converting a callback API into an Observable 9 | 10 | * `bindCallback` and `bindNodeCallback` 11 | 12 | ```ts 13 | const fn = bindCallback((a, b, cb) => { 14 | // When calling `cb` with certain arguments, those arguments 15 | // will be sent to the subscriber 16 | // The arguments can be the result of some operations 17 | 18 | cb(result1, result2, result3); 19 | 20 | // When using `bindNodeCallback`, the first arg is the error 21 | cb(new Error('err!')) 22 | cb(null, result1, result2); 23 | }); 24 | 25 | fn(aArg, bArg).subscribe(console.log, console.error/* Visible when an error notif. is sent: calling cb(err) with `bindNodeCallback` */) 26 | ``` 27 | -------------------------------------------------------------------------------- /articles/rxjs/knowledge-pills.md: -------------------------------------------------------------------------------- 1 | # RxJs Knowledge Pills 2 | 3 | * `delayWhen` 4 | * [Delay subscription moment](https://twitter.com/anduser96/status/1237841984418508800?s=20) 5 | * `fromEvent` 6 | * [Bind multiple listeners under a single Observable](https://twitter.com/anduser96/status/1243998828233216000?s=20) 7 | * `race` 8 | * [`mergeMap().pipe(first())` vs `race()`](https://twitter.com/anduser96/status/1244655760879091714?s=20) 9 | * `buffer` 10 | * [`buffer` vs `bufferCount` when source `completes`](https://twitter.com/anduser96/status/1246068466961940481?s=20) 11 | * `distinct` 12 | * [Control when the `Set` object should be cleared](https://twitter.com/anduser96/status/1246477321151922177?s=20) 13 | -------------------------------------------------------------------------------- /articles/rxjs/multicasting.md: -------------------------------------------------------------------------------- 1 | ## multicast 2 | 3 | `multicast(Subject|SubjectFactory, selector)` 4 | 5 | * the base for other **multicasting selectors** 6 | * puts a middleman(a variation of `Subject`) between the operators that are above and below `multicast()` 7 | 8 | ### `selector` provided 9 | 10 | * the source's callback will be invoked on **every** new subscriber 11 | * the `selector` can be used as a way to share data 12 | ```ts 13 | multicast(new Subject(), subject => merge( 14 | subject.pipe(a()), 15 | subject.pipe(b()), 16 | subject.pipe(c()), 17 | )) 18 | ``` 19 | 20 | ```ts 21 | const src$ = new Observable(s => { 22 | console.log('SUSBCRIBED'); 23 | s.next(1); 24 | 25 | setTimeout(() => { 26 | s.next(2); 27 | }, 500); 28 | }).pipe( 29 | multicast( 30 | () => new Subject(), 31 | s => merge( 32 | s.pipe(map(v => v * 2)), 33 | s.pipe(map(v => v * 4)), 34 | ) 35 | ) 36 | ); 37 | 38 | 39 | const s = src$.pipe( 40 | filter(v => !!v), 41 | ).subscribe(console.warn); 42 | 43 | src$.pipe(map(v => v * 10)).subscribe(console.log); 44 | ``` 45 | 46 | ### `selector` not provided 47 | 48 | * a `ConnectableObservable` will be returned 49 | * the subscriber will be added to the `Subject`'s list of subscribers 50 | * all the subscribers whose operators are **above** `multicast` will become descendants of `ConnectableSubscriber` 51 | * all the subscribers that are **below** `multicast` will be part of the list of subscribers that belongs to the `Subject` in use 52 | * does not matter if the first arg is a `Subject` or a `SubjectFactory`, as the _factory_ will be needed only once 53 | * when the source `errors`/`completes` - the subject in use will be nulled out 54 | * if the `connectable` is unsubscribed from(with `(connectable$.connect()).unsubscribed()`) 55 | * the subject in use will be nulled out 56 | * the `ConnectableSubscribers`'s descendants will be unsubscribed as well 57 | 58 | ```ts 59 | const src$ = new Observable(s => { 60 | setTimeout(() => { 61 | s.next(1); 62 | s.next(2); 63 | }, 500); 64 | }).pipe( 65 | map(v => v), 66 | multicast(() => new Subject()), 67 | ); 68 | 69 | src$.pipe( 70 | filter(v => !!v), 71 | ).subscribe(console.warn) 72 | 73 | const conn = src$.connect(); 74 | ``` 75 | 76 | --- 77 | 78 | ## `ConnectableObservable` 79 | 80 | * will **subscribe** to the `source` when its `connect()` method is invoked 81 | * a `ConnectableSubscriber` will be provided to the `source` 82 | * maintains a single `Subject` instance(`Subject`/`BehaviorSubject` etc) 83 | 84 | ### `ConnectableSubscriber` 85 | 86 | * it is a `SubjectSubscriber` 87 | * `error/complete` - will first `unsubscribe`, then pass along the notif. to the destination subject, which will in turn pass the notif. along to its registered subscribers 88 | * `unsubscribe` 89 | * will _close_ the connection: `connection.unsubscribe()` 90 | * responsible for **clean-up**: `subject`, `connection`, `connectable` of `ConnectableObservable` 91 | 92 | --- 93 | 94 | ```ts 95 | const src$ = new Observable(s => { 96 | console.log('SUBSCRIBED!'); 97 | 98 | setTimeout(() => { 99 | s.next(1); 100 | }, 500); 101 | 102 | // After the second subscriber `subscribed` 103 | setTimeout(() => { 104 | s.next(2); 105 | // s.complete(); 106 | }, 800); 107 | }).pipe( 108 | // publish(), // multicast(new Subject()), 109 | // publishBehavior(0), // `BehaviorSubject(0)` as a middleman 110 | // publishLast(), // `AsyncSubject` as a middleman 111 | 112 | // `ReplaySubject` as a middleman 113 | // publishReplay(1), 114 | // refCount(), 115 | // shareReplay(1), 116 | 117 | // share(), 118 | ); 119 | 120 | const s = src$.subscribe(console.warn); 121 | 122 | setTimeout(() => { 123 | src$.subscribe(console.log); 124 | }, 700); 125 | ``` 126 | -------------------------------------------------------------------------------- /articles/rxjs/window.md: -------------------------------------------------------------------------------- 1 | # window 2 | 3 | * the **window** itself is actually a `Subject` ❗️ 4 | 5 | * there can only be one active window 6 | 7 | * one inner subscriber for `windowBoundaries$` 8 | * when it emits, the current window will be closed(i.e: `window.complete()`) 9 | 10 | * what happens when **source or window** `errors/completes` 11 | * it will send the notification through the current active window 12 | * when it will propagate the notification to the next subscriber in the chain 13 | 14 | * diagram 15 | * show `windowBoundaries` 16 | * `error`/`complete` -> send notif & remove window 17 | * show current window(which is a `Subject` instance) 18 | * show how the dest. subscriber handles the received window(e.g: `mergeMap`) 19 | * show the flow of the notification that was sent by the window(from window to the inner subscriber of the dest. subscriber 😃) 20 | * `next` 21 | * `error`/`complete` -> send notif & remove window 22 | 23 | --- 24 | 25 | ## windowTime 26 | 27 | * `windowTimeSpan` 28 | * how long a window should last 29 | * `windowTime(windowTimeSpan) === window(timer(windowTimeSpan))` 30 | * if only this argument is specified, there will only be **one active window**, whose duration is determined by `windowTimeSpan` 31 | * a new window will be created periodically, depending on `windowTimeSpan`; when a new window is created, the current one will be closed(will emit a `complete` notification) 32 | * `windowCreationInterval` 33 | * the period at which a new window will be created and the current one will be closed 34 | * when this argument is specified as well, there can be **multiple active windows** 35 | * every `windowCreationInterval` ms a new window will be created; the life span of that window depends on `windowTimeSpan` 36 | 37 | * every **value** received from the source will be **sent** to all the **active windows** 38 | ```ts 39 | const docClick$ = fromEvent(document, 'click'); 40 | 41 | const source = docClick$; 42 | const example = source.pipe( 43 | windowTime(6000, 1000, /* 3 */), 44 | tap(_ => console.log('NEW WINDOW!')) 45 | ); 46 | 47 | const subscribeTwo = example 48 | .pipe( 49 | mergeMap(s => s.pipe( 50 | tap(null, null, () => console.log('complete')) 51 | )) 52 | ) 53 | .subscribe(val => console.log(val)); 54 | ``` 55 | 56 | * every `error`/`complete` notification, will be sent to the **active windows**, while they are being removed from the `windows array` 57 | 58 | * `maxWindowSize` - specify the maximum number of items emitted by a window 59 | * when this number is reached, the window will be closed(will emit a `complete` notification) 60 | 61 | * diagram 62 | * `maxWindowZie` 63 | * scheduled actions _section_ 64 | * `windows array` 65 | * action scheduled at every `windowCreationInterval` ms schedules another action that will be closed after `windowTimeSpan`(it is a 1:1 rel. between the action scheduled at every `windowCreationInterval` and the action that it creates) 66 | * outer value is sent to all the active windows 67 | * `error`/`complete` notification sent to the windows, then remove window from arr 68 | 69 | --- 70 | 71 | ## windowWhen 72 | 73 | * accepts a functions that will produce(return) an **observable** 74 | * can be only **one active window**(`Subject` instance) 75 | * when the obs. resulted from the factory function `emits`/`completes` 76 | * the **current window** will be **closed**(the window will emit a` complete` notification) 77 | * the current **observable** will be **unsubscribed** an a **new inner subscriber** will be created, that will inform the outer subscriber(`WindowWhenSubscriber`) the inner obs(created by the factory function) emits 78 | * the outer value will be sent to the current active window 79 | * `error`/`complete` notif. from the source 80 | * send the notif. through the window 81 | * unsubscribe from the inner observable(that one resulted from the factory function) 82 | * send the notif. to the destination subscriber 83 | * diagram 84 | * factory 85 | * active window sent to the dest. subscriber(`---->`) 86 | * when the source emits a value, sent it to the window 87 | * when the obs emits/completes 88 | * window completes 89 | * inner obs. unsubscribe 90 | * create new inner obs. & window 91 | 92 | --- 93 | 94 | ## windowToggle 95 | 96 | `windowToggle(openingObs$, (valueOfOpening) => closingObs$)` 97 | 98 | [StackBlitz](https://stackblitz.com/edit/windowtoggle?file=index.ts). 99 | 100 | * the factory function that creates the `closing observable` can accept that **inner value** that comes from the `opening observable` as an argument 101 | * the outer value will be sent to all the active windows 102 | * when `openingObs$` emits 103 | * it will create a new window 104 | * will use provided **factory function** to create a **closing observable**; the inner value resulted from `openingObs$` will be passed as an argument to the factory function 105 | * each **new window** will be **paired** with the **inner subscriber** of the newly created **closing observable** 106 | * when `closingObs$` `emits`/`completes` 107 | * it will be unsubscribed 108 | * the window that was paired with its inner subscriber will be closed(will emit a `complete` notification) 109 | * when `openingObs$` completes -> nothing happens, it simply means that no extra windows can be created 110 | * if the outer subscriber(`WindowToggleSubscriber`) is unsubscribed, all the stored closing subscriber-window pairs will be iterated through and window will complete and each subscriber will be unsubscribed 111 | * when the outer subscriber `errors`/`completes` 112 | * the notif. will be sent to all the existing windows 113 | * each closing subscriber will be unsubscribed 114 | 115 | * diagram 116 | * openings obs. 117 | * closing obs factory 118 | * contexts(array of closing subscriber-window pairs) 119 | * active windows sent to the destination subscriber(each with `----->`) 120 | * when opening emits -> create pair -> add to contexts -> add `----->` 121 | * when closing emits -> remove from pair; remove `----->` 122 | 123 | --- 124 | 125 | ## windowCount 126 | 127 | `windowCount(windowSize, startWindowEvery = 0)` 128 | 129 | * it is similar to `windowTime(windowTimeSpan, windowCreationInterval)`, but instead of specifying time intervals, you specify counters 130 | * can have **multiple active windows** 131 | * a window can emit at most `windowSize` items 132 | * every `startWindowEvery` values, a **new window** will be created 133 | * an outer value will be sent to all the active values 134 | 135 | * diagram (do not need to use real numbers) 136 | * active counter 137 | * `windowSize` 138 | * `startWindowEvery` 139 | * show window immediately(`----->`) 140 | * when value comes in: increment active counter + send value through window 141 | * when `windowSize` is reached: close window(remove arrow) 142 | * when `startWindowEvery` is reached: create a new window(add arrow) & emit the current value to it 143 | 144 | --- 145 | -------------------------------------------------------------------------------- /bash-scripts/generate-boilerplate/main.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | js="" 4 | 5 | html="$(echo " 6 | 7 | 8 | 9 | 10 | 11 | 12 | Document 13 | 14 | 15 | 16 | 17 | 18 | $([ "$2" == 'js' ] && echo $js || echo '') 19 | 20 | " 21 | )" 22 | 23 | # Choose your location 24 | dirPath=$HOME/Documents/Workspace/train/ 25 | cd $dirPath 26 | 27 | nrFiles="$(ls -1 | wc -l)" 28 | nrFiles=$(($nrFiles + 1)) 29 | prefix=$([ $nrFiles -lt 10 ] && echo "0${nrFiles}" || echo $nrFiles) 30 | 31 | mkdir "${prefix}_$1" && cd $_ 32 | 33 | echo "$html" > index.html 34 | echo '' > main.css 35 | 36 | if [[ "$2" == 'js' ]]; then 37 | echo '' > main.js 38 | fi 39 | 40 | code . -------------------------------------------------------------------------------- /bash-scripts/generate-boilerplate/readme.md: -------------------------------------------------------------------------------- 1 | ## Generate boilerplate 2 | A simple script that will generate the boilerplate for your small UI projects. 3 | 4 | ### Motivation 5 | Every time I want to experiment a little bit with CSS and/or UI-related stuff I find it quite monotonous to create a new project, add `index.html`, `main.css` and maybe `main.js`. 6 | So now, with the help of a simple command, I can get started much quicker. 7 | 8 | ### Getting started 9 | 10 | ```bash 11 | # pwd = $HOME 12 | mkdir bin && cd $_ 13 | 14 | touch 15 | sudo chmod 777 16 | 17 | # In order to access your script globally, open `.bash_profile`(if !exists, create it) 18 | # and paste the following line 19 | export PATH=$PATH:/home/andubuntu 20 | ``` 21 | 22 | ### Usage 23 | 24 | Before running the script, make sure that you choose your location where it would generate the files. You can do this by opening `main.sh` and look for the suggestive comment. 25 | 26 | ```bash 27 | # If you want your project to have a `main.js` 28 | js 29 | # Otherwise 30 | 31 | ``` -------------------------------------------------------------------------------- /notebooks/concepts.md: -------------------------------------------------------------------------------- 1 | # Concepts 2 | 3 | - [Concepts](#concepts) 4 | - [Software Architecture](#software-architecture) 5 | - [Referential Transparency](#referential-transparency) 6 | - [Component](#component) 7 | - [Stateful Components](#stateful-components) 8 | - [Stateless Components](#stateless-components) 9 | 10 | ## Software Architecture 11 | 12 | A **unit** composed of **multiple parts** along with **rules & constraints** that define how these **parts communicate**. 13 | 14 | --- 15 | 16 | ## Referential Transparency 17 | 18 | A functional programming-related concept, which says that in a program, an **expression** can be **replaced** by a **value** **without changing** the **result** of the **program**. 19 | 20 | In order words, it means that given the **same inputs**, the expression will always **produce** the **same output**. 21 | 22 | ```typescript 23 | function plusOne (num: number) { 24 | return num + 1; 25 | } 26 | ``` 27 | 28 | The above function is a referential transparent one, because you can **replace** it **with** a **value** instead of calling the function. 29 | We could, for example, use `11` instead of `plusOne(10)`. 30 | 31 | --- 32 | 33 | ## Component 34 | 35 | An isolated piece of functionality that allows us to achieve a better separation of concerns. 36 | 37 | ### Stateful Components 38 | 39 | - drives state changes 40 | - provides data(i.e from http layers) 41 | - utilises **stateless components** 42 | - has knowledge of the current state 43 | 44 | ### Stateless Components 45 | 46 | - similar to **pure functions**: they **do not** contain **free variables** 47 | - receive **data** via **property binding**(equivalent to **function arguments**) 48 | - emit **changes** via an **event**(equivalent to a **return** statement) 49 | 50 | --- 51 | -------------------------------------------------------------------------------- /notebooks/css.md: -------------------------------------------------------------------------------- 1 | 2 | # CSS Notebook 3 | 4 | - [CSS Notebook](#css-notebook) 5 | - [Knowledge](#knowledge) 6 | - [Rendering](#rendering) 7 | - [layout](#layout) 8 | - [paint](#paint) 9 | - [compositing](#compositing) 10 | - [`@import` vs ``](#import-vs-link) 11 | - [extrinsic vs intrinsic dimensions](#extrinsic-vs-intrinsic-dimensions) 12 | - [stacking context](#stacking-context) 13 | - [`z-index`](#z-index) 14 | - [replaced element](#replaced-element) 15 | - [Properties](#properties) 16 | - [`display`](#display) 17 | - [`visibility`](#visibility) 18 | - [`width`](#width) 19 | - [`backdrop-filter`](#backdrop-filter) 20 | - [Tricks](#tricks) 21 | - [Triangle(Arrow)](#trianglearrow) 22 | - [Checking if an input is empty with CSS](#checking-if-an-input-is-empty-with-css) 23 | - [Hover Media Query](#hover-media-query) 24 | - [prefers-reduced-motion](#prefers-reduced-motion) 25 | - [Accessibility](#accessibility) 26 | - [Hiding an element](#hiding-an-element) 27 | - [BEM](#bem) 28 | - [Namespaces](#namespaces) 29 | - [Cascade and Specificity](#cascade-and-specificity) 30 | - [Cascade](#cascade) 31 | - [Specificity](#specificity) 32 | - [Order of priority](#order-of-priority) 33 | - [CSS Grid](#css-grid) 34 | - [`fr` and `auto`](#fr-and-auto) 35 | - [`auto`](#auto) 36 | - [`fr`](#fr) 37 | - [`justify-self` vs `justify-content` vs `justify-items`](#justify-self-vs-justify-content-vs-justify-items) 38 | - [Flexbox](#flexbox) 39 | - [SCSS](#scss) 40 | - [mixin vs placeholder](#mixin-vs-placeholder) 41 | - [box-shadow: list()](#box-shadow-list) 42 | - [Animations](#animations) 43 | - [`@keyframes`](#keyframes) 44 | 45 | ## Knowledge 46 | 47 | * `speculative parsing`: **fetch** other needed **resources** while a **script** is being **executed** 48 | 49 | * `initial containing block`: the containing block in which the **root element**(``) resides; it has the dimensions of the **viewport**. 50 | 51 | ### Rendering 52 | [Article 1](https://dev.to/devdevcharlie/things-nobody-ever-taught-me-about-css-2lhj) 53 | [Article 2](https://itnext.io/how-the-browser-renders-a-web-page-dom-cssom-and-rendering-df10531c9969) 54 | 55 | After the **Render-tree** has been constructed from **DOM + CSSOM**, the browser starts printing elements on the screen. 56 | 57 | * CSS does **not block** DOM construction, it **blocks rendering**: you won't be able to see anything on the page until the browser has **both DOM and CSSSOM** 58 | 59 | Changes in **one phase** will have **consequences** on the **following phases**. 60 | 61 | * when ``(load external `css` file) is encountered: the browser will send a request to fetch the `.css` file **asynchronously** and **continue to parse** the **other HTML elements** below 62 | 63 | * when `