@atlaskit/editor-plugin-autocomplete 2.1.0 → 2.3.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 (37) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/afm-cc/tsconfig.json +3 -1
  3. package/afm-products/tsconfig.json +3 -1
  4. package/build/tsconfig.json +0 -1
  5. package/dist/cjs/autocompletePlugin.js +3 -2
  6. package/dist/cjs/pm-plugins/autocomplete-plugin.js +59 -3
  7. package/dist/cjs/pm-plugins/debug-mode.js +24 -0
  8. package/dist/cjs/pm-plugins/slow-lane-client.js +42 -35
  9. package/dist/cjs/pm-plugins/text-predictor.js +12 -32
  10. package/dist/es2019/autocompletePlugin.js +3 -2
  11. package/dist/es2019/pm-plugins/autocomplete-plugin.js +59 -3
  12. package/dist/es2019/pm-plugins/debug-mode.js +18 -0
  13. package/dist/es2019/pm-plugins/slow-lane-client.js +29 -23
  14. package/dist/es2019/pm-plugins/text-predictor.js +6 -26
  15. package/dist/esm/autocompletePlugin.js +3 -2
  16. package/dist/esm/pm-plugins/autocomplete-plugin.js +59 -3
  17. package/dist/esm/pm-plugins/debug-mode.js +18 -0
  18. package/dist/esm/pm-plugins/slow-lane-client.js +43 -35
  19. package/dist/esm/pm-plugins/text-predictor.js +11 -31
  20. package/dist/types/autocompletePluginType.d.ts +3 -1
  21. package/dist/types/pm-plugins/autocomplete-plugin.d.ts +4 -2
  22. package/dist/types/pm-plugins/debug-mode.d.ts +12 -0
  23. package/dist/types/pm-plugins/text-predictor.d.ts +0 -2
  24. package/dist/types-ts4.5/autocompletePluginType.d.ts +5 -1
  25. package/dist/types-ts4.5/pm-plugins/autocomplete-plugin.d.ts +4 -2
  26. package/dist/types-ts4.5/pm-plugins/debug-mode.d.ts +12 -0
  27. package/dist/types-ts4.5/pm-plugins/text-predictor.d.ts +0 -2
  28. package/package.json +3 -2
  29. package/src/autocompletePlugin.tsx +2 -2
  30. package/src/autocompletePluginType.ts +3 -1
  31. package/src/pm-plugins/autocomplete-plugin.ts +70 -4
  32. package/src/pm-plugins/debug-mode.ts +18 -0
  33. package/src/pm-plugins/slow-lane-client.ts +53 -45
  34. package/src/pm-plugins/text-predictor.ts +12 -34
  35. package/tsconfig.app.json +6 -1
  36. package/tsconfig.dev.json +2 -1
  37. package/afm-jira/tsconfig.json +0 -30
