@atlaskit/editor-synced-block-provider 8.5.7 → 8.6.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/CHANGELOG.md +24 -0
- package/dist/cjs/store-manager/referenceSyncBlockStoreManager.js +1 -1
- package/dist/cjs/store-manager/sourceSyncBlockStoreManager.js +72 -13
- package/dist/cjs/store-manager/syncBlockSubscriptionManager.js +216 -66
- package/dist/cjs/utils/errorHandling.js +47 -9
- package/dist/es2019/store-manager/referenceSyncBlockStoreManager.js +1 -1
- package/dist/es2019/store-manager/sourceSyncBlockStoreManager.js +79 -22
- package/dist/es2019/store-manager/syncBlockSubscriptionManager.js +133 -7
- package/dist/es2019/utils/errorHandling.js +50 -6
- package/dist/esm/store-manager/referenceSyncBlockStoreManager.js +1 -1
- package/dist/esm/store-manager/sourceSyncBlockStoreManager.js +73 -14
- package/dist/esm/store-manager/syncBlockSubscriptionManager.js +216 -66
- package/dist/esm/utils/errorHandling.js +46 -8
- package/dist/types/entry-points/errorHandling.d.ts +1 -0
- package/dist/types/store-manager/sourceSyncBlockStoreManager.d.ts +27 -1
- package/dist/types/store-manager/syncBlockSubscriptionManager.d.ts +28 -0
- package/dist/types/utils/errorHandling.d.ts +31 -6
- package/package.json +5 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @atlaskit/editor-synced-block-provider
|
|
2
2
|
|
|
3
|
+
## 8.6.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`f543995529d9d`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/f543995529d9d) -
|
|
8
|
+
[ux] Synced blocks now recover automatically from realtime connection drops that happen while a
|
|
9
|
+
tab is hidden or the network is offline. Instead of showing a fetch error when reconnection
|
|
10
|
+
attempts are exhausted in the background, the block silently re-arms and reconnects when the tab
|
|
11
|
+
becomes visible again or the network comes back online.
|
|
12
|
+
- Updated dependencies
|
|
13
|
+
|
|
14
|
+
## 8.6.0
|
|
15
|
+
|
|
16
|
+
### Minor Changes
|
|
17
|
+
|
|
18
|
+
- [`c0b0b98789f7a`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/c0b0b98789f7a) -
|
|
19
|
+
Add analytics for synced block source creation: record the creation input method and whether the
|
|
20
|
+
block was created empty, and emit a one-off event the first time an empty source block gains
|
|
21
|
+
content.
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- Updated dependencies
|
|
26
|
+
|
|
3
27
|
## 8.5.7
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
|
@@ -1020,7 +1020,7 @@ var ReferenceSyncBlockStoreManager = exports.ReferenceSyncBlockStoreManager = /*
|
|
|
1020
1020
|
_context4.next = 1;
|
|
1021
1021
|
break;
|
|
1022
1022
|
}
|
|
1023
|
-
return _context4.abrupt("return",
|
|
1023
|
+
return _context4.abrupt("return", true);
|
|
1024
1024
|
case 1:
|
|
1025
1025
|
if (this.isCacheDirty) {
|
|
1026
1026
|
_context4.next = 2;
|
|
@@ -59,6 +59,20 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
59
59
|
* multiple blocks are created concurrently. See EDITOR-7112.
|
|
60
60
|
*/
|
|
61
61
|
(0, _defineProperty2.default)(this, "creationsTimedOutDuringFlush", new Set());
|
|
62
|
+
/**
|
|
63
|
+
* Creation-type signals captured at `createBodiedSyncBlockNode` time and read
|
|
64
|
+
* back in `commitPendingCreation` to enrich the `syncedBlockCreate` event.
|
|
65
|
+
* Kept out of the flushed cache record so it never leaks into Block Service /
|
|
66
|
+
* ADF; removed once consumed.
|
|
67
|
+
*/
|
|
68
|
+
(0, _defineProperty2.default)(this, "creationEnrichment", new Map());
|
|
69
|
+
/**
|
|
70
|
+
* Resource IDs of blocks created empty this session that have not yet fired
|
|
71
|
+
* the first-content-added event. Added on empty creation, removed when the
|
|
72
|
+
* block first gains content (the event fires once). Blocks created with
|
|
73
|
+
* content or not created this session are never tracked.
|
|
74
|
+
*/
|
|
75
|
+
(0, _defineProperty2.default)(this, "awaitingFirstContent", new Set());
|
|
62
76
|
/**
|
|
63
77
|
* resourceId -> timestamp (ms) of the last `syncedBlockDelete` emission, used
|
|
64
78
|
* to suppress duplicates within {@link DELETE_DEDUPE_WINDOW_MS}. Only consulted
|
|
@@ -411,17 +425,48 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
411
425
|
var _this$fireAnalyticsEv4;
|
|
412
426
|
var sourceProduct = (0, _utils.getSourceProductFromResourceIdSafe)(resourceId);
|
|
413
427
|
(_this$fireAnalyticsEv4 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv4 === void 0 || _this$fireAnalyticsEv4.call(this, (0, _errorHandling.createSuccessPayload)(resourceId || '', sourceProduct));
|
|
414
|
-
// Operational create-success event with the join key
|
|
428
|
+
// Operational create-success event with the join key + creation-type
|
|
429
|
+
// signals (inputMethod / createdEmpty) captured at the command layer.
|
|
415
430
|
if ((0, _platformFeatureFlags.fg)('platform_editor_blocks_patch_4')) {
|
|
416
431
|
var _this$fireAnalyticsEv5, _this$syncBlockCache$;
|
|
417
|
-
(_this$fireAnalyticsEv5 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv5 === void 0 || _this$fireAnalyticsEv5.call(this, (0, _errorHandling.createSuccessOperationalPayload)(resourceId || '', (_this$syncBlockCache$ = this.syncBlockCache.get(resourceId)) === null || _this$syncBlockCache$ === void 0 ? void 0 : _this$syncBlockCache$.blockInstanceId, sourceProduct));
|
|
432
|
+
(_this$fireAnalyticsEv5 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv5 === void 0 || _this$fireAnalyticsEv5.call(this, (0, _errorHandling.createSuccessOperationalPayload)(resourceId || '', (_this$syncBlockCache$ = this.syncBlockCache.get(resourceId)) === null || _this$syncBlockCache$ === void 0 ? void 0 : _this$syncBlockCache$.blockInstanceId, sourceProduct, this.creationEnrichment.get(resourceId)));
|
|
418
433
|
}
|
|
419
434
|
} else {
|
|
420
435
|
var _this$fireAnalyticsEv6;
|
|
421
436
|
// Delete the node from cache if fail to create so it's not flushed to BE
|
|
422
437
|
this.syncBlockCache.delete(resourceId || '');
|
|
438
|
+
// Creation failed, so there is no block to add content to — drop the
|
|
439
|
+
// first-content tracking entry so a later unrelated edit cannot fire it.
|
|
440
|
+
this.awaitingFirstContent.delete(resourceId || '');
|
|
423
441
|
(_this$fireAnalyticsEv6 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv6 === void 0 || _this$fireAnalyticsEv6.call(this, (0, _errorHandling.createErrorPayload)('Fail to create bodied sync block', resourceId, (0, _utils.getSourceProductFromResourceIdSafe)(resourceId)));
|
|
424
442
|
}
|
|
443
|
+
// Enrichment is single-use — drop it once the create has resolved either way.
|
|
444
|
+
this.creationEnrichment.delete(resourceId || '');
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Fire the first-content-added event once when a block created empty this
|
|
449
|
+
* session first gains content. The caller detects the in-block edit; this owns
|
|
450
|
+
* dedupe + emission (fires at most once per block, only for empty→content).
|
|
451
|
+
* Gated behind `platform_editor_blocks_patch_4`.
|
|
452
|
+
*/
|
|
453
|
+
}, {
|
|
454
|
+
key: "maybeEmitFirstContentAdded",
|
|
455
|
+
value: function maybeEmitFirstContentAdded(resourceId, blockInstanceId) {
|
|
456
|
+
var _this$fireAnalyticsEv7;
|
|
457
|
+
if (this.viewMode === 'view') {
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
if (!(0, _platformFeatureFlags.fg)('platform_editor_blocks_patch_4')) {
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
// `delete` returns false when the id was not tracked (already emitted, or
|
|
464
|
+
// the block was not created empty this session), so this both dedupes and
|
|
465
|
+
// scopes emission to genuine first-content transitions in one check.
|
|
466
|
+
if (!this.awaitingFirstContent.delete(resourceId)) {
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
(_this$fireAnalyticsEv7 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv7 === void 0 || _this$fireAnalyticsEv7.call(this, (0, _errorHandling.addContentSuccessPayload)(resourceId, blockInstanceId, (0, _utils.getSourceProductFromResourceIdSafe)(resourceId)));
|
|
425
470
|
}
|
|
426
471
|
}, {
|
|
427
472
|
key: "registerConfirmationCallback",
|
|
@@ -461,16 +506,28 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
461
506
|
* @param attrs attributes Ids of the node
|
|
462
507
|
* @param node the ProseMirror node to cache
|
|
463
508
|
* @param onCompletion callback invoked when creation completes
|
|
509
|
+
* @param enrichment optional creation-type signals stashed and attached to the
|
|
510
|
+
* `syncedBlockCreate` event when the async create resolves. When
|
|
511
|
+
* `createdEmpty` is true the block is also registered for the
|
|
512
|
+
* first-content-added event.
|
|
464
513
|
*/
|
|
465
514
|
}, {
|
|
466
515
|
key: "createBodiedSyncBlockNode",
|
|
467
|
-
value: function createBodiedSyncBlockNode(attrs, node, onCompletion) {
|
|
516
|
+
value: function createBodiedSyncBlockNode(attrs, node, onCompletion, enrichment) {
|
|
468
517
|
var _this4 = this;
|
|
469
518
|
if (this.viewMode === 'view') {
|
|
470
519
|
return;
|
|
471
520
|
}
|
|
472
521
|
var resourceId = attrs.resourceId,
|
|
473
522
|
blockInstanceId = attrs.localId;
|
|
523
|
+
// Stash creation-type signals for commitPendingCreation to read.
|
|
524
|
+
if (enrichment) {
|
|
525
|
+
this.creationEnrichment.set(resourceId, enrichment);
|
|
526
|
+
// Only empty-created blocks can produce an empty→content transition.
|
|
527
|
+
if (enrichment.createdEmpty) {
|
|
528
|
+
this.awaitingFirstContent.add(resourceId);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
474
531
|
try {
|
|
475
532
|
var _this$createExperienc;
|
|
476
533
|
if (!this.dataProvider) {
|
|
@@ -520,14 +577,14 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
520
577
|
});
|
|
521
578
|
this.pendingCreationPromises.set(resourceId, creationPromise);
|
|
522
579
|
} catch (error) {
|
|
523
|
-
var _this$
|
|
580
|
+
var _this$fireAnalyticsEv8;
|
|
524
581
|
if (this.isPendingCreation(resourceId)) {
|
|
525
582
|
this.commitPendingCreation(false, resourceId);
|
|
526
583
|
}
|
|
527
584
|
(0, _monitoring.logException)(error, {
|
|
528
585
|
location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
|
|
529
586
|
});
|
|
530
|
-
(_this$
|
|
587
|
+
(_this$fireAnalyticsEv8 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv8 === void 0 || _this$fireAnalyticsEv8.call(this, (0, _errorHandling.createErrorPayload)(error.message, resourceId, (0, _utils.getSourceProductFromResourceIdSafe)(resourceId)));
|
|
531
588
|
}
|
|
532
589
|
}
|
|
533
590
|
}, {
|
|
@@ -565,11 +622,11 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
565
622
|
}, {
|
|
566
623
|
key: "emitDeleteSuccess",
|
|
567
624
|
value: function emitDeleteSuccess(resourceId, reason, mechanism) {
|
|
568
|
-
var _this$syncBlockCache$2, _this$
|
|
625
|
+
var _this$syncBlockCache$2, _this$fireAnalyticsEv0;
|
|
569
626
|
var sourceProduct = (0, _utils.getSourceProductFromResourceIdSafe)(resourceId);
|
|
570
627
|
if (!(0, _platformFeatureFlags.fg)('platform_editor_blocks_patch_4')) {
|
|
571
|
-
var _this$
|
|
572
|
-
(_this$
|
|
628
|
+
var _this$fireAnalyticsEv9;
|
|
629
|
+
(_this$fireAnalyticsEv9 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv9 === void 0 || _this$fireAnalyticsEv9.call(this, (0, _errorHandling.deleteSuccessPayload)(resourceId, sourceProduct));
|
|
573
630
|
return;
|
|
574
631
|
}
|
|
575
632
|
var now = Date.now();
|
|
@@ -584,7 +641,7 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
584
641
|
deletionReason: reason,
|
|
585
642
|
mechanism: mechanism
|
|
586
643
|
};
|
|
587
|
-
(_this$
|
|
644
|
+
(_this$fireAnalyticsEv0 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv0 === void 0 || _this$fireAnalyticsEv0.call(this, (0, _errorHandling.deleteSuccessPayload)(resourceId, sourceProduct, enrichment));
|
|
588
645
|
}
|
|
589
646
|
}, {
|
|
590
647
|
key: "delete",
|
|
@@ -933,11 +990,11 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
933
990
|
return sourceInfo;
|
|
934
991
|
});
|
|
935
992
|
} catch (error) {
|
|
936
|
-
var _this$
|
|
993
|
+
var _this$fireAnalyticsEv1;
|
|
937
994
|
(0, _monitoring.logException)(error, {
|
|
938
995
|
location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
|
|
939
996
|
});
|
|
940
|
-
(_this$
|
|
997
|
+
(_this$fireAnalyticsEv1 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv1 === void 0 || _this$fireAnalyticsEv1.call(this, (0, _errorHandling.getSourceInfoErrorPayload)(error.message));
|
|
941
998
|
return Promise.resolve(undefined);
|
|
942
999
|
}
|
|
943
1000
|
}
|
|
@@ -950,11 +1007,11 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
950
1007
|
}
|
|
951
1008
|
return this.dataProvider.fetchReferences(resourceId, true);
|
|
952
1009
|
} catch (error) {
|
|
953
|
-
var _this$
|
|
1010
|
+
var _this$fireAnalyticsEv10;
|
|
954
1011
|
(0, _monitoring.logException)(error, {
|
|
955
1012
|
location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
|
|
956
1013
|
});
|
|
957
|
-
(_this$
|
|
1014
|
+
(_this$fireAnalyticsEv10 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv10 === void 0 || _this$fireAnalyticsEv10.call(this, (0, _errorHandling.fetchReferencesErrorPayload)(error.message, resourceId, (0, _utils.getSourceProductFromResourceIdSafe)(resourceId)));
|
|
958
1015
|
return Promise.resolve({
|
|
959
1016
|
error: _types.SyncBlockError.Errored
|
|
960
1017
|
});
|
|
@@ -971,6 +1028,8 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
971
1028
|
this.postCreationFlushCallback = undefined;
|
|
972
1029
|
this.pendingCreationPromises.clear();
|
|
973
1030
|
this.creationsTimedOutDuringFlush.clear();
|
|
1031
|
+
this.creationEnrichment.clear();
|
|
1032
|
+
this.awaitingFirstContent.clear();
|
|
974
1033
|
this.recentDeleteEmissions.clear();
|
|
975
1034
|
this.dataProvider = undefined;
|
|
976
1035
|
(_this$saveExperience4 = this.saveExperience) === null || _this$saveExperience4 === void 0 || _this$saveExperience4.abort({
|