Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/js-evo-sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
"name": "@dashevo/evo-sdk",
"version": "2.1.0-dev.5",
"type": "module",
"main": "./dist/sdk.js",
"main": "./dist/evo-sdk.module.js",
"types": "./dist/sdk.d.ts",
"exports": {
".": {
"types": "./dist/sdk.d.ts",
"import": "./dist/sdk.js"
"import": "./dist/evo-sdk.module.js"
},
"./module": {
"import": "./dist/sdk.js"
"import": "./dist/evo-sdk.module.js"
}
},
"sideEffects": false,
Expand Down
6 changes: 3 additions & 3 deletions packages/js-evo-sdk/src/wasm.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// ESM wrapper around @dashevo/wasm-sdk with one-time init
import initWasmSdk, * as wasm from '@dashevo/wasm-sdk';
import initWasmSdk, * as wasm from '@dashevo/wasm-sdk/compressed';

let initPromise: Promise<any> | undefined;

Expand All @@ -11,5 +11,5 @@ export async function ensureInitialized(): Promise<void> {
}

// Re-export all wasm SDK symbols for convenience
export * from '@dashevo/wasm-sdk';
export { default } from '@dashevo/wasm-sdk';
export * from '@dashevo/wasm-sdk/compressed';
export { default } from '@dashevo/wasm-sdk/compressed';
1 change: 1 addition & 0 deletions packages/js-evo-sdk/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"resolveJsonModule": true,
"baseUrl": ".",
"paths": {
"@dashevo/wasm-sdk/compressed": ["../wasm-sdk/dist/sdk.d.ts"],
"@dashevo/wasm-sdk": ["../wasm-sdk/dist/sdk.d.ts"],
"@dashevo/wasm-sdk/*": ["../wasm-sdk/dist/*"]
}
Expand Down
2 changes: 1 addition & 1 deletion packages/js-evo-sdk/webpack.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const esm = {
experiments: { outputModule: true },
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'sdk.js',
filename: 'evo-sdk.module.js',
library: { type: 'module' },
module: true,
},
Expand Down
4 changes: 4 additions & 0 deletions packages/wasm-sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
"types": "./dist/sdk.d.ts",
"import": "./dist/sdk.js"
},
"./compressed": {
"types": "./dist/sdk.d.ts",
"import": "./dist/sdk.compressed.js"
},
"./raw": {
"types": "./dist/raw/wasm_sdk.d.ts",
"import": "./dist/raw/wasm_sdk.js"
Expand Down
24 changes: 21 additions & 3 deletions packages/wasm-sdk/scripts/bundle.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

const fs = require('fs');
const path = require('path');
const zlib = require('zlib');

const root = process.cwd();
const pkgDir = path.join(root, 'pkg');
Expand Down Expand Up @@ -49,14 +50,31 @@ const sanitizedJs = rawJs.replace(defaultUrlRegex, "if (typeof module_or_path ==
fs.writeFileSync(path.join(rawDir, 'wasm_sdk.no_url.js'), sanitizedJs);

// Build single-file wrapper with inlined WASM and worker-based compile in the browser
const wasmBase64 = fs.readFileSync(wasmPath).toString('base64');
const wasmBytes = fs.readFileSync(wasmPath);
const wasmBase64 = wasmBytes.toString('base64');
const wasmGzip = zlib.gzipSync(wasmBytes, { level: zlib.constants.Z_BEST_COMPRESSION });
const wasmGzipBase64 = wasmGzip.toString('base64');

const wrapper = `// Single-file ESM wrapper around wasm-bindgen output.\n// - Inlines WASM bytes as base64.\n// - Exposes async default init() for both Node and browser.\n// - Browser compiles in a Web Worker and instantiates on main thread (fallback to async compile).\n// - Node uses initSync with inlined bytes (still awaitable for uniform API).\n\nimport rawInit, { initSync as rawInitSync } from './raw/wasm_sdk.no_url.js';\n\nexport * from './raw/wasm_sdk.no_url.js';\nexport { initSync } from './raw/wasm_sdk.no_url.js';\n\nconst __WASM_BASE64 = '${wasmBase64}';\nfunction __wasmBytes() {\n if (typeof Buffer !== 'undefined' && typeof Buffer.from === 'function') {\n return Buffer.from(__WASM_BASE64, 'base64');\n }\n const atobFn = (typeof atob === 'function') ? atob : (s) => globalThis.atob(s);\n const bin = atobFn(__WASM_BASE64);\n const len = bin.length;\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) bytes[i] = bin.charCodeAt(i);\n return bytes;\n}\n\nfunction __supportsWorker() {\n return typeof Worker !== 'undefined' && typeof Blob !== 'undefined' && typeof URL !== 'undefined';\n}\n\nasync function __compileInWorker(bytes) {\n if (!__supportsWorker()) {\n return WebAssembly.compile(bytes);\n }\n const src = 'self.onmessage=async(e)=>{try{const m=await WebAssembly.compile(e.data);self.postMessage({ok:1,mod:m});}catch(err){self.postMessage({ok:0,err:String(err)});}}';\n const blob = new Blob([src], { type: 'application/javascript' });\n const url = URL.createObjectURL(blob);\n return new Promise((resolve) => {\n const w = new Worker(url);\n w.onmessage = (ev) => {\n URL.revokeObjectURL(url);\n w.terminate();\n const d = ev.data || {};\n if (d.ok && d.mod) {\n resolve(d.mod);\n } else {\n resolve(WebAssembly.compile(bytes));\n }\n };\n // Transfer the underlying buffer to avoid copy\n try {\n w.postMessage(bytes.buffer, [bytes.buffer]);\n } catch (_) {\n // If transfer fails (detached), send a copy\n w.postMessage(new Uint8Array(bytes));\n }\n });\n}\n\nconst isNode = typeof window === 'undefined' && typeof process !== 'undefined' && !!(process.versions && process.versions.node);\n\nexport default async function init(moduleOrPath) {\n if (isNode) {\n if (typeof moduleOrPath === 'undefined') {\n const bytes = __wasmBytes();\n return rawInitSync({ module: bytes });\n }\n return rawInit(moduleOrPath);\n }\n if (typeof moduleOrPath === 'undefined') {\n const bytes = __wasmBytes();\n let mod;\n try {\n mod = await __compileInWorker(bytes);\n } catch (_) {\n mod = await WebAssembly.compile(bytes);\n }\n return rawInit({ module_or_path: mod });\n }\n return rawInit(moduleOrPath);\n}\n`;
fs.writeFileSync(path.join(distDir, 'sdk.js'), wrapper);

const compressedWrapper = `// Gzip-compressed single-file ESM wrapper around wasm-bindgen output.\n// - Inlines WASM as base64 gzip payload to reduce bundle size.\n// - Decompresses off-thread when possible to minimize main-thread work.\n// - Preserves async init() API shape.\n\nimport rawInit, { initSync as rawInitSync } from './raw/wasm_sdk.no_url.js';\n\nexport * from './raw/wasm_sdk.no_url.js';\nexport { initSync } from './raw/wasm_sdk.no_url.js';\n\nconst __WASM_COMPRESSED_BASE64 = '${wasmGzipBase64}';\nconst __WASM_COMPRESSION = 'gzip';\nconst isNode = typeof window === 'undefined' && typeof process !== 'undefined' && !!(process.versions && process.versions.node);\n\nfunction __decodeBase64(source) {\n if (typeof Buffer !== 'undefined' && typeof Buffer.from === 'function') {\n return Buffer.from(source, 'base64');\n }\n const atobFn = (typeof atob === 'function') ? atob : (s) => globalThis.atob(s);\n const bin = atobFn(source);\n const len = bin.length;\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) bytes[i] = bin.charCodeAt(i);\n return bytes;\n}\n\nasync function __decompress(bytes) {\n if (!__WASM_COMPRESSION) {\n return bytes;\n }\n if (isNode) {\n const { gunzipSync } = await import(/* webpackIgnore: true */ 'node:zlib');\n const out = gunzipSync(bytes);\n return out instanceof Uint8Array\n ? out\n : new Uint8Array(out.buffer, out.byteOffset, out.byteLength);\n }\n if (typeof Blob === 'function' && typeof Response === 'function' && typeof DecompressionStream === 'function') {\n const res = new Response(\n new Blob([bytes]).stream().pipeThrough(new DecompressionStream(__WASM_COMPRESSION))\n );\n const buf = await res.arrayBuffer();\n return new Uint8Array(buf);\n }\n throw new Error('Gzip decompression not supported in this environment.');\n}\n\nasync function __wasmBytes(options = {}) {\n const { decompress = true } = options;\n if (!__WASM_COMPRESSION) {\n throw new Error('Compression metadata missing.');\n }\n const compressed = __decodeBase64(__WASM_COMPRESSED_BASE64);\n if (!decompress) {\n return compressed;\n }\n return __decompress(compressed);\n}\n\nfunction __supportsWorker() {\n return typeof Worker !== 'undefined' && typeof Blob !== 'undefined' && typeof URL !== 'undefined';\n}\n\nasync function __compileInWorker(compressedBytes) {\n const bytes = compressedBytes instanceof Uint8Array ? compressedBytes : new Uint8Array(compressedBytes);\n if (!__supportsWorker()) {\n const decompressed = await __decompress(bytes);\n return WebAssembly.compile(decompressed);\n }\n const src = "self.onmessage=async(event)=>{try{const data=event.data||{};let bytes=data.compressed;const compression=data.compression||null;if(!(bytes instanceof Uint8Array)){bytes=bytes?new Uint8Array(bytes):new Uint8Array();}if(compression){if(typeof Blob==='function'&&typeof Response==='function'&&typeof DecompressionStream==='function'){const res=new Response(new Blob([bytes]).stream().pipeThrough(new DecompressionStream(compression)));const buf=await res.arrayBuffer();bytes=new Uint8Array(buf);}else{throw new Error('DecompressionStream not available');}}const mod=await WebAssembly.compile(bytes);self.postMessage({ok:1,mod});}catch(err){self.postMessage({ok:0,err:String(err)})}}";\n const blob = new Blob([src], { type: 'application/javascript' });\n const url = URL.createObjectURL(blob);\n return new Promise((resolve, reject) => {\n const worker = new Worker(url);\n const cleanup = () => {\n URL.revokeObjectURL(url);\n worker.terminate();\n };\n worker.onmessage = (ev) => {\n const d = ev.data || {};\n if (d.ok && d.mod) {\n cleanup();\n resolve(d.mod);\n } else {\n cleanup();\n reject(new Error(d.err || 'Worker failed to compile WASM.'));\n }\n };\n worker.onerror = (err) => {\n cleanup();\n reject(err instanceof Error ? err : new Error(String(err && err.message ? err.message : err)));\n };\n try {\n worker.postMessage({ compressed: bytes, compression: __WASM_COMPRESSION });\n } catch (postErr) {\n cleanup();\n reject(postErr);\n }\n });\n}\n\nexport default async function init(moduleOrPath) {\n if (isNode) {\n if (typeof moduleOrPath === 'undefined') {\n const bytes = await __wasmBytes();\n return rawInitSync({ module: bytes });\n }\n return rawInit(moduleOrPath);\n }\n if (typeof moduleOrPath === 'undefined') {\n const compressedBytes = await __wasmBytes({ decompress: false });\n let mod;\n try {\n mod = await __compileInWorker(compressedBytes);\n } catch (_) {\n const decompressed = await __decompress(compressedBytes);\n mod = await WebAssembly.compile(decompressed);\n }\n return rawInit({ module_or_path: mod });\n }\n return rawInit(moduleOrPath);\n}\n`
fs.writeFileSync(path.join(distDir, 'sdk.compressed.js'), compressedWrapper);

const sdkJsPath = path.join(distDir, 'sdk.js');
const sdkCompressedPath = path.join(distDir, 'sdk.compressed.js');

const baseStat = fs.statSync(sdkJsPath);
const compressedStat = fs.statSync(sdkCompressedPath);
const baseGzipSize = zlib.gzipSync(fs.readFileSync(sdkJsPath)).length;
const compressedGzipSize = zlib.gzipSync(fs.readFileSync(sdkCompressedPath)).length;

fs.copyFileSync(dtsPath, path.join(distDir, 'sdk.d.ts'));

// Basic report
const outStat = fs.statSync(path.join(distDir, 'sdk.js'));
console.log(`Wrote dist/sdk.js (${outStat.size} bytes) single-file wrapper (inline WASM)`);
console.log(`Wrote dist/sdk.js (${baseStat.size} bytes) single-file wrapper (inline WASM)`);
console.log(`Wrote dist/sdk.compressed.js (${compressedStat.size} bytes) gzip inline wrapper`);
console.log(`gzip(sdk.js): ${baseGzipSize} bytes | gzip(sdk.compressed.js): ${compressedGzipSize} bytes`);
console.log('Wrote dist/sdk.d.ts');
console.log('Copied extra type declarations (if any)');
console.log('Wrote dist/raw/* (separate JS + WASM)');
Expand Down
2 changes: 1 addition & 1 deletion packages/wasm-sdk/tests/functional/dpns.spec.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import init, * as sdk from '../../dist/sdk.js';
import init, * as sdk from '../../dist/sdk.compressed.js';

Check failure on line 1 in packages/wasm-sdk/tests/functional/dpns.spec.mjs

View workflow job for this annotation

GitHub Actions / JS packages (@dashevo/wasm-sdk) / Linting

Parse errors in imported module '../../dist/sdk.compressed.js': Unexpected token import (32:34)

Check failure on line 1 in packages/wasm-sdk/tests/functional/dpns.spec.mjs

View workflow job for this annotation

GitHub Actions / JS packages (@dashevo/wasm-sdk) / Linting

Parse errors in imported module '../../dist/sdk.compressed.js': Unexpected token import (32:34)

describe('Document queries', function describeDocumentQueries() {
this.timeout(60000);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import init, * as sdk from '../../dist/sdk.js';
import init, * as sdk from '../../dist/sdk.compressed.js';

Check failure on line 1 in packages/wasm-sdk/tests/functional/epochs-blocks.spec.mjs

View workflow job for this annotation

GitHub Actions / JS packages (@dashevo/wasm-sdk) / Linting

Parse errors in imported module '../../dist/sdk.compressed.js': Unexpected token import (32:34)

Check failure on line 1 in packages/wasm-sdk/tests/functional/epochs-blocks.spec.mjs

View workflow job for this annotation

GitHub Actions / JS packages (@dashevo/wasm-sdk) / Linting

Parse errors in imported module '../../dist/sdk.compressed.js': Unexpected token import (32:34)

describe('Epochs and evonode blocks', function describeEpochs() {
this.timeout(60000);
Expand Down
2 changes: 1 addition & 1 deletion packages/wasm-sdk/tests/functional/groups.spec.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import init, * as sdk from '../../dist/sdk.js';
import init, * as sdk from '../../dist/sdk.compressed.js';

Check failure on line 1 in packages/wasm-sdk/tests/functional/groups.spec.mjs

View workflow job for this annotation

GitHub Actions / JS packages (@dashevo/wasm-sdk) / Linting

Parse errors in imported module '../../dist/sdk.compressed.js': Unexpected token import (32:34)

Check failure on line 1 in packages/wasm-sdk/tests/functional/groups.spec.mjs

View workflow job for this annotation

GitHub Actions / JS packages (@dashevo/wasm-sdk) / Linting

Parse errors in imported module '../../dist/sdk.compressed.js': Unexpected token import (32:34)

describe('Group queries', function describeGroupQueries() {
this.timeout(60000);
Expand Down
2 changes: 1 addition & 1 deletion packages/wasm-sdk/tests/functional/identities.spec.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import init, * as sdk from '../../dist/sdk.js';
import init, * as sdk from '../../dist/sdk.compressed.js';

Check failure on line 1 in packages/wasm-sdk/tests/functional/identities.spec.mjs

View workflow job for this annotation

GitHub Actions / JS packages (@dashevo/wasm-sdk) / Linting

Parse errors in imported module '../../dist/sdk.compressed.js': Unexpected token import (32:34)

Check failure on line 1 in packages/wasm-sdk/tests/functional/identities.spec.mjs

View workflow job for this annotation

GitHub Actions / JS packages (@dashevo/wasm-sdk) / Linting

Parse errors in imported module '../../dist/sdk.compressed.js': Unexpected token import (32:34)

describe('Identity queries', function describeBlock() {
this.timeout(90000);
Expand Down
2 changes: 1 addition & 1 deletion packages/wasm-sdk/tests/functional/protocol.spec.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import init, * as sdk from '../../dist/sdk.js';
import init, * as sdk from '../../dist/sdk.compressed.js';

Check failure on line 1 in packages/wasm-sdk/tests/functional/protocol.spec.mjs

View workflow job for this annotation

GitHub Actions / JS packages (@dashevo/wasm-sdk) / Linting

Parse errors in imported module '../../dist/sdk.compressed.js': Unexpected token import (32:34)

Check failure on line 1 in packages/wasm-sdk/tests/functional/protocol.spec.mjs

View workflow job for this annotation

GitHub Actions / JS packages (@dashevo/wasm-sdk) / Linting

Parse errors in imported module '../../dist/sdk.compressed.js': Unexpected token import (32:34)

describe('Protocol versions', function describeProtocolVersions() {
this.timeout(60000);
Expand Down
2 changes: 1 addition & 1 deletion packages/wasm-sdk/tests/functional/status.spec.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import init, * as sdk from '../../dist/sdk.js';
import init, * as sdk from '../../dist/sdk.compressed.js';

describe('Status endpoint', function describeBlock() {
this.timeout(30000);
Expand Down
2 changes: 1 addition & 1 deletion packages/wasm-sdk/tests/functional/system.spec.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import init, * as sdk from '../../dist/sdk.js';
import init, * as sdk from '../../dist/sdk.compressed.js';

describe('System info', function describeSystemInfo() {
this.timeout(60000);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import init, * as sdk from '../../dist/sdk.js';
import init, * as sdk from '../../dist/sdk.compressed.js';

describe('Token pricing', function describeTokenPricing() {
this.timeout(60000);
Expand Down
2 changes: 1 addition & 1 deletion packages/wasm-sdk/tests/functional/tokens.spec.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import init, * as sdk from '../../dist/sdk.js';
import init, * as sdk from '../../dist/sdk.compressed.js';

describe('Token queries', function describeTokenQueries() {
this.timeout(60000);
Expand Down
2 changes: 1 addition & 1 deletion packages/wasm-sdk/tests/functional/transitions.spec.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import init, * as sdk from '../../dist/sdk.js';
import init, * as sdk from '../../dist/sdk.compressed.js';

const TOKEN_CONTRACT = 'H7FRpZJqZK933r9CzZMsCuf1BM34NT5P2wSJyjDkprqy';
const TEST_IDENTITY = '5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk';
Expand Down
2 changes: 1 addition & 1 deletion packages/wasm-sdk/tests/functional/utilities.spec.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import init, * as sdk from '../../dist/sdk.js';
import init, * as sdk from '../../dist/sdk.compressed.js';

describe('Utilities', function describeUtilities() {
before(async () => { await init(); });
Expand Down
2 changes: 1 addition & 1 deletion packages/wasm-sdk/tests/functional/voting.spec.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import init, * as sdk from '../../dist/sdk.js';
import init, * as sdk from '../../dist/sdk.compressed.js';

describe('Contested resources & voting', function describeContestedResources() {
this.timeout(60000);
Expand Down
2 changes: 1 addition & 1 deletion packages/wasm-sdk/tests/unit/address-validation.spec.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import init, * as sdk from '../../dist/sdk.js';
import init, * as sdk from '../../dist/sdk.compressed.js';

describe('Address validation', () => {
before(async () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/wasm-sdk/tests/unit/api-availability.spec.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import init, * as sdk from '../../dist/sdk.js';
import init, * as sdk from '../../dist/sdk.compressed.js';

describe('API availability (exports and methods)', () => {
before(async () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/wasm-sdk/tests/unit/builder.spec.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import init, * as sdk from '../../dist/sdk.js';
import init, * as sdk from '../../dist/sdk.compressed.js';

describe('WasmSdkBuilder', () => {
before(async () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/wasm-sdk/tests/unit/derivation.spec.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import init, * as sdk from '../../dist/sdk.js';
import init, * as sdk from '../../dist/sdk.compressed.js';

describe('Key derivation', () => {
before(async () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/wasm-sdk/tests/unit/dpns-utils.spec.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import init, * as sdk from '../../dist/sdk.js';
import init, * as sdk from '../../dist/sdk.compressed.js';

describe('DPNS utils (homograph + validation)', () => {
before(async () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/wasm-sdk/tests/unit/errors.spec.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import init, * as sdk from '../../dist/sdk.js';
import init, * as sdk from '../../dist/sdk.compressed.js';

describe('WasmSdkError shape (unit)', () => {
before(async () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/wasm-sdk/tests/unit/extended-keys.spec.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import init, * as sdk from '../../dist/sdk.js';
import init, * as sdk from '../../dist/sdk.compressed.js';

describe('Extended keys', () => {
const TEST_MNEMONIC = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
Expand Down
2 changes: 1 addition & 1 deletion packages/wasm-sdk/tests/unit/key-generation.spec.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import init, * as sdk from '../../dist/sdk.js';
import init, * as sdk from '../../dist/sdk.compressed.js';

describe('Keys and mnemonics', () => {
const TEST_MNEMONIC = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
Expand Down
Loading