From 6245753e8d0069397b0dc2a4ef7c34eb53d1b8d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Fri, 16 Jan 2026 21:41:05 +0100 Subject: [PATCH 01/53] Bundle `sdk` --- package-lock.json | 249 +++++++++++++++++++++++++++ packages/sdk/bin/tsconfig.json | 2 +- packages/sdk/fix-esm.sh | 3 - packages/sdk/package.json | 49 ++++-- packages/sdk/rollup.config.mts | 149 ++++++++++++++++ packages/sdk/scripts/postbuild.sh | 11 -- packages/sdk/src/exports-browser.ts | 5 - packages/sdk/src/exports-commonjs.js | 8 - packages/sdk/src/exports-esm.mjs | 5 - packages/sdk/src/exports.ts | 5 +- packages/sdk/src/index.ts | 1 - packages/sdk/tsconfig.generated.json | 2 +- packages/sdk/tsconfig.json | 22 +-- packages/sdk/tsconfig.node.json | 31 ++++ 14 files changed, 466 insertions(+), 76 deletions(-) delete mode 100755 packages/sdk/fix-esm.sh create mode 100644 packages/sdk/rollup.config.mts delete mode 100755 packages/sdk/scripts/postbuild.sh delete mode 100644 packages/sdk/src/exports-browser.ts delete mode 100644 packages/sdk/src/exports-commonjs.js delete mode 100644 packages/sdk/src/exports-esm.mjs create mode 100644 packages/sdk/tsconfig.node.json diff --git a/package-lock.json b/package-lock.json index bcbcc9c44d..07426fcc74 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8851,6 +8851,27 @@ "@types/send": "*" } }, + "node_modules/@types/fs-extra": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.5.tgz", + "integrity": "sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, "node_modules/@types/haversine": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/@types/haversine/-/haversine-1.1.8.tgz", @@ -13712,6 +13733,29 @@ "dev": true, "license": "MIT" }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dir-glob/node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/dns2": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/dns2/-/dns2-2.1.0.tgz", @@ -16457,6 +16501,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/globby": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", + "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -17686,6 +17750,16 @@ "node": ">=0.10.0" } }, + "node_modules/is-plain-object": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz", + "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", @@ -25454,6 +25528,65 @@ "fsevents": "~2.3.2" } }, + "node_modules/rollup-plugin-copy": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-copy/-/rollup-plugin-copy-3.5.0.tgz", + "integrity": "sha512-wI8D5dvYovRMx/YYKtUNt3Yxaw4ORC9xo6Gt9t22kveWz1enG9QrhVlagzwrxSC455xD1dHMKhIJkbsQ7d48BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/fs-extra": "^8.0.1", + "colorette": "^1.1.0", + "fs-extra": "^8.1.0", + "globby": "10.0.1", + "is-plain-object": "^3.0.0" + }, + "engines": { + "node": ">=8.3" + } + }, + "node_modules/rollup-plugin-copy/node_modules/colorette": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", + "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", + "dev": true, + "license": "MIT" + }, + "node_modules/rollup-plugin-copy/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/rollup-plugin-copy/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/rollup-plugin-copy/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/rollup-plugin-dts": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-6.3.0.tgz", @@ -30729,6 +30862,9 @@ "@babel/preset-env": "^7.28.5", "@babel/preset-typescript": "^7.28.5", "@jest/globals": "^30.0.5", + "@rollup/plugin-commonjs": "^28.0.6", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^16.0.3", "@streamr/test-utils": "103.2.0-experiment.1", "@types/heap": "^0.2.35", "@types/lodash": "^4.17.21", @@ -30749,9 +30885,14 @@ "lodash-webpack-plugin": "^0.11.6", "nightwatch": "^3.12.3", "node-polyfill-webpack-plugin": "^4.1.0", + "rimraf": "^6.1.2", + "rollup": "^4.55.1", + "rollup-plugin-copy": "^3.5.0", + "rollup-plugin-dts": "^6.3.0", "terser-webpack-plugin": "^5.3.14", "ts-loader": "^9.5.4", "ts-node": "^10.9.2", + "tsx": "^4.21.0", "util": "^0.12.4", "weak-napi": "^2.0.2", "webpack": "^5.103.0", @@ -30764,6 +30905,77 @@ "utf-8-validate": "^6.0.5" } }, + "packages/sdk/node_modules/@rollup/plugin-commonjs": { + "version": "28.0.9", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.9.tgz", + "integrity": "sha512-PIR4/OHZ79romx0BVVll/PkwWpJ7e5lsqFa3gFfcrFPWwLXLV39JVUzQV9RKjWerE7B845Hqjj9VYlQeieZ2dA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "fdir": "^6.2.0", + "is-reference": "1.2.1", + "magic-string": "^0.30.3", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=16.0.0 || 14 >= 14.17" + }, + "peerDependencies": { + "rollup": "^2.68.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "packages/sdk/node_modules/glob": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", + "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/sdk/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/sdk/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "packages/sdk/node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -30779,6 +30991,43 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "packages/sdk/node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/sdk/node_modules/rimraf": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz", + "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "glob": "^13.0.0", + "package-json-from-dist": "^1.0.1" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "packages/test-utils": { "name": "@streamr/test-utils", "version": "103.2.0-experiment.1", diff --git a/packages/sdk/bin/tsconfig.json b/packages/sdk/bin/tsconfig.json index 5a03dbdeb8..626d58c3b4 100644 --- a/packages/sdk/bin/tsconfig.json +++ b/packages/sdk/bin/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "..", + "extends": "../tsconfig.node.json", "include": [ "**/*" ] diff --git a/packages/sdk/fix-esm.sh b/packages/sdk/fix-esm.sh deleted file mode 100755 index f88cbc1801..0000000000 --- a/packages/sdk/fix-esm.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -mkdir -p dist/src/ -cp -f src/exports-esm.mjs dist/src/exports-esm.mjs diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 3d76cac685..a4a28a30ec 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -7,39 +7,42 @@ "url": "git+https://github.com/streamr-dev/network.git", "directory": "packages/client" }, - "types": "./dist/types/src/index.d.ts", - "main": "./dist/src/exports-commonjs.js", - "module": "./dist/src/exports-esm.mjs", - "script": "./dist/streamr-sdk.web.min.js", - "browser": { - "./src/utils/persistence/ServerPersistence.ts": "./src/utils/persistence/BrowserPersistence.mts", - "./dist/src/utils/persistence/ServerPersistence.js": "./dist/src/utils/persistence/BrowserPersistence.mjs" - }, + "main": "./dist/exports-nodejs.cjs", + "module": "./dist/exports-nodejs.js", + "types": "./dist/exports-nodejs.d.ts", + "script": "./dist/exports-browser.umd.js", "exports": { - "default": { - "types": "./dist/types/src/index.d.ts", - "import": "./dist/src/exports-esm.mjs", - "require": "./dist/src/exports-commonjs.js" + ".": { + "types": "./dist/exports-nodejs.d.ts", + "browser": { + "types": "./dist/exports-browser.d.ts", + "import": "./dist/exports-browser.js", + "require": "./dist/exports-browser.cjs", + "default": "./dist/exports-browser.js" + }, + "node": "./dist/exports-nodejs.cjs", + "import": "./dist/exports-nodejs.js", + "require": "./dist/exports-nodejs.cjs", + "default": "./dist/exports-nodejs.js" } }, "files": [ - "dist", + "dist/exports-nodejs.*", + "dist/exports-browser.*", + "dist/encryption/migrations", "!*.tsbuildinfo", "LICENSE", "README.md", "readme-header.png" ], "scripts": { - "prebuild": "node bin/generate-config-validator.js && ./proto.sh", - "postbuild": "./scripts/postbuild.sh && bash fix-esm.sh", + "prebuild": "npm run reset-self && node bin/generate-config-validator.js && ./proto.sh", "build": "tsc -b", - "build-browser": "npm run build-browser-development && npm run build-browser-production", - "build-browser-development": "NODE_ENV=development webpack --mode=development --progress", - "build-browser-production": "NODE_ENV=production webpack --mode=production --progress", + "postbuild": "NODE_OPTIONS='--import tsx' rollup -c rollup.config.mts", "check": "tsc -b tsconfig.jest.json", + "reset-self": "rimraf --glob 'dist/**/*.tsbuildinfo'", "clean": "jest --clearCache --config '{}' || true; rm -rf dist src/generated *.tsbuildinfo node_modules/.cache || true", "eslint": "eslint --cache --cache-location=node_modules/.cache/.eslintcache/ '*/**/*.{js,ts,mts}'", - "generate-protoc-code": "./proto.sh", "test": "npm run test-unit && npm run test-integration && npm run test-end-to-end", "test-unit": "jest --useStderr --forceExit test/unit", "test-integration": "jest --bail --useStderr --forceExit --testTimeout=40000 test/integration/*.test.*", @@ -60,6 +63,9 @@ "@babel/preset-env": "^7.28.5", "@babel/preset-typescript": "^7.28.5", "@jest/globals": "^30.0.5", + "@rollup/plugin-commonjs": "^28.0.6", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^16.0.3", "@streamr/test-utils": "103.2.0-experiment.1", "@types/heap": "^0.2.35", "@types/lodash": "^4.17.21", @@ -80,9 +86,14 @@ "lodash-webpack-plugin": "^0.11.6", "nightwatch": "^3.12.3", "node-polyfill-webpack-plugin": "^4.1.0", + "rimraf": "^6.1.2", + "rollup": "^4.55.1", + "rollup-plugin-copy": "^3.5.0", + "rollup-plugin-dts": "^6.3.0", "terser-webpack-plugin": "^5.3.14", "ts-loader": "^9.5.4", "ts-node": "^10.9.2", + "tsx": "^4.21.0", "util": "^0.12.4", "weak-napi": "^2.0.2", "webpack": "^5.103.0", diff --git a/packages/sdk/rollup.config.mts b/packages/sdk/rollup.config.mts new file mode 100644 index 0000000000..ed4768f925 --- /dev/null +++ b/packages/sdk/rollup.config.mts @@ -0,0 +1,149 @@ +import { defineConfig, type RollupLog, type RollupOptions } from 'rollup' +import { dts } from 'rollup-plugin-dts' +import { nodeResolve } from '@rollup/plugin-node-resolve' +import cjs from '@rollup/plugin-commonjs' +import json from '@rollup/plugin-json' +import copy from 'rollup-plugin-copy' + +export default defineConfig([ + nodejs(), + nodejsTypes(), + browser(), + browserTypes(), + umd(), +]) + +function onwarn(log: RollupLog, rollupWarn: (log: RollupLog) => void): void { + // Suppress circular dependency warnings from external libraries + if (log.code === 'CIRCULAR_DEPENDENCY' && /node_modules/.test(log.message ?? '')) { + return + } + + rollupWarn(log) +} + +function nodejs(): RollupOptions { + return { + input: './dist/src/exports.js', + output: [ + { + format: 'es', + file: './dist/exports-nodejs.js', + sourcemap: true, + }, + { + format: 'cjs', + file: './dist/exports-nodejs.cjs', + sourcemap: true, + }, + ], + plugins: [ + json(), + nodeResolve({ + preferBuiltins: true, + }), + cjs(), + copy({ + targets: [ + { + src: 'src/encryption/migrations/*', + dest: 'dist/encryption/migrations' + } + ] + }), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + onwarn, + } +} + +function nodejsTypes(): RollupOptions { + return { + input: './dist/src/index.d.ts', + output: [ + { file: './dist/exports-nodejs.d.ts' }, + ], + plugins: [ + nodeResolve(), + dts(), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + } +} + +function browser(): RollupOptions { + return { + input: './dist/src/exports.js', + output: [ + { + format: 'es', + file: './dist/exports-browser.js', + sourcemap: true, + }, + { + format: 'cjs', + file: './dist/exports-browser.cjs', + sourcemap: true, + }, + ], + plugins: [ + json(), + nodeResolve({ + browser: true, + preferBuiltins: false, + }), + cjs(), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + onwarn, + } +} + +function browserTypes(): RollupOptions { + return { + input: './dist/src/index.d.ts', + output: [ + { file: './dist/exports-browser.d.ts' }, + ], + plugins: [ + nodeResolve(), + dts(), + ], + external: [ + /node_modules/, + /@streamr\//, + ], + } +} + +function umd(): RollupOptions { + return { + input: './dist/src/exports.js', + context: 'window', + output: { + format: 'umd', + name: 'StreamrClient', + file: './dist/streamr-client.umd.js', + sourcemap: true, + }, + plugins: [ + json(), + nodeResolve({ + browser: true, + preferBuiltins: false, + }), + cjs(), + ], + external: [], + onwarn, + } +} diff --git a/packages/sdk/scripts/postbuild.sh b/packages/sdk/scripts/postbuild.sh deleted file mode 100755 index 5d7015328d..0000000000 --- a/packages/sdk/scripts/postbuild.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -mkdir -p dist - -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -cd "${SCRIPT_DIR}/.." - -# Copy over the migrations -mkdir -p dist/src/encryption/migrations -cp -f src/encryption/migrations/* dist/src/encryption/migrations diff --git a/packages/sdk/src/exports-browser.ts b/packages/sdk/src/exports-browser.ts deleted file mode 100644 index d023d614e4..0000000000 --- a/packages/sdk/src/exports-browser.ts +++ /dev/null @@ -1,5 +0,0 @@ -import * as StreamrClientExports from './exports' - -Object.assign(StreamrClientExports.StreamrClient, StreamrClientExports) - -export default StreamrClientExports.StreamrClient diff --git a/packages/sdk/src/exports-commonjs.js b/packages/sdk/src/exports-commonjs.js deleted file mode 100644 index ec0043374d..0000000000 --- a/packages/sdk/src/exports-commonjs.js +++ /dev/null @@ -1,8 +0,0 @@ -/* eslint-disable @typescript-eslint/no-require-imports */ -// CJS entrypoint. -const StreamrClientExports = require('./exports') - -Object.assign(StreamrClientExports.StreamrClient, StreamrClientExports) - -// required to get require('@streamr/sdk') instead of require('@streamr/sdk').default -module.exports = StreamrClientExports.StreamrClient diff --git a/packages/sdk/src/exports-esm.mjs b/packages/sdk/src/exports-esm.mjs deleted file mode 100644 index e485e020ab..0000000000 --- a/packages/sdk/src/exports-esm.mjs +++ /dev/null @@ -1,5 +0,0 @@ -// ESM EntryPoint -export * from './index.js' -// required to get import StreamrClient from '@streamr/sdk' to work -export { StreamrClient as default } from './index.js' -// note this file is manually copied as-is into dist/src since we don't want tsc to compile it to commonjs diff --git a/packages/sdk/src/exports.ts b/packages/sdk/src/exports.ts index a12186d0f0..2a9549451e 100644 --- a/packages/sdk/src/exports.ts +++ b/packages/sdk/src/exports.ts @@ -1,6 +1,5 @@ -/** - * This file captures named exports so we can manipulate them for cjs/browser builds. - */ +import 'reflect-metadata' + export { StreamrClient, type SubscribeOptions, type ExtraSubscribeOptions } from './StreamrClient' export { Stream } from './Stream' export { type StreamMetadata, parseMetadata as parseStreamMetadata, getPartitionCount as getStreamPartitionCount } from './StreamMetadata' diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index 59d487c57d..b7bdb10bce 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -9,4 +9,3 @@ import { StreamrClient } from './StreamrClient' export * from './exports' export default StreamrClient -// Note awful export wrappers in exports-commonjs.js & exports-esm.mjs diff --git a/packages/sdk/tsconfig.generated.json b/packages/sdk/tsconfig.generated.json index b0ee61428f..3353d4682b 100644 --- a/packages/sdk/tsconfig.generated.json +++ b/packages/sdk/tsconfig.generated.json @@ -1,5 +1,5 @@ { - "extends": "./tsconfig.json", + "extends": "./tsconfig.node.json", "compilerOptions": { "noImplicitOverride": false }, diff --git a/packages/sdk/tsconfig.json b/packages/sdk/tsconfig.json index 55522d1c1f..667d1ae42d 100644 --- a/packages/sdk/tsconfig.json +++ b/packages/sdk/tsconfig.json @@ -1,25 +1,9 @@ { - "extends": "../../tsconfig.node.json", + "files": [], "compilerOptions": { - "outDir": "dist", - "declarationDir": "dist/types", - "lib": ["es2021"], - "experimentalDecorators": true, - "emitDecoratorMetadata": true + "composite": true }, - "include": [ - "src", - "src/**/*.json" - ], - "exclude": [ - "src/generated", - "src/exports-esm.mjs" - ], "references": [ - { "path": "../utils" }, - { "path": "../proto-rpc" }, - { "path": "../dht" }, - { "path": "../trackerless-network" }, - { "path": "./tsconfig.generated.json" } + { "path": "./tsconfig.node.json" } ] } diff --git a/packages/sdk/tsconfig.node.json b/packages/sdk/tsconfig.node.json new file mode 100644 index 0000000000..9001b3cf7a --- /dev/null +++ b/packages/sdk/tsconfig.node.json @@ -0,0 +1,31 @@ +{ + "extends": "../../tsconfig.node.json", + "compilerOptions": { + "outDir": "dist", + "lib": ["es2021"], + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + + /* Don't emit helpers inline. Import them from tslib instead – key for using tsyringe with rollup. */ + "importHelpers": true, + + /* Resolution */ + "moduleResolution": "bundler", + "module": "preserve", + "baseUrl": ".", + }, + "include": [ + "src", + "src/**/*.json" + ], + "exclude": [ + "src/generated" + ], + "references": [ + { "path": "../utils" }, + { "path": "../proto-rpc" }, + { "path": "../dht" }, + { "path": "../trackerless-network" }, + { "path": "./tsconfig.generated.json" } + ] +} From 57e5fd049979a78188d1879723b3536b7a64ddd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Fri, 16 Jan 2026 23:48:54 +0100 Subject: [PATCH 02/53] Include a tersered UMD build of the SDK, too --- package-lock.json | 41 ++++++++++++++++++++++++++++++++++ packages/sdk/package.json | 1 + packages/sdk/rollup.config.mts | 26 +++++++++++++++++++++ 3 files changed, 68 insertions(+) diff --git a/package-lock.json b/package-lock.json index 07426fcc74..646cfbbf0d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7385,6 +7385,39 @@ } } }, + "node_modules/@rollup/plugin-terser": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "serialize-javascript": "^6.0.1", + "smob": "^1.0.0", + "terser": "^5.17.4" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-terser/node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, "node_modules/@rollup/pluginutils": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", @@ -26349,6 +26382,13 @@ "npm": ">= 3.0.0" } }, + "node_modules/smob": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", + "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==", + "dev": true, + "license": "MIT" + }, "node_modules/socket.io": { "version": "4.8.1", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", @@ -30865,6 +30905,7 @@ "@rollup/plugin-commonjs": "^28.0.6", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.3", + "@rollup/plugin-terser": "^0.4.4", "@streamr/test-utils": "103.2.0-experiment.1", "@types/heap": "^0.2.35", "@types/lodash": "^4.17.21", diff --git a/packages/sdk/package.json b/packages/sdk/package.json index a4a28a30ec..d50e7f0891 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -87,6 +87,7 @@ "nightwatch": "^3.12.3", "node-polyfill-webpack-plugin": "^4.1.0", "rimraf": "^6.1.2", + "@rollup/plugin-terser": "^0.4.4", "rollup": "^4.55.1", "rollup-plugin-copy": "^3.5.0", "rollup-plugin-dts": "^6.3.0", diff --git a/packages/sdk/rollup.config.mts b/packages/sdk/rollup.config.mts index ed4768f925..c10602b586 100644 --- a/packages/sdk/rollup.config.mts +++ b/packages/sdk/rollup.config.mts @@ -4,6 +4,7 @@ import { nodeResolve } from '@rollup/plugin-node-resolve' import cjs from '@rollup/plugin-commonjs' import json from '@rollup/plugin-json' import copy from 'rollup-plugin-copy' +import terser from '@rollup/plugin-terser' export default defineConfig([ nodejs(), @@ -11,6 +12,7 @@ export default defineConfig([ browser(), browserTypes(), umd(), + umdMinified(), ]) function onwarn(log: RollupLog, rollupWarn: (log: RollupLog) => void): void { @@ -147,3 +149,27 @@ function umd(): RollupOptions { onwarn, } } + +function umdMinified(): RollupOptions { + return { + input: './dist/src/exports.js', + context: 'window', + output: { + format: 'umd', + name: 'StreamrClient', + file: './dist/streamr-client.umd.min.js', + sourcemap: true, + }, + plugins: [ + json(), + nodeResolve({ + browser: true, + preferBuiltins: false, + }), + cjs(), + terser(), + ], + external: [], + onwarn, + } +} From bd8dfbb22a610cdfb1a64b36bc80f35d0c3139a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Mon, 19 Jan 2026 13:26:55 +0100 Subject: [PATCH 03/53] Format --- packages/sdk/rollup.config.mts | 47 ++++++++++++---------------------- 1 file changed, 17 insertions(+), 30 deletions(-) diff --git a/packages/sdk/rollup.config.mts b/packages/sdk/rollup.config.mts index c10602b586..33987a2ea1 100644 --- a/packages/sdk/rollup.config.mts +++ b/packages/sdk/rollup.config.mts @@ -17,7 +17,10 @@ export default defineConfig([ function onwarn(log: RollupLog, rollupWarn: (log: RollupLog) => void): void { // Suppress circular dependency warnings from external libraries - if (log.code === 'CIRCULAR_DEPENDENCY' && /node_modules/.test(log.message ?? '')) { + if ( + log.code === 'CIRCULAR_DEPENDENCY' && + /node_modules/.test(log.message ?? '') + ) { return } @@ -49,15 +52,12 @@ function nodejs(): RollupOptions { targets: [ { src: 'src/encryption/migrations/*', - dest: 'dist/encryption/migrations' - } - ] + dest: 'dist/encryption/migrations', + }, + ], }), ], - external: [ - /node_modules/, - /@streamr\//, - ], + external: [/node_modules/, /@streamr\//], onwarn, } } @@ -65,17 +65,9 @@ function nodejs(): RollupOptions { function nodejsTypes(): RollupOptions { return { input: './dist/src/index.d.ts', - output: [ - { file: './dist/exports-nodejs.d.ts' }, - ], - plugins: [ - nodeResolve(), - dts(), - ], - external: [ - /node_modules/, - /@streamr\//, - ], + output: [{ file: './dist/exports-nodejs.d.ts' }], + plugins: [nodeResolve(), dts()], + external: [/node_modules/, /@streamr\//], } } @@ -102,10 +94,7 @@ function browser(): RollupOptions { }), cjs(), ], - external: [ - /node_modules/, - /@streamr\//, - ], + external: [/node_modules/, /@streamr\//], onwarn, } } @@ -113,17 +102,12 @@ function browser(): RollupOptions { function browserTypes(): RollupOptions { return { input: './dist/src/index.d.ts', - output: [ - { file: './dist/exports-browser.d.ts' }, - ], + output: [{ file: './dist/exports-browser.d.ts' }], plugins: [ nodeResolve(), dts(), ], - external: [ - /node_modules/, - /@streamr\//, - ], + external: [/node_modules/, /@streamr\//], } } @@ -162,6 +146,9 @@ function umdMinified(): RollupOptions { }, plugins: [ json(), + alias({ + entries: browserAliases, + }), nodeResolve({ browser: true, preferBuiltins: false, From db16a44c5398b338653d1c7c1d3b6cc00946e8ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Mon, 19 Jan 2026 13:27:22 +0100 Subject: [PATCH 04/53] Alias `timers` properly --- package-lock.json | 5 ++--- packages/sdk/package.json | 5 +++-- packages/sdk/rollup.config.mts | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 646cfbbf0d..b2671ffe4f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26124,7 +26124,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true, "license": "MIT" }, "node_modules/setimmediate-napi": { @@ -27934,7 +27933,6 @@ "version": "2.0.12", "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", - "dev": true, "license": "MIT", "dependencies": { "setimmediate": "^1.0.4" @@ -30888,6 +30886,7 @@ "reflect-metadata": "^0.2.1", "sqlite": "^5.1.1", "sqlite3": "^5.1.7", + "timers-browserify": "^2.0.12", "ts-essentials": "^10.1.1", "ts-toolbelt": "^9.6.0", "tsyringe": "^4.10.0", @@ -30902,6 +30901,7 @@ "@babel/preset-env": "^7.28.5", "@babel/preset-typescript": "^7.28.5", "@jest/globals": "^30.0.5", + "@rollup/plugin-alias": "^6.0.0", "@rollup/plugin-commonjs": "^28.0.6", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.3", @@ -30918,7 +30918,6 @@ "buffer": "^6.0.3", "bytes": "^3.1.1", "chromedriver": "^121.0.2", - "crypto-browserify": "^3.12.1", "express": "^5.2.0", "git-revision-webpack-plugin": "^5.0.0", "jest-leak-detector": "^27.3.1", diff --git a/packages/sdk/package.json b/packages/sdk/package.json index d50e7f0891..e3be8fb066 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -63,9 +63,11 @@ "@babel/preset-env": "^7.28.5", "@babel/preset-typescript": "^7.28.5", "@jest/globals": "^30.0.5", + "@rollup/plugin-alias": "^6.0.0", "@rollup/plugin-commonjs": "^28.0.6", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.3", + "@rollup/plugin-terser": "^0.4.4", "@streamr/test-utils": "103.2.0-experiment.1", "@types/heap": "^0.2.35", "@types/lodash": "^4.17.21", @@ -78,7 +80,6 @@ "buffer": "^6.0.3", "bytes": "^3.1.1", "chromedriver": "^121.0.2", - "crypto-browserify": "^3.12.1", "express": "^5.2.0", "git-revision-webpack-plugin": "^5.0.0", "jest-leak-detector": "^27.3.1", @@ -87,7 +88,6 @@ "nightwatch": "^3.12.3", "node-polyfill-webpack-plugin": "^4.1.0", "rimraf": "^6.1.2", - "@rollup/plugin-terser": "^0.4.4", "rollup": "^4.55.1", "rollup-plugin-copy": "^3.5.0", "rollup-plugin-dts": "^6.3.0", @@ -128,6 +128,7 @@ "reflect-metadata": "^0.2.1", "sqlite": "^5.1.1", "sqlite3": "^5.1.7", + "timers-browserify": "^2.0.12", "ts-essentials": "^10.1.1", "ts-toolbelt": "^9.6.0", "tsyringe": "^4.10.0", diff --git a/packages/sdk/rollup.config.mts b/packages/sdk/rollup.config.mts index 33987a2ea1..7ccd8b8c03 100644 --- a/packages/sdk/rollup.config.mts +++ b/packages/sdk/rollup.config.mts @@ -5,6 +5,11 @@ import cjs from '@rollup/plugin-commonjs' import json from '@rollup/plugin-json' import copy from 'rollup-plugin-copy' import terser from '@rollup/plugin-terser' +import alias, { type Alias } from '@rollup/plugin-alias' + +const browserAliases: Alias[] = [ + { find: 'timers', replacement: 'timers-browserify' }, +] export default defineConfig([ nodejs(), @@ -88,6 +93,9 @@ function browser(): RollupOptions { ], plugins: [ json(), + alias({ + entries: browserAliases, + }), nodeResolve({ browser: true, preferBuiltins: false, @@ -104,6 +112,9 @@ function browserTypes(): RollupOptions { input: './dist/src/index.d.ts', output: [{ file: './dist/exports-browser.d.ts' }], plugins: [ + alias({ + entries: browserAliases, + }), nodeResolve(), dts(), ], @@ -123,6 +134,9 @@ function umd(): RollupOptions { }, plugins: [ json(), + alias({ + entries: browserAliases, + }), nodeResolve({ browser: true, preferBuiltins: false, From 83db66dff1ff7779ef96a03b96c85a2e86269b42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Mon, 19 Jan 2026 13:37:46 +0100 Subject: [PATCH 05/53] refactor(sdk): Rename `Persistence.ts` to `types.ts` in persistence utils - Move Persistence interface from Persistence.ts to types.ts - Update import in PersistenceManager to use type-only import --- packages/sdk/src/PersistenceManager.ts | 2 +- packages/sdk/src/utils/persistence/{Persistence.ts => types.ts} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename packages/sdk/src/utils/persistence/{Persistence.ts => types.ts} (100%) diff --git a/packages/sdk/src/PersistenceManager.ts b/packages/sdk/src/PersistenceManager.ts index d3b27152ea..28128e1474 100644 --- a/packages/sdk/src/PersistenceManager.ts +++ b/packages/sdk/src/PersistenceManager.ts @@ -3,7 +3,7 @@ import { inject, Lifecycle, scoped } from 'tsyringe' import { Identity, IdentityInjectionToken } from './identity/Identity' import { DestroySignal } from './DestroySignal' import { LoggerFactory } from './utils/LoggerFactory' -import { Persistence } from './utils/persistence/Persistence' +import type { Persistence } from './utils/persistence/types' import ServerPersistence from './utils/persistence/ServerPersistence' export const NAMESPACES = { diff --git a/packages/sdk/src/utils/persistence/Persistence.ts b/packages/sdk/src/utils/persistence/types.ts similarity index 100% rename from packages/sdk/src/utils/persistence/Persistence.ts rename to packages/sdk/src/utils/persistence/types.ts From 9452c52869b0cba2bda73b751db370c069771301 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Mon, 19 Jan 2026 13:50:03 +0100 Subject: [PATCH 06/53] Add `@/` path aliases for `_browser` and `_nodejs` folders in SDK --- packages/sdk/rollup.config.mts | 39 ++++++++++++--- packages/sdk/tsconfig.browser-generated.json | 10 ++++ packages/sdk/tsconfig.browser.json | 50 +++++++++++++++++++ packages/sdk/tsconfig.jest.json | 8 ++- packages/sdk/tsconfig.json | 3 +- ...ated.json => tsconfig.node-generated.json} | 0 packages/sdk/tsconfig.node.json | 10 ++-- 7 files changed, 108 insertions(+), 12 deletions(-) create mode 100644 packages/sdk/tsconfig.browser-generated.json create mode 100644 packages/sdk/tsconfig.browser.json rename packages/sdk/{tsconfig.generated.json => tsconfig.node-generated.json} (100%) diff --git a/packages/sdk/rollup.config.mts b/packages/sdk/rollup.config.mts index 7ccd8b8c03..9fe691b1bf 100644 --- a/packages/sdk/rollup.config.mts +++ b/packages/sdk/rollup.config.mts @@ -6,8 +6,24 @@ import json from '@rollup/plugin-json' import copy from 'rollup-plugin-copy' import terser from '@rollup/plugin-terser' import alias, { type Alias } from '@rollup/plugin-alias' +import { fileURLToPath } from 'node:url' + +const nodejsAliases: Alias[] = [ + { + find: /^@\//, + replacement: fileURLToPath( + new URL('./dist/nodejs/src/_nodejs/', import.meta.url) + ), + }, +] const browserAliases: Alias[] = [ + { + find: /^@\//, + replacement: fileURLToPath( + new URL('./dist/browser/src/_browser/', import.meta.url) + ), + }, { find: 'timers', replacement: 'timers-browserify' }, ] @@ -34,7 +50,7 @@ function onwarn(log: RollupLog, rollupWarn: (log: RollupLog) => void): void { function nodejs(): RollupOptions { return { - input: './dist/src/exports.js', + input: './dist/nodejs/src/exports.js', output: [ { format: 'es', @@ -49,6 +65,9 @@ function nodejs(): RollupOptions { ], plugins: [ json(), + alias({ + entries: nodejsAliases, + }), nodeResolve({ preferBuiltins: true, }), @@ -69,16 +88,22 @@ function nodejs(): RollupOptions { function nodejsTypes(): RollupOptions { return { - input: './dist/src/index.d.ts', + input: './dist/nodejs/src/index.d.ts', output: [{ file: './dist/exports-nodejs.d.ts' }], - plugins: [nodeResolve(), dts()], + plugins: [ + alias({ + entries: nodejsAliases, + }), + nodeResolve(), + dts(), + ], external: [/node_modules/, /@streamr\//], } } function browser(): RollupOptions { return { - input: './dist/src/exports.js', + input: './dist/browser/src/exports.js', output: [ { format: 'es', @@ -109,7 +134,7 @@ function browser(): RollupOptions { function browserTypes(): RollupOptions { return { - input: './dist/src/index.d.ts', + input: './dist/browser/src/index.d.ts', output: [{ file: './dist/exports-browser.d.ts' }], plugins: [ alias({ @@ -124,7 +149,7 @@ function browserTypes(): RollupOptions { function umd(): RollupOptions { return { - input: './dist/src/exports.js', + input: './dist/browser/src/exports.js', context: 'window', output: { format: 'umd', @@ -150,7 +175,7 @@ function umd(): RollupOptions { function umdMinified(): RollupOptions { return { - input: './dist/src/exports.js', + input: './dist/browser/src/exports.js', context: 'window', output: { format: 'umd', diff --git a/packages/sdk/tsconfig.browser-generated.json b/packages/sdk/tsconfig.browser-generated.json new file mode 100644 index 0000000000..6a742101fc --- /dev/null +++ b/packages/sdk/tsconfig.browser-generated.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.browser.json", + "compilerOptions": { + "noImplicitOverride": false + }, + "include": [ + "src/generated" + ], + "exclude": [] +} diff --git a/packages/sdk/tsconfig.browser.json b/packages/sdk/tsconfig.browser.json new file mode 100644 index 0000000000..828128de4e --- /dev/null +++ b/packages/sdk/tsconfig.browser.json @@ -0,0 +1,50 @@ +{ + "extends": "../../tsconfig.browser.json", + "compilerOptions": { + "outDir": "dist/browser", + "lib": ["ES2022", "DOM"], + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + + "allowJs": true, + + /* Don't emit helpers inline. Import them from tslib instead – key for using tsyringe with rollup. */ + "importHelpers": true, + + /* Resolution */ + "baseUrl": ".", + "paths": { + "@/*": ["src/_browser/*"] + }, + + /* @todo Make verbatimModuleSyntax (true) work. */ + "verbatimModuleSyntax": false, + + /* @todo Make useUnknownInCatchVariables (true) work. */ + "useUnknownInCatchVariables": false, + + /* @todo Make erasableSyntaxOnly (true) work. */ + "erasableSyntaxOnly": false, + + /* @todo Make noUnusedLocals (true) work. */ + "noUnusedLocals": false, + + /* @todo Make noUnusedParameters (true) work. */ + "noUnusedParameters": false + }, + "include": [ + "src", + "src/**/*.json" + ], + "exclude": [ + "src/generated", + "src/_nodejs" + ], + "references": [ + { "path": "../utils/tsconfig.browser.json" }, + { "path": "../proto-rpc" }, + { "path": "../dht/tsconfig.browser.json" }, + { "path": "../trackerless-network" }, + { "path": "./tsconfig.browser-generated.json" } + ] +} diff --git a/packages/sdk/tsconfig.jest.json b/packages/sdk/tsconfig.jest.json index afb7f0c5f3..841eae478a 100644 --- a/packages/sdk/tsconfig.jest.json +++ b/packages/sdk/tsconfig.jest.json @@ -3,7 +3,13 @@ "compilerOptions": { "lib": ["es2021"], "experimentalDecorators": true, - "emitDecoratorMetadata": true + "emitDecoratorMetadata": true, + "module": "preserve", + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": { + "@/*": ["src/_nodejs/*"] + } }, "include": [ "package.json", diff --git a/packages/sdk/tsconfig.json b/packages/sdk/tsconfig.json index 667d1ae42d..9a557a2379 100644 --- a/packages/sdk/tsconfig.json +++ b/packages/sdk/tsconfig.json @@ -4,6 +4,7 @@ "composite": true }, "references": [ - { "path": "./tsconfig.node.json" } + { "path": "./tsconfig.node.json" }, + { "path": "./tsconfig.browser.json" } ] } diff --git a/packages/sdk/tsconfig.generated.json b/packages/sdk/tsconfig.node-generated.json similarity index 100% rename from packages/sdk/tsconfig.generated.json rename to packages/sdk/tsconfig.node-generated.json diff --git a/packages/sdk/tsconfig.node.json b/packages/sdk/tsconfig.node.json index 9001b3cf7a..548317fb50 100644 --- a/packages/sdk/tsconfig.node.json +++ b/packages/sdk/tsconfig.node.json @@ -1,7 +1,7 @@ { "extends": "../../tsconfig.node.json", "compilerOptions": { - "outDir": "dist", + "outDir": "dist/nodejs", "lib": ["es2021"], "experimentalDecorators": true, "emitDecoratorMetadata": true, @@ -13,19 +13,23 @@ "moduleResolution": "bundler", "module": "preserve", "baseUrl": ".", + "paths": { + "@/*": ["src/_nodejs/*"] + } }, "include": [ "src", "src/**/*.json" ], "exclude": [ - "src/generated" + "src/generated", + "src/_browser" ], "references": [ { "path": "../utils" }, { "path": "../proto-rpc" }, { "path": "../dht" }, { "path": "../trackerless-network" }, - { "path": "./tsconfig.generated.json" } + { "path": "./tsconfig.node-generated.json" } ] } From 75154325e36bb264584d424d391aa036124a8d15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Mon, 19 Jan 2026 14:29:17 +0100 Subject: [PATCH 07/53] refactor(sdk): Move persistence implementations to platform-specific directories - Move `BrowserPersistence` and `ServerPersistence` to `_browser` and `_nodejs` directories respectively. - Rename both classes to `Persistence` with named exports, enabling consistent imports via the `@/` path alias that resolves to the appropriate platform directory at build time. --- packages/sdk/src/PersistenceManager.ts | 10 +++++----- .../Persistence.ts} | 8 ++++---- .../Persistence.ts} | 18 +++++++++--------- 3 files changed, 18 insertions(+), 18 deletions(-) rename packages/sdk/src/{utils/persistence/BrowserPersistence.mts => _browser/Persistence.ts} (90%) rename packages/sdk/src/{utils/persistence/ServerPersistence.ts => _nodejs/Persistence.ts} (91%) diff --git a/packages/sdk/src/PersistenceManager.ts b/packages/sdk/src/PersistenceManager.ts index 28128e1474..283bd2c162 100644 --- a/packages/sdk/src/PersistenceManager.ts +++ b/packages/sdk/src/PersistenceManager.ts @@ -3,8 +3,8 @@ import { inject, Lifecycle, scoped } from 'tsyringe' import { Identity, IdentityInjectionToken } from './identity/Identity' import { DestroySignal } from './DestroySignal' import { LoggerFactory } from './utils/LoggerFactory' -import type { Persistence } from './utils/persistence/types' -import ServerPersistence from './utils/persistence/ServerPersistence' +import type { Persistence as PersistenceInterface } from './utils/persistence/types' +import { Persistence } from '@/Persistence' export const NAMESPACES = { ENCRYPTION_KEYS: 'EncryptionKeys', @@ -14,7 +14,7 @@ export const NAMESPACES = { @scoped(Lifecycle.ContainerScoped) export class PersistenceManager { - private persistence?: ServerPersistence + private persistence?: Persistence private readonly identity: Identity private readonly loggerFactory: LoggerFactory @@ -34,7 +34,7 @@ export class PersistenceManager { } private async ensureInitialized() { - this.persistence ??= await ServerPersistence.createInstance({ + this.persistence ??= await Persistence.createInstance({ loggerFactory: this.loggerFactory, ownerId: await this.identity.getUserId(), namespaces: Object.values(NAMESPACES), @@ -42,7 +42,7 @@ export class PersistenceManager { }) } - async getPersistence(namespace: string): Promise { + async getPersistence(namespace: string): Promise { await this.ensureInitialized() return { get: (key: string): Promise => { diff --git a/packages/sdk/src/utils/persistence/BrowserPersistence.mts b/packages/sdk/src/_browser/Persistence.ts similarity index 90% rename from packages/sdk/src/utils/persistence/BrowserPersistence.mts rename to packages/sdk/src/_browser/Persistence.ts index a10f6d932e..3f423c008d 100644 --- a/packages/sdk/src/utils/persistence/BrowserPersistence.mts +++ b/packages/sdk/src/_browser/Persistence.ts @@ -1,5 +1,5 @@ import { openDB, IDBPDatabase } from 'idb' -import { PersistenceContext, PersistenceContextOptions } from './PersistenceContext.js' +import { PersistenceContext, PersistenceContextOptions } from '../utils/persistence/PersistenceContext' /** * This file is a ES module (.mts) instead of CommonJS. It was converted to ESM to resolve @@ -16,17 +16,17 @@ import { PersistenceContext, PersistenceContextOptions } from './PersistenceCont * See https://github.com/streamr-dev/network/pull/2848 */ -export default class BrowserPersistence implements PersistenceContext { +export class Persistence implements PersistenceContext { private readonly db: IDBPDatabase - static async createInstance(opts: PersistenceContextOptions): Promise { + static async createInstance(opts: PersistenceContextOptions): Promise { const db = await openDB(`streamr-sdk::${opts.ownerId}`, 1, { upgrade(db) { opts.namespaces.forEach((namespace) => db.createObjectStore(namespace)) } }) - return new BrowserPersistence(db) + return new Persistence(db) } private constructor(db: IDBPDatabase) { diff --git a/packages/sdk/src/utils/persistence/ServerPersistence.ts b/packages/sdk/src/_nodejs/Persistence.ts similarity index 91% rename from packages/sdk/src/utils/persistence/ServerPersistence.ts rename to packages/sdk/src/_nodejs/Persistence.ts index a367352b77..c5f65c68ae 100644 --- a/packages/sdk/src/utils/persistence/ServerPersistence.ts +++ b/packages/sdk/src/_nodejs/Persistence.ts @@ -4,19 +4,19 @@ import { promises as fs } from 'fs' import { open, Database } from 'sqlite' import sqlite3 from 'sqlite3' -import { pOnce } from '../promises' +import { pOnce } from '../utils/promises' -import { PersistenceContext, PersistenceContextOptions } from './PersistenceContext' +import { PersistenceContext, PersistenceContextOptions } from '../utils/persistence/PersistenceContext' import { Logger, wait } from '@streamr/utils' -import { LoggerFactory } from '../LoggerFactory' +import { LoggerFactory } from '../utils/LoggerFactory' -export interface ServerPersistenceOptions extends PersistenceContextOptions { +export interface PersistenceOptions extends PersistenceContextOptions { loggerFactory: LoggerFactory migrationsPath?: string onInit?: (db: Database) => Promise } -export default class ServerPersistence implements PersistenceContext { +export class Persistence implements PersistenceContext { private readonly logger: Logger private readonly dbFilePath: string private store?: Database @@ -27,12 +27,12 @@ export default class ServerPersistence implements PersistenceContext { // uses createInstance factory pattern so that ServerPersistence and BrowserPersistence // are interchangeable - static async createInstance(opts: ServerPersistenceOptions): Promise { + static async createInstance(opts: PersistenceOptions): Promise { // TODO init() call could called here, so that we don't need to separate logic for // initialization (i.e. check this.initCalled flag before eaach call). // It would be ok to do initialization, because the PersistenceManager already lazy loads // and therefore doesn't create this instance before it is needed - return new ServerPersistence(opts) + return new Persistence(opts) } private constructor({ @@ -40,8 +40,8 @@ export default class ServerPersistence implements PersistenceContext { ownerId, migrationsPath, onInit - }: ServerPersistenceOptions) { - this.logger = loggerFactory.createLogger('ServerPersistence') + }: PersistenceOptions) { + this.logger = loggerFactory.createLogger('Persistence') const paths = envPaths('streamr-sdk') // ownerId could be too long for the FS, but unlikely to collide locally - concatenate to first 50 chars this.dbFilePath = resolve(paths.data, join('./', ownerId.substring(0, 50), `GroupKeys.db`)) From 191b62cdfd09b9d1e01347bb318ae26adaa2c1b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Mon, 19 Jan 2026 15:10:08 +0100 Subject: [PATCH 08/53] refactor(sdk): Consolidate persistence types into single file --- packages/sdk/src/Persistence.types.ts | 33 +++++++++++++++++++ packages/sdk/src/PersistenceManager.ts | 2 +- packages/sdk/src/_browser/Persistence.ts | 6 ++-- packages/sdk/src/_nodejs/Persistence.ts | 16 +++------ .../utils/persistence/PersistenceContext.ts | 13 -------- packages/sdk/src/utils/persistence/types.ts | 4 --- 6 files changed, 41 insertions(+), 33 deletions(-) create mode 100644 packages/sdk/src/Persistence.types.ts delete mode 100644 packages/sdk/src/utils/persistence/PersistenceContext.ts delete mode 100644 packages/sdk/src/utils/persistence/types.ts diff --git a/packages/sdk/src/Persistence.types.ts b/packages/sdk/src/Persistence.types.ts new file mode 100644 index 0000000000..c4380c991a --- /dev/null +++ b/packages/sdk/src/Persistence.types.ts @@ -0,0 +1,33 @@ +import { UserID } from '@streamr/utils' +import { LoggerFactory } from './utils/LoggerFactory' + +/** + * Full persistence context interface with namespace parameter. + * Implemented by platform-specific Persistence classes. + */ +export interface PersistenceContext { + get(key: string, namespace: string): Promise + set(key: string, value: string, namespace: string): Promise + close(): Promise +} + +/** + * Namespace-bound persistence interface. + * Returned by PersistenceManager.getPersistence(). + */ +export interface Persistence { + get(key: string): Promise + set(key: string, value: string): Promise +} + +/** + * Unified options for Persistence.createInstance(). + * Browser implementation ignores Node.js-specific fields (loggerFactory, migrationsPath, onInit). + */ +export interface PersistenceOptions { + ownerId: UserID + namespaces: string[] + loggerFactory: LoggerFactory + migrationsPath?: string + onInit?: (db: unknown) => Promise +} diff --git a/packages/sdk/src/PersistenceManager.ts b/packages/sdk/src/PersistenceManager.ts index 283bd2c162..f6852a3f00 100644 --- a/packages/sdk/src/PersistenceManager.ts +++ b/packages/sdk/src/PersistenceManager.ts @@ -3,7 +3,7 @@ import { inject, Lifecycle, scoped } from 'tsyringe' import { Identity, IdentityInjectionToken } from './identity/Identity' import { DestroySignal } from './DestroySignal' import { LoggerFactory } from './utils/LoggerFactory' -import type { Persistence as PersistenceInterface } from './utils/persistence/types' +import type { Persistence as PersistenceInterface } from './Persistence.types' import { Persistence } from '@/Persistence' export const NAMESPACES = { diff --git a/packages/sdk/src/_browser/Persistence.ts b/packages/sdk/src/_browser/Persistence.ts index 3f423c008d..9f68bd9a2f 100644 --- a/packages/sdk/src/_browser/Persistence.ts +++ b/packages/sdk/src/_browser/Persistence.ts @@ -1,5 +1,5 @@ -import { openDB, IDBPDatabase } from 'idb' -import { PersistenceContext, PersistenceContextOptions } from '../utils/persistence/PersistenceContext' +import { openDB, type IDBPDatabase } from 'idb' +import type { PersistenceContext, PersistenceOptions } from '../Persistence.types' /** * This file is a ES module (.mts) instead of CommonJS. It was converted to ESM to resolve @@ -20,7 +20,7 @@ export class Persistence implements PersistenceContext { private readonly db: IDBPDatabase - static async createInstance(opts: PersistenceContextOptions): Promise { + static async createInstance(opts: PersistenceOptions): Promise { const db = await openDB(`streamr-sdk::${opts.ownerId}`, 1, { upgrade(db) { opts.namespaces.forEach((namespace) => db.createObjectStore(namespace)) diff --git a/packages/sdk/src/_nodejs/Persistence.ts b/packages/sdk/src/_nodejs/Persistence.ts index c5f65c68ae..871a400f2b 100644 --- a/packages/sdk/src/_nodejs/Persistence.ts +++ b/packages/sdk/src/_nodejs/Persistence.ts @@ -1,20 +1,12 @@ import envPaths from 'env-paths' import { dirname, resolve, join } from 'path' import { promises as fs } from 'fs' -import { open, Database } from 'sqlite' +import { open, type Database } from 'sqlite' import sqlite3 from 'sqlite3' - import { pOnce } from '../utils/promises' - -import { PersistenceContext, PersistenceContextOptions } from '../utils/persistence/PersistenceContext' -import { Logger, wait } from '@streamr/utils' -import { LoggerFactory } from '../utils/LoggerFactory' - -export interface PersistenceOptions extends PersistenceContextOptions { - loggerFactory: LoggerFactory - migrationsPath?: string - onInit?: (db: Database) => Promise -} +import type { PersistenceContext, PersistenceOptions } from '../Persistence.types' +import type { Logger } from '@streamr/utils' +import { wait } from '@streamr/utils' export class Persistence implements PersistenceContext { private readonly logger: Logger diff --git a/packages/sdk/src/utils/persistence/PersistenceContext.ts b/packages/sdk/src/utils/persistence/PersistenceContext.ts deleted file mode 100644 index fe3b34b202..0000000000 --- a/packages/sdk/src/utils/persistence/PersistenceContext.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { UserID } from '@streamr/utils' - -// TODO: make into abstract base class and define abstract constructor to enforce options? -export interface PersistenceContext { - get(key: string, namespace: string): Promise - set(key: string, value: string, namespace: string): Promise - close(): Promise -} - -export interface PersistenceContextOptions { - ownerId: UserID - namespaces: string[] -} diff --git a/packages/sdk/src/utils/persistence/types.ts b/packages/sdk/src/utils/persistence/types.ts deleted file mode 100644 index b473cd102d..0000000000 --- a/packages/sdk/src/utils/persistence/types.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface Persistence { - get(key: string): Promise - set(key: string, value: string): Promise -} From 6bff8adb6dab43d1b9b57291f490911d14b2da53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Mon, 19 Jan 2026 15:15:54 +0100 Subject: [PATCH 09/53] refactor(sdk): Replace `crypto.randomBytes` with `@noble/post-quantum` Switch from Node.js `crypto.randomBytes` to `@noble/post-quantum/utils` `randomBytes` for browser compatibility across encryption utilities and test files. --- packages/sdk/src/encryption/EncryptionUtil.ts | 2 +- packages/sdk/src/encryption/GroupKey.ts | 6 +++--- packages/sdk/src/encryption/GroupKeyManager.ts | 4 ++-- packages/sdk/test/test-utils/fake/FakeNetworkNode.ts | 4 ++-- packages/sdk/test/test-utils/utils.ts | 4 ++-- packages/sdk/test/unit/GroupKey.test.ts | 6 +++--- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/sdk/src/encryption/EncryptionUtil.ts b/packages/sdk/src/encryption/EncryptionUtil.ts index 7f2231675a..583ec59795 100644 --- a/packages/sdk/src/encryption/EncryptionUtil.ts +++ b/packages/sdk/src/encryption/EncryptionUtil.ts @@ -146,7 +146,7 @@ export class EncryptionUtil { * Returns a hex string without the '0x' prefix. */ static encryptWithAES(data: Uint8Array, cipherKey: CipherKey): Uint8Array { - const iv = crypto.randomBytes(INITIALIZATION_VECTOR_LENGTH) // always need a fresh IV when using CTR mode + const iv = randomBytes(INITIALIZATION_VECTOR_LENGTH) // always need a fresh IV when using CTR mode const cipher = crypto.createCipheriv('aes-256-ctr', cipherKey, iv) return Buffer.concat([iv, cipher.update(data), cipher.final()]) } diff --git a/packages/sdk/src/encryption/GroupKey.ts b/packages/sdk/src/encryption/GroupKey.ts index f52146c6d7..9dda22dbd2 100644 --- a/packages/sdk/src/encryption/GroupKey.ts +++ b/packages/sdk/src/encryption/GroupKey.ts @@ -1,7 +1,7 @@ -import crypto from 'crypto' import { EncryptedGroupKey } from '@streamr/trackerless-network' import { uuid } from '../utils/uuid' import { EncryptionUtil } from './EncryptionUtil' +import { randomBytes } from '@noble/post-quantum/utils' export class GroupKeyError extends Error { public groupKey?: GroupKey @@ -64,8 +64,8 @@ export class GroupKey { } static generate(id = uuid('GroupKey')): GroupKey { - const keyBytes = crypto.randomBytes(32) - return new GroupKey(id, keyBytes) + const keyBytes = randomBytes(32) + return new GroupKey(id, Buffer.from(keyBytes)) } /** @internal */ diff --git a/packages/sdk/src/encryption/GroupKeyManager.ts b/packages/sdk/src/encryption/GroupKeyManager.ts index 1342f076ff..df9e537492 100644 --- a/packages/sdk/src/encryption/GroupKeyManager.ts +++ b/packages/sdk/src/encryption/GroupKeyManager.ts @@ -1,5 +1,5 @@ import { hexToBinary, StreamID, StreamPartID, StreamPartIDUtils, UserID, waitForEvent } from '@streamr/utils' -import crypto from 'crypto' +import { randomBytes } from '@noble/post-quantum/utils' import { Lifecycle, inject, scoped } from 'tsyringe' import { Identity, IdentityInjectionToken } from '../identity/Identity' import { ConfigInjectionToken, type StrictStreamrClientConfig } from '../ConfigTypes' @@ -113,7 +113,7 @@ export class GroupKeyManager { throw new Error('storeKey: storing latest encryption keys for other publishers not supported.') } if (groupKey === undefined) { - const keyData = crypto.randomBytes(32) + const keyData = Buffer.from(randomBytes(32)) groupKey = new GroupKey(uuid('GroupKey'), keyData) } await this.localGroupKeyStore.set(groupKey.id, publisherId, groupKey.data) diff --git a/packages/sdk/test/test-utils/fake/FakeNetworkNode.ts b/packages/sdk/test/test-utils/fake/FakeNetworkNode.ts index 7448718ca0..0479f81172 100644 --- a/packages/sdk/test/test-utils/fake/FakeNetworkNode.ts +++ b/packages/sdk/test/test-utils/fake/FakeNetworkNode.ts @@ -7,7 +7,7 @@ import { ProxyDirection } from '@streamr/trackerless-network' import { MetricsContext, StreamPartID, UserID } from '@streamr/utils' -import crypto from 'crypto' +import { randomBytes } from '@noble/post-quantum/utils' import pull from 'lodash/pull' import { Lifecycle, scoped } from 'tsyringe' import { NetworkNodeFactory, NetworkNodeStub } from '../../../src/NetworkNodeFacade' @@ -26,7 +26,7 @@ export class FakeNetworkNode implements NetworkNodeStub { private readonly network: FakeNetwork constructor(network: FakeNetwork, options: NetworkOptions = {}) { - this.id = toDhtAddress(crypto.randomBytes(10)) + this.id = toDhtAddress(randomBytes(10)) this.options = options this.network = network } diff --git a/packages/sdk/test/test-utils/utils.ts b/packages/sdk/test/test-utils/utils.ts index b38c4db3cb..004eddbf95 100644 --- a/packages/sdk/test/test-utils/utils.ts +++ b/packages/sdk/test/test-utils/utils.ts @@ -15,7 +15,7 @@ import { utf8ToBinary, wait } from '@streamr/utils' -import crypto from 'crypto' +import { randomBytes } from '@noble/post-quantum/utils' import { id, Wallet } from 'ethers' import { once } from 'events' import express, { Request, Response } from 'express' @@ -75,7 +75,7 @@ const getTestName = (module: NodeModule): string => { return (groups !== null) ? groups[1] : moduleFilename } -const randomTestRunId = process.pid ?? crypto.randomBytes(4).toString('hex') +const randomTestRunId = process.pid ?? randomBytes(4).toString('hex') export const createRelativeTestStreamId = (module: NodeModule, suffix?: string): string => { return counterId(`/test/${randomTestRunId}/${getTestName(module)}${(suffix !== undefined) ? '-' + suffix : ''}`, '-') diff --git a/packages/sdk/test/unit/GroupKey.test.ts b/packages/sdk/test/unit/GroupKey.test.ts index 13f7ef6c5d..4cf443f90b 100644 --- a/packages/sdk/test/unit/GroupKey.test.ts +++ b/packages/sdk/test/unit/GroupKey.test.ts @@ -1,4 +1,4 @@ -import crypto from 'crypto' +import { randomBytes } from '@noble/post-quantum/utils' import { GroupKey } from '../../src/encryption/GroupKey' describe('GroupKey', () => { @@ -11,14 +11,14 @@ describe('GroupKey', () => { it('throws if key is the wrong size', () => { expect(() => { - new GroupKey('test', crypto.randomBytes(16)) + new GroupKey('test', Buffer.from(randomBytes(16))) }).toThrow('size') }) it('throws if key is not a buffer', () => { expect(() => { // @ts-expect-error expected error below is desirable, show typecheks working as intended - new GroupKey('test', Array.from(crypto.randomBytes(32))) + new GroupKey('test', Array.from(randomBytes(32))) }).toThrow('Buffer') }) }) From 2d2d42a9d79245779e503d567afc888622085d52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Mon, 19 Jan 2026 15:31:11 +0100 Subject: [PATCH 10/53] refactor(sdk): Use cipheriv utils from `@streamr/utils` --- packages/sdk/src/encryption/EncryptionUtil.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/sdk/src/encryption/EncryptionUtil.ts b/packages/sdk/src/encryption/EncryptionUtil.ts index 583ec59795..81794ce0e3 100644 --- a/packages/sdk/src/encryption/EncryptionUtil.ts +++ b/packages/sdk/src/encryption/EncryptionUtil.ts @@ -1,11 +1,10 @@ -import crypto, { CipherKey } from 'crypto' import { ml_kem1024 } from '@noble/post-quantum/ml-kem' import { randomBytes } from '@noble/post-quantum/utils' import { StreamMessageAESEncrypted } from '../protocol/StreamMessage' import { StreamrClientError } from '../StreamrClientError' import { GroupKey } from './GroupKey' import { AsymmetricEncryptionType } from '@streamr/trackerless-network' -import { binaryToUtf8, getSubtle } from '@streamr/utils' +import { binaryToUtf8, createCipheriv, createDecipheriv, getSubtle } from '@streamr/utils' export const INITIALIZATION_VECTOR_LENGTH = 16 @@ -145,18 +144,18 @@ export class EncryptionUtil { /* * Returns a hex string without the '0x' prefix. */ - static encryptWithAES(data: Uint8Array, cipherKey: CipherKey): Uint8Array { + static encryptWithAES(data: Uint8Array, cipherKey: Uint8Array): Uint8Array { const iv = randomBytes(INITIALIZATION_VECTOR_LENGTH) // always need a fresh IV when using CTR mode - const cipher = crypto.createCipheriv('aes-256-ctr', cipherKey, iv) + const cipher = createCipheriv('aes-256-ctr', cipherKey, iv) return Buffer.concat([iv, cipher.update(data), cipher.final()]) } /* * 'ciphertext' must be a hex string (without '0x' prefix), 'groupKey' must be a GroupKey. Returns a Buffer. */ - static decryptWithAES(cipher: Uint8Array, cipherKey: CipherKey): Buffer { + static decryptWithAES(cipher: Uint8Array, cipherKey: Uint8Array): Buffer { const iv = cipher.slice(0, INITIALIZATION_VECTOR_LENGTH) - const decipher = crypto.createDecipheriv('aes-256-ctr', cipherKey, iv) + const decipher = createDecipheriv('aes-256-ctr', cipherKey, iv) return Buffer.concat([decipher.update(cipher.slice(INITIALIZATION_VECTOR_LENGTH)), decipher.final()]) } From a9a5e8eca6ae8a04f83a84c54a2173629ffd29cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Mon, 19 Jan 2026 19:05:20 +0100 Subject: [PATCH 11/53] Format --- packages/utils/src/browser/crypto.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/utils/src/browser/crypto.ts b/packages/utils/src/browser/crypto.ts index de13cf1715..e674e72840 100644 --- a/packages/utils/src/browser/crypto.ts +++ b/packages/utils/src/browser/crypto.ts @@ -45,7 +45,9 @@ export function createCipheriv( return createCipherivUtil(suite, key, iv) } - throw new TypeError(`Invalid suite type. In browser only AES is supported but got ${algorithm}.`) + throw new TypeError( + `Invalid suite type. In browser only AES is supported but got ${algorithm}.` + ) } export function createDecipheriv( @@ -59,5 +61,7 @@ export function createDecipheriv( return createDecipherivUtil(suite, key, iv) } - throw new TypeError(`Invalid suite type. In browser only AES is supported but got ${algorithm}.`) + throw new TypeError( + `Invalid suite type. In browser only AES is supported but got ${algorithm}.` + ) } From d0eb9e240fcf81d0092bd48936bec601bf6712bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Mon, 19 Jan 2026 19:28:48 +0100 Subject: [PATCH 12/53] feat(utils): Add `publicEncrypt` and `privateDecrypt` --- package-lock.json | 47 +------------------ packages/sdk/src/encryption/EncryptionUtil.ts | 6 +-- packages/utils/package.json | 3 +- packages/utils/rollup.config.mts | 7 +-- packages/utils/src/browser/crypto.ts | 23 +++++++-- packages/utils/src/exports.ts | 2 +- packages/utils/src/nodejs/crypto.ts | 14 ++++++ packages/utils/src/public-encrypt.d.ts | 6 +++ 8 files changed, 47 insertions(+), 61 deletions(-) create mode 100644 packages/utils/src/public-encrypt.d.ts diff --git a/package-lock.json b/package-lock.json index b2671ffe4f..9e9020ca7b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10834,7 +10834,6 @@ "version": "4.10.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, "license": "MIT", "dependencies": { "bn.js": "^4.0.0", @@ -10846,7 +10845,6 @@ "version": "4.12.1", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz", "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==", - "dev": true, "license": "MIT" }, "node_modules/asn1js": { @@ -11306,7 +11304,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true, "license": "MIT" }, "node_modules/body-parser": { @@ -11562,7 +11559,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.1.tgz", "integrity": "sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==", - "dev": true, "license": "MIT", "dependencies": { "bn.js": "^5.2.1", @@ -12112,15 +12108,6 @@ "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", "license": "MIT" }, - "node_modules/charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", - "license": "BSD-3-Clause", - "engines": { - "node": "*" - } - }, "node_modules/check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", @@ -13157,7 +13144,6 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, "license": "MIT", "dependencies": { "cipher-base": "^1.0.3", @@ -13189,15 +13175,6 @@ "node": ">= 8" } }, - "node_modules/crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", - "license": "BSD-3-Clause", - "engines": { - "node": "*" - } - }, "node_modules/crypto-browserify": { "version": "3.12.1", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.1.tgz", @@ -17485,12 +17462,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "license": "MIT" - }, "node_modules/is-bun-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", @@ -20757,17 +20728,6 @@ "node": ">= 0.4" } }, - "node_modules/md5": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", - "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", - "license": "BSD-3-Clause", - "dependencies": { - "charenc": "0.0.2", - "crypt": "0.0.2", - "is-buffer": "~1.1.6" - } - }, "node_modules/md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -23807,7 +23767,6 @@ "version": "5.1.7", "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz", "integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==", - "dev": true, "license": "ISC", "dependencies": { "asn1.js": "^4.10.1", @@ -24073,7 +24032,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, "license": "MIT", "dependencies": { "create-hash": "^1.1.2", @@ -24508,7 +24466,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, "license": "MIT", "dependencies": { "bn.js": "^4.1.0", @@ -24523,7 +24480,6 @@ "version": "4.12.1", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz", "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==", - "dev": true, "license": "MIT" }, "node_modules/pump": { @@ -31308,11 +31264,10 @@ "buffer-shim": "^1.0.1", "eventemitter3": "^5.0.0", "lodash": "^4.17.21", - "md5": "^2.3.0", - "md5.js": "^1.3.5", "path-browserify": "^1.0.1", "pino": "^10.1.0", "pino-pretty": "^13.1.2", + "public-encrypt": "^4.0.3", "readable-stream": "^4.7.0", "secp256k1": "^5.0.1", "sha3": "^2.1.4" diff --git a/packages/sdk/src/encryption/EncryptionUtil.ts b/packages/sdk/src/encryption/EncryptionUtil.ts index 81794ce0e3..b0bb87f5e2 100644 --- a/packages/sdk/src/encryption/EncryptionUtil.ts +++ b/packages/sdk/src/encryption/EncryptionUtil.ts @@ -4,7 +4,7 @@ import { StreamMessageAESEncrypted } from '../protocol/StreamMessage' import { StreamrClientError } from '../StreamrClientError' import { GroupKey } from './GroupKey' import { AsymmetricEncryptionType } from '@streamr/trackerless-network' -import { binaryToUtf8, createCipheriv, createDecipheriv, getSubtle } from '@streamr/utils' +import { binaryToUtf8, createCipheriv, createDecipheriv, getSubtle, privateDecrypt, publicEncrypt } from '@streamr/utils' export const INITIALIZATION_VECTOR_LENGTH = 16 @@ -62,13 +62,13 @@ export class EncryptionUtil { private static encryptWithRSAPublicKey(plaintextBuffer: Uint8Array, publicKey: Uint8Array): Buffer { const keyString = this.toRSAPublicKeyString(publicKey) - const ciphertextBuffer = crypto.publicEncrypt(keyString, plaintextBuffer) + const ciphertextBuffer = publicEncrypt(keyString, plaintextBuffer) return ciphertextBuffer } private static decryptWithRSAPrivateKey(ciphertext: Uint8Array, privateKey: Uint8Array): Buffer { const keyString = this.toRSAPrivateKeyString(privateKey) - return crypto.privateDecrypt(keyString, ciphertext) + return privateDecrypt(keyString, ciphertext) } /** diff --git a/packages/utils/package.json b/packages/utils/package.json index ac268963aa..89bdd4a45e 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -54,11 +54,10 @@ "buffer-shim": "^1.0.1", "eventemitter3": "^5.0.0", "lodash": "^4.17.21", - "md5": "^2.3.0", - "md5.js": "^1.3.5", "path-browserify": "^1.0.1", "pino": "^10.1.0", "pino-pretty": "^13.1.2", + "public-encrypt": "^4.0.3", "readable-stream": "^4.7.0", "secp256k1": "^5.0.1", "sha3": "^2.1.4" diff --git a/packages/utils/rollup.config.mts b/packages/utils/rollup.config.mts index ed7ba94871..42a46931fc 100644 --- a/packages/utils/rollup.config.mts +++ b/packages/utils/rollup.config.mts @@ -106,12 +106,7 @@ function browser(): RollupOptions { }), ], external: [ - /** - * We need to bundle some dependencies in. This will make sure we use the local `md5.js` - * and not the one shipped with `create-hash` (which is outdated and has issues with - * modern bundlers). - */ - /node_modules\/(?!browserify-aes|cipher-base|evp_bytestokey|md5.js|hash-base)/, + /node_modules/, /@streamr\//, ], } diff --git a/packages/utils/src/browser/crypto.ts b/packages/utils/src/browser/crypto.ts index e674e72840..b0fdbcbe48 100644 --- a/packages/utils/src/browser/crypto.ts +++ b/packages/utils/src/browser/crypto.ts @@ -1,12 +1,15 @@ -import md5 from 'md5' import { createCipheriv as createCipherivUtil, createDecipheriv as createDecipherivUtil, } from 'browserify-aes' import aesModes from 'browserify-aes/modes' -import { sha1 } from '@noble/hashes/legacy.js' +import { sha1, md5 } from '@noble/hashes/legacy.js' import type { Transform } from 'readable-stream' import { utf8ToBinary } from '../binaryUtils' +import { + publicEncrypt as publicEncryptUtil, + privateDecrypt as privateDecryptUtil, +} from 'public-encrypt' export function getSubtle(): SubtleCrypto { const { crypto } = globalThis @@ -23,7 +26,7 @@ export function getSubtle(): SubtleCrypto { } export function computeMd5(input: string): Buffer { - return Buffer.from(md5(input), 'hex') + return Buffer.from(md5(utf8ToBinary(input))) } export function computeSha1(input: string): Buffer { @@ -65,3 +68,17 @@ export function createDecipheriv( `Invalid suite type. In browser only AES is supported but got ${algorithm}.` ) } + +export function publicEncrypt( + publicKey: string, + buffer: Buffer | Uint8Array +): Buffer { + return publicEncryptUtil(publicKey, buffer) +} + +export function privateDecrypt( + privateKey: string, + buffer: Buffer | Uint8Array +): Buffer { + return privateDecryptUtil(privateKey, buffer) +} diff --git a/packages/utils/src/exports.ts b/packages/utils/src/exports.ts index 519581734d..5fe2bf1afc 100644 --- a/packages/utils/src/exports.ts +++ b/packages/utils/src/exports.ts @@ -53,6 +53,6 @@ export { type UserID, type UserIDRaw, toUserId, toUserIdRaw, isValidUserId, isEt export type { HexString } from './HexString' export type { ChangeFieldType, MapKey } from './types' export { type WeiAmount, multiplyWeiAmount } from './WeiAmount' -export { getSubtle, computeMd5, computeSha1, createCipheriv, createDecipheriv } from '@/crypto' +export { getSubtle, computeMd5, computeSha1, createCipheriv, createDecipheriv, publicEncrypt, privateDecrypt } from '@/crypto' export { SigningUtil, EcdsaSecp256k1Evm, EcdsaSecp256r1, MlDsa87, type KeyType, KEY_TYPES } from './SigningUtil' export { randomBytes } from '@noble/post-quantum/utils' diff --git a/packages/utils/src/nodejs/crypto.ts b/packages/utils/src/nodejs/crypto.ts index cfeb7c8573..1a254725fe 100644 --- a/packages/utils/src/nodejs/crypto.ts +++ b/packages/utils/src/nodejs/crypto.ts @@ -41,3 +41,17 @@ export function createDecipheriv( ): crypto.Decipheriv { return crypto.createDecipheriv(algorithm, key, iv) } + +export function publicEncrypt( + publicKey: string, + buffer: Buffer | Uint8Array +): Buffer { + return crypto.publicEncrypt(publicKey, buffer) +} + +export function privateDecrypt( + privateKey: string, + buffer: Buffer | Uint8Array +): Buffer { + return crypto.privateDecrypt(privateKey, buffer) +} diff --git a/packages/utils/src/public-encrypt.d.ts b/packages/utils/src/public-encrypt.d.ts new file mode 100644 index 0000000000..c32cfa45f7 --- /dev/null +++ b/packages/utils/src/public-encrypt.d.ts @@ -0,0 +1,6 @@ +declare module 'public-encrypt' { + export function publicEncrypt(key: string, msg: Uint8Array): Buffer + export function privateDecrypt(key: string, enc: Uint8Array): Buffer + export function privateEncrypt(key: string, buf: Uint8Array): Buffer + export function publicDecrypt(key: string, buf: Uint8Array): Buffer +} From dbbdaf3bac7dd6dbf74f82d123c3ada7335bffd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Mon, 19 Jan 2026 19:57:36 +0100 Subject: [PATCH 13/53] refactor(sdk): Extract `RSAKeyPair` creation to environment-specific files --- packages/sdk/src/_browser/createRSAKeyPair.ts | 45 +++++++++++ packages/sdk/src/_nodejs/createRSAKeyPair.ts | 20 +++++ packages/sdk/src/encryption/RSAKeyPair.ts | 81 +------------------ packages/sdk/src/encryption/types.ts | 4 + packages/utils/src/exports.ts | 2 +- 5 files changed, 73 insertions(+), 79 deletions(-) create mode 100644 packages/sdk/src/_browser/createRSAKeyPair.ts create mode 100644 packages/sdk/src/_nodejs/createRSAKeyPair.ts create mode 100644 packages/sdk/src/encryption/types.ts diff --git a/packages/sdk/src/_browser/createRSAKeyPair.ts b/packages/sdk/src/_browser/createRSAKeyPair.ts new file mode 100644 index 0000000000..4196d68f43 --- /dev/null +++ b/packages/sdk/src/_browser/createRSAKeyPair.ts @@ -0,0 +1,45 @@ +import { type CryptoKey, getSubtle } from '@streamr/utils' +import type { PemKeyPair } from '../encryption/types' + +function arrayBufferToString(buffer: ArrayBuffer): string { + return String.fromCharCode.apply(null, [...new Uint8Array(buffer)]) +} + +async function exportCryptoKey( + key: CryptoKey, + { isPrivate = false } = {} +): Promise { + const keyType = isPrivate ? 'pkcs8' : 'spki' + const exported = await getSubtle().exportKey(keyType, key) + const exportedAsString = arrayBufferToString(exported) + const exportedAsBase64 = btoa(exportedAsString) + const TYPE = isPrivate ? 'PRIVATE' : 'PUBLIC' + + return `-----BEGIN ${TYPE} KEY-----\n${exportedAsBase64}\n-----END ${TYPE} KEY-----\n` +} + +export async function createRSAKeyPair( + keyLength: number +): Promise { + const { publicKey, privateKey } = await getSubtle().generateKey( + { + name: 'RSA-OAEP', + modulusLength: keyLength, + publicExponent: new Uint8Array([1, 0, 1]), // 65537 + hash: 'SHA-256', + }, + true, + ['encrypt', 'decrypt'] + ) + + const [exportedPrivate, exportedPublic] = await Promise.all([ + exportCryptoKey(privateKey, { + isPrivate: true, + }), + exportCryptoKey(publicKey, { + isPrivate: false, + }), + ]) + + return { privateKey: exportedPrivate, publicKey: exportedPublic } +} diff --git a/packages/sdk/src/_nodejs/createRSAKeyPair.ts b/packages/sdk/src/_nodejs/createRSAKeyPair.ts new file mode 100644 index 0000000000..305e08d492 --- /dev/null +++ b/packages/sdk/src/_nodejs/createRSAKeyPair.ts @@ -0,0 +1,20 @@ +import crypto from 'crypto' +import { promisify } from 'util' +import type { PemKeyPair } from '../encryption/types' + +export async function createRSAKeyPair(keyLength: number): Promise { + const generateKeyPair = promisify(crypto.generateKeyPair) + const { publicKey, privateKey } = await generateKeyPair('rsa', { + modulusLength: keyLength, + publicKeyEncoding: { + type: 'spki', + format: 'pem', + }, + privateKeyEncoding: { + type: 'pkcs8', + format: 'pem', + }, + }) + + return { privateKey, publicKey } +} diff --git a/packages/sdk/src/encryption/RSAKeyPair.ts b/packages/sdk/src/encryption/RSAKeyPair.ts index 705d9ec5d2..444246db3a 100644 --- a/packages/sdk/src/encryption/RSAKeyPair.ts +++ b/packages/sdk/src/encryption/RSAKeyPair.ts @@ -1,16 +1,7 @@ -/** - * @todo This file contains code for both browser and Node.js environments. Consider - * making it environment-specific (using separate files or conditional exports), and - * remove the following "dom" lib reference when done. - */ -/// - -import crypto from 'crypto' -import { promisify } from 'util' import { KeyExchangeKeyPair } from './KeyExchangeKeyPair' import { AsymmetricEncryptionType } from '@streamr/trackerless-network' -import { utf8ToBinary, getSubtle } from '@streamr/utils' -import type { webcrypto } from 'crypto' +import { utf8ToBinary } from '@streamr/utils' +import { createRSAKeyPair } from '@/createRSAKeyPair' /** * The length of encrypted data determines the minimum length. In StreamrClient we use RSA @@ -20,34 +11,6 @@ import type { webcrypto } from 'crypto' */ export const MIN_KEY_LENGTH = 640 -function ab2str(...args: any[]): string { - // @ts-expect-error Uint8Array parameters - return String.fromCharCode.apply(null, new Uint8Array(...args) as unknown as number[]) -} - -// shim browser btoa for node -function btoa(str: string | Uint8Array): string { - if (global.btoa) { return global.btoa(str as string) } - let buffer - - if (Buffer.isBuffer(str)) { - buffer = str - } else { - buffer = Buffer.from(str.toString(), 'binary') - } - - return buffer.toString('base64') -} - -async function exportCryptoKey(key: webcrypto.CryptoKey, { isPrivate = false } = {}): Promise { - const keyType = isPrivate ? 'pkcs8' : 'spki' - const exported = await getSubtle().exportKey(keyType, key) - const exportedAsString = ab2str(exported) - const exportedAsBase64 = btoa(exportedAsString) - const TYPE = isPrivate ? 'PRIVATE' : 'PUBLIC' - return `-----BEGIN ${TYPE} KEY-----\n${exportedAsBase64}\n-----END ${TYPE} KEY-----\n` -} - export class RSAKeyPair implements KeyExchangeKeyPair { // the keys are in PEM format private readonly privateKey: string @@ -74,45 +37,7 @@ export class RSAKeyPair implements KeyExchangeKeyPair { } static async create(keyLength: number): Promise { - return (typeof window !== 'undefined') - ? RSAKeyPair.create_browserEnvironment(keyLength) - : RSAKeyPair.create_serverEnvironment(keyLength) - } - - private static async create_serverEnvironment(keyLength: number): Promise { - // promisify here to work around browser/server packaging - const generateKeyPair = promisify(crypto.generateKeyPair) - const { publicKey, privateKey } = await generateKeyPair('rsa', { - modulusLength: keyLength, - publicKeyEncoding: { - type: 'spki', - format: 'pem', - }, - privateKeyEncoding: { - type: 'pkcs8', - format: 'pem', - }, - }) - + const { privateKey, publicKey } = await createRSAKeyPair(keyLength) return new RSAKeyPair(privateKey, publicKey) } - - private static async create_browserEnvironment(keyLength: number): Promise { - const { publicKey, privateKey } = await getSubtle().generateKey({ - name: 'RSA-OAEP', - modulusLength: keyLength, - publicExponent: new Uint8Array([1, 0, 1]), // 65537 - hash: 'SHA-256' - }, true, ['encrypt', 'decrypt']) - - const [exportedPrivate, exportedPublic] = await Promise.all([ - exportCryptoKey(privateKey, { - isPrivate: true, - }), - exportCryptoKey(publicKey, { - isPrivate: false, - }) - ]) - return new RSAKeyPair(exportedPrivate, exportedPublic) - } } diff --git a/packages/sdk/src/encryption/types.ts b/packages/sdk/src/encryption/types.ts new file mode 100644 index 0000000000..36355f4100 --- /dev/null +++ b/packages/sdk/src/encryption/types.ts @@ -0,0 +1,4 @@ +export interface PemKeyPair { + privateKey: string + publicKey: string +} diff --git a/packages/utils/src/exports.ts b/packages/utils/src/exports.ts index 5fe2bf1afc..432ec72c91 100644 --- a/packages/utils/src/exports.ts +++ b/packages/utils/src/exports.ts @@ -53,6 +53,6 @@ export { type UserID, type UserIDRaw, toUserId, toUserIdRaw, isValidUserId, isEt export type { HexString } from './HexString' export type { ChangeFieldType, MapKey } from './types' export { type WeiAmount, multiplyWeiAmount } from './WeiAmount' -export { getSubtle, computeMd5, computeSha1, createCipheriv, createDecipheriv, publicEncrypt, privateDecrypt } from '@/crypto' +export { getSubtle, computeMd5, computeSha1, createCipheriv, createDecipheriv, publicEncrypt, privateDecrypt, type CryptoKey, type Jwk } from '@/crypto' export { SigningUtil, EcdsaSecp256k1Evm, EcdsaSecp256r1, MlDsa87, type KeyType, KEY_TYPES } from './SigningUtil' export { randomBytes } from '@noble/post-quantum/utils' From 91bfadd9e3d656cbe9f1271b34e7796e215f71b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Mon, 19 Jan 2026 20:15:21 +0100 Subject: [PATCH 14/53] Swap `stream` to `readable-stream` for browsers --- package-lock.json | 1 + packages/sdk/package.json | 1 + packages/sdk/rollup.config.mts | 1 + packages/sdk/src/utils/WebStreamToNodeStream.ts | 7 +++---- packages/sdk/src/utils/utils.ts | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9e9020ca7b..f0ca475798 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30839,6 +30839,7 @@ "p-limit": "^3.1.0", "p-memoize": "4.0.4", "p-throttle": "4.1.1", + "readable-stream": "^4.7.0", "reflect-metadata": "^0.2.1", "sqlite": "^5.1.1", "sqlite3": "^5.1.7", diff --git a/packages/sdk/package.json b/packages/sdk/package.json index e3be8fb066..5bd6dde011 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -125,6 +125,7 @@ "p-limit": "^3.1.0", "p-memoize": "4.0.4", "p-throttle": "4.1.1", + "readable-stream": "^4.7.0", "reflect-metadata": "^0.2.1", "sqlite": "^5.1.1", "sqlite3": "^5.1.7", diff --git a/packages/sdk/rollup.config.mts b/packages/sdk/rollup.config.mts index 9fe691b1bf..a4077b7a65 100644 --- a/packages/sdk/rollup.config.mts +++ b/packages/sdk/rollup.config.mts @@ -25,6 +25,7 @@ const browserAliases: Alias[] = [ ), }, { find: 'timers', replacement: 'timers-browserify' }, + { find: 'stream', replacement: 'readable-stream' }, ] export default defineConfig([ diff --git a/packages/sdk/src/utils/WebStreamToNodeStream.ts b/packages/sdk/src/utils/WebStreamToNodeStream.ts index 3f152363c0..aa6d3c64a1 100644 --- a/packages/sdk/src/utils/WebStreamToNodeStream.ts +++ b/packages/sdk/src/utils/WebStreamToNodeStream.ts @@ -1,12 +1,11 @@ -import { PassThrough, Readable, TransformOptions } from 'stream' -import WebStream from 'node:stream/web' +import { PassThrough, type Readable, type TransformOptions } from 'stream' import { once } from 'events' /** * Background async task to pull data from the browser stream and push it into the node stream. */ async function pull( - webStream: ReadableStream | WebStream.ReadableStream, + webStream: ReadableStream, nodeStream: PassThrough ): Promise { const reader = webStream.getReader() @@ -63,7 +62,7 @@ async function pull( * Convert browser ReadableStream to Node stream.Readable. */ export function WebStreamToNodeStream( - webStream: ReadableStream | Readable | WebStream.ReadableStream, + webStream: ReadableStream | Readable, nodeStreamOptions?: TransformOptions ): Readable { if ('pipe' in webStream) { diff --git a/packages/sdk/src/utils/utils.ts b/packages/sdk/src/utils/utils.ts index bda80738e7..a91f999ec9 100644 --- a/packages/sdk/src/utils/utils.ts +++ b/packages/sdk/src/utils/utils.ts @@ -5,7 +5,7 @@ import { randomString, toEthereumAddress, toStreamID } from '@streamr/utils' import { ContractTransactionReceipt } from 'ethers' -import { Readable } from 'stream' +import type { Readable } from 'stream' import { LRUCache } from 'lru-cache' import { NetworkNodeType, type NetworkPeerDescriptor, type StrictStreamrClientConfig } from '../ConfigTypes' import { StreamrClientEventEmitter } from '../events' From 2337482581ef5a3f77a0a7825c598007947ed629 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Mon, 19 Jan 2026 20:33:19 +0100 Subject: [PATCH 15/53] refactor(sdk): Use URL for migrations path instead of string Replace migrationsPath with migrationsUrl to use import.meta.url in shared code, avoiding path/url imports. Node.js Persistence converts URL to path using fileURLToPath. --- packages/sdk/src/Persistence.types.ts | 4 ++-- packages/sdk/src/PersistenceManager.ts | 5 +++-- packages/sdk/src/_nodejs/Persistence.ts | 11 ++++++----- .../sdk/test/unit/ServerPersistence.test.ts | 17 ++++++++--------- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/packages/sdk/src/Persistence.types.ts b/packages/sdk/src/Persistence.types.ts index c4380c991a..5b2539f388 100644 --- a/packages/sdk/src/Persistence.types.ts +++ b/packages/sdk/src/Persistence.types.ts @@ -22,12 +22,12 @@ export interface Persistence { /** * Unified options for Persistence.createInstance(). - * Browser implementation ignores Node.js-specific fields (loggerFactory, migrationsPath, onInit). + * Browser implementation ignores Node.js-specific fields (loggerFactory, migrationsUrl, onInit). */ export interface PersistenceOptions { ownerId: UserID namespaces: string[] loggerFactory: LoggerFactory - migrationsPath?: string + migrationsUrl?: URL onInit?: (db: unknown) => Promise } diff --git a/packages/sdk/src/PersistenceManager.ts b/packages/sdk/src/PersistenceManager.ts index f6852a3f00..9fbf9d9288 100644 --- a/packages/sdk/src/PersistenceManager.ts +++ b/packages/sdk/src/PersistenceManager.ts @@ -1,4 +1,5 @@ -import { join } from 'path' +import './setupTsyringe' + import { inject, Lifecycle, scoped } from 'tsyringe' import { Identity, IdentityInjectionToken } from './identity/Identity' import { DestroySignal } from './DestroySignal' @@ -38,7 +39,7 @@ export class PersistenceManager { loggerFactory: this.loggerFactory, ownerId: await this.identity.getUserId(), namespaces: Object.values(NAMESPACES), - migrationsPath: join(__dirname, 'encryption/migrations') // TODO move migrations to some generic place? + migrationsUrl: new URL('./encryption/migrations', import.meta.url) }) } diff --git a/packages/sdk/src/_nodejs/Persistence.ts b/packages/sdk/src/_nodejs/Persistence.ts index 871a400f2b..f57a175180 100644 --- a/packages/sdk/src/_nodejs/Persistence.ts +++ b/packages/sdk/src/_nodejs/Persistence.ts @@ -1,5 +1,6 @@ import envPaths from 'env-paths' import { dirname, resolve, join } from 'path' +import { fileURLToPath } from 'url' import { promises as fs } from 'fs' import { open, type Database } from 'sqlite' import sqlite3 from 'sqlite3' @@ -14,7 +15,7 @@ export class Persistence implements PersistenceContext { private store?: Database private error?: Error private initCalled = false - private readonly migrationsPath?: string + private readonly migrationsUrl?: URL private readonly onInit?: (db: Database) => Promise // uses createInstance factory pattern so that ServerPersistence and BrowserPersistence @@ -30,14 +31,14 @@ export class Persistence implements PersistenceContext { private constructor({ loggerFactory, ownerId, - migrationsPath, + migrationsUrl, onInit }: PersistenceOptions) { this.logger = loggerFactory.createLogger('Persistence') const paths = envPaths('streamr-sdk') // ownerId could be too long for the FS, but unlikely to collide locally - concatenate to first 50 chars this.dbFilePath = resolve(paths.data, join('./', ownerId.substring(0, 50), `GroupKeys.db`)) - this.migrationsPath = migrationsPath + this.migrationsUrl = migrationsUrl this.onInit = onInit this.init = pOnce(this.init.bind(this)) } @@ -93,11 +94,11 @@ export class Persistence implements PersistenceContext { await store.configure('busyTimeout', 200) await store.run('PRAGMA journal_mode = WAL;') }) - if (this.migrationsPath !== undefined) { + if (this.migrationsUrl !== undefined) { await this.tryExec(async () => { try { await store.migrate({ - migrationsPath: this.migrationsPath + migrationsPath: fileURLToPath(this.migrationsUrl!) }) } catch (err) { if (err.code.startsWith('SQLITE_')) { diff --git a/packages/sdk/test/unit/ServerPersistence.test.ts b/packages/sdk/test/unit/ServerPersistence.test.ts index eb611fd113..f01eb7446a 100644 --- a/packages/sdk/test/unit/ServerPersistence.test.ts +++ b/packages/sdk/test/unit/ServerPersistence.test.ts @@ -1,24 +1,23 @@ import { randomUserId, testOnlyInNodeJs } from '@streamr/test-utils' import range from 'lodash/range' -import { join } from 'path' import { Database } from 'sqlite' -import ServerPersistence from '../../src/utils/persistence/ServerPersistence' +import { Persistence } from '../../src/_nodejs/Persistence' import { mockLoggerFactory } from '../test-utils/utils' const NAMESPACE = 'MockTable' -describe('ServerPersistence', () => { +describe('Persistence', () => { - let persistence: ServerPersistence + let persistence: Persistence beforeEach(async () => { const ownerId = randomUserId() - persistence = await ServerPersistence.createInstance({ + persistence = await Persistence.createInstance({ loggerFactory: mockLoggerFactory(), ownerId, namespaces: [NAMESPACE], - onInit: async (db: Database) => { - await db.exec(`CREATE TABLE IF NOT EXISTS ${NAMESPACE} (key_ TEXT NOT NULL PRIMARY KEY, value_ TEXT);`) + onInit: async (db) => { + await (db as Database).exec(`CREATE TABLE IF NOT EXISTS ${NAMESPACE} (key_ TEXT NOT NULL PRIMARY KEY, value_ TEXT);`) } }) }) @@ -57,11 +56,11 @@ describe('ServerPersistence', () => { const instanceCount = 10 const ownerId = randomUserId() const values = await Promise.all(range(instanceCount).map(async (i: number) => { - const instance = await ServerPersistence.createInstance({ + const instance = await Persistence.createInstance({ loggerFactory: mockLoggerFactory(), ownerId, namespaces: ['EncryptionKeys'], - migrationsPath: join(__dirname, '../../src/encryption/migrations') + migrationsUrl: new URL('../../src/encryption/migrations', import.meta.url) }) await instance.set('key', `value${i}`, 'EncryptionKeys') const value = await instance.get('key', 'EncryptionKeys') From b3513104803ea2a5e83c3d8704acd6443970b4af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Mon, 19 Jan 2026 20:38:03 +0100 Subject: [PATCH 16/53] Format --- packages/utils/src/exports.ts | 63 ++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/packages/utils/src/exports.ts b/packages/utils/src/exports.ts index 432ec72c91..40efe4418e 100644 --- a/packages/utils/src/exports.ts +++ b/packages/utils/src/exports.ts @@ -15,7 +15,7 @@ export { MetricsContext, type MetricsDefinition, type MetricsReport, - RateMetric + RateMetric, } from './Metric' export { Multimap } from './Multimap' export { randomString } from './randomString' @@ -28,7 +28,10 @@ export { wait } from './wait' export { waitForEvent } from './waitForEvent' export { raceForEvent } from './raceForEvent' export { TimeoutError, withTimeout } from './withTimeout' -export { composeAbortSignals, type ComposedAbortSignal } from './composeAbortSignals' +export { + composeAbortSignals, + type ComposedAbortSignal, +} from './composeAbortSignals' export { until } from './until' export { withRateLimit } from './withRateLimit' export { ObservableEventEmitter } from './ObservableEventEmitter' @@ -40,19 +43,61 @@ export { Gate } from './Gate' export { TheGraphClient, type GraphQLQuery } from './TheGraphClient' export { Heap } from './Heap' export { executeSafePromise } from './executeSafePromise' -export { binaryToHex, binaryToUtf8, hexToBinary, utf8ToBinary, areEqualBinaries } from './binaryUtils' +export { + binaryToHex, + binaryToUtf8, + hexToBinary, + utf8ToBinary, + areEqualBinaries, +} from './binaryUtils' export { filePathToNodeFormat } from './filePathToNodeFormat' export { retry } from './retry' -export { toLengthPrefixedFrame, LengthPrefixedFrameDecoder } from './lengthPrefixedFrameUtils' +export { + toLengthPrefixedFrame, + LengthPrefixedFrameDecoder, +} from './lengthPrefixedFrameUtils' export { ipv4ToNumber, numberToIpv4 } from './ipv4ToNumber' export { MapWithTtl } from './MapWithTtl' export { type StreamID, toStreamID, StreamIDUtils } from './StreamID' -export { DEFAULT_PARTITION_COUNT, MAX_PARTITION_COUNT, ensureValidStreamPartitionCount, ensureValidStreamPartitionIndex } from './partition' -export { type StreamPartID, toStreamPartID, StreamPartIDUtils } from './StreamPartID' -export { type UserID, type UserIDRaw, toUserId, toUserIdRaw, isValidUserId, isEthereumAddressUserId } from './UserID' +export { + DEFAULT_PARTITION_COUNT, + MAX_PARTITION_COUNT, + ensureValidStreamPartitionCount, + ensureValidStreamPartitionIndex, +} from './partition' +export { + type StreamPartID, + toStreamPartID, + StreamPartIDUtils, +} from './StreamPartID' +export { + type UserID, + type UserIDRaw, + toUserId, + toUserIdRaw, + isValidUserId, + isEthereumAddressUserId, +} from './UserID' export type { HexString } from './HexString' export type { ChangeFieldType, MapKey } from './types' export { type WeiAmount, multiplyWeiAmount } from './WeiAmount' -export { getSubtle, computeMd5, computeSha1, createCipheriv, createDecipheriv, publicEncrypt, privateDecrypt, type CryptoKey, type Jwk } from '@/crypto' -export { SigningUtil, EcdsaSecp256k1Evm, EcdsaSecp256r1, MlDsa87, type KeyType, KEY_TYPES } from './SigningUtil' +export { + getSubtle, + computeMd5, + computeSha1, + createCipheriv, + createDecipheriv, + publicEncrypt, + privateDecrypt, + type CryptoKey, + type Jwk, +} from '@/crypto' +export { + SigningUtil, + EcdsaSecp256k1Evm, + EcdsaSecp256r1, + MlDsa87, + type KeyType, + KEY_TYPES, +} from './SigningUtil' export { randomBytes } from '@noble/post-quantum/utils' From ee5e3b3af1c4add5ee36086524ea0539f0068558 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Mon, 19 Jan 2026 20:56:35 +0100 Subject: [PATCH 17/53] breaking: Stick to named export only --- packages/sdk/src/index.ts | 11 ----------- packages/sdk/test/exports/tests/typescript.ts | 8 +++----- 2 files changed, 3 insertions(+), 16 deletions(-) delete mode 100644 packages/sdk/src/index.ts diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts deleted file mode 100644 index b7bdb10bce..0000000000 --- a/packages/sdk/src/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Streamr JavaScript Client - * - * @packageDocumentation - * @module StreamrClient - */ - -import { StreamrClient } from './StreamrClient' - -export * from './exports' -export default StreamrClient diff --git a/packages/sdk/test/exports/tests/typescript.ts b/packages/sdk/test/exports/tests/typescript.ts index 46bb99dd0f..22ed8cb4a8 100644 --- a/packages/sdk/test/exports/tests/typescript.ts +++ b/packages/sdk/test/exports/tests/typescript.ts @@ -1,15 +1,13 @@ // check ts esm works via tsc -import DefaultExport, * as NamedExports from '@streamr/sdk' +import { StreamrClient, Subscription } from '@streamr/sdk' -console.info('import DefaultExport, * as NamedExports from \'@streamr/sdk\':', { DefaultExport, NamedExports }) +console.info('import { StreamrClient, Subscription } from \'@streamr/sdk\':', { StreamrClient, Subscription }) -const StreamrClient = DefaultExport +console.assert(!!Subscription, 'Named exports should have Subscription') const client = new StreamrClient() - console.assert(!!NamedExports.Subscription, 'NamedExports should have Subscription') - client.connect().then(async () => { console.info('success') await client.destroy() From ca38e650323971ac2e5bc4975fdd766f85a7dd36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Mon, 19 Jan 2026 23:15:30 +0100 Subject: [PATCH 18/53] Fix build; rename "script" bundle The new name matches the pattern. --- packages/sdk/package.json | 2 +- packages/sdk/rollup.config.mts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 5bd6dde011..7c1967ff29 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -10,7 +10,7 @@ "main": "./dist/exports-nodejs.cjs", "module": "./dist/exports-nodejs.js", "types": "./dist/exports-nodejs.d.ts", - "script": "./dist/exports-browser.umd.js", + "script": "./dist/exports-umd.min.js", "exports": { ".": { "types": "./dist/exports-nodejs.d.ts", diff --git a/packages/sdk/rollup.config.mts b/packages/sdk/rollup.config.mts index a4077b7a65..6f5769a8b0 100644 --- a/packages/sdk/rollup.config.mts +++ b/packages/sdk/rollup.config.mts @@ -89,7 +89,7 @@ function nodejs(): RollupOptions { function nodejsTypes(): RollupOptions { return { - input: './dist/nodejs/src/index.d.ts', + input: './dist/nodejs/src/exports.d.ts', output: [{ file: './dist/exports-nodejs.d.ts' }], plugins: [ alias({ @@ -135,7 +135,7 @@ function browser(): RollupOptions { function browserTypes(): RollupOptions { return { - input: './dist/browser/src/index.d.ts', + input: './dist/browser/src/exports.d.ts', output: [{ file: './dist/exports-browser.d.ts' }], plugins: [ alias({ @@ -155,7 +155,7 @@ function umd(): RollupOptions { output: { format: 'umd', name: 'StreamrClient', - file: './dist/streamr-client.umd.js', + file: './dist/exports-umd.js', sourcemap: true, }, plugins: [ @@ -181,7 +181,7 @@ function umdMinified(): RollupOptions { output: { format: 'umd', name: 'StreamrClient', - file: './dist/streamr-client.umd.min.js', + file: './dist/exports-umd.min.js', sourcemap: true, }, plugins: [ From d792d9c1bb6438242cf548587a1c5fe5969c0643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Mon, 19 Jan 2026 23:31:34 +0100 Subject: [PATCH 19/53] Fix missing tsconfig (fixes SDK's build) --- packages/sdk/tsconfig.jest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sdk/tsconfig.jest.json b/packages/sdk/tsconfig.jest.json index 841eae478a..2b5d289bc8 100644 --- a/packages/sdk/tsconfig.jest.json +++ b/packages/sdk/tsconfig.jest.json @@ -25,6 +25,6 @@ "test/exports" ], "references": [ - { "path": "./tsconfig.generated.json" } + { "path": "./tsconfig.node-generated.json" } ] } From b1456b51232200b221abadee81bc4ac4977a0460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Mon, 19 Jan 2026 23:31:57 +0100 Subject: [PATCH 20/53] Re-wire imports (don't import internals via re-exports) --- packages/sdk/src/StreamrClientError.ts | 2 +- packages/sdk/src/contracts/OperatorRegistry.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/sdk/src/StreamrClientError.ts b/packages/sdk/src/StreamrClientError.ts index d401e0293e..daaa0e7aca 100644 --- a/packages/sdk/src/StreamrClientError.ts +++ b/packages/sdk/src/StreamrClientError.ts @@ -1,4 +1,4 @@ -import { StreamMessage } from './exports' +import type { StreamMessage } from './protocol/StreamMessage' import { MessageID } from './protocol/MessageID' export type StreamrClientErrorCode = diff --git a/packages/sdk/src/contracts/OperatorRegistry.ts b/packages/sdk/src/contracts/OperatorRegistry.ts index 56269db5c2..5a649e840b 100644 --- a/packages/sdk/src/contracts/OperatorRegistry.ts +++ b/packages/sdk/src/contracts/OperatorRegistry.ts @@ -1,9 +1,8 @@ -import { Logger, TheGraphClient, GraphQLQuery, EthereumAddress, toEthereumAddress } from '@streamr/utils' +import { Logger, TheGraphClient, GraphQLQuery, EthereumAddress, toEthereumAddress, type StreamID } from '@streamr/utils' import shuffle from 'lodash/shuffle' import { Lifecycle, scoped } from 'tsyringe' import type { NetworkPeerDescriptor } from '../ConfigTypes' import { LoggerFactory } from '../utils/LoggerFactory' -import { StreamID } from '../exports' // TODO maybe this class could be removed/renamed (the method could be extracted to be a function as there is no state) From f1a01c79184ed22476688837ea6c827846e948e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Mon, 19 Jan 2026 23:41:51 +0100 Subject: [PATCH 21/53] Fix usage of the `randomBytes` util --- packages/sdk/test/test-utils/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sdk/test/test-utils/utils.ts b/packages/sdk/test/test-utils/utils.ts index 004eddbf95..b97bf96e77 100644 --- a/packages/sdk/test/test-utils/utils.ts +++ b/packages/sdk/test/test-utils/utils.ts @@ -75,7 +75,7 @@ const getTestName = (module: NodeModule): string => { return (groups !== null) ? groups[1] : moduleFilename } -const randomTestRunId = process.pid ?? randomBytes(4).toString('hex') +const randomTestRunId = process.pid ?? Buffer.from(randomBytes(4)).toString('hex') export const createRelativeTestStreamId = (module: NodeModule, suffix?: string): string => { return counterId(`/test/${randomTestRunId}/${getTestName(module)}${(suffix !== undefined) ? '-' + suffix : ''}`, '-') From a2cfaddaa8d9aa72c58e1d220ac472c89ff73609 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Mon, 19 Jan 2026 23:42:33 +0100 Subject: [PATCH 22/53] Fix imports from (now-gone) sdk's index file No such thing anymore. We follow the pattern of exporting everything from `exports.ts`. --- packages/sdk/test/end-to-end/StreamrClient.test.ts | 2 +- .../sdk/test/end-to-end/erc1271-publish-subscribe.test.ts | 2 +- packages/sdk/test/end-to-end/operatorContractUtils.test.ts | 2 +- packages/sdk/test/end-to-end/publish-subscribe-raw.test.ts | 3 ++- .../sdk/test/end-to-end/sponsorship-created-event.test.ts | 2 +- packages/sdk/test/integration/PublisherKeyExchange.test.ts | 3 ++- packages/sdk/test/integration/SubscriberKeyExchange.test.ts | 2 +- packages/sdk/test/integration/quantum-policy.test.ts | 4 +++- .../sdk/test/test-utils/fake/FakeStreamStorageRegistry.ts | 2 +- packages/sdk/test/unit/SubscriptionSession.test.ts | 2 +- 10 files changed, 14 insertions(+), 10 deletions(-) diff --git a/packages/sdk/test/end-to-end/StreamrClient.test.ts b/packages/sdk/test/end-to-end/StreamrClient.test.ts index 80aebae007..cdbbec9f28 100644 --- a/packages/sdk/test/end-to-end/StreamrClient.test.ts +++ b/packages/sdk/test/end-to-end/StreamrClient.test.ts @@ -1,5 +1,5 @@ import { isRunningInElectron } from '@streamr/test-utils' -import { StreamrClient } from '../../src' +import { StreamrClient } from '../../src/StreamrClient' describe('StreamrClient', () => { let client: StreamrClient diff --git a/packages/sdk/test/end-to-end/erc1271-publish-subscribe.test.ts b/packages/sdk/test/end-to-end/erc1271-publish-subscribe.test.ts index 6d31bf31bb..ae24877b82 100644 --- a/packages/sdk/test/end-to-end/erc1271-publish-subscribe.test.ts +++ b/packages/sdk/test/end-to-end/erc1271-publish-subscribe.test.ts @@ -1,7 +1,7 @@ import { createTestPrivateKey, createTestWallet } from '@streamr/test-utils' import { EthereumAddress, StreamID, areEqualBinaries, toEthereumAddress, until } from '@streamr/utils' import { Wallet } from 'ethers' -import { MessageMetadata } from '../../src' +import type { MessageMetadata } from '../../src/Message' import { StreamrClient } from '../../src/StreamrClient' import { StreamPermission } from '../../src/permission' import { deployTestERC1271Contract } from '../test-utils/deployTestERC1271Contract' diff --git a/packages/sdk/test/end-to-end/operatorContractUtils.test.ts b/packages/sdk/test/end-to-end/operatorContractUtils.test.ts index a65be4ba87..98fbc58718 100644 --- a/packages/sdk/test/end-to-end/operatorContractUtils.test.ts +++ b/packages/sdk/test/end-to-end/operatorContractUtils.test.ts @@ -2,7 +2,7 @@ import { config as CHAIN_CONFIG } from '@streamr/config' import { createTestWallet, describeOnlyInNodeJs } from '@streamr/test-utils' import { Logger, TheGraphClient, until } from '@streamr/utils' import { parseEther } from 'ethers' -import { _operatorContractUtils } from '../../src' +import { _operatorContractUtils } from '../../src/exports' import { createTestClient, createTestStream } from '../test-utils/utils' const createTheGraphClient = (): TheGraphClient => { diff --git a/packages/sdk/test/end-to-end/publish-subscribe-raw.test.ts b/packages/sdk/test/end-to-end/publish-subscribe-raw.test.ts index 1525f16327..ee4a796d43 100644 --- a/packages/sdk/test/end-to-end/publish-subscribe-raw.test.ts +++ b/packages/sdk/test/end-to-end/publish-subscribe-raw.test.ts @@ -6,7 +6,8 @@ import { MessageSigner } from '../../src/signature/MessageSigner' import { Wallet } from 'ethers' import { MessageID } from '../../src/protocol/MessageID' import { ContentType, EncryptionType, SignatureType } from '@streamr/trackerless-network' -import { StreamMessageType, StreamPermission } from '../../src' +import { StreamMessageType } from '../../src/protocol/StreamMessage' +import { StreamPermission } from '../../src/permission' import { createTestWallet } from '@streamr/test-utils' describe('publish-subscribe-raw', () => { diff --git a/packages/sdk/test/end-to-end/sponsorship-created-event.test.ts b/packages/sdk/test/end-to-end/sponsorship-created-event.test.ts index bffedf54a0..e72dc9162e 100644 --- a/packages/sdk/test/end-to-end/sponsorship-created-event.test.ts +++ b/packages/sdk/test/end-to-end/sponsorship-created-event.test.ts @@ -2,7 +2,7 @@ import { createTestWallet } from '@streamr/test-utils' import { Wallet, parseEther } from 'ethers' import { StreamrClient } from '../../src/StreamrClient' import { createTestClient, createTestStream, deployTestSponsorshipContract } from '../test-utils/utils' -import { Stream } from '../../src' +import { Stream } from '../../src/Stream' import { toEthereumAddress, waitForEvent } from '@streamr/utils' import { SponsorshipCreatedEvent } from '../../src/contracts/SponsorshipFactory' diff --git a/packages/sdk/test/integration/PublisherKeyExchange.test.ts b/packages/sdk/test/integration/PublisherKeyExchange.test.ts index 01e907f412..962a69b4ef 100644 --- a/packages/sdk/test/integration/PublisherKeyExchange.test.ts +++ b/packages/sdk/test/integration/PublisherKeyExchange.test.ts @@ -8,7 +8,8 @@ import { FakeEnvironment } from '../test-utils/fake/FakeEnvironment' import { createRelativeTestStreamId, startPublisherKeyExchangeSubscription } from '../test-utils/utils' import { StreamMessage, StreamMessageType } from './../../src/protocol/StreamMessage' import { ContentType, EncryptionType, GroupKeyResponse, SignatureType } from '@streamr/trackerless-network' -import { Stream, StreamrClientConfig } from '../../src' +import { Stream } from '../../src/Stream' +import type { StreamrClientConfig } from '../../src/ConfigTypes' describe('PublisherKeyExchange', () => { diff --git a/packages/sdk/test/integration/SubscriberKeyExchange.test.ts b/packages/sdk/test/integration/SubscriberKeyExchange.test.ts index dc78beac03..36557a5ad4 100644 --- a/packages/sdk/test/integration/SubscriberKeyExchange.test.ts +++ b/packages/sdk/test/integration/SubscriberKeyExchange.test.ts @@ -20,7 +20,7 @@ import { } from '../test-utils/utils' import { StreamMessage, StreamMessageType } from './../../src/protocol/StreamMessage' import { AsymmetricEncryptionType, ContentType, EncryptionType, GroupKeyRequest, SignatureType } from '@streamr/trackerless-network' -import { StreamrClientConfig } from '../../src' +import type { StreamrClientConfig } from '../../src/ConfigTypes' describe('SubscriberKeyExchange', () => { diff --git a/packages/sdk/test/integration/quantum-policy.test.ts b/packages/sdk/test/integration/quantum-policy.test.ts index ca60788572..cbb9911f18 100644 --- a/packages/sdk/test/integration/quantum-policy.test.ts +++ b/packages/sdk/test/integration/quantum-policy.test.ts @@ -4,7 +4,9 @@ import { StreamPermission } from '../../src/permission' import { FakeEnvironment } from '../test-utils/fake/FakeEnvironment' import { Msg } from '../test-utils/publish' import { createTestStream } from '../test-utils/utils' -import { EthereumKeyPairIdentity, Identity, MLDSAKeyPairIdentity } from '../../src' +import { EthereumKeyPairIdentity } from '../../src/identity/EthereumKeyPairIdentity' +import { Identity } from '../../src/identity/Identity' +import { MLDSAKeyPairIdentity } from '../../src/identity/MLDSAKeyPairIdentity' import { collect } from '@streamr/utils' describe('Quantum encryption policies', () => { diff --git a/packages/sdk/test/test-utils/fake/FakeStreamStorageRegistry.ts b/packages/sdk/test/test-utils/fake/FakeStreamStorageRegistry.ts index 8aa032095c..10e9e76b13 100644 --- a/packages/sdk/test/test-utils/fake/FakeStreamStorageRegistry.ts +++ b/packages/sdk/test/test-utils/fake/FakeStreamStorageRegistry.ts @@ -1,7 +1,7 @@ import { Methods } from '@streamr/test-utils' import { EthereumAddress, StreamID } from '@streamr/utils' import { Lifecycle, scoped } from 'tsyringe' -import { StreamMetadata } from '../../../src' +import type { StreamMetadata } from '../../../src/StreamMetadata' import { StreamIDBuilder } from '../../../src/StreamIDBuilder' import { StreamStorageRegistry } from '../../../src/contracts/StreamStorageRegistry' import { FakeChain } from './FakeChain' diff --git a/packages/sdk/test/unit/SubscriptionSession.test.ts b/packages/sdk/test/unit/SubscriptionSession.test.ts index 97cd59468a..fc9a48f998 100644 --- a/packages/sdk/test/unit/SubscriptionSession.test.ts +++ b/packages/sdk/test/unit/SubscriptionSession.test.ts @@ -1,7 +1,7 @@ import { randomEthereumAddress } from '@streamr/test-utils' import { EthereumAddress, toStreamID, toStreamPartID } from '@streamr/utils' import { mock } from 'jest-mock-extended' -import { Subscription } from '../../src' +import { Subscription } from '../../src/subscribe/Subscription' import { NetworkNodeFacade } from '../../src/NetworkNodeFacade' import { MessagePipelineFactory } from '../../src/subscribe/MessagePipelineFactory' import { SubscriptionSession } from '../../src/subscribe/SubscriptionSession' From b674ab7406db73a42ef38f120ebc28217880aa77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Mon, 19 Jan 2026 23:49:52 +0100 Subject: [PATCH 23/53] Bump `@rollup/plugin-commonjs` to the "most common" version --- package-lock.json | 29 +---------------------------- packages/sdk/package.json | 2 +- 2 files changed, 2 insertions(+), 29 deletions(-) diff --git a/package-lock.json b/package-lock.json index f0ca475798..c9be9e43a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30859,7 +30859,7 @@ "@babel/preset-typescript": "^7.28.5", "@jest/globals": "^30.0.5", "@rollup/plugin-alias": "^6.0.0", - "@rollup/plugin-commonjs": "^28.0.6", + "@rollup/plugin-commonjs": "^29.0.0", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.3", "@rollup/plugin-terser": "^0.4.4", @@ -30902,33 +30902,6 @@ "utf-8-validate": "^6.0.5" } }, - "packages/sdk/node_modules/@rollup/plugin-commonjs": { - "version": "28.0.9", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.9.tgz", - "integrity": "sha512-PIR4/OHZ79romx0BVVll/PkwWpJ7e5lsqFa3gFfcrFPWwLXLV39JVUzQV9RKjWerE7B845Hqjj9VYlQeieZ2dA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "commondir": "^1.0.1", - "estree-walker": "^2.0.2", - "fdir": "^6.2.0", - "is-reference": "1.2.1", - "magic-string": "^0.30.3", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=16.0.0 || 14 >= 14.17" - }, - "peerDependencies": { - "rollup": "^2.68.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, "packages/sdk/node_modules/glob": { "version": "13.0.0", "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 7c1967ff29..5363e17eb1 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -64,7 +64,7 @@ "@babel/preset-typescript": "^7.28.5", "@jest/globals": "^30.0.5", "@rollup/plugin-alias": "^6.0.0", - "@rollup/plugin-commonjs": "^28.0.6", + "@rollup/plugin-commonjs": "^29.0.0", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.3", "@rollup/plugin-terser": "^0.4.4", From a4b8494100187f2e27506cf4a681e461c6de97e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Tue, 20 Jan 2026 14:59:28 +0100 Subject: [PATCH 24/53] Let's, after all, inline decorator imports This will cause a "`this` rewritten to `undefined`" warning. All good tho. It'll work. --- packages/sdk/tsconfig.browser.json | 3 --- packages/sdk/tsconfig.node.json | 3 --- 2 files changed, 6 deletions(-) diff --git a/packages/sdk/tsconfig.browser.json b/packages/sdk/tsconfig.browser.json index 828128de4e..46f0bf4679 100644 --- a/packages/sdk/tsconfig.browser.json +++ b/packages/sdk/tsconfig.browser.json @@ -8,9 +8,6 @@ "allowJs": true, - /* Don't emit helpers inline. Import them from tslib instead – key for using tsyringe with rollup. */ - "importHelpers": true, - /* Resolution */ "baseUrl": ".", "paths": { diff --git a/packages/sdk/tsconfig.node.json b/packages/sdk/tsconfig.node.json index 548317fb50..546fd62b93 100644 --- a/packages/sdk/tsconfig.node.json +++ b/packages/sdk/tsconfig.node.json @@ -6,9 +6,6 @@ "experimentalDecorators": true, "emitDecoratorMetadata": true, - /* Don't emit helpers inline. Import them from tslib instead – key for using tsyringe with rollup. */ - "importHelpers": true, - /* Resolution */ "moduleResolution": "bundler", "module": "preserve", From 37cb025491769fa6e8f2ad7a845d0d824f045504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Tue, 20 Jan 2026 15:07:01 +0100 Subject: [PATCH 25/53] Add remaining aliases --- packages/sdk/jest.config.ts | 3 +++ packages/sdk/webpack.config.js | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/sdk/jest.config.ts b/packages/sdk/jest.config.ts index e55af8f288..a83c811ae7 100644 --- a/packages/sdk/jest.config.ts +++ b/packages/sdk/jest.config.ts @@ -10,6 +10,9 @@ const config: Config.InitialOptions = { './test/test-utils/customMatchers.ts', '@streamr/test-utils/setupCustomMatchers', ], + moduleNameMapper: { + "^@/(.*)$": "/src/_nodejs/$1", + }, } export default config diff --git a/packages/sdk/webpack.config.js b/packages/sdk/webpack.config.js index d7005da143..6fcec4e354 100644 --- a/packages/sdk/webpack.config.js +++ b/packages/sdk/webpack.config.js @@ -52,7 +52,9 @@ module.exports = (env, argv) => { ] }, resolve: { - alias: {}, + alias: { + '@': path.resolve(__dirname, 'src/_browser'), + }, fallback: {}, modules: ['node_modules', ...require.resolve.paths('')], extensions: ['.json', '.js', '.ts'], From b3eedef4dedbecfd826a48afd3fde5622f21a39e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Tue, 20 Jan 2026 15:16:26 +0100 Subject: [PATCH 26/53] Don't use import.meta.url (?) Thanks jest! :/ --- packages/sdk/src/PersistenceManager.ts | 2 +- packages/sdk/test/unit/ServerPersistence.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/sdk/src/PersistenceManager.ts b/packages/sdk/src/PersistenceManager.ts index 9fbf9d9288..a72f06bdf3 100644 --- a/packages/sdk/src/PersistenceManager.ts +++ b/packages/sdk/src/PersistenceManager.ts @@ -39,7 +39,7 @@ export class PersistenceManager { loggerFactory: this.loggerFactory, ownerId: await this.identity.getUserId(), namespaces: Object.values(NAMESPACES), - migrationsUrl: new URL('./encryption/migrations', import.meta.url) + migrationsUrl: new URL('./encryption/migrations', `file://${__dirname}/`), }) } diff --git a/packages/sdk/test/unit/ServerPersistence.test.ts b/packages/sdk/test/unit/ServerPersistence.test.ts index f01eb7446a..3e0ac1c99b 100644 --- a/packages/sdk/test/unit/ServerPersistence.test.ts +++ b/packages/sdk/test/unit/ServerPersistence.test.ts @@ -60,7 +60,7 @@ describe('Persistence', () => { loggerFactory: mockLoggerFactory(), ownerId, namespaces: ['EncryptionKeys'], - migrationsUrl: new URL('../../src/encryption/migrations', import.meta.url) + migrationsUrl: new URL('../../src/encryption/migrations', `file://${__dirname}/`), }) await instance.set('key', `value${i}`, 'EncryptionKeys') const value = await instance.get('key', 'EncryptionKeys') From 5eded686384ead5f522f6d0a8883a59ff2edfdf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Tue, 20 Jan 2026 21:39:51 +0100 Subject: [PATCH 27/53] =?UTF-8?q?Fix=20`this`=20=E2=86=92=20`undefined`=20?= =?UTF-8?q?rewrite=20(use=20`globalThis`)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/sdk/rollup.config.mts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/sdk/rollup.config.mts b/packages/sdk/rollup.config.mts index 6f5769a8b0..b5d70b8ec3 100644 --- a/packages/sdk/rollup.config.mts +++ b/packages/sdk/rollup.config.mts @@ -52,6 +52,7 @@ function onwarn(log: RollupLog, rollupWarn: (log: RollupLog) => void): void { function nodejs(): RollupOptions { return { input: './dist/nodejs/src/exports.js', + context: 'globalThis', output: [ { format: 'es', @@ -105,6 +106,7 @@ function nodejsTypes(): RollupOptions { function browser(): RollupOptions { return { input: './dist/browser/src/exports.js', + context: 'globalThis', output: [ { format: 'es', From 94106a9b74ea6d7c0a342dc14d13663b4405dce6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Wed, 21 Jan 2026 11:29:38 +0100 Subject: [PATCH 28/53] Resolve yet another circular dependency --- packages/sdk/src/PersistenceManager.ts | 2 -- packages/sdk/src/setupTsyringe.ts | 11 +++++++++++ packages/sdk/src/subscribe/MessagePipelineFactory.ts | 4 ++-- packages/sdk/src/subscribe/Resends.ts | 5 +++-- packages/sdk/src/subscribe/Subscriber.ts | 7 ++++--- packages/sdk/src/tokens.ts | 3 ++- 6 files changed, 22 insertions(+), 10 deletions(-) diff --git a/packages/sdk/src/PersistenceManager.ts b/packages/sdk/src/PersistenceManager.ts index a72f06bdf3..b8383ba7d0 100644 --- a/packages/sdk/src/PersistenceManager.ts +++ b/packages/sdk/src/PersistenceManager.ts @@ -1,5 +1,3 @@ -import './setupTsyringe' - import { inject, Lifecycle, scoped } from 'tsyringe' import { Identity, IdentityInjectionToken } from './identity/Identity' import { DestroySignal } from './DestroySignal' diff --git a/packages/sdk/src/setupTsyringe.ts b/packages/sdk/src/setupTsyringe.ts index db8a03a93c..29ab31e2ed 100644 --- a/packages/sdk/src/setupTsyringe.ts +++ b/packages/sdk/src/setupTsyringe.ts @@ -4,6 +4,7 @@ import { container, Lifecycle } from 'tsyringe' import { Resends } from './subscribe/Resends' import { Subscriber } from './subscribe/Subscriber' import { Tokens } from './tokens' +import { MessagePipelineFactory } from './subscribe/MessagePipelineFactory' container.register( Tokens.Resends, @@ -24,3 +25,13 @@ container.register( lifecycle: Lifecycle.ContainerScoped, } ) + +container.register( + Tokens.MessagePipelineFactory, + { + useClass: MessagePipelineFactory, + }, + { + lifecycle: Lifecycle.ContainerScoped, + } +) diff --git a/packages/sdk/src/subscribe/MessagePipelineFactory.ts b/packages/sdk/src/subscribe/MessagePipelineFactory.ts index c5c1283660..f0e6ef5af5 100644 --- a/packages/sdk/src/subscribe/MessagePipelineFactory.ts +++ b/packages/sdk/src/subscribe/MessagePipelineFactory.ts @@ -1,6 +1,6 @@ import { StreamID } from '@streamr/utils' import { MarkOptional } from 'ts-essentials' -import { Lifecycle, delay, inject, scoped } from 'tsyringe' +import { delay, inject, injectable } from 'tsyringe' import { ConfigInjectionToken } from '../ConfigTypes' import { DestroySignal } from '../DestroySignal' import { StreamRegistry } from '../contracts/StreamRegistry' @@ -24,7 +24,7 @@ type MessagePipelineFactoryOptions = MarkOptional -@scoped(Lifecycle.ContainerScoped) +@injectable() export class MessagePipelineFactory { private readonly resends: Resends diff --git a/packages/sdk/src/subscribe/Resends.ts b/packages/sdk/src/subscribe/Resends.ts index c2439e788b..9db16b33ac 100644 --- a/packages/sdk/src/subscribe/Resends.ts +++ b/packages/sdk/src/subscribe/Resends.ts @@ -24,7 +24,8 @@ import { LoggerFactory } from '../utils/LoggerFactory' import { pull } from '../utils/PushBuffer' import { PushPipeline } from '../utils/PushPipeline' import { FetchHttpStreamResponseError, createQueryString, fetchLengthPrefixedFrameHttpBinaryStream } from '../utils/utils' -import { MessagePipelineFactory } from './MessagePipelineFactory' +import type { MessagePipelineFactory } from './MessagePipelineFactory' +import { Tokens } from '../tokens' type QueryDict = Record @@ -130,7 +131,7 @@ export class Resends { /* eslint-disable indent */ constructor( @inject(delay(() => StorageNodeRegistry)) storageNodeRegistry: StorageNodeRegistry, - @inject(delay(() => MessagePipelineFactory)) messagePipelineFactory: MessagePipelineFactory, + @inject(Tokens.MessagePipelineFactory) messagePipelineFactory: MessagePipelineFactory, @inject(ConfigInjectionToken) config: StrictStreamrClientConfig, loggerFactory: LoggerFactory ) { diff --git a/packages/sdk/src/subscribe/Subscriber.ts b/packages/sdk/src/subscribe/Subscriber.ts index fbff01b764..60222b7f79 100644 --- a/packages/sdk/src/subscribe/Subscriber.ts +++ b/packages/sdk/src/subscribe/Subscriber.ts @@ -1,10 +1,11 @@ import { EthereumAddress, Logger, StreamPartID } from '@streamr/utils' -import { delay, inject, injectable } from 'tsyringe' +import { inject, injectable } from 'tsyringe' import { NetworkNodeFacade } from '../NetworkNodeFacade' import { LoggerFactory } from '../utils/LoggerFactory' -import { MessagePipelineFactory } from './MessagePipelineFactory' +import type { MessagePipelineFactory } from './MessagePipelineFactory' import { Subscription } from './Subscription' import { SubscriptionSession } from './SubscriptionSession' +import { Tokens } from '../tokens' @injectable() export class Subscriber { @@ -16,7 +17,7 @@ export class Subscriber { constructor( node: NetworkNodeFacade, - @inject(delay(() => MessagePipelineFactory)) messagePipelineFactory: MessagePipelineFactory, + @inject(Tokens.MessagePipelineFactory) messagePipelineFactory: MessagePipelineFactory, loggerFactory: LoggerFactory, ) { this.node = node diff --git a/packages/sdk/src/tokens.ts b/packages/sdk/src/tokens.ts index 51ef874f47..1065414e61 100644 --- a/packages/sdk/src/tokens.ts +++ b/packages/sdk/src/tokens.ts @@ -1,4 +1,5 @@ export const Tokens = { Resends: Symbol('Resends'), - Subscriber: Symbol('Subscriber') + Subscriber: Symbol('Subscriber'), + MessagePipelineFactory: Symbol('MessagePipelineFactory'), } From 41391137b06163229ec533fdfb126f1173e547c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Wed, 21 Jan 2026 11:55:39 +0100 Subject: [PATCH 29/53] Revert "Resolve yet another circular dependency" This reverts commit 1cf013c30a502d329a00da0f4be0b981b6b033fc. --- packages/sdk/src/PersistenceManager.ts | 2 ++ packages/sdk/src/setupTsyringe.ts | 11 ----------- packages/sdk/src/subscribe/MessagePipelineFactory.ts | 4 ++-- packages/sdk/src/subscribe/Resends.ts | 5 ++--- packages/sdk/src/subscribe/Subscriber.ts | 7 +++---- packages/sdk/src/tokens.ts | 3 +-- 6 files changed, 10 insertions(+), 22 deletions(-) diff --git a/packages/sdk/src/PersistenceManager.ts b/packages/sdk/src/PersistenceManager.ts index b8383ba7d0..a72f06bdf3 100644 --- a/packages/sdk/src/PersistenceManager.ts +++ b/packages/sdk/src/PersistenceManager.ts @@ -1,3 +1,5 @@ +import './setupTsyringe' + import { inject, Lifecycle, scoped } from 'tsyringe' import { Identity, IdentityInjectionToken } from './identity/Identity' import { DestroySignal } from './DestroySignal' diff --git a/packages/sdk/src/setupTsyringe.ts b/packages/sdk/src/setupTsyringe.ts index 29ab31e2ed..db8a03a93c 100644 --- a/packages/sdk/src/setupTsyringe.ts +++ b/packages/sdk/src/setupTsyringe.ts @@ -4,7 +4,6 @@ import { container, Lifecycle } from 'tsyringe' import { Resends } from './subscribe/Resends' import { Subscriber } from './subscribe/Subscriber' import { Tokens } from './tokens' -import { MessagePipelineFactory } from './subscribe/MessagePipelineFactory' container.register( Tokens.Resends, @@ -25,13 +24,3 @@ container.register( lifecycle: Lifecycle.ContainerScoped, } ) - -container.register( - Tokens.MessagePipelineFactory, - { - useClass: MessagePipelineFactory, - }, - { - lifecycle: Lifecycle.ContainerScoped, - } -) diff --git a/packages/sdk/src/subscribe/MessagePipelineFactory.ts b/packages/sdk/src/subscribe/MessagePipelineFactory.ts index f0e6ef5af5..c5c1283660 100644 --- a/packages/sdk/src/subscribe/MessagePipelineFactory.ts +++ b/packages/sdk/src/subscribe/MessagePipelineFactory.ts @@ -1,6 +1,6 @@ import { StreamID } from '@streamr/utils' import { MarkOptional } from 'ts-essentials' -import { delay, inject, injectable } from 'tsyringe' +import { Lifecycle, delay, inject, scoped } from 'tsyringe' import { ConfigInjectionToken } from '../ConfigTypes' import { DestroySignal } from '../DestroySignal' import { StreamRegistry } from '../contracts/StreamRegistry' @@ -24,7 +24,7 @@ type MessagePipelineFactoryOptions = MarkOptional -@injectable() +@scoped(Lifecycle.ContainerScoped) export class MessagePipelineFactory { private readonly resends: Resends diff --git a/packages/sdk/src/subscribe/Resends.ts b/packages/sdk/src/subscribe/Resends.ts index 9db16b33ac..c2439e788b 100644 --- a/packages/sdk/src/subscribe/Resends.ts +++ b/packages/sdk/src/subscribe/Resends.ts @@ -24,8 +24,7 @@ import { LoggerFactory } from '../utils/LoggerFactory' import { pull } from '../utils/PushBuffer' import { PushPipeline } from '../utils/PushPipeline' import { FetchHttpStreamResponseError, createQueryString, fetchLengthPrefixedFrameHttpBinaryStream } from '../utils/utils' -import type { MessagePipelineFactory } from './MessagePipelineFactory' -import { Tokens } from '../tokens' +import { MessagePipelineFactory } from './MessagePipelineFactory' type QueryDict = Record @@ -131,7 +130,7 @@ export class Resends { /* eslint-disable indent */ constructor( @inject(delay(() => StorageNodeRegistry)) storageNodeRegistry: StorageNodeRegistry, - @inject(Tokens.MessagePipelineFactory) messagePipelineFactory: MessagePipelineFactory, + @inject(delay(() => MessagePipelineFactory)) messagePipelineFactory: MessagePipelineFactory, @inject(ConfigInjectionToken) config: StrictStreamrClientConfig, loggerFactory: LoggerFactory ) { diff --git a/packages/sdk/src/subscribe/Subscriber.ts b/packages/sdk/src/subscribe/Subscriber.ts index 60222b7f79..fbff01b764 100644 --- a/packages/sdk/src/subscribe/Subscriber.ts +++ b/packages/sdk/src/subscribe/Subscriber.ts @@ -1,11 +1,10 @@ import { EthereumAddress, Logger, StreamPartID } from '@streamr/utils' -import { inject, injectable } from 'tsyringe' +import { delay, inject, injectable } from 'tsyringe' import { NetworkNodeFacade } from '../NetworkNodeFacade' import { LoggerFactory } from '../utils/LoggerFactory' -import type { MessagePipelineFactory } from './MessagePipelineFactory' +import { MessagePipelineFactory } from './MessagePipelineFactory' import { Subscription } from './Subscription' import { SubscriptionSession } from './SubscriptionSession' -import { Tokens } from '../tokens' @injectable() export class Subscriber { @@ -17,7 +16,7 @@ export class Subscriber { constructor( node: NetworkNodeFacade, - @inject(Tokens.MessagePipelineFactory) messagePipelineFactory: MessagePipelineFactory, + @inject(delay(() => MessagePipelineFactory)) messagePipelineFactory: MessagePipelineFactory, loggerFactory: LoggerFactory, ) { this.node = node diff --git a/packages/sdk/src/tokens.ts b/packages/sdk/src/tokens.ts index 1065414e61..51ef874f47 100644 --- a/packages/sdk/src/tokens.ts +++ b/packages/sdk/src/tokens.ts @@ -1,5 +1,4 @@ export const Tokens = { Resends: Symbol('Resends'), - Subscriber: Symbol('Subscriber'), - MessagePipelineFactory: Symbol('MessagePipelineFactory'), + Subscriber: Symbol('Subscriber') } From 9521faaf73a3a90934ab9998a983184f6ae32e03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Wed, 21 Jan 2026 11:56:58 +0100 Subject: [PATCH 30/53] Fix circular dependency by removing redundant tsyringe setup --- packages/sdk/src/PersistenceManager.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/sdk/src/PersistenceManager.ts b/packages/sdk/src/PersistenceManager.ts index a72f06bdf3..b8383ba7d0 100644 --- a/packages/sdk/src/PersistenceManager.ts +++ b/packages/sdk/src/PersistenceManager.ts @@ -1,5 +1,3 @@ -import './setupTsyringe' - import { inject, Lifecycle, scoped } from 'tsyringe' import { Identity, IdentityInjectionToken } from './identity/Identity' import { DestroySignal } from './DestroySignal' From 44dab5ee8e720a5d5b41a746de9b8bac009ef657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Wed, 21 Jan 2026 12:49:55 +0100 Subject: [PATCH 31/53] Properly test Persistance (both browser and node versions) --- packages/sdk/src/Persistence.types.ts | 1 + packages/sdk/src/_browser/Persistence.ts | 5 +++++ .../unit/{ServerPersistence.test.ts => Persistence.test.ts} | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) rename packages/sdk/test/unit/{ServerPersistence.test.ts => Persistence.test.ts} (97%) diff --git a/packages/sdk/src/Persistence.types.ts b/packages/sdk/src/Persistence.types.ts index 5b2539f388..eff0e81ce3 100644 --- a/packages/sdk/src/Persistence.types.ts +++ b/packages/sdk/src/Persistence.types.ts @@ -8,6 +8,7 @@ import { LoggerFactory } from './utils/LoggerFactory' export interface PersistenceContext { get(key: string, namespace: string): Promise set(key: string, value: string, namespace: string): Promise + exists(): Promise close(): Promise } diff --git a/packages/sdk/src/_browser/Persistence.ts b/packages/sdk/src/_browser/Persistence.ts index 9f68bd9a2f..c45dcbf0d8 100644 --- a/packages/sdk/src/_browser/Persistence.ts +++ b/packages/sdk/src/_browser/Persistence.ts @@ -33,6 +33,11 @@ export class Persistence implements PersistenceContext { this.db = db } + // eslint-disable-next-line class-methods-use-this + async exists(): Promise { + throw new Error('Method not implemented in browser Persistence.') + } + async get(key: string, namespace: string): Promise { return this.db.get(namespace, key) } diff --git a/packages/sdk/test/unit/ServerPersistence.test.ts b/packages/sdk/test/unit/Persistence.test.ts similarity index 97% rename from packages/sdk/test/unit/ServerPersistence.test.ts rename to packages/sdk/test/unit/Persistence.test.ts index 3e0ac1c99b..6d4082c693 100644 --- a/packages/sdk/test/unit/ServerPersistence.test.ts +++ b/packages/sdk/test/unit/Persistence.test.ts @@ -1,7 +1,7 @@ import { randomUserId, testOnlyInNodeJs } from '@streamr/test-utils' import range from 'lodash/range' import { Database } from 'sqlite' -import { Persistence } from '../../src/_nodejs/Persistence' +import { Persistence } from '@/Persistence' import { mockLoggerFactory } from '../test-utils/utils' const NAMESPACE = 'MockTable' From 78a89d102fabf501e01e0a6e1af6683335ad90f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Wed, 21 Jan 2026 13:14:07 +0100 Subject: [PATCH 32/53] Fix sdk's karma tests (attempt 0) --- packages/sdk/createKarmaConfig.ts | 43 ++++++++++++++++++++++++ packages/sdk/karma-end-to-end.config.ts | 6 ++-- packages/sdk/karma-integration.config.ts | 6 ++-- packages/sdk/karma-unit.config.ts | 6 ++-- packages/sdk/tsconfig.karma.json | 25 ++++++++++++++ 5 files changed, 74 insertions(+), 12 deletions(-) create mode 100644 packages/sdk/createKarmaConfig.ts create mode 100644 packages/sdk/tsconfig.karma.json diff --git a/packages/sdk/createKarmaConfig.ts b/packages/sdk/createKarmaConfig.ts new file mode 100644 index 0000000000..bc6e50e070 --- /dev/null +++ b/packages/sdk/createKarmaConfig.ts @@ -0,0 +1,43 @@ +import { + createKarmaConfig as createKarmaConfigUtil, + createWebpackConfig, +} from '@streamr/browser-test-runner' +import { resolve } from 'node:path' + +export function createKarmaConfig(testPaths: string[]): ReturnType { + return createKarmaConfigUtil( + testPaths, + createWebpackConfig({ + libraryName: 'sdk', + alias: { + /** + * @todo Our "browser" tests use the Node.js build of DHT package – needed + * for WebSocket/Simulator stuff, but still, very confusing. + */ + '@streamr/dht': resolve( + __dirname, + '../dht/dist/exports-nodejs.cjs' + ), + + '@jest/globals': resolve( + __dirname, + 'test/test-utils/jestGlobalsMock.ts' + ), + '@': resolve(__dirname, 'src/_browser'), + }, + fallback: { + v8: false, + module: false, + }, + externals: { + http: 'HTTP', + ws: 'WebSocket', + 'node-datachannel': 'commonjs node-datachannel', + express: 'Express', + 'node:stream/web': 'stream/web', + 'node:timers/promises': 'timers/promises', + }, + }), + __dirname + ) +} diff --git a/packages/sdk/karma-end-to-end.config.ts b/packages/sdk/karma-end-to-end.config.ts index 4cdf76f6ec..72a5fd5878 100644 --- a/packages/sdk/karma-end-to-end.config.ts +++ b/packages/sdk/karma-end-to-end.config.ts @@ -1,4 +1,2 @@ -import webpackConfig from './webpack-karma.config' -import { createKarmaConfig } from '@streamr/browser-test-runner' - -export default createKarmaConfig(['test/end-to-end/**/*.ts'], webpackConfig, __dirname) +import { createKarmaConfig } from './createKarmaConfig' +export default createKarmaConfig(['test/end-to-end/**/*.ts']) diff --git a/packages/sdk/karma-integration.config.ts b/packages/sdk/karma-integration.config.ts index b2848a6117..bf56bb6b58 100644 --- a/packages/sdk/karma-integration.config.ts +++ b/packages/sdk/karma-integration.config.ts @@ -1,4 +1,2 @@ -import webpackConfig from './webpack-karma.config' -import { createKarmaConfig } from '@streamr/browser-test-runner' - -export default createKarmaConfig(['test/integration/**/*.ts'], webpackConfig, __dirname) +import { createKarmaConfig } from './createKarmaConfig' +export default createKarmaConfig(['test/integration/**/*.ts']) diff --git a/packages/sdk/karma-unit.config.ts b/packages/sdk/karma-unit.config.ts index 907753406d..340f36e1e2 100644 --- a/packages/sdk/karma-unit.config.ts +++ b/packages/sdk/karma-unit.config.ts @@ -1,4 +1,2 @@ -import webpackConfig from './webpack-karma.config' -import { createKarmaConfig } from '@streamr/browser-test-runner' - -export default createKarmaConfig(['test/unit/**/*.ts'], webpackConfig, __dirname) +import { createKarmaConfig } from './createKarmaConfig' +export default createKarmaConfig(['test/unit/**/*.ts']) diff --git a/packages/sdk/tsconfig.karma.json b/packages/sdk/tsconfig.karma.json new file mode 100644 index 0000000000..48eaf139e1 --- /dev/null +++ b/packages/sdk/tsconfig.karma.json @@ -0,0 +1,25 @@ +{ + "extends": "../../tsconfig.karma.json", + "compilerOptions": { + "target": "es2020", + "outDir": "dist/karma", + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "baseUrl": ".", + + /* Mapping */ + "paths": { + "@/*": [ + "src/_browser/*" + ] + } + }, + "include": [ + "src", + "src/**/*.json" + ], + "exclude": [ + "src/generated", + "src/_nodejs" + ] +} From e91ea3b796c5def55af1fe7be7a0bbdef7ec286e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Wed, 21 Jan 2026 13:24:36 +0100 Subject: [PATCH 33/53] Drop sdk's obsolete webpack setup --- package-lock.json | 2076 ++------------------------ packages/sdk/package.json | 24 +- packages/sdk/webpack-karma.config.ts | 25 - packages/sdk/webpack.config.js | 162 -- 4 files changed, 113 insertions(+), 2174 deletions(-) delete mode 100644 packages/sdk/webpack-karma.config.ts delete mode 100644 packages/sdk/webpack.config.js diff --git a/package-lock.json b/package-lock.json index c9be9e43a4..fa52dcf5f5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -822,19 +822,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", - "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.27.3" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-compilation-targets": { "version": "7.27.2", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", @@ -875,83 +862,6 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "license": "ISC" }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz", - "integrity": "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-member-expression-to-functions": "^7.28.5", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/traverse": "^7.28.5", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz", - "integrity": "sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "regexpu-core": "^6.2.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", - "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "debug": "^4.4.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.22.10" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, "node_modules/@babel/helper-globals": { "version": "7.28.0", "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", @@ -961,20 +871,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", - "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.28.5", - "@babel/types": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-module-imports": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", @@ -1005,19 +901,6 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", - "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-plugin-utils": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", @@ -1027,56 +910,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", - "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-wrap-function": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", - "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.27.1", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", - "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-string-parser": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", @@ -1090,1170 +923,91 @@ "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.27.1.tgz", - "integrity": "sha512-NFJK2sHUvrjo8wAU/nQTWU890/zB2jj0qBcCbZbbf+005cAsv6tMjXz31fBign6M5ov1o0Bllu+9nbqkfsjjJQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.27.1", - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", - "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", - "license": "MIT", - "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.5" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz", - "integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", - "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", - "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", - "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/plugin-transform-optional-chaining": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz", - "integrity": "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.28.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.28.0.tgz", - "integrity": "sha512-zOiZqvANjWDUaUS9xMxbMcK/Zccztbe/6ikvUXaG9nsPH3w6qh5UaPGAnirI/WhIbZ8m3OHU0ReyPrknG+ZKeg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-syntax-decorators": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-decorators": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.27.1.tgz", - "integrity": "sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz", - "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", - "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", - "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", - "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", - "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz", - "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-remap-async-to-generator": "^7.27.1", - "@babel/traverse": "^7.28.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", - "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-remap-async-to-generator": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", - "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz", - "integrity": "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", - "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz", - "integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.28.3", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz", - "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-globals": "^7.28.0", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1", - "@babel/traverse": "^7.28.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", - "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/template": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz", - "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz", - "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", - "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz", - "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", - "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-explicit-resource-management": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz", - "integrity": "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.28.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.5.tgz", - "integrity": "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", - "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", - "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", - "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz", - "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", - "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz", - "integrity": "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", - "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", - "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", - "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz", - "integrity": "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5", - "@babel/traverse": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", - "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", - "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", - "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", - "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz", - "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz", - "integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.28.0", - "@babel/plugin-transform-parameters": "^7.27.7", - "@babel/traverse": "^7.28.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", - "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz", - "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz", - "integrity": "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.27.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", - "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", - "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, + "license": "MIT", "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-private-property-in-object": { + "node_modules/@babel/helper-validator-option": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz", - "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", - "dev": true, + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", - "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", - "dev": true, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz", - "integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==", - "dev": true, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" }, "engines": { - "node": ">=6.9.0" + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-regexp-modifiers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz", - "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==", - "dev": true, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", - "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", - "dev": true, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.12.13" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-runtime": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.5.tgz", - "integrity": "sha512-20NUVgOrinudkIBzQ2bNxP08YpKprUkRTiRSd2/Z5GOdPImJGkoN4Z7IQe1T5AdyKI1i5L6RBmluqdSzvaq9/w==", - "dev": true, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "babel-plugin-polyfill-corejs2": "^0.4.14", - "babel-plugin-polyfill-corejs3": "^0.13.0", - "babel-plugin-polyfill-regenerator": "^0.6.5", - "semver": "^6.3.1" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { "node": ">=6.9.0" @@ -2262,21 +1016,10 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { + "node_modules/@babel/plugin-syntax-import-attributes": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", - "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", - "dev": true, + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", + "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -2288,44 +1031,34 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", - "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", - "dev": true, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.10.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", - "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", - "dev": true, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-template-literals": { + "node_modules/@babel/plugin-syntax-jsx": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", - "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", - "dev": true, + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", + "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -2337,186 +1070,85 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", - "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", - "dev": true, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.10.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.5.tgz", - "integrity": "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA==", - "dev": true, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-create-class-features-plugin": "^7.28.5", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/plugin-syntax-typescript": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", - "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", - "dev": true, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.10.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz", - "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==", - "dev": true, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", - "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", - "dev": true, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz", - "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==", - "dev": true, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/preset-env": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.5.tgz", - "integrity": "sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg==", - "dev": true, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.28.5", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-option": "^7.27.1", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", - "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-import-assertions": "^7.27.1", - "@babel/plugin-syntax-import-attributes": "^7.27.1", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.27.1", - "@babel/plugin-transform-async-generator-functions": "^7.28.0", - "@babel/plugin-transform-async-to-generator": "^7.27.1", - "@babel/plugin-transform-block-scoped-functions": "^7.27.1", - "@babel/plugin-transform-block-scoping": "^7.28.5", - "@babel/plugin-transform-class-properties": "^7.27.1", - "@babel/plugin-transform-class-static-block": "^7.28.3", - "@babel/plugin-transform-classes": "^7.28.4", - "@babel/plugin-transform-computed-properties": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.28.5", - "@babel/plugin-transform-dotall-regex": "^7.27.1", - "@babel/plugin-transform-duplicate-keys": "^7.27.1", - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", - "@babel/plugin-transform-dynamic-import": "^7.27.1", - "@babel/plugin-transform-explicit-resource-management": "^7.28.0", - "@babel/plugin-transform-exponentiation-operator": "^7.28.5", - "@babel/plugin-transform-export-namespace-from": "^7.27.1", - "@babel/plugin-transform-for-of": "^7.27.1", - "@babel/plugin-transform-function-name": "^7.27.1", - "@babel/plugin-transform-json-strings": "^7.27.1", - "@babel/plugin-transform-literals": "^7.27.1", - "@babel/plugin-transform-logical-assignment-operators": "^7.28.5", - "@babel/plugin-transform-member-expression-literals": "^7.27.1", - "@babel/plugin-transform-modules-amd": "^7.27.1", - "@babel/plugin-transform-modules-commonjs": "^7.27.1", - "@babel/plugin-transform-modules-systemjs": "^7.28.5", - "@babel/plugin-transform-modules-umd": "^7.27.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", - "@babel/plugin-transform-new-target": "^7.27.1", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", - "@babel/plugin-transform-numeric-separator": "^7.27.1", - "@babel/plugin-transform-object-rest-spread": "^7.28.4", - "@babel/plugin-transform-object-super": "^7.27.1", - "@babel/plugin-transform-optional-catch-binding": "^7.27.1", - "@babel/plugin-transform-optional-chaining": "^7.28.5", - "@babel/plugin-transform-parameters": "^7.27.7", - "@babel/plugin-transform-private-methods": "^7.27.1", - "@babel/plugin-transform-private-property-in-object": "^7.27.1", - "@babel/plugin-transform-property-literals": "^7.27.1", - "@babel/plugin-transform-regenerator": "^7.28.4", - "@babel/plugin-transform-regexp-modifiers": "^7.27.1", - "@babel/plugin-transform-reserved-words": "^7.27.1", - "@babel/plugin-transform-shorthand-properties": "^7.27.1", - "@babel/plugin-transform-spread": "^7.27.1", - "@babel/plugin-transform-sticky-regex": "^7.27.1", - "@babel/plugin-transform-template-literals": "^7.27.1", - "@babel/plugin-transform-typeof-symbol": "^7.27.1", - "@babel/plugin-transform-unicode-escapes": "^7.27.1", - "@babel/plugin-transform-unicode-property-regex": "^7.27.1", - "@babel/plugin-transform-unicode-regex": "^7.27.1", - "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", - "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.14", - "babel-plugin-polyfill-corejs3": "^0.13.0", - "babel-plugin-polyfill-regenerator": "^0.6.5", - "core-js-compat": "^3.43.0", - "semver": "^6.3.1" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { "node": ">=6.9.0" @@ -2525,43 +1157,28 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/preset-env/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.6-no-external-plugins", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", - "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", - "dev": true, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/preset-typescript": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz", - "integrity": "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==", - "dev": true, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", + "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-option": "^7.27.1", - "@babel/plugin-syntax-jsx": "^7.27.1", - "@babel/plugin-transform-modules-commonjs": "^7.27.1", - "@babel/plugin-transform-typescript": "^7.28.5" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -2579,18 +1196,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/runtime-corejs3": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.28.4.tgz", - "integrity": "sha512-h7iEYiW4HebClDEhtvFObtPmIvrd1SSfpI9EhOeKk4CtIK/ngBWFpuhCzhdmRKtg71ylcue+9I6dv54XYO1epQ==", - "license": "MIT", - "dependencies": { - "core-js-pure": "^3.43.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/template": { "version": "7.27.2", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", @@ -2831,16 +1436,6 @@ "node": ">=18" } }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/@electron/get": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", @@ -7229,13 +5824,6 @@ "node": ">=12" } }, - "node_modules/@polka/url": { - "version": "1.0.0-next.28", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", - "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==", - "dev": true, - "license": "MIT" - }, "node_modules/@protobuf-ts/plugin": { "version": "2.11.1", "resolved": "https://registry.npmjs.org/@protobuf-ts/plugin/-/plugin-2.11.1.tgz", @@ -10982,33 +9570,9 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, "peerDependencies": { - "@babel/core": "^7.11.0 || ^8.0.0-0" - } - }, - "node_modules/babel-loader": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-10.0.0.tgz", - "integrity": "sha512-z8jt+EdS61AMw22nSfoNJAZ0vrtmhPRVi6ghL3rCeRZI8cdNYFiV5xeV3HbE7rlZZNmGH8BVccwWt8/ED0QOHA==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^5.0.0" - }, - "engines": { - "node": "^18.20.0 || ^20.10.0 || >=22.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0", - "webpack": ">=5.61.0" + "@babel/core": "^7.11.0 || ^8.0.0-0" } }, - "node_modules/babel-plugin-add-module-exports": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-1.0.4.tgz", - "integrity": "sha512-g+8yxHUZ60RcyaUpfNzy56OtWW+x9cyEe9j+CranqLiqbju2yf/Cy6ZtYK40EZxtrdHllzlVZgLmcOUCTlJ7Jg==", - "dev": true, - "license": "MIT" - }, "node_modules/babel-plugin-istanbul": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", @@ -11040,76 +9604,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", - "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.27.7", - "@babel/helper-define-polyfill-provider": "^0.6.5", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", - "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.5", - "core-js-compat": "^3.43.0" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", - "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.5" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-transform-typescript-metadata": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-typescript-metadata/-/babel-plugin-transform-typescript-metadata-0.4.0.tgz", - "integrity": "sha512-thy3pV6nMurTsjxONcv14/AyWCLY3RoftFQGJSTrhLOToYSVFCQlm2PD6KHK1UqHPKHwRPXgujfUWhrKuVctcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0 || ^8.0.0-0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": false - } - } - }, "node_modules/babel-preset-current-node-syntax": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", @@ -12984,42 +11478,6 @@ "dev": true, "license": "MIT" }, - "node_modules/core-js": { - "version": "3.47.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.47.0.tgz", - "integrity": "sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg==", - "hasInstallScript": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-compat": { - "version": "3.44.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.44.0.tgz", - "integrity": "sha512-JepmAj2zfl6ogy34qfWtcE7nHKAJnKsQFRn++scjVS2bZFllwptzw61BZcZFYBPpUznLfAvh0LGhxKppk04ClA==", - "dev": true, - "license": "MIT", - "dependencies": { - "browserslist": "^4.25.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-pure": { - "version": "3.44.0", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.44.0.tgz", - "integrity": "sha512-gvMQAGB4dfVUxpYD0k3Fq8J+n5bB6Ytl15lqlZrOIXFzxOhtPaObfkQGHtMRdyjIf7z2IeNULwi1jEwyS+ltKQ==", - "hasInstallScript": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -13354,13 +11812,6 @@ "node": "*" } }, - "node_modules/debounce": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", - "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", - "dev": true, - "license": "MIT" - }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -16332,19 +14783,6 @@ "node": ">=0.10.0" } }, - "node_modules/git-revision-webpack-plugin": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/git-revision-webpack-plugin/-/git-revision-webpack-plugin-5.0.0.tgz", - "integrity": "sha512-RptQN/4UKcEPkCBmRy8kLPo5i8MnF8+XfAgFYN9gbwmKLTLx4YHsQw726H+C5+sIGDixDkmGL3IxPA2gKo+u4w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, "node_modules/git-semver-tags": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-5.0.1.tgz", @@ -20300,26 +18738,6 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "license": "MIT" }, - "node_modules/lodash-webpack-plugin": { - "version": "0.11.6", - "resolved": "https://registry.npmjs.org/lodash-webpack-plugin/-/lodash-webpack-plugin-0.11.6.tgz", - "integrity": "sha512-nsHN/+IxZK/C425vGC8pAxkKJ8KQH2+NJnhDul14zYNWr6HJcA95w+oRR7Cp0oZpOdMplDZXmjVROp8prPk7ig==", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash": "^4.17.20" - }, - "peerDependencies": { - "webpack": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.1.0" - } - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true, - "license": "MIT" - }, "node_modules/lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -21706,16 +20124,6 @@ } } }, - "node_modules/mrmime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", - "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -23037,16 +21445,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", - "dev": true, - "license": "(WTFPL OR MIT)", - "bin": { - "opener": "bin/opener-bin.js" - } - }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -25087,26 +23485,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true, - "license": "MIT" - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", - "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", - "dev": true, - "license": "MIT", - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/regexp.prototype.flags": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", @@ -25128,24 +23506,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regexpu-core": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", - "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", - "dev": true, - "license": "MIT", - "dependencies": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.2.0", - "regjsgen": "^0.8.0", - "regjsparser": "^0.12.0", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/registry-auth-token": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.1.0.tgz", @@ -25175,39 +23535,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/regjsparser": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", - "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "jsesc": "~3.0.2" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/reinterval": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", @@ -26302,21 +24629,6 @@ "simple-concat": "^1.0.0" } }, - "node_modules/sirv": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", - "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@polka/url": "^1.0.0-next.24", - "mrmime": "^2.0.0", - "totalist": "^3.0.0" - }, - "engines": { - "node": ">= 10" - } - }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -27958,16 +26270,6 @@ "node": ">=0.6" } }, - "node_modules/totalist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/tough-cookie": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", @@ -28150,37 +26452,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ts-loader": { - "version": "9.5.4", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.4.tgz", - "integrity": "sha512-nCz0rEwunlTZiy6rXFByQU1kVVpCIgUpc/psFiKVrUwrizdnIbRFu8w7bxhUF0X613DYwT4XzrZHpVyMe758hQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4", - "source-map": "^0.7.4" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "typescript": "*", - "webpack": "^5.0.0" - } - }, - "node_modules/ts-loader/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 8" - } - }, "node_modules/ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", @@ -28606,50 +26877,6 @@ "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "license": "MIT" }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", - "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", - "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/unique-filename": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-4.0.0.tgz", @@ -29096,64 +27323,6 @@ } } }, - "node_modules/webpack-bundle-analyzer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-5.0.1.tgz", - "integrity": "sha512-PUp3YFOHysSw8t+13rcF+8o5SGaP/AZ5KnIF3qJfFodv4xJkmixnfcyy+LOwNadpzvyrEKpaMlewAG2sFUfdpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@discoveryjs/json-ext": "0.5.7", - "acorn": "^8.0.4", - "acorn-walk": "^8.0.0", - "commander": "^7.2.0", - "debounce": "^1.2.1", - "escape-string-regexp": "^4.0.0", - "html-escaper": "^2.0.2", - "opener": "^1.5.2", - "picocolors": "^1.0.0", - "sirv": "^2.0.3", - "ws": "^7.3.1" - }, - "bin": { - "webpack-bundle-analyzer": "lib/bin/analyzer.js" - }, - "engines": { - "node": ">= 20.9.0" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/webpack-cli": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-6.0.1.tgz", @@ -30818,8 +28987,6 @@ "version": "103.2.0-experiment.1", "license": "Apache-2.0", "dependencies": { - "@babel/runtime": "^7.28.4", - "@babel/runtime-corejs3": "^7.28.4", "@noble/post-quantum": "^0.4.1", "@protobuf-ts/runtime": "^2.8.2", "@protobuf-ts/runtime-rpc": "^2.8.2", @@ -30829,7 +28996,6 @@ "@streamr/proto-rpc": "103.2.0-experiment.1", "@streamr/trackerless-network": "103.2.0-experiment.1", "@streamr/utils": "103.2.0-experiment.1", - "core-js": "^3.47.0", "env-paths": "^2.2.1", "ethers": "^6.13.0", "eventemitter3": "^5.0.0", @@ -30851,12 +29017,6 @@ "zod": "^4.1.13" }, "devDependencies": { - "@babel/core": "^7.28.5", - "@babel/plugin-proposal-decorators": "^7.28.0", - "@babel/plugin-transform-modules-commonjs": "^7.27.1", - "@babel/plugin-transform-runtime": "^7.28.5", - "@babel/preset-env": "^7.28.5", - "@babel/preset-typescript": "^7.28.5", "@jest/globals": "^30.0.5", "@rollup/plugin-alias": "^6.0.0", "@rollup/plugin-commonjs": "^29.0.0", @@ -30868,34 +29028,22 @@ "@types/lodash": "^4.17.21", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", - "babel-loader": "^10.0.0", - "babel-plugin-add-module-exports": "^1.0.4", - "babel-plugin-transform-typescript-metadata": "^0.4.0", "benchmark": "^2.1.4", "buffer": "^6.0.3", "bytes": "^3.1.1", "chromedriver": "^121.0.2", "express": "^5.2.0", - "git-revision-webpack-plugin": "^5.0.0", "jest-leak-detector": "^27.3.1", "jest-matcher-utils": "^30.0.5", - "lodash-webpack-plugin": "^0.11.6", "nightwatch": "^3.12.3", - "node-polyfill-webpack-plugin": "^4.1.0", "rimraf": "^6.1.2", "rollup": "^4.55.1", "rollup-plugin-copy": "^3.5.0", "rollup-plugin-dts": "^6.3.0", - "terser-webpack-plugin": "^5.3.14", - "ts-loader": "^9.5.4", "ts-node": "^10.9.2", "tsx": "^4.21.0", "util": "^0.12.4", - "weak-napi": "^2.0.2", - "webpack": "^5.103.0", - "webpack-bundle-analyzer": "^5.0.1", - "webpack-cli": "^6.0.1", - "webpack-merge": "^6.0.1" + "weak-napi": "^2.0.2" }, "optionalDependencies": { "bufferutil": "^4.0.9", diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 5363e17eb1..1fa8c5812b 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -56,12 +56,6 @@ "author": "Streamr Network AG ", "license": "Apache-2.0", "devDependencies": { - "@babel/core": "^7.28.5", - "@babel/plugin-proposal-decorators": "^7.28.0", - "@babel/plugin-transform-modules-commonjs": "^7.27.1", - "@babel/plugin-transform-runtime": "^7.28.5", - "@babel/preset-env": "^7.28.5", - "@babel/preset-typescript": "^7.28.5", "@jest/globals": "^30.0.5", "@rollup/plugin-alias": "^6.0.0", "@rollup/plugin-commonjs": "^29.0.0", @@ -73,39 +67,24 @@ "@types/lodash": "^4.17.21", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", - "babel-loader": "^10.0.0", - "babel-plugin-add-module-exports": "^1.0.4", - "babel-plugin-transform-typescript-metadata": "^0.4.0", "benchmark": "^2.1.4", "buffer": "^6.0.3", "bytes": "^3.1.1", "chromedriver": "^121.0.2", "express": "^5.2.0", - "git-revision-webpack-plugin": "^5.0.0", "jest-leak-detector": "^27.3.1", "jest-matcher-utils": "^30.0.5", - "lodash-webpack-plugin": "^0.11.6", "nightwatch": "^3.12.3", - "node-polyfill-webpack-plugin": "^4.1.0", "rimraf": "^6.1.2", "rollup": "^4.55.1", "rollup-plugin-copy": "^3.5.0", "rollup-plugin-dts": "^6.3.0", - "terser-webpack-plugin": "^5.3.14", - "ts-loader": "^9.5.4", "ts-node": "^10.9.2", "tsx": "^4.21.0", "util": "^0.12.4", - "weak-napi": "^2.0.2", - "webpack": "^5.103.0", - "webpack-bundle-analyzer": "^5.0.1", - "webpack-cli": "^6.0.1", - "webpack-merge": "^6.0.1" + "weak-napi": "^2.0.2" }, - "#IMPORTANT": "babel-runtime must be in dependencies, not devDependencies", "dependencies": { - "@babel/runtime": "^7.28.4", - "@babel/runtime-corejs3": "^7.28.4", "@noble/post-quantum": "^0.4.1", "@protobuf-ts/runtime": "^2.8.2", "@protobuf-ts/runtime-rpc": "^2.8.2", @@ -115,7 +94,6 @@ "@streamr/proto-rpc": "103.2.0-experiment.1", "@streamr/trackerless-network": "103.2.0-experiment.1", "@streamr/utils": "103.2.0-experiment.1", - "core-js": "^3.47.0", "env-paths": "^2.2.1", "ethers": "^6.13.0", "eventemitter3": "^5.0.0", diff --git a/packages/sdk/webpack-karma.config.ts b/packages/sdk/webpack-karma.config.ts deleted file mode 100644 index 16856745cf..0000000000 --- a/packages/sdk/webpack-karma.config.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { Configuration } from 'webpack' -import defaultConfig from './webpack.config' -import { resolve } from 'path' - -const karmaWebpackConfig: (env?: Record, argv?: Record) => Configuration = (env = {}, argv = {}) => { - const config = defaultConfig(env, argv) - - return { - ...config, - resolve: { - ...config.resolve, - alias: { - ...config.resolve.alias, - '@jest/globals': resolve(__dirname, 'test/test-utils/jestGlobalsMock.ts') - }, - fallback: { - ...config.resolve.fallback, - v8: false, - 'jest-leak-detector': false, - } - }, - } as Configuration -} - -export default karmaWebpackConfig diff --git a/packages/sdk/webpack.config.js b/packages/sdk/webpack.config.js deleted file mode 100644 index 6fcec4e354..0000000000 --- a/packages/sdk/webpack.config.js +++ /dev/null @@ -1,162 +0,0 @@ -process.env.NODE_ENV = process.env.NODE_ENV || 'development' // set a default NODE_ENV - -const path = require('path') - -const webpack = require('webpack') -const TerserPlugin = require('terser-webpack-plugin') -const { merge } = require('webpack-merge') -const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer') -const { GitRevisionPlugin } = require('git-revision-webpack-plugin') -const NodePolyfillPlugin = require('node-polyfill-webpack-plugin') - -const pkg = require('./package.json') - -const gitRevisionPlugin = new GitRevisionPlugin() - -module.exports = (env, argv) => { - const isProduction = argv?.mode === 'production' || process.env.NODE_ENV === 'production' - - const analyze = !!process.env.BUNDLE_ANALYSIS - - const commonConfig = { - cache: { - type: 'filesystem', - }, - name: 'streamr-sdk', - mode: isProduction ? 'production' : 'development', - entry: { - 'streamr-sdk': path.join(__dirname, 'src', 'exports-browser.ts'), - }, - devtool: 'source-map', - output: { - umdNamedDefine: true, - }, - optimization: { - minimize: false, - moduleIds: 'named', - }, - module: { - rules: [ - { - test: /(\.jsx|\.js|\.ts|\.mts)$/, - exclude: /node_modules/, - use: { - loader: 'babel-loader', - options: { - configFile: path.resolve(__dirname, '.babel.browser.config.js'), - babelrc: false, - cacheDirectory: true, - } - } - } - ] - }, - resolve: { - alias: { - '@': path.resolve(__dirname, 'src/_browser'), - }, - fallback: {}, - modules: ['node_modules', ...require.resolve.paths('')], - extensions: ['.json', '.js', '.ts'], - }, - plugins: [ - gitRevisionPlugin, - new webpack.EnvironmentPlugin({ - NODE_ENV: process.env.NODE_ENV, - version: pkg.version, - GIT_VERSION: gitRevisionPlugin.version(), - GIT_COMMITHASH: gitRevisionPlugin.commithash(), - GIT_BRANCH: gitRevisionPlugin.branch(), - }), - new webpack.optimize.LimitChunkCountPlugin({ - maxChunks: 1 - }) - ], - performance: { - hints: 'warning', - }, - } - - const clientConfig = merge({}, commonConfig, { - target: 'web', - output: { - filename: '[name].web.js', - libraryTarget: 'umd', - library: 'StreamrClient', - // NOTE: - // exporting the class directly - // `export default class StreamrClient {}` - // becomes: - // `window.StreamrClient === StreamrClient` - // which is correct, but if we define the class and export separately, - // which is required if we do interface StreamrClient extends …: - // `class StreamrClient {}; export default StreamrClient;` - // becomes: - // `window.StreamrClient = { default: StreamrClient, … }` - // which is wrong for browser builds. - // see: https://github.com/webpack/webpack/issues/706#issuecomment-438007763 - // libraryExport: 'StreamrClient', // This fixes the above. - globalObject: 'globalThis', - }, - resolve: { - fallback: { - module: false, - } - }, - plugins: [ - new NodePolyfillPlugin({ - additionalAliases: ['process'], - excludeAliases: ['console'], - }), - ...(analyze ? [ - new BundleAnalyzerPlugin({ - analyzerMode: 'static', - openAnalyzer: false, - generateStatsFile: true, - }) - ] : []), - new webpack.ProvidePlugin({ - Buffer: ['buffer', 'Buffer'], - }), - new webpack.NormalModuleReplacementPlugin(/node:/, (resource) => { - const library = resource.request.replace(/^node:/, '') - if (library === 'buffer') { - resource.request = 'buffer' - } else if (library === 'stream/web') { - resource.request = false - } - }) - ], - externals: { - 'express': 'Express', - 'node:stream/web': 'stream/web', - 'node:timers/promises': 'timers/promises' - } - }) - - if (!isProduction) { - return clientConfig - } else { - return merge({}, clientConfig, { - cache: false, - optimization: { - minimize: true, - minimizer: [ - new TerserPlugin({ - parallel: true, - terserOptions: { - ecma: 2018, - output: { - comments: false, - ascii_only: true - } - } - }) - ] - }, - output: { - filename: '[name].web.min.js', - } - }) - } -} From 45ad4d8fdf92b82ed2c7b00db1e2dc928afaf115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Wed, 21 Jan 2026 13:47:50 +0100 Subject: [PATCH 34/53] Incl. the umd build in the package --- packages/sdk/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 1fa8c5812b..ced62705d9 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -29,6 +29,7 @@ "files": [ "dist/exports-nodejs.*", "dist/exports-browser.*", + "dist/exports-umd.*", "dist/encryption/migrations", "!*.tsbuildinfo", "LICENSE", From a476810fbce0606cf178bede7c27f5a94dc9ccda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Wed, 21 Jan 2026 13:59:02 +0100 Subject: [PATCH 35/53] Add `ts-loader` to `browser-test-runner` (it's where it belongs) --- package-lock.json | 32 +++++++++++++++++++++++ packages/browser-test-runner/package.json | 1 + 2 files changed, 33 insertions(+) diff --git a/package-lock.json b/package-lock.json index fa52dcf5f5..49cec0bc7c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26452,6 +26452,37 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ts-loader": { + "version": "9.5.4", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.4.tgz", + "integrity": "sha512-nCz0rEwunlTZiy6rXFByQU1kVVpCIgUpc/psFiKVrUwrizdnIbRFu8w7bxhUF0X613DYwT4XzrZHpVyMe758hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" + } + }, + "node_modules/ts-loader/node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, "node_modules/ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", @@ -28349,6 +28380,7 @@ "rimraf": "^6.1.2", "rollup": "^4.55.1", "rollup-plugin-dts": "^6.3.0", + "ts-loader": "^9.5.4", "tsx": "^4.21.0", "webpack": "^5.103.0", "webpack-cli": "^6.0.1" diff --git a/packages/browser-test-runner/package.json b/packages/browser-test-runner/package.json index 5dee6d7307..25c286a2b3 100644 --- a/packages/browser-test-runner/package.json +++ b/packages/browser-test-runner/package.json @@ -50,6 +50,7 @@ "rimraf": "^6.1.2", "rollup": "^4.55.1", "rollup-plugin-dts": "^6.3.0", + "ts-loader": "^9.5.4", "tsx": "^4.21.0", "webpack": "^5.103.0", "webpack-cli": "^6.0.1" From 3fa22ad2448251ff82505af7bc8c54a9880b94f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Wed, 21 Jan 2026 15:18:49 +0100 Subject: [PATCH 36/53] Fix git info passed to jest --- packages/sdk/jest.setup.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/packages/sdk/jest.setup.ts b/packages/sdk/jest.setup.ts index 952dbb4978..26b1618e93 100644 --- a/packages/sdk/jest.setup.ts +++ b/packages/sdk/jest.setup.ts @@ -1,19 +1,22 @@ -// eslint-disable-next-line import/no-extraneous-dependencies -import { GitRevisionPlugin } from 'git-revision-webpack-plugin' +import { execSync } from 'child_process' import pkg from './package.json' +const execGitCommand = (command: string): string => { + try { + return execSync(command, { encoding: 'utf8' }).trim() + } catch { + return '' + } +} + export default async function setup(): Promise { if (process.env.GIT_VERSION) { return } - const gitRevisionPlugin = new GitRevisionPlugin() - - const [GIT_VERSION, GIT_COMMITHASH, GIT_BRANCH] = await Promise.all([ - gitRevisionPlugin.version(), - gitRevisionPlugin.commithash(), - gitRevisionPlugin.branch(), - ]) + const GIT_VERSION = execGitCommand('git describe --always --tags') + const GIT_COMMITHASH = execGitCommand('git rev-parse HEAD') + const GIT_BRANCH = execGitCommand('git rev-parse --abbrev-ref HEAD') Object.assign(process.env, { version: pkg.version, From d2332a4dae683bfeb2af46f2569206cefdf5cf84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Wed, 21 Jan 2026 17:08:41 +0100 Subject: [PATCH 37/53] Refactor sdk's custom matchers setup --- packages/sdk/jest.config.ts | 2 +- .../sdk/test/test-utils/customMatchers.ts | 38 +++++++++++++------ .../test/test-utils/setupCustomMatchers.ts | 5 +++ 3 files changed, 32 insertions(+), 13 deletions(-) create mode 100644 packages/sdk/test/test-utils/setupCustomMatchers.ts diff --git a/packages/sdk/jest.config.ts b/packages/sdk/jest.config.ts index a83c811ae7..396f2f7ddb 100644 --- a/packages/sdk/jest.config.ts +++ b/packages/sdk/jest.config.ts @@ -7,7 +7,7 @@ const config: Config.InitialOptions = { setupFilesAfterEnv: [ ...defaultConfig.setupFilesAfterEnv, './src/setupTsyringe.ts', - './test/test-utils/customMatchers.ts', + './test/test-utils/setupCustomMatchers.ts', '@streamr/test-utils/setupCustomMatchers', ], moduleNameMapper: { diff --git a/packages/sdk/test/test-utils/customMatchers.ts b/packages/sdk/test/test-utils/customMatchers.ts index f2311fa828..e35c4b5da4 100644 --- a/packages/sdk/test/test-utils/customMatchers.ts +++ b/packages/sdk/test/test-utils/customMatchers.ts @@ -8,18 +8,6 @@ interface PartialStreamrClientError { message?: string } -// we could ES2015 module syntax (https://jestjs.io/docs/expect#expectextendmatchers), -// but the IDE doesn't find custom matchers if we do that -declare global { - // eslint-disable-next-line @typescript-eslint/no-namespace - namespace jest { - interface Matchers { - toThrowStreamrClientError(expectedError: PartialStreamrClientError): R - toEqualStreamrClientError(expectedError: PartialStreamrClientError): R - } - } -} - const formErrorMessage = (field: keyof StreamrClientError, expected: string, actual: string): string => { return `StreamrClientError ${field} values don't match:\nExpected: ${printExpected(expected)}\nReceived: ${printReceived(actual)}` } @@ -97,3 +85,29 @@ expect.extend({ toThrowStreamrClientError, toEqualStreamrClientError }) + +export const customMatchers = { + toThrowStreamrClientError, + toEqualStreamrClientError, +} + +export interface CustomMatchers { + toThrowStreamrClientError(expectedError: PartialStreamrClientError): R + toEqualStreamrClientError(expectedError: PartialStreamrClientError): R +} + +declare global { + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace jest { + // eslint-disable-next-line @typescript-eslint/no-empty-object-type + interface Matchers extends CustomMatchers {} + } +} + +declare module 'expect' { + // eslint-disable-next-line @typescript-eslint/no-empty-object-type + interface AsymmetricMatchers extends CustomMatchers {} + + // eslint-disable-next-line @typescript-eslint/no-empty-object-type + interface Matchers extends CustomMatchers {} +} diff --git a/packages/sdk/test/test-utils/setupCustomMatchers.ts b/packages/sdk/test/test-utils/setupCustomMatchers.ts new file mode 100644 index 0000000000..08300875e5 --- /dev/null +++ b/packages/sdk/test/test-utils/setupCustomMatchers.ts @@ -0,0 +1,5 @@ +import { customMatchers as localCustomMatchers } from './customMatchers' +import { customMatchers } from '@streamr/test-utils' + +expect.extend(localCustomMatchers) +expect.extend(customMatchers) From 73a0bfcd63e14e8e7de0f9442fa1a55cc8d66966 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Wed, 21 Jan 2026 17:08:54 +0100 Subject: [PATCH 38/53] Fix sdk's karma --- packages/sdk/createKarmaConfig.ts | 9 --------- packages/sdk/{karma-setup.js => karma-setup.ts} | 7 ++----- 2 files changed, 2 insertions(+), 14 deletions(-) rename packages/sdk/{karma-setup.js => karma-setup.ts} (50%) diff --git a/packages/sdk/createKarmaConfig.ts b/packages/sdk/createKarmaConfig.ts index bc6e50e070..47e0ffdb5d 100644 --- a/packages/sdk/createKarmaConfig.ts +++ b/packages/sdk/createKarmaConfig.ts @@ -10,15 +10,6 @@ export function createKarmaConfig(testPaths: string[]): ReturnType Date: Wed, 21 Jan 2026 17:38:43 +0100 Subject: [PATCH 39/53] Incl. all custom matchers, also in Karma --- packages/sdk/test/types/global.d.ts | 1 + packages/sdk/tsconfig.karma.json | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/sdk/test/types/global.d.ts b/packages/sdk/test/types/global.d.ts index a0c38efe3f..4f30df8cb4 100644 --- a/packages/sdk/test/types/global.d.ts +++ b/packages/sdk/test/types/global.d.ts @@ -1,2 +1,3 @@ import 'jest-extended' import '@streamr/test-utils/customMatchers' +import '../test-utils/customMatchers' diff --git a/packages/sdk/tsconfig.karma.json b/packages/sdk/tsconfig.karma.json index 48eaf139e1..15c25c4071 100644 --- a/packages/sdk/tsconfig.karma.json +++ b/packages/sdk/tsconfig.karma.json @@ -16,6 +16,7 @@ }, "include": [ "src", + "test/types", "src/**/*.json" ], "exclude": [ From 17a579a56de34f317abfd40e20868a43c4e9a655 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Wed, 21 Jan 2026 17:38:54 +0100 Subject: [PATCH 40/53] Missing casting --- packages/sdk/test/unit/WebStreamToNodeStream.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/sdk/test/unit/WebStreamToNodeStream.test.ts b/packages/sdk/test/unit/WebStreamToNodeStream.test.ts index f4ba0f4fc4..415804e9b1 100644 --- a/packages/sdk/test/unit/WebStreamToNodeStream.test.ts +++ b/packages/sdk/test/unit/WebStreamToNodeStream.test.ts @@ -23,7 +23,7 @@ describeOnlyInNodeJs('WebStreamToNodeStream', () => { } }) - const nodeStream = WebStreamToNodeStream(webStream, { objectMode: true }) + const nodeStream = WebStreamToNodeStream(webStream as ReadableStream, { objectMode: true }) expect(typeof nodeStream.pipe).toBe('function') const received = [] for await (const msg of nodeStream) { @@ -49,7 +49,7 @@ describeOnlyInNodeJs('WebStreamToNodeStream', () => { } }) - const nodeStream = WebStreamToNodeStream(webStream, { objectMode: true, highWaterMark: 1 }) + const nodeStream = WebStreamToNodeStream(webStream as ReadableStream, { objectMode: true, highWaterMark: 1 }) expect(typeof nodeStream.pipe).toBe('function') const received = [] for await (const msg of nodeStream) { @@ -77,7 +77,7 @@ describeOnlyInNodeJs('WebStreamToNodeStream', () => { const err = new Error('expected') const received: any[] = [] - const nodeStream = WebStreamToNodeStream(webStream, { + const nodeStream = WebStreamToNodeStream(webStream as ReadableStream, { objectMode: true, highWaterMark: 1, transform(chunk, _enc, done) { From 9aed209cc2fc1c733326a246e5d8b238b27403fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Wed, 21 Jan 2026 17:39:51 +0100 Subject: [PATCH 41/53] Force karma to use cjs build of DHT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ¯\_(ツ)_/¯ --- packages/sdk/createKarmaConfig.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/sdk/createKarmaConfig.ts b/packages/sdk/createKarmaConfig.ts index 47e0ffdb5d..8c0769f11e 100644 --- a/packages/sdk/createKarmaConfig.ts +++ b/packages/sdk/createKarmaConfig.ts @@ -14,6 +14,7 @@ export function createKarmaConfig(testPaths: string[]): ReturnType Date: Thu, 22 Jan 2026 11:28:15 +0100 Subject: [PATCH 42/53] Update comment for bundled browser dependencies in rollup config --- packages/utils/rollup.config.mts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/utils/rollup.config.mts b/packages/utils/rollup.config.mts index 42a46931fc..1e2925dd7d 100644 --- a/packages/utils/rollup.config.mts +++ b/packages/utils/rollup.config.mts @@ -106,7 +106,12 @@ function browser(): RollupOptions { }), ], external: [ - /node_modules/, + /** + * Bundle certain dependencies to use browser-compatible versions of their + * sub-dependencies (e.g. `readable-stream` for `stream`). This also ensures we + * use up-to-date versions that work with modern bundlers. + */ + /node_modules\/(?!browserify-aes|cipher-base|evp_bytestokey|md5.js|hash-base|public-encrypt|create-hash|parse-asn1|ripemd160)/, /@streamr\//, ], } From 862baa24d7f1bed7f9e50f84877b181a5d2f127b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Thu, 22 Jan 2026 11:29:03 +0100 Subject: [PATCH 43/53] =?UTF-8?q?There's=20no=20`build-browser`=20anymore?= =?UTF-8?q?=20=E2=80=93=20all=20bundles=20at=20once?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- release.sh | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/release.sh b/release.sh index 0af0f24b86..cc9e7b90c2 100755 --- a/release.sh +++ b/release.sh @@ -15,17 +15,6 @@ fi npm run build -# Build sdk webpack bundle -npm run build-browser -w packages/sdk - -if [ $? -ne 0 ] -then - echo - echo 'SDK build failed, did not publish all packages!' - echo - exit 1 -fi - cd packages/utils || exit npm publish --access public --tag $NPM_TAG cd ../.. From 02430d311e78b664baf43528cb0e3cdaafcf9a25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Thu, 22 Jan 2026 12:36:15 +0100 Subject: [PATCH 44/53] Drill to resolve browser-ready modules + custom `randombytes` --- packages/utils/rollup.config.mts | 30 +++++++++++++---------- packages/utils/src/browser/randombytes.ts | 1 + 2 files changed, 18 insertions(+), 13 deletions(-) create mode 100644 packages/utils/src/browser/randombytes.ts diff --git a/packages/utils/rollup.config.mts b/packages/utils/rollup.config.mts index 1e2925dd7d..e12fdc4585 100644 --- a/packages/utils/rollup.config.mts +++ b/packages/utils/rollup.config.mts @@ -40,6 +40,19 @@ const browserAliases: Alias[] = [ find: /^pino$/, replacement: 'pino/browser', }, + { + /** + * Although `randombytes` has a browser build, it uses `global` keyword which + * breaks some bundlers (e.g. Vite). Therefore, we use a custom one. + */ + find: 'randombytes', + replacement: fileURLToPath( + new URL( + './dist/browser/src/browser/randombytes.js', + import.meta.url + ) + ), + }, ] export default defineConfig([ @@ -72,10 +85,7 @@ function nodejs(): RollupOptions { preferBuiltins: true, }), ], - external: [ - /node_modules/, - /@streamr\//, - ], + external: [/node_modules/, /@streamr\//], } } @@ -111,7 +121,7 @@ function browser(): RollupOptions { * sub-dependencies (e.g. `readable-stream` for `stream`). This also ensures we * use up-to-date versions that work with modern bundlers. */ - /node_modules\/(?!browserify-aes|cipher-base|evp_bytestokey|md5.js|hash-base|public-encrypt|create-hash|parse-asn1|ripemd160)/, + /node_modules\/(?!browserify-aes|cipher-base|evp_bytestokey|md5.js|hash-base|public-encrypt|create-hash|parse-asn1|ripemd160|pbkdf2|browserify-rsa)/, /@streamr\//, ], } @@ -132,10 +142,7 @@ function nodejsTypes(): RollupOptions { nodeResolve(), dts(), ], - external: [ - /node_modules/, - /@streamr\//, - ], + external: [/node_modules/, /@streamr\//], } } @@ -157,9 +164,6 @@ function browserTypes(): RollupOptions { }), dts(), ], - external: [ - /node_modules/, - /@streamr\//, - ], + external: [/node_modules/, /@streamr\//], } } diff --git a/packages/utils/src/browser/randombytes.ts b/packages/utils/src/browser/randombytes.ts new file mode 100644 index 0000000000..b75cde0db5 --- /dev/null +++ b/packages/utils/src/browser/randombytes.ts @@ -0,0 +1 @@ +export { randomBytes as default } from '@noble/post-quantum/utils' From c0d18e0356a569933eaceddd326482d0254fb07d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Thu, 22 Jan 2026 13:37:39 +0100 Subject: [PATCH 45/53] Make `generateClientId` `process`-less browser-ready --- packages/sdk/src/utils/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sdk/src/utils/utils.ts b/packages/sdk/src/utils/utils.ts index a91f999ec9..25c9ee5693 100644 --- a/packages/sdk/src/utils/utils.ts +++ b/packages/sdk/src/utils/utils.ts @@ -149,7 +149,7 @@ export function convertPeerDescriptorToNetworkPeerDescriptor(descriptor: PeerDes } export function generateClientId(): string { - return counterId(process.pid ? `${process.pid}` : randomString(4), '/') + return counterId(typeof process !== 'undefined' && process.pid ? `${process.pid}` : randomString(4), '/') } export type LookupKeyType = (string | number | symbol) | (string | number | symbol)[] From 2d3051ec3ccaae4e050930c1385f79df9883469f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Thu, 22 Jan 2026 13:42:46 +0100 Subject: [PATCH 46/53] Let `nightwatch` pick `chromedriver` automatically --- packages/sdk/test/browser-smoke-test/nightwatch.conf.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/sdk/test/browser-smoke-test/nightwatch.conf.js b/packages/sdk/test/browser-smoke-test/nightwatch.conf.js index 0fba357140..a41a51cc0c 100644 --- a/packages/sdk/test/browser-smoke-test/nightwatch.conf.js +++ b/packages/sdk/test/browser-smoke-test/nightwatch.conf.js @@ -1,10 +1,8 @@ -// eslint-disable-next-line @typescript-eslint/no-require-imports -const chromedriver = require('chromedriver') module.exports = { live_output: true, webdriver: { start_process: true, - server_path: chromedriver.path, + server_path: '', cli_args: [ '--verbose' ], From a55dbe03f7881118fd0234a286134adcdf151e04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Thu, 22 Jan 2026 13:42:58 +0100 Subject: [PATCH 47/53] Update smoke tests --- packages/sdk/rollup.config.mts | 2 ++ packages/sdk/test/browser-smoke-test/smoke-test.html | 2 +- packages/sdk/test/browser-smoke-test/smoke-test.sh | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/sdk/rollup.config.mts b/packages/sdk/rollup.config.mts index b5d70b8ec3..183eb3fca3 100644 --- a/packages/sdk/rollup.config.mts +++ b/packages/sdk/rollup.config.mts @@ -159,6 +159,7 @@ function umd(): RollupOptions { name: 'StreamrClient', file: './dist/exports-umd.js', sourcemap: true, + outro: 'window.StreamrClient = window.StreamrClient.StreamrClient;', }, plugins: [ json(), @@ -185,6 +186,7 @@ function umdMinified(): RollupOptions { name: 'StreamrClient', file: './dist/exports-umd.min.js', sourcemap: true, + outro: 'window.StreamrClient = window.StreamrClient.StreamrClient;', }, plugins: [ json(), diff --git a/packages/sdk/test/browser-smoke-test/smoke-test.html b/packages/sdk/test/browser-smoke-test/smoke-test.html index 3b7dd43ce8..5e5743fa41 100644 --- a/packages/sdk/test/browser-smoke-test/smoke-test.html +++ b/packages/sdk/test/browser-smoke-test/smoke-test.html @@ -3,7 +3,7 @@ Smoke Test - + + ``` #### Browser extension diff --git a/packages/sdk/README.md b/packages/sdk/README.md index 1acfba1062..d6118a7575 100644 --- a/packages/sdk/README.md +++ b/packages/sdk/README.md @@ -41,7 +41,7 @@ The Streamr SDK is built for the browser and Node.js environments. **Browser (Website/WebApps)** - For usage in the browser include the latest build, e.g. by including a `` +- `` - To use within React, please see [streamr-client-react](https://github.com/streamr-dev/streamr-client-react) **Browser extension** From 7730264515b749d4e22aa854a9b667a4bfc486c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Fri, 23 Jan 2026 15:24:36 +0100 Subject: [PATCH 51/53] Remove empty chromedriver path Both work but empty string is confusing. --- packages/sdk/test/browser-smoke-test/nightwatch.conf.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/sdk/test/browser-smoke-test/nightwatch.conf.js b/packages/sdk/test/browser-smoke-test/nightwatch.conf.js index a41a51cc0c..13ab37033b 100644 --- a/packages/sdk/test/browser-smoke-test/nightwatch.conf.js +++ b/packages/sdk/test/browser-smoke-test/nightwatch.conf.js @@ -2,7 +2,6 @@ module.exports = { live_output: true, webdriver: { start_process: true, - server_path: '', cli_args: [ '--verbose' ], From a0ca39376d11a88b55623db1873223db0f4b503c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Fri, 23 Jan 2026 15:59:42 +0100 Subject: [PATCH 52/53] Explain packages bundled directly into browser build of `@streamr/utils` --- package-lock.json | 85 +++++++++++++++++++++++++++----- packages/utils/package.json | 1 + packages/utils/rollup.config.mts | 81 ++++++++++++++++++++++++++---- 3 files changed, 145 insertions(+), 22 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6c41576a2f..3c9949164a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9512,7 +9512,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" @@ -10422,7 +10421,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.0", @@ -11445,7 +11443,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true, "license": "MIT" }, "node_modules/cors": { @@ -11964,7 +11961,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", @@ -14190,7 +14186,6 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", - "dev": true, "license": "MIT", "dependencies": { "is-callable": "^1.2.7" @@ -15048,7 +15043,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" @@ -15867,7 +15861,6 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -16300,7 +16293,6 @@ "version": "1.1.15", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", - "dev": true, "license": "MIT", "dependencies": { "which-typed-array": "^1.1.16" @@ -16394,7 +16386,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true, "license": "MIT" }, "node_modules/isbinaryfile": { @@ -22538,7 +22529,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -24289,7 +24279,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", @@ -26144,6 +26133,20 @@ "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "license": "BSD-3-Clause" }, + "node_modules/to-buffer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", + "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", + "license": "MIT", + "dependencies": { + "isarray": "^2.0.5", + "safe-buffer": "^5.2.1", + "typed-array-buffer": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -26609,7 +26612,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -27562,7 +27564,6 @@ "version": "1.1.19", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", - "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", @@ -29312,6 +29313,7 @@ "buffer": "^6.0.3", "buffer-shim": "^1.0.1", "eventemitter3": "^5.0.0", + "hash-base": "^3.1.2", "lodash": "^4.17.21", "path-browserify": "^1.0.1", "pino": "^10.1.0", @@ -29385,6 +29387,48 @@ "url": "https://github.com/sponsors/isaacs" } }, + "packages/utils/node_modules/hash-base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.2.tgz", + "integrity": "sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^2.3.8", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "packages/utils/node_modules/hash-base/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "packages/utils/node_modules/hash-base/node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "packages/utils/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, "packages/utils/node_modules/minimatch": { "version": "10.1.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", @@ -29447,6 +29491,21 @@ "funding": { "url": "https://github.com/sponsors/isaacs" } + }, + "packages/utils/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "packages/utils/node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" } } } diff --git a/packages/utils/package.json b/packages/utils/package.json index fe5ea3d9a2..8f50485760 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -54,6 +54,7 @@ "buffer": "^6.0.3", "buffer-shim": "^1.0.1", "eventemitter3": "^5.0.0", + "hash-base": "^3.1.2", "lodash": "^4.17.21", "path-browserify": "^1.0.1", "pino": "^10.1.0", diff --git a/packages/utils/rollup.config.mts b/packages/utils/rollup.config.mts index e12fdc4585..0d2d1edf18 100644 --- a/packages/utils/rollup.config.mts +++ b/packages/utils/rollup.config.mts @@ -15,6 +15,67 @@ const nodejsAliases: Alias[] = [ }, ] +/** + * Dependencies to bundle for browser builds. These need browser-compatible versions of their + * sub-dependencies (e.g. `readable-stream` for `stream`). Bundling also ensures we use up-to-date + * versions that work with modern bundlers. + */ +const bundledBrowserDeps = [ + /** + * Unwrap `browserify-aes` to get to `cipher-base`, `create-hash`, `evp_bytestokey`. + */ + 'browserify-aes', + + /** + * Unwrap `public-encrypt` to get to `browserify-rsa`, `create-hash`, `parse-asn1`, + * `randombytes`. + */ + 'public-encrypt', + + /** + * Unwrap `browserify-rsa` to get to `randombytes`. + */ + 'browserify-rsa', + + /** + * Unwrap `parse-asn1` to get to `asn1.js`, `browserify-aes`, `evp_bytestokey`, `pbkdf2`. + */ + 'parse-asn1', + + /** + * Unwrap `pbkdf2` to get to `create-hash`, `ripemd160`. + */ + 'pbkdf2', + + /** + * Unwrap `evp_bytestokey` to get to `md5.js`. + */ + 'evp_bytestokey', + + /** + * Unwrap `create-hash` to get to `cipher-base`, `md5.js`, `ripemd160`. + */ + 'create-hash', + + /** + * Unwrap `md5.js` and 'ripemd160' to get to `hash-base`. + */ + 'md5.js', + + /** + * Unwrap `cipher-base` to get to Node's `stream` used inside. For browser builds, we want + * to swap it to `readable-stream` instead. + */ + 'cipher-base', + + /** + * Additionally, we + * - use custom implementation of `randombytes` for browser (see alias below), + * - install `asn1.js` and `hash-base` as backward compatible direct dependencies to ensure + * we have browser-compatible versions. + */ +] + const browserAliases: Alias[] = [ { find: /^@\//, @@ -115,15 +176,17 @@ function browser(): RollupOptions { preferBuiltins: false, }), ], - external: [ - /** - * Bundle certain dependencies to use browser-compatible versions of their - * sub-dependencies (e.g. `readable-stream` for `stream`). This also ensures we - * use up-to-date versions that work with modern bundlers. - */ - /node_modules\/(?!browserify-aes|cipher-base|evp_bytestokey|md5.js|hash-base|public-encrypt|create-hash|parse-asn1|ripemd160|pbkdf2|browserify-rsa)/, - /@streamr\//, - ], + external: (id: string) => { + if (/@streamr\//.test(id)) { + return true + } + if (id.includes('node_modules')) { + return !bundledBrowserDeps.some((dep) => + id.includes(`node_modules/${dep}`) + ) + } + return false + }, } } From 56c211ec8071df22821e1e1eff4c19076293c877 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Roli=C5=84ski?= Date: Fri, 23 Jan 2026 16:07:29 +0100 Subject: [PATCH 53/53] Missed `ripemd160` --- packages/utils/rollup.config.mts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/utils/rollup.config.mts b/packages/utils/rollup.config.mts index 0d2d1edf18..89c4648297 100644 --- a/packages/utils/rollup.config.mts +++ b/packages/utils/rollup.config.mts @@ -61,6 +61,7 @@ const bundledBrowserDeps = [ * Unwrap `md5.js` and 'ripemd160' to get to `hash-base`. */ 'md5.js', + 'ripemd160', /** * Unwrap `cipher-base` to get to Node's `stream` used inside. For browser builds, we want