Tuesday, June 18, 2019

Redux Saga - what if need to run multiple tasks in parallel

The yield statement is great for representing asynchronous control flow in a linear style, but we also need to do things in parallel. We can't write:

// wrong, effects will be executed in sequence
const users = yield call(fetch, '/users')
const repos = yield call(fetch, '/repos')

Because the 2nd effect will not get executed until the first call resolves. Instead we have to write:

import { all, call } from 'redux-saga/effects'

// correct, effects will get executed in parallel
const [users, repos] = yield all([
  call(fetch, '/users'),
  call(fetch, '/repos')
])

When we yield an array of effects, the generator is blocked until all the effects are resolved or as soon as one is rejected (just like how Promise.all behaves).

To note, the call inside the array need not be covered in yield call.


References:
https://redux-saga.js.org/docs/advanced/RunningTasksInParallel.html

Node Express, how to get the user agent and other requester details

The package express-useragent gives much of the details

npm install express-useragent

The usage is like below

var express = require('express');
var app = express();
var useragent = require('express-useragent');

app.use(useragent.express());
app.get('/', function(req, res){
    res.send(req.useragent);

});
app.listen(3000);


The result is like this below, pretty useful. In this sample, the geoIP is coming as empty however.


{ isAuthoritative: true,
  isMobile: false,
  isTablet: false,
  isiPad: false,
  isiPod: false,
  isiPhone: false,
  isAndroid: false,
  isBlackberry: false,
  isOpera: false,
  isIE: false,
  isEdge: false,
  isIECompatibilityMode: false,
  isSafari: false,
  isFirefox: false,
  isWebkit: false,
  isChrome: true,
  isKonqueror: false,
  isOmniWeb: false,
  isSeaMonkey: false,
  isFlock: false,
  isAmaya: false,
  isPhantomJS: false,
  isEpiphany: false,
  isDesktop: true,
  isWindows: false,
  isLinux: false,
  isLinux64: false,
  isMac: true,
  isChromeOS: false,
  isBada: false,
  isSamsung: false,
  isRaspberry: false,
  isBot: false,
  isCurl: false,
  isAndroidTablet: false,
  isWinJs: false,
  isKindleFire: false,
  isSilk: false,
  isCaptive: false,
  isSmartTV: false,
  isUC: false,
  isFacebook: false,
  isAlamoFire: false,
  silkAccelerated: false,
  browser: 'Chrome',
  version: '74.0.3729.169',
  os: 'macOS High Sierra',
  platform: 'Apple Mac',
  geoIp: {},
  source:
   'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36' }

References:
https://www.npmjs.com/package/express-useragent



Express Node JS, how do we get the requesting user's IP ?



The request-ip package seems to be very effective in this regard
npm install request-ip --save

Below is the usage for this

const requestIp = require('request-ip');
app.use(requestIp.mw())

app.use(function(req, res) {
    const ip = req.clientIp;
    res.end(ip);
});

It looks for specific headers in the request and falls back to some defaults if they do not exist.

