dataflux 1.6.1 → 1.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2022-present Massimo Candela
3
+ Copyright (c) 2022-present Massimo Candela <https://massimocandela.com>
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -276,6 +276,7 @@ All the possible options for a model creation are (they are all optional):
276
276
  | parseMoment | Automatically creates Moment.js objects out of ISO8601 strings. E.g., if an object has a property `createdAt: "2022-01-07T21:38:50.295Z"`, this will be transformed to a moment object. | |
277
277
  | hiddenFields | An array of attribute names that will never be sent back to the API. E.g., if you set `hiddenFields: ["pages"]`, a book object can contain an attribute `pages` locally, but this will be stripped out in PUT/POST requests. |
278
278
  | deep | A boolean defining if nested objects should be enriched with the object methods. | true |
279
+ | lazyLoad | A boolean defining if the model should be lazy loaded on the first use. This takes precedence over the lazyLoad declared during store initialization. | false |
279
280
 
280
281
  ### Operations
281
282
  As described in the table above, there are four possible operations: **retrieve, insert, update,** and **delete**. An operation can be defined as an operation object or a function.
@@ -341,28 +342,84 @@ const book = new Model("book", options);
341
342
 
342
343
  #### Operation function
343
344
 
344
- To be even more flexible, you can pass functions and handle yourself the operations. An operation function must return a promise, the promise must return an array of JSON objects when these are ready.
345
+ To be even more flexible, you can pass functions to generate the API urls or retrieve the data. An operation function can return a url or a promise. If the function returns a promise, the promise must resolve in an array of JSON objects when these are ready.
345
346
 
346
347
 
348
+ Example of operation function returning from the API and submitting to the API an array of JSON objects.
349
+
347
350
  ```js
348
351
  const options = {
349
352
  retrieve: () => {
350
353
  // 1) get the data from the API
351
354
  // 2) tranforms the data
352
355
  // 3) return the data to the store
353
- return Promise.resolve(data);
356
+ return axios({ // Example with axios, but you can use whatever you prefer
357
+ url: "https://api.example.net/example",
358
+ method: "get"
359
+ });
354
360
  },
355
361
  insert: (data) => {
356
362
  // 1) recieve the data from the store
357
363
  // 2) transform the data however you like
358
- // 3) send data to server and resolve empty
359
- return Promise.resolve();
364
+ // 3) send data to server
365
+ return axios({
366
+ url: "https://api.example.net/example",
367
+ data,
368
+ method: "post"
369
+ });
360
370
  }
361
371
  };
362
372
 
363
373
  const book = new Model("book", options);
364
374
  ```
365
375
 
376
+ #### Object factory
377
+
378
+ In the examples we saw above, objects are retrieved from an API returning one or more objects. However, sometimes object creation requires a more complex logic. This can be summarized as: the object must be created based on some input parameter
379
+
380
+ Typical examples are:
381
+ * There is no API returning all the objects of a given type, you can only access specific objects based on a parameter (e.g., based on the ID).
382
+ * It doesn't make sense to retrieve all the objects of a given type, since the client needs to access only to a subset of them.
383
+ * The APIs to get/post/put/delete objects are parametric (e.g., you need to specify the ID in the url).
384
+ * The model is polymorphic, and the final object's format is based on some parameter;
385
+ * The model is polymorphic, a different API is used to retrieve the objects based on some input parameter (e.g., they are all books, but there are different APIs by genre).
386
+
387
+ This is a well-know problem, described by the [factory design pattern](https://refactoring.guru/design-patterns/factory-method).
388
+ In DataFlux, the store provides for this use case the `.factory()` method that allows you to implement Factory.
389
+
390
+ To create a factory, you must declare a model as follows:
391
+
392
+ ```js
393
+ const author = new Model("author", {
394
+ lazyLoad: true, // It MUST be lazyLoaded
395
+ retrieve: (params) => { // The retrieve function now takes some parameters
396
+
397
+ if (params) {
398
+ // You can return a URL or directly one or more JSON objects
399
+ return `https://api.example.net/authors/${params.id}`
400
+ } else {
401
+ return Promise.resolve([]); // It's important to handle the base case where params is null
402
+ }
403
+ }
404
+ });
405
+
406
+ store.addModel(author);
407
+ ```
408
+
409
+ It is important to notice in the example above, how `lazyLoad` must be set to `true` and how the retrieve function returns a URL based on an input parameter. As always, the operation function can return a URL (DataFlux will download the objects) or directly a collection of objects.
410
+
411
+ > If you don't specify the insert/update/delete operation functions, the same URL of the retrieve function will be used.
412
+
413
+ Once the parametric retrieve function is declared, you can instantiate the objects with the `store.factory()` method:
414
+
415
+ ```js
416
+ store.factory("author", {id: 4});
417
+ ```
418
+ Invoking `store.factory()` will create a new object in the "author" collection.
419
+
420
+ > store.factory() will not return the object. It just inserts the object in the collection. You will need to use any of the usual .find/.findOne/.findAll/.subscribe to retrieve it.
421
+
422
+
366
423
  #### Object enrichment
367
424
 
368
425
  DataFlux objects can have a `load()` method which enables you to load extra attributes of an object.
@@ -526,13 +583,13 @@ You can operate on the reviews similarly to how you operate on the main model's
526
583
 
527
584
  ```js
