# Overview

JSRE is part of EdgerOS (an Edge Computing Operating System based on SylixOS kernel) that provides a powerful JavaScript runtime environment.

# Why JavaScript

There are two famous sayings in the JavaScript world:

  • Any application that can be written in JavaScript, will eventually be written in JavaScript.
  • When you understand the JavaScript design philosophy, you will find other languages too clumsy.

JavaScript is lightweight, easy to learn, and has a high degree of Internet affinity. It is the best choice for Internet edge computing.

This manual only contains JSRE modules and program development guide. For JavaScript language related tutorials, please refer to:

JSRE has made significant improvements to the JavaScript language style, enabling the JavaScript language to support Synchronous Multitasking mode. Of course, JSRE also retains JavaScript Asynchronous features, so developing applications based on JSRE is very flexible.

JSRE allows each task in applications using an Infinite Loop. Just like other synchronous multitasking languages:

while (true) {
	console.log('Hello World!');
	sys.sleep(1000); // Sleep 1000 milliseconds.
}

you can use any mechanism you like (synchronous or asynchronous) develop applications. When you develop applications using traditional asynchronous mechanism, each task needs to add the following code at the end of the code for event scheduling:

setInterval(function() {
	console.log('Hello World!');
}, 1000);

// Event loop.
while (true) {
	iosched.poll();
}

Or:

setInterval(function() {
	console.log('Hello World!');
}, 1000);

// Event loop (never quit except an uncaught error occurs).
iosched.forever();

Since JSRE provides an infinite loop for each task, so JSRE supports the interrupt mechanism. There are some types of JSRE interrupts: SigSlot (A multi-tasking subscription and publishing message mechanism), Promise, Task.nextTick() and Timer.

JSRE supports setting the interrupt response mode to control when the interrupt is responded, the setting function is interrupt.level(option) valid options include:

Definition Description
interrupt.ANYTIME Responds interrupt at any time. Only for Privileged Mode applications.
interrupt.ONPEND Responds interrupt when program is blocked, such as blocking at network receive and send function call.
interrupt.ONRPEND Responds interrupt only when system has a read/receive blocking. This is default setting.
interrupt.ONPOLL Responds interrupt when sys.sleep(), sys.select() or iosched.poll() function blocked.

If there is a program fragment in the application that you don't want to be interrupted, you can use the following method:

unbreakable(() => {
	// Here will not be break by interrupts.
});

JSRE provides a standard multitasking environment where users can create many tasks to handle different things. Multitasking environment can improve the processing parallel. If in SMP (Symmetric Multi Processor) environment, the operating system will schedule different task on different CPU, achieve true Parallel Execution.

Of course, JSRE also provides efficient inter-task synchronization, mutual exclusion and communication mechanisms, including Semaphore, Mutex, Message, Shared memory, Signal and Slot.

If there is a program fragment in the application that you don't want to be preempted by multitasking, the easiest way to do this is to use:

synchronize(() => {
	// This code is mutually exclusive.
});

NOTICE: You must use the Arrow Function callback function to keep this correct.

Multi task creation and exit will be introduced in later chapters.

# ECMAScript

In order to run more programs simultaneously in a resource-constrained embedded environment, JSRE uses a low memory consumption JavaScript engine as its core. The JSRE engine core uses bytecode running techniques, first compile JavaScript application into bytecode and then run it using a dedicated bytecode virtual machine.

JSRE currently supports all ECMAScript 6 standards, and it also supports some newer ECMAScript 7, ECMAScript 8 standards. Such as:

  • let & const
  • Class
  • ArrayBuffer
  • TypedArray
  • DataView
  • Iterator
  • Promise
  • Proxy
  • Symbol
  • Reflect
  • Map & WeakMap
  • Set & WeakSet
  • Arrow function
  • Async function
  • Generator function
  • Rest arguments
  • Default arguments
  • Template string
  • BigInt
  • import & export
  • ...

