UNPKG

5.38 kBJavaScriptView Raw
1import { isChain } from '../../utils/is.js';
2import { format } from '../../utils/string.js';
3import { hasOwnProperty, lazy } from '../../utils/object.js';
4import { factory } from '../../utils/factory.js';
5var name = 'Chain';
6var dependencies = ['?on', 'math'];
7export var createChainClass = /* #__PURE__ */factory(name, dependencies, (_ref) => {
8 var {
9 on,
10 math
11 } = _ref;
12
13 /**
14 * @constructor Chain
15 * Wrap any value in a chain, allowing to perform chained operations on
16 * the value.
17 *
18 * All methods available in the math.js library can be called upon the chain,
19 * and then will be evaluated with the value itself as first argument.
20 * The chain can be closed by executing chain.done(), which will return
21 * the final value.
22 *
23 * The Chain has a number of special functions:
24 * - done() Finalize the chained operation and return the
25 * chain's value.
26 * - valueOf() The same as done()
27 * - toString() Returns a string representation of the chain's value.
28 *
29 * @param {*} [value]
30 */
31 function Chain(value) {
32 if (!(this instanceof Chain)) {
33 throw new SyntaxError('Constructor must be called with the new operator');
34 }
35
36 if (isChain(value)) {
37 this.value = value.value;
38 } else {
39 this.value = value;
40 }
41 }
42 /**
43 * Attach type information
44 */
45
46
47 Chain.prototype.type = 'Chain';
48 Chain.prototype.isChain = true;
49 /**
50 * Close the chain. Returns the final value.
51 * Does the same as method valueOf()
52 * @returns {*} value
53 */
54
55 Chain.prototype.done = function () {
56 return this.value;
57 };
58 /**
59 * Close the chain. Returns the final value.
60 * Does the same as method done()
61 * @returns {*} value
62 */
63
64
65 Chain.prototype.valueOf = function () {
66 return this.value;
67 };
68 /**
69 * Get a string representation of the value in the chain
70 * @returns {string}
71 */
72
73
74 Chain.prototype.toString = function () {
75 return format(this.value);
76 };
77 /**
78 * Get a JSON representation of the chain
79 * @returns {Object}
80 */
81
82
83 Chain.prototype.toJSON = function () {
84 return {
85 mathjs: 'Chain',
86 value: this.value
87 };
88 };
89 /**
90 * Instantiate a Chain from its JSON representation
91 * @param {Object} json An object structured like
92 * `{"mathjs": "Chain", value: ...}`,
93 * where mathjs is optional
94 * @returns {Chain}
95 */
96
97
98 Chain.fromJSON = function (json) {
99 return new Chain(json.value);
100 };
101 /**
102 * Create a proxy method for the chain
103 * @param {string} name
104 * @param {Function} fn The function to be proxied
105 * If fn is no function, it is silently ignored.
106 * @private
107 */
108
109
110 function createProxy(name, fn) {
111 if (typeof fn === 'function') {
112 Chain.prototype[name] = chainify(fn);
113 }
114 }
115 /**
116 * Create a proxy method for the chain
117 * @param {string} name
118 * @param {function} resolver The function resolving with the
119 * function to be proxied
120 * @private
121 */
122
123
124 function createLazyProxy(name, resolver) {
125 lazy(Chain.prototype, name, function outerResolver() {
126 var fn = resolver();
127
128 if (typeof fn === 'function') {
129 return chainify(fn);
130 }
131
132 return undefined; // if not a function, ignore
133 });
134 }
135 /**
136 * Make a function chainable
137 * @param {function} fn
138 * @return {Function} chain function
139 * @private
140 */
141
142
143 function chainify(fn) {
144 return function () {
145 var args = [this.value]; // `this` will be the context of a Chain instance
146
147 for (var i = 0; i < arguments.length; i++) {
148 args[i + 1] = arguments[i];
149 }
150
151 return new Chain(fn.apply(fn, args));
152 };
153 }
154 /**
155 * Create a proxy for a single method, or an object with multiple methods.
156 * Example usage:
157 *
158 * Chain.createProxy('add', function add (x, y) {...})
159 * Chain.createProxy({
160 * add: function add (x, y) {...},
161 * subtract: function subtract (x, y) {...}
162 * }
163 *
164 * @param {string | Object} arg0 A name (string), or an object with
165 * functions
166 * @param {*} [arg1] A function, when arg0 is a name
167 */
168
169
170 Chain.createProxy = function (arg0, arg1) {
171 if (typeof arg0 === 'string') {
172 // createProxy(name, value)
173 createProxy(arg0, arg1);
174 } else {
175 var _loop = function _loop(_name) {
176 if (hasOwnProperty(arg0, _name) && excludedNames[_name] === undefined) {
177 createLazyProxy(_name, () => arg0[_name]);
178 }
179 };
180
181 // createProxy(values)
182 for (var _name in arg0) {
183 _loop(_name);
184 }
185 }
186 };
187
188 var excludedNames = {
189 expression: true,
190 docs: true,
191 type: true,
192 classes: true,
193 json: true,
194 error: true,
195 isChain: true // conflicts with the property isChain of a Chain instance
196
197 }; // create proxy for everything that is in math.js
198
199 Chain.createProxy(math); // register on the import event, automatically add a proxy for every imported function.
200
201 if (on) {
202 on('import', function (name, resolver, path) {
203 if (!path) {
204 // an imported function (not a data type or something special)
205 createLazyProxy(name, resolver);
206 }
207 });
208 }
209
210 return Chain;
211}, {
212 isClass: true
213});
\No newline at end of file