Friday, May 28, 2021

3 Ways to Name Types in Typescript

TypeScript type's system is structural and hence, it allows for the easy creation of types based on the shape of data. These types can be created and used without having a name. For example:

let john: {name: string, age: number} = { 
  name: "John Doe", 
  age: 30
}

Where {name: string, age: number} is the type defined.

But there is a problem with using the type definition this way. If we want to create another person and annotate another variable with the type, we would need to repeat ourselves:

let john: {name: string, age: number} = {
  name: "John Doe", 
  age: 30
}

let jane: {name: string, age: number} = {
   name: "Jane Doe", 
   age: 45
}

This is not dry.


Saturday, May 22, 2021

How to implement sleep function in JavaScript

Most popular mainstream languages have a sleep functionality that allows for the pausing of code execution for a specified amount of time. Not surprising this functionality is often implemented via a function usually named sleep. For example:

// ruby
sleep(time_secs)
// python
import time
time.sleep(time_secs)
// Java
Thread.sleep(time_milli_secs)
// Perl
sleep(time_secs)

JavaScript does not have a similar sleep function, although it has the setTimeout function which can be used to achieve a similar purpose. The only problem is, using setTimeout is not as convenient as one would like. This is due to the fact that setTimeout is an asynchronous function, hence one would have to continue the execution of the code, in the callback passed to it, after the elapsed time.

console.log("Executing code..."); 
setTimeout(() => { 
console.log("continue after pause"); 
}, 3000)

This is not convenient.

A more convenient option would be to have something similar to:

console.log("Executing code..."); 
// sleep for some time
// sleep()
console.log("continue after pause");

Unfortunately, this does not exist natively in JavaScript. But this is not to say we can't implement one!


Thursday, May 20, 2021

Callback, Promise and Async/Await by Example in JavaScript

This post is going to show,  by way of code examples, how to take a callback based API, modify it to use Promises and then use the Async/Await syntax. This post won't go into a detailed explanation of callbacks, promises or the Async/Await syntax. For such a detailed explanation of these concepts please check Asynchronous JavaScript, which is a section of MDN Web Docs, that explains asynchronicity and how callbacks, promises, and the Async/Await syntax helps with working with asynchronous JavaScript.

This post is meant for the developer who has somewhat of an understanding of asynchronicity in JavaScript, but requires a straight to the point code example to serve as a quick syntax reference for how to take a callback based API, update it to use promises and finally use the Async/Await with it.

For demonstration purposes, we are going to use the fs.readFile, which is a callback based API from reading files. We will have a file test.txt that would contain some text, we will then have a file script.js that would open the file, read the contents, and print it to the terminal.

The code will first be implemented using callbacks, it would then be updated to use Promises, and finally, instead of using Promise directly, it will be updated to use Async/Await.

Let's get started.


Sunday, May 09, 2021

ip-num v1.3.2 has been released

ip-num is A TypeScript/JavaScript library for working with ASN, IPv4, and IPv6 numbers. It provides representations of these internet protocol numbers with the ability to perform various IP related operations like parsing, validating etc, on them.

A new version of ip-num, version 1.3.2 is now available.

This release contains one new feature and a bug fix.

Add method to split range into smaller ranges of certain size

In previous versions of ip-num, it was possible to take IP ranges with prefix less than /32 and split them into two. For example:

import {IPv4CidrRange} from "ip-num/IPRange";
import {IPv4Prefix} from "ip-num/Prefix";

let ipv4CidrRange = IPv4CidrRange.fromCidr("192.168.208.0/24");
let splitRanges: Array<IPv4CidrRange> = ipv4CidrRange.split();

// console logs:
// 192.168.208.0/25
// 192.168.208.128/25

splitRanges.forEach(range => console.log(range.toCidrString()))

But what if one needs to take an IP range and instead of just splitting into two, there is the requirement to split into a number of ranges with a specified prefix? Well, that is now possible with the addition of splitInto method:

import {IPv4CidrRange} from "ip-num/IPRange";
import {IPv4Prefix} from "ip-num/Prefix";

let ipv4CidrRange = IPv4CidrRange.fromCidr("192.168.208.0/24");
let splitRanges: Array<IPv4CidrRange> = 
ipv4CidrRange.splitInto(IPv4Prefix.fromNumber(26));

// console logs:
// 192.168.208.0/26
// 192.168.208.64/26
// 192.168.208.128/26
// 192.168.208.192/26

splitRanges.forEach(range => console.log(range.toCidrString()))

RangedSet.isCidrAble() incorrect results

Previous versions of ip-num failed to properly report that a string representing a single IP can be represented in the CIDR notation. This has now been fixed:

import {RangedSet} from "ip-num/IPRange";

let rangedSet= RangedSet.fromRangeString("1.2.3.4-1.2.3.4");

// now returns true
console.log(rangedSet.isCidrAble())

As always, ip-num is just an npm install or npm upgrade away.

Feel free to open an issue to discuss a feature or to report a bug.