UNPKG

mathjs

Version:

Math.js is an extensive math library for JavaScript and Node.js. It features a flexible expression parser with support for symbolic computation, comes with a large set of built-in functions and constants, and offers an integrated solution to work with dif

213 lines (201 loc) 9.27 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.create = create; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _typedFunction = _interopRequireDefault(require("typed-function")); var _ArgumentsError = require("../error/ArgumentsError.js"); var _DimensionError = require("../error/DimensionError.js"); var _IndexError = require("../error/IndexError.js"); var _factory = require("../utils/factory.js"); var _is = require("../utils/is.js"); var _object = require("../utils/object.js"); var emitter = _interopRequireWildcard(require("./../utils/emitter.js")); var _config = require("./config.js"); var _config2 = require("./function/config.js"); var _import = require("./function/import.js"); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } /** * Create a mathjs instance from given factory functions and optionally config * * Usage: * * const mathjs1 = create({ createAdd, createMultiply, ...}) * const config = { number: 'BigNumber' } * const mathjs2 = create(all, config) * * @param {Object} [factories] An object with factory functions * The object can contain nested objects, * all nested objects will be flattened. * @param {Object} [config] Available options: * {number} relTol * Minimum relative difference between two * compared values, used by all comparison functions. * {number} absTol * Minimum absolute difference between two * compared values, used by all comparison functions. * {string} matrix * A string 'Matrix' (default) or 'Array'. * {string} number * A string 'number' (default), 'BigNumber', or 'Fraction' * {number} precision * The number of significant digits for BigNumbers. * Not applicable for Numbers. * {boolean} predictable * Predictable output type of functions. When true, * output type depends only on the input types. When * false (default), output type can vary depending * on input values. For example `math.sqrt(-4)` * returns `complex('2i')` when predictable is false, and * returns `NaN` when true. * {string} randomSeed * Random seed for seeded pseudo random number generator. * Set to null to randomly seed. * @returns {Object} Returns a bare-bone math.js instance containing * functions: * - `import` to add new functions * - `config` to change configuration * - `on`, `off`, `once`, `emit` for events */ function create(factories, config) { const configInternal = (0, _extends2.default)({}, _config.DEFAULT_CONFIG, config); // simple test for ES5 support if (typeof Object.create !== 'function') { throw new Error('ES5 not supported by this JavaScript engine. ' + 'Please load the es5-shim and es5-sham library for compatibility.'); } // create the mathjs instance const math = emitter.mixin({ // only here for backward compatibility for legacy factory functions isNumber: _is.isNumber, isComplex: _is.isComplex, isBigNumber: _is.isBigNumber, isBigInt: _is.isBigInt, isFraction: _is.isFraction, isUnit: _is.isUnit, isString: _is.isString, isArray: _is.isArray, isMatrix: _is.isMatrix, isCollection: _is.isCollection, isDenseMatrix: _is.isDenseMatrix, isSparseMatrix: _is.isSparseMatrix, isRange: _is.isRange, isIndex: _is.isIndex, isBoolean: _is.isBoolean, isResultSet: _is.isResultSet, isHelp: _is.isHelp, isFunction: _is.isFunction, isDate: _is.isDate, isRegExp: _is.isRegExp, isObject: _is.isObject, isMap: _is.isMap, isPartitionedMap: _is.isPartitionedMap, isObjectWrappingMap: _is.isObjectWrappingMap, isNull: _is.isNull, isUndefined: _is.isUndefined, isAccessorNode: _is.isAccessorNode, isArrayNode: _is.isArrayNode, isAssignmentNode: _is.isAssignmentNode, isBlockNode: _is.isBlockNode, isConditionalNode: _is.isConditionalNode, isConstantNode: _is.isConstantNode, isFunctionAssignmentNode: _is.isFunctionAssignmentNode, isFunctionNode: _is.isFunctionNode, isIndexNode: _is.isIndexNode, isNode: _is.isNode, isObjectNode: _is.isObjectNode, isOperatorNode: _is.isOperatorNode, isParenthesisNode: _is.isParenthesisNode, isRangeNode: _is.isRangeNode, isRelationalNode: _is.isRelationalNode, isSymbolNode: _is.isSymbolNode, isChain: _is.isChain }); // load config function and apply provided config math.config = (0, _config2.configFactory)(configInternal, math.emit); math.expression = { transform: {}, mathWithTransform: { config: math.config } }; // cached factories and instances used by function load const legacyFactories = []; const legacyInstances = []; /** * Load a function or data type from a factory. * If the function or data type already exists, the existing instance is * returned. * @param {Function} factory * @returns {*} */ function load(factory) { if ((0, _factory.isFactory)(factory)) { return factory(math); } const firstProperty = factory[Object.keys(factory)[0]]; if ((0, _factory.isFactory)(firstProperty)) { return firstProperty(math); } if (!(0, _object.isLegacyFactory)(factory)) { console.warn('Factory object with properties `type`, `name`, and `factory` expected', factory); throw new Error('Factory object with properties `type`, `name`, and `factory` expected'); } const index = legacyFactories.indexOf(factory); let instance; if (index === -1) { // doesn't yet exist if (factory.math === true) { // pass with math namespace instance = factory.factory(math.type, configInternal, load, math.typed, math); } else { instance = factory.factory(math.type, configInternal, load, math.typed); } // append to the cache legacyFactories.push(factory); legacyInstances.push(instance); } else { // already existing function, return the cached instance instance = legacyInstances[index]; } return instance; } const importedFactories = {}; // load the import function function lazyTyped() { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return math.typed.apply(math.typed, args); } lazyTyped.isTypedFunction = _typedFunction.default.isTypedFunction; const internalImport = (0, _import.importFactory)(lazyTyped, load, math, importedFactories); math.import = internalImport; // listen for changes in config, import all functions again when changed // TODO: move this listener into the import function? math.on('config', () => { Object.values(importedFactories).forEach(factory => { if (factory && factory.meta && factory.meta.recreateOnConfigChange) { // FIXME: only re-create when the current instance is the same as was initially created // FIXME: delete the functions/constants before importing them again? internalImport(factory, { override: true }); } }); }); // the create function exposed on the mathjs instance is bound to // the factory functions passed before math.create = create.bind(null, factories); // export factory function math.factory = _factory.factory; // import the factory functions like createAdd as an array instead of object, // else they will get a different naming (`createAdd` instead of `add`). math.import(Object.values((0, _object.deepFlatten)(factories))); math.ArgumentsError = _ArgumentsError.ArgumentsError; math.DimensionError = _DimensionError.DimensionError; math.IndexError = _IndexError.IndexError; return math; }