@atlaskit/editor-plugin-autocomplete 2.3.0 → 2.5.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 (66) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/afm-cc/tsconfig.json +3 -0
  3. package/afm-products/tsconfig.json +3 -0
  4. package/autocompletePlugin/package.json +15 -0
  5. package/autocompletePluginType/package.json +15 -0
  6. package/dist/cjs/analytics/ufo.js +111 -0
  7. package/dist/cjs/entry-points/autocompletePlugin.js +12 -0
  8. package/dist/cjs/entry-points/autocompletePluginType.js +1 -0
  9. package/dist/cjs/entry-points/src-pm-plugins-autocomplete-plugin.js +18 -0
  10. package/dist/cjs/entry-points/src-pm-plugins-slow-lane-client.js +36 -0
  11. package/dist/cjs/entry-points/src-pm-plugins-text-predictor.js +66 -0
  12. package/dist/cjs/pm-plugins/autocomplete-plugin.js +126 -64
  13. package/dist/cjs/pm-plugins/local-slow-lane-client.js +447 -0
  14. package/dist/cjs/pm-plugins/slow-lane-client.js +45 -16
  15. package/dist/cjs/pm-plugins/text-predictor.js +72 -40
  16. package/dist/es2019/analytics/ufo.js +110 -0
  17. package/dist/es2019/entry-points/autocompletePlugin.js +2 -0
  18. package/dist/es2019/entry-points/autocompletePluginType.js +0 -0
  19. package/dist/es2019/entry-points/src-pm-plugins-autocomplete-plugin.js +2 -0
  20. package/dist/es2019/entry-points/src-pm-plugins-slow-lane-client.js +2 -0
  21. package/dist/es2019/entry-points/src-pm-plugins-text-predictor.js +2 -0
  22. package/dist/es2019/pm-plugins/autocomplete-plugin.js +132 -72
  23. package/dist/es2019/pm-plugins/local-slow-lane-client.js +355 -0
  24. package/dist/es2019/pm-plugins/slow-lane-client.js +29 -2
  25. package/dist/es2019/pm-plugins/text-predictor.js +48 -15
  26. package/dist/esm/analytics/ufo.js +105 -0
  27. package/dist/esm/entry-points/autocompletePlugin.js +2 -0
  28. package/dist/esm/entry-points/autocompletePluginType.js +0 -0
  29. package/dist/esm/entry-points/src-pm-plugins-autocomplete-plugin.js +2 -0
  30. package/dist/esm/entry-points/src-pm-plugins-slow-lane-client.js +2 -0
  31. package/dist/esm/entry-points/src-pm-plugins-text-predictor.js +2 -0
  32. package/dist/esm/pm-plugins/autocomplete-plugin.js +126 -64
  33. package/dist/esm/pm-plugins/local-slow-lane-client.js +439 -0
  34. package/dist/esm/pm-plugins/slow-lane-client.js +45 -16
  35. package/dist/esm/pm-plugins/text-predictor.js +73 -40
  36. package/dist/types/analytics/ufo.d.ts +38 -0
  37. package/dist/types/entry-points/autocompletePlugin.d.ts +1 -0
  38. package/dist/types/entry-points/autocompletePluginType.d.ts +1 -0
  39. package/dist/types/entry-points/src-pm-plugins-autocomplete-plugin.d.ts +2 -0
  40. package/dist/types/entry-points/src-pm-plugins-slow-lane-client.d.ts +2 -0
  41. package/dist/types/entry-points/src-pm-plugins-text-predictor.d.ts +2 -0
  42. package/dist/types/pm-plugins/autocomplete-plugin.d.ts +5 -0
  43. package/dist/types/pm-plugins/local-slow-lane-client.d.ts +102 -0
  44. package/dist/types-ts4.5/analytics/ufo.d.ts +38 -0
  45. package/dist/types-ts4.5/entry-points/autocompletePlugin.d.ts +1 -0
  46. package/dist/types-ts4.5/entry-points/autocompletePluginType.d.ts +1 -0
  47. package/dist/types-ts4.5/entry-points/src-pm-plugins-autocomplete-plugin.d.ts +2 -0
  48. package/dist/types-ts4.5/entry-points/src-pm-plugins-slow-lane-client.d.ts +2 -0
  49. package/dist/types-ts4.5/entry-points/src-pm-plugins-text-predictor.d.ts +2 -0
  50. package/dist/types-ts4.5/pm-plugins/autocomplete-plugin.d.ts +5 -0
  51. package/dist/types-ts4.5/pm-plugins/local-slow-lane-client.d.ts +102 -0
  52. package/package.json +8 -3
  53. package/src/analytics/ufo.ts +139 -0
  54. package/src/entry-points/autocompletePlugin.tsx +2 -0
  55. package/src/entry-points/autocompletePluginType.ts +2 -0
  56. package/src/entry-points/src-pm-plugins-autocomplete-plugin.ts +7 -0
  57. package/src/entry-points/src-pm-plugins-slow-lane-client.ts +13 -0
  58. package/src/entry-points/src-pm-plugins-text-predictor.ts +14 -0
  59. package/src/pm-plugins/autocomplete-plugin/package.json +5 -5
  60. package/src/pm-plugins/autocomplete-plugin.ts +126 -64
  61. package/src/pm-plugins/local-slow-lane-client.ts +480 -0
  62. package/src/pm-plugins/slow-lane-client/package.json +5 -5
  63. package/src/pm-plugins/slow-lane-client.ts +28 -2
  64. package/src/pm-plugins/text-predictor/package.json +5 -5
  65. package/src/pm-plugins/text-predictor.ts +42 -12
  66. package/tsconfig.app.json +3 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,47 @@
