dataflux 1.3.0 → 1.4.0
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/README.md +14 -14
- package/dist/Model.js +40 -6
- package/dist/Obj.js +17 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -261,18 +261,18 @@ const book = new Model("book", options);
|
|
|
261
261
|
|
|
262
262
|
All the possible options for a model creation are (they are all optional):
|
|
263
263
|
|
|
264
|
-
| Name
|
|
265
|
-
|
|
266
|
-
| retrieve
|
|
267
|
-
| insert
|
|
268
|
-
| update
|
|
269
|
-
| delete
|
|
270
|
-
| fields
|
|
271
|
-
| headers
|
|
272
|
-
| load
|
|
273
|
-
| axios
|
|
274
|
-
| parseMoment
|
|
275
|
-
|
|
264
|
+
| Name | Description | Default |
|
|
265
|
+
|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------|
|
|
266
|
+
| retrieve | Describes the operation to retrieve the collection of objects from the REST API. It can be an operation object or a function. See [operations](#operations). | `{method: "get"}` |
|
|
267
|
+
| insert | Describes the operation to insert a new object in the collection. It can be an operation object or a function. See [operations](#operations). | `{method: "post"}` |
|
|
268
|
+
| update | Describes the operation to update objects of the collection. It can be an operation object or a function. See [operations](#operations). | `{method: "put"}` |
|
|
269
|
+
| delete | Describes the operation to remove objects from the collection. It can be an operation object or a function. See [operations](#operations). | `{method: "delete"}` |
|
|
270
|
+
| fields | An array of strings defining which attributes the retrieved objects should have. Essentially, it allows you to contemporarily specify the [X-Fields header](https://flask-restplus.readthedocs.io/en/stable/mask.html) and the [fields GET parameter](https://developers.google.com/slides/api/guides/performance#partial). This reduces transfer size and memory usage. E.g., if you have a collection of books, of which you are interested only in the name, you can define `fields: ["name"]`. In combination with `load` it allows for partial lazy load of the objects. | All the fields |
|
|
271
|
+
| headers | A dictionary of headers for the HTTP request. E.g., `{"Authorization": "bearer XXXX"}`. | No headers |
|
|
272
|
+
| load | A function that allows to enrich the objects on demand. E.g., you can use `fields` to download only the titles of a collection of books, and `load` to load completely the object. See [object enrichment](#object-enrichment). |
|
|
273
|
+
| axios | It allows to specify an axios instance to be used for the queries. If not specified, a new one will be used. | A new axios instance |
|
|
274
|
+
| 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. | |
|
|
275
|
+
| 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. |
|
|
276
276
|
|
|
277
277
|
### Operations
|
|
278
278
|
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.
|
|
@@ -484,7 +484,7 @@ Each object created is enriched with the following methods.
|
|
|
484
484
|
| Method | Description |
|
|
485
485
|
|------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
486
486
|
| getId() | It returns a unique ID used by the store to identify the object. The ID is unique inside a single model. Be aware, `object.id` and `objet.getId()` may return different values, since store's IDs can be different from the one of the REST API. |
|
|
487
|
-
| set(attribute, value)
|
|
487
|
+
| set(attribute, value, hidden) | A method to set an attribute to the object. It provides some advantages compared to doing `object.attribute = value`, these are discussed in [below](#editing-objects). |
|
|
488
488
|
| save() | Method to save the object. You can do `store.save()` instead. |
|
|
489
489
|
| destroy() | Method to delete the object. You can do `store.delete()` instead. |
|
|
490
490
|
| get(attribute) | If you like symmetry and since you do `.set()` you would like to do also `.get()` of the attributes. It does not provide any advantage compared to accessing directly the attribute (e.g., `author.name`). |
|
|
@@ -518,7 +518,7 @@ The option `autoSave` can be `true`, `false`, or a number (milliseconds).
|
|
|
518
518
|
|
|
519
519
|
The store will perform as if the `autoSave` was set to `true`; hence, changes performed with `.set(attribute, value)` are synced. However, it will periodically attempt also a `store.save()`. Since `store.save()` is always able to recognize edited objects, also changes directly operated on an attribute of the object (`object.name = "Dante"`) are synced.
|
|
520
520
|
|
|
521
|
-
|
|
521
|
+
> The method set takes 3 parameters in input, "attribute, value, hidden". The "hidden" parameter allows you to set an attribute to the object that will not trigger autoSave. However, hidden attributes cannot be persisted (they act like "hiddenFields" specified during model creation).
|
|
522
522
|
|
|
523
523
|
## API interaction
|
|
524
524
|
DataFlux is able to identify three sets of objects: inserted, updated, deleted.
|
package/dist/Model.js
CHANGED
|
@@ -19,14 +19,16 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra
|
|
|
19
19
|
|
|
20
20
|
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."); }
|
|
21
21
|
|
|
22
|
-
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); }
|
|
23
|
-
|
|
24
|
-
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
25
|
-
|
|
26
22
|
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
27
23
|
|
|
28
24
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
29
25
|
|
|
26
|
+
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; } } }; }
|
|
27
|
+
|
|
28
|
+
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); }
|
|
29
|
+
|
|
30
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
31
|
+
|
|
30
32
|
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
|
31
33
|
|
|
32
34
|
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
@@ -87,12 +89,16 @@ var _axios = /*#__PURE__*/new WeakMap();
|
|
|
87
89
|
|
|
88
90
|
var _loadFunction = /*#__PURE__*/new WeakMap();
|
|
89
91
|
|
|
92
|
+
var _hiddenFields = /*#__PURE__*/new WeakMap();
|
|
93
|
+
|
|
90
94
|
var _error = /*#__PURE__*/new WeakSet();
|
|
91
95
|
|
|
92
96
|
var _addRelationByField = /*#__PURE__*/new WeakMap();
|
|
93
97
|
|
|
94
98
|
var _addRelationByFilter = /*#__PURE__*/new WeakMap();
|
|
95
99
|
|
|
100
|
+
var _removeHiddenFields = /*#__PURE__*/new WeakMap();
|
|
101
|
+
|
|
96
102
|
var _bulkOperation = /*#__PURE__*/new WeakMap();
|
|
97
103
|
|
|
98
104
|
var _toArray = /*#__PURE__*/new WeakMap();
|
|
@@ -167,6 +173,11 @@ var Model = /*#__PURE__*/_createClass(function Model(name) {
|
|
|
167
173
|
value: void 0
|
|
168
174
|
});
|
|
169
175
|
|
|
176
|
+
_classPrivateFieldInitSpec(this, _hiddenFields, {
|
|
177
|
+
writable: true,
|
|
178
|
+
value: void 0
|
|
179
|
+
});
|
|
180
|
+
|
|
170
181
|
_defineProperty(this, "getStore", function () {
|
|
171
182
|
return _classPrivateFieldGet(_this, _store);
|
|
172
183
|
});
|
|
@@ -293,16 +304,37 @@ var Model = /*#__PURE__*/_createClass(function Model(name) {
|
|
|
293
304
|
}
|
|
294
305
|
});
|
|
295
306
|
|
|
307
|
+
_classPrivateFieldInitSpec(this, _removeHiddenFields, {
|
|
308
|
+
writable: true,
|
|
309
|
+
value: function value(json) {
|
|
310
|
+
var _iterator = _createForOfIteratorHelper(_classPrivateFieldGet(_this, _hiddenFields)),
|
|
311
|
+
_step;
|
|
312
|
+
|
|
313
|
+
try {
|
|
314
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
315
|
+
var attribute = _step.value;
|
|
316
|
+
delete json[attribute];
|
|
317
|
+
}
|
|
318
|
+
} catch (err) {
|
|
319
|
+
_iterator.e(err);
|
|
320
|
+
} finally {
|
|
321
|
+
_iterator.f();
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
return json;
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
|
|
296
328
|
_classPrivateFieldInitSpec(this, _bulkOperation, {
|
|
297
329
|
writable: true,
|
|
298
330
|
value: function value(objects, action) {
|
|
299
331
|
if (_classPrivateFieldGet(_this, _singleItemQuery)) {
|
|
300
332
|
return (0, _batchPromises["default"])(_classPrivateFieldGet(_this, _batchSize), objects.map(function (i) {
|
|
301
|
-
return i.toJSON();
|
|
333
|
+
return _classPrivateFieldGet(_this, _removeHiddenFields).call(_this, i.toJSON());
|
|
302
334
|
}), action);
|
|
303
335
|
} else {
|
|
304
336
|
return action(objects.map(function (i) {
|
|
305
|
-
return i.toJSON();
|
|
337
|
+
return _classPrivateFieldGet(_this, _removeHiddenFields).call(_this, i.toJSON());
|
|
306
338
|
}));
|
|
307
339
|
}
|
|
308
340
|
}
|
|
@@ -352,6 +384,8 @@ var Model = /*#__PURE__*/_createClass(function Model(name) {
|
|
|
352
384
|
|
|
353
385
|
_classPrivateFieldSet(this, _axios, options.axios || _axios2["default"]);
|
|
354
386
|
|
|
387
|
+
_classPrivateFieldSet(this, _hiddenFields, options.hiddenFields || []);
|
|
388
|
+
|
|
355
389
|
_classPrivateFieldSet(this, _loadFunction, options.load || null);
|
|
356
390
|
|
|
357
391
|
if (!name || !options) {
|
package/dist/Obj.js
CHANGED
|
@@ -39,6 +39,8 @@ var dateRegex = new RegExp("^[0-9][0-9][0-9][0-9]-[0-9].*T[0-9].*Z$");
|
|
|
39
39
|
|
|
40
40
|
var _loaded = /*#__PURE__*/new WeakMap();
|
|
41
41
|
|
|
42
|
+
var _setHidden = /*#__PURE__*/new WeakMap();
|
|
43
|
+
|
|
42
44
|
var Obj = /*#__PURE__*/_createClass(function Obj(values, _model) {
|
|
43
45
|
var _this = this;
|
|
44
46
|
|
|
@@ -49,6 +51,11 @@ var Obj = /*#__PURE__*/_createClass(function Obj(values, _model) {
|
|
|
49
51
|
value: false
|
|
50
52
|
});
|
|
51
53
|
|
|
54
|
+
_classPrivateFieldInitSpec(this, _setHidden, {
|
|
55
|
+
writable: true,
|
|
56
|
+
value: {}
|
|
57
|
+
});
|
|
58
|
+
|
|
52
59
|
_defineProperty(this, "load", function () {
|
|
53
60
|
if (_classPrivateFieldGet(_this, _loaded)) {
|
|
54
61
|
return Promise.resolve(_this);
|
|
@@ -70,19 +77,24 @@ var Obj = /*#__PURE__*/_createClass(function Obj(values, _model) {
|
|
|
70
77
|
});
|
|
71
78
|
|
|
72
79
|
_defineProperty(this, "get", function (attribute) {
|
|
73
|
-
return _this[attribute];
|
|
80
|
+
return _classPrivateFieldGet(_this, _setHidden)[attribute] || _this[attribute];
|
|
74
81
|
});
|
|
75
82
|
|
|
76
83
|
_defineProperty(this, "getRelation", function (type, filterFunction) {
|
|
77
84
|
return _this.getModel().getRelation(_this, type, filterFunction);
|
|
78
85
|
});
|
|
79
86
|
|
|
80
|
-
_defineProperty(this, "set", function (attribute, value) {
|
|
81
|
-
if (
|
|
82
|
-
|
|
87
|
+
_defineProperty(this, "set", function (attribute, value, hidden) {
|
|
88
|
+
if (hidden) {
|
|
89
|
+
_classPrivateFieldGet(_this, _setHidden)[attribute] = value;
|
|
90
|
+
} else {
|
|
91
|
+
if (attribute === "id") {
|
|
92
|
+
throw new Error("You cannot change the ID");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
_this[attribute] = value;
|
|
83
96
|
}
|
|
84
97
|
|
|
85
|
-
_this[attribute] = value;
|
|
86
98
|
return _this.getModel().getStore().update([_this]);
|
|
87
99
|
});
|
|
88
100
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dataflux",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
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",
|