UNPKG

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