The user ip is determined by the following order:

    X-Client-IP
    X-Forwarded-For (Header may return multiple IP addresses in the format: "client IP, proxy 1 IP, proxy 2 IP", so we take the the first one.)
    CF-Connecting-IP (Cloudflare)
    Fastly-Client-Ip (Fastly CDN and Firebase hosting header when forwarded to a cloud function)
    True-Client-Ip (Akamai and Cloudflare)
    X-Real-IP (Nginx proxy/FastCGI)
    X-Cluster-Client-IP (Rackspace LB, Riverbed Stingray)
    X-Forwarded, Forwarded-For and Forwarded (Variations of #2)
    req.connection.remoteAddress
    req.socket.remoteAddress
    req.connection.socket.remoteAddress
    req.info.remoteAddress

If an IP address cannot be found, it will return null.

References:
https://www.npmjs.com/package/request-ip


Express, node JS. How to get the local IP where the app runs

Below are the properties from the Connection where we get the IP address and the port info.

req.connection.localAddress
req.connection.localPort

However this was not giving the public


References:
https://stackoverflow.com/questions/38423930/how-to-retrieve-client-and-server-ip-address-and-port-number-in-node-js


Node Express, serving the static files

To serve static files, below is what to be done, pretty simple.

Define the folder which is to be used for serving the files from

app.use(express.static('public'))

Now, you can load the files that are in the public directory:

http://localhost:3000/images/kitten.jpg
http://localhost:3000/css/style.css
http://localhost:3000/js/app.js
http://localhost:3000/images/bg.png
http://localhost:3000/hello.html

To use multiple static assets directories, call the express.static middleware function multiple times:

app.use(express.static('public'))
app.use(express.static('files'))

To create a virtual path prefix (where the path does not actually exist in the file system) for files that are served by the express.static function, specify a mount path for the static directory, as shown below:

app.use('/static', express.static('public'))

http://localhost:3000/static/images/kitten.jpg
http://localhost:3000/static/css/style.css

http://localhost:3000/static/js/app.js
http://localhost:3000/static/images/bg.png
http://localhost:3000/static/hello.html


References:
https://expressjs.com/en/starter/static-files.html

Express, Node - How to send the files in the server response

Below is how to do it

app.get('/', function(req, res) {
    res.sendFile('index.html', { root: __dirname });
});

__dirname is a keyword which will help to get the directory name of the app that is currently running.
This way the file can be streamed as well.


References:
https://stackoverflow.com/questions/26079611/node-js-typeerror-path-must-be-absolute-or-specify-root-to-res-sendfile-failed


How to Enable CORS in node JS app on the server side

Simple thing will be to enable Core middleware, like the below

const cors = require('cors')

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

app.get('/', cors(), (request, response) => {
  response.send('OK, am up!')
})


References:
https://flaviocopes.com/express-cors/

Saturday, June 8, 2019

Material UI - Theme provider

Lets say we create an app with

It seems that you will need a couple of material-ui components:

An AppBar
2 Buttons

And the app.js look like below

import AppBar from 'material-ui/AppBar';
import Button from 'material-ui/Button';
import React, { PureComponent } from 'react';

export default class Header extends PureComponent {
  render() {
    return (
     
       

         
           
Button 1

         
         
           
Button 2

         
       
     
    );
  }
}

To customise the material theme, below to be done

First, create a file theme.js in your app folder. We would like to give some pinkful color to our app bar:

import { createMuiTheme } from 'material-ui/styles';
import indigo from 'material-ui/colors/indigo';
import pink from 'material-ui/colors/pink';
import red from 'material-ui/colors/red';

export default createMuiTheme({
  palette: {
    primary: pink,
    secondary: indigo // Indigo is probably a good match with pink
  }
});

Then, we have to provide the theme above to your app. In order to this, we will encapsulate our app in a MuiThemeProvider.

import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import theme from 'xx/xx/theme';

Encapsulate the app in it and pass your theme file in props
export default class Header extends PureComponent {
  render() {
    return (
     
       
         

           
             
Button 1

           
           
             
Button 2

           
         
       
     
    );
  }
}

One step further, what if we want to customise all instances of a component type?

To customize a specific kind of material UI components within our app, we will add an overrides property to our theme.js file as described below. You will need to provide to your theme object, the name and class of the component you want to customize. This will be found in the material-ui API documentation.


import { createMuiTheme } from 'material-ui/styles';
import indigo from 'material-ui/colors/indigo';
import pink from 'material-ui/colors/pink';
import red from 'material-ui/colors/red';

export default createMuiTheme({
  palette: {
    primary: pink,
    secondary: indigo
  },
  overrides: {
    MuiButton: {
      root: {
        color: 'white',
        '&:hover': {
          backgroundColor: 'purple'
        }
      }
    }
  }
});

And what if we need to override for a specific instance of a component ?

MaterialUI theme will not be of any help here anymore, and our best chance is to inline style our left Button.

export default class Header extends PureComponent {
  render() {
    return (
     
       
         

           
             
Button 1

           
           
             
Button 2

           
         
       
     
    );
  }
}


https://blog.bam.tech/developper-news/get-the-best-of-your-react-app-design-by-using-material-ui-theme

Material-UI Styling getting started

To install and save in your package.json dependencies, run:

yarn add @material-ui/styles

There are  3 different APIs to generate and apply styles, however they all share the same underlying logic.

Hook API

import React from 'react';
import { makeStyles } from '@material-ui/styles';
import Button from '@material-ui/core/Button';

const useStyles = makeStyles({
  root: {
    background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
    border: 0,
    borderRadius: 3,
    boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
    color: 'white',
    height: 48,
    padding: '0 30px',
  },
});

export default function Hook() {
  const classes = useStyles();
  return ;
}


Styled components API

import React from 'react';
import { styled } from '@material-ui/styles';
import Button from '@material-ui/core/Button';

const MyButton = styled(Button)({
  background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
  border: 0,
  borderRadius: 3,
  boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
  color: 'white',
  height: 48,
  padding: '0 30px',
});

export default function StyledComponents() {
  return Styled Components;
}

Higher-order component API

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/styles';
import Button from '@material-ui/core/Button';

const styles = {
  root: {
    background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
    border: 0,
    borderRadius: 3,
    boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
    color: 'white',
    height: 48,
    padding: '0 30px',
  },
};

function HigherOrderComponent(props) {
  const { classes } = props;
  return ;
}

HigherOrderComponent.propTypes = {
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(HigherOrderComponent);



references:
https://material-ui.com/styles/basics/#installation

Why use Material-UI's styling solution CSS-In-JS

Material-UI's styling solution is inspired by many other styling libraries such as styled-components and emotion.

💅 You can expect the same advantages as styled-components.
🚀 It's blazing fast.
🧩 It's extensible via a plugin API.
⚡️ It uses JSS at its core – a high performance JavaScript to CSS compiler which works at runtime and server-side.
📦 Less than 15 KB gzipped; and no bundle size increase if used alongside Material-UI.



references:
https://material-ui.com/styles/basics/

CSS in JS - A Unified Styling Language?

In the past few years we’ve seen the rise of CSS-in-JS, emerging primarily from within the React community. This, of course, hasn’t been without its controversies. Many people, particularly those already intimately familiar with CSS, have looked on in disbelief.

To get a clearer understanding of why people are choosing to write their styles in JavaScript, we’ll focus on the practical benefits that emerge when taking this approach.


broken this down into five major areas:

Scoped styles
Critical CSS
Smarter optimisations
Package management
Non-browser styling

Scoped styles
It’s no secret that architecting CSS effectively at scale is incredibly difficult. When joining an existing long-lived project, it wasn’t uncommon to find that the CSS was the hardest part of the system to figure out.

To counter this, the CSS community has invested heavily in trying to address these issues, making our styles more maintainable with methodologies like OOCSS by Nicole Sullivan and SMACSS by Jonathan Snook—but the clear winner right now in terms of popularity seems to be BEM, or Block Element Modifier, from Yandex.

Ultimately, BEM (when applied purely to CSS) is just a naming convention, opting to limit styles to classes following a .Block__element--modifier pattern. In any given BEM-styled codebase, developers have to remember to follow BEM’s rules at all times. When strictly followed, BEM works really well, but why is something as fundamental as scoping left up to pure convention?

Whether they explicitly say so or not, the majority of CSS-in-JS libraries are following the BEM mindset of trying to target styles to individual UI elements, but implementing it in a radically different way.

What does this look like in practice? When using glamor by Sunil Pai, it looks something like this:

import { css } from 'glamor'
const title = css({
  fontSize: '1.8em',
  fontFamily: 'Comic Sans MS',
  color: 'blue'
})
console.log(title)
// → 'css-1pyvz'
What you’ll notice here is that the CSS class is nowhere to be found in our code. It’s no longer a hard-coded reference to a class defined elsewhere in the system. Instead, it is generated automatically for us by the library. We don’t have to worry about our selectors clashing in the global scope, which means we no longer have to manually prefix them.

The scoping of this selector matches the scoping rules of the surrounding code. If you want to make this rule available to the rest of your application, you’ll need to turn it into a JavaScript module and import it wherever it’s used. In terms of keeping our codebases maintainable over time, this is incredibly powerful, making sure that the source of any given style can be easily traced like any other code.

By moving from mere convention towards enforcing locally-scoped styles by default, we’ve now improved the baseline quality of our styles. BEM is baked in, not opt-in.


Most of the earliest CSS-in-JS libraries attached styles directly to each element, but the critical flaw in this model is that ‘style’ attributes can’t do everything that CSS can do. Most new libraries instead focus on dynamic style sheets, inserting and removing rules at runtime from a global set of styles.

As an example, let’s have a look at JSS by Oleg Slobodskoi, one of the earliest CSS-in-JS libraries to generate real CSS.

When using JSS, you can use standard CSS features like hover styles and media queries, which map directly to the equivalent CSS rules.

const styles = {
  button: {
    padding: '10px',
    '&:hover': {
      background: 'blue'
    }
  },
  '@media (min-width: 1024px)': {
    button: {
      padding: '20px'
    }
  }
}

Once you insert these styles into the document, the automatically generated classes are provided to you.

const { classes } = jss.createStyleSheet(styles).attach()

These generated classes can then be used instead of hard-coded class strings when generating markup in JavaScript. This pattern works regardless of whether you’re using a full-blown framework, or something as simple as innerHTML.

document.body.innerHTML = `
 

Hello World!


`

Managing the styles in this way is of little benefit by itself—it’s usually paired with some kind of component library. As a result, it’s typical to find bindings available for the most popular libraries. For example, JSS can easily bind to React components with the help of react-jss, injecting a small set of styles into each component while managing the global lifecycle for you.

import injectSheet from 'react-jss'
const Button = ({ classes, children }) => (
 
   
      {children}
   
 
)
export default injectSheet(styles)(Button)

references:
https://medium.com/seek-blog/a-unified-styling-language-d0c208de2660

What is Styled-Component

By focusing our styles around components, integrating them more closely at the code level, we’re effectively taking BEM to its logical conclusion. So much so that many in the CSS-in-JS community felt like the importance of extracting, naming and reusing components was being lost in all the style-binding boilerplate.


An entirely new way of thinking about this problem emerged with the introduction of styled-components by Glen Maddern and Max Stoiber.

import styled from 'styled-components'

const Title = styled.h1`
  font-family: Comic Sans MS;
  color: blue;
`

When applying these styles, we don’t attach a class to an existing element. We simply render the generated component.

Hello World!

While styled-components uses traditional CSS syntax via tagged template literals, others prefer working with data structures instead. A notable alternative is Glamorous by Kent C. Dodds from PayPal.

Glamorous offers the same component-first API as styled-components, but opts for objects instead of strings, eliminating the need to include a CSS parser in the library—reducing the library’s size and performance footprint.



import glamorous from 'glamorous'

const Title = glamorous.h1({
  fontFamily: 'Comic Sans MS',
  color: 'blue'
})

Whichever syntax you use to describe your styles, they’re no longer just scoped to components—they’re inseparable from them. When using a library like React, components are the fundamental building blocks, and now our styles form a core part of that architecture. If we describe everything in our app as components, why not our styles too?



references:
https://medium.com/seek-blog/a-unified-styling-language-d0c208de2660

What is CSS in JS


CSS-in-JS refers to a collection of ideas to solve complex problems with CSS. Since it is NOT a particular library, different libs might solve a different subset of problems and use different approaches, depending on their implementation details.


However, all implementations have in common that they tackle the problems using APIs instead of convention and they leverage JavaScript as a language for styles authoring.

Lack of modules
CSS historically never had actual modules, neither did JavaScript. Requirements for web applications evolved and JavaScript has added a module system. First in the form of a bolt-on solution (CommonJS), later as a standard, statically analyzable module system known as ECMAScript Modules (ESM).

The reasoning behind modules applies to both JavaScript and CSS: to be able to hide implementation details by exposing only public APIs. We need to be able to decouple subsystems of an application explicitly so that changing code becomes more predictable.


Lack of scoping
We know CSS always had a single global namespace, for example, a class can be added to any element, a tag selector can target any element in the document. CSS was initially created to style documents and there was no need for components. The entire page was styled as one big chunk and it usually didn’t involve many people working on it. Since then the complexity of many sites has dramatically increased and this is the main reason why many CSS methodologies were created. None of the conventions is easy to establish and consistently enforce when many people contribute to a project over the years.



references:
https://medium.com/dailyjs/what-is-actually-css-in-js-f2f529a2757
https://github.com/oliviertassinari/a-journey-toward-better-style

What is LESS

Less (which stands for Leaner Style Sheets) is a backwards-compatible language extension for CSS. This is the official documentation for Less, the language and Less.js, the JavaScript tool that converts your Less styles to CSS styles. Because Less looks just like CSS, learning it is a breeze.

Variables

@width: 10px;
@height: @width + 10px;

#header {
  width: @width;
  height: @height;
}

Mixins
Mixins are a way of including ("mixing in") a bunch of properties from one rule-set into another rule-set. So say we have the following class:

.bordered {
  border-top: dotted 1px black;
  border-bottom: solid 2px black;
}

And we want to use these properties inside other rule-sets. Well, we just have to drop in the name of the class where we want the properties, like so:

#menu a {
  color: #111;
  .bordered();
}

