# Javascript

## Limitations

* The "os" module (files, setTimeout, etc.) support is not available yet.
* We support ES6 modules but use rollup to bundle dependencies in a single file.
* The use of sub-directories is not available yet.
* Node libraries are not available (alternative libraries with no Node dependencies should be used instead).
* Currently, only calling synchronous functions is permitted within the context of the [fs module](https://nodejs.org/api/fs.html).

## Task Preparation

### Source Code Structure

In order to compile your source code, make sure you have the following file structure within the `❮sourceCodePath❯` folder that will be built.

📁 src \
└─ 📄 main.js\
&#x20;📁 dist\
└─ 📄 main.js\
📄 package-lock.json\
📄 package.json

{% hint style="info" %}
The ***dist*** folder and the ***main.js*** file are going to be generated after running the `npx rollup -c` command.&#x20;
{% endhint %}

### Setup Rollup

We need to roll up your JS code with all required dependencies into a single file to be able to execute it. Please follow the following steps to merge all the files into a single one.&#x20;

1. Install the Rollup Tool with the following command

```bash
npm i rollup
npm i
```

2. Once the task is developed and working correctly, use the following command to bundle dependencies in a single file. After running this command you will get the following file *dist/main.js*

<pre class="language-bash"><code class="lang-bash"><strong>npx rollup -c
</strong></code></pre>

3. The rollup command generates a single JS file that includes your code and all its dependencies. Now you can test your task in Truebit (run the 'Build' and 'Start' commands in the command-line interface)
4. As you continue your development, you might need to update multiple times your [rollup config file](#rollup-config-file) to keep testing

{% hint style="danger" %}
If you encounter dependency issues, please ensure you are not relying on native Node.js libraries. If you are, try to find an alternative library to resolve the problem.
{% endhint %}

#### Rollup Config File

The `rollup.config.mjs` file is where you provide instructions to Rollup on how to bundle your JavaScript code, making it a fundamental part of the Rollup setup.

{% hint style="info" %}
For more information, visit the [rollup official website](https://rollupjs.org/)
{% endhint %}

<details>

<summary>Rollup config example</summary>

{% code overflow="wrap" %}

```javascript
import nodeResolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';

export default [
  {
    input: 'src/main.js',
    output: {
      file: 'dist/main.js',
      format: 'es',
      name: 'fibonacci',
    },
    plugins: [nodeResolve(), commonjs()],
  },
];
```

{% endcode %}

</details>

#### Variables

* **Input:** Set up the file that Rollup will use as the starting point for bundling everything together&#x20;
* **Output:** Define how the output file will be generated. &#x20;
  * **file:** Output rollup file
  * **format:** Specifies the format of the generated bundle. [Available format](https://rollupjs.org/configuration-options/#output-format)
  * **name:** This is the name of the bundle
* **plugins:** Set up the  Rollup plugins that perform additional tasks during bundling. This could include things like converting code, making it smaller, or dealing with outside modules.
* **Optional sections:** You can add additional sections to configure specific aspects of your project, such as module resolution or custom settings.

### Built-in Libraries

#### Crypto Libraries

Truebit provides built-in Cryptographic library functions within our interpreter to make it easier to use and to boost execution speeds. At the moment, we support Bun.js and Deno.

#### Comparison

<table><thead><tr><th width="110">Library</th><th width="164">API</th><th width="205">Performance</th><th>Adoption</th></tr></thead><tbody><tr><td><a href="../function-task-examples/encrypt-sha256-using-bun.js">Bun.js</a></td><td><strong>Older</strong>. It's Node.js Propietary</td><td><strong>Slower</strong>. It's implemented in JS</td><td><strong>Widely adopted</strong>. The API is easy to understand for the large community of Node.js developers.</td></tr><tr><td><a href="../function-task-examples/encrypt-sha256-using-deno">Deno</a></td><td><strong>Newer</strong>. WebCrypto is a web standard</td><td><strong>Faster</strong>. It's implemented in Rust, then compiled as WebAssembly code.</td><td><strong>Limited adopted.</strong> The API is familiar to web developers and those using Deno (the next generation of Node.js).</td></tr></tbody></table>

#### Performance

When running the examples below, Deno's compiled WebAssembly performs much better than Bun.js, surpassing it by a huge margin.

#### Bun.js

To use Bun.js, import the library into the function task using the following ES6 module syntax

{% code overflow="wrap" %}

```javascript
import crypto from 'crypto';
```

{% endcode %}

#### Example using Bun.js  (Node.js crypto API):

{% code overflow="wrap" lineNumbers="true" %}

```javascript
import crypto from 'crypto';

function main() {
    const message = 'truebit'.repeat(5000);
    
    let i = 100;
    while (i--) {
    	const hash = crypto.createHash('sha256');
    	const result = hash.update(message).digest('hex');
        console.log(result);
    }
}

main();
```

{% endcode %}

{% hint style="info" %}
Click [Here](https://nodejs.org/api/crypto.html) to check the node.js crypto API documentation
{% endhint %}

#### Deno

To use Deno, import the library into the function task using the following ES6 module syntax

```javascript
import crypto from 'webcrypto';
```

#### Example Using  Deno (WebCrypto API):

{% code overflow="wrap" lineNumbers="true" %}

```javascript
import crypto from 'webcrypto';
import TextEncoder from 'encoding';

function buf2hex(buffer) {
return [...new Uint8Array(buffer)]
    .map(x => x.toString(16).padStart(2, '0'))
    .join('');
}

async function main() {
    const message = 'truebit'.repeat(5000);
    const encoder = new TextEncoder('ascii');
    const data = encoder.encode(message).buffer;
    let i = 100;
    while (i--) {
        const hash = await crypto.subtle.digest('sha-256', data);
        const result = buf2hex(hash);
        console.log(result);
    }
}
main();
```

{% endcode %}

{% hint style="info" %}
Click [Here](https://www.w3.org/TR/WebCryptoAPI/) to check the WebCrypto API documentation
{% endhint %}
