simple-squiggle

A restricted subset of Squiggle
Log | Files | Refs | README

create.js (9205B)


      1 "use strict";
      2 
      3 var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
      4 
      5 var _typeof = require("@babel/runtime/helpers/typeof");
      6 
      7 Object.defineProperty(exports, "__esModule", {
      8   value: true
      9 });
     10 exports.create = create;
     11 
     12 var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
     13 
     14 require("./../utils/polyfills.js");
     15 
     16 var _object = require("../utils/object.js");
     17 
     18 var emitter = _interopRequireWildcard(require("./../utils/emitter.js"));
     19 
     20 var _import = require("./function/import.js");
     21 
     22 var _config = require("./function/config.js");
     23 
     24 var _factory = require("../utils/factory.js");
     25 
     26 var _is = require("../utils/is.js");
     27 
     28 var _ArgumentsError = require("../error/ArgumentsError.js");
     29 
     30 var _DimensionError = require("../error/DimensionError.js");
     31 
     32 var _IndexError = require("../error/IndexError.js");
     33 
     34 var _config2 = require("./config.js");
     35 
     36 function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
     37 
     38 function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
     39 
     40 /**
     41  * Create a mathjs instance from given factory functions and optionally config
     42  *
     43  * Usage:
     44  *
     45  *     const mathjs1 = create({ createAdd, createMultiply, ...})
     46  *     const config = { number: 'BigNumber' }
     47  *     const mathjs2 = create(all, config)
     48  *
     49  * @param {Object} [factories] An object with factory functions
     50  *                             The object can contain nested objects,
     51  *                             all nested objects will be flattened.
     52  * @param {Object} [config]    Available options:
     53  *                            {number} epsilon
     54  *                              Minimum relative difference between two
     55  *                              compared values, used by all comparison functions.
     56  *                            {string} matrix
     57  *                              A string 'Matrix' (default) or 'Array'.
     58  *                            {string} number
     59  *                              A string 'number' (default), 'BigNumber', or 'Fraction'
     60  *                            {number} precision
     61  *                              The number of significant digits for BigNumbers.
     62  *                              Not applicable for Numbers.
     63  *                            {boolean} predictable
     64  *                              Predictable output type of functions. When true,
     65  *                              output type depends only on the input types. When
     66  *                              false (default), output type can vary depending
     67  *                              on input values. For example `math.sqrt(-4)`
     68  *                              returns `complex('2i')` when predictable is false, and
     69  *                              returns `NaN` when true.
     70  *                            {string} randomSeed
     71  *                              Random seed for seeded pseudo random number generator.
     72  *                              Set to null to randomly seed.
     73  * @returns {Object} Returns a bare-bone math.js instance containing
     74  *                   functions:
     75  *                   - `import` to add new functions
     76  *                   - `config` to change configuration
     77  *                   - `on`, `off`, `once`, `emit` for events
     78  */
     79 function create(factories, config) {
     80   var configInternal = (0, _extends2.default)({}, _config2.DEFAULT_CONFIG, config); // simple test for ES5 support
     81 
     82   if (typeof Object.create !== 'function') {
     83     throw new Error('ES5 not supported by this JavaScript engine. ' + 'Please load the es5-shim and es5-sham library for compatibility.');
     84   } // create the mathjs instance
     85 
     86 
     87   var math = emitter.mixin({
     88     // only here for backward compatibility for legacy factory functions
     89     isNumber: _is.isNumber,
     90     isComplex: _is.isComplex,
     91     isBigNumber: _is.isBigNumber,
     92     isFraction: _is.isFraction,
     93     isUnit: _is.isUnit,
     94     isString: _is.isString,
     95     isArray: _is.isArray,
     96     isMatrix: _is.isMatrix,
     97     isCollection: _is.isCollection,
     98     isDenseMatrix: _is.isDenseMatrix,
     99     isSparseMatrix: _is.isSparseMatrix,
    100     isRange: _is.isRange,
    101     isIndex: _is.isIndex,
    102     isBoolean: _is.isBoolean,
    103     isResultSet: _is.isResultSet,
    104     isHelp: _is.isHelp,
    105     isFunction: _is.isFunction,
    106     isDate: _is.isDate,
    107     isRegExp: _is.isRegExp,
    108     isObject: _is.isObject,
    109     isNull: _is.isNull,
    110     isUndefined: _is.isUndefined,
    111     isAccessorNode: _is.isAccessorNode,
    112     isArrayNode: _is.isArrayNode,
    113     isAssignmentNode: _is.isAssignmentNode,
    114     isBlockNode: _is.isBlockNode,
    115     isConditionalNode: _is.isConditionalNode,
    116     isConstantNode: _is.isConstantNode,
    117     isFunctionAssignmentNode: _is.isFunctionAssignmentNode,
    118     isFunctionNode: _is.isFunctionNode,
    119     isIndexNode: _is.isIndexNode,
    120     isNode: _is.isNode,
    121     isObjectNode: _is.isObjectNode,
    122     isOperatorNode: _is.isOperatorNode,
    123     isParenthesisNode: _is.isParenthesisNode,
    124     isRangeNode: _is.isRangeNode,
    125     isSymbolNode: _is.isSymbolNode,
    126     isChain: _is.isChain
    127   }); // load config function and apply provided config
    128 
    129   math.config = (0, _config.configFactory)(configInternal, math.emit);
    130   math.expression = {
    131     transform: {},
    132     mathWithTransform: {
    133       config: math.config
    134     }
    135   }; // cached factories and instances used by function load
    136 
    137   var legacyFactories = [];
    138   var legacyInstances = [];
    139   /**
    140    * Load a function or data type from a factory.
    141    * If the function or data type already exists, the existing instance is
    142    * returned.
    143    * @param {Function} factory
    144    * @returns {*}
    145    */
    146 
    147   function load(factory) {
    148     if ((0, _factory.isFactory)(factory)) {
    149       return factory(math);
    150     }
    151 
    152     var firstProperty = factory[Object.keys(factory)[0]];
    153 
    154     if ((0, _factory.isFactory)(firstProperty)) {
    155       return firstProperty(math);
    156     }
    157 
    158     if (!(0, _object.isLegacyFactory)(factory)) {
    159       console.warn('Factory object with properties `type`, `name`, and `factory` expected', factory);
    160       throw new Error('Factory object with properties `type`, `name`, and `factory` expected');
    161     }
    162 
    163     var index = legacyFactories.indexOf(factory);
    164     var instance;
    165 
    166     if (index === -1) {
    167       // doesn't yet exist
    168       if (factory.math === true) {
    169         // pass with math namespace
    170         instance = factory.factory(math.type, configInternal, load, math.typed, math);
    171       } else {
    172         instance = factory.factory(math.type, configInternal, load, math.typed);
    173       } // append to the cache
    174 
    175 
    176       legacyFactories.push(factory);
    177       legacyInstances.push(instance);
    178     } else {
    179       // already existing function, return the cached instance
    180       instance = legacyInstances[index];
    181     }
    182 
    183     return instance;
    184   }
    185 
    186   var importedFactories = {}; // load the import function
    187 
    188   function lazyTyped() {
    189     for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
    190       args[_key] = arguments[_key];
    191     }
    192 
    193     return math.typed.apply(math.typed, args);
    194   }
    195 
    196   var internalImport = (0, _import.importFactory)(lazyTyped, load, math, importedFactories);
    197   math.import = internalImport; // listen for changes in config, import all functions again when changed
    198   // TODO: move this listener into the import function?
    199 
    200   math.on('config', function () {
    201     (0, _object.values)(importedFactories).forEach(function (factory) {
    202       if (factory && factory.meta && factory.meta.recreateOnConfigChange) {
    203         // FIXME: only re-create when the current instance is the same as was initially created
    204         // FIXME: delete the functions/constants before importing them again?
    205         internalImport(factory, {
    206           override: true
    207         });
    208       }
    209     });
    210   }); // the create function exposed on the mathjs instance is bound to
    211   // the factory functions passed before
    212 
    213   math.create = create.bind(null, factories); // export factory function
    214 
    215   math.factory = _factory.factory; // import the factory functions like createAdd as an array instead of object,
    216   // else they will get a different naming (`createAdd` instead of `add`).
    217 
    218   math.import((0, _object.values)((0, _object.deepFlatten)(factories)));
    219   math.ArgumentsError = _ArgumentsError.ArgumentsError;
    220   math.DimensionError = _DimensionError.DimensionError;
    221   math.IndexError = _IndexError.IndexError;
    222   return math;
    223 }