# TypeScript

TypeScript is an open-source language which builds on JavaScript, one of the world’s most used tools, by adding static type definitions. Types provide a way to describe the shape of an object, providing better documentation, and allowing TypeScript to validate that your code is working correctly. Writing types can be optional in TypeScript, because type inference allows you to get a lot of power without writing additional code.

JSRE and EdgerOS provide complete type declaration files, and developer can import related modules to develop apps using TypeScript. Please check for details (opens new window)

import * as fs from 'fs';

const path: string = './data.txt';

fs.writeFile(path, 'Hello TypeScript on EdgerOS!');

If you are familiar with TypeScript, it is recommended to use TypeScript, which can reduce development errors and use the newest ECMAScript standard.

# Modules

JSRE provides a lot of modules providers for application use. It's include:

# General

  • assert Assertion testing.
  • buffer Binary data buffer.
  • console Standard output.
  • chksum Checksum calculation tools.
  • crypto Crypto library.
  • events Event emitter.
  • iosched I/O event scheduler.
  • module Module manager.
  • path Path tools.
  • timer Timer.
  • stream Abstract interface for streaming data.
  • stringdecoder buffer to string decoding.
  • sys System status and setting.
  • error Error management.
  • bytecode Bytecode compiler.
  • url URL parser.
  • util Utility tools.
  • rbtree Red Black tree.
  • yallist Yet another linked list.
  • lru-cache Least-Recently-Used cache manager.

# Local Device

  • buzzer Buzzer device.
  • canbus CAN-Bus device.
  • gpio General purpose I/O.
  • tty TTY device such as UART.
  • thermal CPU temperature detection.
  • hotplug Hotplug event management.

# Network

  • dns DNS lookup.
  • inetaddr Internet address operating.
  • netif Network interface management.
  • socket Standard socket operation functions.
  • tcp TCP communication.
  • udp UDP communication with multicast support.
  • tls TLS / SSL communication.
  • dtls Datagram TLS communication.
  • net Network client and server based on stream.
  • dgram UDP network module.
  • querystring Parsing and formatting URL query strings.
  • http HTTP server, client, proxy and utility.
  • websocket Websocket server and client.
  • webproxy Web proxy server.
  • webget Download files using the http protocol.
  • mobile Mobile network support.

# IoT Protocol

  • mqtt Mqtt subscribe and publish protocol client.
  • coap Constrained Application Protocol.
  • sddc Smart Device Discovery & Control protocol.
  • miio Mi home devices protocol.

# File System

  • fs File system.
  • fsstream Steam file system.
  • ini INI parser.
  • html HTML parser.
  • zip ZIP package management.

# Database

  • synctable Multi-Task Key/Value in memory table.
  • ndbm UNIX Key/Value database.
  • lightkv Light transaction Key/Value database.
  • leveldb LevelDB Key/Value database.
  • sqlite3 SQLite3 SQL database.
  • redis Redis database client.

# Multi-Task

  • task Multi-Task management.
  • sigslot Signal-Slot subscribe and publish communications.
  • mutex Mutex.
  • rms Rate monotonic scheduling.
  • lpc Local procedure call.
  • semaphore Semaphore.
  • shared Shared memory.

# Multi-Process

  • process Multi-Process management.
  • message Message communication.
  • monitor Resource usage monitoring
  • pipe Pipe communication.
  • rpc Remote Procedure Call.
  • gss Global Signal-Slot service.

# Router

  • ifevent Network interface event.
  • ppp Point to point networking.
  • qos Network Quality of Service management.
  • bridge Network bridge.
  • flowctl Network flow control.
  • natctl NAT network management.
  • npfctl Network packets filter.
  • rttable Routing table management.
  • rtutil Other routing tools.
  • vlan Virtual Local Area Network management.
  • arp ARP table management.