@@ -33,8 +33,6 @@ interface VectorStore {
33
33
  * expects a simple array of strings: ["about", "above", "actually", ...]
34
34
  */
35
35
  export declare const initL3Vocabulary: (l3Words: string[]) => void;
36
- /** Enable or disable debug logging. Also checks localStorage key `autocomplete-debug`. */
37
- export declare const setDebugMode: (enabled: boolean) => void;
38
36
  /**
39
37
  * Get predictor status for debugging.
40
38
  * vectorsLoaded: true when semantic scoring is active
@@ -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,7 +1,9 @@
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';
4
- export declare const autocompletePluginKey: PluginKey<any>;
5
+ import type { AutocompletePlugin } from '../autocompletePluginType';
6
+ export declare const autocompletePluginKey: PluginKey;
5
7
  export interface AutocompletePluginState {
6
8
  /** The decoration set containing the ghost text widget */
7
9
  decorationSet: DecorationSet;
@@ -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>;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Contextual Typeahead Completions (CTC) debug logging utility.
3
+ *
4
+ * Logs are silent by default. To enable in any environment (dev, staging, prod):
5
+ *
6
+ * localStorage.setItem('atl-ctc-dbg', '1')
7
+ *
8
+ * Then reload the page. To disable:
9
+ *
10
+ * localStorage.removeItem('atl-ctc-dbg')
11
+ */
12
+ export declare const isAutocompleteDebugEnabled: () => boolean;
@@ -33,8 +33,6 @@ interface VectorStore {
33
33
  * expects a simple array of strings: ["about", "above", "actually", ...]
34
34
  */
35
35
  export declare const initL3Vocabulary: (l3Words: string[]) => void;
36
- /** Enable or disable debug logging. Also checks localStorage key `autocomplete-debug`. */
37
- export declare const setDebugMode: (enabled: boolean) => void;
38
36
  /**
39
37
  * Get predictor status for debugging.
40
38
  * vectorsLoaded: true when semantic scoring is active
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.3.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.22.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 {
@@ -21,7 +25,7 @@ import {
21
25
 
22
26
  const SLOW_LANE_ENDPOINT = '/gateway/api/v1/autocomplete/typeahead-encodings';
23
27
 
24
- export const autocompletePluginKey = new PluginKey('autocomplete');
28
+ export const autocompletePluginKey: PluginKey = new PluginKey('autocomplete');
25
29
 
26
30
  const DEBOUNCE_MS = 150;
27
31
 
@@ -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,20 @@ const buildSlowLaneText = (docText: string, context?: AutocompleteContext): stri
196
202
  return lines.join('\n');
197
203
  };
198
204
 
199
- export const createAutocompletePlugin = (options?: AutocompletePluginOptions) => {
205
+ const getTypedLengthForPrediction = (textBefore: string): number => {
206
+ if (isWordBoundary(textBefore)) {
207
+ return 0;
208
+ }
209
+
210
+ // eslint-disable-next-line require-unicode-regexp
211
+ const trailingToken = textBefore.match(/([^\s.,;:!?]*)$/)?.[1] ?? '';
212
+ return trailingToken.length;
213
+ };
214
+
215
+ export const createAutocompletePlugin = (
216
+ options?: AutocompletePluginOptions,
217
+ api?: ExtractInjectionAPI<AutocompletePlugin>,
218
+ ): SafePlugin<AutocompletePluginState> => {
200
219
  let debounceTimer: ReturnType<typeof setTimeout> | null = null;
201
220
  let hasIngestedPage = false;
202
221
  let resolvedContext: AutocompleteContext | undefined;
@@ -213,6 +232,25 @@ export const createAutocompletePlugin = (options?: AutocompletePluginOptions) =>
213
232
  * re-showing the same suggestion. Resets to null as soon as the text changes.
214
233
  */
215
234
  let dismissedContext: string | null = null;
235
+ let lastSuggestionTypedLength = 0;
236
+ let lastSuggestionLength = 0;
237
+
238
+ const fireSuggestionInsertedAnalytics = (ghostText: string): void => {
239
+ const typedLength = lastSuggestionTypedLength;
240
+ const suggestionLength = lastSuggestionLength || typedLength + ghostText.length;
241
+ const kssDelta = suggestionLength - typedLength;
242
+
243
+ api?.analytics?.actions.fireAnalyticsEvent({
244
+ action: ACTION.SUGGESTION_INSERTED,
245
+ actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
246
+ eventType: EVENT_TYPE.TRACK,
247
+ attributes: {
248
+ suggestionLength,
249
+ typedLength,
250
+ kssDelta,
251
+ },
252
+ });
253
+ };
216
254
 
217
255
  const slowLaneClient = createSlowLaneClient({
218
256
  baseUrl: '',
@@ -257,7 +295,19 @@ export const createAutocompletePlugin = (options?: AutocompletePluginOptions) =>
257
295
  const prediction = predict(textBefore);
258
296
 
259
297
  if (prediction && prediction.length > 0) {
298
+ const typedLength = getTypedLengthForPrediction(textBefore);
299
+ lastSuggestionTypedLength = typedLength;
300
+ lastSuggestionLength = typedLength + prediction.length;
301
+
260
302
  showGhostText(view, prediction, selection.from);
303
+ if (prediction !== lastShownGhostText) {
304
+ lastShownGhostText = prediction;
305
+ api?.analytics?.actions.fireAnalyticsEvent({
306
+ action: ACTION.SUGGESTION_VIEWED,
307
+ actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
308
+ eventType: EVENT_TYPE.TRACK,
309
+ });
310
+ }
261
311
  }
262
312
  }, DEBOUNCE_MS);
263
313
  };
@@ -345,13 +395,29 @@ export const createAutocompletePlugin = (options?: AutocompletePluginOptions) =>
345
395
 
346
396
  handleKeyDown: keydownHandler({
347
397
  Tab: (state: EditorState, dispatch?: (tr: Transaction) => void) => {
398
+ const pluginState = autocompletePluginKey.getState(state) as
399
+ | AutocompletePluginState
400
+ | undefined;
401
+ const ghostText = pluginState?.ghostText ?? '';
348
402
  const accepted = acceptGhostText(state, dispatch);
349
- if (accepted) justAccepted = true;
403
+ if (accepted) {
404
+ justAccepted = true;
405
+ lastShownGhostText = '';
406
+ fireSuggestionInsertedAnalytics(ghostText);
407
+ }
350
408
  return accepted;
351
409
  },
352
410
  ArrowRight: (state: EditorState, dispatch?: (tr: Transaction) => void) => {
411
+ const pluginState = autocompletePluginKey.getState(state) as
412
+ | AutocompletePluginState
413
+ | undefined;
414
+ const ghostText = pluginState?.ghostText ?? '';
353
415
  const accepted = acceptGhostText(state, dispatch);
354
- if (accepted) justAccepted = true;
416
+ if (accepted) {
417
+ justAccepted = true;
418
+ lastShownGhostText = '';
419
+ fireSuggestionInsertedAnalytics(ghostText);
420
+ }
355
421
  return accepted;
356
422
  },
357
423
  Escape: (state: EditorState, dispatch?: (tr: Transaction) => void) => {
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Contextual Typeahead Completions (CTC) debug logging utility.
3
+ *
4
+ * Logs are silent by default. To enable in any environment (dev, staging, prod):
5
+ *
6
+ * localStorage.setItem('atl-ctc-dbg', '1')
7
+ *
8
+ * Then reload the page. To disable:
9
+ *
10
+ * localStorage.removeItem('atl-ctc-dbg')
11
+ */
12
+ export const isAutocompleteDebugEnabled = (): boolean => {
13
+ try {
14
+ return typeof localStorage !== 'undefined' && localStorage.getItem('atl-ctc-dbg') === '1';
15
+ } catch {
16
+ return false;
17
+ }
18
+ };
@@ -7,6 +7,8 @@
7
7
  * Response: { semantic_vector: number[], lm_logits: Record<string, number> }
8
8
  */
9
9
 
10
+ import { isAutocompleteDebugEnabled } from './debug-mode';
11
+
10
12
  // ─── Types ───────────────────────────────────────────────────────────────────
11
13
 
12
14
  /** Request payload for typeahead-encodings endpoint. */
@@ -95,19 +97,20 @@ export const createSlowLaneClient = (
95
97
  session_id: sessionId,
96
98
  };
97
99
 
98
- // Log the exact payload being sent so the comment/reply structure is visible
99
- // eslint-disable-next-line no-console
100
- console.groupCollapsed(
101
- `%c[SlowLane] %c📤 Sending context | ${text.length} chars`,
102
- 'color: #9c27b0; font-weight: bold;',
103
- 'color: inherit;',
104
- );
105
- text.split('\n').forEach((line, i, arr) => {
100
+ if (isAutocompleteDebugEnabled()) {
101
+ // eslint-disable-next-line no-console
102
+ console.groupCollapsed(
103
+ `%c[SlowLane] %c📤 Sending context | ${text.length} chars`,
104
+ 'color: #9c27b0; font-weight: bold;',
105
+ 'color: inherit;',
106
+ );
107
+ text.split('\n').forEach((line, i, arr) => {
108
+ // eslint-disable-next-line no-console
109
+ console.log(` ${i === arr.length - 1 ? '▶' : ' '} ${line}`);
110
+ });
106
111
  // eslint-disable-next-line no-console
107
- console.log(` ${i === arr.length - 1 ? '▶' : ' '} ${line}`);
108
- });
109
- // eslint-disable-next-line no-console
110
- console.groupEnd();
112
+ console.groupEnd();
113
+ }
111
114
 
112
115
  try {
113
116
  const res = await fetchFn(url, {
@@ -119,12 +122,14 @@ export const createSlowLaneClient = (
119
122
  if (!res.ok) {
120
123
  storedContextVector = null;
121
124
  storedLmLogits = null;
122
- // eslint-disable-next-line no-console
123
- console.log(
124
- `%c[SlowLane] %c❌ Request failed (${res.status})`,
125
- 'color: #9c27b0; font-weight: bold;',
126
- 'color: #f44336;',
127
- );
125
+ if (isAutocompleteDebugEnabled()) {
126
+ // eslint-disable-next-line no-console
127
+ console.log(
128
+ `%c[SlowLane] %c❌ Request failed (${res.status})`,
129
+ 'color: #9c27b0; font-weight: bold;',
130
+ 'color: #f44336;',
131
+ );
132
+ }
128
133
  return;
129
134
  }
130
135
 
@@ -142,27 +147,28 @@ export const createSlowLaneClient = (
142
147
  storedLmLogits = null;
143
148
  }
144
149
 
145
- // Log what came back so it can be correlated with the next prediction group
146
- // eslint-disable-next-line no-console
147
- console.groupCollapsed(
148
- `%c[SlowLane] %c📥 Response received`,
149
- 'color: #9c27b0; font-weight: bold;',
150
- 'color: inherit;',
151
- );
152
- // eslint-disable-next-line no-console
153
- console.log(
154
- storedContextVector
155
- ? `✅ semantic_vector: ${storedContextVector.length} dims`
156
- : '❌ No semantic_vector',
157
- );
158
- // eslint-disable-next-line no-console
159
- console.log(
160
- storedLmLogits
161
- ? `✅ lm_logits: ${Object.keys(storedLmLogits).length} tokens`
162
- : '❌ No lm_logits',
163
- );
164
- // eslint-disable-next-line no-console
165
- console.groupEnd();
150
+ if (isAutocompleteDebugEnabled()) {
151
+ // eslint-disable-next-line no-console
152
+ console.groupCollapsed(
153
+ `%c[SlowLane] %c📥 Response received`,
154
+ 'color: #9c27b0; font-weight: bold;',
155
+ 'color: inherit;',
156
+ );
157
+ // eslint-disable-next-line no-console
158
+ console.log(
159
+ storedContextVector
160
+ ? `✅ semantic_vector: ${storedContextVector.length} dims`
161
+ : '❌ No semantic_vector',
162
+ );
163
+ // eslint-disable-next-line no-console
164
+ console.log(
165
+ storedLmLogits
166
+ ? `✅ lm_logits: ${Object.keys(storedLmLogits).length} tokens`
167
+ : '❌ No lm_logits',
168
+ );
169
+ // eslint-disable-next-line no-console
170
+ console.groupEnd();
171
+ }
166
172
 
167
173
  onUpdate?.({
168
174
  textLength: text.length,
@@ -173,12 +179,14 @@ export const createSlowLaneClient = (
173
179
  } catch (e) {
174
180
  storedContextVector = null;
175
181
  storedLmLogits = null;
176
- // eslint-disable-next-line no-console
177
- console.log(
178
- '%c[SlowLane] %c❌ Network error — context cleared',
179
- 'color: #9c27b0; font-weight: bold;',
180
- 'color: #f44336;',
181
- );
182
+ if (isAutocompleteDebugEnabled()) {
183
+ // eslint-disable-next-line no-console
184
+ console.log(
185
+ '%c[SlowLane] %c❌ Network error — context cleared',
186
+ 'color: #9c27b0; font-weight: bold;',
187
+ 'color: #f44336;',
188
+ );
189
+ }
182
190
  }
183
191
  };
184
192
 
@@ -20,6 +20,7 @@ import l3VocabularyData from './data/l3_vocabulary.json';
20
20
  import vocabularyData from './data/vocabulary_10k.json';
21
21
  import wordIndexData from './data/word_index_10k.json';
22
22
  // import { rankCandidates, isGrammarAllowed } from './scoring-pipeline';
23
+ import { isAutocompleteDebugEnabled } from './debug-mode';
23
24
  import { rankCandidates, STAGE1_WEIGHT, STAGE2_WEIGHT, MIN_STAGE1_SCORE } from './scoring-pipeline';
24
25
  import type { ScoringCandidate } from './scoring-pipeline';
25
26
  import { getStoredContextVector, getStoredLmLogits } from './slow-lane-client';
@@ -183,7 +184,7 @@ export const initL3Vocabulary = (l3Words: string[]): void => {
183
184
  // loses to any domain word in Stage 1, but still scores above 0.
184
185
  l3Trie.insert(word, L3_BASELINE_FREQ, 0, 0);
185
186
  }
186
- if (debugMode) {
187
+ if (isAutocompleteDebugEnabled()) {
187
188
  // eslint-disable-next-line no-console
188
189
  console.log(`[text-predictor] L3 General English loaded: ${l3Words.length} words`);
189
190
  }
@@ -199,8 +200,6 @@ let vectorStore: VectorStore | null = null;
199
200
 
200
201
  let vectorsLoadStarted = false;
201
202
 
202
- let debugMode = true;
203
-
204
203
  let lastPredictionDebug: {
205
204
  contextWords: string[];
206
205
  currentWord: string;
@@ -216,8 +215,6 @@ let lastPredictionDebug: {
216
215
  }>;
217
216
  } | null = null;
218
217
 
219
- let hasLoggedSemanticActive = false;
220
-
221
218
  /** Get vector for a word from the store. */
222
219
  const getWordVector = (word: string): Float32Array | null => {
223
220
  if (!vectorStore) {
@@ -306,18 +303,6 @@ const extractPreviousWord = (text: string): string => {
306
303
 
307
304
  // ─── Debug Helpers ───────────────────────────────────────────────────────────
308
305
 
309
- /** Enable or disable debug logging. Also checks localStorage key `autocomplete-debug`. */
310
- export const setDebugMode = (enabled: boolean): void => {
311
- debugMode = enabled;
312
- };
313
-
314
- /** Check localStorage for autocomplete-debug on first access. */
315
- const ensureDebugModeFromStorage = (): void => {
316
- if (typeof localStorage !== 'undefined' && localStorage.getItem('autocomplete-debug') === '1') {
317
- debugMode = true;
318
- }
319
- };
320
-
321
306
  /**
322
307
  * Get predictor status for debugging.
323
308
  * vectorsLoaded: true when semantic scoring is active
@@ -329,7 +314,6 @@ export const getPredictorStatus = (): {
329
314
  vectorsLoadStarted: boolean;
330
315
  wordCount: number;
331
316
  } => {
332
- ensureDebugModeFromStorage();
333
317
  return {
334
318
  vectorsLoaded: vectorStore !== null,
335
319
  wordCount: vectorStore ? Object.keys(vectorStore.wordIndex).length : 0,
@@ -356,7 +340,6 @@ export const getLastPredictionDebug = (): {
356
340
  word: string;
357
341
  }>;
358
342
  } | null => {
359
- ensureDebugModeFromStorage();
360
343
  return lastPredictionDebug;
361
344
  };
362
345
 
@@ -401,7 +384,7 @@ export const ingestDocumentPage = (pageContent: string | undefined): void => {
401
384
  }
402
385
  }
403
386
 
404
- if (debugMode && validBoostedWords.size > 0) {
387
+ if (isAutocompleteDebugEnabled() && validBoostedWords.size > 0) {
405
388
  // eslint-disable-next-line no-console
406
389
  console.groupCollapsed(
407
390
  `%c[L1 Session] %cPrimed ${validBoostedWords.size} valid dictionary words from page`,
@@ -416,8 +399,6 @@ export const ingestDocumentPage = (pageContent: string | undefined): void => {
416
399
  };
417
400
 
418
401
  export const predict = (textBefore: string): string | null => {
419
- ensureDebugModeFromStorage();
420
-
421
402
  if (!isInitialized) {
422
403
  loadDefaultVocabulary();
423
404
  }
@@ -506,7 +487,7 @@ export const predict = (textBefore: string): string | null => {
506
487
  const lmLogits = getStoredLmLogits();
507
488
 
508
489
  // Raw LM Output Logger
509
- if (debugMode && lmLogits && Object.keys(lmLogits).length > 0) {
490
+ if (isAutocompleteDebugEnabled() && lmLogits && Object.keys(lmLogits).length > 0) {
510
491
  const rawLmTop = Object.entries(lmLogits)
511
492
  .sort((a, b) => b[1] - a[1])
512
493
  .slice(0, 5)
@@ -520,10 +501,6 @@ export const predict = (textBefore: string): string | null => {
520
501
 
521
502
  const mode: 'cold' | 'warm' = contextVector ? 'warm' : 'cold';
522
503
 
523
- if (debugMode && contextVector && !hasLoggedSemanticActive) {
524
- hasLoggedSemanticActive = true;
525
- }
526
-
527
504
  // Build ScoringCandidate array from TrieNodes
528
505
  const scoringCandidates: ScoringCandidate[] = candidates.map(({ word, node }) => ({
529
506
  word,
@@ -537,11 +514,13 @@ export const predict = (textBefore: string): string | null => {
537
514
  // lmMax in rankCandidates reflects prefix-relevant signal, not the global distribution.
538
515
  const prefix = currentWord.toLowerCase();
539
516
  const prefixLmLogits = lmLogits
540
- ? Object.fromEntries(
541
- Object.entries(lmLogits).filter(([word]) => word.startsWith(prefix))
542
- )
517
+ ? Object.fromEntries(Object.entries(lmLogits).filter(([word]) => word.startsWith(prefix)))
543
518
  : null;
544
- const { candidates: ranked, grammarMeta, pipelineDebug } = rankCandidates(
519
+ const {
520
+ candidates: ranked,
521
+ grammarMeta,
522
+ pipelineDebug,
523
+ } = rankCandidates(
545
524
  scoringCandidates,
546
525
  contextVector,
547
526
  (w: string) => getWordVector(w),
@@ -554,7 +533,7 @@ export const predict = (textBefore: string): string | null => {
554
533
  const suggestion =
555
534
  best && best.finalScore >= MIN_SCORE_THRESHOLD ? best.word.slice(currentWord.length) : null;
556
535
 
557
- if (debugMode) {
536
+ if (isAutocompleteDebugEnabled()) {
558
537
  const latencyMs = performance.now() - t0;
559
538
  const tokens = tokenize(trimmed);
560
539
  const contextWords = tokens.slice(-CONTEXT_WORDS);
@@ -770,8 +749,7 @@ export const loadVectorsAsync = async (options?: {
770
749
  const dim = float32.length / nWords;
771
750
 
772
751
  vectorStore = { float32, wordIndex, dim };
773
- ensureDebugModeFromStorage();
774
- if (debugMode) {
752
+ if (isAutocompleteDebugEnabled()) {
775
753
  // eslint-disable-next-line no-console
776
754
  console.log('[text-predictor] Vectors loaded:', {
777
755
  wordCount: nWords,
package/tsconfig.app.json CHANGED
@@ -2,6 +2,7 @@
2
2
  "extends": "../../../tsconfig.base.json",
3
3
  "include": ["./src/**/*.ts", "./src/**/*.tsx", "./src/**/*.json"],
4
4
  "exclude": [
5
+ "**/*.docs.tsx",
5
6
  "**/docs/**/*",
6
7
  "**/__tests__/**/*",
7
8
  "**/vr-tests/**/*",
@@ -29,12 +30,16 @@
29
30
  "compilerOptions": {
30
31
  "composite": true,
31
32
  "outDir": "../../../tsDist/@atlaskit__editor-plugin-autocomplete/app",
32
- "resolveJsonModule": true
33
+ "resolveJsonModule": true,
34
+ "isolatedDeclarations": true
33
35
  },
34
36
  "references": [
35
37
  {
36
38
  "path": "../editor-common/tsconfig.app.json"
37
39
  },
40
+ {
41
+ "path": "../editor-plugin-analytics/tsconfig.app.json"
42
+ },
38
43
  {
39
44
  "path": "../editor-prosemirror/tsconfig.app.json"
40
45
  }
package/tsconfig.dev.json CHANGED
@@ -28,7 +28,8 @@
28
28
  "exclude": ["./dist/**/*", "./build/**/*", "./node_modules/**/*"],
29
29
  "compilerOptions": {
30
30
  "composite": true,
31
- "outDir": "../../../tsDist/@atlaskit__editor-plugin-autocomplete/dev"
31
+ "outDir": "../../../tsDist/@atlaskit__editor-plugin-autocomplete/dev",
32
+ "isolatedDeclarations": true
32
33
  },
33
34
  "references": [
34
35
  {
@@ -1,30 +0,0 @@
1
- {
2
- "extends": "../../../../tsconfig.local-consumption.json",
3
- "compilerOptions": {
4
- "target": "es5",
5
- "outDir": "../../../../../jira/tsDist/@atlaskit__editor-plugin-autocomplete/app",
6
- "rootDir": "../",
7
- "composite": true,
8
- "noCheck": true,
9
- "resolveJsonModule": true
10
- },
11
- "include": [
12
- "../src/**/*.ts",
13
- "../src/**/*.tsx"
14
- ],
15
- "exclude": [
16
- "../src/**/__tests__/*",
17
- "../src/**/*.test.*",
18
- "../src/**/test.*",
19
- "../src/**/mocks/*",
20
- "../src/**/examples.*"
21
- ],
22
- "references": [
23
- {
24
- "path": "../../editor-prosemirror/afm-jira/tsconfig.json"
25
- },
26
- {
27
- "path": "../../editor-common/afm-jira/tsconfig.json"
28
- }
29
- ]
30
- }