refactor(quantus-crypto): drop the @polkadot/wasm-util dependency
It cost more than it saved. Two problems, the second only visible once quantus/common tried to consume this package: Its index re-exports packageDetect, whose only job is a side effect registering with @polkadot/util — a peer dependency inherited for nothing. Deep imports (/base64, /fflate) avoided that. But it is a workspace package, so a symlinked consumer resolves its dependencies through *this* repo's node_modules, where @polkadot/wasm-util points at the package source rather than its build and carries no exports map. Node follows symlinks to their realpath, so `@polkadot/wasm-util/base64` failed to resolve from quantus/common no matter which yarn protocol was used — portal: and link: behave the same once the realpath is taken. So: fflate directly for zlib inflate, and fifteen lines for base64 rather than a dependency at all. Deliberately not atob or Buffer.from — the first is browser-only, the second node-only, and this runs in an MV3 service worker, a Worker, node tests and a bundled extension page. The package is now self-contained apart from fflate, which resolves normally from any checkout. Size is unchanged at 234,292 raw / 109,649 zlib / 146,200 base64. Refs quantus/wasm#1, quantus/common#2 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012uDUodEcRbBwNRi3UCmw8f
This commit is contained in:
co-authored by
Claude Opus 5
parent
8323e442d9
commit
a6d3685c59
@@ -28,6 +28,14 @@ wasm-bindgen 0.2.79's JS-heap ABI, while this crate builds with 0.2.128, which
|
||||
uses externref tables. wasm-bindgen's own generated glue plus `initSync` is both
|
||||
smaller and correct.
|
||||
|
||||
The only runtime dependency is `fflate`, for zlib inflate. Base64 decoding is
|
||||
fifteen lines here rather than a dependency. Both were originally taken from
|
||||
`@polkadot/wasm-util`, which turned out to cost more than it saved: its index
|
||||
re-exports `packageDetect`, dragging in a `@polkadot/util` peer dependency for a
|
||||
side effect we do not want, and being a workspace package it resolved through its
|
||||
*own* repo's node_modules when this package was consumed by symlink from another
|
||||
checkout — which is exactly how `quantus/common` consumes it during development.
|
||||
|
||||
## Scheme selector
|
||||
|
||||
`Scheme.MlDsa87 = 0`, `Scheme.MlDsa65 = 1` — these are the chain's own
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"version": "0.1.0",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@polkadot/wasm-util": "7.5.4",
|
||||
"fflate": "^0.8.2",
|
||||
"tslib": "^2.7.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
// Copyright 2026 @quantus/crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
const CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||||
|
||||
// An array indexer rather than a Map: the input is ASCII by construction, so it
|
||||
// cannot overflow, and array access is measurably faster on the hot loop.
|
||||
const MAP = new Array<number>(256);
|
||||
|
||||
for (let i = 0; i < CHARS.length; i++) {
|
||||
MAP[CHARS.charCodeAt(i)] = i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode base64 into a caller-supplied buffer.
|
||||
*
|
||||
* Deliberately not `atob` or `Buffer.from`: the first is browser-only, the second
|
||||
* node-only, and this runs in an MV3 service worker, a Worker, node tests and a
|
||||
* bundled extension page. The output length is known at build time, so the
|
||||
* caller provides the buffer and there is no growth or reallocation.
|
||||
*
|
||||
* This is a reimplementation of `@polkadot/wasm-util`'s base64Decode, which was
|
||||
* the dependency it replaced. That package's index re-exports `packageDetect`,
|
||||
* dragging in a `@polkadot/util` peer dependency for a side effect we do not
|
||||
* want, and being a workspace package it resolved through its own repo's
|
||||
* node_modules when consumed by symlink from another checkout. Fifteen lines is
|
||||
* cheaper than either problem.
|
||||
*/
|
||||
export function base64Decode (data: string, out: Uint8Array): Uint8Array {
|
||||
let byte = 0;
|
||||
let bits = 0;
|
||||
let pos = 0;
|
||||
|
||||
for (let i = 0; i < data.length && pos < out.length; i++) {
|
||||
const value = MAP[data.charCodeAt(i)];
|
||||
|
||||
if (value === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
byte = (byte << 6) | value;
|
||||
bits += 6;
|
||||
|
||||
if (bits >= 8) {
|
||||
bits -= 8;
|
||||
out[pos++] = (byte >>> bits) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
@@ -1,12 +1,9 @@
|
||||
// Copyright 2026 @quantus/crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Deep imports, not the package index. `@polkadot/wasm-util`'s index re-exports
|
||||
// `packageDetect`, whose only job is a side effect registering the package with
|
||||
// `@polkadot/util` — a peer dependency we would otherwise inherit for nothing.
|
||||
// These two subpaths are pure functions with no dependencies at all.
|
||||
import { base64Decode } from '@polkadot/wasm-util/base64';
|
||||
import { unzlibSync } from '@polkadot/wasm-util/fflate';
|
||||
import { unzlibSync } from 'fflate';
|
||||
|
||||
import { base64Decode } from './base64.js';
|
||||
|
||||
import { bytes, lenOut } from './bytes.js';
|
||||
import { initSync } from './generated/quantus_crypto.js';
|
||||
|
||||
@@ -6,14 +6,6 @@
|
||||
"declaration": true,
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src",
|
||||
"paths": {
|
||||
"@polkadot/wasm-util/base64": [
|
||||
"wasm-util/build/base64.d.ts"
|
||||
],
|
||||
"@polkadot/wasm-util/fflate": [
|
||||
"wasm-util/build/fflate.d.ts"
|
||||
]
|
||||
},
|
||||
"emitDeclarationOnly": false
|
||||
},
|
||||
"exclude": [
|
||||
|
||||
@@ -4,13 +4,12 @@
|
||||
|
||||
# Runs the consumer test against a staged node_modules rather than in-place.
|
||||
#
|
||||
# In this repo `node_modules/@polkadot/wasm-util` symlinks to the package *source*
|
||||
# directory, whose package.json carries no `exports` map — only the build output
|
||||
# does. So a deep import like `@polkadot/wasm-util/base64` resolves for a real
|
||||
# consumer and fails here, which would make the in-place test wrong in a way that
|
||||
# has nothing to do with our package. Staging the built artifacts the way an
|
||||
# install lays them out tests module resolution too, which is half of what can
|
||||
# break in a published package.
|
||||
# Staging the built artifact the way an install lays it out tests module
|
||||
# resolution too, which is half of what can break in a published package — it is
|
||||
# what caught binaryen 105 producing a wasm that fails to instantiate.
|
||||
#
|
||||
# `fflate`, the one runtime dependency, resolves by node walking up to the repo's
|
||||
# own node_modules, which is exactly what it would do inside a real install.
|
||||
|
||||
set -e
|
||||
|
||||
@@ -18,10 +17,9 @@ PKG=packages/quantus-crypto
|
||||
STAGE=$PKG/build-test
|
||||
|
||||
rm -rf $STAGE
|
||||
mkdir -p $STAGE/node_modules/@quantus $STAGE/node_modules/@polkadot
|
||||
mkdir -p $STAGE/node_modules/@quantus
|
||||
|
||||
cp -r $PKG/build $STAGE/node_modules/@quantus/crypto
|
||||
cp -r packages/wasm-util/build $STAGE/node_modules/@polkadot/wasm-util
|
||||
echo '{ "name": "quantus-crypto-consumer-test", "type": "module", "version": "0.0.0" }' > $STAGE/package.json
|
||||
cp $PKG/test/consumer.mjs $STAGE/consumer.mjs
|
||||
|
||||
|
||||
Reference in New Issue
Block a user