# App Framework

  • webapp RESTfull Application framework.
  • webmedia Web multi-media server framework.
  • middleware Web Application middleware.
  • ejs EJS render engine.
  • jwt JSON Web Token.
  • socket.io Event-based communication: Ajax, jsonp, websocket all in one.

# Quick start

If you are using EdgerOS, please consult the EdgerOS related documentation and ignore this section.

You can install JSRE on the SylixOS using the automated deployment tools provided by ACOINFO. The JSRE default environment includes:

# /bin/javascript

JSRE main program. You can use this program to run a js program:

  • hello.js
console.log('Hello JSRE!');
  • Shell command:
$ javascript hello.js

# /sbin/gssd

JSRE Global (Multi-Process) Signal Slot deamon. If you want to enable this feature, you need to run this program (background execution is recommended):

$ gssd &

# /lib/jsre/lib*.so

There are a lot of JSRE runtime shared libraries installed here.

The /bin/javascript program automatically loads these libraries when it run, so you need to check to see if LD_LIBRARY_PATH environmental variable contains the /lib/jsre directory, if not added using the following method:

$ LD_LIBRARY_PATH=/lib/jsre:$LD_LIBRARY_PATH
$ echo $LD_LIBRARY_PATH
$ varsave

# /lib/jsre/quota.json

JSRE quota management file, if no other management file is specified, this file is used by default when starting an application.

JSRE provides resource quota management support for each application, such as maximum number of tasks, built-in library support, default garbage collection strategy, etc.

JSRE does not recommend users to modify the default quota file. If some applications require different configurations, you can specify different quota files by parameter when starting the /bin/javascript program.

# /lib/jsre/js/*.js

JSRE built-in module export file, the application can use the require() method to import these modules into the application. for example:

var Gpio = require('gpio');
var Tcp = require('tcp');

The JSRE module import path rules will be introduced in later chapters.

# /lib/jsre/ext

JSRE allows operating system publishers to use this directory to extend the JSRE built-in library. You can place the *.so directory in this directory and install the necessary *.js files into the /lib/jsre/exe/js directory, When /bin/javascript starts, it will automatically scan these modules and perform the necessary pre-processing operations.

# Entry program

/bin/javascript is the runtime entry for JSRE, which users can use to load and run js programs.

$ javascript -h
USAGE: javascript [options] *.js
Run '*.js' file.

-v          : Show JSRE version.
-h          : Show this message.
-u          : User permission. (default is 'Privilege' permission)
-b          : Block sending data by network at 'User' permission.
-r          : Allows RTSP streaming media protocol at 'User' permission.
-c          : Allows CoAP IoT protocol at 'User' permission.
-n          : AI Neural Network Computing support at 'User' permission.
-j          : JavaScript argument is json
-g mode     : Global Signal Slot mode. (0: off(default) 1: listener 2: publisher)
-z zone     : Global Signal Slot zone. (zone identifier)
-s service  : Service name.
-i priority : JSRE priority. (default is 'normal')
-a jsarg    : JavaScript argument. (default is "")
-d appid    : Set the current process application identifier. (Only EdgerOS use this option)
-p eapid    : Set the current application package identifier. (bundle ID)
-m mode     : MQTT mode at 'User' permission. (0: off(default) 1: listener 2: publisher)
-x num      : Log level. (0: error(default), 1: warning, 2: debug, 3: trace)
-w path     : Working directory. (default is current)
-e path     : Auxiliary storage path.
-o file     : Standard file. (default is current)
-q file     : Quota file.
Parameter Description
-v Show JSRE version.
-h Show help message.
-u Specify to use User permission. default is Privilege.
-b Block sending data by network at 'User' permission. default allow network sending in User mode
-r Allows RTSP streaming media protocol at 'User' permission.
-c Allows CoAP IoT protocol at 'User' permission.
-n AI Neural Network Computing support at 'User' permission.
-j If a parameter exists, specifies that the parameter is a JSON object.
-g mode Global Signal Slot mode. (0: off(default) 1: listener 2: publisher)
-z zone Global Signal Slot zone. Processes with the same zone identifier can communicate use GSS.
-s service Run as a Service, Will not use the process number as the process communication message name, but use the given parameter as the message name. *see the message module for details.
-i priority JSRE priority. default is 'normal'
-a jsarg Main task parameters, js main task can get this parameter through ARGUMENT variable. default:''.
-d appid Only used in EdgerOS environment.
-p eapid Only used in EdgerOS environment.
-m mode MQTT mode at 'User' permission. (0: off(default) 1: listener 2: publisher)
-x num Log level. (0: error(default), 1: warning, 2: debug, 3: trace)
-w path js program working directory. (default is current)
-e path Auxiliary storage path.
-o file Standard out file. default is to inherit the current process related files.
-q file Quota file. Specify quota file, default is JSRE environment quota file.

