1 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
2 |
|
3 | function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
4 |
|
5 | import { isBigNumber, isComplex, isFraction, isMatrix, isUnit } from '../../utils/is';
|
6 | import { isFactory, stripOptionalNotation } from '../../utils/factory';
|
7 | import { hasOwnProperty, isLegacyFactory, lazy, traverse } from '../../utils/object';
|
8 | import { contains } from '../../utils/array';
|
9 | import { ArgumentsError } from '../../error/ArgumentsError';
|
10 | import { warnOnce } from '../../utils/log';
|
11 | export function importFactory(typed, load, math, importedFactories) {
|
12 | |
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 | function mathImport(functions, options) {
|
68 | var num = arguments.length;
|
69 |
|
70 | if (num !== 1 && num !== 2) {
|
71 | throw new ArgumentsError('import', num, 1, 2);
|
72 | }
|
73 |
|
74 | if (!options) {
|
75 | options = {};
|
76 | }
|
77 |
|
78 | function flattenImports(flatValues, value, name) {
|
79 | if (isLegacyFactory(value)) {
|
80 |
|
81 |
|
82 | _importLegacyFactory(value, options);
|
83 | } else if (Array.isArray(value)) {
|
84 | value.forEach(function (item) {
|
85 | return flattenImports(flatValues, item);
|
86 | });
|
87 | } else if (_typeof(value) === 'object') {
|
88 | for (var _name in value) {
|
89 | if (hasOwnProperty(value, _name)) {
|
90 | flattenImports(flatValues, value[_name], _name);
|
91 | }
|
92 | }
|
93 | } else if (isFactory(value) || name !== undefined) {
|
94 | var flatName = isFactory(value) ? isTransformFunctionFactory(value) ? value.fn + '.transform' :
|
95 | value.fn : name;
|
96 |
|
97 | if (hasOwnProperty(flatValues, flatName) && flatValues[flatName] !== value && !options.silent) {
|
98 | throw new Error('Cannot import "' + flatName + '" twice');
|
99 | }
|
100 |
|
101 | flatValues[flatName] = value;
|
102 | } else {
|
103 | if (!options.silent) {
|
104 | throw new TypeError('Factory, Object, or Array expected');
|
105 | }
|
106 | }
|
107 | }
|
108 |
|
109 | var flatValues = {};
|
110 | flattenImports(flatValues, functions);
|
111 |
|
112 | for (var name in flatValues) {
|
113 | if (hasOwnProperty(flatValues, name)) {
|
114 |
|
115 | var value = flatValues[name];
|
116 |
|
117 | if (isFactory(value)) {
|
118 |
|
119 |
|
120 |
|
121 | _importFactory(value, options);
|
122 | } else if (isSupportedType(value)) {
|
123 | _import(name, value, options);
|
124 | } else {
|
125 | if (!options.silent) {
|
126 | throw new TypeError('Factory, Object, or Array expected');
|
127 | }
|
128 | }
|
129 | }
|
130 | }
|
131 | }
|
132 | |
133 |
|
134 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 | function _import(name, value, options) {
|
142 |
|
143 | if (options.wrap && typeof value === 'function') {
|
144 |
|
145 | value = _wrap(value);
|
146 | }
|
147 |
|
148 |
|
149 | if (hasTypedFunctionSignature(value)) {
|
150 | value = typed(name, _defineProperty({}, value.signature, value));
|
151 | }
|
152 |
|
153 | if (isTypedFunction(math[name]) && isTypedFunction(value)) {
|
154 | if (options.override) {
|
155 |
|
156 | value = typed(name, value.signatures);
|
157 | } else {
|
158 |
|
159 | value = typed(math[name], value);
|
160 | }
|
161 |
|
162 | math[name] = value;
|
163 | delete importedFactories[name];
|
164 |
|
165 | _importTransform(name, value);
|
166 |
|
167 | math.emit('import', name, function resolver() {
|
168 | return value;
|
169 | });
|
170 | return;
|
171 | }
|
172 |
|
173 | if (math[name] === undefined || options.override) {
|
174 | math[name] = value;
|
175 | delete importedFactories[name];
|
176 |
|
177 | _importTransform(name, value);
|
178 |
|
179 | math.emit('import', name, function resolver() {
|
180 | return value;
|
181 | });
|
182 | return;
|
183 | }
|
184 |
|
185 | if (!options.silent) {
|
186 | throw new Error('Cannot import "' + name + '": already exists');
|
187 | }
|
188 | }
|
189 |
|
190 | function _importTransform(name, value) {
|
191 | if (value && typeof value.transform === 'function') {
|
192 | math.expression.transform[name] = value.transform;
|
193 |
|
194 | if (allowedInExpressions(name)) {
|
195 | math.expression.mathWithTransform[name] = value.transform;
|
196 | }
|
197 | } else {
|
198 |
|
199 | delete math.expression.transform[name];
|
200 |
|
201 | if (allowedInExpressions(name)) {
|
202 | math.expression.mathWithTransform[name] = value;
|
203 | }
|
204 | }
|
205 | }
|
206 |
|
207 | function _deleteTransform(name) {
|
208 | delete math.expression.transform[name];
|
209 |
|
210 | if (allowedInExpressions(name)) {
|
211 | math.expression.mathWithTransform[name] = math[name];
|
212 | } else {
|
213 | delete math.expression.mathWithTransform[name];
|
214 | }
|
215 | }
|
216 | |
217 |
|
218 |
|
219 |
|
220 |
|
221 |
|
222 |
|
223 |
|
224 |
|
225 | function _wrap(fn) {
|
226 | var wrapper = function wrapper() {
|
227 | var args = [];
|
228 |
|
229 | for (var i = 0, len = arguments.length; i < len; i++) {
|
230 | var arg = arguments[i];
|
231 | args[i] = arg && arg.valueOf();
|
232 | }
|
233 |
|
234 | return fn.apply(math, args);
|
235 | };
|
236 |
|
237 | if (fn.transform) {
|
238 | wrapper.transform = fn.transform;
|
239 | }
|
240 |
|
241 | return wrapper;
|
242 | }
|
243 | |
244 |
|
245 |
|
246 |
|
247 |
|
248 |
|
249 |
|
250 |
|
251 |
|
252 | function _importLegacyFactory(factory, options) {
|
253 | warnOnce('Factories of type { name, factory } are deprecated since v6. ' + 'Please create your factory functions using the math.factory function.');
|
254 |
|
255 | if (typeof factory.name === 'string') {
|
256 | var name = factory.name;
|
257 | var existingTransform = name in math.expression.transform;
|
258 | var namespace = factory.path ? traverse(math, factory.path) : math;
|
259 | var existing = hasOwnProperty(namespace, name) ? namespace[name] : undefined;
|
260 |
|
261 | var resolver = function resolver() {
|
262 | var instance = load(factory);
|
263 |
|
264 | if (instance && typeof instance.transform === 'function') {
|
265 | throw new Error('Transforms cannot be attached to factory functions. ' + 'Please create a separate function for it with exports.path="expression.transform"');
|
266 | }
|
267 |
|
268 | if (isTypedFunction(existing) && isTypedFunction(instance)) {
|
269 | if (options.override) {
|
270 | } else {
|
271 |
|
272 | instance = typed(existing, instance);
|
273 | }
|
274 |
|
275 | return instance;
|
276 | }
|
277 |
|
278 | if (existing === undefined || options.override) {
|
279 | return instance;
|
280 | }
|
281 |
|
282 | if (options.silent) {
|
283 | return existing;
|
284 | } else {
|
285 | throw new Error('Cannot import "' + name + '": already exists');
|
286 | }
|
287 | };
|
288 |
|
289 | if (factory.lazy !== false) {
|
290 | lazy(namespace, name, resolver);
|
291 |
|
292 | if (existingTransform) {
|
293 | _deleteTransform(name);
|
294 | } else {
|
295 | if (factory.path === 'expression.transform' || legacyFactoryAllowedInExpressions(factory)) {
|
296 | lazy(math.expression.mathWithTransform, name, resolver);
|
297 | }
|
298 | }
|
299 | } else {
|
300 | namespace[name] = resolver();
|
301 |
|
302 | if (existingTransform) {
|
303 | _deleteTransform(name);
|
304 | } else {
|
305 | if (factory.path === 'expression.transform' || legacyFactoryAllowedInExpressions(factory)) {
|
306 | math.expression.mathWithTransform[name] = resolver();
|
307 | }
|
308 | }
|
309 | }
|
310 |
|
311 | var key = factory.path ? factory.path + '.' + factory.name : factory.name;
|
312 | importedFactories[key] = factory;
|
313 | math.emit('import', name, resolver, factory.path);
|
314 | } else {
|
315 |
|
316 |
|
317 | load(factory);
|
318 | }
|
319 | }
|
320 | |
321 |
|
322 |
|
323 |
|
324 |
|
325 |
|
326 |
|
327 |
|
328 |
|
329 | function _importFactory(factory, options) {
|
330 | var name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : factory.fn;
|
331 |
|
332 | if (contains(name, '.')) {
|
333 | throw new Error('Factory name should not contain a nested path. ' + 'Name: ' + JSON.stringify(name));
|
334 | }
|
335 |
|
336 | var namespace = isTransformFunctionFactory(factory) ? math.expression.transform : math;
|
337 | var existingTransform = name in math.expression.transform;
|
338 | var existing = hasOwnProperty(namespace, name) ? namespace[name] : undefined;
|
339 |
|
340 | var resolver = function resolver() {
|
341 |
|
342 | var dependencies = {};
|
343 | factory.dependencies.map(stripOptionalNotation).forEach(function (dependency) {
|
344 | if (contains(dependency, '.')) {
|
345 | throw new Error('Factory dependency should not contain a nested path. ' + 'Name: ' + JSON.stringify(dependency));
|
346 | }
|
347 |
|
348 | if (dependency === 'math') {
|
349 | dependencies.math = math;
|
350 | } else if (dependency === 'mathWithTransform') {
|
351 | dependencies.mathWithTransform = math.expression.mathWithTransform;
|
352 | } else if (dependency === 'classes') {
|
353 |
|
354 | dependencies.classes = math;
|
355 | } else {
|
356 | dependencies[dependency] = math[dependency];
|
357 | }
|
358 | });
|
359 | var instance =
|
360 |
|
361 | factory(dependencies);
|
362 |
|
363 | if (instance && typeof instance.transform === 'function') {
|
364 | throw new Error('Transforms cannot be attached to factory functions. ' + 'Please create a separate function for it with exports.path="expression.transform"');
|
365 | }
|
366 |
|
367 | if (existing === undefined || options.override) {
|
368 | return instance;
|
369 | }
|
370 |
|
371 | if (isTypedFunction(existing) && isTypedFunction(instance)) {
|
372 |
|
373 | return typed(existing, instance);
|
374 | }
|
375 |
|
376 | if (options.silent) {
|
377 |
|
378 | return existing;
|
379 | } else {
|
380 | throw new Error('Cannot import "' + name + '": already exists');
|
381 | }
|
382 | };
|
383 |
|
384 |
|
385 | if (!factory.meta || factory.meta.lazy !== false) {
|
386 | lazy(namespace, name, resolver);
|
387 |
|
388 | if (existing && existingTransform) {
|
389 | _deleteTransform(name);
|
390 | } else {
|
391 | if (isTransformFunctionFactory(factory) || factoryAllowedInExpressions(factory)) {
|
392 | lazy(math.expression.mathWithTransform, name, function () {
|
393 | return namespace[name];
|
394 | });
|
395 | }
|
396 | }
|
397 | } else {
|
398 | namespace[name] = resolver();
|
399 |
|
400 | if (existing && existingTransform) {
|
401 | _deleteTransform(name);
|
402 | } else {
|
403 | if (isTransformFunctionFactory(factory) || factoryAllowedInExpressions(factory)) {
|
404 | lazy(math.expression.mathWithTransform, name, function () {
|
405 | return namespace[name];
|
406 | });
|
407 | }
|
408 | }
|
409 | }
|
410 |
|
411 |
|
412 | importedFactories[name] = factory;
|
413 | math.emit('import', name, resolver);
|
414 | }
|
415 | |
416 |
|
417 |
|
418 |
|
419 |
|
420 |
|
421 |
|
422 |
|
423 | function isSupportedType(object) {
|
424 | return typeof object === 'function' || typeof object === 'number' || typeof object === 'string' || typeof object === 'boolean' || object === null || isUnit(object) || isComplex(object) || isBigNumber(object) || isFraction(object) || isMatrix(object) || Array.isArray(object);
|
425 | }
|
426 | |
427 |
|
428 |
|
429 |
|
430 |
|
431 |
|
432 |
|
433 | function isTypedFunction(fn) {
|
434 | return typeof fn === 'function' && _typeof(fn.signatures) === 'object';
|
435 | }
|
436 |
|
437 | function hasTypedFunctionSignature(fn) {
|
438 | return typeof fn === 'function' && typeof fn.signature === 'string';
|
439 | }
|
440 |
|
441 | function allowedInExpressions(name) {
|
442 | return !hasOwnProperty(unsafe, name);
|
443 | }
|
444 |
|
445 | function legacyFactoryAllowedInExpressions(factory) {
|
446 | return factory.path === undefined && !hasOwnProperty(unsafe, factory.name);
|
447 | }
|
448 |
|
449 | function factoryAllowedInExpressions(factory) {
|
450 | return factory.fn.indexOf('.') === -1 &&
|
451 | !hasOwnProperty(unsafe, factory.fn) && (!factory.meta || !factory.meta.isClass);
|
452 | }
|
453 |
|
454 | function isTransformFunctionFactory(factory) {
|
455 | return factory !== undefined && factory.meta !== undefined && factory.meta.isTransformFunction === true || false;
|
456 | }
|
457 |
|
458 |
|
459 | var unsafe = {
|
460 | expression: true,
|
461 | type: true,
|
462 | docs: true,
|
463 | error: true,
|
464 | json: true,
|
465 | chain: true
|
466 |
|
467 | };
|
468 | return mathImport;
|
469 | } |
\ | No newline at end of file |