dataflux 1.2.4 → 1.4.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/LICENSE +1 -1
- package/README.md +106 -56
- package/dist/Model.js +44 -6
- package/dist/Obj.js +40 -10
- package/dist/ObserverStore.js +81 -37
- package/dist/fingerprint.js +13 -1
- package/package.json +4 -3
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -17
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -17
- package/.github/dependabot.yml +0 -8
- package/.github/stale.yml +0 -20
- package/.github/workflows/main.yml +0 -83
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -30,23 +30,34 @@ Create your global store by creating a file (e.g., named `store.js`) containing
|
|
|
30
30
|
Consider the following hypothetical store/model declaration common to all the examples below:
|
|
31
31
|
|
|
32
32
|
```js
|
|
33
|
+
// Content of your store.js
|
|
33
34
|
import {Store, Model} from "dataflux";
|
|
34
35
|
|
|
36
|
+
// We create a new Store
|
|
35
37
|
const store = new Store();
|
|
36
|
-
const author = new Model("author", `https://rest.example.net/api/v1/authors`);
|
|
37
|
-
const book = new Model("book", `https://rest.example.net/api/v1/books`);
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
// We now create two models, "author" and "book".
|
|
40
|
+
// Both of them are auto generated based on the output of a REST API.
|
|
41
|
+
// The REST API does NOT need to provide a specific format.
|
|
42
|
+
// E.g., /books returns [{"title": "Hamlet", "year": 1600}, ...].
|
|
43
|
+
// See "REST API format" below for more info.
|
|
44
|
+
const book = new Model("book", `https://api.example.net/books`);
|
|
45
|
+
const author = new Model("author", `https://api.example.net/authors`);
|
|
46
|
+
|
|
47
|
+
// We add the models to the store
|
|
40
48
|
store.addModel(book);
|
|
49
|
+
store.addModel(author);
|
|
41
50
|
|
|
42
|
-
//
|
|
51
|
+
// Optionally, we can declare relations among models.
|
|
52
|
+
// E.g., we can declare that an author has one or more books.
|
|
43
53
|
author.addRelation(book, "id", "authorId");
|
|
54
|
+
// The relation will provide all the books where author.id = book.authorId
|
|
44
55
|
|
|
45
56
|
export default store;
|
|
46
57
|
```
|
|
47
58
|
|
|
48
59
|
|
|
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.
|
|
60
|
+
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 (store.js in this case) and import it in multiple places.
|
|
50
61
|
|
|
51
62
|
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
63
|
|
|
@@ -55,28 +66,31 @@ A JS object is automatically created for each item returned by the API, for each
|
|
|
55
66
|
|
|
56
67
|
### Example 1
|
|
57
68
|
|
|
58
|
-
Retrieve and edit an author
|
|
69
|
+
Retrieve and edit an author by name and surname:
|
|
59
70
|
|
|
60
71
|
```js
|
|
61
|
-
import store from "./store";
|
|
72
|
+
import store from "./store"; // Import our store.js
|
|
62
73
|
|
|
63
74
|
// Find the author Dante Alighieri
|
|
64
75
|
store.find("author", ({name, surname}) => name == "Dante" && surname == "Alighieri")
|
|
65
76
|
.then(([author]) => {
|
|
77
|
+
|
|
78
|
+
// We got the author, let's now edit it
|
|
66
79
|
author.set("country", "Italy");
|
|
67
80
|
author.set("type", "poet");
|
|
68
|
-
// Nothing else to do, the store does a single PUT request to the model's API about the edited object
|
|
69
81
|
});
|
|
70
82
|
```
|
|
71
83
|
|
|
72
|
-
|
|
84
|
+
Nothing else to do! After your edit, the store will do a single PUT request to the model's API to save the edited object. This behavior can be disabled, see next example.
|
|
85
|
+
|
|
86
|
+
> You don't necessarily need to use `object.set` to edit an object attribute. You could do `author.country = "Italy"`. However, this approach has disadvantages, read [editing objects](#editing-objects) for more information
|
|
73
87
|
|
|
74
88
|
### Example 2
|
|
75
89
|
|
|
76
|
-
|
|
90
|
+
DataFlux automatically sends the edited objects back to the API to be saved. However, you can disable this behavior and manually instruct the store when to save.
|
|
77
91
|
|
|
78
92
|
```js
|
|
79
|
-
// To disable autoSave you must declare the store as follows
|
|
93
|
+
// To disable autoSave you must declare the store (in store.js) as follows
|
|
80
94
|
const store = new Store({autoSave: false});
|
|
81
95
|
```
|
|
82
96
|
|
|
@@ -86,11 +100,13 @@ The same example above now becomes:
|
|
|
86
100
|
// Find the author Dante Alighieri
|
|
87
101
|
store.find("author", ({name, surname}) => name == "Dante" && surname == "Alighieri")
|
|
88
102
|
.then(([author]) => {
|
|
89
|
-
|
|
103
|
+
|
|
104
|
+
// When autoSave is false, author.set("country", "Italy") and
|
|
105
|
+
// author.country = "Italy" are equivalent
|
|
90
106
|
author.country = "Italy"
|
|
91
107
|
author.type = "poet"
|
|
92
108
|
|
|
93
|
-
store.save(); //
|
|
109
|
+
store.save(); // Instruct the store to save
|
|
94
110
|
});
|
|
95
111
|
```
|
|
96
112
|
|
|
@@ -129,6 +145,7 @@ author.getRelation("book");
|
|
|
129
145
|
|
|
130
146
|
If you use `subscribe` instead of `find`, you can provide a callback to be invoked when data is ready or there is a change in the data.
|
|
131
147
|
|
|
148
|
+
_**DataFlux remembers your query and calls your callback every time any change is affecting the result of your query!**_
|
|
132
149
|
|
|
133
150
|
```js
|
|
134
151
|
const drawBooksCallback = (books) => {
|
|
@@ -139,7 +156,7 @@ const drawBooksCallback = (books) => {
|
|
|
139
156
|
store.subscribe("book", drawBooks, ({price}) => price < 20);
|
|
140
157
|
```
|
|
141
158
|
|
|
142
|
-
If now
|
|
159
|
+
If now a book is inserted/deleted/edited:
|
|
143
160
|
* if the book has `price < 20`, `drawBooksCallback` will be called again with the new dataset;
|
|
144
161
|
* if the book has `price > 20`, `drawBooksCallback` will NOT be called again (because the new book doesn't impact our selection).
|
|
145
162
|
|
|
@@ -151,14 +168,31 @@ const subKey = store.subscribe("book", drawBooks, ({price}) => price < 20); // S
|
|
|
151
168
|
store.unsubscribe(subKey); // Unsubscribe
|
|
152
169
|
```
|
|
153
170
|
|
|
171
|
+
You can also do multiple subscriptions at once:
|
|
172
|
+
|
|
173
|
+
```js
|
|
174
|
+
const subscriptions = [
|
|
175
|
+
["book", ({title}) => title === "The little prince"], // Model name and filter function
|
|
176
|
+
["author"], // No filter function, all objects returned
|
|
177
|
+
];
|
|
178
|
+
|
|
179
|
+
const callback = ([books, authors]) => {
|
|
180
|
+
// Objects are ready
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const subKey = store.multipleSubscribe(requests, callback); // Subscribe
|
|
184
|
+
|
|
185
|
+
store.unsubscribe(subKey); // Unsubscribe
|
|
186
|
+
```
|
|
187
|
+
|
|
154
188
|
### Example 6 - Observability + React
|
|
155
189
|
|
|
156
190
|
The integration with React is offered transparently when using the store inside a `React.Component`.
|
|
157
|
-
You can use two methods: `findOne`, and `findAll
|
|
191
|
+
You can use two methods: `findOne`, and `findAll` (which are a react-specific syntactic sugar over `subscribe`).
|
|
158
192
|
|
|
159
|
-
|
|
193
|
+
**_Since the store is able to detect changes deep in a nested structure, you will not have to worry about the component not re-rendering. Also, the setState will be triggered ONLY when the next change of the dataset is impacting your selection._**
|
|
160
194
|
|
|
161
|
-
React Component example
|
|
195
|
+
React Component example:
|
|
162
196
|
```jsx
|
|
163
197
|
class MyComponent extends React.Component {
|
|
164
198
|
constructor(props) {
|
|
@@ -168,9 +202,9 @@ class MyComponent extends React.Component {
|
|
|
168
202
|
componentDidMount() {
|
|
169
203
|
// Get all books with a price < 20
|
|
170
204
|
store.findAll("book", "books", this, ({price}) => price < 20);
|
|
171
|
-
//
|
|
172
|
-
//
|
|
173
|
-
//
|
|
205
|
+
// An attribute "books" will be added/updated in the
|
|
206
|
+
// state (the rest of the state remains unchanged) every time
|
|
207
|
+
// a book in our selection is inserted/deleted/edited.
|
|
174
208
|
|
|
175
209
|
// findAll is a syntactic sugar for:
|
|
176
210
|
// const callback = (books) => {this.setState({...this.state, books})};
|
|
@@ -185,7 +219,7 @@ class MyComponent extends React.Component {
|
|
|
185
219
|
onTitleChange={(title) => book.set("title", title)}
|
|
186
220
|
// onTitleChange will alter the book and so the current
|
|
187
221
|
// state of "books" (a setState will be performed).
|
|
188
|
-
|
|
222
|
+
|
|
189
223
|
// Alternatively:
|
|
190
224
|
// onTitleChange={store.handleChange(book, "title")}
|
|
191
225
|
// is a syntactic sugar of the function above
|
|
@@ -194,9 +228,9 @@ class MyComponent extends React.Component {
|
|
|
194
228
|
}
|
|
195
229
|
```
|
|
196
230
|
|
|
197
|
-
The method `findAll` returns always an array. The method `findOne` returns a single object (if multiple objects satisfy the
|
|
231
|
+
The method `findAll` returns always an array. The method `findOne` returns a single object (if multiple objects satisfy the query, the first is returned).
|
|
198
232
|
|
|
199
|
-
When the component will unmount, the `findAll` subscription will be automatically terminated without the need to unsubscribe. Be aware, `store.findAll` injects the unsubscribe call inside `componentWillUnmount`. If your component already implements `componentWillUnmount()`, then you will have to use `store.subscribe` and `store.unsubscribe` instead of `store.findAll`, to avoid side effects when the component is unmounted.
|
|
233
|
+
When the component will unmount, the `findAll` subscription will be automatically terminated without the need to unsubscribe. Be aware, `store.findAll()` injects the unsubscribe call inside `componentWillUnmount()`. If your component already implements `componentWillUnmount()`, then you will have to use `store.subscribe()` and `store.unsubscribe()` instead of `store.findAll()`, to avoid side effects when the component is unmounted.
|
|
200
234
|
|
|
201
235
|
## Configuration
|
|
202
236
|
|
|
@@ -216,7 +250,7 @@ The store can be configured with the following options:
|
|
|
216
250
|
A model can be simply created with:
|
|
217
251
|
|
|
218
252
|
```js
|
|
219
|
-
const book = new Model("book", `https://
|
|
253
|
+
const book = new Model("book", `https://api.example.net/books`);
|
|
220
254
|
```
|
|
221
255
|
|
|
222
256
|
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.
|
|
@@ -227,17 +261,18 @@ const book = new Model("book", options);
|
|
|
227
261
|
|
|
228
262
|
All the possible options for a model creation are (they are all optional):
|
|
229
263
|
|
|
230
|
-
| Name
|
|
231
|
-
|
|
232
|
-
| retrieve
|
|
233
|
-
| insert
|
|
234
|
-
| update
|
|
235
|
-
| delete
|
|
236
|
-
| fields
|
|
237
|
-
| headers
|
|
238
|
-
| load
|
|
239
|
-
| axios
|
|
240
|
-
|
|
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. |
|
|
241
276
|
|
|
242
277
|
### Operations
|
|
243
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.
|
|
@@ -418,31 +453,46 @@ author1.getRelation("book", (book) => book.price < 20)
|
|
|
418
453
|
|
|
419
454
|
The store has the following method.
|
|
420
455
|
|
|
421
|
-
| Method
|
|
422
|
-
|
|
423
|
-
|
|
|
424
|
-
|
|
|
425
|
-
|
|
|
426
|
-
|
|
|
427
|
-
| delete(
|
|
428
|
-
|
|
|
456
|
+
| Method | Description |
|
|
457
|
+
|--------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
458
|
+
| on(event, callback) | Method to subscribe to the events emitted by the store. See [events](#store-events) below. |
|
|
459
|
+
| addModel(model) | Introduce a new model to the store. If lazyLoad = false (default), the model is populated with the objects coming from the API. |
|
|
460
|
+
| get(type, id) | It allows to retrieve an object based on its type and store's ID (see `getId()` in [objects methods](#objects-methods). The type is the name of the model. |
|
|
461
|
+
| find(type, filterFunction) | The promise-oriented method to access objects given a type and a filter function. If the filter function is missing, all the objects are returned. See [example 1](#example-1). |
|
|
462
|
+
| delete(objects) | It deletes an array of objects. See [example 1](#example-3). |
|
|
463
|
+
| delete(type, filterFunction) | It deleted objects given an array and a filter function. See [example 1](#example-3). |
|
|
464
|
+
| insert(type, object) | It creates a new object of a given type and inserts it in the store. |
|
|
465
|
+
| subscribe(type, callback, filterFunction) | The callback-oriented method to access objects given a type and a filter function. It returns the key of the subscription, needed to unsubscribe. If the filter function is missing, all the objects are returned. **DataFlux remembers your query and calls the callback every time any change is affecting the result of your query.** See [example 5](#example-5---observability). |
|
|
466
|
+
| multipleSubscribe(subscriptions, callback) | A method to subscribe to multiple models. The first parameter is an array of models' names and filterFunctions, the second parameter is the callback to be called when the cumulative dataset is ready. E.g., `multipleSubscribe([["book", filterFunction1], ["author", filterFunction2]], callback)`. It returns the key of the subscription. See [example 5](#example-5---observability). |
|
|
467
|
+
| unsubscribe(key) | Method to terminate a subscription given a subscription key. See [example 5](#example-5---observability). |
|
|
468
|
+
| findOne(type, stateAttribute, context, filterFunction) | This method automatically injects and updates the React state with the requested data. If multiple objects satisfy the query, only the first is selected. The `stateAttribute` is the name of the attribute that will be added/updated in the state, the `context` is the React.Component. It automatically unsubscribe when the React.Component will unmount. See [example 6](#example-6---observability--react). |
|
|
469
|
+
| findAll(type, stateAttribute, context, filterFunction) | This method automatically injects and updates the React state with the requested data. The `stateAttribute` is the name of the attribute that will be added/updated in the state, the `context` is the React.Component. It automatically unsubscribe when the React.Component will unmount. If the filter function is missing, all the objects are returned. See [example 6](#example-6---observability--react). |
|
|
470
|
+
|
|
471
|
+
## Store events
|
|
472
|
+
The store emits the following events:
|
|
473
|
+
|
|
474
|
+
| Name | Description |
|
|
475
|
+
|---------|---------------------------------------------------------------------------------------------------------------------------------------|
|
|
476
|
+
| error | To listen the errors emitted by the store. |
|
|
477
|
+
| save | Possible emitted values are `start` and `end`. They are emitted when the store starts/finishes to persist the data (API interaction). |
|
|
478
|
+
| loading | The event is emitted while a new model is loaded. The value contains something like `{status: "start", model: "book"}` |
|
|
429
479
|
|
|
430
480
|
## Objects methods
|
|
431
481
|
Each object created is enriched with the following methods.
|
|
432
482
|
|
|
433
483
|
|
|
434
|
-
| Method | Description
|
|
435
|
-
|
|
436
|
-
| 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.
|
|
437
|
-
| set(attribute, value)
|
|
438
|
-
| save() | Method to save the object. You can do `store.save()` instead.
|
|
439
|
-
| destroy() | Method to delete the object. You can do `store.delete()` instead.
|
|
440
|
-
| get(attribute)
|
|
441
|
-
| getRelation(model, filterFunction) | To get all the objects respecting a specific relation with this object (see [model relations](#model-relations)).
|
|
442
|
-
| toJSON() | It returns a pure JSON representation of the object.
|
|
443
|
-
| toString() | It returns a string representation of the object.
|
|
444
|
-
| getFingerprint() | It returns a hash of the object. The hash changes at every change of the object or of any nested object. Useful to detect object changes.
|
|
445
|
-
| getModel() | It returns the model of this object. Mostly useful to do `object.getModel().getType()` and obtain a string defining the type of the object.
|
|
484
|
+
| Method | Description |
|
|
485
|
+
|------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
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, 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
|
+
| save() | Method to save the object. You can do `store.save()` instead. |
|
|
489
|
+
| destroy() | Method to delete the object. You can do `store.delete()` instead. |
|
|
490
|
+
| get(attribute, defaultValue) | Method to retrieve the value of an attribute. It does not provide any advantage compared to accessing directly the attribute (e.g., `author.name`); except for hidden fields, which can be retrieved only with the `.get` method. Additionally, you can provide a default value as a second parameter in case the object doesn't have that attribute. |
|
|
491
|
+
| getRelation(model, filterFunction) | To get all the objects respecting a specific relation with this object (see [model relations](#model-relations)). |
|
|
492
|
+
| toJSON() | It returns a pure JSON representation of the object. |
|
|
493
|
+
| toString() | It returns a string representation of the object. |
|
|
494
|
+
| getFingerprint() | It returns a hash of the object. The hash changes at every change of the object or of any nested object. Useful to detect object changes. |
|
|
495
|
+
| getModel() | It returns the model of this object. Mostly useful to do `object.getModel().getType()` and obtain a string defining the type of the object. |
|
|
446
496
|
|
|
447
497
|
## Editing objects
|
|
448
498
|
The option `autoSave` can be `true`, `false`, or a number (milliseconds).
|
|
@@ -468,7 +518,7 @@ The option `autoSave` can be `true`, `false`, or a number (milliseconds).
|
|
|
468
518
|
|
|
469
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.
|
|
470
520
|
|
|
471
|
-
|
|
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).
|
|
472
522
|
|
|
473
523
|
## API interaction
|
|
474
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
|
}
|
|
@@ -342,12 +374,18 @@ var Model = /*#__PURE__*/_createClass(function Model(name) {
|
|
|
342
374
|
|
|
343
375
|
_classPrivateFieldSet(this, _type, name);
|
|
344
376
|
|
|
377
|
+
this.options = {
|
|
378
|
+
parseMoment: options.parseMoment
|
|
379
|
+
};
|
|
380
|
+
|
|
345
381
|
_classPrivateFieldSet(this, _store, null);
|
|
346
382
|
|
|
347
383
|
_classPrivateFieldSet(this, _includes, {});
|
|
348
384
|
|
|
349
385
|
_classPrivateFieldSet(this, _axios, options.axios || _axios2["default"]);
|
|
350
386
|
|
|
387
|
+
_classPrivateFieldSet(this, _hiddenFields, options.hiddenFields || []);
|
|
388
|
+
|
|
351
389
|
_classPrivateFieldSet(this, _loadFunction, options.load || null);
|
|
352
390
|
|
|
353
391
|
if (!name || !options) {
|
package/dist/Obj.js
CHANGED
|
@@ -9,6 +9,8 @@ var _fingerprint = _interopRequireDefault(require("./fingerprint"));
|
|
|
9
9
|
|
|
10
10
|
var _uuid = require("uuid");
|
|
11
11
|
|
|
12
|
+
var _moment = _interopRequireDefault(require("moment/moment"));
|
|
13
|
+
|
|
12
14
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
13
15
|
|
|
14
16
|
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); } }
|
|
@@ -33,8 +35,12 @@ function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!priva
|
|
|
33
35
|
|
|
34
36
|
function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; }
|
|
35
37
|
|
|
38
|
+
var dateRegex = new RegExp("^[0-9][0-9][0-9][0-9]-[0-9].*T[0-9].*Z$");
|
|
39
|
+
|
|
36
40
|
var _loaded = /*#__PURE__*/new WeakMap();
|
|
37
41
|
|
|
42
|
+
var _setHidden = /*#__PURE__*/new WeakMap();
|
|
43
|
+
|
|
38
44
|
var Obj = /*#__PURE__*/_createClass(function Obj(values, _model) {
|
|
39
45
|
var _this = this;
|
|
40
46
|
|
|
@@ -45,6 +51,11 @@ var Obj = /*#__PURE__*/_createClass(function Obj(values, _model) {
|
|
|
45
51
|
value: false
|
|
46
52
|
});
|
|
47
53
|
|
|
54
|
+
_classPrivateFieldInitSpec(this, _setHidden, {
|
|
55
|
+
writable: true,
|
|
56
|
+
value: {}
|
|
57
|
+
});
|
|
58
|
+
|
|
48
59
|
_defineProperty(this, "load", function () {
|
|
49
60
|
if (_classPrivateFieldGet(_this, _loaded)) {
|
|
50
61
|
return Promise.resolve(_this);
|
|
@@ -65,20 +76,27 @@ var Obj = /*#__PURE__*/_createClass(function Obj(values, _model) {
|
|
|
65
76
|
return (0, _fingerprint["default"])(_this.toJSON());
|
|
66
77
|
});
|
|
67
78
|
|
|
68
|
-
_defineProperty(this, "get", function (attribute) {
|
|
69
|
-
|
|
79
|
+
_defineProperty(this, "get", function (attribute, defaultValue) {
|
|
80
|
+
var _ref, _classPrivateFieldGet2;
|
|
81
|
+
|
|
82
|
+
return (_ref = (_classPrivateFieldGet2 = _classPrivateFieldGet(_this, _setHidden)[attribute]) !== null && _classPrivateFieldGet2 !== void 0 ? _classPrivateFieldGet2 : _this[attribute]) !== null && _ref !== void 0 ? _ref : defaultValue;
|
|
70
83
|
});
|
|
71
84
|
|
|
72
85
|
_defineProperty(this, "getRelation", function (type, filterFunction) {
|
|
73
86
|
return _this.getModel().getRelation(_this, type, filterFunction);
|
|
74
87
|
});
|
|
75
88
|
|
|
76
|
-
_defineProperty(this, "set", function (attribute, value) {
|
|
77
|
-
if (
|
|
78
|
-
|
|
89
|
+
_defineProperty(this, "set", function (attribute, value, hidden) {
|
|
90
|
+
if (hidden) {
|
|
91
|
+
_classPrivateFieldGet(_this, _setHidden)[attribute] = value;
|
|
92
|
+
} else {
|
|
93
|
+
if (attribute === "id") {
|
|
94
|
+
throw new Error("You cannot change the ID");
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
_this[attribute] = value;
|
|
79
98
|
}
|
|
80
99
|
|
|
81
|
-
_this[attribute] = value;
|
|
82
100
|
return _this.getModel().getStore().update([_this]);
|
|
83
101
|
});
|
|
84
102
|
|
|
@@ -97,7 +115,11 @@ var Obj = /*#__PURE__*/_createClass(function Obj(values, _model) {
|
|
|
97
115
|
for (var _i = 0, _attrs = attrs; _i < _attrs.length; _i++) {
|
|
98
116
|
var a = _attrs[_i];
|
|
99
117
|
|
|
100
|
-
if (
|
|
118
|
+
if (_this[a] instanceof _moment["default"]) {
|
|
119
|
+
out[a] = _this[a].toISOString();
|
|
120
|
+
} else if (_this[a] instanceof Date) {
|
|
121
|
+
out[a] = (0, _moment["default"])(_this[a]).toISOString();
|
|
122
|
+
} else if (typeof _this[a] !== "function") {
|
|
101
123
|
out[a] = _this[a];
|
|
102
124
|
}
|
|
103
125
|
}
|
|
@@ -113,9 +135,17 @@ var Obj = /*#__PURE__*/_createClass(function Obj(values, _model) {
|
|
|
113
135
|
return _model;
|
|
114
136
|
};
|
|
115
137
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
138
|
+
var frEach = _model.options.parseMoment ? function (key) {
|
|
139
|
+
if (dateRegex.test(values[key])) {
|
|
140
|
+
var mmnt = (0, _moment["default"])(values[key]);
|
|
141
|
+
_this[key] = mmnt.isValid() ? mmnt : values[key];
|
|
142
|
+
} else {
|
|
143
|
+
_this[key] = values[key];
|
|
144
|
+
}
|
|
145
|
+
} : function (key) {
|
|
146
|
+
return _this[key] = values[key];
|
|
147
|
+
};
|
|
148
|
+
Object.keys(values).forEach(frEach);
|
|
119
149
|
var id;
|
|
120
150
|
|
|
121
151
|
if (this.id && (typeof this.id === "string" || typeof this.id === "number")) {
|
package/dist/ObserverStore.js
CHANGED
|
@@ -17,8 +17,16 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "d
|
|
|
17
17
|
|
|
18
18
|
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; } } }; }
|
|
19
19
|
|
|
20
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
21
|
+
|
|
22
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
23
|
+
|
|
20
24
|
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); }
|
|
21
25
|
|
|
26
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
27
|
+
|
|
28
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
29
|
+
|
|
22
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; }
|
|
23
31
|
|
|
24
32
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
@@ -83,6 +91,22 @@ var ObserverStore = /*#__PURE__*/function (_PersistentStore) {
|
|
|
83
91
|
|
|
84
92
|
_classPrivateMethodInitSpec(_assertThisInitialized(_this), _propagateInsertChange);
|
|
85
93
|
|
|
94
|
+
_defineProperty(_assertThisInitialized(_this), "multipleSubscribe", function (subscriptions, callback) {
|
|
95
|
+
return Promise.all(subscriptions.map(function (sub, index) {
|
|
96
|
+
var attrs = Array.from(Array(index + 1)).map(function () {
|
|
97
|
+
return null;
|
|
98
|
+
});
|
|
99
|
+
return _this.subscribe(sub[0], sub[1], function (data) {
|
|
100
|
+
attrs[index] = data;
|
|
101
|
+
return callback.apply(void 0, _toConsumableArray(attrs));
|
|
102
|
+
});
|
|
103
|
+
})).then(function (subKeys) {
|
|
104
|
+
var subKey = (0, _uuid.v4)();
|
|
105
|
+
_this._multipleSubscribed[subKey] = subKeys;
|
|
106
|
+
return subKey;
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
|
|
86
110
|
_defineProperty(_assertThisInitialized(_this), "subscribe", function (type, callback, filterFunction) {
|
|
87
111
|
var subKey = (0, _uuid.v4)();
|
|
88
112
|
|
|
@@ -104,14 +128,33 @@ var ObserverStore = /*#__PURE__*/function (_PersistentStore) {
|
|
|
104
128
|
});
|
|
105
129
|
|
|
106
130
|
_defineProperty(_assertThisInitialized(_this), "unsubscribe", function (key) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
131
|
+
if (_this._multipleSubscribed[key]) {
|
|
132
|
+
var _iterator = _createForOfIteratorHelper(_this._multipleSubscribed[key]),
|
|
133
|
+
_step;
|
|
134
|
+
|
|
135
|
+
try {
|
|
136
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
137
|
+
var sub = _step.value;
|
|
112
138
|
|
|
113
|
-
|
|
114
|
-
|
|
139
|
+
_this.unsubscribe(sub);
|
|
140
|
+
}
|
|
141
|
+
} catch (err) {
|
|
142
|
+
_iterator.e(err);
|
|
143
|
+
} finally {
|
|
144
|
+
_iterator.f();
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
delete _this._multipleSubscribed[key];
|
|
148
|
+
} else {
|
|
149
|
+
for (var type in _this._subscribed) {
|
|
150
|
+
for (var id in _this._subscribed[type]) {
|
|
151
|
+
_this._subscribed[type][id] = _this._subscribed[type][id].filter(function (i) {
|
|
152
|
+
return i.subKey !== key;
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
if (_this._subscribed[type][id].length === 0) {
|
|
156
|
+
delete _this._subscribed[type][id];
|
|
157
|
+
}
|
|
115
158
|
}
|
|
116
159
|
}
|
|
117
160
|
}
|
|
@@ -122,34 +165,34 @@ var ObserverStore = /*#__PURE__*/function (_PersistentStore) {
|
|
|
122
165
|
value: function value(objects, type) {
|
|
123
166
|
var out = {};
|
|
124
167
|
|
|
125
|
-
var
|
|
126
|
-
|
|
168
|
+
var _iterator2 = _createForOfIteratorHelper(objects),
|
|
169
|
+
_step2;
|
|
127
170
|
|
|
128
171
|
try {
|
|
129
|
-
for (
|
|
130
|
-
var object =
|
|
172
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
173
|
+
var object = _step2.value;
|
|
131
174
|
var objectId = object.getId();
|
|
132
175
|
var typeChannel = _this._subscribed[type] || {};
|
|
133
176
|
var subscribedToObject = typeChannel[objectId] || [];
|
|
134
177
|
|
|
135
|
-
var
|
|
136
|
-
|
|
178
|
+
var _iterator3 = _createForOfIteratorHelper(subscribedToObject),
|
|
179
|
+
_step3;
|
|
137
180
|
|
|
138
181
|
try {
|
|
139
|
-
for (
|
|
140
|
-
var sub =
|
|
182
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
183
|
+
var sub = _step3.value;
|
|
141
184
|
out[sub.subKey] = out[sub.subKey] || sub;
|
|
142
185
|
}
|
|
143
186
|
} catch (err) {
|
|
144
|
-
|
|
187
|
+
_iterator3.e(err);
|
|
145
188
|
} finally {
|
|
146
|
-
|
|
189
|
+
_iterator3.f();
|
|
147
190
|
}
|
|
148
191
|
}
|
|
149
192
|
} catch (err) {
|
|
150
|
-
|
|
193
|
+
_iterator2.e(err);
|
|
151
194
|
} finally {
|
|
152
|
-
|
|
195
|
+
_iterator2.f();
|
|
153
196
|
}
|
|
154
197
|
|
|
155
198
|
return Object.values(out);
|
|
@@ -180,12 +223,12 @@ var ObserverStore = /*#__PURE__*/function (_PersistentStore) {
|
|
|
180
223
|
_classPrivateFieldInitSpec(_assertThisInitialized(_this), _subscribeToObjects, {
|
|
181
224
|
writable: true,
|
|
182
225
|
value: function value(type, objectsToSubscribe, item) {
|
|
183
|
-
var
|
|
184
|
-
|
|
226
|
+
var _iterator4 = _createForOfIteratorHelper(objectsToSubscribe),
|
|
227
|
+
_step4;
|
|
185
228
|
|
|
186
229
|
try {
|
|
187
|
-
for (
|
|
188
|
-
var object =
|
|
230
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
231
|
+
var object = _step4.value;
|
|
189
232
|
var id = object.getId();
|
|
190
233
|
|
|
191
234
|
if (!_this._subscribed[type][id]) {
|
|
@@ -195,14 +238,15 @@ var ObserverStore = /*#__PURE__*/function (_PersistentStore) {
|
|
|
195
238
|
_this._subscribed[type][id].push(item);
|
|
196
239
|
}
|
|
197
240
|
} catch (err) {
|
|
198
|
-
|
|
241
|
+
_iterator4.e(err);
|
|
199
242
|
} finally {
|
|
200
|
-
|
|
243
|
+
_iterator4.f();
|
|
201
244
|
}
|
|
202
245
|
}
|
|
203
246
|
});
|
|
204
247
|
|
|
205
248
|
_this._subscribed = {};
|
|
249
|
+
_this._multipleSubscribed = {};
|
|
206
250
|
return _this;
|
|
207
251
|
}
|
|
208
252
|
|
|
@@ -243,21 +287,21 @@ function _propagateInsertChange2(type, newObjects) {
|
|
|
243
287
|
for (var _i = 0, _objects = objects; _i < _objects.length; _i++) {
|
|
244
288
|
var object = _objects[_i];
|
|
245
289
|
|
|
246
|
-
var
|
|
247
|
-
|
|
290
|
+
var _iterator5 = _createForOfIteratorHelper(object),
|
|
291
|
+
_step5;
|
|
248
292
|
|
|
249
293
|
try {
|
|
250
|
-
for (
|
|
251
|
-
var sub =
|
|
294
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
295
|
+
var sub = _step5.value;
|
|
252
296
|
|
|
253
297
|
if (!uniqueSubs[sub.subKey]) {
|
|
254
298
|
uniqueSubs[sub.subKey] = sub;
|
|
255
299
|
}
|
|
256
300
|
}
|
|
257
301
|
} catch (err) {
|
|
258
|
-
|
|
302
|
+
_iterator5.e(err);
|
|
259
303
|
} finally {
|
|
260
|
-
|
|
304
|
+
_iterator5.f();
|
|
261
305
|
}
|
|
262
306
|
}
|
|
263
307
|
|
|
@@ -272,12 +316,12 @@ function _propagateInsertChange2(type, newObjects) {
|
|
|
272
316
|
return _this3.find(type, filterFunction).then(function (data) {
|
|
273
317
|
var subKey;
|
|
274
318
|
|
|
275
|
-
var
|
|
276
|
-
|
|
319
|
+
var _iterator6 = _createForOfIteratorHelper(data),
|
|
320
|
+
_step6;
|
|
277
321
|
|
|
278
322
|
try {
|
|
279
|
-
for (
|
|
280
|
-
var d =
|
|
323
|
+
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|
324
|
+
var d = _step6.value;
|
|
281
325
|
|
|
282
326
|
var item = _this3._subscribed[d.getModel().getType()][d.getId()];
|
|
283
327
|
|
|
@@ -285,9 +329,9 @@ function _propagateInsertChange2(type, newObjects) {
|
|
|
285
329
|
if (subKey) break;
|
|
286
330
|
}
|
|
287
331
|
} catch (err) {
|
|
288
|
-
|
|
332
|
+
_iterator6.e(err);
|
|
289
333
|
} finally {
|
|
290
|
-
|
|
334
|
+
_iterator6.f();
|
|
291
335
|
}
|
|
292
336
|
|
|
293
337
|
_classPrivateFieldGet(_this3, _subscribeToObjects).call(_this3, type, objectsToSubscribe, {
|
package/dist/fingerprint.js
CHANGED
|
@@ -5,6 +5,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports["default"] = fingerprint;
|
|
7
7
|
|
|
8
|
+
var _moment = _interopRequireDefault(require("moment"));
|
|
9
|
+
|
|
10
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
11
|
+
|
|
8
12
|
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; } } }; }
|
|
9
13
|
|
|
10
14
|
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); }
|
|
@@ -18,7 +22,15 @@ var CRC32 = require('crc-32');
|
|
|
18
22
|
var _getFingerprint = function _getFingerprint(object) {
|
|
19
23
|
switch (_typeof(object)) {
|
|
20
24
|
case "object":
|
|
21
|
-
|
|
25
|
+
if (object._isAMomentObject) {
|
|
26
|
+
return "m:".concat(object.toISOString());
|
|
27
|
+
} else if (object instanceof Date) {
|
|
28
|
+
return "m:".concat((0, _moment["default"])(object).toISOString());
|
|
29
|
+
} else if (object !== null) {
|
|
30
|
+
return "o:".concat(getObjectFingerprint(object));
|
|
31
|
+
} else {
|
|
32
|
+
return "o:null";
|
|
33
|
+
}
|
|
22
34
|
|
|
23
35
|
case "boolean":
|
|
24
36
|
return "b:".concat(object ? "t" : "f");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dataflux",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.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",
|
|
@@ -89,14 +89,15 @@
|
|
|
89
89
|
"chai": "^4.3.4",
|
|
90
90
|
"chai-subset": "^1.6.0",
|
|
91
91
|
"dotenv-cli": "^4.1.1",
|
|
92
|
-
"mocha": "^9.
|
|
93
|
-
"release-it": "^14.12.
|
|
92
|
+
"mocha": "^9.2.0",
|
|
93
|
+
"release-it": "^14.12.4"
|
|
94
94
|
},
|
|
95
95
|
"dependencies": {
|
|
96
96
|
"axios": "^0.25.0",
|
|
97
97
|
"batch-promises": "^0.0.3",
|
|
98
98
|
"brembo": "^2.0.6",
|
|
99
99
|
"crc-32": "^1.2.0",
|
|
100
|
+
"moment": "^2.29.1",
|
|
100
101
|
"uuid": "^8.3.2"
|
|
101
102
|
},
|
|
102
103
|
"resolutions": {}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: Bug report
|
|
3
|
-
about: Create a bug report
|
|
4
|
-
title: ''
|
|
5
|
-
labels: bug
|
|
6
|
-
assignees: ''
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
**Describe the bug**
|
|
11
|
-
A clear and concise description of what the bug is.
|
|
12
|
-
|
|
13
|
-
**Provide an example**
|
|
14
|
-
Provide an example in terms of prefixes and BGP messages. Possibly provide a snippet of config.yml and prefixes.yml.
|
|
15
|
-
|
|
16
|
-
**Expected behavior**
|
|
17
|
-
A clear and concise description of what you expected to happen.
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: Feature request
|
|
3
|
-
about: Suggest an idea for this project
|
|
4
|
-
title: ''
|
|
5
|
-
labels: enhancement
|
|
6
|
-
assignees: ''
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
**Describe what you would like to achieve**
|
|
11
|
-
A clear and concise description of what you want to happen.
|
|
12
|
-
|
|
13
|
-
**Describe why the current solution (if any) is not satisfactory**
|
|
14
|
-
A clear and concise description.
|
|
15
|
-
|
|
16
|
-
**Provide an example**
|
|
17
|
-
Provide an example in terms of prefixes and BGP messages. Possibly provide a snippet of config.yml and prefixes.yml.
|
package/.github/dependabot.yml
DELETED
package/.github/stale.yml
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# Number of days of inactivity before an issue becomes stale
|
|
2
|
-
daysUntilStale: 90
|
|
3
|
-
# Number of days of inactivity before a stale issue is closed
|
|
4
|
-
daysUntilClose: 1
|
|
5
|
-
# Issues with these labels will never be considered stale
|
|
6
|
-
exemptLabels:
|
|
7
|
-
- pinned
|
|
8
|
-
- security
|
|
9
|
-
- no-stale
|
|
10
|
-
|
|
11
|
-
# Label to use when marking an issue as stale
|
|
12
|
-
staleLabel: wontfix
|
|
13
|
-
|
|
14
|
-
markComment: false
|
|
15
|
-
|
|
16
|
-
# Comment to post when marking an issue as stale. Set to `false` to disable
|
|
17
|
-
closeComment: >
|
|
18
|
-
This issue has been automatically closed as stale.
|
|
19
|
-
This mechanism helps to prioritize feature requests which received more support from the community.
|
|
20
|
-
If you want to open again this issue you have to provide a Pull Request.
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
name: Main
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [ "*" ]
|
|
6
|
-
pull_request:
|
|
7
|
-
branches: [ "*" ]
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
build:
|
|
11
|
-
name: Build
|
|
12
|
-
runs-on: ubuntu-latest
|
|
13
|
-
steps:
|
|
14
|
-
|
|
15
|
-
- name: Set up Javascript/Node
|
|
16
|
-
uses: actions/setup-node@v2
|
|
17
|
-
with:
|
|
18
|
-
node-version: '14'
|
|
19
|
-
|
|
20
|
-
- name: Check out code
|
|
21
|
-
uses: actions/checkout@v2
|
|
22
|
-
with:
|
|
23
|
-
fetch-depth: '0'
|
|
24
|
-
|
|
25
|
-
- name: Cache multiple paths
|
|
26
|
-
uses: actions/cache@v2
|
|
27
|
-
with:
|
|
28
|
-
path: ~/.npm
|
|
29
|
-
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
|
30
|
-
restore-keys: |
|
|
31
|
-
${{ runner.os }}-node-
|
|
32
|
-
|
|
33
|
-
- name: Build
|
|
34
|
-
run: |
|
|
35
|
-
npm install
|
|
36
|
-
npm run compile
|
|
37
|
-
|
|
38
|
-
- name: Upload Artifact
|
|
39
|
-
uses: actions/upload-artifact@v2
|
|
40
|
-
if: ${{ always() }}
|
|
41
|
-
with:
|
|
42
|
-
name: logs
|
|
43
|
-
path: ~/.npm/_logs/*
|
|
44
|
-
retention-days: 14
|
|
45
|
-
|
|
46
|
-
test:
|
|
47
|
-
name: Test
|
|
48
|
-
runs-on: ubuntu-latest
|
|
49
|
-
steps:
|
|
50
|
-
|
|
51
|
-
- name: Set up Javascript/Node
|
|
52
|
-
uses: actions/setup-node@v2
|
|
53
|
-
with:
|
|
54
|
-
node-version: '14'
|
|
55
|
-
|
|
56
|
-
- name: Check out code
|
|
57
|
-
uses: actions/checkout@v2
|
|
58
|
-
with:
|
|
59
|
-
fetch-depth: '0'
|
|
60
|
-
|
|
61
|
-
- name: Cache multiple paths
|
|
62
|
-
uses: actions/cache@v2
|
|
63
|
-
with:
|
|
64
|
-
path: ~/.npm
|
|
65
|
-
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
|
66
|
-
restore-keys: |
|
|
67
|
-
${{ runner.os }}-node-
|
|
68
|
-
|
|
69
|
-
- name: Install
|
|
70
|
-
run: |
|
|
71
|
-
npm install
|
|
72
|
-
|
|
73
|
-
- name: Tests
|
|
74
|
-
run: |
|
|
75
|
-
npm run test
|
|
76
|
-
|
|
77
|
-
- name: Upload Artifact
|
|
78
|
-
uses: actions/upload-artifact@v2
|
|
79
|
-
if: ${{ always() }}
|
|
80
|
-
with:
|
|
81
|
-
name: logs
|
|
82
|
-
path: ~/.npm/_logs/*
|
|
83
|
-
retention-days: 14
|