.post a {
  color: red;
  .bordered();
}

The properties of the .bordered class will now appear in both #menu a and .post a. (Note that you can also use #ids as mixins.)

Nesting
Less gives you the ability to use nesting instead of, or in combination with cascading. Let's say we have the following CSS:

#header {
  color: black;
}
#header .navigation {
  font-size: 12px;
}
#header .logo {
  width: 300px;
}

In Less, we can also write it this way:

#header {
  color: black;
  .navigation {
    font-size: 12px;
  }
  .logo {
    width: 300px;
  }
}

The resulting code is more concise, and mimics the structure of your HTML.
You can also bundle pseudo-selectors with your mixins using this method. Here's the classic clearfix hack, rewritten as a mixin (& represents the current selector parent):

.clearfix {
  display: block;
  zoom: 1;

  &:after {
    content: " ";
    display: block;
    font-size: 0;
    height: 0;
    clear: both;
    visibility: hidden;
  }
}



references
http://lesscss.org/

Wednesday, June 5, 2019

Creating first WebRTC application - WebRTC overview

Below are the expectations from WebRTC

Streaming of audio, video or other data.
Getting network information such as IP addresses and ports. Exchanging of this information with other WebRTC clients (peers) to enable connection even through NATs and firewalls.
In case of error reporting, initiation, session closing and coordinating with signaling communication.
Communicating with streaming video, audio or data.
Exchange of information about media and client capability such as resolution and codecs.


