@atlaskit/node-data-provider 7.2.2 → 7.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/dist/cjs/node-data-provider.js +77 -56
- package/dist/es2019/node-data-provider.js +66 -41
- package/dist/esm/node-data-provider.js +77 -56
- package/dist/types/node-data-provider.d.ts +25 -1
- package/dist/types-ts4.5/node-data-provider.d.ts +25 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @atlaskit/node-data-provider
|
|
2
2
|
|
|
3
|
+
## 7.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`fdba2e94783b7`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/fdba2e94783b7) -
|
|
8
|
+
[https://product-fabric.atlassian.net/browse/ED-29638](ED-29638) - fix editor NodeDataProvider
|
|
9
|
+
network requests deduplication
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
|
|
15
|
+
## 7.3.0
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- [`5319dac3f8740`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/5319dac3f8740) -
|
|
20
|
+
Do not re-fetch emoji on a client after successful ssr
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- Updated dependencies
|
|
25
|
+
|
|
3
26
|
## 7.2.2
|
|
4
27
|
|
|
5
28
|
### Patch Changes
|
|
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
});
|
|
7
7
|
exports.NodeDataProvider = void 0;
|
|
8
8
|
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
9
|
-
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
|
|
10
9
|
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
11
10
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
12
11
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
@@ -31,7 +30,7 @@ var _coreUtils = require("@atlaskit/editor-common/core-utils");
|
|
|
31
30
|
* @example
|
|
32
31
|
* {
|
|
33
32
|
* 'node-id-1': { source: 'ssr', data: { value: 'some data' } },
|
|
34
|
-
* 'node-id-2': { source: 'network', data:
|
|
33
|
+
* 'node-id-2': { source: 'network', data: { value: 'other data' } }
|
|
35
34
|
* }
|
|
36
35
|
*/
|
|
37
36
|
/**
|
|
@@ -50,6 +49,7 @@ var NodeDataProvider = exports.NodeDataProvider = /*#__PURE__*/function () {
|
|
|
50
49
|
(0, _classCallCheck2.default)(this, NodeDataProvider);
|
|
51
50
|
this.cacheVersion = 0;
|
|
52
51
|
this.cache = {};
|
|
52
|
+
this.networkRequestsInFlight = {};
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
/**
|
|
@@ -136,102 +136,114 @@ var NodeDataProvider = exports.NodeDataProvider = /*#__PURE__*/function () {
|
|
|
136
136
|
key: "getDataAsync",
|
|
137
137
|
value: function () {
|
|
138
138
|
var _getDataAsync = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(node, callback) {
|
|
139
|
-
var jsonNode,
|
|
139
|
+
var jsonNode, dataKey, dataFromCache, cacheVersionBeforeRequest, networkRequestInFlightKey, networkRequestInFlight, data, dataPromise, _data;
|
|
140
140
|
return _regenerator.default.wrap(function _callee$(_context) {
|
|
141
141
|
while (1) switch (_context.prev = _context.next) {
|
|
142
142
|
case 0:
|
|
143
|
-
_context.prev = 0;
|
|
144
143
|
jsonNode = 'toJSON' in node ? node.toJSON() : node;
|
|
145
144
|
if (this.isNodeSupported(jsonNode)) {
|
|
146
|
-
_context.next =
|
|
145
|
+
_context.next = 4;
|
|
147
146
|
break;
|
|
148
147
|
}
|
|
149
148
|
// eslint-disable-next-line no-console
|
|
150
149
|
console.error("The ".concat(this.constructor.name, " doesn't support Node ").concat(jsonNode.type, "."));
|
|
151
150
|
return _context.abrupt("return");
|
|
152
|
-
case
|
|
153
|
-
|
|
154
|
-
dataFromCache = this.cache[
|
|
151
|
+
case 4:
|
|
152
|
+
dataKey = this.nodeDataKey(jsonNode);
|
|
153
|
+
dataFromCache = this.cache[dataKey];
|
|
155
154
|
if (!(dataFromCache !== undefined)) {
|
|
156
|
-
_context.next =
|
|
155
|
+
_context.next = 10;
|
|
157
156
|
break;
|
|
158
157
|
}
|
|
159
|
-
|
|
160
|
-
_context.next = 17;
|
|
161
|
-
break;
|
|
162
|
-
}
|
|
163
|
-
_context.t0 = callback;
|
|
164
|
-
_context.next = 12;
|
|
165
|
-
return dataFromCache.data;
|
|
166
|
-
case 12:
|
|
167
|
-
_context.t1 = _context.sent;
|
|
168
|
-
_context.t2 = {
|
|
169
|
-
data: _context.t1
|
|
170
|
-
};
|
|
171
|
-
(0, _context.t0)(_context.t2);
|
|
172
|
-
_context.next = 18;
|
|
173
|
-
break;
|
|
174
|
-
case 17:
|
|
158
|
+
// If we have the data in the SSR data, we can use it directly
|
|
175
159
|
callback({
|
|
176
160
|
data: dataFromCache.data
|
|
177
161
|
});
|
|
178
|
-
case 18:
|
|
179
162
|
if (!(0, _coreUtils.isSSR)()) {
|
|
180
|
-
_context.next =
|
|
163
|
+
_context.next = 10;
|
|
181
164
|
break;
|
|
182
165
|
}
|
|
183
166
|
return _context.abrupt("return");
|
|
184
|
-
case
|
|
167
|
+
case 10:
|
|
185
168
|
if (!((dataFromCache === null || dataFromCache === void 0 ? void 0 : dataFromCache.source) !== 'network')) {
|
|
186
|
-
_context.next =
|
|
169
|
+
_context.next = 42;
|
|
187
170
|
break;
|
|
188
171
|
}
|
|
189
172
|
// Store the current cache version before making the request,
|
|
190
173
|
// so we can check if the cache has changed while we are waiting for the network response.
|
|
191
|
-
cacheVersionBeforeRequest = this.cacheVersion;
|
|
174
|
+
cacheVersionBeforeRequest = this.cacheVersion; // Create a unique key for the in-flight network request
|
|
175
|
+
// based on the cache version and the data key.
|
|
176
|
+
networkRequestInFlightKey = "".concat(cacheVersionBeforeRequest, "-").concat(dataKey); // Check if there is already a network request in flight for this data
|
|
177
|
+
// to avoid duplicate requests.
|
|
178
|
+
networkRequestInFlight = this.networkRequestsInFlight[networkRequestInFlightKey];
|
|
179
|
+
if (!networkRequestInFlight) {
|
|
180
|
+
_context.next = 26;
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
_context.prev = 15;
|
|
184
|
+
_context.next = 18;
|
|
185
|
+
return networkRequestInFlight;
|
|
186
|
+
case 18:
|
|
187
|
+
data = _context.sent;
|
|
188
|
+
callback({
|
|
189
|
+
data: data
|
|
190
|
+
});
|
|
191
|
+
_context.next = 25;
|
|
192
|
+
break;
|
|
193
|
+
case 22:
|
|
194
|
+
_context.prev = 22;
|
|
195
|
+
_context.t0 = _context["catch"](15);
|
|
196
|
+
callback({
|
|
197
|
+
error: _context.t0 instanceof Error ? _context.t0 : new Error(String(_context.t0))
|
|
198
|
+
});
|
|
199
|
+
case 25:
|
|
200
|
+
return _context.abrupt("return");
|
|
201
|
+
case 26:
|
|
202
|
+
_context.prev = 26;
|
|
192
203
|
dataPromise = this.fetchNodesData([jsonNode]).then(function (_ref3) {
|
|
193
204
|
var _ref4 = (0, _slicedToArray2.default)(_ref3, 1),
|
|
194
205
|
value = _ref4[0];
|
|
195
206
|
return value;
|
|
196
|
-
}); // Store the promise in the
|
|
197
|
-
this.
|
|
198
|
-
|
|
199
|
-
data: dataPromise
|
|
200
|
-
};
|
|
201
|
-
_context.next = 26;
|
|
207
|
+
}); // Store the promise in the in-flight requests map
|
|
208
|
+
this.networkRequestsInFlight[networkRequestInFlightKey] = dataPromise;
|
|
209
|
+
_context.next = 31;
|
|
202
210
|
return dataPromise;
|
|
203
|
-
case
|
|
204
|
-
|
|
211
|
+
case 31:
|
|
212
|
+
_data = _context.sent;
|
|
205
213
|
// We need to call the callback with the data with result even if the cache version has changed,
|
|
206
214
|
// so all promises that are waiting for the data can resolve.
|
|
207
215
|
callback({
|
|
208
|
-
data:
|
|
216
|
+
data: _data
|
|
209
217
|
});
|
|
210
218
|
|
|
211
219
|
// If the cache version has changed, we don't want to use the data from the network
|
|
212
220
|
// because it could be stale data.
|
|
213
221
|
if (cacheVersionBeforeRequest === this.cacheVersion) {
|
|
214
222
|
// Replace promise with the resolved data in the cache
|
|
215
|
-
this.cache[
|
|
223
|
+
this.cache[dataKey] = {
|
|
216
224
|
source: 'network',
|
|
217
|
-
data:
|
|
225
|
+
data: _data
|
|
218
226
|
};
|
|
219
227
|
}
|
|
220
|
-
|
|
221
|
-
_context.next = 34;
|
|
228
|
+
_context.next = 39;
|
|
222
229
|
break;
|
|
223
|
-
case
|
|
224
|
-
_context.prev =
|
|
225
|
-
_context.
|
|
230
|
+
case 36:
|
|
231
|
+
_context.prev = 36;
|
|
232
|
+
_context.t1 = _context["catch"](26);
|
|
226
233
|
// If an error occurs, we call the callback with the error
|
|
227
234
|
callback({
|
|
228
|
-
error: _context.
|
|
235
|
+
error: _context.t1 instanceof Error ? _context.t1 : new Error(String(_context.t1))
|
|
229
236
|
});
|
|
230
|
-
case
|
|
237
|
+
case 39:
|
|
238
|
+
_context.prev = 39;
|
|
239
|
+
// Ensure we clean up the in-flight request entry
|
|
240
|
+
delete this.networkRequestsInFlight[networkRequestInFlightKey];
|
|
241
|
+
return _context.finish(39);
|
|
242
|
+
case 42:
|
|
231
243
|
case "end":
|
|
232
244
|
return _context.stop();
|
|
233
245
|
}
|
|
234
|
-
}, _callee, this, [[
|
|
246
|
+
}, _callee, this, [[15, 22], [26, 36, 39, 42]]);
|
|
235
247
|
}));
|
|
236
248
|
function getDataAsync(_x, _x2) {
|
|
237
249
|
return _getDataAsync.apply(this, arguments);
|
|
@@ -287,18 +299,27 @@ var NodeDataProvider = exports.NodeDataProvider = /*#__PURE__*/function () {
|
|
|
287
299
|
}, {
|
|
288
300
|
key: "getCacheStatusForNode",
|
|
289
301
|
value: function getCacheStatusForNode(node) {
|
|
302
|
+
var dataFromCache = this.getNodeDataFromCache(node);
|
|
303
|
+
return dataFromCache ? dataFromCache.source : false;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Retrieves the cached data for a given node, if available.
|
|
308
|
+
*
|
|
309
|
+
* @param node The node (or its ProseMirror representation) for which to retrieve cached data.
|
|
310
|
+
* @returns The cached data object containing `data` and `source`, or `undefined` if no cache entry exists.
|
|
311
|
+
*/
|
|
312
|
+
}, {
|
|
313
|
+
key: "getNodeDataFromCache",
|
|
314
|
+
value: function getNodeDataFromCache(node) {
|
|
290
315
|
var jsonNode = 'toJSON' in node ? node.toJSON() : node;
|
|
291
316
|
if (!this.isNodeSupported(jsonNode)) {
|
|
292
317
|
// eslint-disable-next-line no-console
|
|
293
318
|
console.error("The ".concat(this.constructor.name, " doesn't support Node ").concat(jsonNode.type, "."));
|
|
294
|
-
return
|
|
319
|
+
return undefined;
|
|
295
320
|
}
|
|
296
321
|
var dataKey = this.nodeDataKey(jsonNode);
|
|
297
|
-
|
|
298
|
-
return dataFromCache ? dataFromCache.source : false;
|
|
322
|
+
return this.cache[dataKey];
|
|
299
323
|
}
|
|
300
324
|
}]);
|
|
301
|
-
}();
|
|
302
|
-
function isPromise(value) {
|
|
303
|
-
return (0, _typeof2.default)(value) === 'object' && value !== null && 'then' in value && typeof value.then === 'function';
|
|
304
|
-
}
|
|
325
|
+
}();
|
|
@@ -20,7 +20,7 @@ import { isSSR } from '@atlaskit/editor-common/core-utils';
|
|
|
20
20
|
* @example
|
|
21
21
|
* {
|
|
22
22
|
* 'node-id-1': { source: 'ssr', data: { value: 'some data' } },
|
|
23
|
-
* 'node-id-2': { source: 'network', data:
|
|
23
|
+
* 'node-id-2': { source: 'network', data: { value: 'other data' } }
|
|
24
24
|
* }
|
|
25
25
|
*/
|
|
26
26
|
|
|
@@ -66,6 +66,7 @@ export class NodeDataProvider {
|
|
|
66
66
|
constructor() {
|
|
67
67
|
this.cacheVersion = 0;
|
|
68
68
|
this.cache = {};
|
|
69
|
+
this.networkRequestsInFlight = {};
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
/**
|
|
@@ -137,45 +138,59 @@ export class NodeDataProvider {
|
|
|
137
138
|
void this.getDataAsync(node, callback);
|
|
138
139
|
}
|
|
139
140
|
async getDataAsync(node, callback) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
141
|
+
const jsonNode = 'toJSON' in node ? node.toJSON() : node;
|
|
142
|
+
if (!this.isNodeSupported(jsonNode)) {
|
|
143
|
+
// eslint-disable-next-line no-console
|
|
144
|
+
console.error(`The ${this.constructor.name} doesn't support Node ${jsonNode.type}.`);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const dataKey = this.nodeDataKey(jsonNode);
|
|
148
|
+
const dataFromCache = this.cache[dataKey];
|
|
149
|
+
if (dataFromCache !== undefined) {
|
|
150
|
+
// If we have the data in the SSR data, we can use it directly
|
|
151
|
+
callback({
|
|
152
|
+
data: dataFromCache.data
|
|
153
|
+
});
|
|
154
|
+
if (isSSR()) {
|
|
155
|
+
// If we are in SSR, we don't want to fetch the data again, as it is already available in the SSR data
|
|
145
156
|
return;
|
|
146
157
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// If no data is available in the cache, or the data is from the network,
|
|
161
|
+
// we need to fetch it from the network.
|
|
162
|
+
if ((dataFromCache === null || dataFromCache === void 0 ? void 0 : dataFromCache.source) !== 'network') {
|
|
163
|
+
// Store the current cache version before making the request,
|
|
164
|
+
// so we can check if the cache has changed while we are waiting for the network response.
|
|
165
|
+
const cacheVersionBeforeRequest = this.cacheVersion;
|
|
166
|
+
|
|
167
|
+
// Create a unique key for the in-flight network request
|
|
168
|
+
// based on the cache version and the data key.
|
|
169
|
+
const networkRequestInFlightKey = `${cacheVersionBeforeRequest}-${dataKey}`;
|
|
170
|
+
|
|
171
|
+
// Check if there is already a network request in flight for this data
|
|
172
|
+
// to avoid duplicate requests.
|
|
173
|
+
const networkRequestInFlight = this.networkRequestsInFlight[networkRequestInFlightKey];
|
|
174
|
+
if (networkRequestInFlight) {
|
|
175
|
+
try {
|
|
176
|
+
const data = await networkRequestInFlight;
|
|
152
177
|
callback({
|
|
153
|
-
data
|
|
178
|
+
data
|
|
154
179
|
});
|
|
155
|
-
}
|
|
180
|
+
} catch (error) {
|
|
156
181
|
callback({
|
|
157
|
-
|
|
182
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
158
183
|
});
|
|
159
184
|
}
|
|
160
|
-
|
|
161
|
-
// If we are in SSR, we don't want to fetch the data again, as it is already available in the SSR data
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
185
|
+
return;
|
|
164
186
|
}
|
|
165
|
-
|
|
166
|
-
// If no data is available in the cache or the data is from the network,
|
|
167
|
-
// we need to fetch it from the network.
|
|
168
|
-
if ((dataFromCache === null || dataFromCache === void 0 ? void 0 : dataFromCache.source) !== 'network') {
|
|
169
|
-
// Store the current cache version before making the request,
|
|
170
|
-
// so we can check if the cache has changed while we are waiting for the network response.
|
|
171
|
-
const cacheVersionBeforeRequest = this.cacheVersion;
|
|
187
|
+
try {
|
|
172
188
|
const dataPromise = this.fetchNodesData([jsonNode]).then(([value]) => value);
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
data: dataPromise
|
|
177
|
-
};
|
|
189
|
+
|
|
190
|
+
// Store the promise in the in-flight requests map
|
|
191
|
+
this.networkRequestsInFlight[networkRequestInFlightKey] = dataPromise;
|
|
178
192
|
const data = await dataPromise;
|
|
193
|
+
|
|
179
194
|
// We need to call the callback with the data with result even if the cache version has changed,
|
|
180
195
|
// so all promises that are waiting for the data can resolve.
|
|
181
196
|
callback({
|
|
@@ -191,12 +206,15 @@ export class NodeDataProvider {
|
|
|
191
206
|
data
|
|
192
207
|
};
|
|
193
208
|
}
|
|
209
|
+
} catch (error) {
|
|
210
|
+
// If an error occurs, we call the callback with the error
|
|
211
|
+
callback({
|
|
212
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
213
|
+
});
|
|
214
|
+
} finally {
|
|
215
|
+
// Ensure we clean up the in-flight request entry
|
|
216
|
+
delete this.networkRequestsInFlight[networkRequestInFlightKey];
|
|
194
217
|
}
|
|
195
|
-
} catch (error) {
|
|
196
|
-
// If an error occurs, we call the callback with the error
|
|
197
|
-
callback({
|
|
198
|
-
error: error instanceof Error ? error : new Error(String(error))
|
|
199
|
-
});
|
|
200
218
|
}
|
|
201
219
|
}
|
|
202
220
|
|
|
@@ -244,17 +262,24 @@ export class NodeDataProvider {
|
|
|
244
262
|
* @returns The cache status: `false`, `'ssr'`, or `'network'`.
|
|
245
263
|
*/
|
|
246
264
|
getCacheStatusForNode(node) {
|
|
265
|
+
const dataFromCache = this.getNodeDataFromCache(node);
|
|
266
|
+
return dataFromCache ? dataFromCache.source : false;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Retrieves the cached data for a given node, if available.
|
|
271
|
+
*
|
|
272
|
+
* @param node The node (or its ProseMirror representation) for which to retrieve cached data.
|
|
273
|
+
* @returns The cached data object containing `data` and `source`, or `undefined` if no cache entry exists.
|
|
274
|
+
*/
|
|
275
|
+
getNodeDataFromCache(node) {
|
|
247
276
|
const jsonNode = 'toJSON' in node ? node.toJSON() : node;
|
|
248
277
|
if (!this.isNodeSupported(jsonNode)) {
|
|
249
278
|
// eslint-disable-next-line no-console
|
|
250
279
|
console.error(`The ${this.constructor.name} doesn't support Node ${jsonNode.type}.`);
|
|
251
|
-
return
|
|
280
|
+
return undefined;
|
|
252
281
|
}
|
|
253
282
|
const dataKey = this.nodeDataKey(jsonNode);
|
|
254
|
-
|
|
255
|
-
return dataFromCache ? dataFromCache.source : false;
|
|
283
|
+
return this.cache[dataKey];
|
|
256
284
|
}
|
|
257
|
-
}
|
|
258
|
-
function isPromise(value) {
|
|
259
|
-
return typeof value === 'object' && value !== null && 'then' in value && typeof value.then === 'function';
|
|
260
285
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import _typeof from "@babel/runtime/helpers/typeof";
|
|
2
1
|
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
3
2
|
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
4
3
|
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
@@ -26,7 +25,7 @@ import { isSSR } from '@atlaskit/editor-common/core-utils';
|
|
|
26
25
|
* @example
|
|
27
26
|
* {
|
|
28
27
|
* 'node-id-1': { source: 'ssr', data: { value: 'some data' } },
|
|
29
|
-
* 'node-id-2': { source: 'network', data:
|
|
28
|
+
* 'node-id-2': { source: 'network', data: { value: 'other data' } }
|
|
30
29
|
* }
|
|
31
30
|
*/
|
|
32
31
|
|
|
@@ -47,6 +46,7 @@ export var NodeDataProvider = /*#__PURE__*/function () {
|
|
|
47
46
|
_classCallCheck(this, NodeDataProvider);
|
|
48
47
|
this.cacheVersion = 0;
|
|
49
48
|
this.cache = {};
|
|
49
|
+
this.networkRequestsInFlight = {};
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
/**
|
|
@@ -133,102 +133,114 @@ export var NodeDataProvider = /*#__PURE__*/function () {
|
|
|
133
133
|
key: "getDataAsync",
|
|
134
134
|
value: function () {
|
|
135
135
|
var _getDataAsync = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(node, callback) {
|
|
136
|
-
var jsonNode,
|
|
136
|
+
var jsonNode, dataKey, dataFromCache, cacheVersionBeforeRequest, networkRequestInFlightKey, networkRequestInFlight, data, dataPromise, _data;
|
|
137
137
|
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
138
138
|
while (1) switch (_context.prev = _context.next) {
|
|
139
139
|
case 0:
|
|
140
|
-
_context.prev = 0;
|
|
141
140
|
jsonNode = 'toJSON' in node ? node.toJSON() : node;
|
|
142
141
|
if (this.isNodeSupported(jsonNode)) {
|
|
143
|
-
_context.next =
|
|
142
|
+
_context.next = 4;
|
|
144
143
|
break;
|
|
145
144
|
}
|
|
146
145
|
// eslint-disable-next-line no-console
|
|
147
146
|
console.error("The ".concat(this.constructor.name, " doesn't support Node ").concat(jsonNode.type, "."));
|
|
148
147
|
return _context.abrupt("return");
|
|
149
|
-
case
|
|
150
|
-
|
|
151
|
-
dataFromCache = this.cache[
|
|
148
|
+
case 4:
|
|
149
|
+
dataKey = this.nodeDataKey(jsonNode);
|
|
150
|
+
dataFromCache = this.cache[dataKey];
|
|
152
151
|
if (!(dataFromCache !== undefined)) {
|
|
153
|
-
_context.next =
|
|
152
|
+
_context.next = 10;
|
|
154
153
|
break;
|
|
155
154
|
}
|
|
156
|
-
|
|
157
|
-
_context.next = 17;
|
|
158
|
-
break;
|
|
159
|
-
}
|
|
160
|
-
_context.t0 = callback;
|
|
161
|
-
_context.next = 12;
|
|
162
|
-
return dataFromCache.data;
|
|
163
|
-
case 12:
|
|
164
|
-
_context.t1 = _context.sent;
|
|
165
|
-
_context.t2 = {
|
|
166
|
-
data: _context.t1
|
|
167
|
-
};
|
|
168
|
-
(0, _context.t0)(_context.t2);
|
|
169
|
-
_context.next = 18;
|
|
170
|
-
break;
|
|
171
|
-
case 17:
|
|
155
|
+
// If we have the data in the SSR data, we can use it directly
|
|
172
156
|
callback({
|
|
173
157
|
data: dataFromCache.data
|
|
174
158
|
});
|
|
175
|
-
case 18:
|
|
176
159
|
if (!isSSR()) {
|
|
177
|
-
_context.next =
|
|
160
|
+
_context.next = 10;
|
|
178
161
|
break;
|
|
179
162
|
}
|
|
180
163
|
return _context.abrupt("return");
|
|
181
|
-
case
|
|
164
|
+
case 10:
|
|
182
165
|
if (!((dataFromCache === null || dataFromCache === void 0 ? void 0 : dataFromCache.source) !== 'network')) {
|
|
183
|
-
_context.next =
|
|
166
|
+
_context.next = 42;
|
|
184
167
|
break;
|
|
185
168
|
}
|
|
186
169
|
// Store the current cache version before making the request,
|
|
187
170
|
// so we can check if the cache has changed while we are waiting for the network response.
|
|
188
|
-
cacheVersionBeforeRequest = this.cacheVersion;
|
|
171
|
+
cacheVersionBeforeRequest = this.cacheVersion; // Create a unique key for the in-flight network request
|
|
172
|
+
// based on the cache version and the data key.
|
|
173
|
+
networkRequestInFlightKey = "".concat(cacheVersionBeforeRequest, "-").concat(dataKey); // Check if there is already a network request in flight for this data
|
|
174
|
+
// to avoid duplicate requests.
|
|
175
|
+
networkRequestInFlight = this.networkRequestsInFlight[networkRequestInFlightKey];
|
|
176
|
+
if (!networkRequestInFlight) {
|
|
177
|
+
_context.next = 26;
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
_context.prev = 15;
|
|
181
|
+
_context.next = 18;
|
|
182
|
+
return networkRequestInFlight;
|
|
183
|
+
case 18:
|
|
184
|
+
data = _context.sent;
|
|
185
|
+
callback({
|
|
186
|
+
data: data
|
|
187
|
+
});
|
|
188
|
+
_context.next = 25;
|
|
189
|
+
break;
|
|
190
|
+
case 22:
|
|
191
|
+
_context.prev = 22;
|
|
192
|
+
_context.t0 = _context["catch"](15);
|
|
193
|
+
callback({
|
|
194
|
+
error: _context.t0 instanceof Error ? _context.t0 : new Error(String(_context.t0))
|
|
195
|
+
});
|
|
196
|
+
case 25:
|
|
197
|
+
return _context.abrupt("return");
|
|
198
|
+
case 26:
|
|
199
|
+
_context.prev = 26;
|
|
189
200
|
dataPromise = this.fetchNodesData([jsonNode]).then(function (_ref3) {
|
|
190
201
|
var _ref4 = _slicedToArray(_ref3, 1),
|
|
191
202
|
value = _ref4[0];
|
|
192
203
|
return value;
|
|
193
|
-
}); // Store the promise in the
|
|
194
|
-
this.
|
|
195
|
-
|
|
196
|
-
data: dataPromise
|
|
197
|
-
};
|
|
198
|
-
_context.next = 26;
|
|
204
|
+
}); // Store the promise in the in-flight requests map
|
|
205
|
+
this.networkRequestsInFlight[networkRequestInFlightKey] = dataPromise;
|
|
206
|
+
_context.next = 31;
|
|
199
207
|
return dataPromise;
|
|
200
|
-
case
|
|
201
|
-
|
|
208
|
+
case 31:
|
|
209
|
+
_data = _context.sent;
|
|
202
210
|
// We need to call the callback with the data with result even if the cache version has changed,
|
|
203
211
|
// so all promises that are waiting for the data can resolve.
|
|
204
212
|
callback({
|
|
205
|
-
data:
|
|
213
|
+
data: _data
|
|
206
214
|
});
|
|
207
215
|
|
|
208
216
|
// If the cache version has changed, we don't want to use the data from the network
|
|
209
217
|
// because it could be stale data.
|
|
210
218
|
if (cacheVersionBeforeRequest === this.cacheVersion) {
|
|
211
219
|
// Replace promise with the resolved data in the cache
|
|
212
|
-
this.cache[
|
|
220
|
+
this.cache[dataKey] = {
|
|
213
221
|
source: 'network',
|
|
214
|
-
data:
|
|
222
|
+
data: _data
|
|
215
223
|
};
|
|
216
224
|
}
|
|
217
|
-
|
|
218
|
-
_context.next = 34;
|
|
225
|
+
_context.next = 39;
|
|
219
226
|
break;
|
|
220
|
-
case
|
|
221
|
-
_context.prev =
|
|
222
|
-
_context.
|
|
227
|
+
case 36:
|
|
228
|
+
_context.prev = 36;
|
|
229
|
+
_context.t1 = _context["catch"](26);
|
|
223
230
|
// If an error occurs, we call the callback with the error
|
|
224
231
|
callback({
|
|
225
|
-
error: _context.
|
|
232
|
+
error: _context.t1 instanceof Error ? _context.t1 : new Error(String(_context.t1))
|
|
226
233
|
});
|
|
227
|
-
case
|
|
234
|
+
case 39:
|
|
235
|
+
_context.prev = 39;
|
|
236
|
+
// Ensure we clean up the in-flight request entry
|
|
237
|
+
delete this.networkRequestsInFlight[networkRequestInFlightKey];
|
|
238
|
+
return _context.finish(39);
|
|
239
|
+
case 42:
|
|
228
240
|
case "end":
|
|
229
241
|
return _context.stop();
|
|
230
242
|
}
|
|
231
|
-
}, _callee, this, [[
|
|
243
|
+
}, _callee, this, [[15, 22], [26, 36, 39, 42]]);
|
|
232
244
|
}));
|
|
233
245
|
function getDataAsync(_x, _x2) {
|
|
234
246
|
return _getDataAsync.apply(this, arguments);
|
|
@@ -284,18 +296,27 @@ export var NodeDataProvider = /*#__PURE__*/function () {
|
|
|
284
296
|
}, {
|
|
285
297
|
key: "getCacheStatusForNode",
|
|
286
298
|
value: function getCacheStatusForNode(node) {
|
|
299
|
+
var dataFromCache = this.getNodeDataFromCache(node);
|
|
300
|
+
return dataFromCache ? dataFromCache.source : false;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Retrieves the cached data for a given node, if available.
|
|
305
|
+
*
|
|
306
|
+
* @param node The node (or its ProseMirror representation) for which to retrieve cached data.
|
|
307
|
+
* @returns The cached data object containing `data` and `source`, or `undefined` if no cache entry exists.
|
|
308
|
+
*/
|
|
309
|
+
}, {
|
|
310
|
+
key: "getNodeDataFromCache",
|
|
311
|
+
value: function getNodeDataFromCache(node) {
|
|
287
312
|
var jsonNode = 'toJSON' in node ? node.toJSON() : node;
|
|
288
313
|
if (!this.isNodeSupported(jsonNode)) {
|
|
289
314
|
// eslint-disable-next-line no-console
|
|
290
315
|
console.error("The ".concat(this.constructor.name, " doesn't support Node ").concat(jsonNode.type, "."));
|
|
291
|
-
return
|
|
316
|
+
return undefined;
|
|
292
317
|
}
|
|
293
318
|
var dataKey = this.nodeDataKey(jsonNode);
|
|
294
|
-
|
|
295
|
-
return dataFromCache ? dataFromCache.source : false;
|
|
319
|
+
return this.cache[dataKey];
|
|
296
320
|
}
|
|
297
321
|
}]);
|
|
298
|
-
}();
|
|
299
|
-
function isPromise(value) {
|
|
300
|
-
return _typeof(value) === 'object' && value !== null && 'then' in value && typeof value.then === 'function';
|
|
301
|
-
}
|
|
322
|
+
}();
|
|
@@ -13,6 +13,22 @@ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
|
13
13
|
type SSRData<Data> = {
|
|
14
14
|
[dataKey: string]: Data;
|
|
15
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* Represents the cached data for a Node Data Provider.
|
|
18
|
+
* Each key is a unique node data key, and the value is an object containing:
|
|
19
|
+
* - `source`: Indicates whether the data was fetched from SSR or the network.
|
|
20
|
+
* - `data`: The actual data, which can be either a resolved value or a Promise.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* {
|
|
24
|
+
* 'node-id-1': { source: 'ssr', data: { value: 'some data' } },
|
|
25
|
+
* 'node-id-2': { source: 'network', data: { value: 'other data' } }
|
|
26
|
+
* }
|
|
27
|
+
*/
|
|
28
|
+
type CacheData<Data> = Record<string, {
|
|
29
|
+
data: Data;
|
|
30
|
+
source: 'ssr' | 'network';
|
|
31
|
+
}>;
|
|
16
32
|
/**
|
|
17
33
|
* Represents the payload passed to the callback function when data is fetched.
|
|
18
34
|
* It can either contain an error or the fetched data.
|
|
@@ -36,6 +52,7 @@ type CallbackPayload<Data> = {
|
|
|
36
52
|
export declare abstract class NodeDataProvider<Node extends JSONNode, Data> {
|
|
37
53
|
private cacheVersion;
|
|
38
54
|
private cache;
|
|
55
|
+
private readonly networkRequestsInFlight;
|
|
39
56
|
/**
|
|
40
57
|
* A unique name for the provider. Used for identification in SSR.
|
|
41
58
|
*/
|
|
@@ -116,7 +133,7 @@ export declare abstract class NodeDataProvider<Node extends JSONNode, Data> {
|
|
|
116
133
|
* @param callback The callback function to call with the fetched data or an error.
|
|
117
134
|
*/
|
|
118
135
|
getData(node: Node | PMNode, callback: (payload: CallbackPayload<Data>) => void): void;
|
|
119
|
-
|
|
136
|
+
protected getDataAsync(node: Node | PMNode, callback: (payload: CallbackPayload<Data>) => void): Promise<void>;
|
|
120
137
|
/**
|
|
121
138
|
* Fetches data for a given node and returns it as a Promise.
|
|
122
139
|
* This is a convenience wrapper around the `data` method for use with async/await.
|
|
@@ -146,5 +163,12 @@ export declare abstract class NodeDataProvider<Node extends JSONNode, Data> {
|
|
|
146
163
|
* @returns The cache status: `false`, `'ssr'`, or `'network'`.
|
|
147
164
|
*/
|
|
148
165
|
getCacheStatusForNode(node: Node | PMNode): false | 'ssr' | 'network';
|
|
166
|
+
/**
|
|
167
|
+
* Retrieves the cached data for a given node, if available.
|
|
168
|
+
*
|
|
169
|
+
* @param node The node (or its ProseMirror representation) for which to retrieve cached data.
|
|
170
|
+
* @returns The cached data object containing `data` and `source`, or `undefined` if no cache entry exists.
|
|
171
|
+
*/
|
|
172
|
+
getNodeDataFromCache(node: JSONNode | PMNode): CacheData<Data>[string] | undefined;
|
|
149
173
|
}
|
|
150
174
|
export {};
|
|
@@ -13,6 +13,22 @@ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
|
13
13
|
type SSRData<Data> = {
|
|
14
14
|
[dataKey: string]: Data;
|
|
15
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* Represents the cached data for a Node Data Provider.
|
|
18
|
+
* Each key is a unique node data key, and the value is an object containing:
|
|
19
|
+
* - `source`: Indicates whether the data was fetched from SSR or the network.
|
|
20
|
+
* - `data`: The actual data, which can be either a resolved value or a Promise.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* {
|
|
24
|
+
* 'node-id-1': { source: 'ssr', data: { value: 'some data' } },
|
|
25
|
+
* 'node-id-2': { source: 'network', data: { value: 'other data' } }
|
|
26
|
+
* }
|
|
27
|
+
*/
|
|
28
|
+
type CacheData<Data> = Record<string, {
|
|
29
|
+
data: Data;
|
|
30
|
+
source: 'ssr' | 'network';
|
|
31
|
+
}>;
|
|
16
32
|
/**
|
|
17
33
|
* Represents the payload passed to the callback function when data is fetched.
|
|
18
34
|
* It can either contain an error or the fetched data.
|
|
@@ -36,6 +52,7 @@ type CallbackPayload<Data> = {
|
|
|
36
52
|
export declare abstract class NodeDataProvider<Node extends JSONNode, Data> {
|
|
37
53
|
private cacheVersion;
|
|
38
54
|
private cache;
|
|
55
|
+
private readonly networkRequestsInFlight;
|
|
39
56
|
/**
|
|
40
57
|
* A unique name for the provider. Used for identification in SSR.
|
|
41
58
|
*/
|
|
@@ -116,7 +133,7 @@ export declare abstract class NodeDataProvider<Node extends JSONNode, Data> {
|
|
|
116
133
|
* @param callback The callback function to call with the fetched data or an error.
|
|
117
134
|
*/
|
|
118
135
|
getData(node: Node | PMNode, callback: (payload: CallbackPayload<Data>) => void): void;
|
|
119
|
-
|
|
136
|
+
protected getDataAsync(node: Node | PMNode, callback: (payload: CallbackPayload<Data>) => void): Promise<void>;
|
|
120
137
|
/**
|
|
121
138
|
* Fetches data for a given node and returns it as a Promise.
|
|
122
139
|
* This is a convenience wrapper around the `data` method for use with async/await.
|
|
@@ -146,5 +163,12 @@ export declare abstract class NodeDataProvider<Node extends JSONNode, Data> {
|
|
|
146
163
|
* @returns The cache status: `false`, `'ssr'`, or `'network'`.
|
|
147
164
|
*/
|
|
148
165
|
getCacheStatusForNode(node: Node | PMNode): false | 'ssr' | 'network';
|
|
166
|
+
/**
|
|
167
|
+
* Retrieves the cached data for a given node, if available.
|
|
168
|
+
*
|
|
169
|
+
* @param node The node (or its ProseMirror representation) for which to retrieve cached data.
|
|
170
|
+
* @returns The cached data object containing `data` and `source`, or `undefined` if no cache entry exists.
|
|
171
|
+
*/
|
|
172
|
+
getNodeDataFromCache(node: JSONNode | PMNode): CacheData<Data>[string] | undefined;
|
|
149
173
|
}
|
|
150
174
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/node-data-provider",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.4.0",
|
|
4
4
|
"description": "Node data provider for @atlaskit/editor-core plugins and @atlaskit/renderer",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"@babel/runtime": "^7.0.0"
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
|
-
"@atlaskit/editor-common": "^110.
|
|
29
|
+
"@atlaskit/editor-common": "^110.21.0"
|
|
30
30
|
},
|
|
31
31
|
"techstack": {
|
|
32
32
|
"@atlassian/frontend": {
|