# NodeJS
- Executable for nodejs app
[https://www.youtube.com/watch?v=50f6y-npKAY](https://www.youtube.com/watch?v=50f6y-npKAY)
`npm i -g pkg`
`pkg app.js`
[https://www.youtube.com/watch?v=crnaBzztX44](https://www.youtube.com/watch?v=crnaBzztX44)
[https://www.npmjs.com/package/pkg](https://www.npmjs.com/package/pkg)
in package.json add:
```json
"pkg": {
"scripts": "build/**/*.js",
"assets": ["views/**/*","public/**","build/**"],
"targets": [ "node14-win-x64" ]
}
```
Now type:
`pkg app.js -c package.json`
this will create the exe file. In assets resources is assigned like build/** so that all build folder is included as its front end in smart brain app. if we have images folder then include that too.
- converting callback to async/await
```jsx
const promiseSetTimeOut = (time) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, time);
});
};
// or
// delay.js
export function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
```
- apk version fo nodejs app
[Apache Cordova app development setup guide - Andrés Zsögön (andreszsogon.com)](https://www.andreszsogon.com/setting-up-your-environment-for-apache-cordova-apps/)
[https://cordova.apache.org/docs/en/3.5.0/guide/cli/index.html](https://cordova.apache.org/docs/en/3.5.0/guide/cli/index.html)
expressjs in mobile:
[https://www.sitepoint.com/how-to-run-node-js-with-express-on-mobile-devices/](https://www.sitepoint.com/how-to-run-node-js-with-express-on-mobile-devices/)
[https://github.com/node-on-mobile/node-on-android](https://github.com/node-on-mobile/node-on-android)
- Exposing localhost to internet for testing
```jsx
const localtunnel = require('localtunnel');
(async () => {
const tunnel = await localtunnel({ port: 80 });
// the assigned public url for your tunnel
// i.e. https://abcdefgjhij.localtunnel.me
// tunnel.url;
console.log('url: ',tunnel.url)
tunnel.on('close', () => {
// tunnels are closed
});
})();
```
Ngrok:
Install ngrok or add ngrok.exe file in environment path from [https://ngrok.com/download](https://ngrok.com/download)
If local nodejs app is started in port number say 3000 then type
`ngrok http 3000`
public url wil be printed in terminal or access by [http://localhost:4040](http://localhost:4040/)
[NodeGUI](../../Export-9fad9947-5bd5-4195-952b-6512c5a4beb1/Web%20development%2083dd4e6675f04ba782a6865a434a0598/NodeJS%206d499253059041d699e2e6fa36ded013/NodeGUI%20ac8ad0b3e1a74e0ca752c60add16e6ce.md)
- Extract metadata
[https://www.npmjs.com/package/metadata-scraper?activeTab=readme](https://www.npmjs.com/package/metadata-scraper?activeTab=readme)
[](https://www.npmjs.com/package/metadata-scraper?activeTab=readme)
[https://www.npmjs.com/package/page-metadata-parser](https://www.npmjs.com/package/page-metadata-parser)
[https://www.scrapingbee.com/blog/node-fetch/](https://www.scrapingbee.com/blog/node-fetch/)
- Page scrapper
browser as service : [https://www.browserless.io/blog/2022/05/31/youtube-scraper/](https://www.browserless.io/blog/2022/05/31/youtube-scraper/)
[https://www.demo2s.com/node.js/node-js-url-project-playlist-scraper-takes-a-youtube-playlist-url-gi.html](https://www.demo2s.com/node.js/node-js-url-project-playlist-scraper-takes-a-youtube-playlist-url-gi.html)
- for lazy loading content(which render when we scroll down to that):
[https://stackoverflow.com/questions/51529332/puppeteer-scroll-down-until-you-cant-anymore](https://stackoverflow.com/questions/51529332/puppeteer-scroll-down-until-you-cant-anymore)
```jsx
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: false
});
const page = await browser.newPage();
await page.goto('https://www.yoursite.com');
await page.setViewport({
width: 1200,
height: 800
});
await autoScroll(page);
await page.screenshot({
path: 'yoursite.png',
fullPage: true
});
await browser.close();
})();
async function autoScroll(page){
await page.evaluate(async () => {
await new Promise((resolve) => {
var totalHeight = 0;
var distance = 100;
var timer = setInterval(() => {
var scrollHeight = document.body.scrollHeight;
window.scrollBy(0, distance);
totalHeight += distance;
// scrollheight is subtracted as innerheight is portion
// only rendered so remaining portion to be scrolled down
if(totalHeight >= scrollHeight - window.innerHeight){
clearInterval(timer);
resolve();
}
}, 100);
});
});
}
```
- Download any file from web server
[https://www.npmjs.com/package/nodejs-file-downloader](https://www.npmjs.com/package/nodejs-file-downloader)
- Alternative of axios
[https://stackoverflow.com/questions/13864983/how-to-post-multipart-form-data-with-node-js-superagent](https://stackoverflow.com/questions/13864983/how-to-post-multipart-form-data-with-node-js-superagent)
```jsx
const superagent = require('superagent');
superagent
.post('https://www.y2mate.com/mates/en423/analyze/ajax')
// .send(formData) // sends a JSON post body
.set('accept', 'application/json')
.field('url',url)
.field('q_auto',0)
.field('ajax',2)
.end(async (err, res) => {
// same as finally means both then and catch
}
```
or for json:
```jsx
superagent
.post('/api/pet')
.send({ name: 'Manny', species: 'cat' }) // sends a JSON post body
.set('X-API-Key', 'foobar')
.set('accept', 'json')
.end((err, res) => {
// Calling the end function will send the request
});
// promise with then/catch
superagent.post('/api/pet').then(console.log).catch(console.error);
```
- Inspect nodejs app to Chrome
`node inspect app.js`
In browser type
`chrome://inspect` and open dedicated DevTools for Node
- Update nodejs and npm
[https://www.geeksforgeeks.org/how-to-update-node-js-and-npm-to-next-version/](https://www.geeksforgeeks.org/how-to-update-node-js-and-npm-to-next-version/)
- Taking input in synchronous way
```jsx
// to take input from user
const readlineSync = require('readline-sync');
// Wait for user's response.
const phrase = readlineSync.question('Type a phrase (or quit to exit program): ');
```
- async fs without callback hell
[https://www.youtube.com/watch?v=msnTtrx2C4s](https://www.youtube.com/watch?v=msnTtrx2C4s)
- file system cache in nodejs
[https://www.npmjs.com/package/file-system-cache](https://www.npmjs.com/package/file-system-cache)
Example:
```jsx
// const NodeCache=require('node-cache')
// const myCache=new NodeCache();
const FileSystemCache_1 =require('file-system-cache')
const options={basePath: "./.cache", // Optional. Path where cache files are stored (default).
ns: "my-namespace" // Optional. A grouping namespace for items.
}
const cache=new FileSystemCache_1.FileSystemCache(options)
const heavyComputation=()=>{
let temp = 0;
for(let i=0; i<100000; i++)
temp = (Math.random()*5342)%i;
return 123;
}
const main=async()=>{
if(await cache.fileExists('key'))
{
console.log('res: ',await cache.get('key'))
}
else{
let res= heavyComputation()
cache.set('key',res)
console.log('Value not present performing calculation')
console.log('res2: ',res)
}
}
main()
```
some changes in `./node_modules/file-system-cache/lib/index.js` :
```jsx
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FileSystemCache = void 0;
const FileSystemCache_1 = require("./FileSystemCache");
Object.defineProperty(exports, "FileSystemCache", { enumerable: true, get: function () { return FileSystemCache_1.FileSystemCache; } });
const Cache= (options) => new FileSystemCache_1.FileSystemCache(options);
exports.default = FileSystemCache_1
```
- Mockable.io
used by front end developers to create rest api
- read only file system
When working on read only file system use the /tmp to perform write functions.
`fs.writeFileSync("/tmp/users.json", JSON.stringify(users))`
- state management in nodejs
```jsx
//state.js file
class State {
constructor() {
this.currentState = false;
this.data = null;
this.setState = (st) => {
this.currentState=st;
};
this.setData = (da) => {
this.data = da;
}
}
}
const appState = new State();
module.exports = appState;
```
```jsx
const appState = require("./state");
const PORT = 3000;
const promiseSetTimeOut = (time) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, time);
});
};
const app = express();
app.use(express.static(__dirname + "/public"));
app.get("/getData", (req, res) => {
res.json(appState.currentState);
});
app.put("/updateData/:st", (req, res) => {
const { st } = req.params;
let stBool = false;
let actualValue;
if (st == "1") {
stBool = true;
actualValue=st
}
res.json("updating");
const promiseID = promiseSetTimeOut(5000);
promiseID.then(() => {
// console.log("updated ",stBool);
appState.setState(stBool);
appState.setData(actualValue);
console.log(appState);
});
});
app.listen(PORT, () => {
console.log("listening");
});
```
- Polling for limited timeout problem
[https://www.npmjs.com/package/http-delayed-response](https://www.npmjs.com/package/http-delayed-response)
[https://spin.atomicobject.com/2018/05/15/extending-heroku-timeout-node/](https://spin.atomicobject.com/2018/05/15/extending-heroku-timeout-node/)
- Deta
[https://deta.space/docs/en/quickstart-guides/node](https://deta.space/docs/en/quickstart-guides/node)
https://deta.space/docs/en/build/quick-starts/node
https://deta.space/builder : to go to builder page
**Uninstalling deta**:
It makes a hidden directory named as ".detaspace" in home directory just delete it .
to open setting: [https://deta.space/?tty_open=settings](https://deta.space/?tty_open=settings)
- Installing from github instead of npm library
`"ytdl-core": "git+https://github.com/khlevon/node-ytdl-core.git#v4.11.4-patch.2”`
`npm -i [https://github.com/khlevon/node-ytdl-core#v4.11.4-patch.2](https://github.com/khlevon/node-ytdl-core#v4.11.4-patch.2) —no-audit`
- Socket
backend
```jsx
const WebSocket = require("ws");
// creating a websocket connection at port 8080
const server = new WebSocket.Server({ port: 8080 });
// this callback function will respond once client connect to ws://localhost:8080
server.on("connection", (socket) => {
console.log("connected");
// this one respond once client send back a message here
socket.on("message", (message, isString) => {
// by default message is in buffer si convert it to string
let msg = isString ? message : message.toString();
console.log("message: ", msg);
// sending back the same message which was sent here by client
socket.send(msg);
});
});
```
frontend
```jsx
// ws protocol is used instead of http
const socket = new WebSocket("ws://localhost:8080");
// this callback function will respond once server send back a message here
socket.onmessage = (e) => {
console.log("Message: ", e.data);
};
document.querySelector("button").onclick = () => {
// send method to send the message to server
socket.send("helo");
};
```
- socket.io
high level library which uses ws to provide support for multiple clients and broadcasting
backend
```jsx
const PORT = process.env.PORT || 8080;
const httpServer = require("http").createServer();
const socketIO = require("socket.io");
// linking with httpserver
const io = socketIO(httpServer, {
cors: { origin: "*" },
});
// when client connects to the server
io.on("connection", (socket) => {
console.log(`user connected ${socket.id}`);
// when listening to custom event named 'message'
socket.on("message", (message) => {
// here using socket.boradcast.emit will send message to all client except the one who originally sent to server
socket.broadcast.emit(
"message",
`${socket.id.substr(0, 2)} said ${message}`
);
// to send to all including OP, use io.emit
// and for particular client use
// io.to(socket.id). emit("event", data);
});
});
httpServer.listen(PORT, () => {
console.log("listening");
});
```
frontend
```jsx
const socket = io("ws://localhost:8080");
const list = document.querySelector("#msgList");
const inputEle = document.querySelector("#chatInput");
// when listening to custom event named 'message'
socket.on("message", (msg) => {
const li = document.createElement("li");
li.innerText = msg;
list.appendChild(li);
});
document.querySelector("#sendBtn").onclick = () => {
const text = inputEle.value;
// emitting custom event named 'message' and passing the paramter $text
socket.emit("message", text);
const li = document.createElement("li");
li.innerText = `you said ${text}`;
list.appendChild(li);
inputEle.value = "";
};
```
- AES file encryption
[https://github.com/AKASHAorg/easy-web-crypto](https://github.com/AKASHAorg/easy-web-crypto)
```jsx
function processFile(evt) {
var file = evt.target.files[0],
reader = new FileReader();
reader.onload = function(e) {
var data = e.target.result,
iv = crypto.getRandomValues(new Uint8Array(16));
crypto.subtle.generateKey({ 'name': 'AES-CBC', 'length': 256 }, false, ['encrypt', 'decrypt'])
.then(key => crypto.subtle.encrypt({ 'name': 'AES-CBC', iv }, key, data) )
.then(encrypted => {
console.log(encrypted);
alert('The encrypted data is ' + encrypted.byteLength + ' bytes long'); // encrypted is an ArrayBuffer
})
.catch(console.error);
}
reader.readAsArrayBuffer(file);
```
``
- more
[https://stackoverflow.com/questions/60520526/aes-encryption-and-decryption-of-files-using-crypto-js](https://stackoverflow.com/questions/60520526/aes-encryption-and-decryption-of-files-using-crypto-js)
Slicing files to chunks
[https://stackoverflow.com/questions/29731329/cryptojs-sha256-large-file-progressive-checksum/62824083#62824083](https://stackoverflow.com/questions/29731329/cryptojs-sha256-large-file-progressive-checksum/62824083#62824083)
```jsx
function encrypt(input) {
var file = input.files[0];
var reader = new FileReader();
reader.onload = () => {
var key = "1234567887654321";
var wordArray = CryptoJS.lib.WordArray.create(reader.result); // Convert: ArrayBuffer -> WordArray
var encrypted = CryptoJS.AES.encrypt(wordArray, key).toString(); // Encryption: I: WordArray -> O: -> Base64 encoded string (OpenSSL-format)
var fileEnc = new Blob([encrypted]); // Create blob from string
var a = document.createElement("a");
var url = window.URL.createObjectURL(fileEnc);
var filename = file.name + ".enc";
a.href = url;
a.download = filename;
a.click();
window.URL.revokeObjectURL(url);
};
reader.readAsArrayBuffer(file);
}
function convertWordArrayToUint8Array(wordArray) {
var arrayOfWords = wordArray.hasOwnProperty("words") ? wordArray.words : [];
var length = wordArray.hasOwnProperty("sigBytes") ? wordArray.sigBytes : arrayOfWords.length * 4;
var uInt8Array = new Uint8Array(length), index=0, word, i;
for (i=0; i> 24;
uInt8Array[index++] = (word >> 16) & 0xff;
uInt8Array[index++] = (word >> 8) & 0xff;
uInt8Array[index++] = word & 0xff;
}
return uInt8Array;
}
function decrypt(input) {
var file = input.files[0];
var reader = new FileReader();
reader.onload = () => {
var key = "1234567887654321";
var decrypted = CryptoJS.AES.decrypt(reader.result, key); // Decryption: I: Base64 encoded string (OpenSSL-format) -> O: WordArray
var typedArray = convertWordArrayToUint8Array(decrypted); // Convert: WordArray -> typed array
var fileDec = new Blob([typedArray]); // Create blob from typed array
var a = document.createElement("a");
var url = window.URL.createObjectURL(fileDec);
var filename = file.name.substr(0, file.name.length - 4) + ".dec";
a.href = url;
a.download = filename;
a.click();
window.URL.revokeObjectURL(url);
};
reader.readAsText(file);
}
```
Slicing
```jsx
import CryptoJS from 'crypto-js';
class ChecksumService {
async sha256(file: File): Promise {
let sha256 = CryptoJS.algo.SHA256.create();
const sliceSize = 10_485_760; // 10 MiB
let start = 0;
while (start < file.size) {
const slice: Uint8Array = await this.readSlice(file, start, sliceSize);
const wordArray = CryptoJS.lib.WordArray.create(slice);
sha256 = sha256.update(wordArray);
start += sliceSize;
}
sha256.finalize();
return sha256._hash.toString();
}
private async readSlice(file: File, start: number, size: number): Promise {
return new Promise((resolve, reject) => {
const fileReader = new FileReader();
const slice = file.slice(start, start + size);
fileReader.onload = () => resolve(new Uint8Array(fileReader.result as any));
fileReader.onerror = reject;
fileReader.readAsArrayBuffer(slice);
});
}
}
```
- Tauri
[Download first_tauri.zip-423.8 MB](https://www.mediafire.com/file/m2jld5bq1adnxil/first_tauri.zip/file)
[Download linux_tauri.zip-574.9 MB](https://www.mediafire.com/file/q16pyty2nqkb9do/linux_tauri.zip/file)