create.js 9.1 KB

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