or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

index.mddocs/

babel-plugin-transform-jsbi-to-bigint

A Babel plugin that transforms JSBI (JavaScript BigInt) library calls into native BigInt syntax, enabling developers to write BigInt code that works in older environments through JSBI while automatically transpiling to modern native BigInt operations for better performance and cleaner code.

Package Information

  • Package Name: babel-plugin-transform-jsbi-to-bigint
  • Package Type: npm
  • Language: JavaScript (ES6+)
  • Installation: npm install babel-plugin-transform-jsbi-to-bigint

Core Imports

Since this is a Babel plugin, it's not imported directly in your code. Instead, it's configured in your Babel configuration.

Via .babelrc (Recommended)

{
  "plugins": ["transform-jsbi-to-bigint"]
}

Via CLI

babel --plugins transform-jsbi-to-bigint script.js

Via Node.js API

require('@babel/core').transform(code, {
  'plugins': ['transform-jsbi-to-bigint']
});

Direct Plugin Import (for programmatic use)

import transformJSBIToBigInt from 'babel-plugin-transform-jsbi-to-bigint';

Basic Usage

This plugin transforms JSBI code to native BigInt code. Write your code using JSBI syntax and the plugin will transform it during compilation.

Input code using JSBI:

import JSBI from 'jsbi';

const a = JSBI.BigInt(Number.MAX_SAFE_INTEGER);
const b = JSBI.BigInt('42');

JSBI.add(a, b);
JSBI.subtract(a, b);
JSBI.multiply(a, b);

JSBI.equal(a, b);
JSBI.lessThan(a, b);

JSBI.unaryMinus(a);
JSBI.bitwiseNot(a);

a instanceof JSBI;
JSBI.toNumber(a);

Transpiled output using native BigInt:

const a = BigInt(Number.MAX_SAFE_INTEGER);
const b = 42n;

a + b;
a - b;
a * b;

a === b;
a < b;

-a;
~a;

typeof a === 'bigint';
Number(a);

Architecture

The plugin works by:

  1. Import Detection: Identifies JSBI imports and marks them for removal
  2. Method Transformation: Converts JSBI method calls to native BigInt operations
  3. Variable Tracking: Handles destructured JSBI methods and aliases
  4. Type Checking: Transforms instanceof JSBI to typeof x === 'bigint'
  5. Cleanup: Removes JSBI imports and variable declarations

Capabilities

Plugin Factory Function

The main export is a Babel plugin factory function.

/**
 * Babel plugin factory function that transforms JSBI calls to native BigInt
 * @param {Object} babel - Babel core object containing types and utilities
 * @param {Object} babel.types - Babel types helper functions for AST manipulation
 * @returns {BabelPlugin} Babel plugin configuration object with visitor methods
 */
export default function(babel): BabelPlugin;

interface BabelPlugin {
  pre?(): void;
  visitor: {
    Program?: {
      exit(): void;
    };
    ImportDeclaration?(path: NodePath<ImportDeclaration>): void;
    VariableDeclarator?(path: NodePath<VariableDeclarator>): void;
    CallExpression?(path: NodePath<CallExpression>): void;
    BinaryExpression?(path: NodePath<BinaryExpression>): void;
  };
}

Usage in Babel configuration:

// babel.config.js
module.exports = {
  plugins: [
    require('babel-plugin-transform-jsbi-to-bigint')
  ]
};

Binary Operations Transformation

Transforms JSBI binary operations to native BigInt operators.

// Arithmetic operations
JSBI.add(a, b)        → a + b
JSBI.subtract(a, b)   → a - b
JSBI.multiply(a, b)   → a * b
JSBI.divide(a, b)     → a / b
JSBI.remainder(a, b)  → a % b
JSBI.exponentiate(a, b) → a ** b

// Bitwise operations
JSBI.leftShift(a, b)      → a << b
JSBI.signedRightShift(a, b) → a >> b
JSBI.bitwiseAnd(a, b)     → a & b
JSBI.bitwiseOr(a, b)      → a | b
JSBI.bitwiseXor(a, b)     → a ^ b

// Comparison operations (strict)
JSBI.equal(a, b)          → a === b
JSBI.notEqual(a, b)       → a !== b
JSBI.lessThan(a, b)       → a < b
JSBI.lessThanOrEqual(a, b) → a <= b
JSBI.greaterThan(a, b)    → a > b
JSBI.greaterThanOrEqual(a, b) → a >= b

// Comparison operations (loose)
JSBI.EQ(a, b) → a == b
JSBI.NE(a, b) → a != b
JSBI.LT(a, b) → a < b
JSBI.LE(a, b) → a <= b
JSBI.GT(a, b) → a > b
JSBI.GE(a, b) → a >= b

// Special case for ADD
JSBI.ADD(a, b) → a + b

Unary Operations Transformation

