Skip to content

Commit

Permalink
Feat/js reed solomon (#422)
Browse files Browse the repository at this point in the history
* feat: Js implement reed solomon

* docs: Update README

* docs: Update README

* Create beige-beds-lay.md

* feat: Empty buffer

* chore: Update params

* feat: Nodejs support worker

* feat: Nodejs support worker

* feat: Add types

* chore: Update Nodejs example

* chore: Update docs and example
  • Loading branch information
rrr523 authored Dec 18, 2023
1 parent a940e06 commit 18891a4
Show file tree
Hide file tree
Showing 19 changed files with 5,689 additions and 279 deletions.
5 changes: 5 additions & 0 deletions .changeset/beige-beds-lay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@bnb-chain/reed-solomon": patch
---

js reed solomon
5 changes: 5 additions & 0 deletions .changeset/gold-tigers-taste.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@bnb-chain/reed-solomon': patch
---

feat: Add types
5 changes: 5 additions & 0 deletions .changeset/happy-ears-tap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@bnb-chain/reed-solomon': patch
---

feat: Nodejs Support Worker
9 changes: 5 additions & 4 deletions examples/nodejs/cases/storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const fs = require('fs');
const path = require('path');
const mimeTypes = require('mime-types');
const { getCheckSums } = require('@bnb-chain/greenfiled-file-handle');
const { NodeAdapterReedSolomon } = require('@bnb-chain/reed-solomon/node.adapter');
const { client, selectSp, generateString } = require('../client');
const { ACCOUNT_ADDRESS, ACCOUNT_PRIVATEKEY } = require('../env');

Expand All @@ -12,6 +13,7 @@ const objectName = generateString(10);
const fileBuffer = fs.readFileSync(filePath);
const extname = path.extname(filePath);
const fileType = mimeTypes.lookup(extname);
const rs = new NodeAdapterReedSolomon();

console.log('bucketName', bucketName);
console.log('objectName', objectName);
Expand Down Expand Up @@ -58,8 +60,7 @@ console.log('objectName', objectName);
console.log('create bucket success', createBucketTxRes);

// create object example:
const hashResult = await getCheckSums(fileBuffer);
const { contentLength, expectCheckSums } = hashResult;
const expectCheckSums = await rs.encodeInWorker(__filename, Uint8Array.from(fileBuffer));

const createObjectTx = await client.object.createObject(
{
Expand All @@ -69,8 +70,8 @@ console.log('objectName', objectName);
visibility: 'VISIBILITY_TYPE_PRIVATE',
fileType: fileType,
redundancyType: 'REDUNDANCY_EC_TYPE',
contentLength,
expectCheckSums: JSON.parse(expectCheckSums),
contentLength: fileBuffer.length,
expectCheckSums,
tags: {
tags: [],
},
Expand Down
1 change: 1 addition & 0 deletions examples/nodejs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"dependencies": {
"@bnb-chain/greenfield-js-sdk": "workspace:*",
"@bnb-chain/greenfiled-file-handle": "workspace:*",
"@bnb-chain/reed-solomon": "workspace:*",
"dotenv": "^16.0.3",
"mime-types": "^2.1.35"
}
Expand Down
66 changes: 66 additions & 0 deletions packages/reed-solomon/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Reed Solomon

Lighting implementation for [klauspost/reedsolomon](https://github.com/klauspost/reedsolomon).

Compatible with [greenfield-common](https://github.com/bnb-chain/greenfield-common/blob/master/go/hash/hash.go).

## Install

```bash
> npm install @bnb-chain/reed-solomon
```

## Usage Examples

### Browser

Use directly in the browser via script tag:

```html
<input type="file" id="file" />
<button id="btn">
get reed solomon
</button>

<script src="https://cdn.jsdelivr.net/npm/@bnb-chain/reed-solomon/index.aio.js"></script>
<script>
const fileInput = document.getElementById('file');
document.getElementById('btn').onclick = async function() {
const selectFile = fileInput.files[0];
const arrBuffer = await selectFile.arrayBuffer()
if (!arrBuffer) alert('no file selected');
const rs = new RS.ReedSolomon();
const res = rs.encode(new Uint8Array(arrBuffer))
}
</script>
```

### ESM

If you use module bundler such as [Webpack](https://webpack.js.org/), [Rollup](https://rollupjs.org/guide/en/), etc:

```js
import {ReedSolomon} from '@bnb-chain/reed-solomon'

const rs = new RS.ReedSolomon();
const res = rs.encode(new Uint8Array(fileBuffer))
```

### Nodejs

Using in Nodejs:

```js
const { NodeAdapterReedSolomon } = require('@bnb-chain/reed-solomon/node.adapter');

const fileBuffer = fs.readFileSync('./output_file');

const rs = new NodeAdapterReedSolomon();
const res = await rs.encodeInWorker(__filename, Uint8Array.from(fileBuffer))
```

* [calcute single file](./examples/singlefile.js)
* [calcute several file in a folder](./examples/folder.js)
30 changes: 30 additions & 0 deletions packages/reed-solomon/examples/folder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* eslint-disable */
const fs = require('node:fs/promises');
const path = require('node:path');
const { NodeAdapterReedSolomon } = require('../dist/node.adapter');

const rs = new NodeAdapterReedSolomon();
const folderPath = './dist';

(async () => {
async function traverse(currentPath) {
const start = Date.now();
const files = await fs.readdir(currentPath);

for (let i = 0; i < files.length; i++) {
const file = files[i];
const filePath = path.join(currentPath, file);
const stat = await fs.stat(filePath);

const start = Date.now();
const fileBuffer = await fs.readFile(filePath);
const res = await rs.encodeInWorker(__filename, Uint8Array.from(fileBuffer));
console.log('res', file, Date.now() - start, res);
}

console.log('files count: ', files.length);
console.log('total cost time: ', Date.now() - start);
}

await traverse(folderPath);
})();
16 changes: 16 additions & 0 deletions packages/reed-solomon/examples/singlefile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* eslint-disable */
const fs = require('node:fs');
const path = require('node:path');
const { NodeAdapterReedSolomon } = require('../dist/node.adapter');

const fileBuffer = fs.readFileSync('./README.md');

const rs = new NodeAdapterReedSolomon();

// single file
(async () => {
const start = Date.now();
const res = await rs.encodeInWorker(__filename, Uint8Array.from(fileBuffer));
console.log('res', res);
console.log('cost time', Date.now() - start);
})();
57 changes: 57 additions & 0 deletions packages/reed-solomon/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"name": "@bnb-chain/reed-solomon",
"version": "1.0.0",
"description": "lighting implement for reed solomon",
"module": "./dist/index.esm.js",
"main": "./dist/index.js",
"types": "./types/index.d.ts",
"exports": {
".": {
"import": "./dist/index.aio.js",
"require": "./dist/index.js",
"main": "./dist/index.js",
"default": "./dist/index.js",
"types": "./types/index.d.ts"
},
"./node.adapter": {
"default": "./dist/node.adapter.js",
"types": "./types/node.adapter.d.ts",
"node": "./dist/node.adapter.js",
"require": "./dist/node.adapter.js"
},
"./utils": {
"default": "./dist/utils.js",
"types": "./types/utils.d.ts"
}
},
"scripts": {
"prebuild": "rimraf ./dist",
"build": "rollup -c"
},
"repository": {
"type": "git",
"url": "https://github.com/bnb-chain/greenfield-js-sdk",
"directory": "packages/reed-solomon"
},
"homepage": "https://github.com/bnb-chain/greenfield-js-sdk/tree/alpha/packages/reed-solomon#readme",
"bugs": "https://github.com/bnb-chain/greenfield-js-sdk/issues",
"keywords": [
"greenfiled",
"checksums",
"reed-solomon"
],
"author": "",
"license": "GPLv3",
"files": [
"dist",
"types"
],
"publishConfig": {
"registry": "https://registry.npmjs.org/",
"access": "public"
},
"dependencies": {
"@ethersproject/base64": "^5.7.0",
"ethereum-cryptography": "^2.0.0"
}
}
63 changes: 63 additions & 0 deletions packages/reed-solomon/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';
import pkg from './package.json';
// const pathResolve = (p) => path.resolve(__dirname, p);

function resolveExternal() {
return [...Object.keys(pkg.dependencies || {}), ...Object.keys(pkg.peerDependencies || {})];
}

export default async () => {
return [
{
input: './src/index.js',
output: {
file: 'dist/index.esm.js',
sourcemap: true,
},
external: resolveExternal(),
context: 'window',
treeshake: true,
plugins: [
commonjs(),
resolve({
browser: true,
preferBuiltins: false,
}),
],
},
{
input: ['./src/index.js', './src/node.adapter.js', './src/utils.js'],
output: {
format: 'cjs',
// file: 'dist/index.js',
dir: 'dist',
sourcemap: true,
},
external: resolveExternal(),
plugins: [
// commonjs(),
// resolve({
// browser: true,
// preferBuiltins: false,
// }),
],
},
{
input: './src/index.js',
output: {
format: 'umd',
file: 'dist/index.aio.js',
name: 'RS',
sourcemap: true,
},
plugins: [
commonjs(),
resolve({
browser: true,
preferBuiltins: false,
}),
],
},
];
};
Loading

0 comments on commit 18891a4

Please sign in to comment.