The above functions are been implemented by WebRTC by employing some main APIs listed below:
MediaStream (aka getUserMedia)
RTCPeerConnection
RTCDataChannel


Below is a close look at these APIS
MediaStream

getUserMedia or MediaStream takes the access to data streams for example from user’s camera and microphone. MediaStream is available in Chrome, Firefox and Opera. MediaSream API represents synchronized streams of media. This can be well-explained that a stream taken from camera and microphone input has synchronized video and audio tracks. Each MediaStream has an input, which might be a MediaStrem generated by navigator. getUserMedia(), and an output might have been passed to a video element or an RTCPeer Connection.


getUserMedia() method takes three parameters:


A constraint’s object.
Success callback which, if called, is passed a MediaStream.
Failure callback which, if called, is passed an error object.


Each MediaStream has a label, such as ’Xk7EuLhsuHKbnjLWkW4yYGNJJ8ONsgwHBvLQ’. An array of MediaStreamTracks is returned by the getAudioTracks() and getVideoTracks() methods.

For the simpl.info/gum example, stream.getAudioTracks() returns an empty array (because there’s no audio) and, assuming a working webcam is connected, stream.getVideoTracks() returns an array of one MediaStreamTrack representing the stream from the webcam. Each MediaStreamTrack has a kind (‘video’ or ‘audio’), and a label (like ‘FaceTime HD Camera (Built-in)’), and represents one or more channels of either audio or video. In this case, there is only one video track and no audio, but you can easily imagine with use cases where there are more: for example, a chat application that gets streams from the front camera, rear camera, microphone, and a ‘screenshared’ application.