Transforms JSBI unary operations to native BigInt operators.

JSBI.unaryMinus(a) → -a
JSBI.bitwiseNot(a) → ~a

Static Methods Transformation

Transforms JSBI static methods to native BigInt static methods.

JSBI.asIntN(bits, value)  → BigInt.asIntN(bits, value)
JSBI.asUintN(bits, value) → BigInt.asUintN(bits, value)

Usage example:

// Input
JSBI.asIntN(64, JSBI.BigInt('42'));
JSBI.asUintN(64, JSBI.BigInt('42'));

// Output
BigInt.asIntN(64, 42n);
BigInt.asUintN(64, 42n);

DataView Methods Transformation

Transforms JSBI DataView methods to native DataView BigInt methods.

JSBI.DataViewGetBigInt64(view, offset, ...)  → view.getBigInt64(offset, ...)
JSBI.DataViewSetBigInt64(view, offset, ...)  → view.setBigInt64(offset, ...)
JSBI.DataViewGetBigUint64(view, offset, ...) → view.getBigUint64(offset, ...)
JSBI.DataViewSetBigUint64(view, offset, ...) → view.setBigUint64(offset, ...)

Usage example:

// Input
const buffer = new ArrayBuffer(16);
const view = new DataView(buffer);
const max = JSBI.BigInt('9223372036854775807');
JSBI.DataViewSetBigInt64(view, 0, max);
const result = JSBI.DataViewGetBigInt64(view, 0);

// Output
const buffer = new ArrayBuffer(16);
const view = new DataView(buffer);
const max = 9223372036854775807n;
view.setBigInt64(0, max);
const result = view.getBigInt64(0);

Constructor and Utility Transformations

Transforms JSBI constructor and utility methods to native BigInt equivalents.

/**
 * Constructor transformation - converts to BigInt literal when possible
 * @param {number|string} value - Value to convert to BigInt
 * @returns {BigIntLiteral|CallExpression} BigInt literal or constructor call
 */
JSBI.BigInt(value) → BigInt(value) | ${value}n

/**
 * Utility method transformation - converts to Number constructor
 * @param {BigInt} value - BigInt value to convert to number
 * @returns {CallExpression} Number constructor call
 */
JSBI.toNumber(value) → Number(value)

/**
 * Type checking transformation - converts instanceof to typeof check
 * @param {any} x - Value to check
 * @returns {BinaryExpression} typeof comparison expression
 */
x instanceof JSBI → typeof x === 'bigint'

Constructor Optimization Examples:

// Numeric literals are converted to BigInt literals
JSBI.BigInt(42);        // → 42n
JSBI.BigInt(0);         // → 0n

// String literals with valid integers become BigInt literals  
JSBI.BigInt('123');     // → 123n
JSBI.BigInt('0');       // → 0n

// Complex strings or variables use constructor call
JSBI.BigInt('00034');   // → BigInt('00034') (preserves leading zeros)
JSBI.BigInt(variable);  // → BigInt(variable)
JSBI.BigInt('0x10');    // → BigInt('0x10') (hex format preserved)

Import Pattern Support

The plugin handles various JSBI import and usage patterns.

// Supported import patterns
import JSBI from 'jsbi';
import JSBI from './path/to/jsbi.mjs';

// Supported destructuring patterns
const JSBigInt = JSBI.BigInt;
const JSBigInt2 = JSBI['BigInt'];
const JSBIadd = JSBI.add;

// All these are transformed appropriately
JSBigInt(34);    // → 34n
JSBigInt2(56);   // → 56n
JSBIadd(7, 8);   // → 7 + 8

Error Handling

The plugin provides descriptive error messages for incorrect usage:

  • Binary operators: Must have exactly two arguments
  • Unary operators: Must have exactly one argument
  • Static methods: Must have exactly two arguments
  • DataView methods: Must have 2-4 arguments depending on the method
  • toNumber method: Must have exactly one argument
  • Unknown JSBI functions: Clear error message with function name
  • Invalid property access: Only .BigInt or ['BigInt'] patterns allowed

Transformation Examples

Complex Transformation Example

// Input
import JSBI from 'jsbi';

function calculateCompoundInterest(principal, rate, time) {
  const p = JSBI.BigInt(principal);
  const r = JSBI.BigInt(rate);
  const t = JSBI.BigInt(time);
  const hundred = JSBI.BigInt(100);
  
  const rateDecimal = JSBI.divide(r, hundred);
  const onePlusRate = JSBI.add(JSBI.BigInt(1), rateDecimal);
  const compound = JSBI.exponentiate(onePlusRate, t);
  
  return JSBI.multiply(p, compound);
}

// Check if result is greater than threshold
const result = calculateCompoundInterest('1000', '5', '10');
const threshold = JSBI.BigInt('1500');