1
1
  # @atlaskit/editor-plugin-autocomplete
2
2
 
3
+ ## 2.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`09fd1de566937`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/09fd1de566937) -
8
+ Add UFO experience tracking to `@atlaskit/editor-plugin-autocomplete` for the asynchronous
9
+ operations that have meaningful latency and success/failure outcomes — slow-lane fetch, vocabulary
10
+ load, and vectors load. Experiences surface downstream as
11
+ `platform.fe.operation.editor-plugin-autocomplete.<name>`.
12
+
13
+ Per-keystroke suggestion lifecycle counters (view, insert, dismiss) are tracked exclusively via
14
+ analytics-next instead of UFO, to avoid emitting zero-duration events on every word boundary. A
15
+ new `suggestionDismissed` contextual-typeahead analytics event is added
16
+ (`@atlaskit/editor-common`) alongside the existing `suggestionViewed` / `suggestionInserted`
17
+ events, with a `reason: 'escape' | 'blur'` attribute.
18
+
19
+ ### Patch Changes
20
+
21
+ - [`60d4bf83adcbc`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/60d4bf83adcbc) -
22
+ Wrap risky imperative paths (PM tree mutations, debounced prediction timer, async
23
+ vocabulary/vectors/context loads) with try/catch + logException so failures surface in Sentry and
24
+ the editor never silently dies on a malformed prediction or stale state. Follows the convention
25
+ used by editor-plugin-block-controls, editor-plugin-paste-options-toolbar, editor-plugin-emoji,
26
+ etc.
27
+ - [`43e460948b5c6`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/43e460948b5c6) -
28
+ Fix LocalSlowLaneClient: remove dead `void engineUnloadPromise` no-op, add WebGPU pre-flight check
29
+ before model load, prevent infinite init retries with a permanent-failure flag, call `onUpdate` on
30
+ inference error to maintain consistent notification contract, and add `.catch` handler to suppress
31
+ unhandled promise rejections in `doUpdateContext`.
32
+ - Updated dependencies
33
+
34
+ ## 2.4.0
35
+
36
+ ### Minor Changes
37
+
38
+ - [`ce30a31e6369d`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/ce30a31e6369d) -
39
+ Autofix: add explicit package exports (barrel removal)
40
+
41
+ ### Patch Changes
42
+
43
+ - Updated dependencies
44
+
3
45
  ## 2.3.0
4
46
 
5
47
  ### Minor Changes
@@ -22,6 +22,9 @@
22
22
  {
23
23
  "path": "../../editor-prosemirror/afm-cc/tsconfig.json"
24
24
  },