# First program

Create a hello.js file. If it is not the root user, enable this file to execute permissions.

$ touch hello.js
$ chmod 777 hello.js

The content of the hello.js file can be:

console.log('Hello World!');

Can be run as follows:

$ javascript hello.js
[JSRE-USR]Hello World!
[JSRE-SYS]Exit code: 0

You can also add the following statement in the first line of hello.js

#!/bin/javascript

console.log('Hello World!');

Can be run as follows:

$ ./hello.js
[JSRE-USR]Hello World!
[JSRE-SYS]Exit code: 0

# Simple Multi-Task

Use the above method to create two files, main.js and task.js. The contents of these two files are as follows:

  • main.js
#!/bin/javascript

console.inspectEnable = true;

var task = new Task('./task.js');
var msg  = { a: 3, b: 5 };

console.log('new task id:', task.id());

while (true) {
	task.send(msg);
	sys.sleep(1000);
}
  • task.js
console.inspectEnable = true;

console.log('new task run!, id:', Task.me());

Task.on('message', function(msg, from) {
	console.log('recv:', msg, 'from:', from);
});

require('iosched').forever();

Can be run as follows:

$ ./main.js
[JSRE-USR]new task id: 67174472
[JSRE-USR]new task run!, id: 67174472
[JSRE-USR]recv: {a:3,b:5} from: {id:67174470}
[JSRE-USR]recv: {a:3,b:5} from: {id:67174470}
[JSRE-USR]recv: {a:3,b:5} from: {id:67174470}
...

NOTICE: When the main task exits, the process stops immediately and other tasks are automatically deleted.

Here is just an example. For details, please refer to the Task module chapter.

# Signal Slot

Signal Slot uses asynchronous and multi-tasking multi-process communication mode, which is simple and flexible to use. Here is just an example. For details, please refer to the Signal Slot module chapter.

Replace the above main.js with task.js with the program given below:

  • main.js
#!/bin/javascript

console.inspectEnable = true;

var SigSlot = require('sigslot');

var sigslot = new SigSlot('Test');
var task = new Task('./task.js');
var msg = { a: 3, b: 5 };

// Subscribe
sigslot.slot('event1', (msg) => {
	console.log('main event1 arrived:', msg);
});

while (true) {
	// Publish
	sigslot.emit('event1', msg);
	sys.sleep(1000);
}
  • task.js
console.inspectEnable = true;

var SigSlot = require('sigslot');

var sigslot = new SigSlot('Test');

// Subscribe
sigslot.slot('event1', (msg) => {
	console.log('task event1 arrived:', msg);
});

while (true) {
	// Nothing to do, relax CPU.
	sys.sleep(1000);
}

Can be run as follows:

$ ./main.js
[JSRE-USR]main event1 arrived: {a:3,b:5}
[JSRE-USR]task event1 arrived: {a:3,b:5}
[JSRE-USR]main event1 arrived: {a:3,b:5}
[JSRE-USR]task event1 arrived: {a:3,b:5}
...

For more detail, please refer to the relevant module documentation.