if (JSBI.greaterThan(result, threshold)) {
  console.log('Investment exceeded threshold');
}
// Output
function calculateCompoundInterest(principal, rate, time) {
  const p = BigInt(principal);
  const r = BigInt(rate);
  const t = BigInt(time);
  const hundred = 100n;
  
  const rateDecimal = r / hundred;
  const onePlusRate = 1n + rateDecimal;
  const compound = onePlusRate ** t;
  
  return p * compound;
}

// Check if result is greater than threshold
const result = calculateCompoundInterest('1000', '5', '10');
const threshold = 1500n;

if (result > threshold) {
  console.log('Investment exceeded threshold');
}

Variable Aliasing Example

// Input
import JSBI from 'jsbi';

const BigIntConstructor = JSBI.BigInt;
const add = JSBI.add;
const isEqual = JSBI.equal;

const a = BigIntConstructor('100');
const b = BigIntConstructor('200');
const sum = add(a, b);

if (isEqual(sum, BigIntConstructor('300'))) {
  console.log('Math checks out!');
}

// Output
const a = 100n;
const b = 200n;
const sum = a + b;

if (sum === 300n) {
  console.log('Math checks out!');
}

Internal Helper Functions

The plugin uses several internal helper functions for AST manipulation:

/**
 * Creates appropriate expression based on JSBI method name
 * @param {NodePath} path - Current AST node path for error reporting
 * @param {string} name - JSBI method name (e.g., 'add', 'BigInt', 'asIntN')
 * @param {Node[]} args - Array of argument nodes
 * @returns {Node} Transformed AST node (BinaryExpr, UnaryExpr, CallExpr, etc.)
 * @throws {Error} When method is unknown or has incorrect argument count
 */
function createExpression(path: NodePath, name: string, args: Node[]): Node;

/**
 * Creates BigInt constructor call or literal when possible
 * @param {NodePath} path - Current AST node path
 * @returns {Node} BigIntLiteral or CallExpression node
 */
function createBigIntConstructor(path: NodePath): Node;

/**
 * Extracts property name from member expression or string literal
 * @param {NodePath} path - Property node path
 * @returns {string} Property name
 * @throws {Error} When property access pattern is not supported
 */
function getPropertyName(path: NodePath): string;

/**
 * Resolves variable binding through the scope chain
 * @param {NodePath} path - Current path
 * @param {string} name - Variable name to resolve
 * @returns {Binding|undefined} Resolved binding or undefined
 */
function resolveBinding(path: NodePath, name: string): Binding | undefined;

/**
 * Gets JSBI-related data from variable binding
 * @param {NodePath} path - Current path
 * @param {string} name - Variable name
 * @returns {string|undefined} JSBI property name or undefined
 */
function getJSBIProperty(path: NodePath, name: string): string | undefined;

/**
 * Sets JSBI-related data on path for tracking
 * @param {NodePath} path - Path to mark
 * @param {string} data - JSBI property identifier
 * @returns {NodePath} The marked path
 */
function setJSBIProperty(path: NodePath, data: string): NodePath;

/**
 * Checks if variable has JSBI-related data
 * @param {NodePath} path - Current path
 * @param {string} name - Variable name to check
 * @returns {boolean} True if variable is JSBI-related
 */
function hasJSBIProperty(path: NodePath, name: string): boolean;

Error Handling

The plugin provides specific error messages for various invalid usage patterns:

// Error messages thrown by the plugin:

// Binary operators (add, subtract, multiply, etc.)
"Binary operators must have exactly two arguments"

// Unary operators (unaryMinus, bitwiseNot)
"Unary operators must have exactly one argument"

// Static methods (asIntN, asUintN)
"Static methods must have exactly two arguments"

// DataView methods with variable argument counts
"${methodName}: incorrect number of arguments"

// toNumber method
"toNumber must have exactly one argument"

// Unknown JSBI functions
"Unknown JSBI function '${functionName}'"

// Invalid property access patterns
"Only .BigInt or ['BigInt'] allowed here."

Error Example:

// This will throw an error during compilation:
import JSBI from 'jsbi';
JSBI.add(a); // Error: Binary operators must have exactly two arguments
JSBI.unknownMethod(a); // Error: Unknown JSBI function 'unknownMethod'

Plugin Configuration Object Structure

The plugin returns a standard Babel plugin configuration object:

The returned plugin object contains:

  • pre(): Initialization hook that sets up internal removal tracking state
  • visitor.Program.exit(): Cleanup hook that removes all tracked import/declaration nodes
  • visitor.ImportDeclaration(): Processes and marks JSBI imports for removal
  • visitor.VariableDeclarator(): Handles variable declarations with JSBI method destructuring
  • visitor.CallExpression(): Transforms JSBI method calls to native BigInt operations
  • visitor.BinaryExpression(): Specifically handles instanceof JSBI transformations to typeof x === 'bigint'