smile-js
Javascript Smile implementation.
Overview
This project is an implementation of Jackson's Smile format. The library supports encoding and decoding.
Documentation
Command-line tools
smile-cli
smile-cli # installed globally
node_modules/smile-js/bin/smile-cli # [npm] installed locally
pnpm exec smile-cli # [pnpm] installed locally
Usage: smile-cli [options] [command]
SMILE CLI
Options:
-V, --version output the version number
-h, --help display help for command
Commands:
encode [options] [jsonFile] [smileFile] Encode JSON to SMILE
decode [options] [smileFile] [jsonFile] Decode SMILE to JSON
help [command] display help for command
HTML Script Tag
To use smile-js via the HTML script tag:
<script src="https://cdn.jsdelivr.net/npm/smile-js@0.10.1/dist/smile-js.iife.js"></script>
The module will be exported as windows.smile
.
Example
<!DOCTYPE html>
<html lang="en-US">
<head>
<title>smile-js test</title>
<script src="https://cdn.jsdelivr.net/npm/smile-js@0.10.1/dist/smile-js.iife.js"></script>
<script>
function onChooseFile(e) {
const file = e.target.files.item(0)
file.arrayBuffer()
.then(arrayBuffer => {
const data = new Uint8Array(arrayBuffer);
try {
const o = window.smile.decode(data);
console.log(o);
document.getElementById("output").innerText = JSON.stringify(o, null, 2);
} catch (e) {
alert(e);
}
})
.catch(e => {
alert(e);
});
}
</script>
</head>
<body>
<div>
<label for="file">Select SMILE-encoded file</label>
<input id="file" type="file" onchange="onChooseFile(event)"/>
</div>
<div>
<label for="output">JSON representation:</label>
<pre id="output"></pre>
</div>
</body>
</html>
Svelte example
App.svelte
<script lang="ts">
import {decode, encode} from 'smile-js';
import {isInteger, parse, stringify} from 'lossless-json';
import {Base64} from 'js-base64';
let decodedJson: string = '';
let inputJson: string = '';
function onChooseEncodedFile(e: Event) {
const target = e.target as HTMLInputElement;
if (!target.files || (target.files.length < 1)) {
return;
}
const file = target.files.item(0)
if (!file) {
return;
}
file.arrayBuffer()
.then(arrayBuffer => {
const data = new Uint8Array(arrayBuffer);
try {
const o = decode(data);
console.log(o);
const json = stringify(o, null, ' ');
if (json !== undefined) {
decodedJson = json;
} else {
alert('could not JSON stringify object')
}
} catch (e) {
alert(e);
}
})
.catch(e => {
alert(e);
});
}
function onClickEncode(e: Event) {
try {
const o = parse(inputJson, null, parseNumber);
console.log('input', o);
const encodedData = encode(o);
download('encoded.smile', 'application/x-jackson-smile', encodedData);
} catch (e) {
alert(e);
}
}
function download(filename: string, contentType: string, data: Uint8Array) {
const element = document.createElement('a');
element.setAttribute('href', `data:${contentType};base64,${Base64.fromUint8Array(data)}`);
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
function parseNumber(v: string): unknown {
if (isInteger(v)) {
const b = BigInt(v);
if ((b >= BigInt(Number.MIN_SAFE_INTEGER)) && (b <= BigInt(Number.MAX_SAFE_INTEGER))) {
return Number(b);
} else {
return b;
}
} else {
return parseFloat(v);
}
}
</script>
<h1>smile-js demo</h1>
<h2>Decode</h2>
<div>
<label for="file">Select SMILE-encoded file</label>
<input id="file" type="file" on:change={onChooseEncodedFile}/>
</div>
<div>
<label for="output">JSON representation:</label>
<pre id="output">{decodedJson}</pre>
</div>
<hr>
<h2>Encode</h2>
<button on:click={onClickEncode}>Encode</button>
<textarea class="inputJson" bind:value={inputJson}></textarea>
<style>
.inputJson {
width: 100%;
height: 20em;
}
</style>