@atlaskit/editor-plugin-autocomplete 0.1.0 → 0.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.
Files changed (52) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/afm-cc/tsconfig.json +5 -1
  3. package/afm-jira/tsconfig.json +5 -1
  4. package/afm-products/tsconfig.json +5 -1
  5. package/build/tsconfig.json +24 -0
  6. package/dist/cjs/autocompletePlugin.js +18 -5
  7. package/dist/cjs/autocompletePluginType.js +5 -1
  8. package/dist/cjs/pm-plugins/autocomplete-plugin.js +361 -0
  9. package/dist/cjs/pm-plugins/ghost-text-decoration.js +39 -0
  10. package/dist/cjs/pm-plugins/scoring-pipeline.js +258 -0
  11. package/dist/cjs/pm-plugins/slow-lane-client.js +197 -0
  12. package/dist/cjs/pm-plugins/text-predictor.js +786 -0
  13. package/dist/es2019/autocompletePlugin.js +20 -6
  14. package/dist/es2019/autocompletePluginType.js +1 -0
  15. package/dist/es2019/pm-plugins/autocomplete-plugin.js +360 -0
  16. package/dist/es2019/pm-plugins/ghost-text-decoration.js +33 -0
  17. package/dist/es2019/pm-plugins/scoring-pipeline.js +224 -0
  18. package/dist/es2019/pm-plugins/slow-lane-client.js +154 -0
  19. package/dist/es2019/pm-plugins/text-predictor.js +624 -0
  20. package/dist/esm/autocompletePlugin.js +18 -5
  21. package/dist/esm/autocompletePluginType.js +1 -0
  22. package/dist/esm/pm-plugins/autocomplete-plugin.js +354 -0
  23. package/dist/esm/pm-plugins/ghost-text-decoration.js +33 -0
  24. package/dist/esm/pm-plugins/scoring-pipeline.js +255 -0
  25. package/dist/esm/pm-plugins/slow-lane-client.js +190 -0
  26. package/dist/esm/pm-plugins/text-predictor.js +783 -0
  27. package/dist/types/autocompletePluginType.d.ts +6 -3
  28. package/dist/types/pm-plugins/autocomplete-plugin.d.ts +36 -0
  29. package/dist/types/pm-plugins/ghost-text-decoration.d.ts +7 -0
  30. package/dist/types/pm-plugins/scoring-pipeline.d.ts +33 -0
  31. package/dist/types/pm-plugins/slow-lane-client.d.ts +46 -0
  32. package/dist/types/pm-plugins/text-predictor.d.ts +90 -0
  33. package/dist/types-ts4.5/autocompletePluginType.d.ts +6 -3
  34. package/dist/types-ts4.5/pm-plugins/autocomplete-plugin.d.ts +36 -0
  35. package/dist/types-ts4.5/pm-plugins/ghost-text-decoration.d.ts +7 -0
  36. package/dist/types-ts4.5/pm-plugins/scoring-pipeline.d.ts +33 -0
  37. package/dist/types-ts4.5/pm-plugins/slow-lane-client.d.ts +46 -0
  38. package/dist/types-ts4.5/pm-plugins/text-predictor.d.ts +90 -0
  39. package/package.json +2 -2
  40. package/src/autocompletePlugin.tsx +25 -5
  41. package/src/autocompletePluginType.ts +14 -3
  42. package/src/pm-plugins/autocomplete-plugin/package.json +15 -0
  43. package/src/pm-plugins/autocomplete-plugin.ts +429 -0
  44. package/src/pm-plugins/ghost-text-decoration.ts +44 -0
  45. package/src/pm-plugins/scoring-pipeline.ts +297 -0
  46. package/src/pm-plugins/slow-lane-client/package.json +15 -0
  47. package/src/pm-plugins/slow-lane-client.ts +220 -0
  48. package/src/pm-plugins/text-predictor/package.json +15 -0
  49. package/src/pm-plugins/text-predictor.ts +771 -0
  50. package/src/pm-plugins/typings.d.ts +12 -0
  51. package/tsconfig.app.json +10 -2
  52. package/tsconfig.json +3 -1
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Slow Lane Client: Backend context encoding for autocomplete.
3
+ *
4
+ * Fires a BE request on word boundaries to encode document context.
5
+ * Expects the typeahead-encodings API format:
6
+ * Request: { text, session_id }
7
+ * Response: { semantic_vector: number[], lm_logits: Record<string, number> }
8
+ */
9
+
10
+ // ─── Types ───────────────────────────────────────────────────────────────────
11
+
12
+ /** Request payload for typeahead-encodings endpoint. */
13
+
14
+ /** Response from typeahead-encodings endpoint. */
15
+
16
+ // ─── Constants ───────────────────────────────────────────────────────────────
17
+
18
+ const WORD_BOUNDARY_CHARS = /[\s.,;:!?]/u;
19
+ const DEFAULT_DEBOUNCE_MS = 300;
20
+
21
+ /**
22
+ * Check if text ends with a word boundary character (space or punctuation).
23
+ */
24
+ export const isWordBoundary = text => {
25
+ if (!text || text.length === 0) {
26
+ return false;
27
+ }
28
+ const lastChar = text[text.length - 1];
29
+ return WORD_BOUNDARY_CHARS.test(lastChar);
30
+ };
31
+
32
+ // ─── Slow Lane Client ────────────────────────────────────────────────────────
33
+
34
+ export const createSlowLaneClient = config => {
35
+ const {
36
+ baseUrl,
37
+ sessionId: configSessionId,
38
+ productKey = 'confluence',
39
+ endpoint = '/gateway/api/v1/autocomplete/typeahead-encodings',
40
+ debounceMs = DEFAULT_DEBOUNCE_MS,
41
+ fetchFn = fetch,
42
+ onUpdate
43
+ } = config;
44
+ const sessionId = configSessionId !== null && configSessionId !== void 0 ? configSessionId : crypto.randomUUID();
45
+ const headers = {
46
+ 'Content-Type': 'application/json',
47
+ 'x-experience-id': 'confluence-smart-typeahead-encodings',
48
+ 'x-product': productKey
49
+ };
50
+ let debounceTimer = null;
51
+ let lastRequestedText = '';
52
+ let storedContextVector = null;
53
+ let storedLmLogits = null;
54
+ const doUpdateContext = async text => {
55
+ if (!text || text.trim().length === 0) {
56
+ return;
57
+ }
58
+ const url = `${baseUrl.replace(/\/$/u, '')}${endpoint}`;
59
+ const payload = {
60
+ text,
61
+ session_id: sessionId
62
+ };
63
+
64
+ // Log the exact payload being sent so the comment/reply structure is visible
65
+ // eslint-disable-next-line no-console
66
+ console.groupCollapsed(`%c[SlowLane] %c📤 Sending context | ${text.length} chars`, 'color: #9c27b0; font-weight: bold;', 'color: inherit;');
67
+ text.split('\n').forEach((line, i, arr) => {
68
+ // eslint-disable-next-line no-console
69
+ console.log(` ${i === arr.length - 1 ? '▶' : ' '} ${line}`);
70
+ });
71
+ // eslint-disable-next-line no-console
72
+ console.groupEnd();
73
+ try {
74
+ const res = await fetchFn(url, {
75
+ method: 'POST',
76
+ headers,
77
+ body: JSON.stringify(payload)
78
+ });
79
+ if (!res.ok) {
80
+ storedContextVector = null;
81
+ storedLmLogits = null;
82
+ // eslint-disable-next-line no-console
83
+ console.log(`%c[SlowLane] %c❌ Request failed (${res.status})`, 'color: #9c27b0; font-weight: bold;', 'color: #f44336;');
84
+ return;
85
+ }
86
+ const data = await res.json();
87
+ if (data.semantic_vector && Array.isArray(data.semantic_vector)) {
88
+ storedContextVector = new Float32Array(data.semantic_vector);
89
+ } else {
90
+ storedContextVector = null;
91
+ }
92
+ if (data.lm_logits && typeof data.lm_logits === 'object') {
93
+ storedLmLogits = data.lm_logits;
94
+ } else {
95
+ storedLmLogits = null;
96
+ }
97
+
98
+ // Log what came back so it can be correlated with the next prediction group
99
+ // eslint-disable-next-line no-console
100
+ console.groupCollapsed(`%c[SlowLane] %c📥 Response received`, 'color: #9c27b0; font-weight: bold;', 'color: inherit;');
101
+ // eslint-disable-next-line no-console
102
+ console.log(storedContextVector ? `✅ semantic_vector: ${storedContextVector.length} dims` : '❌ No semantic_vector');
103
+ // eslint-disable-next-line no-console
104
+ console.log(storedLmLogits ? `✅ lm_logits: ${Object.keys(storedLmLogits).length} tokens` : '❌ No lm_logits');
105
+ // eslint-disable-next-line no-console
106
+ console.groupEnd();
107
+ onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate({
108
+ textLength: text.length,
109
+ hasVector: storedContextVector !== null,
110
+ hasLmLogits: storedLmLogits !== null
111
+ });
112
+ // eslint-disable-next-line no-unused-vars
113
+ } catch (e) {
114
+ storedContextVector = null;
115
+ storedLmLogits = null;
116
+ // eslint-disable-next-line no-console
117
+ console.log('%c[SlowLane] %c❌ Network error — context cleared', 'color: #9c27b0; font-weight: bold;', 'color: #f44336;');
118
+ }
119
+ };
120
+ const updateContextDebounced = text => {
121
+ if (debounceTimer) {
122
+ clearTimeout(debounceTimer);
123
+ }
124
+ lastRequestedText = text;
125
+ debounceTimer = setTimeout(() => {
126
+ debounceTimer = null;
127
+ doUpdateContext(lastRequestedText);
128
+ }, debounceMs);
129
+ };
130
+ return {
131
+ updateContext: updateContextDebounced,
132
+ getContextVector: () => storedContextVector,
133
+ getLmLogits: () => storedLmLogits,
134
+ setContextVector: vector => {
135
+ storedContextVector = vector;
136
+ },
137
+ setLmLogits: logits => {
138
+ storedLmLogits = logits;
139
+ },
140
+ isWordBoundary
141
+ };
142
+ };
143
+ let defaultSlowLaneClient = null;
144
+ export const setDefaultSlowLaneClient = client => {
145
+ defaultSlowLaneClient = client;
146
+ };
147
+ export const getStoredContextVector = () => {
148
+ var _defaultSlowLaneClien, _defaultSlowLaneClien2;
149
+ return (_defaultSlowLaneClien = (_defaultSlowLaneClien2 = defaultSlowLaneClient) === null || _defaultSlowLaneClien2 === void 0 ? void 0 : _defaultSlowLaneClien2.getContextVector()) !== null && _defaultSlowLaneClien !== void 0 ? _defaultSlowLaneClien : null;
150
+ };
151
+ export const getStoredLmLogits = () => {
152
+ var _defaultSlowLaneClien3, _defaultSlowLaneClien4;
153
+ return (_defaultSlowLaneClien3 = (_defaultSlowLaneClien4 = defaultSlowLaneClient) === null || _defaultSlowLaneClien4 === void 0 ? void 0 : _defaultSlowLaneClien4.getLmLogits()) !== null && _defaultSlowLaneClien3 !== void 0 ? _defaultSlowLaneClien3 : null;
154
+ };