dataflux 1.1.0 → 1.2.1
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 +95 -10
- package/dist/Model.js +63 -5
- package/dist/PersistentStore.js +0 -3
- package/dist/ReactStore.js +22 -2
- package/dist/Store.js +13 -0
- package/dist/StoreObject.js +36 -3
- package/dist/fingerprint.js +3 -5
- package/dist/modelHooksUtils.js +37 -12
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ export default store;
|
|
|
48
48
|
|
|
49
49
|
The store can be initialized with [various options](#configuration). You need only one store for the entire application, that's why you should declare it in its own file and import it in multiple places.
|
|
50
50
|
|
|
51
|
-
The creation of a model requires at least a name and
|
|
51
|
+
The creation of a model requires at least a name and a url. GET, POST, PUT, and DELETE operations are going to be performed against the same url. [Models can be created with considerably more advanced options.](#models-creation)
|
|
52
52
|
|
|
53
53
|
A JS object is automatically created for each item returned by the API, for each model. The object has the same properties of the JSON item plus some high-level method (see [objects methods](#objects-methods)).
|
|
54
54
|
**All the objects are indexed in the store.**
|
|
@@ -219,39 +219,78 @@ A model can be simply created with:
|
|
|
219
219
|
const book = new Model("book", `https://rest.example.net/api/v1/books`);
|
|
220
220
|
```
|
|
221
221
|
|
|
222
|
-
However,
|
|
222
|
+
However, sometimes you may want to define a more complex interaction with the API. In such cases you can pass options to perform more elaborated model's initializations.
|
|
223
223
|
|
|
224
|
-
|
|
224
|
+
```js
|
|
225
|
+
const book = new Model("book", options);
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
All the possible options for a model creation are (they are all optional):
|
|
229
|
+
|
|
230
|
+
| Name | Description | Default |
|
|
231
|
+
|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------|
|
|
232
|
+
| 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"}` |
|
|
233
|
+
| 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"}` |
|
|
234
|
+
| update | Describes the operation to update objects of the collection. It can be an operation object or a function. See [operations](#operations). | `{method: "put"}` |
|
|
235
|
+
| delete | Describes the operation to remove objects from the collection. It can be an operation object or a function. See [operations](#operations). | `{method: "delete"}` |
|
|
236
|
+
| 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 |
|
|
237
|
+
| headers | A dictionary of headers for the HTTP request. E.g., `{"Authorization": "bearer XXXX"}`. | No headers |
|
|
238
|
+
| 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). |
|
|
239
|
+
| 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 |
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
### Operations
|
|
243
|
+
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.
|
|
244
|
+
|
|
245
|
+
#### Operation object
|
|
246
|
+
|
|
247
|
+
An operation object is an object like follows:
|
|
248
|
+
|
|
249
|
+
```json
|
|
250
|
+
{
|
|
251
|
+
"method": "get",
|
|
252
|
+
"url": "https://api.example.com",
|
|
253
|
+
"headers": {"Authorization": "bearer XXXX"}
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Usage example:
|
|
225
258
|
|
|
226
259
|
```js
|
|
227
260
|
const options = {
|
|
261
|
+
|
|
228
262
|
retrieve: {
|
|
229
263
|
method: "get",
|
|
230
|
-
url: "https://rest.example.net/api/v1/books"
|
|
264
|
+
url: "https://rest.example.net/api/v1/books",
|
|
265
|
+
headers: {} // Headers can be define per operation or globally
|
|
231
266
|
},
|
|
267
|
+
|
|
232
268
|
insert: {
|
|
233
269
|
method: "post",
|
|
234
270
|
url: "https://rest.example.net/api/v1/books"
|
|
235
271
|
},
|
|
272
|
+
|
|
236
273
|
update: {
|
|
237
274
|
method: "put",
|
|
238
275
|
url: "https://rest.example.net/api/v1/books"
|
|
239
276
|
},
|
|
277
|
+
|
|
240
278
|
delete: {
|
|
241
279
|
method: "delete",
|
|
242
280
|
url: "https://rest.example.net/api/v1/books"
|
|
243
|
-
}
|
|
281
|
+
},
|
|
282
|
+
|
|
283
|
+
headers: {"Authorization": "bearer XXXX"} // Globally defined headers
|
|
244
284
|
};
|
|
245
285
|
|
|
246
286
|
const book = new Model("book", options);
|
|
247
287
|
```
|
|
248
|
-
You don't
|
|
288
|
+
You don't need to specify all the attributes for each operation, only the ones you want to variate from the defaults (see table above). If a url is not specified for an operation, the url defined for the `GET` operation is used.
|
|
249
289
|
|
|
250
|
-
For example, if you want to perform both inserts and updates with `PUT
|
|
290
|
+
For example, if you are ok with the default behaviour except you want to perform both inserts and updates with `PUT` (instead of post/put), you can do:
|
|
251
291
|
```js
|
|
252
292
|
const options = {
|
|
253
293
|
retrieve: {
|
|
254
|
-
method: "get",
|
|
255
294
|
url: "https://rest.example.net/api/v1/books"
|
|
256
295
|
},
|
|
257
296
|
insert: {
|
|
@@ -262,7 +301,9 @@ const options = {
|
|
|
262
301
|
const book = new Model("book", options);
|
|
263
302
|
```
|
|
264
303
|
|
|
265
|
-
|
|
304
|
+
#### Operation function
|
|
305
|
+
|
|
306
|
+
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.
|
|
266
307
|
|
|
267
308
|
|
|
268
309
|
```js
|
|
@@ -276,7 +317,7 @@ const options = {
|
|
|
276
317
|
insert: (data) => {
|
|
277
318
|
// 1) recieve the data from the store
|
|
278
319
|
// 2) transform the data however you like
|
|
279
|
-
// 3) send data to server
|
|
320
|
+
// 3) send data to server and resolve empty
|
|
280
321
|
return Promise.resolve();
|
|
281
322
|
}
|
|
282
323
|
};
|
|
@@ -284,6 +325,50 @@ const options = {
|
|
|
284
325
|
const book = new Model("book", options);
|
|
285
326
|
```
|
|
286
327
|
|
|
328
|
+
#### Object enrichment
|
|
329
|
+
|
|
330
|
+
DataFlux objects can have a `load()` method which enables you to load extra attributes of an object.
|
|
331
|
+
|
|
332
|
+
Example of usage of `load()`:
|
|
333
|
+
|
|
334
|
+
```js
|
|
335
|
+
console.log(book);
|
|
336
|
+
// {title: "The little prince"}
|
|
337
|
+
|
|
338
|
+
book.load();
|
|
339
|
+
// The book object will be updated and it will contain
|
|
340
|
+
// {id: 23, title: "The little prince", price: 9.99, year: 1943}
|
|
341
|
+
//
|
|
342
|
+
// If you are using React, book.load() will automatically update your state
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
To enable such a method, you have to define the `load` option during model creation. The load option accepts a function that returns the complete object of a url. The function receives in input the current JSON object.
|
|
348
|
+
|
|
349
|
+
Example of creation of a model with `load` support:
|
|
350
|
+
```js
|
|
351
|
+
const book = new Model("book", {
|
|
352
|
+
retrieve: {
|
|
353
|
+
url: "https://rest.example.net/api/v1/books/"
|
|
354
|
+
},
|
|
355
|
+
fields: ["title"], // By default the books will contain only the title
|
|
356
|
+
load: (object) => { // "object" contains the current object to be enriched
|
|
357
|
+
|
|
358
|
+
// Return the url where to retrieve the object
|
|
359
|
+
return "https://rest.example.net/api/v1/books/" + object.id;
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
```
|
|
363
|
+
Alternatively, the `load` function can return directly the enriched object.
|
|
364
|
+
```js
|
|
365
|
+
const book = new Model("book", {
|
|
366
|
+
load: (object) => {
|
|
367
|
+
return axios({...}).then(raw => raw.data);
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
```
|
|
371
|
+
|
|
287
372
|
### Model relations
|
|
288
373
|
|
|
289
374
|
Optionally, you can create relations among models.
|
package/dist/Model.js
CHANGED
|
@@ -9,6 +9,8 @@ var _modelHooksUtils = require("./modelHooksUtils");
|
|
|
9
9
|
|
|
10
10
|
var _batchPromises = _interopRequireDefault(require("batch-promises"));
|
|
11
11
|
|
|
12
|
+
var _axios2 = _interopRequireDefault(require("axios"));
|
|
13
|
+
|
|
12
14
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
13
15
|
|
|
14
16
|
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); }
|
|
@@ -65,6 +67,10 @@ var _singleItemQuery = /*#__PURE__*/new WeakMap();
|
|
|
65
67
|
|
|
66
68
|
var _batchSize = /*#__PURE__*/new WeakMap();
|
|
67
69
|
|
|
70
|
+
var _axios = /*#__PURE__*/new WeakMap();
|
|
71
|
+
|
|
72
|
+
var _loadFunction = /*#__PURE__*/new WeakMap();
|
|
73
|
+
|
|
68
74
|
var _addRelationByField = /*#__PURE__*/new WeakMap();
|
|
69
75
|
|
|
70
76
|
var _addRelationByFilter = /*#__PURE__*/new WeakMap();
|
|
@@ -79,9 +85,11 @@ var _updateObjects = /*#__PURE__*/new WeakMap();
|
|
|
79
85
|
|
|
80
86
|
var _deleteObjects = /*#__PURE__*/new WeakMap();
|
|
81
87
|
|
|
82
|
-
var Model = /*#__PURE__*/_createClass(function Model(name
|
|
88
|
+
var Model = /*#__PURE__*/_createClass(function Model(name) {
|
|
83
89
|
var _this = this;
|
|
84
90
|
|
|
91
|
+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
92
|
+
|
|
85
93
|
_classCallCheck(this, Model);
|
|
86
94
|
|
|
87
95
|
_classPrivateFieldInitSpec(this, _type, {
|
|
@@ -129,6 +137,16 @@ var Model = /*#__PURE__*/_createClass(function Model(name, options) {
|
|
|
129
137
|
value: void 0
|
|
130
138
|
});
|
|
131
139
|
|
|
140
|
+
_classPrivateFieldInitSpec(this, _axios, {
|
|
141
|
+
writable: true,
|
|
142
|
+
value: void 0
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
_classPrivateFieldInitSpec(this, _loadFunction, {
|
|
146
|
+
writable: true,
|
|
147
|
+
value: void 0
|
|
148
|
+
});
|
|
149
|
+
|
|
132
150
|
_defineProperty(this, "getStore", function () {
|
|
133
151
|
return _classPrivateFieldGet(_this, _store);
|
|
134
152
|
});
|
|
@@ -141,6 +159,38 @@ var Model = /*#__PURE__*/_createClass(function Model(name, options) {
|
|
|
141
159
|
}
|
|
142
160
|
});
|
|
143
161
|
|
|
162
|
+
_defineProperty(this, "load", function (obj) {
|
|
163
|
+
return new Promise(function (resolve, reject) {
|
|
164
|
+
var applyData = function applyData(data) {
|
|
165
|
+
for (var att in data) {
|
|
166
|
+
if (att !== "id" || obj.id === undefined || att === "id" && obj.id === data.id) {
|
|
167
|
+
obj[att] = data[att];
|
|
168
|
+
} else {
|
|
169
|
+
return Promise.reject("The loading function cannot change the id of the object.");
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
if (_classPrivateFieldGet(_this, _loadFunction)) {
|
|
175
|
+
var res = _classPrivateFieldGet(_this, _loadFunction).call(_this, obj.toJson());
|
|
176
|
+
|
|
177
|
+
if (typeof res === "string") {
|
|
178
|
+
_classPrivateFieldGet(_this, _axios).call(_this, {
|
|
179
|
+
method: "get",
|
|
180
|
+
url: res,
|
|
181
|
+
responseType: "json"
|
|
182
|
+
}).then(function (data) {
|
|
183
|
+
return applyData(data.data);
|
|
184
|
+
}).then(resolve);
|
|
185
|
+
} else {
|
|
186
|
+
res.then(applyData).then(resolve);
|
|
187
|
+
}
|
|
188
|
+
} else {
|
|
189
|
+
reject("You must define a loading function in the model to enable load().");
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
|
|
144
194
|
_defineProperty(this, "addRelation", function (model, param2, param3) {
|
|
145
195
|
if (model) {
|
|
146
196
|
_this.getStore().validateModel(model);
|
|
@@ -185,7 +235,7 @@ var Model = /*#__PURE__*/_createClass(function Model(name, options) {
|
|
|
185
235
|
});
|
|
186
236
|
|
|
187
237
|
_defineProperty(this, "retrieveAll", function () {
|
|
188
|
-
return (0, _modelHooksUtils.executeHook)("retrieve", _classPrivateFieldGet(_this, _retrieveHook), null, _this
|
|
238
|
+
return (0, _modelHooksUtils.executeHook)("retrieve", _classPrivateFieldGet(_this, _retrieveHook), null, _classPrivateFieldGet(_this, _axios)).then(_classPrivateFieldGet(_this, _toArray));
|
|
189
239
|
});
|
|
190
240
|
|
|
191
241
|
_defineProperty(this, "insertObjects", function (objects) {
|
|
@@ -248,21 +298,21 @@ var Model = /*#__PURE__*/_createClass(function Model(name, options) {
|
|
|
248
298
|
_classPrivateFieldInitSpec(this, _insertObjects, {
|
|
249
299
|
writable: true,
|
|
250
300
|
value: function value(data) {
|
|
251
|
-
return (0, _modelHooksUtils.executeHook)("insert", _classPrivateFieldGet(_this, _insertHook), data, _this
|
|
301
|
+
return (0, _modelHooksUtils.executeHook)("insert", _classPrivateFieldGet(_this, _insertHook), data, _classPrivateFieldGet(_this, _axios)).then(_classPrivateFieldGet(_this, _toArray));
|
|
252
302
|
}
|
|
253
303
|
});
|
|
254
304
|
|
|
255
305
|
_classPrivateFieldInitSpec(this, _updateObjects, {
|
|
256
306
|
writable: true,
|
|
257
307
|
value: function value(data) {
|
|
258
|
-
return (0, _modelHooksUtils.executeHook)("update", _classPrivateFieldGet(_this, _updateHook), data, _this
|
|
308
|
+
return (0, _modelHooksUtils.executeHook)("update", _classPrivateFieldGet(_this, _updateHook), data, _classPrivateFieldGet(_this, _axios)).then(_classPrivateFieldGet(_this, _toArray));
|
|
259
309
|
}
|
|
260
310
|
});
|
|
261
311
|
|
|
262
312
|
_classPrivateFieldInitSpec(this, _deleteObjects, {
|
|
263
313
|
writable: true,
|
|
264
314
|
value: function value(data) {
|
|
265
|
-
return (0, _modelHooksUtils.executeHook)("delete", _classPrivateFieldGet(_this, _deleteHook), data, _this
|
|
315
|
+
return (0, _modelHooksUtils.executeHook)("delete", _classPrivateFieldGet(_this, _deleteHook), data, _classPrivateFieldGet(_this, _axios)).then(_classPrivateFieldGet(_this, _toArray));
|
|
266
316
|
}
|
|
267
317
|
});
|
|
268
318
|
|
|
@@ -272,10 +322,18 @@ var Model = /*#__PURE__*/_createClass(function Model(name, options) {
|
|
|
272
322
|
|
|
273
323
|
_classPrivateFieldSet(this, _includes, {});
|
|
274
324
|
|
|
325
|
+
_classPrivateFieldSet(this, _axios, options.axios || _axios2["default"]);
|
|
326
|
+
|
|
327
|
+
_classPrivateFieldSet(this, _loadFunction, options.load || null);
|
|
328
|
+
|
|
275
329
|
if (!name || !options) {
|
|
276
330
|
throw new Error("A Model requires at least a name and a hook");
|
|
277
331
|
}
|
|
278
332
|
|
|
333
|
+
if (_classPrivateFieldGet(this, _loadFunction) && typeof _classPrivateFieldGet(this, _loadFunction) !== "function") {
|
|
334
|
+
throw new Error("The load option must be a function");
|
|
335
|
+
}
|
|
336
|
+
|
|
279
337
|
var _ref = _typeof(options) === "object" ? (0, _modelHooksUtils.getHooksFromOptions)(options) : (0, _modelHooksUtils.getHooksFromUrl)(options),
|
|
280
338
|
_ref2 = _slicedToArray(_ref, 4),
|
|
281
339
|
retrieveHook = _ref2[0],
|
package/dist/PersistentStore.js
CHANGED
|
@@ -9,8 +9,6 @@ exports["default"] = void 0;
|
|
|
9
9
|
|
|
10
10
|
var _Store2 = _interopRequireDefault(require("./Store"));
|
|
11
11
|
|
|
12
|
-
var _axios = _interopRequireDefault(require("axios"));
|
|
13
|
-
|
|
14
12
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
15
13
|
|
|
16
14
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
@@ -113,7 +111,6 @@ var PersistentStore = /*#__PURE__*/function (_Store) {
|
|
|
113
111
|
}
|
|
114
112
|
});
|
|
115
113
|
|
|
116
|
-
_this.axios = options.axios || _axios["default"];
|
|
117
114
|
_this._busy = false;
|
|
118
115
|
_this._delayedSaveTimer = null;
|
|
119
116
|
|
package/dist/ReactStore.js
CHANGED
|
@@ -39,6 +39,12 @@ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.g
|
|
|
39
39
|
|
|
40
40
|
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; }
|
|
41
41
|
|
|
42
|
+
function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
|
|
43
|
+
|
|
44
|
+
function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
|
|
45
|
+
|
|
46
|
+
function _classPrivateMethodGet(receiver, privateSet, fn) { if (!privateSet.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return fn; }
|
|
47
|
+
|
|
42
48
|
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(_e) { throw _e; }, 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(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
|
|
43
49
|
|
|
44
50
|
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); }
|
|
@@ -73,6 +79,8 @@ var addSubscriptionToContext = function addSubscriptionToContext(context, subKey
|
|
|
73
79
|
};
|
|
74
80
|
};
|
|
75
81
|
|
|
82
|
+
var _fixState = /*#__PURE__*/new WeakSet();
|
|
83
|
+
|
|
76
84
|
var ReactStore = /*#__PURE__*/function (_ObserverStore) {
|
|
77
85
|
_inherits(ReactStore, _ObserverStore);
|
|
78
86
|
|
|
@@ -85,6 +93,8 @@ var ReactStore = /*#__PURE__*/function (_ObserverStore) {
|
|
|
85
93
|
|
|
86
94
|
_this2 = _super.call(this, options);
|
|
87
95
|
|
|
96
|
+
_classPrivateMethodInitSpec(_assertThisInitialized(_this2), _fixState);
|
|
97
|
+
|
|
88
98
|
_defineProperty(_assertThisInitialized(_this2), "handleChange", function (object, name) {
|
|
89
99
|
return function (event, rawValue) {
|
|
90
100
|
var value = event ? event.target.type === "checkbox" ? event.target.checked : event.target.value : "";
|
|
@@ -98,14 +108,18 @@ var ReactStore = /*#__PURE__*/function (_ObserverStore) {
|
|
|
98
108
|
_createClass(ReactStore, [{
|
|
99
109
|
key: "findAll",
|
|
100
110
|
value: function findAll(type, stateAttribute, context, filterFunction) {
|
|
111
|
+
_classPrivateMethodGet(this, _fixState, _fixState2).call(this, stateAttribute, context, false);
|
|
112
|
+
|
|
101
113
|
var subKey = this.subscribe(type, function (data) {
|
|
102
|
-
context.setState(_objectSpread(_objectSpread({}, context.state), {}, _defineProperty({}, stateAttribute, data)));
|
|
114
|
+
context.setState(_objectSpread(_objectSpread({}, context.state), {}, _defineProperty({}, stateAttribute, data || [])));
|
|
103
115
|
}, filterFunction);
|
|
104
116
|
addSubscriptionToContext(context, subKey);
|
|
105
117
|
}
|
|
106
118
|
}, {
|
|
107
119
|
key: "findOne",
|
|
108
120
|
value: function findOne(type, stateAttribute, context, filterFunction) {
|
|
121
|
+
_classPrivateMethodGet(this, _fixState, _fixState2).call(this, stateAttribute, context, true);
|
|
122
|
+
|
|
109
123
|
var subKey = this.subscribe(type, function (data) {
|
|
110
124
|
context.setState(_objectSpread(_objectSpread({}, context.state), {}, _defineProperty({}, stateAttribute, data && data.length ? data[0] : null)));
|
|
111
125
|
}, filterFunction);
|
|
@@ -116,4 +130,10 @@ var ReactStore = /*#__PURE__*/function (_ObserverStore) {
|
|
|
116
130
|
return ReactStore;
|
|
117
131
|
}(_ObserverStore2["default"]);
|
|
118
132
|
|
|
119
|
-
exports["default"] = ReactStore;
|
|
133
|
+
exports["default"] = ReactStore;
|
|
134
|
+
|
|
135
|
+
function _fixState2(stateAttribute, context, one) {
|
|
136
|
+
if (!context[stateAttribute]) {
|
|
137
|
+
context[stateAttribute] = one ? null : []; // side effect on state
|
|
138
|
+
}
|
|
139
|
+
}
|
package/dist/Store.js
CHANGED
|
@@ -159,6 +159,10 @@ var Store = /*#__PURE__*/function () {
|
|
|
159
159
|
return i.object;
|
|
160
160
|
});
|
|
161
161
|
return filterFunction ? all.filter(filterFunction) : all;
|
|
162
|
+
})["catch"](function (error) {
|
|
163
|
+
_this4.pubSub.publish("error", error);
|
|
164
|
+
|
|
165
|
+
return Promise.reject(error);
|
|
162
166
|
});
|
|
163
167
|
}
|
|
164
168
|
}, {
|
|
@@ -320,6 +324,10 @@ function _loadObjects2(type) {
|
|
|
320
324
|
var _this9 = this;
|
|
321
325
|
|
|
322
326
|
var item = this.models[type];
|
|
327
|
+
this.pubSub.publish("loading", {
|
|
328
|
+
status: "start",
|
|
329
|
+
model: type
|
|
330
|
+
});
|
|
323
331
|
return item.promise = item.model.retrieveAll().then(function (items) {
|
|
324
332
|
var _iterator4 = _createForOfIteratorHelper(items),
|
|
325
333
|
_step4;
|
|
@@ -335,5 +343,10 @@ function _loadObjects2(type) {
|
|
|
335
343
|
} finally {
|
|
336
344
|
_iterator4.f();
|
|
337
345
|
}
|
|
346
|
+
|
|
347
|
+
_this9.pubSub.publish("loading", {
|
|
348
|
+
status: "end",
|
|
349
|
+
model: type
|
|
350
|
+
});
|
|
338
351
|
});
|
|
339
352
|
}
|
package/dist/StoreObject.js
CHANGED
|
@@ -19,13 +19,46 @@ 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
|
+
function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
|
|
23
|
+
|
|
24
|
+
function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
|
|
25
|
+
|
|
26
|
+
function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); _classApplyDescriptorSet(receiver, descriptor, value); return value; }
|
|
27
|
+
|
|
28
|
+
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; } }
|
|
29
|
+
|
|
30
|
+
function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); }
|
|
31
|
+
|
|
32
|
+
function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); }
|
|
33
|
+
|
|
34
|
+
function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; }
|
|
35
|
+
|
|
36
|
+
var _loaded = /*#__PURE__*/new WeakMap();
|
|
37
|
+
|
|
22
38
|
var Obj = /*#__PURE__*/_createClass(function Obj(values, model) {
|
|
23
39
|
var _this = this;
|
|
24
40
|
|
|
25
41
|
_classCallCheck(this, Obj);
|
|
26
42
|
|
|
43
|
+
_classPrivateFieldInitSpec(this, _loaded, {
|
|
44
|
+
writable: true,
|
|
45
|
+
value: false
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
_defineProperty(this, "load", function () {
|
|
49
|
+
if (_classPrivateFieldGet(_this, _loaded)) {
|
|
50
|
+
return Promise.resolve(_this);
|
|
51
|
+
} else {
|
|
52
|
+
return _this.getModel().load(_this).then(function () {
|
|
53
|
+
_classPrivateFieldSet(_this, _loaded, true);
|
|
54
|
+
|
|
55
|
+
return _this;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
27
60
|
_defineProperty(this, "getFingerprint", function () {
|
|
28
|
-
return (0, _fingerprint["default"])(_this.
|
|
61
|
+
return (0, _fingerprint["default"])(_this.toJSON());
|
|
29
62
|
});
|
|
30
63
|
|
|
31
64
|
_defineProperty(this, "get", function (attribute) {
|
|
@@ -54,7 +87,7 @@ var Obj = /*#__PURE__*/_createClass(function Obj(values, model) {
|
|
|
54
87
|
return _this.getModel().getStore()["delete"]([_this]);
|
|
55
88
|
});
|
|
56
89
|
|
|
57
|
-
_defineProperty(this, "
|
|
90
|
+
_defineProperty(this, "toJSON", function () {
|
|
58
91
|
var attrs = Object.keys(_this);
|
|
59
92
|
var out = {};
|
|
60
93
|
|
|
@@ -70,7 +103,7 @@ var Obj = /*#__PURE__*/_createClass(function Obj(values, model) {
|
|
|
70
103
|
});
|
|
71
104
|
|
|
72
105
|
_defineProperty(this, "toString", function () {
|
|
73
|
-
return JSON.stringify(_this.
|
|
106
|
+
return JSON.stringify(_this.toJSON());
|
|
74
107
|
});
|
|
75
108
|
|
|
76
109
|
this.getModel = function () {
|
package/dist/fingerprint.js
CHANGED
|
@@ -5,10 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports["default"] = fingerprint;
|
|
7
7
|
|
|
8
|
-
var _crc = _interopRequireDefault(require("crc/crc32"));
|
|
9
|
-
|
|
10
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
11
|
-
|
|
12
8
|
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(_e) { throw _e; }, 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(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
|
|
13
9
|
|
|
14
10
|
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); }
|
|
@@ -17,6 +13,8 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
|
|
|
17
13
|
|
|
18
14
|
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); }
|
|
19
15
|
|
|
16
|
+
var CRC32 = require('crc-32');
|
|
17
|
+
|
|
20
18
|
var _getFingerprint = function _getFingerprint(object) {
|
|
21
19
|
switch (_typeof(object)) {
|
|
22
20
|
case "object":
|
|
@@ -61,5 +59,5 @@ var getObjectFingerprint = function getObjectFingerprint(value) {
|
|
|
61
59
|
};
|
|
62
60
|
|
|
63
61
|
function fingerprint(object) {
|
|
64
|
-
return (
|
|
62
|
+
return CRC32.str(_getFingerprint(object)).toString(16);
|
|
65
63
|
}
|
package/dist/modelHooksUtils.js
CHANGED
|
@@ -5,23 +5,46 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.getHooksFromUrl = exports.getHooksFromOptions = exports.executeHook = void 0;
|
|
7
7
|
|
|
8
|
+
var _brembo = _interopRequireDefault(require("brembo"));
|
|
9
|
+
|
|
10
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
11
|
+
|
|
8
12
|
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); }
|
|
9
13
|
|
|
10
|
-
var getDataStringHook = function getDataStringHook(
|
|
11
|
-
var
|
|
12
|
-
var
|
|
13
|
-
var
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
method: method,
|
|
14
|
+
var getDataStringHook = function getDataStringHook(hook) {
|
|
15
|
+
var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
16
|
+
var axios = arguments.length > 2 ? arguments[2] : undefined;
|
|
17
|
+
var options = {
|
|
18
|
+
url: hook.url,
|
|
19
|
+
method: hook.method || "get",
|
|
17
20
|
data: data,
|
|
18
21
|
reponseType: 'json'
|
|
19
|
-
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
if (hook.headers) {
|
|
25
|
+
options.headers = hook.headers;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (hook.fields) {
|
|
29
|
+
setFields(options, hook);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return axios(options).then(function (data) {
|
|
20
33
|
return data.data;
|
|
21
34
|
});
|
|
22
35
|
};
|
|
23
36
|
|
|
24
|
-
var
|
|
37
|
+
var setFields = function setFields(options, hook) {
|
|
38
|
+
options.headers = options.headers || {};
|
|
39
|
+
options.headers['X-Fields'] = hook.fields;
|
|
40
|
+
options.url = _brembo["default"].build(options.url, {
|
|
41
|
+
params: {
|
|
42
|
+
fields: hook.fields.join(",")
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
var createHookItem = function createHookItem(optionItem, defaultMethod, defaultUrl, options) {
|
|
25
48
|
switch (_typeof(optionItem)) {
|
|
26
49
|
case "undefined":
|
|
27
50
|
if (!defaultUrl) {
|
|
@@ -44,7 +67,9 @@ var createHookItem = function createHookItem(optionItem, defaultMethod, defaultU
|
|
|
44
67
|
case "object":
|
|
45
68
|
return {
|
|
46
69
|
method: optionItem.method || defaultMethod,
|
|
47
|
-
url: optionItem.url || defaultUrl
|
|
70
|
+
url: optionItem.url || defaultUrl,
|
|
71
|
+
fields: options.fields || [],
|
|
72
|
+
headers: optionItem.headers || options.headers || {}
|
|
48
73
|
};
|
|
49
74
|
|
|
50
75
|
default:
|
|
@@ -54,7 +79,7 @@ var createHookItem = function createHookItem(optionItem, defaultMethod, defaultU
|
|
|
54
79
|
|
|
55
80
|
var getHooksFromOptions = function getHooksFromOptions(options) {
|
|
56
81
|
var defaultUrl = typeof options.retrieve === "function" ? null : options.retrieve.url;
|
|
57
|
-
return [createHookItem(options.retrieve, "get", defaultUrl), createHookItem(options.insert, "post", defaultUrl), createHookItem(options.update, "put", defaultUrl), createHookItem(options["delete"], "delete", defaultUrl)];
|
|
82
|
+
return [createHookItem(options.retrieve, "get", defaultUrl, options), createHookItem(options.insert, "post", defaultUrl, options), createHookItem(options.update, "put", defaultUrl, options), createHookItem(options["delete"], "delete", defaultUrl, options)];
|
|
58
83
|
};
|
|
59
84
|
|
|
60
85
|
exports.getHooksFromOptions = getHooksFromOptions;
|
|
@@ -82,7 +107,7 @@ var executeHook = function executeHook(type, hook, data, axios) {
|
|
|
82
107
|
|
|
83
108
|
switch (hookType) {
|
|
84
109
|
case "object":
|
|
85
|
-
return getDataStringHook(hook
|
|
110
|
+
return getDataStringHook(hook, data, axios);
|
|
86
111
|
|
|
87
112
|
case "function":
|
|
88
113
|
return hook(data);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dataflux",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.1",
|
|
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",
|
|
@@ -78,13 +78,13 @@
|
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
80
|
"@babel/cli": "^7.16.8",
|
|
81
|
-
"@babel/core": "^7.16.
|
|
81
|
+
"@babel/core": "^7.16.12",
|
|
82
82
|
"@babel/node": "^7.16.8",
|
|
83
83
|
"@babel/plugin-proposal-class-properties": "^7.16.7",
|
|
84
84
|
"@babel/plugin-proposal-object-rest-spread": "^7.16.7",
|
|
85
85
|
"@babel/plugin-transform-async-to-generator": "^7.16.8",
|
|
86
86
|
"@babel/plugin-transform-runtime": "^7.16.10",
|
|
87
|
-
"@babel/preset-env": "^7.16.
|
|
87
|
+
"@babel/preset-env": "^7.16.11",
|
|
88
88
|
"@babel/preset-react": "^7.16.7",
|
|
89
89
|
"dotenv-cli": "^4.1.1",
|
|
90
90
|
"release-it": "^14.12.3"
|
|
@@ -92,7 +92,8 @@
|
|
|
92
92
|
"dependencies": {
|
|
93
93
|
"axios": "^0.25.0",
|
|
94
94
|
"batch-promises": "^0.0.3",
|
|
95
|
-
"
|
|
95
|
+
"brembo": "^2.0.6",
|
|
96
|
+
"crc-32": "^1.2.0",
|
|
96
97
|
"uuid": "^8.3.2"
|
|
97
98
|
},
|
|
98
99
|
"resolutions": {}
|