getUserMedia can also be added in Chromium-based apps and extensions. Adding audioCapture and/or videoCapture permissions enables permission to be requested and granted only once, on installation. Thereafter, the user permission for camera or microphone access is not asked.

Similarly, pages using HTTPS: permission only has to be granted once for getUserMedia(). Very first time an Always Allow button is displayed in the info-bar of the browser.
It is always required on enabling MediaStream for any streaming data source not just a camera or microphone. This enables streaming from disc or from arbitrary data sources such as other inputs and sensors.
Note that getUserMedia() must be used on a server, not the local file system, otherwise a PERMISSION_DENIED: 1 error will be thrown.


2. RTCPeerConnection
RTCPeerConnection: Audio or video calling holds the extension of encryption and bandwidth management. It gets supported in Chrome (in desktop and Android both), Opera (on desktop and Android) and of course in Firefox too. RTCPeerConnection is implemented by Chrome and Opera as webkitRTCPeerConnection and by Firefox as mozRTCPeerConnection. There’s an ultra-simple demo of Chromium’s RTCPeerConnection implementation at simpl.info/pc and a great video chat application at apprtc.appspot.com. This app uses adapter.js, a JavaScript shim maintained by Google, that abstracts away browser differences and spec changes.

RTCPeerConnection is the WebRTC component that handles stable and efficient communication of streaming data between peers.


 RTCPeerConnection safeguards web developers from the myriad complexities. The codecs and protocols used by WebRTC takes care of huge amount of work to make real-time communication even over unreliable networks:



    Packet loss concealment

    Echo cancellation

    Bandwidth adaptivity

    Dynamic jitter buffering

    Automatic gain control

    Noise reduction and suppression

    Image ‘cleaning.’


WebRTC Signalling, session control, network and media information


WebRTC uses RTCPeerConnection to communicate streaming data between browsers. Along with this it also needs a mechanism to coordinate communication and to send control messages. This process can be defined as a signaling. One should know that signaling is not part of the RTCPeerConnection API.

developers can choose whatever messaging protocol they prefer, such as SIP or XMPP, and also an appropriate duplex (two-way) communication channel.


WebRTC needs four types of server-side functionality:

User discovery and communication.
Signaling.
NAT/firewall traversal.
Relay servers in case peer-to-peer communication fails.

RTCDataChannel: peer-to-peer communication of generic data. The API is supported by Chrome 25, Opera 18 and Firefox 22 and above.

References
https://dzone.com/articles/how-to-create-your-first-webrtc-application