528
585
  store.find("book")
529
- .then(([book]) => {
530
- const firstReview = book.reviews[0];
586
+ .then(([book]) => {
587
+ const firstReview = book.reviews[0];
531
588
 
532
- // Examples of what you can do:
533
- firstReview.detroy(); // The first review is removed from the array book.reviews
534
- firstReview.set("stars", 5); // Set the stars of the first review to 5
535
- });
589
+ // Examples of what you can do:
590
+ firstReview.detroy(); // The first review is removed from the array book.reviews
591
+ firstReview.set("stars", 5); // Set the stars of the first review to 5
592
+ });
536
593
  ```
537
594
 
538
595
 
package/dist/BasicObj.js CHANGED
@@ -48,7 +48,9 @@ function setValues(values, model, SubObj, parent, context) {
48
48
  context[key] = mmnt.isValid() ? mmnt : value;
49
49
  } else if (model.options.deep && value != null && _typeof(value) === "object" && !Array.isArray(value)) {
50
50
  context[key] = new SubObj(parent, key, value, model);
51
- } else if (model.options.deep && value != null && Array.isArray(value)) {
51
+ } else if (model.options.deep && value != null && Array.isArray(value) && !value.some(function (str) {
52
+ return ["string", "number"].includes(_typeof(str));
53
+ })) {
52
54
  context[key] = value.map(function (i) {
53
55
  return new SubObj(parent, key, i, model);
54
56
  });
package/dist/Model.js CHANGED
@@ -17,8 +17,6 @@ var _SubObj = _interopRequireDefault(require("./SubObj"));
17
17
 
18
18
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
19
19
 
20
- function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
21
-
22
20
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
23
21
 
24
22
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -31,6 +29,8 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
31
29
 
32
30
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
33
31
 
32
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
33
+
34
34
  function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
35
35
 
36
36
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
@@ -63,18 +63,6 @@ function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!priva
63
63
 
64
64
  function _classApplyDescriptorSet(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } }
65
65
 
66
- var applyData = function applyData(obj, data) {
67
- for (var att in data) {
68
- if (att !== "id" || obj.id === undefined || att === "id" && obj.id === data.id) {
69
- obj[att] = data[att];
70
- } else {
71
- return Promise.reject("The loading function cannot change the id of the object.");
72
- }
73
- }
74
-
75
- return Promise.resolve(obj);
76
- };
77
-
78
66
  var _type = /*#__PURE__*/new WeakMap();
79
67
 
80
68
  var _store = /*#__PURE__*/new WeakMap();
@@ -272,13 +260,11 @@ var Model = /*#__PURE__*/_createClass(function Model(name) {
272
260
 
273
261
  _defineProperty(this, "retrieveAll", function () {
274
262
  return (0, _modelHooksUtils.executeHook)("retrieve", _classPrivateFieldGet(_this, _retrieveHook), null, _classPrivateFieldGet(_this, _axios)).then(function (data) {
275
- if (Array.isArray(data)) {
276
- return data;
277
- } else {
263
+ if (!Array.isArray(data)) {
278
264
  _classPrivateFieldSet(_this, _singleItemQuery, true);
279
-
280
- return [data];
281
265
  }
266
+
267
+ return _classPrivateFieldGet(_this, _toArray).call(_this, data);
282
268
  });
283
269
  });
284
270
 
@@ -294,6 +280,14 @@ var Model = /*#__PURE__*/_createClass(function Model(name) {
294
280
  return objects.length ? _classPrivateFieldGet(_this, _bulkOperation).call(_this, objects, _classPrivateFieldGet(_this, _deleteObjects)) : Promise.resolve();
295
281
  });
296
282
 
283
+ _defineProperty(this, "factory", function (params) {
284
+ if (!_this.options.lazyLoad) {
285
+ return Promise.reject("Factory can be used only on a model declared with lazyLoad: true");
286
+ } else {
287
+ return (0, _modelHooksUtils.executeHook)("retrieve", _classPrivateFieldGet(_this, _retrieveHook), params, _classPrivateFieldGet(_this, _axios));
288
+ }
289
+ });
290
+
297
291
  _classPrivateFieldInitSpec(this, _addRelationByField, {
298
292
  writable: true,
299
293
  value: function value(model, localField) {
@@ -355,9 +349,23 @@ var Model = /*#__PURE__*/_createClass(function Model(name) {
355
349
  writable: true,
356
350
  value: function value(data) {
357
351
  if (Array.isArray(data)) {
358
- return data;
352
+ if (data.every(function (str) {
353
+ return ["string", "number"].includes(_typeof(str));
354
+ })) {
355
+ return [{
356
+ value: data
357
+ }];
358
+ } else {
359
+ return data;
360
+ }
359
361
  } else {
360
- return [data];
362
+ if (["string", "number"].includes(_typeof(data))) {
363
+ return [{
364
+ value: data
365
+ }];
366
+ } else {
367
+ return [data];
368
+ }
361
369
  }
362
370
  }
363
371
  });
@@ -387,7 +395,8 @@ var Model = /*#__PURE__*/_createClass(function Model(name) {
387
395
 
388
396
  this.options = _objectSpread(_objectSpread({}, options), {}, {
389
397
  deep: (_options$deep = options.deep) !== null && _options$deep !== void 0 ? _options$deep : true,
390
- parseMoment: (_options$parseMoment = options.parseMoment) !== null && _options$parseMoment !== void 0 ? _options$parseMoment : false
398
+ parseMoment: (_options$parseMoment = options.parseMoment) !== null && _options$parseMoment !== void 0 ? _options$parseMoment : false,
399
+ lazyLoad: options.lazyLoad
391
400
  });
392
401
 
393
402
  _classPrivateFieldSet(this, _store, null);
package/dist/PubSub.js CHANGED
@@ -19,6 +19,29 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
19
19
 
20
20
  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; }
21
21
 
22
+ /*
23
+ * MIT License
24
+ *
25
+ * Copyright (c) 2022 Massimo Candela <https://massimocandela.com>
26
+ *
27
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
28
+ * of this software and associated documentation files (the "Software"), to deal
29
+ * in the Software without restriction, including without limitation the rights
30
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
31
+ * copies of the Software, and to permit persons to whom the Software is
32
+ * furnished to do so, subject to the following conditions:
33
+ *
34
+ * The above copyright notice and this permission notice shall be included in all
35
+ * copies or substantial portions of the Software.
36
+ *
37
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
38
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
39
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
40
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
41
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
42
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
43
+ * SOFTWARE.
44
+ */
22
45
  var PubSub = /*#__PURE__*/_createClass(function PubSub() {
23
46
  var _this = this;
24
47
 
package/dist/Store.js CHANGED
@@ -29,6 +29,8 @@ function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclarati
29
29
 
30
30
  function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
31
31
 
32
+ 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; }
33
+
32
34
  function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); }
33
35
 
34
36
  function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); }
@@ -67,6 +69,10 @@ var Store = /*#__PURE__*/function () {
67
69
 
68
70
  _classPrivateMethodInitSpec(this, _error);
69
71
 
72
+ _defineProperty(this, "getModels", function () {
73
+ return Object.keys(_this.models);
74
+ });
75
+
70
76
  _classPrivateFieldInitSpec(this, _deleteByObject, {
71
77
  writable: true,
72
78
  value: function value(object) {
@@ -114,16 +120,19 @@ var Store = /*#__PURE__*/function () {
114
120
  var type = model.getType();
115
121
 
116
122
  if (!_this2.models[type]) {
123
+ var _model$options$lazyLo;
124
+
117
125
  _this2.models[type] = {
118
126
  model: model,
119
127
  storedObjects: {}
120
128
  };
121
129
  model.setStore(_this2);
130
+ var lazyLoad = (_model$options$lazyLo = model.options.lazyLoad) !== null && _model$options$lazyLo !== void 0 ? _model$options$lazyLo : _this2.options.lazyLoad;
122
131
 
123
- if (!_this2.options.lazyLoad) {
124
- resolve(_classPrivateMethodGet(_this2, _loadObjects, _loadObjects2).call(_this2, type));
125
- } else {
132
+ if (lazyLoad) {
126
133
  resolve();
134
+ } else {
135
+ resolve(_classPrivateMethodGet(_this2, _loadObjects, _loadObjects2).call(_this2, type));
127
136
  }
128
137
  } else {
129
138
  var error = "The model already exists";
@@ -290,6 +299,38 @@ var Store = /*#__PURE__*/function () {
290
299
  };
291
300
  });
292
301
  }
302
+ }, {
303
+ key: "factory",
304
+ value: function factory(type, params) {
305
+ var _this8 = this;
306
+
307
+ var item = this.models[type];
308
+ this.pubSub.publish("loading", {
309
+ status: "start",
310
+ model: type
311
+ });
312
+ return item.promise = item.model.factory(params).then(function (items) {
313
+ var _iterator3 = _createForOfIteratorHelper(items),
314
+ _step3;
315
+
316
+ try {
317
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
318
+ var _item = _step3.value;
319
+
320
+ _classPrivateMethodGet(_this8, _insertObject, _insertObject2).call(_this8, type, _item, false);
321
+ }
322
+ } catch (err) {
323
+ _iterator3.e(err);
324
+ } finally {
325
+ _iterator3.f();
326
+ }
327
+
328
+ _this8.pubSub.publish("loading", {
329
+ status: "end",
330
+ model: type
331
+ });
332
+ });
333
+ }
293
334
  }]);
294
335
 
295
336
  return Store;
@@ -304,25 +345,25 @@ function _error2(error) {
304
345
  }
305
346
 
306
347
  function _deleteByFilter2(type, filterFunction) {
307
- var _this8 = this;
348
+ var _this9 = this;
308
349
 
309
350
  return _classPrivateMethodGet(this, _getPromise, _getPromise2).call(this, type).then(function () {
310
- var deleted = Object.values(_this8.models[type].storedObjects).filter(function (i) {
351
+ var deleted = Object.values(_this9.models[type].storedObjects).filter(function (i) {
311
352
  return filterFunction(i.object);
312
353
  });
313
354
 
314
- var _iterator3 = _createForOfIteratorHelper(deleted),
315
- _step3;
355
+ var _iterator4 = _createForOfIteratorHelper(deleted),
356
+ _step4;
316
357
 
317
358
  try {
318
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
319
- var object = _step3.value;
359
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
360
+ var object = _step4.value;
320
361
  object.status = "deleted";
321
362
  }
322
363
  } catch (err) {
323
- _iterator3.e(err);
364
+ _iterator4.e(err);
324
365
  } finally {
325
- _iterator3.f();
366
+ _iterator4.f();
326
367
  }
327
368
 
328
369
  return deleted.map(function (i) {
@@ -332,7 +373,7 @@ function _deleteByFilter2(type, filterFunction) {
332
373
  }
333
374
 
334
375
  function _getPromise2(type) {
335
- var _this9 = this;
376
+ var _this10 = this;
336
377
 
337
378
  if (!this.models[type]) {
338
379
  return Promise.reject("The model doesn't exist");
@@ -340,7 +381,7 @@ function _getPromise2(type) {
340
381
  return Promise.reject("The model is not loaded");
341
382
  } else if (!this.models[type].promise && this.options.lazyLoad) {
342
383
  return _classPrivateMethodGet(this, _loadObjects, _loadObjects2).call(this, type).then(function () {
343
- return _this9.models[type].promise;
384
+ return _this10.models[type].promise;
344
385
  });
345
386
  } else {
346
387
  return this.models[type].promise;
@@ -367,7 +408,7 @@ function _insertObject2(type, item) {
367
408
  }
368
409
 
369
410
  function _loadObjects2(type) {
370
- var _this10 = this;
411
+ var _this11 = this;
371
412
 
372
413
  var item = this.models[type];
373
414
  this.pubSub.publish("loading", {
@@ -375,22 +416,22 @@ function _loadObjects2(type) {
375
416
  model: type
376
417
  });
377
418
  return item.promise = item.model.retrieveAll().then(function (items) {
378
- var _iterator4 = _createForOfIteratorHelper(items),
379
- _step4;
419
+ var _iterator5 = _createForOfIteratorHelper(items),
420
+ _step5;
380
421
 
381
422
  try {
382
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
383
- var _item = _step4.value;
423
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
424
+ var _item2 = _step5.value;
384
425
 
385
- _classPrivateMethodGet(_this10, _insertObject, _insertObject2).call(_this10, type, _item, false);
426
+ _classPrivateMethodGet(_this11, _insertObject, _insertObject2).call(_this11, type, _item2, false);
386
427
  }
387
428
  } catch (err) {
388
- _iterator4.e(err);
429
+ _iterator5.e(err);
389
430
  } finally {
390
- _iterator4.f();
431
+ _iterator5.f();
391
432
  }
392
433
 
393
- _this10.pubSub.publish("loading", {
434
+ _this11.pubSub.publish("loading", {
394
435
  status: "end",
395
436
  model: type
396
437
  });
@@ -65,7 +65,18 @@ var createHookItem = function createHookItem(optionItem, defaultMethod, defaultU
65
65
 
66
66
  case "function":
67
67
  return function (data) {
68
- return Promise.resolve(optionItem(data));
68
+ var res = optionItem(data);
69
+
70
+ if (typeof res === "string") {
71
+ return {
72
+ method: defaultMethod,
73
+ url: res,
74
+ fields: options.fields || [],
75
+ headers: options.headers || {}
76
+ };
77
+ } else {
78
+ return Promise.resolve(res);
79
+ }
69
80
  };
70
81
 
71
82
  case "object":
@@ -114,7 +125,13 @@ var executeHook = function executeHook(type, hook, data, axios) {
114
125
  return getDataStringHook(hook, data, axios);
115
126
 
116
127
  case "function":
117
- return hook(data);
128
+ var res = hook(data);
129
+
130
+ if (res.method && res.url && res.headers) {
131
+ return getDataStringHook(res, data, axios);
132
+ } else {
133
+ return res;
134
+ }
118
135
 
119
136
  default:
120
137
  return Promise.reject("The ".concat(type, " hook must be a URL or a function returning a promise"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dataflux",
3
- "version": "1.6.1",
3
+ "version": "1.7.2",
4
4
  "description": "DataFlux, automatically interfaces with your REST APIs to create a 2-way-synced local data store. Transparently manages data propagation in the React state.",
5
5
  "main": "dist/index.js",
6
6
  "bin": "dist/index.js",
package/CNAME DELETED
@@ -1 +0,0 @@
1
- dataflux.js.org
package/_config.yml DELETED
@@ -1 +0,0 @@
1
- theme: jekyll-theme-cayman