@atlaskit/collab-provider 8.3.0 → 8.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.
Files changed (42) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/analytics/index.js +2 -1
  3. package/dist/cjs/analytics/performance.js +1 -0
  4. package/dist/cjs/channel.js +230 -120
  5. package/dist/cjs/{error-code-mapper.js → errors/error-code-mapper.js} +1 -1
  6. package/dist/cjs/errors/error-types.js +43 -0
  7. package/dist/cjs/helpers/const.js +2 -4
  8. package/dist/cjs/provider/commit-step.js +39 -35
  9. package/dist/cjs/provider/index.js +71 -56
  10. package/dist/cjs/version-wrapper.js +1 -1
  11. package/dist/cjs/version.json +1 -1
  12. package/dist/es2019/analytics/index.js +2 -1
  13. package/dist/es2019/analytics/performance.js +1 -0
  14. package/dist/es2019/channel.js +116 -48
  15. package/dist/es2019/{error-code-mapper.js → errors/error-code-mapper.js} +1 -1
  16. package/dist/es2019/errors/error-types.js +13 -0
  17. package/dist/es2019/helpers/const.js +2 -4
  18. package/dist/es2019/provider/commit-step.js +37 -33
  19. package/dist/es2019/provider/index.js +83 -71
  20. package/dist/es2019/version-wrapper.js +1 -1
  21. package/dist/es2019/version.json +1 -1
  22. package/dist/esm/analytics/index.js +2 -1
  23. package/dist/esm/analytics/performance.js +1 -0
  24. package/dist/esm/channel.js +231 -121
  25. package/dist/esm/{error-code-mapper.js → errors/error-code-mapper.js} +1 -1
  26. package/dist/esm/errors/error-types.js +34 -0
  27. package/dist/esm/helpers/const.js +2 -4
  28. package/dist/esm/provider/commit-step.js +39 -35
  29. package/dist/esm/provider/index.js +70 -56
  30. package/dist/esm/version-wrapper.js +1 -1
  31. package/dist/esm/version.json +1 -1
  32. package/dist/types/analytics/performance.d.ts +2 -1
  33. package/dist/types/channel.d.ts +5 -0
  34. package/dist/types/{error-code-mapper.d.ts → errors/error-code-mapper.d.ts} +1 -1
  35. package/dist/types/errors/error-types.d.ts +8 -0
  36. package/dist/types/helpers/const.d.ts +29 -6
  37. package/dist/types/provider/index.d.ts +15 -1
  38. package/dist/types/socket-io-provider.d.ts +2 -2
  39. package/dist/types/types.d.ts +18 -3
  40. package/package.json +3 -3
  41. package/report.api.md +21 -4
  42. package/error-code-mapper/package.json +0 -15
@@ -9,7 +9,7 @@ import { createLogger, getParticipant, sleep } from '../helpers/utils';
9
9
  import { ACK_MAX_TRY, EVENT_ACTION, EVENT_STATUS } from '../helpers/const';
10
10
  import AnalyticsHelper from '../analytics';
11
11
  import { catchup } from './catchup';
12
- import { ErrorCodeMapper, errorCodeMapper } from '../error-code-mapper';
12
+ import { ErrorCodeMapper, errorCodeMapper } from '../errors/error-code-mapper';
13
13
  import { disconnectedReasonMapper } from '../disconnected-reason-mapper';
14
14
  import { MEASURE_NAME, startMeasure, stopMeasure } from '../analytics/performance';
15
15
  import { commitStep } from './commit-step';
@@ -22,7 +22,7 @@ const CATCHUP_THROTTLE = 1 * 1000; // 1 second
22
22
  const OUT_OF_SYNC_PERIOD = 3 * 1000; // 3 seconds
23
23
  const noop = () => {};
24
24
  export const MAX_STEP_REJECTED_ERROR = 15;
