better support for Node.js ESM

This commit is contained in:
Juanra Dikal 2022-08-01 04:19:48 +02:00
parent 76a446070b
commit 995b7b64cb
29 changed files with 1689 additions and 2225 deletions

View File

@ -1,6 +1,6 @@
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
[![build](https://github.com/juanelas/bigint-crypto-utils/workflows/build/badge.svg)](https://github.com/juanelas/bigint-crypto-utils/actions?query=workflow%3A%22build%22)
[![Node.js CI](https://github.com/juanelas/bigint-crypto-utils/workflows/build/badge.svg)](https://github.com/juanelas/bigint-crypto-utils/actions?query=workflow%3A%22build%22)
[![Coverage Status](https://coveralls.io/repos/github/juanelas/bigint-crypto-utils/badge.svg?branch=master)](https://coveralls.io/github/juanelas/bigint-crypto-utils?branch=master)
# bigint-crypto-utils
@ -46,7 +46,7 @@ The appropriate version for browser or node is automatically exported.
> 1. If you experience issues using webpack/babel to create your production bundles, you may edit the supported browsers list and leave only [supported browsers and versions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#Browser_compatibility). The browsers list is usually located in your project's `package.json` or the `.browserslistrc` file.
> 2. In order to use `bigint-crypto-utils` with TypeScript you need to set `target`, and `lib` and `module` if in use, to `ES2020` in your project's `tsconfig.json`.
You can also download the [IIFE bundle](https://raw.githubusercontent.com/juanelas/bigint-crypto-utils/master/dist/bundles/iife.js), the [ESM bundle](https://raw.githubusercontent.com/juanelas/bigint-crypto-utils/master/dist/bundles/esm.js) or the [UMD bundle](https://raw.githubusercontent.com/juanelas/bigint-crypto-utils/master/dist/bundles/umd.js) and manually add it to your project, or, if you have already installed `bigint-crypto-utils` in your project, just get the bundles from `node_modules/bigint-crypto-utils/dist/bundles/`.
You can also download the [IIFE bundle](https://raw.githubusercontent.com/juanelas/bigint-crypto-utils/master/dist/bundles/iife.js), the [ESM bundle](https://raw.githubusercontent.com/juanelas/bigint-crypto-utils/master/dist/bundles/esm.min.js) or the [UMD bundle](https://raw.githubusercontent.com/juanelas/bigint-crypto-utils/master/dist/bundles/umd.js) and manually add it to your project, or, if you have already installed `bigint-crypto-utils` in your project, just get the bundles from `node_modules/bigint-crypto-utils/dist/bundles/`.
An example of usage could be (complete examples can be found in the [examples](https://github.com/juanelas/bigint-crypto-utils/tree/master/examples) directory):

View File

@ -13,10 +13,12 @@ const glob = require('glob')
const processedArgs = processArgs(process.argv.slice(2))
// Now we can run a script and invoke a callback when complete, e.g.
runScript(path.join(rootDir, 'node_modules/.bin/mocha'), processArgs(processedArgs))
runScript(path.join(rootDir, 'node_modules/mocha/bin/mocha'), processedArgs)
function processArgs (args) {
args = process.argv.slice(2).map(arg => {
// Let us first remove surrounding quotes in string (it gives issues in windows)
arg = arg.replace(/^['"]/, '').replace(/['"]$/, '')
const filenames = glob.sync(arg, { cwd: rootDir, matchBase: true })
if (filenames.length > 0) {
return filenames.map(file => {
@ -56,7 +58,7 @@ function processArgs (args) {
}
function runScript (scriptPath, args) {
const mochaCmd = childProcess.fork(path.join(rootDir, 'node_modules/.bin/mocha'), processedArgs, {
const mochaCmd = childProcess.fork(scriptPath, args, {
cwd: rootDir
})

View File

@ -28,7 +28,8 @@ async function typedoc () {
includeVersion: true,
entryDocument: 'API.md',
readme: 'none',
hideBreadcrumbs: true
hideBreadcrumbs: true,
excludePrivate: true
})
const project = app.convert()
@ -53,6 +54,16 @@ function getRepositoryData () {
repoName: repodata.slice(2).join('/')
}
} else return null
} else {
if (pkgJson.repository.url !== 'undefined') {
const regex = /(?:.+?\+)?http[s]?:\/\/(?<repoProvider>[\w._-]+)\.\w{2,3}\/(?<repoUsername>[\w._-]+)\/(?<repoName>[\w._\-/]+?)\.git/
const match = pkgJson.repository.url.match(regex)
return {
repoProvider: match[1],
repoUsername: match[2],
repoName: match[3]
}
}
}
}
@ -73,14 +84,14 @@ if (repoProvider) {
iifeBundle = `[IIFE bundle](https://raw.githubusercontent.com/${repoUsername}/${repoName}/master/${iifeBundlePath})`
esmBundle = `[ESM bundle](https://raw.githubusercontent.com/${repoUsername}/${repoName}/master/${esmBundlePath})`
umdBundle = `[UMD bundle](https://raw.githubusercontent.com/${repoUsername}/${repoName}/master/${umdBundlePath})`
workflowBadget = `[![build](https://github.com/${repoUsername}/${repoName}/workflows/build/badge.svg)](https://github.com/${repoUsername}/${repoName}/actions?query=workflow%3A%22build%22)`
workflowBadget = `[![Node.js CI](https://github.com/${repoUsername}/${repoName}/workflows/build/badge.svg)](https://github.com/${repoUsername}/${repoName}/actions?query=workflow%3A%22build%22)`
coverallsBadge = `[![Coverage Status](https://coveralls.io/repos/github/${repoUsername}/${repoName}/badge.svg?branch=master)](https://coveralls.io/github/${repoUsername}/${repoName}?branch=master)`
break
case 'gitlab':
iifeBundle = `[IIFE bundle](https://gitlab.com/${repoUsername}/${repoName}/-/raw/master/dist/${iifeBundlePath}?inline=false)`
esmBundle = `[ESM bundle](https://gitlab.com/${repoUsername}/${repoName}/-/raw/master/dist/${esmBundlePath}?inline=false)`
umdBundle = `[UMD bundle](https://gitlab.com/${repoUsername}/${repoName}/-/raw/master/dist/${umdBundlePath}?inline=false)`
iifeBundle = `[IIFE bundle](https://gitlab.com/${repoUsername}/${repoName}/-/raw/master/${iifeBundlePath}?inline=false)`
esmBundle = `[ESM bundle](https://gitlab.com/${repoUsername}/${repoName}/-/raw/master/${esmBundlePath}?inline=false)`
umdBundle = `[UMD bundle](https://gitlab.com/${repoUsername}/${repoName}/-/raw/master/${umdBundlePath}?inline=false)`
break
default:

View File

@ -0,0 +1,42 @@
import { mkdirSync, readFileSync, writeFileSync } from 'fs'
import ts from 'typescript'
import { join, dirname } from 'path'
import { sync } from 'rimraf'
const { readJsonConfigFile, sys, parseJsonSourceFileConfigFileContent, createCompilerHost, createProgram } = ts
const rootDir = join(__dirname, '..')
const pkgJson = JSON.parse(readFileSync(join(rootDir, 'package.json')))
const srcFile = join(rootDir, 'src/ts/index.ts')
const outDir = dirname(join(rootDir, pkgJson.types))
const tsConfigPath = join(rootDir, 'tsconfig.json')
const configFile = readJsonConfigFile(tsConfigPath, (file) => {
return sys.readFile(file)
})
const tsConfig = parseJsonSourceFileConfigFileContent(configFile, sys, dirname(tsConfigPath))
const compilerOptions = {
...tsConfig.options,
declaration: true,
declarationMap: true,
emitDeclarationOnly: true,
outDir
}
const host = createCompilerHost(compilerOptions)
host.writeFile = (fileName, contents) => {
mkdirSync(dirname(fileName), { recursive: true })
writeFileSync(fileName, contents)
}
export const compile = () => {
// Clear the types dir
sync(outDir)
// Prepare and emit the d.ts files
const program = createProgram([srcFile], compilerOptions, host)
program.emit()
}

View File

@ -5,10 +5,12 @@ import replace from '@rollup/plugin-replace'
import { terser } from 'rollup-plugin-terser'
import typescriptPlugin from '@rollup/plugin-typescript'
import commonjs from '@rollup/plugin-commonjs'
import json from '@rollup/plugin-json'
import { dirname, join } from 'path'
import { existsSync, moveSync, removeSync } from 'fs-extra'
import { directories, name as _name, /* dependencies, peerDependencies, */ exports, types } from '../package.json'
import { join } from 'path'
import { existsSync } from 'fs-extra'
import { directories, name as _name, exports } from '../package.json'
import { compile } from './rollup-plugin-dts.js'
const rootDir = join(__dirname, '..')
const dstDir = join(rootDir, directories.dist)
@ -31,34 +33,37 @@ if (existsSync(input) !== true) throw new Error('The entry point should be index
const tsBundleOptions = {
tsconfig: join(rootDir, 'tsconfig.json'),
outDir: undefined, // ignore outDir in tsconfig.json
exclude: ['test/**/*', 'src/**/*.spec.ts', './build/typings/global-this-pkg.d.ts']
include: ['src/ts/**/*', 'build/typings/is-browser.d.ts'],
exclude: ['src/**/*.spec.ts']
}
// const external = [...Object.keys(dependencies || {}), ...Object.keys(peerDependencies || {})]
const sourcemapOutputOptions = {
sourcemap: 'inline',
sourcemapExcludeSources: true
}
function moveDirPlugin (srcDir, dstDir) {
function compileDts () {
return {
name: 'move-dir',
name: 'compile-dts',
closeBundle () {
removeSync(dstDir)
moveSync(srcDir, dstDir, { overwrite: true })
compile()
}
}
}
export default [
{ // ESM for browsers
{ // ESM for browsers and declarations
input: input,
output: [
{
file: join(rootDir, exports['.'].default),
...sourcemapOutputOptions,
format: 'es'
},
{
file: join(dstDir, 'bundles/esm.min.js'),
format: 'es',
plugins: [terser()]
}
],
plugins: [
@ -69,29 +74,35 @@ export default [
typescriptPlugin(tsBundleOptions),
resolve({
browser: true,
exportConditions: ['browser', 'module', 'import', 'default']
})
exportConditions: ['browser', 'default']
}),
compileDts(),
commonjs({ extensions: ['.js', '.cjs', '.ts', '.jsx', '.cjsx', '.tsx'] }), // the ".ts" extension is required
json()
]
},
{ // Other Browser bundles
{ // Browser bundles
input: input,
output: [
{
file: join(dstDir, 'bundles/iife.js'),
format: 'iife',
name: pkgCamelisedName
},
{
file: join(dstDir, 'bundles/esm.js'),
format: 'es'
name: pkgCamelisedName,
plugins: [terser()]
},
{
file: join(dstDir, 'bundles/umd.js'),
format: 'umd',
name: pkgCamelisedName
name: pkgCamelisedName,
plugins: [terser()]
}
],
plugins: [
replace({
'await import(': 'require(',
delimiters: ['', ''],
preventAssignment: true
}),
replace({
IS_BROWSER: true,
preventAssignment: true
@ -99,36 +110,11 @@ export default [
typescriptPlugin(tsBundleOptions),
resolve({
browser: true,
exportConditions: ['browser', 'module', 'import', 'default']
exportConditions: ['browser', 'default'],
mainFields: ['browser', 'module', 'main']
}),
terser()
]
},
{ // Node ESM with declaration files
input: input,
output: {
file: join(rootDir, exports['.'].node.import),
...sourcemapOutputOptions,
format: 'es'
},
plugins: [
replace({
IS_BROWSER: false,
preventAssignment: true
}),
typescriptPlugin({
...tsBundleOptions,
// outDir: path.join(rootDir, path.dirname(pkgJson.exports['.'].node.import)),
declaration: true,
declarationDir: 'types',
declarationMap: true
}),
resolve({
browser: false,
exportConditions: ['node', 'module', 'require']
}),
commonjs({ extensions: ['.js', '.cjs', '.ts'] }), // the ".ts" extension is required
moveDirPlugin(join(rootDir, dirname(exports['.'].node.import), 'types'), join(rootDir, dirname(types)))
commonjs({ extensions: ['.js', '.cjs', '.ts', '.jsx', '.cjsx', '.tsx'] }), // the ".ts" extension is required
json()
]
},
{ // Node CJS
@ -137,12 +123,36 @@ export default [
{
file: join(rootDir, exports['.'].node.require),
...sourcemapOutputOptions,
format: 'cjs'
},
format: 'cjs',
exports: 'auto'
}
],
plugins: [
replace({
'await import(': 'require(',
delimiters: ['', ''],
preventAssignment: true
}),
replace({
IS_BROWSER: false,
preventAssignment: true
}),
typescriptPlugin(tsBundleOptions),
resolve({
browser: false,
exportConditions: ['node', 'module', 'import']
}),
commonjs({ extensions: ['.js', '.cjs', '.ts', '.jsx', '.cjsx', '.tsx'] }), // the ".ts" extension is required
json()
]
},
{ // Node ESM
input: input,
output: [
{
file: join(rootDir, exports['.'].node.require).slice(0, -4) + '.js', // .js extension instead of .cjs for Node 10 support
file: join(rootDir, exports['.'].node.import),
...sourcemapOutputOptions,
format: 'cjs'
format: 'es'
}
],
plugins: [
@ -153,9 +163,10 @@ export default [
typescriptPlugin(tsBundleOptions),
resolve({
browser: false,
exportConditions: ['node', 'module', 'require']
exportConditions: ['node', 'module', 'import']
}),
commonjs({ extensions: ['.js', '.cjs', '.ts'] }) // the ".ts" extension is required
commonjs({ extensions: ['.js', '.cjs', '.ts', '.jsx', '.cjsx', '.tsx'] }), // the ".ts" extension is required
json()
]
}
]

View File

@ -15,7 +15,7 @@ const browserTests = async (
devtools: true
}
}, testFiles) => {
const server = require('./server.js').server
const server = require('./server.cjs').server
await server.init(testFiles)
await server.listen(serverPort)
const browser = await puppeteer.launch(puppeteerOptions)

View File

@ -5,7 +5,7 @@ const path = require('path')
const rollup = require('rollup')
const loadAndParseConfigFile = require('rollup/dist/loadConfigFile.js')
const Builder = require('./Builder.js')
const Builder = require('./Builder.cjs')
const rootDir = path.join(__dirname, '../../../../')
const pkgJson = require(path.join(rootDir, 'package.json'))

View File

@ -4,7 +4,7 @@ const fs = require('fs')
const ts = require('typescript')
const JSON5 = require('json5')
const Builder = require('./Builder.js')
const Builder = require('./Builder.cjs')
const rootDir = path.join(__dirname, '../../../../')
const mochaTsRelativeDir = '.mocha-ts'
@ -44,7 +44,7 @@ module.exports = class TestsBuilder extends Builder {
tsConfig.compilerOptions.sourceMap = true
// This prevents SyntaxError: Cannot use import statement outside a module
tsConfig.compilerOptions.module = 'commonjs'
// tsConfig.compilerOptions.module = 'commonjs'
// Removed typeroots (it causes issues)
tsConfig.compilerOptions.typeRoots = undefined

View File

@ -5,8 +5,8 @@ const path = require('path')
const chai = require('chai')
const rimraf = require('rimraf')
const RollupBuilder = require('./builders/RollupBuilder.js')
const TestsBuilder = require('./builders/TestsBuilder.js')
const RollupBuilder = require('./builders/RollupBuilder.cjs')
const TestsBuilder = require('./builders/TestsBuilder.cjs')
require('dotenv').config()

View File

@ -1,7 +1,4 @@
import * as _pkgModule from '../..'
import * as _pkgModule from '../../src/ts/index'
declare global {
const _pkg: typeof _pkgModule
}
export as namespace _pkgTypes
export as namespace _pkg
export = _pkgModule

File diff suppressed because one or more lines are too long

915
dist/cjs/index.node.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -80,7 +80,8 @@ ___
An iterative implementation of the extended euclidean algorithm or extended greatest common divisor algorithm.
Take positive integers a, b as input, and return a triple (g, x, y), such that ax + by = g = gcd(a, b).
**`throws`** {RangeError}
**`Throws`**
This excepction is thrown if a or b are less than 0
#### Parameters
@ -134,7 +135,8 @@ ___
The test first tries if any of the first 250 small primes are a factor of the input number and then passes several
iterations of Miller-Rabin Probabilistic Primality Test (FIPS 186-4 C.3.1)
**`throws`** {RangeError}
**`Throws`**
w MUST be >= 0
#### Parameters
@ -153,7 +155,7 @@ A promise that resolves to a boolean that is either true (a probably prime numbe
#### Defined in
[src/ts/isProbablyPrime.ts:21](https://github.com/juanelas/bigint-crypto-utils/blob/b2b3b8f/src/ts/isProbablyPrime.ts#L21)
[src/ts/isProbablyPrime.ts:21](https://github.com/juanelas/bigint-crypto-utils/blob/76a4460/src/ts/isProbablyPrime.ts#L21)
___
@ -238,7 +240,8 @@ ___
Modular inverse.
**`throws`** {RangeError}
**`Throws`**
Excpeption thorwn when a does not have inverse modulo n
#### Parameters
@ -266,7 +269,8 @@ ___
Modular exponentiation b**e mod n. Currently using the right-to-left binary method
**`throws`** {RangeError}
**`Throws`**
Excpeption thrown when n is not > 0
#### Parameters
@ -299,7 +303,8 @@ main process, and it can be much faster (if several cores or cpu are available).
The node version can also use worker_threads if they are available (enabled by default with Node 11 and
and can be enabled at runtime executing node --experimental-worker with node >=10.5.0).
**`throws`** {RangeError}
**`Throws`**
bitLength MUST be > 0
#### Parameters
@ -317,7 +322,7 @@ A promise that resolves to a bigint probable prime of bitLength bits.
#### Defined in
[src/ts/prime.ts:21](https://github.com/juanelas/bigint-crypto-utils/blob/b2b3b8f/src/ts/prime.ts#L21)
[src/ts/prime.ts:25](https://github.com/juanelas/bigint-crypto-utils/blob/76a4460/src/ts/prime.ts#L25)
___
@ -328,7 +333,8 @@ ___
A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
The sync version is NOT RECOMMENDED since it won't use workers and thus it'll be slower and may freeze thw window in browser's javascript. Please consider using prime() instead.
**`throws`** {RangeError}
**`Throws`**
bitLength MUST be > 0
#### Parameters
@ -346,7 +352,7 @@ A bigint probable prime of bitLength bits.
#### Defined in
[src/ts/prime.ts:100](https://github.com/juanelas/bigint-crypto-utils/blob/b2b3b8f/src/ts/prime.ts#L100)
[src/ts/prime.ts:102](https://github.com/juanelas/bigint-crypto-utils/blob/76a4460/src/ts/prime.ts#L102)
___
@ -356,7 +362,8 @@ ___
Returns a cryptographically secure random integer between [min,max].
**`throws`** {RangeError}
**`Throws`**
Arguments MUST be: max > min
#### Parameters
@ -374,7 +381,7 @@ A cryptographically secure random bigint between [min,max]
#### Defined in
[src/ts/randBetween.ts:15](https://github.com/juanelas/bigint-crypto-utils/blob/b2b3b8f/src/ts/randBetween.ts#L15)
[src/ts/randBetween.ts:15](https://github.com/juanelas/bigint-crypto-utils/blob/76a4460/src/ts/randBetween.ts#L15)
___
@ -384,7 +391,8 @@ ___
Secure random bits for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
**`throws`** {RangeError}
**`Throws`**
bitLength MUST be > 0
#### Parameters
@ -402,7 +410,7 @@ A Promise that resolves to a UInt8Array/Buffer (Browser/Node.js) filled with cry
#### Defined in
[src/ts/randBits.ts:14](https://github.com/juanelas/bigint-crypto-utils/blob/b2b3b8f/src/ts/randBits.ts#L14)
[src/ts/randBits.ts:14](https://github.com/juanelas/bigint-crypto-utils/blob/76a4460/src/ts/randBits.ts#L14)
___
@ -412,7 +420,8 @@ ___
Secure random bits for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
**`throws`** {RangeError}
**`Throws`**
bitLength MUST be > 0
#### Parameters
@ -430,7 +439,7 @@ A Uint8Array/Buffer (Browser/Node.js) filled with cryptographically secure rando
#### Defined in
[src/ts/randBits.ts:45](https://github.com/juanelas/bigint-crypto-utils/blob/b2b3b8f/src/ts/randBits.ts#L45)
[src/ts/randBits.ts:45](https://github.com/juanelas/bigint-crypto-utils/blob/76a4460/src/ts/randBits.ts#L45)
___
@ -440,7 +449,8 @@ ___
Secure random bytes for both node and browsers. Node version uses crypto.randomBytes() and browser one self.crypto.getRandomValues()
**`throws`** {RangeError}
**`Throws`**
byteLength MUST be > 0
#### Parameters
@ -458,7 +468,7 @@ A promise that resolves to a UInt8Array/Buffer (Browser/Node.js) filled with cry
#### Defined in
[src/ts/randBytes.ts:12](https://github.com/juanelas/bigint-crypto-utils/blob/b2b3b8f/src/ts/randBytes.ts#L12)
[src/ts/randBytes.ts:14](https://github.com/juanelas/bigint-crypto-utils/blob/76a4460/src/ts/randBytes.ts#L14)
___
@ -468,7 +478,8 @@ ___
Secure random bytes for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
**`throws`** {RangeError}
**`Throws`**
byteLength MUST be > 0
#### Parameters
@ -486,7 +497,7 @@ A UInt8Array/Buffer (Browser/Node.js) filled with cryptographically secure rando
#### Defined in
[src/ts/randBytes.ts:46](https://github.com/juanelas/bigint-crypto-utils/blob/b2b3b8f/src/ts/randBytes.ts#L46)
[src/ts/randBytes.ts:47](https://github.com/juanelas/bigint-crypto-utils/blob/76a4460/src/ts/randBytes.ts#L47)
___
@ -496,10 +507,12 @@ ___
Finds the smallest positive element that is congruent to a in modulo n
**`remarks`**
**`Remarks`**
a and b must be the same type, either number or bigint
**`throws`** {RangeError}
**`Throws`**
Excpeption thrown when n is not > 0
#### Parameters

View File

@ -1,4 +1,4 @@
const bigintCryptoUtils = require('../')
const bigintCryptoUtils = require('../types')
// const bigintCryptoUtils = require('bigint-crypto-utils')
/* A BigInt with value 666 can be declared calling the bigint constructor as

2513
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -24,6 +24,7 @@
"engines": {
"node": ">=10.4.0"
},
"type": "module",
"types": "./types/index.d.ts",
"main": "./dist/cjs/index.node.cjs",
"browser": "./dist/esm/index.browser.js",
@ -32,11 +33,12 @@
".": {
"node": {
"require": "./dist/cjs/index.node.cjs",
"import": "./dist/esm/index.node.js"
"import": "./dist/esm/index.node.js",
"module": "./dist/esm/index.node.js"
},
"default": "./dist/esm/index.browser.js"
},
"./esm-browser-bundle": "./dist/bundles/esm.js",
"./esm-browser-bundle": "./dist/bundles/esm.min.js",
"./iife-browser-bundle": "./dist/bundles/iife.js",
"./umd-browser-bundle": "./dist/bundles/umd.js",
"./types": "./types/index.d.ts"
@ -52,13 +54,13 @@
"build": "run-s lint build:js docs",
"build:js": "rollup -c build/rollup.config.js",
"clean": "rimraf .nyc_output .mocha-ts coverage dist types docs",
"coverage": "nyc --check-coverage --exclude build --exclude '{src/ts/**/*.spec.ts,test/**/*.ts,.mocha-ts/**/*}' --reporter=text --reporter=lcov node ./build/bin/mocha-ts.js --require build/testing/mocha/mocha-init.js '{src/ts/**/*.spec.ts,test/**/*.ts}'",
"docs": "node build/build.docs.js",
"coverage": "nyc --check-coverage --exclude build --exclude '{src/ts/**/*.spec.ts,test/**/*.ts,.mocha-ts/**/*}' --reporter=text --reporter=lcov node ./build/bin/mocha-ts.cjs --require build/testing/mocha/mocha-init.cjs '{src/ts/**/*.spec.ts,test/**/*.ts}'",
"docs": "node build/build.docs.cjs",
"git:add": "git add -A",
"lint": "ts-standard --fix",
"mocha-ts": "node ./build/bin/mocha-ts.js --require build/testing/mocha/mocha-init.js ",
"mocha-ts:browser": "node build/testing/browser/index.js ",
"mocha-ts:browser-headless": "node build/testing/browser/index.js headless ",
"mocha-ts": "node ./build/bin/mocha-ts.cjs --require build/testing/mocha/mocha-init.cjs ",
"mocha-ts:browser": "node build/testing/browser/index.cjs ",
"mocha-ts:browser-headless": "node build/testing/browser/index.cjs headless ",
"preversion": "run-s clean lint build:js coverage test:browser-headless",
"version": "run-s docs git:add",
"postversion": "git push --follow-tags",
@ -91,13 +93,13 @@
]
},
"devDependencies": {
"@rollup/plugin-commonjs": "^21.0.0",
"@rollup/plugin-commonjs": "^22.0.0",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-multi-entry": "^4.0.0",
"@rollup/plugin-node-resolve": "^13.0.4",
"@rollup/plugin-node-resolve": "^13.0.5",
"@rollup/plugin-replace": "^4.0.0",
"@rollup/plugin-typescript": "^8.2.0",
"@types/chai": "^4.2.14",
"@types/chai": "^4.2.22",
"@types/mocha": "^9.0.0",
"chai": "^4.3.3",
"dotenv": "^16.0.0",
@ -105,21 +107,21 @@
"glob": "^8.0.1",
"json5": "^2.2.0",
"minimatch": "^5.0.1",
"mocha": "^9.0.3",
"mocha": "^10.0.0",
"npm-run-all": "^4.1.5",
"nyc": "^15.1.0",
"pirates": "^4.0.1",
"puppeteer": "^13.6.0",
"puppeteer": "^15.5.0",
"rimraf": "^3.0.2",
"rollup": "^2.40.0",
"rollup": "^2.57.0",
"rollup-plugin-terser": "^7.0.2",
"ts-standard": "^11.0.0",
"tslib": "^2.1.0",
"typedoc": "^0.22.0",
"typedoc-plugin-markdown": "^3.6.0",
"typescript": "^4.2.2"
"tslib": "^2.3.1",
"typedoc": "^0.23.0",
"typedoc-plugin-markdown": "^3.11.0",
"typescript": "^4.4.3"
},
"dependencies": {
"bigint-mod-arith": "^3.0.1"
"bigint-mod-arith": "^3.1.0"
}
}

View File

@ -27,12 +27,11 @@ export function isProbablyPrime (w: number|bigint, iterations: number = 16, disa
if (!IS_BROWSER) { // Node.js
/* istanbul ignore else */
if (!disableWorkers && _useWorkers) {
const { Worker } = require('worker_threads') // eslint-disable-line
return new Promise((resolve, reject) => {
const worker = new Worker(__filename)
const worker = new workerThreads.Worker(__filename)
worker.on('message', (data: WorkerToMainMsg) => {
worker.terminate()
worker.terminate().catch(reject)
resolve(data.isPrime)
})
@ -399,18 +398,18 @@ export function _isProbablyPrimeWorkerUrl (): string {
}
if (!IS_BROWSER && _useWorkers) { // node.js with support for workers
const { parentPort, isMainThread } = require('worker_threads') // eslint-disable-line
const isWorker = !(isMainThread as boolean)
var workerThreads = await import('worker_threads') // eslint-disable-line
const isWorker = !(workerThreads.isMainThread)
/* istanbul ignore if */
if (isWorker) { // worker
parentPort.on('message', function (data: MainToWorkerMsg) { // Let's start once we are called
if (isWorker && workerThreads.parentPort !== null) { // worker
workerThreads.parentPort.on('message', function (data: MainToWorkerMsg) { // Let's start once we are called
const isPrime = _isProbablyPrime(data.rnd, data.iterations)
const msg: WorkerToMainMsg = {
isPrime: isPrime,
value: data.rnd,
id: data.id
}
parentPort.postMessage(msg)
workerThreads.parentPort?.postMessage(msg)
})
}
}

View File

@ -2,6 +2,10 @@ import { fromBuffer } from './fromBuffer'
import { _isProbablyPrime, _isProbablyPrimeWorkerUrl } from './isProbablyPrime'
import { randBits, randBitsSync } from './randBits'
import { _useWorkers, WorkerToMainMsg, MainToWorkerMsg } from './workerUtils'
import type { Worker as NodeWorker } from 'worker_threads'
if (!IS_BROWSER) var os = await import('os') // eslint-disable-line no-var
if (!IS_BROWSER) var workerThreads = await import('worker_threads') // eslint-disable-line no-var
/**
* A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
@ -30,12 +34,12 @@ export function prime (bitLength: number, iterations: number = 16): Promise<bigi
return new Promise((resolve) => { resolve(rnd) })
}
return new Promise((resolve, reject) => {
const workerList: Worker[] = []
const _onmessage = (msg: WorkerToMainMsg, newWorker: Worker): void => {
const workerList: Array<NodeWorker | Worker> = []
const _onmessage = (msg: WorkerToMainMsg, newWorker: Worker | NodeWorker): void => {
if (msg.isPrime) {
// if a prime number has been found, stop all the workers, and return it
for (let j = 0; j < workerList.length; j++) {
workerList[j].terminate()
workerList[j].terminate() // eslint-disable-line @typescript-eslint/no-floating-promises
}
while (workerList.length > 0) {
workerList.pop()
@ -64,10 +68,8 @@ export function prime (bitLength: number, iterations: number = 16): Promise<bigi
workerList.push(newWorker)
}
} else { // Node.js
const { cpus } = require('os') // eslint-disable-line
const { Worker } = require('worker_threads') // eslint-disable-line
for (let i = 0; i < cpus().length - 1; i++) {
const newWorker = new Worker(__filename)
for (let i = 0; i < os.cpus().length - 1; i++) {
const newWorker = new workerThreads.Worker(__filename)
newWorker.on('message', (msg: WorkerToMainMsg) => _onmessage(msg, newWorker))
workerList.push(newWorker)
}

View File

@ -1,3 +1,5 @@
if (!IS_BROWSER) var crypto = await import('crypto') // eslint-disable-line no-var
/**
* Secure random bytes for both node and browsers. Node version uses crypto.randomBytes() and browser one self.crypto.getRandomValues()
*
@ -14,8 +16,7 @@ export function randBytes (byteLength: number, forceLength = false): Promise<Uin
return new Promise(function (resolve, reject) {
if (!IS_BROWSER) {
const crypto = require('crypto') // eslint-disable-line
crypto.randomBytes(byteLength, function (err: Error, buf: Buffer) {
crypto.randomBytes(byteLength, function (err, buf: Buffer) {
/* istanbul ignore if */
if (err !== null) reject(err)
// If fixed length is required we put the first bit to 1 -> to get the necessary bitLength
@ -48,7 +49,6 @@ export function randBytesSync (byteLength: number, forceLength: boolean = false)
/* eslint-disable no-lone-blocks */
if (!IS_BROWSER) { // node
const crypto = require('crypto') // eslint-disable-line
const buf = crypto.randomBytes(byteLength)
// If fixed length is required we put the first bit to 1 -> to get the necessary bitLength
if (forceLength) buf[0] = buf[0] | 128

View File

@ -8,7 +8,7 @@ let _useWorkers = false // The following is just to check whether we can use wor
/* eslint-disable no-lone-blocks */
if (!IS_BROWSER) { // Node.js
try {
require.resolve('worker_threads')
await import('worker_threads')
_useWorkers = true
} catch (e) {
/* istanbul ignore next */

View File

@ -2,6 +2,7 @@
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"target": "ES2020", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
"module": "esnext",
// "lib": [ "es2020" ], /* Specify library files to be included in the compilation. */
"allowJs": true, /* Allow javascript files to be compiled. */
// "outDir": ".dst", /* If not set we cannot import .js files without a warning that is going to be overwritten. outDir is not going to be used in any case */

View File

@ -1 +1 @@
{"version":3,"file":"isProbablyPrime.d.ts","sourceRoot":"","sources":["../src/ts/isProbablyPrime.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAE,CAAC,EAAE,MAAM,GAAC,MAAM,EAAE,UAAU,GAAE,MAAW,EAAE,cAAc,GAAE,OAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAqD7H;AAED,wBAAgB,gBAAgB,CAAE,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CA0TxE;AAED,wBAAgB,yBAAyB,IAAK,MAAM,CAOnD"}
{"version":3,"file":"isProbablyPrime.d.ts","sourceRoot":"","sources":["../src/ts/isProbablyPrime.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAE,CAAC,EAAE,MAAM,GAAC,MAAM,EAAE,UAAU,GAAE,MAAW,EAAE,cAAc,GAAE,OAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAoD7H;AAED,wBAAgB,gBAAgB,CAAE,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CA0TxE;AAED,wBAAgB,yBAAyB,IAAK,MAAM,CAOnD"}

View File

@ -1 +1 @@
{"version":3,"file":"prime.d.ts","sourceRoot":"","sources":["../src/ts/prime.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,KAAK,CAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAE,MAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAiElF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAE,MAAW,GAAG,MAAM,CAO7E"}
{"version":3,"file":"prime.d.ts","sourceRoot":"","sources":["../src/ts/prime.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,KAAK,CAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAE,MAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CA+DlF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAE,MAAW,GAAG,MAAM,CAO7E"}

View File

@ -1 +1 @@
{"version":3,"file":"randBytes.d.ts","sourceRoot":"","sources":["../src/ts/randBytes.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAE,UAAU,EAAE,MAAM,EAAE,WAAW,UAAQ,GAAG,OAAO,CAAC,UAAU,GAAC,MAAM,CAAC,CAqB9F;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAE,UAAU,EAAE,MAAM,EAAE,WAAW,GAAE,OAAe,GAAG,UAAU,GAAC,MAAM,CAkBlG"}
{"version":3,"file":"randBytes.d.ts","sourceRoot":"","sources":["../src/ts/randBytes.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAE,UAAU,EAAE,MAAM,EAAE,WAAW,UAAQ,GAAG,OAAO,CAAC,UAAU,GAAC,MAAM,CAAC,CAoB9F;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAE,UAAU,EAAE,MAAM,EAAE,WAAW,GAAE,OAAe,GAAG,UAAU,GAAC,MAAM,CAiBlG"}