@civet/core 1.0.0-rc7 → 1.1.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.
@@ -171,8 +171,13 @@ var DataProvider = /*#__PURE__*/function () {
171
171
  }
172
172
  }, {
173
173
  key: "compareRequests",
174
- value: function compareRequests(prev, next) {
175
- return (0, _fastDeepEqual["default"])(prev, next);
174
+ value: function compareRequests(nextRequestDetails, prevRequestDetails) {
175
+ return (0, _fastDeepEqual["default"])(nextRequestDetails, prevRequestDetails);
176
+ }
177
+ }, {
178
+ key: "shouldPersist",
179
+ value: function shouldPersist(nextRequestDetails, prevRequestDetails, persistent) {
180
+ return persistent === 'very' || persistent && prevRequestDetails.name === nextRequestDetails.name;
176
181
  }
177
182
  }, {
178
183
  key: "compareItemVersions",
@@ -186,18 +191,18 @@ var DataProvider = /*#__PURE__*/function () {
186
191
  }
187
192
  }, {
188
193
  key: "transition",
189
- value: function transition(nextData) {
190
- return nextData;
194
+ value: function transition(nextContext) {
195
+ return nextContext.data;
191
196
  }
192
197
  }, {
193
198
  key: "recycleItems",
194
- value: function recycleItems(nextData, prevData) {
199
+ value: function recycleItems(nextContext, prevContext) {
195
200
  var _this7 = this;
196
201
 
197
202
  var prevMapping = {};
198
203
 
199
- if (nextData.length > 0) {
200
- prevData.forEach(function (item) {
204
+ if (nextContext.data.length > 0) {
205
+ prevContext.data.forEach(function (item) {
201
206
  var id = _this7.getItemIdentifier(item);
202
207
 
203
208
  if (id != null) prevMapping[id] = item;
@@ -206,8 +211,8 @@ var DataProvider = /*#__PURE__*/function () {
206
211
 
207
212
  var result;
208
213
 
209
- if (prevData.length > 0) {
210
- result = nextData.map(function (nextItem) {
214
+ if (prevContext.data.length > 0) {
215
+ result = nextContext.data.map(function (nextItem) {
211
216
  var id = _this7.getItemIdentifier(nextItem);
212
217
 
213
218
  if (id != null && Object.prototype.hasOwnProperty.call(prevMapping, id)) {
@@ -218,13 +223,13 @@ var DataProvider = /*#__PURE__*/function () {
218
223
  return nextItem;
219
224
  });
220
225
  } else {
221
- result = nextData;
226
+ result = nextContext.data;
222
227
  }
223
228
 
224
- if (prevData.length === result.length && result.reduce(function (sum, item, i) {
225
- return sum && Object.is(prevData[i], item);
229
+ if (prevContext.data.length === result.length && result.reduce(function (sum, item, i) {
230
+ return sum && Object.is(prevContext.data[i], item);
226
231
  }, true)) {
227
- return prevData;
232
+ return prevContext.data;
228
233
  }
229
234
 
230
235
  return result;
@@ -22,7 +22,7 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
22
22
  /**
23
23
  * Returns incrementing unique string identifiers.
24
24
  * Uniqueness is guaranteed for <Number.MAX_SAFE_INTEGER> iterations.
25
- * The values can be compared alphanumerically, as long as they do not exceed the previously specified iterations.
25
+ * The values can be compared alphanumerically, as long as they do not exceed the previously specified number of iterations.
26
26
  *
27
27
  * @param {string?} previous Previous identifier
28
28
  */
@@ -15,8 +15,7 @@ var _Meta = _interopRequireDefault(require("./Meta"));
15
15
 
16
16
  var _uniqueIdentifier = _interopRequireDefault(require("./uniqueIdentifier"));
17
17
 
18
- var _excluded = ["dataProvider", "name", "query", "empty", "options", "persistent"],
19
- _excluded2 = ["data"];
18
+ var _excluded = ["dataProvider", "name", "query", "empty", "options", "persistent"];
20
19
 
21
20
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
22
21
 
@@ -53,11 +52,11 @@ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) r
53
52
  */
54
53
  function useResource(_ref) {
55
54
  var dataProviderProp = _ref.dataProvider,
56
- name = _ref.name,
57
- query = _ref.query,
58
- empty = _ref.empty,
59
- options = _ref.options,
60
- persistent = _ref.persistent,
55
+ nextName = _ref.name,
56
+ nextQuery = _ref.query,
57
+ nextEmpty = _ref.empty,
58
+ nextOptions = _ref.options,
59
+ nextPersistent = _ref.persistent,
61
60
  rest = _objectWithoutProperties(_ref, _excluded);
62
61
 
63
62
  var configContext = (0, _context2.useConfigContext)();
@@ -75,86 +74,88 @@ function useResource(_ref) {
75
74
  throw new Error('Constant violation: The DataProvider provided to the useResource hook must not be replaced - Check your ConfigContext provider and the dataProvider property');
76
75
  }
77
76
 
78
- var comparator = {
79
- name: name,
80
- query: query,
81
- empty: empty,
82
- options: options
83
- };
77
+ var nextRequestDetails = _react["default"].useMemo(function () {
78
+ return {
79
+ name: nextName,
80
+ query: nextQuery,
81
+ empty: nextEmpty,
82
+ options: nextOptions
83
+ };
84
+ }, [nextName, nextQuery, nextEmpty, nextOptions]);
84
85
 
85
86
  var _React$useState = _react["default"].useState(function () {
86
87
  var request = (0, _uniqueIdentifier["default"])();
87
88
  var revision = (0, _uniqueIdentifier["default"])();
88
89
  return {
89
- comparator: comparator,
90
+ requestDetails: nextRequestDetails,
90
91
  request: request,
91
92
  revision: revision,
92
- isLoading: !empty,
93
+ isLoading: !nextRequestDetails.empty,
93
94
  value: {
94
- name: name,
95
- query: query,
96
- options: options,
95
+ name: nextRequestDetails.name,
96
+ query: nextRequestDetails.query,
97
+ options: nextRequestDetails.options,
97
98
  request: request,
98
99
  revision: revision,
99
100
  data: [],
100
101
  meta: {},
101
102
  error: undefined,
102
- isEmpty: empty,
103
- isIncomplete: !empty,
104
- isInitial: !empty
103
+ isEmpty: !!nextRequestDetails.empty,
104
+ isIncomplete: !nextRequestDetails.empty,
105
+ isInitial: !nextRequestDetails.empty
105
106
  },
106
- persistent: persistent
107
+ persistent: nextPersistent
107
108
  };
108
109
  }),
109
110
  _React$useState2 = _slicedToArray(_React$useState, 2),
110
111
  state = _React$useState2[0],
111
112
  setState = _React$useState2[1];
112
113
 
113
- var prevComparator = state.comparator,
114
+ var requestDetails = state.requestDetails,
114
115
  request = state.request,
115
116
  revision = state.revision,
116
117
  isLoading = state.isLoading,
117
118
  value = state.value,
118
- prevPersistent = state.persistent;
119
+ persistent = state.persistent;
119
120
 
120
- if (prevComparator !== comparator && !dataProvider.compareRequests(prevComparator, comparator)) {
121
+ if (requestDetails !== nextRequestDetails && !dataProvider.compareRequests(nextRequestDetails, requestDetails)) {
121
122
  setState(function (prevState) {
122
123
  var nextRequest = (0, _uniqueIdentifier["default"])(prevState.request);
123
124
  var nextRevision = (0, _uniqueIdentifier["default"])(prevState.revision);
124
- var isPersistent;
125
+ var isPersistent = false;
125
126
 
126
- if (prevState.value.meta.persistent === 'very' || persistent === 'very' && prevState.persistent === 'very') {
127
+ if (prevState.persistent === 'very' && nextPersistent === 'very') {
127
128
  isPersistent = 'very';
128
- } else if (prevState.value.meta.persistent || persistent && prevState.persistent) {
129
+ } else if (prevState.persistent && nextPersistent) {
129
130
  isPersistent = true;
130
131
  }
131
132
 
132
- var shouldValuePersist = !empty && isPersistent && (isPersistent === 'very' || prevState.comparator.name === comparator.name);
133
+ var shouldValuePersist = !nextRequestDetails.empty && dataProvider.shouldPersist(nextRequestDetails, prevState.requestDetails, isPersistent, prevState.value);
133
134
  return {
134
- comparator: comparator,
135
+ requestDetails: nextRequestDetails,
135
136
  request: nextRequest,
136
137
  revision: nextRevision,
137
- isLoading: !empty,
138
+ isLoading: !nextRequestDetails.empty,
138
139
  value: shouldValuePersist ? prevState.value : {
139
- name: name,
140
- query: query,
141
- options: options,
140
+ name: nextRequestDetails.name,
141
+ query: nextRequestDetails.query,
142
+ options: nextRequestDetails.options,
142
143
  request: nextRequest,
143
144
  revision: nextRevision,
144
145
  data: [],
145
146
  meta: {},
146
147
  error: undefined,
147
- isEmpty: empty,
148
- isIncomplete: !empty,
149
- isInitial: !empty
148
+ isEmpty: !!nextRequestDetails.empty,
149
+ isIncomplete: !nextRequestDetails.empty,
150
+ isInitial: !nextRequestDetails.empty
150
151
  },
151
- persistent: persistent
152
+ persistent: nextPersistent
152
153
  };
153
154
  });
154
- } else if (prevPersistent !== persistent) {
155
+ } else if (persistent !== nextPersistent) {
155
156
  setState(function (prevState) {
156
157
  return _objectSpread(_objectSpread({}, prevState), {}, {
157
- persistent: persistent
158
+ persistent: nextPersistent
158
159
  });
159
160
  });
160
161
  }
@@ -189,13 +190,13 @@ function useResource(_ref) {
189
190
 
190
191
 
191
192
  _react["default"].useEffect(function () {
192
- if (empty) return undefined;
193
- var unsubscribe = dataProvider.subscribe(name, notify);
193
+ if (requestDetails.empty) return undefined;
194
+ var unsubscribe = dataProvider.subscribe(requestDetails.name, notify);
194
195
  return unsubscribe;
195
- }, [!empty, dataProvider, name, notify]);
196
+ }, [requestDetails.empty, dataProvider, requestDetails.name, notify]);
196
197
 
197
198
  _react["default"].useEffect(function () {
198
- if (empty) return undefined;
199
+ if (requestDetails.empty) return undefined;
199
200
  var abortSignal = new _AbortSignal["default"]();
200
201
  var meta = new _Meta["default"](_objectSpread({}, value.meta));
201
202
 
@@ -213,32 +214,29 @@ function useResource(_ref) {
213
214
  });
214
215
  }
215
216
 
216
- var _prevState$value = prevState.value,
217
- prevData = _prevState$value.data,
218
- prevContext = _objectWithoutProperties(_prevState$value, _excluded2);
219
-
220
217
  var context = {
221
- name: name,
222
- query: query,
223
- options: options,
218
+ name: requestDetails.name,
219
+ query: requestDetails.query,
220
+ options: requestDetails.options,
224
221
  request: request,
225
222
  revision: revision,
226
- meta: meta.commit(prevContext.meta),
223
+ data: data,
224
+ meta: meta.commit(prevState.value.meta),
227
225
  error: undefined,
228
226
  isEmpty: false,
229
227
  isIncomplete: !done,
230
228
  isInitial: !!prevState.isInitial && !done
231
229
  };
230
+ context.data = dataProvider.transition(context, prevState.value);
231
+ context.data = dataProvider.recycleItems(context, prevState.value);
232
232
  return _objectSpread(_objectSpread({}, prevState), {}, {
233
233
  isLoading: !done,
234
- value: _objectSpread(_objectSpread({}, context), {}, {
235
- data: dataProvider.recycleItems(dataProvider.transition(data, prevData, context, prevContext), prevData, context, prevContext)
236
- })
234
+ value: context
237
235
  });
238
236
  });
239
237
  };
240
238
 
241
- dataProvider.continuousGet(name, query, options, meta, callback, abortSignal);
239
+ dataProvider.continuousGet(requestDetails.name, requestDetails.query, requestDetails.options, meta, callback, abortSignal);
242
240
  return function () {
243
241
  abortSignal.abort();
244
242
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@civet/core",
3
- "version": "1.0.0-rc7",
3
+ "version": "1.1.0",
4
4
  "description": "Civet",
5
5
  "main": "./lib/index.js",
6
6
  "scripts": {
@@ -127,8 +127,14 @@ class DataProvider {
127
127
  });
128
128
  }
129
129
 
130
- compareRequests(prev, next) {
131
- return deepEquals(prev, next);
130
+ compareRequests(nextRequestDetails, prevRequestDetails) {
131
+ return deepEquals(nextRequestDetails, prevRequestDetails);
132
+ }
133
+
134
+ shouldPersist(nextRequestDetails, prevRequestDetails, persistent) {
135
+ return (
136
+ persistent === 'very' || (persistent && prevRequestDetails.name === nextRequestDetails.name)
137
+ );
132
138
  }
133
139
 
134
140
  compareItemVersions() {
@@ -139,21 +145,21 @@ class DataProvider {
139
145
  return objectHash(item);
140
146
  }
141
147
 
142
- transition(nextData) {
143
- return nextData;
148
+ transition(nextContext) {
149
+ return nextContext.data;
144
150
  }
145
151
 
146
- recycleItems(nextData, prevData) {
152
+ recycleItems(nextContext, prevContext) {
147
153
  const prevMapping = {};
148
- if (nextData.length > 0) {
149
- prevData.forEach((item) => {
154
+ if (nextContext.data.length > 0) {
155
+ prevContext.data.forEach((item) => {
150
156
  const id = this.getItemIdentifier(item);
151
157
  if (id != null) prevMapping[id] = item;
152
158
  });
153
159
  }
154
160
  let result;
155
- if (prevData.length > 0) {
156
- result = nextData.map((nextItem) => {
161
+ if (prevContext.data.length > 0) {
162
+ result = nextContext.data.map((nextItem) => {
157
163
  const id = this.getItemIdentifier(nextItem);
158
164
  if (id != null && Object.prototype.hasOwnProperty.call(prevMapping, id)) {
159
165
  const prevItem = prevMapping[id];
@@ -162,13 +168,13 @@ class DataProvider {
162
168
  return nextItem;
163
169
  });
164
170
  } else {
165
- result = nextData;
171
+ result = nextContext.data;
166
172
  }
167
173
  if (
168
- prevData.length === result.length &&
169
- result.reduce((sum, item, i) => sum && Object.is(prevData[i], item), true)
174
+ prevContext.data.length === result.length &&
175
+ result.reduce((sum, item, i) => sum && Object.is(prevContext.data[i], item), true)
170
176
  ) {
171
- return prevData;
177
+ return prevContext.data;
172
178
  }
173
179
  return result;
174
180
  }
@@ -3,7 +3,7 @@ import { v1 as uuid } from 'uuid';
3
3
  /**
4
4
  * Returns incrementing unique string identifiers.
5
5
  * Uniqueness is guaranteed for <Number.MAX_SAFE_INTEGER> iterations.
6
- * The values can be compared alphanumerically, as long as they do not exceed the previously specified iterations.
6
+ * The values can be compared alphanumerically, as long as they do not exceed the previously specified number of iterations.
7
7
  *
8
8
  * @param {string?} previous Previous identifier
9
9
  */
@@ -12,11 +12,11 @@ import uniqueIdentifier from './uniqueIdentifier';
12
12
  */
13
13
  function useResource({
14
14
  dataProvider: dataProviderProp,
15
- name,
16
- query,
17
- empty,
18
- options,
19
- persistent,
15
+ name: nextName,
16
+ query: nextQuery,
17
+ empty: nextEmpty,
18
+ options: nextOptions,
19
+ persistent: nextPersistent,
20
20
  ...rest
21
21
  }) {
22
22
  const configContext = useConfigContext();
@@ -33,82 +33,82 @@ function useResource({
33
33
  );
34
34
  }
35
35
 
36
- const comparator = { name, query, empty, options };
36
+ const nextRequestDetails = React.useMemo(
37
+ () => ({ name: nextName, query: nextQuery, empty: nextEmpty, options: nextOptions }),
38
+ [nextName, nextQuery, nextEmpty, nextOptions],
39
+ );
37
40
  const [state, setState] = React.useState(() => {
38
41
  const request = uniqueIdentifier();
39
42
  const revision = uniqueIdentifier();
40
43
  return {
41
- comparator,
44
+ requestDetails: nextRequestDetails,
42
45
  request,
43
46
  revision,
44
- isLoading: !empty,
47
+ isLoading: !nextRequestDetails.empty,
45
48
  value: {
46
- name,
47
- query,
48
- options,
49
+ name: nextRequestDetails.name,
50
+ query: nextRequestDetails.query,
51
+ options: nextRequestDetails.options,
49
52
  request,
50
53
  revision,
51
54
  data: [],
52
55
  meta: {},
53
56
  error: undefined,
54
- isEmpty: empty,
55
- isIncomplete: !empty,
56
- isInitial: !empty,
57
+ isEmpty: !!nextRequestDetails.empty,
58
+ isIncomplete: !nextRequestDetails.empty,
59
+ isInitial: !nextRequestDetails.empty,
57
60
  },
58
- persistent,
61
+ persistent: nextPersistent,
59
62
  };
60
63
  });
61
- const {
62
- comparator: prevComparator,
63
- request,
64
- revision,
65
- isLoading,
66
- value,
67
- persistent: prevPersistent,
68
- } = state;
69
-
70
- if (prevComparator !== comparator && !dataProvider.compareRequests(prevComparator, comparator)) {
64
+ const { requestDetails, request, revision, isLoading, value, persistent } = state;
65
+
66
+ if (
67
+ requestDetails !== nextRequestDetails &&
68
+ !dataProvider.compareRequests(nextRequestDetails, requestDetails)
69
+ ) {
71
70
  setState((prevState) => {
72
71
  const nextRequest = uniqueIdentifier(prevState.request);
73
72
  const nextRevision = uniqueIdentifier(prevState.revision);
74
- let isPersistent;
75
- if (
76
- prevState.value.meta.persistent === 'very' ||
77
- (persistent === 'very' && prevState.persistent === 'very')
78
- ) {
73
+ let isPersistent = false;
74
+ if (prevState.persistent === 'very' && nextPersistent === 'very') {
79
75
  isPersistent = 'very';
80
- } else if (prevState.value.meta.persistent || (persistent && prevState.persistent)) {
76
+ } else if (prevState.persistent && nextPersistent) {
81
77
  isPersistent = true;
82
78
  }
83
79
  const shouldValuePersist =
84
- !empty &&
85
- isPersistent &&
86
- (isPersistent === 'very' || prevState.comparator.name === comparator.name);
80
+ !nextRequestDetails.empty &&
81
+ dataProvider.shouldPersist(
82
+ nextRequestDetails,
83
+ prevState.requestDetails,
84
+ isPersistent,
85
+ prevState.value,
86
+ );
87
87
  return {
88
- comparator,
88
+ requestDetails: nextRequestDetails,
89
89
  request: nextRequest,
90
90
  revision: nextRevision,
91
- isLoading: !empty,
91
+ isLoading: !nextRequestDetails.empty,
92
92
  value: shouldValuePersist
93
93
  ? prevState.value
94
94
  : {
95
- name,
96
- query,
97
- options,
95
+ name: nextRequestDetails.name,
96
+ query: nextRequestDetails.query,
97
+ options: nextRequestDetails.options,
98
98
  request: nextRequest,
99
99
  revision: nextRevision,
100
100
  data: [],
101
101
  meta: {},
102
102
  error: undefined,
103
- isEmpty: empty,
104
- isIncomplete: !empty,
105
- isInitial: !empty,
103
+ isEmpty: !!nextRequestDetails.empty,
104
+ isIncomplete: !nextRequestDetails.empty,
105
+ isInitial: !nextRequestDetails.empty,
106
106
  },
107
- persistent,
107
+ persistent: nextPersistent,
108
108
  };
109
109
  });
110
- } else if (prevPersistent !== persistent) {
111
- setState((prevState) => ({ ...prevState, persistent }));
110
+ } else if (persistent !== nextPersistent) {
111
+ setState((prevState) => ({ ...prevState, persistent: nextPersistent }));
112
112
  }
113
113
 
114
114
  const notify = React.useCallback(
@@ -126,14 +126,14 @@ function useResource({
126
126
 
127
127
  // DataProvider events
128
128
  React.useEffect(() => {
129
- if (empty) return undefined;
129
+ if (requestDetails.empty) return undefined;
130
130
 
131
- const unsubscribe = dataProvider.subscribe(name, notify);
131
+ const unsubscribe = dataProvider.subscribe(requestDetails.name, notify);
132
132
  return unsubscribe;
133
- }, [!empty, dataProvider, name, notify]);
133
+ }, [requestDetails.empty, dataProvider, requestDetails.name, notify]);
134
134
 
135
135
  React.useEffect(() => {
136
- if (empty) return undefined;
136
+ if (requestDetails.empty) return undefined;
137
137
 
138
138
  const abortSignal = new AbortSignal();
139
139
 
@@ -155,37 +155,38 @@ function useResource({
155
155
  };
156
156
  }
157
157
 
158
- const { data: prevData, ...prevContext } = prevState.value;
159
158
  const context = {
160
- name,
161
- query,
162
- options,
159
+ name: requestDetails.name,
160
+ query: requestDetails.query,
161
+ options: requestDetails.options,
163
162
  request,
164
163
  revision,
165
- meta: meta.commit(prevContext.meta),
164
+ data,
165
+ meta: meta.commit(prevState.value.meta),
166
166
  error: undefined,
167
167
  isEmpty: false,
168
168
  isIncomplete: !done,
169
169
  isInitial: !!prevState.isInitial && !done,
170
170
  };
171
+ context.data = dataProvider.transition(context, prevState.value);
172
+ context.data = dataProvider.recycleItems(context, prevState.value);
171
173
 
172
174
  return {
173
175
  ...prevState,
174
176
  isLoading: !done,
175
- value: {
176
- ...context,
177
- data: dataProvider.recycleItems(
178
- dataProvider.transition(data, prevData, context, prevContext),
179
- prevData,
180
- context,
181
- prevContext,
182
- ),
183
- },
177
+ value: context,
184
178
  };
185
179
  });
186
180
  };
187
181
 
188
- dataProvider.continuousGet(name, query, options, meta, callback, abortSignal);
182
+ dataProvider.continuousGet(
183
+ requestDetails.name,
184
+ requestDetails.query,
185
+ requestDetails.options,
186
+ meta,
187
+ callback,
188
+ abortSignal,
189
+ );
189
190
 
190
191
  return () => {
191
192
  abortSignal.abort();