25
- const throttledCommitStep = throttle(commitStep, SEND_STEPS_THROTTLE, {
25
+ export const throttledCommitStep = throttle(commitStep, SEND_STEPS_THROTTLE, {
26
26
  leading: false,
27
27
  trailing: true
28
28
  });
@@ -491,98 +491,107 @@ export class Provider extends Emitter {
491
491
  });
492
492
  _defineProperty(this, "getCurrentState", async () => {
493
493
  try {
494
- var _this$metadata$title;
494
+ var _this$metadata$title, _this$analyticsHelper20;
495
+ startMeasure(MEASURE_NAME.GET_CURRENT_STATE, this.analyticsHelper);
496
+
495
497
  // Convert ProseMirror document in Editor state to ADF document
496
498
  const state = this.getState();
497
499
  const adfDocument = new JSONTransformer().encode(state.doc);
498
- return {
500
+ const currentState = {
499
501
  content: adfDocument,
500
502
  title: (_this$metadata$title = this.metadata.title) === null || _this$metadata$title === void 0 ? void 0 : _this$metadata$title.toString(),
501
503
  stepVersion: getVersion(state)
502
504
  };
505
+ const measure = stopMeasure(MEASURE_NAME.GET_CURRENT_STATE, this.analyticsHelper);
506
+ (_this$analyticsHelper20 = this.analyticsHelper) === null || _this$analyticsHelper20 === void 0 ? void 0 : _this$analyticsHelper20.sendActionEvent(EVENT_ACTION.GET_CURRENT_STATE, EVENT_STATUS.SUCCESS, {
507
+ latency: measure === null || measure === void 0 ? void 0 : measure.duration
508
+ });
509
+ return currentState;
503
510
  } catch (error) {
504
- var _this$analyticsHelper20;
505
- (_this$analyticsHelper20 = this.analyticsHelper) === null || _this$analyticsHelper20 === void 0 ? void 0 : _this$analyticsHelper20.sendErrorEvent(error, 'Error while returning ADF version of current draft document');
506
- throw error;
511
+ var _this$analyticsHelper21, _this$analyticsHelper22;
512
+ const measure = stopMeasure(MEASURE_NAME.GET_CURRENT_STATE, this.analyticsHelper);
513
+ (_this$analyticsHelper21 = this.analyticsHelper) === null || _this$analyticsHelper21 === void 0 ? void 0 : _this$analyticsHelper21.sendActionEvent(EVENT_ACTION.GET_CURRENT_STATE, EVENT_STATUS.FAILURE, {
514
+ latency: measure === null || measure === void 0 ? void 0 : measure.duration
515
+ });
516
+ (_this$analyticsHelper22 = this.analyticsHelper) === null || _this$analyticsHelper22 === void 0 ? void 0 : _this$analyticsHelper22.sendErrorEvent(error, 'Error while returning ADF version of current draft document');
517
+ throw error; // Reject the promise so the consumer can react to it failing
507
518
  }
508
519
  });
509
520
  _defineProperty(this, "commitUnconfirmedSteps", async () => {
510
- let count = 0;
511
521
  const unconfirmedSteps = this.getUnconfirmedSteps();
512
- if (unconfirmedSteps !== null && unconfirmedSteps !== void 0 && unconfirmedSteps.length) {
513
- var _this$analyticsHelper22;
514
- startMeasure(MEASURE_NAME.COMMIT_UNCONFIRMED_STEPS, this.analyticsHelper);
515
- // We use origins here as steps can be rebased. When steps are rebased a new step is created.
516
- // This means that we can not track if it has been removed from the unconfirmed array or not.
517
- // Origins points to the original transaction that the step was created in. This is never changed
518
- // and gets passed down when a step is rebased.
519
- const unconfirmedTrs = this.getUnconfirmedStepsOrigins();
520
- const lastTr = unconfirmedTrs === null || unconfirmedTrs === void 0 ? void 0 : unconfirmedTrs[unconfirmedTrs.length - 1];
521
- let isLastTrConfirmed = false;
522
- while (!isLastTrConfirmed) {
523
- this.sendStepsFromCurrentState();
524
- await sleep(1000);
525
- const nextUnconfirmedSteps = this.getUnconfirmedSteps();
526
- if (nextUnconfirmedSteps !== null && nextUnconfirmedSteps !== void 0 && nextUnconfirmedSteps.length) {
527
- const nextUnconfirmedTrs = this.getUnconfirmedStepsOrigins();
528
- isLastTrConfirmed = !(nextUnconfirmedTrs !== null && nextUnconfirmedTrs !== void 0 && nextUnconfirmedTrs.some(tr => tr === lastTr));
529
- } else {
530
- isLastTrConfirmed = true;
531
- }
532
- if (!isLastTrConfirmed && count++ >= ACK_MAX_TRY) {
533
- var _this$analyticsHelper21;
534
- if (this.onSyncUpError) {
535
- const state = this.getState();
536
- this.onSyncUpError({
537
- lengthOfUnconfirmedSteps: nextUnconfirmedSteps === null || nextUnconfirmedSteps === void 0 ? void 0 : nextUnconfirmedSteps.length,
538
- tries: count,
539
- maxRetries: ACK_MAX_TRY,
540
- clientId: this.clientId,
541
- version: getVersion(state)
542
- });
522
+ try {
523
+ if (unconfirmedSteps !== null && unconfirmedSteps !== void 0 && unconfirmedSteps.length) {
524
+ var _this$analyticsHelper23;
525
+ startMeasure(MEASURE_NAME.COMMIT_UNCONFIRMED_STEPS, this.analyticsHelper);
526
+ let count = 0;
527
+ // We use origins here as steps can be rebased. When steps are rebased a new step is created.
528
+ // This means that we can not track if it has been removed from the unconfirmed array or not.
529
+ // Origins points to the original transaction that the step was created in. This is never changed
530
+ // and gets passed down when a step is rebased.
531
+ const unconfirmedTrs = this.getUnconfirmedStepsOrigins();
532
+ const lastTr = unconfirmedTrs === null || unconfirmedTrs === void 0 ? void 0 : unconfirmedTrs[unconfirmedTrs.length - 1];
533
+ let isLastTrConfirmed = false;
534
+ while (!isLastTrConfirmed) {
535
+ this.sendStepsFromCurrentState();
536
+ await sleep(1000);
537
+ const nextUnconfirmedSteps = this.getUnconfirmedSteps();
538
+ if (nextUnconfirmedSteps !== null && nextUnconfirmedSteps !== void 0 && nextUnconfirmedSteps.length) {
539
+ const nextUnconfirmedTrs = this.getUnconfirmedStepsOrigins();
540
+ isLastTrConfirmed = !(nextUnconfirmedTrs !== null && nextUnconfirmedTrs !== void 0 && nextUnconfirmedTrs.some(tr => tr === lastTr));
541
+ } else {
542
+ isLastTrConfirmed = true;
543
+ }
544
+ if (!isLastTrConfirmed && count++ >= ACK_MAX_TRY) {
545
+ if (this.onSyncUpError) {
546
+ const state = this.getState();
547
+ this.onSyncUpError({
548
+ lengthOfUnconfirmedSteps: nextUnconfirmedSteps === null || nextUnconfirmedSteps === void 0 ? void 0 : nextUnconfirmedSteps.length,
549
+ tries: count,
550
+ maxRetries: ACK_MAX_TRY,
551
+ clientId: this.clientId,
552
+ version: getVersion(state)
553
+ });
554
+ }
555
+ throw new Error("Can't sync up with Collab Service");
543
556
  }
544
- const measure = stopMeasure(MEASURE_NAME.COMMIT_UNCONFIRMED_STEPS, this.analyticsHelper);
545
- (_this$analyticsHelper21 = this.analyticsHelper) === null || _this$analyticsHelper21 === void 0 ? void 0 : _this$analyticsHelper21.sendActionEvent(EVENT_ACTION.COMMIT_UNCONFIRMED_STEPS, EVENT_STATUS.FAILURE, {
546
- latency: measure === null || measure === void 0 ? void 0 : measure.duration,
547
- // upon failure, emit the number of unconfirmed steps we attempted to sync
548
- numUnconfirmedSteps: nextUnconfirmedSteps === null || nextUnconfirmedSteps === void 0 ? void 0 : nextUnconfirmedSteps.length
549
- });
550
- throw new Error("Can't sync up with Collab Service");
551
557
  }
558
+ const measure = stopMeasure(MEASURE_NAME.COMMIT_UNCONFIRMED_STEPS, this.analyticsHelper);
559
+ (_this$analyticsHelper23 = this.analyticsHelper) === null || _this$analyticsHelper23 === void 0 ? void 0 : _this$analyticsHelper23.sendActionEvent(EVENT_ACTION.COMMIT_UNCONFIRMED_STEPS, EVENT_STATUS.SUCCESS, {
560
+ latency: measure === null || measure === void 0 ? void 0 : measure.duration,
561
+ // upon success, emit the total number of unconfirmed steps we synced
562
+ numUnconfirmedSteps: unconfirmedSteps === null || unconfirmedSteps === void 0 ? void 0 : unconfirmedSteps.length
563
+ });
552
564
  }
565
+ } catch (error) {
566
+ var _this$analyticsHelper24, _this$analyticsHelper25;
553
567
  const measure = stopMeasure(MEASURE_NAME.COMMIT_UNCONFIRMED_STEPS, this.analyticsHelper);
554
- (_this$analyticsHelper22 = this.analyticsHelper) === null || _this$analyticsHelper22 === void 0 ? void 0 : _this$analyticsHelper22.sendActionEvent(EVENT_ACTION.COMMIT_UNCONFIRMED_STEPS, EVENT_STATUS.SUCCESS, {
568
+ (_this$analyticsHelper24 = this.analyticsHelper) === null || _this$analyticsHelper24 === void 0 ? void 0 : _this$analyticsHelper24.sendActionEvent(EVENT_ACTION.COMMIT_UNCONFIRMED_STEPS, EVENT_STATUS.FAILURE, {
555
569
  latency: measure === null || measure === void 0 ? void 0 : measure.duration,
556
- // upon success, emit the total number of unconfirmed steps we synced
557
570
  numUnconfirmedSteps: unconfirmedSteps === null || unconfirmedSteps === void 0 ? void 0 : unconfirmedSteps.length
558
571
  });
572
+ (_this$analyticsHelper25 = this.analyticsHelper) === null || _this$analyticsHelper25 === void 0 ? void 0 : _this$analyticsHelper25.sendErrorEvent(error, 'Error while committing unconfirmed steps');
573
+ throw error;
559
574
  }
560
575
  });
561
576
  _defineProperty(this, "getFinalAcknowledgedState", async () => {
562
- // Moved these out of the try catch to maintain the current logic for throwing / not throwing errors
563
- startMeasure(MEASURE_NAME.PUBLISH_PAGE, this.analyticsHelper);
564
- await this.commitUnconfirmedSteps();
565
577
  try {
566
- var _this$analyticsHelper23;
578
+ var _this$analyticsHelper26;
579
+ startMeasure(MEASURE_NAME.PUBLISH_PAGE, this.analyticsHelper);
580
+ await this.commitUnconfirmedSteps();
567
581
  const currentState = await this.getCurrentState();
568
582
  const measure = stopMeasure(MEASURE_NAME.PUBLISH_PAGE, this.analyticsHelper);
569
- (_this$analyticsHelper23 = this.analyticsHelper) === null || _this$analyticsHelper23 === void 0 ? void 0 : _this$analyticsHelper23.sendActionEvent(EVENT_ACTION.PUBLISH_PAGE, EVENT_STATUS.SUCCESS, {
583
+ (_this$analyticsHelper26 = this.analyticsHelper) === null || _this$analyticsHelper26 === void 0 ? void 0 : _this$analyticsHelper26.sendActionEvent(EVENT_ACTION.PUBLISH_PAGE, EVENT_STATUS.SUCCESS, {
570
584
  latency: measure === null || measure === void 0 ? void 0 : measure.duration
571
585
  });
572
586
  return currentState;
573
587
  } catch (error) {
574
- var _this$analyticsHelper24, _this$analyticsHelper25, _this$metadata$title2;
575
- const measure = stopMeasure(MEASURE_NAME.COMMIT_UNCONFIRMED_STEPS, this.analyticsHelper);
576
- (_this$analyticsHelper24 = this.analyticsHelper) === null || _this$analyticsHelper24 === void 0 ? void 0 : _this$analyticsHelper24.sendActionEvent(EVENT_ACTION.PUBLISH_PAGE, EVENT_STATUS.FAILURE, {
588
+ var _this$analyticsHelper27, _this$analyticsHelper28;
589
+ const measure = stopMeasure(MEASURE_NAME.PUBLISH_PAGE, this.analyticsHelper);
590
+ (_this$analyticsHelper27 = this.analyticsHelper) === null || _this$analyticsHelper27 === void 0 ? void 0 : _this$analyticsHelper27.sendActionEvent(EVENT_ACTION.PUBLISH_PAGE, EVENT_STATUS.FAILURE, {
577
591
  latency: measure === null || measure === void 0 ? void 0 : measure.duration
578
592
  });
579
- (_this$analyticsHelper25 = this.analyticsHelper) === null || _this$analyticsHelper25 === void 0 ? void 0 : _this$analyticsHelper25.sendErrorEvent(error, 'Error while returning ADF version of the final draft document');
580
- // TODO: We should likely throw here after we stop using this for draft sync, there is no way of knowing what happened otherwise, but this is what it was doing before
581
- return {
582
- content: undefined,
583
- title: (_this$metadata$title2 = this.metadata.title) === null || _this$metadata$title2 === void 0 ? void 0 : _this$metadata$title2.toString(),
584
- stepVersion: getVersion(this.getState())
585
- };
593
+ (_this$analyticsHelper28 = this.analyticsHelper) === null || _this$analyticsHelper28 === void 0 ? void 0 : _this$analyticsHelper28.sendErrorEvent(error, 'Error while returning ADF version of the final draft document');
594
+ throw error; // Reject the promise so the consumer can react to it failing
586
595
  }
587
596
  });
588
597
  _defineProperty(this, "onNamespaceStatusChanged", async data => {
@@ -641,8 +650,8 @@ export class Provider extends Emitter {
641
650
  this.isChannelInitialized = true;
642
651
  }
643
652
  } catch (initError) {
644
- var _this$analyticsHelper26;
645
- (_this$analyticsHelper26 = this.analyticsHelper) === null || _this$analyticsHelper26 === void 0 ? void 0 : _this$analyticsHelper26.sendErrorEvent(initError, 'Error while initialising the provider');
653
+ var _this$analyticsHelper29;
654
+ (_this$analyticsHelper29 = this.analyticsHelper) === null || _this$analyticsHelper29 === void 0 ? void 0 : _this$analyticsHelper29.sendErrorEvent(initError, 'Error while initialising the provider');
646
655
  // Throw error so consumers are aware the initialisation failed when initialising themselves
647
656
  throw initError;
648
657
  }
@@ -752,9 +761,9 @@ export class Provider extends Emitter {
752
761
  setTimeout(() => this.sendStepsFromCurrentState(), 100);
753
762
  }
754
763
  } catch (error) {
755
- var _this$analyticsHelper27;
764
+ var _this$analyticsHelper30;
756
765
  logger(`Processing steps failed with error: ${error}. Triggering catch up call.`);
757
- (_this$analyticsHelper27 = this.analyticsHelper) === null || _this$analyticsHelper27 === void 0 ? void 0 : _this$analyticsHelper27.sendErrorEvent(error, 'Error while processing steps');
766
+ (_this$analyticsHelper30 = this.analyticsHelper) === null || _this$analyticsHelper30 === void 0 ? void 0 : _this$analyticsHelper30.sendErrorEvent(error, 'Error while processing steps');
758
767
  this.throttledCatchup();
759
768
  }
760
769
  }
@@ -775,9 +784,9 @@ export class Provider extends Emitter {
775
784
  const callback = telepointerCallback(this.config.documentAri);
776
785
  this.channel.broadcast('participant:telepointer', payload, callback);
777
786
  } catch (error) {
778
- var _this$analyticsHelper28;
787
+ var _this$analyticsHelper31;
779
788
  // We don't want to throw errors for Presence features as they tend to self-restore
780
- (_this$analyticsHelper28 = this.analyticsHelper) === null || _this$analyticsHelper28 === void 0 ? void 0 : _this$analyticsHelper28.sendErrorEvent(error, 'Error while sending message - telepointer');
789
+ (_this$analyticsHelper31 = this.analyticsHelper) === null || _this$analyticsHelper31 === void 0 ? void 0 : _this$analyticsHelper31.sendErrorEvent(error, 'Error while sending message - telepointer');
781
790
  }
782
791
  }
783
792
  }
@@ -790,11 +799,14 @@ export class Provider extends Emitter {
790
799
  }
791
800
  });
792
801
  } catch (error) {
793
- var _this$analyticsHelper29;
802
+ var _this$analyticsHelper32;
794
803
  // We don't want to throw errors for Presence features as they tend to self-restore
795
- (_this$analyticsHelper29 = this.analyticsHelper) === null || _this$analyticsHelper29 === void 0 ? void 0 : _this$analyticsHelper29.sendErrorEvent(error, 'Error while emitting telepointers from steps');
804
+ (_this$analyticsHelper32 = this.analyticsHelper) === null || _this$analyticsHelper32 === void 0 ? void 0 : _this$analyticsHelper32.sendErrorEvent(error, 'Error while emitting telepointers from steps');
796
805
  }
797
806
  }
807
+
808
+ // Note: this gets triggered on page reload for Firefox (not other browsers) because of closeOnBeforeunload: false
809
+
798
810
  destroy() {
799
811
  return this.disconnect();
800
812
  }
@@ -1,5 +1,5 @@
1
1
  export const name = "@atlaskit/collab-provider";
2
- export const version = "8.3.0";
2
+ export const version = "8.4.0";
3
3
  export const nextMajorVersion = () => {
4
4
  return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
5
5
  };
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/collab-provider",
3
- "version": "8.3.0",
3
+ "version": "8.4.0",
4
4
  "sideEffects": false
5
5
  }
@@ -60,7 +60,8 @@ var AnalyticsHelper = /*#__PURE__*/function () {
60
60
  eventAction: EVENT_ACTION.ERROR,
61
61
  attributes: {
62
62
  documentAri: this.documentAri,
63
- errorMessage: errorMessage
63
+ errorMessage: errorMessage,
64
+ errorName: error instanceof Error ? error.name : undefined
64
65
  },
65
66
  nonPrivacySafeAttributes: {
66
67
  error: error
@@ -4,6 +4,7 @@ export var MEASURE_NAME;
4
4
  MEASURE_NAME["DOCUMENT_INIT"] = "documentInit";
5
5
  MEASURE_NAME["COMMIT_UNCONFIRMED_STEPS"] = "commitUnconfirmedSteps";
6
6
  MEASURE_NAME["PUBLISH_PAGE"] = "publishPage";
7
+ MEASURE_NAME["GET_CURRENT_STATE"] = "getCurrentState";
7
8
  })(MEASURE_NAME || (MEASURE_NAME = {}));
8
9
  var isPerformanceAPIAvailable = function isPerformanceAPIAvailable() {
9
10
  return typeof window !== 'undefined' && 'performance' in window && ['measure', 'clearMeasures', 'clearMarks', 'getEntriesByName', 'getEntriesByType'].every(function (api) {