@civet/core 1.0.0-rc8 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/DataProvider.js +26 -13
- package/lib/Meta.js +2 -1
- package/lib/uniqueIdentifier.js +1 -1
- package/lib/useResource.js +74 -64
- package/package.json +1 -1
- package/src/DataProvider.js +25 -13
- package/src/Meta.js +2 -1
- package/src/uniqueIdentifier.js +1 -1
- package/src/useResource.js +75 -66
package/lib/DataProvider.js
CHANGED
|
@@ -68,6 +68,14 @@ var DataProvider = /*#__PURE__*/function () {
|
|
|
68
68
|
_createClass(DataProvider, [{
|
|
69
69
|
key: "extend",
|
|
70
70
|
value: function extend() {}
|
|
71
|
+
}, {
|
|
72
|
+
key: "createInstance",
|
|
73
|
+
value: function createInstance() {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}, {
|
|
77
|
+
key: "releaseInstance",
|
|
78
|
+
value: function releaseInstance() {}
|
|
71
79
|
}, {
|
|
72
80
|
key: "subscribe",
|
|
73
81
|
value: function subscribe(resource, handler) {
|
|
@@ -171,8 +179,13 @@ var DataProvider = /*#__PURE__*/function () {
|
|
|
171
179
|
}
|
|
172
180
|
}, {
|
|
173
181
|
key: "compareRequests",
|
|
174
|
-
value: function compareRequests(
|
|
175
|
-
return (0, _fastDeepEqual["default"])(
|
|
182
|
+
value: function compareRequests(nextRequestDetails, prevRequestDetails) {
|
|
183
|
+
return (0, _fastDeepEqual["default"])(nextRequestDetails, prevRequestDetails);
|
|
184
|
+
}
|
|
185
|
+
}, {
|
|
186
|
+
key: "shouldPersist",
|
|
187
|
+
value: function shouldPersist(nextRequestDetails, prevRequestDetails, persistent) {
|
|
188
|
+
return persistent === 'very' || persistent && prevRequestDetails.name === nextRequestDetails.name;
|
|
176
189
|
}
|
|
177
190
|
}, {
|
|
178
191
|
key: "compareItemVersions",
|
|
@@ -186,18 +199,18 @@ var DataProvider = /*#__PURE__*/function () {
|
|
|
186
199
|
}
|
|
187
200
|
}, {
|
|
188
201
|
key: "transition",
|
|
189
|
-
value: function transition(
|
|
190
|
-
return
|
|
202
|
+
value: function transition(nextContext) {
|
|
203
|
+
return nextContext.data;
|
|
191
204
|
}
|
|
192
205
|
}, {
|
|
193
206
|
key: "recycleItems",
|
|
194
|
-
value: function recycleItems(
|
|
207
|
+
value: function recycleItems(nextContext, prevContext) {
|
|
195
208
|
var _this7 = this;
|
|
196
209
|
|
|
197
210
|
var prevMapping = {};
|
|
198
211
|
|
|
199
|
-
if (
|
|
200
|
-
|
|
212
|
+
if (nextContext.data.length > 0) {
|
|
213
|
+
prevContext.data.forEach(function (item) {
|
|
201
214
|
var id = _this7.getItemIdentifier(item);
|
|
202
215
|
|
|
203
216
|
if (id != null) prevMapping[id] = item;
|
|
@@ -206,8 +219,8 @@ var DataProvider = /*#__PURE__*/function () {
|
|
|
206
219
|
|
|
207
220
|
var result;
|
|
208
221
|
|
|
209
|
-
if (
|
|
210
|
-
result =
|
|
222
|
+
if (prevContext.data.length > 0) {
|
|
223
|
+
result = nextContext.data.map(function (nextItem) {
|
|
211
224
|
var id = _this7.getItemIdentifier(nextItem);
|
|
212
225
|
|
|
213
226
|
if (id != null && Object.prototype.hasOwnProperty.call(prevMapping, id)) {
|
|
@@ -218,13 +231,13 @@ var DataProvider = /*#__PURE__*/function () {
|
|
|
218
231
|
return nextItem;
|
|
219
232
|
});
|
|
220
233
|
} else {
|
|
221
|
-
result =
|
|
234
|
+
result = nextContext.data;
|
|
222
235
|
}
|
|
223
236
|
|
|
224
|
-
if (
|
|
225
|
-
return sum && Object.is(
|
|
237
|
+
if (prevContext.data.length === result.length && result.reduce(function (sum, item, i) {
|
|
238
|
+
return sum && Object.is(prevContext.data[i], item);
|
|
226
239
|
}, true)) {
|
|
227
|
-
return
|
|
240
|
+
return prevContext.data;
|
|
228
241
|
}
|
|
229
242
|
|
|
230
243
|
return result;
|
package/lib/Meta.js
CHANGED
|
@@ -18,10 +18,11 @@ function _defineProperties(target, props) { for (var i = 0; i < props.length; i+
|
|
|
18
18
|
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
|
19
19
|
|
|
20
20
|
var Meta = /*#__PURE__*/function () {
|
|
21
|
-
function Meta(base) {
|
|
21
|
+
function Meta(base, instance) {
|
|
22
22
|
_classCallCheck(this, Meta);
|
|
23
23
|
|
|
24
24
|
this.data = base == null ? {} : base;
|
|
25
|
+
this.instance = instance;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
_createClass(Meta, [{
|
package/lib/uniqueIdentifier.js
CHANGED
|
@@ -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
|
*/
|
package/lib/useResource.js
CHANGED
|
@@ -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,19 +52,19 @@ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) r
|
|
|
53
52
|
*/
|
|
54
53
|
function useResource(_ref) {
|
|
55
54
|
var dataProviderProp = _ref.dataProvider,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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)();
|
|
64
63
|
var currentDataProvider = dataProviderProp || configContext.dataProvider;
|
|
65
64
|
|
|
66
|
-
var
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
var _React$useState = _react["default"].useState(currentDataProvider),
|
|
66
|
+
_React$useState2 = _slicedToArray(_React$useState, 1),
|
|
67
|
+
dataProvider = _React$useState2[0];
|
|
69
68
|
|
|
70
69
|
if (dataProvider == null) {
|
|
71
70
|
throw new Error('Unmet requirement: The DataProvider for the useResource hook is missing - Check your ConfigContext provider and the dataProvider property');
|
|
@@ -75,86 +74,100 @@ 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
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
};
|
|
77
|
+
var _React$useState3 = _react["default"].useState(function () {
|
|
78
|
+
return dataProvider.createInstance();
|
|
79
|
+
}),
|
|
80
|
+
_React$useState4 = _slicedToArray(_React$useState3, 1),
|
|
81
|
+
instance = _React$useState4[0];
|
|
84
82
|
|
|
85
|
-
|
|
83
|
+
_react["default"].useEffect(function () {
|
|
84
|
+
return function () {
|
|
85
|
+
dataProvider.releaseInstance(instance);
|
|
86
|
+
};
|
|
87
|
+
}, []);
|
|
88
|
+
|
|
89
|
+
var nextRequestDetails = _react["default"].useMemo(function () {
|
|
90
|
+
return {
|
|
91
|
+
name: nextName,
|
|
92
|
+
query: nextQuery,
|
|
93
|
+
empty: nextEmpty,
|
|
94
|
+
options: nextOptions
|
|
95
|
+
};
|
|
96
|
+
}, [nextName, nextQuery, nextEmpty, nextOptions]);
|
|
97
|
+
|
|
98
|
+
var _React$useState5 = _react["default"].useState(function () {
|
|
86
99
|
var request = (0, _uniqueIdentifier["default"])();
|
|
87
100
|
var revision = (0, _uniqueIdentifier["default"])();
|
|
88
101
|
return {
|
|
89
|
-
|
|
102
|
+
requestDetails: nextRequestDetails,
|
|
90
103
|
request: request,
|
|
91
104
|
revision: revision,
|
|
92
|
-
isLoading: !empty,
|
|
105
|
+
isLoading: !nextRequestDetails.empty,
|
|
93
106
|
value: {
|
|
94
|
-
name: name,
|
|
95
|
-
query: query,
|
|
96
|
-
options: options,
|
|
107
|
+
name: nextRequestDetails.name,
|
|
108
|
+
query: nextRequestDetails.query,
|
|
109
|
+
options: nextRequestDetails.options,
|
|
97
110
|
request: request,
|
|
98
111
|
revision: revision,
|
|
99
112
|
data: [],
|
|
100
113
|
meta: {},
|
|
101
114
|
error: undefined,
|
|
102
|
-
isEmpty: !!empty,
|
|
103
|
-
isIncomplete: !empty,
|
|
104
|
-
isInitial: !empty
|
|
115
|
+
isEmpty: !!nextRequestDetails.empty,
|
|
116
|
+
isIncomplete: !nextRequestDetails.empty,
|
|
117
|
+
isInitial: !nextRequestDetails.empty
|
|
105
118
|
},
|
|
106
|
-
persistent:
|
|
119
|
+
persistent: nextPersistent
|
|
107
120
|
};
|
|
108
121
|
}),
|
|
109
|
-
_React$
|
|
110
|
-
state = _React$
|
|
111
|
-
setState = _React$
|
|
122
|
+
_React$useState6 = _slicedToArray(_React$useState5, 2),
|
|
123
|
+
state = _React$useState6[0],
|
|
124
|
+
setState = _React$useState6[1];
|
|
112
125
|
|
|
113
|
-
var
|
|
126
|
+
var requestDetails = state.requestDetails,
|
|
114
127
|
request = state.request,
|
|
115
128
|
revision = state.revision,
|
|
116
129
|
isLoading = state.isLoading,
|
|
117
130
|
value = state.value,
|
|
118
|
-
|
|
131
|
+
persistent = state.persistent;
|
|
119
132
|
|
|
120
|
-
if (
|
|
133
|
+
if (requestDetails !== nextRequestDetails && !dataProvider.compareRequests(nextRequestDetails, requestDetails)) {
|
|
121
134
|
setState(function (prevState) {
|
|
122
135
|
var nextRequest = (0, _uniqueIdentifier["default"])(prevState.request);
|
|
123
136
|
var nextRevision = (0, _uniqueIdentifier["default"])(prevState.revision);
|
|
124
|
-
var isPersistent;
|
|
137
|
+
var isPersistent = false;
|
|
125
138
|
|
|
126
|
-
if (prevState.
|
|
139
|
+
if (prevState.persistent === 'very' && nextPersistent === 'very') {
|
|
127
140
|
isPersistent = 'very';
|
|
128
|
-
} else if (prevState.
|
|
141
|
+
} else if (prevState.persistent && nextPersistent) {
|
|
129
142
|
isPersistent = true;
|
|
130
143
|
}
|
|
131
144
|
|
|
132
|
-
var shouldValuePersist = !empty &&
|
|
145
|
+
var shouldValuePersist = !nextRequestDetails.empty && dataProvider.shouldPersist(nextRequestDetails, prevState.requestDetails, isPersistent, prevState.value);
|
|
133
146
|
return {
|
|
134
|
-
|
|
147
|
+
requestDetails: nextRequestDetails,
|
|
135
148
|
request: nextRequest,
|
|
136
149
|
revision: nextRevision,
|
|
137
|
-
isLoading: !empty,
|
|
150
|
+
isLoading: !nextRequestDetails.empty,
|
|
138
151
|
value: shouldValuePersist ? prevState.value : {
|
|
139
|
-
name: name,
|
|
140
|
-
query: query,
|
|
141
|
-
options: options,
|
|
152
|
+
name: nextRequestDetails.name,
|
|
153
|
+
query: nextRequestDetails.query,
|
|
154
|
+
options: nextRequestDetails.options,
|
|
142
155
|
request: nextRequest,
|
|
143
156
|
revision: nextRevision,
|
|
144
157
|
data: [],
|
|
145
158
|
meta: {},
|
|
146
159
|
error: undefined,
|
|
147
|
-
isEmpty: !!empty,
|
|
148
|
-
isIncomplete: !empty,
|
|
149
|
-
isInitial: !empty
|
|
160
|
+
isEmpty: !!nextRequestDetails.empty,
|
|
161
|
+
isIncomplete: !nextRequestDetails.empty,
|
|
162
|
+
isInitial: !nextRequestDetails.empty
|
|
150
163
|
},
|
|
151
|
-
persistent:
|
|
164
|
+
persistent: nextPersistent
|
|
152
165
|
};
|
|
153
166
|
});
|
|
154
|
-
} else if (
|
|
167
|
+
} else if (persistent !== nextPersistent) {
|
|
155
168
|
setState(function (prevState) {
|
|
156
169
|
return _objectSpread(_objectSpread({}, prevState), {}, {
|
|
157
|
-
persistent:
|
|
170
|
+
persistent: nextPersistent
|
|
158
171
|
});
|
|
159
172
|
});
|
|
160
173
|
}
|
|
@@ -189,15 +202,15 @@ function useResource(_ref) {
|
|
|
189
202
|
|
|
190
203
|
|
|
191
204
|
_react["default"].useEffect(function () {
|
|
192
|
-
if (empty) return undefined;
|
|
193
|
-
var unsubscribe = dataProvider.subscribe(name, notify);
|
|
205
|
+
if (requestDetails.empty) return undefined;
|
|
206
|
+
var unsubscribe = dataProvider.subscribe(requestDetails.name, notify);
|
|
194
207
|
return unsubscribe;
|
|
195
|
-
}, [
|
|
208
|
+
}, [requestDetails.empty, dataProvider, requestDetails.name, notify]);
|
|
196
209
|
|
|
197
210
|
_react["default"].useEffect(function () {
|
|
198
|
-
if (empty) return undefined;
|
|
211
|
+
if (requestDetails.empty) return undefined;
|
|
199
212
|
var abortSignal = new _AbortSignal["default"]();
|
|
200
|
-
var meta = new _Meta["default"](_objectSpread({}, value.meta));
|
|
213
|
+
var meta = new _Meta["default"](_objectSpread({}, value.meta), instance);
|
|
201
214
|
|
|
202
215
|
var callback = function callback(error, done, data) {
|
|
203
216
|
setState(function (prevState) {
|
|
@@ -213,32 +226,29 @@ function useResource(_ref) {
|
|
|
213
226
|
});
|
|
214
227
|
}
|
|
215
228
|
|
|
216
|
-
var _prevState$value = prevState.value,
|
|
217
|
-
prevData = _prevState$value.data,
|
|
218
|
-
prevContext = _objectWithoutProperties(_prevState$value, _excluded2);
|
|
219
|
-
|
|
220
229
|
var context = {
|
|
221
|
-
name: name,
|
|
222
|
-
query: query,
|
|
223
|
-
options: options,
|
|
230
|
+
name: requestDetails.name,
|
|
231
|
+
query: requestDetails.query,
|
|
232
|
+
options: requestDetails.options,
|
|
224
233
|
request: request,
|
|
225
234
|
revision: revision,
|
|
226
|
-
|
|
235
|
+
data: data,
|
|
236
|
+
meta: meta.commit(prevState.value.meta),
|
|
227
237
|
error: undefined,
|
|
228
238
|
isEmpty: false,
|
|
229
239
|
isIncomplete: !done,
|
|
230
240
|
isInitial: !!prevState.isInitial && !done
|
|
231
241
|
};
|
|
242
|
+
context.data = dataProvider.transition(context, prevState.value);
|
|
243
|
+
context.data = dataProvider.recycleItems(context, prevState.value);
|
|
232
244
|
return _objectSpread(_objectSpread({}, prevState), {}, {
|
|
233
245
|
isLoading: !done,
|
|
234
|
-
value:
|
|
235
|
-
data: dataProvider.recycleItems(dataProvider.transition(data, prevData, context, prevContext), prevData, context, prevContext)
|
|
236
|
-
})
|
|
246
|
+
value: context
|
|
237
247
|
});
|
|
238
248
|
});
|
|
239
249
|
};
|
|
240
250
|
|
|
241
|
-
dataProvider.continuousGet(name, query, options, meta, callback, abortSignal);
|
|
251
|
+
dataProvider.continuousGet(requestDetails.name, requestDetails.query, requestDetails.options, meta, callback, abortSignal);
|
|
242
252
|
return function () {
|
|
243
253
|
abortSignal.abort();
|
|
244
254
|
};
|
package/package.json
CHANGED
package/src/DataProvider.js
CHANGED
|
@@ -42,6 +42,12 @@ class DataProvider {
|
|
|
42
42
|
|
|
43
43
|
extend() {}
|
|
44
44
|
|
|
45
|
+
createInstance() {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
releaseInstance() {}
|
|
50
|
+
|
|
45
51
|
subscribe(resource, handler) {
|
|
46
52
|
if (resource == null) throw new Error('No resource name specified');
|
|
47
53
|
return this.notifier.subscribe(resource, handler);
|
|
@@ -127,8 +133,14 @@ class DataProvider {
|
|
|
127
133
|
});
|
|
128
134
|
}
|
|
129
135
|
|
|
130
|
-
compareRequests(
|
|
131
|
-
return deepEquals(
|
|
136
|
+
compareRequests(nextRequestDetails, prevRequestDetails) {
|
|
137
|
+
return deepEquals(nextRequestDetails, prevRequestDetails);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
shouldPersist(nextRequestDetails, prevRequestDetails, persistent) {
|
|
141
|
+
return (
|
|
142
|
+
persistent === 'very' || (persistent && prevRequestDetails.name === nextRequestDetails.name)
|
|
143
|
+
);
|
|
132
144
|
}
|
|
133
145
|
|
|
134
146
|
compareItemVersions() {
|
|
@@ -139,21 +151,21 @@ class DataProvider {
|
|
|
139
151
|
return objectHash(item);
|
|
140
152
|
}
|
|
141
153
|
|
|
142
|
-
transition(
|
|
143
|
-
return
|
|
154
|
+
transition(nextContext) {
|
|
155
|
+
return nextContext.data;
|
|
144
156
|
}
|
|
145
157
|
|
|
146
|
-
recycleItems(
|
|
158
|
+
recycleItems(nextContext, prevContext) {
|
|
147
159
|
const prevMapping = {};
|
|
148
|
-
if (
|
|
149
|
-
|
|
160
|
+
if (nextContext.data.length > 0) {
|
|
161
|
+
prevContext.data.forEach((item) => {
|
|
150
162
|
const id = this.getItemIdentifier(item);
|
|
151
163
|
if (id != null) prevMapping[id] = item;
|
|
152
164
|
});
|
|
153
165
|
}
|
|
154
166
|
let result;
|
|
155
|
-
if (
|
|
156
|
-
result =
|
|
167
|
+
if (prevContext.data.length > 0) {
|
|
168
|
+
result = nextContext.data.map((nextItem) => {
|
|
157
169
|
const id = this.getItemIdentifier(nextItem);
|
|
158
170
|
if (id != null && Object.prototype.hasOwnProperty.call(prevMapping, id)) {
|
|
159
171
|
const prevItem = prevMapping[id];
|
|
@@ -162,13 +174,13 @@ class DataProvider {
|
|
|
162
174
|
return nextItem;
|
|
163
175
|
});
|
|
164
176
|
} else {
|
|
165
|
-
result =
|
|
177
|
+
result = nextContext.data;
|
|
166
178
|
}
|
|
167
179
|
if (
|
|
168
|
-
|
|
169
|
-
result.reduce((sum, item, i) => sum && Object.is(
|
|
180
|
+
prevContext.data.length === result.length &&
|
|
181
|
+
result.reduce((sum, item, i) => sum && Object.is(prevContext.data[i], item), true)
|
|
170
182
|
) {
|
|
171
|
-
return
|
|
183
|
+
return prevContext.data;
|
|
172
184
|
}
|
|
173
185
|
return result;
|
|
174
186
|
}
|
package/src/Meta.js
CHANGED
package/src/uniqueIdentifier.js
CHANGED
|
@@ -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
|
*/
|
package/src/useResource.js
CHANGED
|
@@ -12,16 +12,16 @@ 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();
|
|
23
23
|
const currentDataProvider = dataProviderProp || configContext.dataProvider;
|
|
24
|
-
const dataProvider = React.
|
|
24
|
+
const [dataProvider] = React.useState(currentDataProvider);
|
|
25
25
|
if (dataProvider == null) {
|
|
26
26
|
throw new Error(
|
|
27
27
|
'Unmet requirement: The DataProvider for the useResource hook is missing - Check your ConfigContext provider and the dataProvider property',
|
|
@@ -33,82 +33,90 @@ function useResource({
|
|
|
33
33
|
);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
const
|
|
36
|
+
const [instance] = React.useState(() => dataProvider.createInstance());
|
|
37
|
+
React.useEffect(
|
|
38
|
+
() => () => {
|
|
39
|
+
dataProvider.releaseInstance(instance);
|
|
40
|
+
},
|
|
41
|
+
[],
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const nextRequestDetails = React.useMemo(
|
|
45
|
+
() => ({ name: nextName, query: nextQuery, empty: nextEmpty, options: nextOptions }),
|
|
46
|
+
[nextName, nextQuery, nextEmpty, nextOptions],
|
|
47
|
+
);
|
|
37
48
|
const [state, setState] = React.useState(() => {
|
|
38
49
|
const request = uniqueIdentifier();
|
|
39
50
|
const revision = uniqueIdentifier();
|
|
40
51
|
return {
|
|
41
|
-
|
|
52
|
+
requestDetails: nextRequestDetails,
|
|
42
53
|
request,
|
|
43
54
|
revision,
|
|
44
|
-
isLoading: !empty,
|
|
55
|
+
isLoading: !nextRequestDetails.empty,
|
|
45
56
|
value: {
|
|
46
|
-
name,
|
|
47
|
-
query,
|
|
48
|
-
options,
|
|
57
|
+
name: nextRequestDetails.name,
|
|
58
|
+
query: nextRequestDetails.query,
|
|
59
|
+
options: nextRequestDetails.options,
|
|
49
60
|
request,
|
|
50
61
|
revision,
|
|
51
62
|
data: [],
|
|
52
63
|
meta: {},
|
|
53
64
|
error: undefined,
|
|
54
|
-
isEmpty: !!empty,
|
|
55
|
-
isIncomplete: !empty,
|
|
56
|
-
isInitial: !empty,
|
|
65
|
+
isEmpty: !!nextRequestDetails.empty,
|
|
66
|
+
isIncomplete: !nextRequestDetails.empty,
|
|
67
|
+
isInitial: !nextRequestDetails.empty,
|
|
57
68
|
},
|
|
58
|
-
persistent,
|
|
69
|
+
persistent: nextPersistent,
|
|
59
70
|
};
|
|
60
71
|
});
|
|
61
|
-
const {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
persistent: prevPersistent,
|
|
68
|
-
} = state;
|
|
69
|
-
|
|
70
|
-
if (prevComparator !== comparator && !dataProvider.compareRequests(prevComparator, comparator)) {
|
|
72
|
+
const { requestDetails, request, revision, isLoading, value, persistent } = state;
|
|
73
|
+
|
|
74
|
+
if (
|
|
75
|
+
requestDetails !== nextRequestDetails &&
|
|
76
|
+
!dataProvider.compareRequests(nextRequestDetails, requestDetails)
|
|
77
|
+
) {
|
|
71
78
|
setState((prevState) => {
|
|
72
79
|
const nextRequest = uniqueIdentifier(prevState.request);
|
|
73
80
|
const nextRevision = uniqueIdentifier(prevState.revision);
|
|
74
|
-
let isPersistent;
|
|
75
|
-
if (
|
|
76
|
-
prevState.value.meta.persistent === 'very' ||
|
|
77
|
-
(persistent === 'very' && prevState.persistent === 'very')
|
|
78
|
-
) {
|
|
81
|
+
let isPersistent = false;
|
|
82
|
+
if (prevState.persistent === 'very' && nextPersistent === 'very') {
|
|
79
83
|
isPersistent = 'very';
|
|
80
|
-
} else if (prevState.
|
|
84
|
+
} else if (prevState.persistent && nextPersistent) {
|
|
81
85
|
isPersistent = true;
|
|
82
86
|
}
|
|
83
87
|
const shouldValuePersist =
|
|
84
|
-
!empty &&
|
|
85
|
-
|
|
86
|
-
|
|
88
|
+
!nextRequestDetails.empty &&
|
|
89
|
+
dataProvider.shouldPersist(
|
|
90
|
+
nextRequestDetails,
|
|
91
|
+
prevState.requestDetails,
|
|
92
|
+
isPersistent,
|
|
93
|
+
prevState.value,
|
|
94
|
+
);
|
|
87
95
|
return {
|
|
88
|
-
|
|
96
|
+
requestDetails: nextRequestDetails,
|
|
89
97
|
request: nextRequest,
|
|
90
98
|
revision: nextRevision,
|
|
91
|
-
isLoading: !empty,
|
|
99
|
+
isLoading: !nextRequestDetails.empty,
|
|
92
100
|
value: shouldValuePersist
|
|
93
101
|
? prevState.value
|
|
94
102
|
: {
|
|
95
|
-
name,
|
|
96
|
-
query,
|
|
97
|
-
options,
|
|
103
|
+
name: nextRequestDetails.name,
|
|
104
|
+
query: nextRequestDetails.query,
|
|
105
|
+
options: nextRequestDetails.options,
|
|
98
106
|
request: nextRequest,
|
|
99
107
|
revision: nextRevision,
|
|
100
108
|
data: [],
|
|
101
109
|
meta: {},
|
|
102
110
|
error: undefined,
|
|
103
|
-
isEmpty: !!empty,
|
|
104
|
-
isIncomplete: !empty,
|
|
105
|
-
isInitial: !empty,
|
|
111
|
+
isEmpty: !!nextRequestDetails.empty,
|
|
112
|
+
isIncomplete: !nextRequestDetails.empty,
|
|
113
|
+
isInitial: !nextRequestDetails.empty,
|
|
106
114
|
},
|
|
107
|
-
persistent,
|
|
115
|
+
persistent: nextPersistent,
|
|
108
116
|
};
|
|
109
117
|
});
|
|
110
|
-
} else if (
|
|
111
|
-
setState((prevState) => ({ ...prevState, persistent }));
|
|
118
|
+
} else if (persistent !== nextPersistent) {
|
|
119
|
+
setState((prevState) => ({ ...prevState, persistent: nextPersistent }));
|
|
112
120
|
}
|
|
113
121
|
|
|
114
122
|
const notify = React.useCallback(
|
|
@@ -126,18 +134,18 @@ function useResource({
|
|
|
126
134
|
|
|
127
135
|
// DataProvider events
|
|
128
136
|
React.useEffect(() => {
|
|
129
|
-
if (empty) return undefined;
|
|
137
|
+
if (requestDetails.empty) return undefined;
|
|
130
138
|
|
|
131
|
-
const unsubscribe = dataProvider.subscribe(name, notify);
|
|
139
|
+
const unsubscribe = dataProvider.subscribe(requestDetails.name, notify);
|
|
132
140
|
return unsubscribe;
|
|
133
|
-
}, [
|
|
141
|
+
}, [requestDetails.empty, dataProvider, requestDetails.name, notify]);
|
|
134
142
|
|
|
135
143
|
React.useEffect(() => {
|
|
136
|
-
if (empty) return undefined;
|
|
144
|
+
if (requestDetails.empty) return undefined;
|
|
137
145
|
|
|
138
146
|
const abortSignal = new AbortSignal();
|
|
139
147
|
|
|
140
|
-
const meta = new Meta({ ...value.meta });
|
|
148
|
+
const meta = new Meta({ ...value.meta }, instance);
|
|
141
149
|
|
|
142
150
|
const callback = (error, done, data) => {
|
|
143
151
|
setState((prevState) => {
|
|
@@ -155,37 +163,38 @@ function useResource({
|
|
|
155
163
|
};
|
|
156
164
|
}
|
|
157
165
|
|
|
158
|
-
const { data: prevData, ...prevContext } = prevState.value;
|
|
159
166
|
const context = {
|
|
160
|
-
name,
|
|
161
|
-
query,
|
|
162
|
-
options,
|
|
167
|
+
name: requestDetails.name,
|
|
168
|
+
query: requestDetails.query,
|
|
169
|
+
options: requestDetails.options,
|
|
163
170
|
request,
|
|
164
171
|
revision,
|
|
165
|
-
|
|
172
|
+
data,
|
|
173
|
+
meta: meta.commit(prevState.value.meta),
|
|
166
174
|
error: undefined,
|
|
167
175
|
isEmpty: false,
|
|
168
176
|
isIncomplete: !done,
|
|
169
177
|
isInitial: !!prevState.isInitial && !done,
|
|
170
178
|
};
|
|
179
|
+
context.data = dataProvider.transition(context, prevState.value);
|
|
180
|
+
context.data = dataProvider.recycleItems(context, prevState.value);
|
|
171
181
|
|
|
172
182
|
return {
|
|
173
183
|
...prevState,
|
|
174
184
|
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
|
-
},
|
|
185
|
+
value: context,
|
|
184
186
|
};
|
|
185
187
|
});
|
|
186
188
|
};
|
|
187
189
|
|
|
188
|
-
dataProvider.continuousGet(
|
|
190
|
+
dataProvider.continuousGet(
|
|
191
|
+
requestDetails.name,
|
|
192
|
+
requestDetails.query,
|
|
193
|
+
requestDetails.options,
|
|
194
|
+
meta,
|
|
195
|
+
callback,
|
|
196
|
+
abortSignal,
|
|
197
|
+
);
|
|
189
198
|
|
|
190
199
|
return () => {
|
|
191
200
|
abortSignal.abort();
|