mirror of
https://github.com/EvernodeXRPL/hpcore.git
synced 2026-04-29 15:37:59 +00:00
Introduced bson support for browser js client lib. (#308)
* Added blake3 import and safari compatibility fix. * Created browser lib with bson support. * Added 'terser' for minification. * Added TextEncoder compatiblity fix.
This commit is contained in:
16
examples/js_client/README.md
Normal file
16
examples/js_client/README.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# Hot Pocket javascript client library and examples
|
||||
|
||||
Single-file javascript library to support json and bson protocols in NodeJs and Browser environments.
|
||||
|
||||
## NodeJs
|
||||
1. Run `npm install` to install all the dependencies.
|
||||
1. `lib/hp-client-lib.js` is the Hot Pocket client library for NodeJs.
|
||||
1. `text-client.js` is the example for json mode.
|
||||
1. `file-client.js` is the example for bson mode.
|
||||
|
||||
## Browser
|
||||
1. Run `npm install` to install all the compilation dependencies.
|
||||
1. Run `npm run build-browser` to produced the minified library for the browser.
|
||||
1. `browser-example.html` is the simple html/javascript example for json mode.
|
||||
|
||||
(For BSON support in browser, a slightly modified version of https://www.npmjs.com/package/bson is used. The minified library includes this bson support library as well)
|
||||
@@ -3,19 +3,14 @@
|
||||
<head>
|
||||
<title>HotPocket browser example</title>
|
||||
|
||||
<script src="hp-client-lib.js"></script>
|
||||
<!--'npm run build-browser' to generate the browser lib.-->
|
||||
<script src="dist/hp-client-lib.min.js"></script>
|
||||
|
||||
<!--Hot Pocket client library requires libsodium js for cryptographic operations.-->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/libsodium-wrappers/0.5.4/sodium.min.js"
|
||||
integrity="sha512-oRfU7aik4u7f0dPAKgOyA4+bb/YRGfAaD5RA4Z3Mb2ycPcGDs+k8qAnDNd7ouruoqlIHSuGVaTTlEs91Gvd37A=="
|
||||
crossorigin="anonymous"></script>
|
||||
|
||||
<!--Hot Pocket client library requires blake3 for hashing operations.-->
|
||||
<script type="module">
|
||||
import init from 'https://cdn.jsdelivr.net/npm/blake3@2.1.4/browser-async.js';
|
||||
init().then(blake3 => HotPocket.setBlake3(blake3)).catch(console.error);
|
||||
</script>
|
||||
|
||||
<script>
|
||||
async function testFunc() {
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ const fs = require('fs');
|
||||
const readline = require('readline');
|
||||
const bson = require('bson');
|
||||
var path = require("path");
|
||||
const HotPocket = require('./hp-client-lib');
|
||||
const HotPocket = require('./lib/hp-client-lib');
|
||||
|
||||
async function main() {
|
||||
|
||||
|
||||
8947
examples/js_client/lib/bson-browser.js
Normal file
8947
examples/js_client/lib/bson-browser.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
* Hot Pocket javascript client library (for NodeJs and Browser)
|
||||
* NodeJs: const HotPocket = require("./hp-client-lib")
|
||||
* Browser: window.HotPocket
|
||||
*/
|
||||
|
||||
(() => {
|
||||
|
||||
// Whether we are in Browser or NodeJs.
|
||||
@@ -7,6 +13,14 @@
|
||||
if (isBrowser && window.HotPocket)
|
||||
return;
|
||||
|
||||
// Common data type initialization.
|
||||
if (!isBrowser) {
|
||||
// In browser, these are available in the global scopre. It's just in NodeJs they are in 'util' scope.
|
||||
const util = require("util");
|
||||
TextEncoder = util.TextEncoder;
|
||||
TextDecoder = util.TextDecoder;
|
||||
}
|
||||
|
||||
const supportedHpVersion = "1.0.0";
|
||||
const serverChallengeSize = 16;
|
||||
const outputValidationPassThreshold = 0.8;
|
||||
@@ -26,7 +40,7 @@
|
||||
/*--- Included in public interface. ---*/
|
||||
const protocols = {
|
||||
json: "json",
|
||||
bson: "bson" // (Requires nodejs or browserified hp client library on Browser)
|
||||
bson: "bson"
|
||||
}
|
||||
Object.freeze(protocols);
|
||||
|
||||
@@ -108,7 +122,7 @@
|
||||
await initBlake3();
|
||||
initWebSocket();
|
||||
if (opt.protocol == protocols.bson)
|
||||
initBson();
|
||||
await initBson();
|
||||
|
||||
// Load servers and serverKeys to object keys to avoid duplicates.
|
||||
|
||||
@@ -684,7 +698,7 @@
|
||||
catch (e) {
|
||||
liblog(1, e);
|
||||
liblog(0, "Exception deserializing: ");
|
||||
liblog(0, (data && (isTextMode ? data.toString() : data) || rcvd));
|
||||
liblog(0, data || rcvd);
|
||||
|
||||
// If we get invalid message during handshake, close the socket.
|
||||
if (connectionStatus < 2)
|
||||
@@ -1078,7 +1092,7 @@
|
||||
}
|
||||
else { // nodejs
|
||||
if (!sodium)
|
||||
sodium = require('libsodium-wrappers');
|
||||
sodium = require("libsodium-wrappers");
|
||||
await sodium.ready;
|
||||
}
|
||||
|
||||
@@ -1087,13 +1101,28 @@
|
||||
}
|
||||
|
||||
// Set bson reference.
|
||||
function initBson() {
|
||||
if (bson) // If already set, do nothing.
|
||||
let bsonAwaiter = null;
|
||||
async function initBson() {
|
||||
if (bson) { // If already set, do nothing.
|
||||
return;
|
||||
else if (isBrowser && window.BSON) // browser
|
||||
bson = window.BSON;
|
||||
else if (!isBrowser) // nodejs
|
||||
bson = require('bson');
|
||||
}
|
||||
else if (isBrowser) { // Browser
|
||||
if (!bsonAwaiter) {
|
||||
bsonAwaiter = new Promise(resolve => {
|
||||
// Trigger a event loop cycle to let the bson lib load.
|
||||
setTimeout(() => {
|
||||
// We assume our custom version of bson-browser.js lib is now loaded.
|
||||
bson = window.BSON;
|
||||
window.Buffer = window.BSON.BufferPolyfill; // Buffer polyfill exposed in our modified BSON lib.
|
||||
resolve();
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
await bsonAwaiter;
|
||||
}
|
||||
else if (!isBrowser) { // nodejs
|
||||
bson = require("bson");
|
||||
}
|
||||
|
||||
if (!bson)
|
||||
throw "BSON reference not found.";
|
||||
@@ -1106,15 +1135,14 @@
|
||||
else if (isBrowser && window.WebSocket) // browser
|
||||
WebSocket = window.WebSocket;
|
||||
else if (!isBrowser) // nodejs
|
||||
WebSocket = require('ws');
|
||||
WebSocket = require("ws");
|
||||
|
||||
if (!WebSocket)
|
||||
throw "WebSocket reference not found.";
|
||||
}
|
||||
|
||||
let blake3Resolver = null;
|
||||
let blake3awaiter = null;
|
||||
// Set blake3 reference.
|
||||
let blake3awaiter = null;
|
||||
async function initBlake3() {
|
||||
if (blake3) { // If already set, do nothing.
|
||||
return;
|
||||
@@ -1122,29 +1150,51 @@
|
||||
else if (isBrowser && window.blake3) {// browser (if blake3 already loaded)
|
||||
blake3 = window.blake3;
|
||||
}
|
||||
else if (isBrowser && !window.blake3) { // If blake3 not yet loaded in browser, wait for it.
|
||||
if (!blake3awaiter)
|
||||
blake3awaiter = new Promise(resolve => blake3Resolver = resolve);
|
||||
blake3 = await blake3awaiter;
|
||||
else if (isBrowser && !window.blake3) { // If blake3 not yet loaded in browser, load it.
|
||||
|
||||
if (!blake3awaiter) {
|
||||
blake3awaiter = new Promise(resolve => {
|
||||
|
||||
// The Blake3 library we are using (https://github.com/connor4312/blake3) causes issue on Mac/iOS (Safari) due
|
||||
// to Safari's lack of support for BigInt/BigUint64Array data types as of 25 Apr 2021. Here, we are adding empty
|
||||
// definitions to avoid complete initialization failure of Blake3 library on Mac/iOS.
|
||||
|
||||
if (typeof (BigUint64Array) === "undefined")
|
||||
BigUint64Array = function (v) { }
|
||||
|
||||
if (typeof (BigInt) === "undefined")
|
||||
BigInt = function (v) { }
|
||||
|
||||
// Import the blake3 browser module at runtime.
|
||||
const url = "https://cdn.jsdelivr.net/npm/blake3@2.1.4/browser-async.js";
|
||||
import(url).then(module => {
|
||||
module.default()
|
||||
.then(blake3ref => {
|
||||
blake3 = blake3ref;
|
||||
resolve();
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
resolve();
|
||||
});
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
await blake3awaiter;
|
||||
return;
|
||||
}
|
||||
else if (!isBrowser) { // nodejs
|
||||
blake3 = require('blake3');
|
||||
blake3 = require("blake3");
|
||||
}
|
||||
|
||||
if (!blake3)
|
||||
throw "Blake3 reference not found.";
|
||||
}
|
||||
|
||||
function setBlake3(blake3ref) {
|
||||
if (blake3Resolver) {
|
||||
blake3Resolver(blake3ref)
|
||||
blake3Resolver = null;
|
||||
}
|
||||
else {
|
||||
blake3 = blake3ref;
|
||||
}
|
||||
}
|
||||
|
||||
function setLogLevel(level) {
|
||||
logLevel = level;
|
||||
}
|
||||
@@ -1160,7 +1210,6 @@
|
||||
createClient,
|
||||
events,
|
||||
protocols,
|
||||
setBlake3,
|
||||
setLogLevel
|
||||
};
|
||||
}
|
||||
2465
examples/js_client/package-lock.json
generated
2465
examples/js_client/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,9 @@
|
||||
{
|
||||
"scripts": {
|
||||
"build-node": "browserify --node -p tinyify hp-client-lib.js -o dist/hp-node-client-lib.js",
|
||||
"build-browser": "browserify -p tinyify hp-client-lib.js -o dist/hp-browser-client-lib.js"
|
||||
"merge-browser": "rm -r dist ; mkdir -p dist && cp lib/bson-browser.js dist/hp-client-lib.js && cat lib/hp-client-lib.js >> dist/hp-client-lib.js",
|
||||
"minify-browser": "terser --compress --mangle reserved=['Binary','Buffer'] -- dist/hp-client-lib.js > dist/hp-client-lib.min.js && rm dist/hp-client-lib.js",
|
||||
"build-browser": "npm run merge-browser && npm run minify-browser",
|
||||
"build-nodejs": "ncc build lib/hp-client-lib.js -o dist/hp-client"
|
||||
},
|
||||
"dependencies": {
|
||||
"libsodium-wrappers": "0.7.6",
|
||||
@@ -10,9 +12,6 @@
|
||||
"bson": "4.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tinyify": "3.0.0",
|
||||
"browserify": "16.5.2",
|
||||
"utf-8-validate": "5.0.2",
|
||||
"bufferutil": "4.0.1"
|
||||
"terser": "5.7.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const readline = require('readline');
|
||||
const HotPocket = require('./hp-client-lib');
|
||||
const HotPocket = require('./lib/hp-client-lib');
|
||||
|
||||
async function main() {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user