@atlaskit/editor-plugin-autocomplete 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @atlaskit/editor-plugin-autocomplete
2
2
 
3
+ ## 2.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`6eb5747f5ba37`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/6eb5747f5ba37) -
8
+ Add SAR analytics for autocomplete plugin
9
+
10
+ ### Patch Changes
11
+
12
+ - Updated dependencies
13
+
3
14
  ## 2.1.0
4
15
 
5
16
  ### Minor Changes
@@ -25,6 +25,9 @@
25
25
  },
26
26
  {
27
27
  "path": "../../editor-common/afm-cc/tsconfig.json"
28
+ },
29
+ {
30
+ "path": "../../editor-plugin-analytics/afm-cc/tsconfig.json"
28
31
  }
29
32
  ]
30
33
  }
@@ -25,6 +25,9 @@
25
25
  },
26
26
  {
27
27
  "path": "../../editor-common/afm-products/tsconfig.json"
28
+ },
29
+ {
30
+ "path": "../../editor-plugin-analytics/afm-products/tsconfig.json"
28
31
  }
29
32
  ]
30
33
  }
@@ -6,7 +6,8 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.autocompletePlugin = void 0;
7
7
  var _autocompletePlugin = require("./pm-plugins/autocomplete-plugin");
8
8
  var autocompletePlugin = exports.autocompletePlugin = function autocompletePlugin(_ref) {
9
- var options = _ref.config;
9
+ var options = _ref.config,
10
+ api = _ref.api;
10
11
  return {
11
12
  name: 'autocomplete',
12
13
  getSharedState: function getSharedState(editorState) {
@@ -19,7 +20,7 @@ var autocompletePlugin = exports.autocompletePlugin = function autocompletePlugi
19
20
  return [{
20
21
  name: 'autocomplete',
21
22
  plugin: function plugin() {
22
- return (0, _autocompletePlugin.createAutocompletePlugin)(options);
23
+ return (0, _autocompletePlugin.createAutocompletePlugin)(options, api);
23
24
  }
24
25
  }];
25
26
  }
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.createAutocompletePlugin = exports.autocompletePluginKey = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _analytics = require("@atlaskit/editor-common/analytics");
9
10
  var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
10
11
  var _keymap = require("@atlaskit/editor-prosemirror/keymap");
11
12
  var _state = require("@atlaskit/editor-prosemirror/state");
@@ -68,6 +69,7 @@ var setAutocompleteMeta = function setAutocompleteMeta(tr, meta) {
68
69
  /**
69
70
  * Apply a ghost text suggestion to the editor state.
70
71
  */
72
+ var lastShownGhostText = '';
71
73
  var showGhostText = function showGhostText(view, text, position) {
72
74
  var state = view.state,
73
75
  dispatch = view.dispatch;
@@ -146,7 +148,7 @@ var buildSlowLaneText = function buildSlowLaneText(docText, context) {
146
148
  lines.push("reply ".concat(nextReplyNumber, ": ").concat(docText));
147
149
  return lines.join('\n');
148
150
  };
149
- var createAutocompletePlugin = exports.createAutocompletePlugin = function createAutocompletePlugin(options) {
151
+ var createAutocompletePlugin = exports.createAutocompletePlugin = function createAutocompletePlugin(options, api) {
150
152
  var debounceTimer = null;
151
153
  var hasIngestedPage = false;
152
154
  var resolvedContext;
@@ -204,6 +206,15 @@ var createAutocompletePlugin = exports.createAutocompletePlugin = function creat
204
206
  var prediction = (0, _textPredictor.predict)(textBefore);
205
207
  if (prediction && prediction.length > 0) {
206
208
  showGhostText(view, prediction, selection.from);
209
+ if (prediction !== lastShownGhostText) {
210
+ var _api$analytics;
211
+ lastShownGhostText = prediction;
212
+ api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || _api$analytics.actions.fireAnalyticsEvent({
213
+ action: _analytics.ACTION.SUGGESTION_VIEWED,
214
+ actionSubject: _analytics.ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
215
+ eventType: _analytics.EVENT_TYPE.TRACK
216
+ });
217
+ }
207
218
  }
208
219
  }, DEBOUNCE_MS);
209
220
  };
@@ -275,12 +286,30 @@ var createAutocompletePlugin = exports.createAutocompletePlugin = function creat
275
286
  handleKeyDown: (0, _keymap.keydownHandler)({
276
287
  Tab: function Tab(state, dispatch) {
277
288
  var accepted = acceptGhostText(state, dispatch);
278
- if (accepted) justAccepted = true;
289
+ if (accepted) {
290
+ var _api$analytics2;
291
+ justAccepted = true;
292
+ lastShownGhostText = '';
293
+ api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 || _api$analytics2.actions.fireAnalyticsEvent({
294
+ action: _analytics.ACTION.SUGGESTION_INSERTED,
295
+ actionSubject: _analytics.ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
296
+ eventType: _analytics.EVENT_TYPE.TRACK
297
+ });
298
+ }
279
299
  return accepted;
280
300
  },
281
301
  ArrowRight: function ArrowRight(state, dispatch) {
282
302
  var accepted = acceptGhostText(state, dispatch);
283
- if (accepted) justAccepted = true;
303
+ if (accepted) {
304
+ var _api$analytics3;
305
+ justAccepted = true;
306
+ lastShownGhostText = '';
307
+ api === null || api === void 0 || (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 || _api$analytics3.actions.fireAnalyticsEvent({
308
+ action: _analytics.ACTION.SUGGESTION_INSERTED,
309
+ actionSubject: _analytics.ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
310
+ eventType: _analytics.EVENT_TYPE.TRACK
311
+ });
312
+ }
284
313
  return accepted;
285
314
  },
286
315
  Escape: function Escape(state, dispatch) {
@@ -1,6 +1,7 @@
1
1
  import { autocompletePluginKey, createAutocompletePlugin } from './pm-plugins/autocomplete-plugin';
2
2
  export const autocompletePlugin = ({
3
- config: options
3
+ config: options,
4
+ api
4
5
  }) => {
5
6
  return {
6
7
  name: 'autocomplete',
@@ -13,7 +14,7 @@ export const autocompletePlugin = ({
13
14
  pmPlugins() {
14
15
  return [{
15
16
  name: 'autocomplete',
16
- plugin: () => createAutocompletePlugin(options)
17
+ plugin: () => createAutocompletePlugin(options, api)
17
18
  }];
18
19
  }
19
20
  };
@@ -1,3 +1,4 @@
1
+ import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
1
2
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
3
  import { keydownHandler } from '@atlaskit/editor-prosemirror/keymap';
3
4
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
@@ -58,6 +59,7 @@ const setAutocompleteMeta = (tr, meta) => {
58
59
  /**
59
60
  * Apply a ghost text suggestion to the editor state.
60
61
  */
62
+ let lastShownGhostText = '';
61
63
  const showGhostText = (view, text, position) => {
62
64
  const {
63
65
  state,
@@ -140,7 +142,7 @@ const buildSlowLaneText = (docText, context) => {
140
142
  lines.push(`reply ${nextReplyNumber}: ${docText}`);
141
143
  return lines.join('\n');
142
144
  };
143
- export const createAutocompletePlugin = options => {
145
+ export const createAutocompletePlugin = (options, api) => {
144
146
  let debounceTimer = null;
145
147
  let hasIngestedPage = false;
146
148
  let resolvedContext;
@@ -202,6 +204,15 @@ export const createAutocompletePlugin = options => {
202
204
  const prediction = predict(textBefore);
203
205
  if (prediction && prediction.length > 0) {
204
206
  showGhostText(view, prediction, selection.from);
207
+ if (prediction !== lastShownGhostText) {
208
+ var _api$analytics;
209
+ lastShownGhostText = prediction;
210
+ api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions.fireAnalyticsEvent({
211
+ action: ACTION.SUGGESTION_VIEWED,
212
+ actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
213
+ eventType: EVENT_TYPE.TRACK
214
+ });
215
+ }
205
216
  }
206
217
  }, DEBOUNCE_MS);
207
218
  };
@@ -276,12 +287,30 @@ export const createAutocompletePlugin = options => {
276
287
  handleKeyDown: keydownHandler({
277
288
  Tab: (state, dispatch) => {
278
289
  const accepted = acceptGhostText(state, dispatch);
279
- if (accepted) justAccepted = true;
290
+ if (accepted) {
291
+ var _api$analytics2;
292
+ justAccepted = true;
293
+ lastShownGhostText = '';
294
+ api === null || api === void 0 ? void 0 : (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions.fireAnalyticsEvent({
295
+ action: ACTION.SUGGESTION_INSERTED,
296
+ actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
297
+ eventType: EVENT_TYPE.TRACK
298
+ });
299
+ }
280
300
  return accepted;
281
301
  },
282
302
  ArrowRight: (state, dispatch) => {
283
303
  const accepted = acceptGhostText(state, dispatch);
284
- if (accepted) justAccepted = true;
304
+ if (accepted) {
305
+ var _api$analytics3;
306
+ justAccepted = true;
307
+ lastShownGhostText = '';
308
+ api === null || api === void 0 ? void 0 : (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions.fireAnalyticsEvent({
309
+ action: ACTION.SUGGESTION_INSERTED,
310
+ actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
311
+ eventType: EVENT_TYPE.TRACK
312
+ });
313
+ }
285
314
  return accepted;
286
315
  },
287
316
  Escape: (state, dispatch) => {
@@ -1,6 +1,7 @@
1
1
  import { autocompletePluginKey, createAutocompletePlugin } from './pm-plugins/autocomplete-plugin';
2
2
  export var autocompletePlugin = function autocompletePlugin(_ref) {
3
- var options = _ref.config;
3
+ var options = _ref.config,
4
+ api = _ref.api;
4
5
  return {
5
6
  name: 'autocomplete',
6
7
  getSharedState: function getSharedState(editorState) {
@@ -13,7 +14,7 @@ export var autocompletePlugin = function autocompletePlugin(_ref) {
13
14
  return [{
14
15
  name: 'autocomplete',
15
16
  plugin: function plugin() {
16
- return createAutocompletePlugin(options);
17
+ return createAutocompletePlugin(options, api);
17
18
  }
18
19
  }];
19
20
  }
@@ -1,6 +1,7 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  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; }
3
3
  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) { _defineProperty(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; }
4
+ import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
4
5
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
5
6
  import { keydownHandler } from '@atlaskit/editor-prosemirror/keymap';
6
7
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
@@ -61,6 +62,7 @@ var setAutocompleteMeta = function setAutocompleteMeta(tr, meta) {
61
62
  /**
62
63
  * Apply a ghost text suggestion to the editor state.
63
64
  */
65
+ var lastShownGhostText = '';
64
66
  var showGhostText = function showGhostText(view, text, position) {
65
67
  var state = view.state,
66
68
  dispatch = view.dispatch;
@@ -139,7 +141,7 @@ var buildSlowLaneText = function buildSlowLaneText(docText, context) {
139
141
  lines.push("reply ".concat(nextReplyNumber, ": ").concat(docText));
140
142
  return lines.join('\n');
141
143
  };
142
- export var createAutocompletePlugin = function createAutocompletePlugin(options) {
144
+ export var createAutocompletePlugin = function createAutocompletePlugin(options, api) {
143
145
  var debounceTimer = null;
144
146
  var hasIngestedPage = false;
145
147
  var resolvedContext;
@@ -197,6 +199,15 @@ export var createAutocompletePlugin = function createAutocompletePlugin(options)
197
199
  var prediction = predict(textBefore);
198
200
  if (prediction && prediction.length > 0) {
199
201
  showGhostText(view, prediction, selection.from);
202
+ if (prediction !== lastShownGhostText) {
203
+ var _api$analytics;
204
+ lastShownGhostText = prediction;
205
+ api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || _api$analytics.actions.fireAnalyticsEvent({
206
+ action: ACTION.SUGGESTION_VIEWED,
207
+ actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
208
+ eventType: EVENT_TYPE.TRACK
209
+ });
210
+ }
200
211
  }
201
212
  }, DEBOUNCE_MS);
202
213
  };
@@ -268,12 +279,30 @@ export var createAutocompletePlugin = function createAutocompletePlugin(options)
268
279
  handleKeyDown: keydownHandler({
269
280
  Tab: function Tab(state, dispatch) {
270
281
  var accepted = acceptGhostText(state, dispatch);
271
- if (accepted) justAccepted = true;
282
+ if (accepted) {
283
+ var _api$analytics2;
284
+ justAccepted = true;
285
+ lastShownGhostText = '';
286
+ api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 || _api$analytics2.actions.fireAnalyticsEvent({
287
+ action: ACTION.SUGGESTION_INSERTED,
288
+ actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
289
+ eventType: EVENT_TYPE.TRACK
290
+ });
291
+ }
272
292
  return accepted;
273
293
  },
274
294
  ArrowRight: function ArrowRight(state, dispatch) {
275
295
  var accepted = acceptGhostText(state, dispatch);
276
- if (accepted) justAccepted = true;
296
+ if (accepted) {
297
+ var _api$analytics3;
298
+ justAccepted = true;
299
+ lastShownGhostText = '';
300
+ api === null || api === void 0 || (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 || _api$analytics3.actions.fireAnalyticsEvent({
301
+ action: ACTION.SUGGESTION_INSERTED,
302
+ actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
303
+ eventType: EVENT_TYPE.TRACK
304
+ });
305
+ }
277
306
  return accepted;
278
307
  },
279
308
  Escape: function Escape(state, dispatch) {
@@ -1,6 +1,8 @@
1
- import type { NextEditorPlugin } from '@atlaskit/editor-common/types';
1
+ import type { NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
2
+ import type { AnalyticsPlugin } from '@atlaskit/editor-plugin-analytics';
2
3
  import type { AutocompletePluginOptions, AutocompletePluginState } from './pm-plugins/autocomplete-plugin';
3
4
  export type AutocompletePlugin = NextEditorPlugin<'autocomplete', {
4
5
  pluginConfiguration?: AutocompletePluginOptions | undefined;
5
6
  sharedState: AutocompletePluginState | undefined;
7
+ dependencies: [OptionalPlugin<AnalyticsPlugin>];
6
8
  }>;
@@ -1,6 +1,8 @@
1
1
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
+ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
3
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
3
4
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
5
+ import type { AutocompletePlugin } from '../autocompletePluginType';
4
6
  export declare const autocompletePluginKey: PluginKey<any>;
5
7
  export interface AutocompletePluginState {
6
8
  /** The decoration set containing the ghost text widget */
@@ -39,4 +41,4 @@ export interface AutocompletePluginOptions {
39
41
  */
40
42
  getVectorsBinaryUrl?: () => Promise<string>;
41
43
  }
42
- export declare const createAutocompletePlugin: (options?: AutocompletePluginOptions) => SafePlugin<AutocompletePluginState>;
44
+ export declare const createAutocompletePlugin: (options?: AutocompletePluginOptions, api?: ExtractInjectionAPI<AutocompletePlugin>) => SafePlugin<AutocompletePluginState>;
@@ -1,6 +1,10 @@
1
- import type { NextEditorPlugin } from '@atlaskit/editor-common/types';
1
+ import type { NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
2
+ import type { AnalyticsPlugin } from '@atlaskit/editor-plugin-analytics';
2
3
  import type { AutocompletePluginOptions, AutocompletePluginState } from './pm-plugins/autocomplete-plugin';
3
4
  export type AutocompletePlugin = NextEditorPlugin<'autocomplete', {
4
5
  pluginConfiguration?: AutocompletePluginOptions | undefined;
5
6
  sharedState: AutocompletePluginState | undefined;
7
+ dependencies: [
8
+ OptionalPlugin<AnalyticsPlugin>
9
+ ];
6
10
  }>;
@@ -1,6 +1,8 @@
1
1
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
+ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
3
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
3
4
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
5
+ import type { AutocompletePlugin } from '../autocompletePluginType';
4
6
  export declare const autocompletePluginKey: PluginKey<any>;
5
7
  export interface AutocompletePluginState {
6
8
  /** The decoration set containing the ghost text widget */
@@ -39,4 +41,4 @@ export interface AutocompletePluginOptions {
39
41
  */
40
42
  getVectorsBinaryUrl?: () => Promise<string>;
41
43
  }
42
- export declare const createAutocompletePlugin: (options?: AutocompletePluginOptions) => SafePlugin<AutocompletePluginState>;
44
+ export declare const createAutocompletePlugin: (options?: AutocompletePluginOptions, api?: ExtractInjectionAPI<AutocompletePlugin>) => SafePlugin<AutocompletePluginState>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-autocomplete",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "description": "Client-side text autocomplete plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -33,7 +33,8 @@
33
33
  "wink-nlp": "^2.4.0"
34
34
  },
35
35
  "peerDependencies": {
36
- "@atlaskit/editor-common": "^114.1.0",
36
+ "@atlaskit/editor-common": "^114.5.0",
37
+ "@atlaskit/editor-plugin-analytics": "^10.0.0",
37
38
  "react": "^18.2.0"
38
39
  },
39
40
  "techstack": {
@@ -2,7 +2,7 @@ import type { AutocompletePlugin } from './autocompletePluginType';
2
2
  import { autocompletePluginKey, createAutocompletePlugin } from './pm-plugins/autocomplete-plugin';
3
3
  import type { AutocompletePluginState } from './pm-plugins/autocomplete-plugin';
4
4
 
5
- export const autocompletePlugin: AutocompletePlugin = ({ config: options }) => {
5
+ export const autocompletePlugin: AutocompletePlugin = ({ config: options, api }) => {
6
6
  return {
7
7
  name: 'autocomplete',
8
8
  getSharedState(editorState): AutocompletePluginState | undefined {
@@ -16,7 +16,7 @@ export const autocompletePlugin: AutocompletePlugin = ({ config: options }) => {
16
16
  return [
17
17
  {
18
18
  name: 'autocomplete',
19
- plugin: () => createAutocompletePlugin(options),
19
+ plugin: () => createAutocompletePlugin(options, api),
20
20
  },
21
21
  ];
22
22
  },
@@ -1,4 +1,5 @@
1
- import type { NextEditorPlugin } from '@atlaskit/editor-common/types';
1
+ import type { NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
2
+ import type { AnalyticsPlugin } from '@atlaskit/editor-plugin-analytics';
2
3
 
3
4
  import type {
4
5
  AutocompletePluginOptions,
@@ -10,5 +11,6 @@ export type AutocompletePlugin = NextEditorPlugin<
10
11
  {
11
12
  pluginConfiguration?: AutocompletePluginOptions | undefined;
12
13
  sharedState: AutocompletePluginState | undefined;
14
+ dependencies: [OptionalPlugin<AnalyticsPlugin>];
13
15
  }
14
16
  >;
@@ -1,4 +1,6 @@
1
+ import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
1
2
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
3
+ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
4
  import { keydownHandler } from '@atlaskit/editor-prosemirror/keymap';
3
5
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
4
6
  import type {
@@ -9,6 +11,8 @@ import type {
9
11
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
10
12
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
11
13
 
14
+ import type { AutocompletePlugin } from '../autocompletePluginType';
15
+
12
16
  import { createGhostTextDecorationSet } from './ghost-text-decoration';
13
17
  import { createSlowLaneClient, setDefaultSlowLaneClient, isWordBoundary } from './slow-lane-client';
14
18
  import {
@@ -90,6 +94,8 @@ const setAutocompleteMeta = (
90
94
  /**
91
95
  * Apply a ghost text suggestion to the editor state.
92
96
  */
97
+ let lastShownGhostText = '';
98
+
93
99
  const showGhostText = (view: EditorView, text: string, position: number): void => {
94
100
  const { state, dispatch } = view;
95
101
  const decorationSet = createGhostTextDecorationSet(state, position, text);
@@ -196,7 +202,7 @@ const buildSlowLaneText = (docText: string, context?: AutocompleteContext): stri
196
202
  return lines.join('\n');
197
203
  };
198
204
 
199
- export const createAutocompletePlugin = (options?: AutocompletePluginOptions) => {
205
+ export const createAutocompletePlugin = (options?: AutocompletePluginOptions, api?: ExtractInjectionAPI<AutocompletePlugin>) => {
200
206
  let debounceTimer: ReturnType<typeof setTimeout> | null = null;
201
207
  let hasIngestedPage = false;
202
208
  let resolvedContext: AutocompleteContext | undefined;
@@ -258,6 +264,14 @@ export const createAutocompletePlugin = (options?: AutocompletePluginOptions) =>
258
264
 
259
265
  if (prediction && prediction.length > 0) {
260
266
  showGhostText(view, prediction, selection.from);
267
+ if (prediction !== lastShownGhostText) {
268
+ lastShownGhostText = prediction;
269
+ api?.analytics?.actions.fireAnalyticsEvent({
270
+ action: ACTION.SUGGESTION_VIEWED,
271
+ actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
272
+ eventType: EVENT_TYPE.TRACK,
273
+ });
274
+ }
261
275
  }
262
276
  }, DEBOUNCE_MS);
263
277
  };
@@ -346,12 +360,28 @@ export const createAutocompletePlugin = (options?: AutocompletePluginOptions) =>
346
360
  handleKeyDown: keydownHandler({
347
361
  Tab: (state: EditorState, dispatch?: (tr: Transaction) => void) => {
348
362
  const accepted = acceptGhostText(state, dispatch);
349
- if (accepted) justAccepted = true;
363
+ if (accepted) {
364
+ justAccepted = true;
365
+ lastShownGhostText = '';
366
+ api?.analytics?.actions.fireAnalyticsEvent({
367
+ action: ACTION.SUGGESTION_INSERTED,
368
+ actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
369
+ eventType: EVENT_TYPE.TRACK,
370
+ });
371
+ }
350
372
  return accepted;
351
373
  },
352
374
  ArrowRight: (state: EditorState, dispatch?: (tr: Transaction) => void) => {
353
375
  const accepted = acceptGhostText(state, dispatch);
354
- if (accepted) justAccepted = true;
376
+ if (accepted) {
377
+ justAccepted = true;
378
+ lastShownGhostText = '';
379
+ api?.analytics?.actions.fireAnalyticsEvent({
380
+ action: ACTION.SUGGESTION_INSERTED,
381
+ actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
382
+ eventType: EVENT_TYPE.TRACK,
383
+ });
384
+ }
355
385
  return accepted;
356
386
  },
357
387
  Escape: (state: EditorState, dispatch?: (tr: Transaction) => void) => {
@@ -537,11 +537,13 @@ export const predict = (textBefore: string): string | null => {
537
537
  // lmMax in rankCandidates reflects prefix-relevant signal, not the global distribution.
538
538
  const prefix = currentWord.toLowerCase();
539
539
  const prefixLmLogits = lmLogits
540
- ? Object.fromEntries(
541
- Object.entries(lmLogits).filter(([word]) => word.startsWith(prefix))
542
- )
540
+ ? Object.fromEntries(Object.entries(lmLogits).filter(([word]) => word.startsWith(prefix)))
543
541
  : null;
544
- const { candidates: ranked, grammarMeta, pipelineDebug } = rankCandidates(
542
+ const {
543
+ candidates: ranked,
544
+ grammarMeta,
545
+ pipelineDebug,
546
+ } = rankCandidates(
545
547
  scoringCandidates,
546
548
  contextVector,
547
549
  (w: string) => getWordVector(w),
package/tsconfig.app.json CHANGED
@@ -35,6 +35,9 @@
35
35
  {
36
36
  "path": "../editor-common/tsconfig.app.json"
37
37
  },
38
+ {
39
+ "path": "../editor-plugin-analytics/tsconfig.app.json"
40
+ },
38
41
  {
39
42
  "path": "../editor-prosemirror/tsconfig.app.json"
40
43
  }