25
+ {
26
+ "path": "../../../data/ufo-external/afm-cc/tsconfig.json"
27
+ },
25
28
  {
26
29
  "path": "../../editor-common/afm-cc/tsconfig.json"
27
30
  },
@@ -22,6 +22,9 @@
22
22
  {
23
23
  "path": "../../editor-prosemirror/afm-products/tsconfig.json"
24
24
  },
25
+ {
26
+ "path": "../../../data/ufo-external/afm-products/tsconfig.json"
27
+ },
25
28
  {
26
29
  "path": "../../editor-common/afm-products/tsconfig.json"
27
30
  },
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "@atlaskit/editor-plugin-autocomplete/autocompletePlugin",
3
+ "main": "../dist/cjs/entry-points/autocompletePlugin.js",
4
+ "module": "../dist/esm/entry-points/autocompletePlugin.js",
5
+ "module:es2019": "../dist/es2019/entry-points/autocompletePlugin.js",
6
+ "sideEffects": false,
7
+ "types": "../dist/types/entry-points/autocompletePlugin.d.ts",
8
+ "typesVersions": {
9
+ ">=4.5 <5.9": {
10
+ "*": [
11
+ "../dist/types-ts4.5/entry-points/autocompletePlugin.d.ts"
12
+ ]
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "@atlaskit/editor-plugin-autocomplete/autocompletePluginType",
3
+ "main": "../dist/cjs/entry-points/autocompletePluginType.js",
4
+ "module": "../dist/esm/entry-points/autocompletePluginType.js",
5
+ "module:es2019": "../dist/es2019/entry-points/autocompletePluginType.js",
6
+ "sideEffects": false,
7
+ "types": "../dist/types/entry-points/autocompletePluginType.d.ts",
8
+ "typesVersions": {
9
+ ">=4.5 <5.9": {
10
+ "*": [
11
+ "../dist/types-ts4.5/entry-points/autocompletePluginType.d.ts"
12
+ ]
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.succeedExp = exports.startExp = exports.failExp = exports.abortExp = exports.EXPERIENCE_NAME = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _ufo = require("@atlaskit/ufo");
10
+ /**
11
+ * UFO experience tracking helpers for `@atlaskit/editor-plugin-autocomplete`.
12
+ *
13
+ * Pattern follows `packages/linking-platform/smart-card/src/state/analytics/ufoExperiences.ts`
14
+ * (ConcurrentExperience keyed per request/instance) plus a try/catch safety wrap
15
+ * inspired by `packages/editor/collab-provider/src/analytics/ufo.ts` so a UFO
16
+ * runtime error can never break the autocomplete feature.
17
+ *
18
+ * Experience names must be registered in DataPortal's `task` attribute before
19
+ * they can power FE Reliability SLOs:
20
+ * https://hello.atlassian.net/wiki/spaces/AA6/pages/3961393753
21
+ */
22
+
23
+ /**
24
+ * Experience name strings are surfaced downstream by the UFO pipeline as
25
+ * `platform.fe.<type>.<platform.component>.<name>` (e.g.
26
+ * `platform.fe.operation.editor-plugin-autocomplete.slow-lane-fetch`), so
27
+ * names here should be short, dot-free, and must not repeat the component
28
+ * name. This matches the convention used by `@atlaskit/emoji`'s
29
+ * `ufoExperiences` map (e.g. `'emoji-rendered'`).
30
+ */
31
+ /**
32
+ * Only experiences with meaningful async work and a real success/failure
33
+ * outcome belong on UFO (which measures latency and success rate for FE
34
+ * Reliability SLOs). Per-keystroke suggestion lifecycle counters (viewed /
35
+ * inserted / dismissed) are tracked via analytics-next instead — they would
36
+ * otherwise emit zero-duration events on every word boundary.
37
+ */
38
+ var EXPERIENCE_NAME = exports.EXPERIENCE_NAME = {
39
+ SLOW_LANE_FETCH: 'slow-lane-fetch',
40
+ LOAD_VOCABULARY: 'load-vocabulary',
41
+ LOAD_VECTORS: 'load-vectors'
42
+ };
43
+ var isUfoEnabled = function isUfoEnabled() {
44
+ var _process;
45
+ return !((_process = process) !== null && _process !== void 0 && (_process = _process.env) !== null && _process !== void 0 && _process.REACT_SSR);
46
+ };
47
+ var operationConfig = {
48
+ platform: {
49
+ component: 'editor-plugin-autocomplete'
50
+ },
51
+ type: _ufo.ExperienceTypes.Operation,
52
+ performanceType: _ufo.ExperiencePerformanceTypes.Custom,
53
+ performanceConfig: {
54
+ histogram: (0, _defineProperty2.default)({}, _ufo.ExperiencePerformanceTypes.Custom, {
55
+ duration: '50_100_250_500_1000_2000_4000'
56
+ })
57
+ }
58
+ };
59
+ var experiences = (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, EXPERIENCE_NAME.SLOW_LANE_FETCH, new _ufo.ConcurrentExperience(EXPERIENCE_NAME.SLOW_LANE_FETCH, operationConfig)), EXPERIENCE_NAME.LOAD_VOCABULARY, new _ufo.ConcurrentExperience(EXPERIENCE_NAME.LOAD_VOCABULARY, operationConfig)), EXPERIENCE_NAME.LOAD_VECTORS, new _ufo.ConcurrentExperience(EXPERIENCE_NAME.LOAD_VECTORS, operationConfig));
60
+ var startExp = exports.startExp = function startExp(name, id, metadata) {
61
+ if (!isUfoEnabled()) {
62
+ return;
63
+ }
64
+ try {
65
+ var instance = experiences[name].getInstance(id);
66
+ instance.start();
67
+ if (metadata) {
68
+ instance.addMetadata(metadata);
69
+ }
70
+ } catch (_unused) {
71
+ // UFO errors must never break the plugin
72
+ }
73
+ };
74
+ var succeedExp = exports.succeedExp = function succeedExp(name, id, metadata) {
75
+ if (!isUfoEnabled()) {
76
+ return;
77
+ }
78
+ try {
79
+ experiences[name].getInstance(id).success({
80
+ metadata: metadata
81
+ });
82
+ } catch (_unused2) {
83
+ // UFO errors must never break the plugin
84
+ }
85
+ };
86
+ var failExp = exports.failExp = function failExp(name, id, metadata) {
87
+ if (!isUfoEnabled()) {
88
+ return;
89
+ }
90
+ try {
91
+ experiences[name].getInstance(id).failure({
92
+ metadata: metadata
93
+ });
94
+ } catch (_unused3) {
95
+ // UFO errors must never break the plugin
96
+ }
97
+ };
98
+ var abortExp = exports.abortExp = function abortExp(name, id, reason) {
99
+ if (!isUfoEnabled()) {
100
+ return;
101
+ }
102
+ try {
103
+ experiences[name].getInstance(id).abort(reason ? {
104
+ metadata: {
105
+ reason: reason
106
+ }
107
+ } : undefined);
108
+ } catch (_unused4) {
109
+ // UFO errors must never break the plugin
110
+ }
111
+ };
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "autocompletePlugin", {
7
+ enumerable: true,
8
+ get: function get() {
9
+ return _autocompletePlugin.autocompletePlugin;
10
+ }
11
+ });
12
+ var _autocompletePlugin = require("../autocompletePlugin");
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "autocompletePluginKey", {
7
+ enumerable: true,
8
+ get: function get() {
9
+ return _autocompletePlugin.autocompletePluginKey;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "createAutocompletePlugin", {
13
+ enumerable: true,
14
+ get: function get() {
15
+ return _autocompletePlugin.createAutocompletePlugin;
16
+ }
17
+ });
18
+ var _autocompletePlugin = require("../pm-plugins/autocomplete-plugin");
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "createSlowLaneClient", {
7
+ enumerable: true,
8
+ get: function get() {
9
+ return _slowLaneClient.createSlowLaneClient;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "getStoredContextVector", {
13
+ enumerable: true,
14
+ get: function get() {
15
+ return _slowLaneClient.getStoredContextVector;
16
+ }
17
+ });
18
+ Object.defineProperty(exports, "getStoredLmLogits", {
19
+ enumerable: true,
20
+ get: function get() {
21
+ return _slowLaneClient.getStoredLmLogits;
22
+ }
23
+ });
24
+ Object.defineProperty(exports, "isWordBoundary", {
25
+ enumerable: true,
26
+ get: function get() {
27
+ return _slowLaneClient.isWordBoundary;
28
+ }
29
+ });
30
+ Object.defineProperty(exports, "setDefaultSlowLaneClient", {
31
+ enumerable: true,
32
+ get: function get() {
33
+ return _slowLaneClient.setDefaultSlowLaneClient;
34
+ }
35
+ });
36
+ var _slowLaneClient = require("../pm-plugins/slow-lane-client");
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "getLastPredictionDebug", {
7
+ enumerable: true,
8
+ get: function get() {
9
+ return _textPredictor.getLastPredictionDebug;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "getPredictorStatus", {
13
+ enumerable: true,
14
+ get: function get() {
15
+ return _textPredictor.getPredictorStatus;
16
+ }
17
+ });
18
+ Object.defineProperty(exports, "incrementSessionFreq", {
19
+ enumerable: true,
20
+ get: function get() {
21
+ return _textPredictor.incrementSessionFreq;
22
+ }
23
+ });
24
+ Object.defineProperty(exports, "ingestDocumentPage", {
25
+ enumerable: true,
26
+ get: function get() {
27
+ return _textPredictor.ingestDocumentPage;
28
+ }
29
+ });
30
+ Object.defineProperty(exports, "initL3Vocabulary", {
31
+ enumerable: true,
32
+ get: function get() {
33
+ return _textPredictor.initL3Vocabulary;
34
+ }
35
+ });
36
+ Object.defineProperty(exports, "initVectors", {
37
+ enumerable: true,
38
+ get: function get() {
39
+ return _textPredictor.initVectors;
40
+ }
41
+ });
42
+ Object.defineProperty(exports, "initVocabulary", {
43
+ enumerable: true,
44
+ get: function get() {
45
+ return _textPredictor.initVocabulary;
46
+ }
47
+ });
48
+ Object.defineProperty(exports, "loadDefaultVocabulary", {
49
+ enumerable: true,
50
+ get: function get() {
51
+ return _textPredictor.loadDefaultVocabulary;
52
+ }
53
+ });
54
+ Object.defineProperty(exports, "loadVectorsAsync", {
55
+ enumerable: true,
56
+ get: function get() {
57
+ return _textPredictor.loadVectorsAsync;
58
+ }
59
+ });
60
+ Object.defineProperty(exports, "predict", {
61
+ enumerable: true,
62
+ get: function get() {
63
+ return _textPredictor.predict;
64
+ }
65
+ });
66
+ var _textPredictor = require("../pm-plugins/text-predictor");
@@ -7,18 +7,22 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.createAutocompletePlugin = exports.autocompletePluginKey = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _analytics = require("@atlaskit/editor-common/analytics");
10
+ var _monitoring = require("@atlaskit/editor-common/monitoring");
10
11
  var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
11
12
  var _keymap = require("@atlaskit/editor-prosemirror/keymap");
12
13
  var _state = require("@atlaskit/editor-prosemirror/state");
13
14
  var _view = require("@atlaskit/editor-prosemirror/view");
14
15
  var _ghostTextDecoration = require("./ghost-text-decoration");
16
+ var _localSlowLaneClient = require("./local-slow-lane-client");
15
17
  var _slowLaneClient = require("./slow-lane-client");
16
18
  var _textPredictor = require("./text-predictor");
17
19
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
18
20
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
19
- var SLOW_LANE_ENDPOINT = '/gateway/api/v1/autocomplete/typeahead-encodings';
20
21
  var autocompletePluginKey = exports.autocompletePluginKey = new _state.PluginKey('autocomplete');
21
22
  var DEBOUNCE_MS = 150;
23
+ var hasDestroy = function hasDestroy(client) {
24
+ return 'destroy' in client && typeof client.destroy === 'function';
25
+ };
22
26
  var createInitialState = function createInitialState() {
23
27
  return {
24
28
  ghostText: '',
@@ -71,15 +75,21 @@ var setAutocompleteMeta = function setAutocompleteMeta(tr, meta) {
71
75
  */
72
76
  var lastShownGhostText = '';
73
77
  var showGhostText = function showGhostText(view, text, position) {
74
- var state = view.state,
75
- dispatch = view.dispatch;
76
- var decorationSet = (0, _ghostTextDecoration.createGhostTextDecorationSet)(state, position, text);
77
- var tr = setAutocompleteMeta(state.tr, {
78
- ghostText: text,
79
- ghostPosition: position,
80
- decorationSet: decorationSet
81
- });
82
- dispatch(tr);
78
+ try {
79
+ var state = view.state,
80
+ dispatch = view.dispatch;
81
+ var decorationSet = (0, _ghostTextDecoration.createGhostTextDecorationSet)(state, position, text);
82
+ var tr = setAutocompleteMeta(state.tr, {
83
+ ghostText: text,
84
+ ghostPosition: position,
85
+ decorationSet: decorationSet
86
+ });
87
+ dispatch(tr);
88
+ } catch (error) {
89
+ (0, _monitoring.logException)(error, {
90
+ location: 'editor-plugin-autocomplete/showGhostText'
91
+ });
92
+ }
83
93
  };
84
94
 
85
95
  /**
@@ -91,12 +101,19 @@ var clearGhostText = function clearGhostText(state, dispatch) {
91
101
  return false;
92
102
  }
93
103
  if (dispatch) {
94
- var tr = setAutocompleteMeta(state.tr, {
95
- ghostText: '',
96
- ghostPosition: -1,
97
- decorationSet: _view.DecorationSet.empty
98
- });
99
- dispatch(tr);
104
+ try {
105
+ var tr = setAutocompleteMeta(state.tr, {
106
+ ghostText: '',
107
+ ghostPosition: -1,
108
+ decorationSet: _view.DecorationSet.empty
109
+ });
110
+ dispatch(tr);
111
+ } catch (error) {
112
+ (0, _monitoring.logException)(error, {
113
+ location: 'editor-plugin-autocomplete/clearGhostText'
114
+ });
115
+ return false;
116
+ }
100
117
  }
101
118
  return true;
102
119
  };
@@ -110,15 +127,22 @@ var acceptGhostText = function acceptGhostText(state, dispatch) {
110
127
  return false;
111
128
  }
112
129
  if (dispatch) {
113
- var ghostText = pluginState.ghostText,
114
- ghostPosition = pluginState.ghostPosition;
115
- var tr = state.tr.insertText(ghostText, ghostPosition);
116
- tr = setAutocompleteMeta(tr, {
117
- ghostText: '',
118
- ghostPosition: -1,
119
- decorationSet: _view.DecorationSet.empty
120
- });
121
- dispatch(tr);
130
+ try {
131
+ var ghostText = pluginState.ghostText,
132
+ ghostPosition = pluginState.ghostPosition;
133
+ var tr = state.tr.insertText(ghostText, ghostPosition);
134
+ tr = setAutocompleteMeta(tr, {
135
+ ghostText: '',
136
+ ghostPosition: -1,
137
+ decorationSet: _view.DecorationSet.empty
138
+ });
139
+ dispatch(tr);
140
+ } catch (error) {
141
+ (0, _monitoring.logException)(error, {
142
+ location: 'editor-plugin-autocomplete/acceptGhostText'
143
+ });
144
+ return false;
145
+ }
122
146
  }
123
147
  return true;
124
148
  };
@@ -177,12 +201,23 @@ var createAutocompletePlugin = exports.createAutocompletePlugin = function creat
177
201
  var dismissedContext = null;
178
202
  var lastSuggestionTypedLength = 0;
179
203
  var lastSuggestionLength = 0;
180
- var fireSuggestionInsertedAnalytics = function fireSuggestionInsertedAnalytics(ghostText) {
204
+ var fireSuggestionDismissedAnalytics = function fireSuggestionDismissedAnalytics(reason) {
181
205
  var _api$analytics;
206
+ api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || _api$analytics.actions.fireAnalyticsEvent({
207
+ action: _analytics.ACTION.SUGGESTION_DISMISSED,
208
+ actionSubject: _analytics.ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
209
+ eventType: _analytics.EVENT_TYPE.TRACK,
210
+ attributes: {
211
+ reason: reason
212
+ }
213
+ });
214
+ };
215
+ var fireSuggestionInsertedAnalytics = function fireSuggestionInsertedAnalytics(ghostText) {
216
+ var _api$analytics2;
182
217
  var typedLength = lastSuggestionTypedLength;
183
218
  var suggestionLength = lastSuggestionLength || typedLength + ghostText.length;
184
219
  var kssDelta = suggestionLength - typedLength;
185
- api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || _api$analytics.actions.fireAnalyticsEvent({
220
+ api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 || _api$analytics2.actions.fireAnalyticsEvent({
186
221
  action: _analytics.ACTION.SUGGESTION_INSERTED,
187
222
  actionSubject: _analytics.ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
188
223
  eventType: _analytics.EVENT_TYPE.TRACK,
@@ -193,9 +228,11 @@ var createAutocompletePlugin = exports.createAutocompletePlugin = function creat
193
228
  }
194
229
  });
195
230
  };
196
- var slowLaneClient = (0, _slowLaneClient.createSlowLaneClient)({
231
+ var slowLaneClient = options !== null && options !== void 0 && options.useLocalModel ? (0, _localSlowLaneClient.createLocalSlowLaneClient)({
232
+ debounceMs: 300
233
+ }) : (0, _slowLaneClient.createSlowLaneClient)({
197
234
  baseUrl: '',
198
- endpoint: SLOW_LANE_ENDPOINT
235
+ debounceMs: 300
199
236
  });
200
237
  (0, _slowLaneClient.setDefaultSlowLaneClient)(slowLaneClient);
201
238
 
@@ -209,43 +246,49 @@ var createAutocompletePlugin = exports.createAutocompletePlugin = function creat
209
246
  clearTimeout(debounceTimer);
210
247
  }
211
248
  debounceTimer = setTimeout(function () {
212
- var state = view.state;
213
- var selection = state.selection;
249
+ try {
250
+ var state = view.state;
251
+ var selection = state.selection;
214
252
 
215
- // Only predict for cursor selections (not range selections)
216
- if (!selection.empty) {
217
- return;
218
- }
219
- var textBefore = getTextBeforeCursor(state);
253
+ // Only predict for cursor selections (not range selections)
254
+ if (!selection.empty) {
255
+ return;
256
+ }
257
+ var textBefore = getTextBeforeCursor(state);
220
258
 
221
- // Suppress re-showing the same suggestion the user just dismissed.
222
- // Once the text context changes (user types or deletes), this clears automatically.
223
- if (textBefore === dismissedContext) {
224
- return;
225
- }
226
- dismissedContext = null;
259
+ // Suppress re-showing the same suggestion the user just dismissed.
260
+ // Once the text context changes (user types or deletes), this clears automatically.
261
+ if (textBefore === dismissedContext) {
262
+ return;
263
+ }
264
+ dismissedContext = null;
227
265
 
228
- // Don't predict if there's not enough context
229
- if (textBefore.trim().length < 3) {
230
- return;
231
- }
266
+ // Don't predict if there's not enough context
267
+ if (textBefore.trim().length < 3) {
268
+ return;
269
+ }
232
270
 
233
- // Tier 1 prediction is synchronous -- no async needed
234
- var prediction = (0, _textPredictor.predict)(textBefore);
235
- if (prediction && prediction.length > 0) {
236
- var typedLength = getTypedLengthForPrediction(textBefore);
237
- lastSuggestionTypedLength = typedLength;
238
- lastSuggestionLength = typedLength + prediction.length;
239
- showGhostText(view, prediction, selection.from);
240
- if (prediction !== lastShownGhostText) {
241
- var _api$analytics2;
242
- lastShownGhostText = prediction;
243
- api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 || _api$analytics2.actions.fireAnalyticsEvent({
244
- action: _analytics.ACTION.SUGGESTION_VIEWED,
245
- actionSubject: _analytics.ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
246
- eventType: _analytics.EVENT_TYPE.TRACK
247
- });
271
+ // Tier 1 prediction is synchronous -- no async needed
272
+ var prediction = (0, _textPredictor.predict)(textBefore);
273
+ if (prediction && prediction.length > 0) {
274
+ var typedLength = getTypedLengthForPrediction(textBefore);
275
+ lastSuggestionTypedLength = typedLength;
276
+ lastSuggestionLength = typedLength + prediction.length;
277
+ showGhostText(view, prediction, selection.from);
278
+ if (prediction !== lastShownGhostText) {
279
+ var _api$analytics3;
280
+ lastShownGhostText = prediction;
281
+ api === null || api === void 0 || (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 || _api$analytics3.actions.fireAnalyticsEvent({
282
+ action: _analytics.ACTION.SUGGESTION_VIEWED,
283
+ actionSubject: _analytics.ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
284
+ eventType: _analytics.EVENT_TYPE.TRACK
285
+ });
286
+ }
248
287
  }
288
+ } catch (error) {
289
+ (0, _monitoring.logException)(error, {
290
+ location: 'editor-plugin-autocomplete/schedulePrediction'
291
+ });
249
292
  }
250
293
  }, DEBOUNCE_MS);
251
294
  };
@@ -343,6 +386,7 @@ var createAutocompletePlugin = exports.createAutocompletePlugin = function creat
343
386
  var didClear = clearGhostText(state, dispatch);
344
387
  if (didClear) {
345
388
  dismissedContext = getTextBeforeCursor(state);
389
+ fireSuggestionDismissedAnalytics('escape');
346
390
  }
347
391
  return didClear;
348
392
  }
@@ -352,14 +396,25 @@ var createAutocompletePlugin = exports.createAutocompletePlugin = function creat
352
396
  var pluginState = autocompletePluginKey.getState(view.state);
353
397
  if (pluginState !== null && pluginState !== void 0 && pluginState.ghostText) {
354
398
  clearGhostText(view.state, view.dispatch);
399
+ fireSuggestionDismissedAnalytics('blur');
355
400
  }
356
401
  return false;
357
402
  },
358
403
  focus: function focus() {
359
- (0, _textPredictor.loadDefaultVocabulary)();
404
+ try {
405
+ (0, _textPredictor.loadDefaultVocabulary)();
406
+ } catch (error) {
407
+ (0, _monitoring.logException)(error, {
408
+ location: 'editor-plugin-autocomplete/loadDefaultVocabulary'
409
+ });
410
+ }
360
411
  (0, _textPredictor.loadVectorsAsync)({
361
412
  getBinaryUrl: options === null || options === void 0 ? void 0 : options.getVectorsBinaryUrl
362
- }).catch(function () {});
413
+ }).catch(function (error) {
414
+ (0, _monitoring.logException)(error, {
415
+ location: 'editor-plugin-autocomplete/loadVectorsAsync'
416
+ });
417
+ });
363
418
  if (!hasIngestedPage) {
364
419
  hasIngestedPage = true;
365
420
  if (options !== null && options !== void 0 && options.getContext) {
@@ -376,7 +431,11 @@ var createAutocompletePlugin = exports.createAutocompletePlugin = function creat
376
431
  (0, _textPredictor.ingestDocumentPage)(context.parentCommentContent);
377
432
  }
378
433
  (_context$siblingComme4 = context.siblingCommentsContents) === null || _context$siblingComme4 === void 0 || _context$siblingComme4.forEach(_textPredictor.ingestDocumentPage);
379
- }).catch(function () {});
434
+ }).catch(function (error) {
435
+ (0, _monitoring.logException)(error, {
436
+ location: 'editor-plugin-autocomplete/getContext'
437
+ });
438
+ });
380
439
  }
381
440
  }
382
441
  return false;
@@ -413,6 +472,9 @@ var createAutocompletePlugin = exports.createAutocompletePlugin = function creat
413
472
  if (debounceTimer) {
414
473
  clearTimeout(debounceTimer);
415
474
  }
475
+ if (hasDestroy(slowLaneClient)) {
476
+ slowLaneClient.destroy();
477
+ }
416
478
  (0, _slowLaneClient.setDefaultSlowLaneClient)(null);
417
479
  }
418
480
  };