@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,258 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.rankCandidates = rankCandidates;
8
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
+ var _combined_l2_l3_pos_tags = _interopRequireDefault(require("./data/combined_l2_l3_pos_tags.json"));
10
+ var _ghost_pos_tags = _interopRequireDefault(require("./data/ghost_pos_tags.json"));
11
+ var _grammar_transitions_10k = _interopRequireDefault(require("./data/grammar_transitions_10k.json"));
12
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
13
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
14
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } /**
15
+ * Scoring Pipeline: Stage 1 (Semantic + Frequency), Grammar Filter, Stage 2 (LM Re-ranking).
16
+ *
17
+ * Operates synchronously on pre-loaded data. Each stage gracefully degrades
18
+ * when its required data isn't available (cold → warm → full warm).
19
+ */ // resolveJsonModule is disabled for this package (see tsconfig.json) to prevent
20
+ // TypeScript from parsing LFS pointer files during CI typecheck. JSON imports
21
+ // are typed via the '*.json' declaration in typings.d.ts.
22
+ // ─── Types ──────────────────────────────────────────────────
23
+
24
+ /** Metadata returned by the grammar filter for debug logging in the caller. */
25
+
26
+ // ─── Scoring Constants ──────────────────────────────────────
27
+
28
+ var ALPHA = 0.5;
29
+ var BETA = 0.5;
30
+ var NEUTRAL_SCORE = 0.5;
31
+ var STAGE1_WEIGHT = 0.6;
32
+ var STAGE2_WEIGHT = 0.4;
33
+ var MIN_STAGE1_SCORE = 0.35;
34
+ var L1_SESSION_CAP = 1.2;
35
+
36
+ // ─── Grammar Data (loaded once on import) ───────────────────
37
+
38
+ var posTags = new Map(Object.entries(_combined_l2_l3_pos_tags.default));
39
+ var grammarTransitions = _grammar_transitions_10k.default;
40
+
41
+ /**
42
+ * Precomputed map from each POS tag to the set of allowed next POS tags.
43
+ * Built once at module load from grammarTransitions so applyGrammarFilter
44
+ * never re-iterates the transition rules per call.
45
+ */
46
+ var precomputedAllowedByPos = new Map(Object.entries(grammarTransitions.transitions).map(function (_ref) {
47
+ var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
48
+ pos = _ref2[0],
49
+ rule = _ref2[1];
50
+ return [pos, new Set(rule.allowed)];
51
+ }));
52
+
53
+ // ─── Math ───────────────────────────────────────────────────
54
+
55
+ function cosineSimilarity(a, b) {
56
+ var dot = 0;
57
+ var normA = 0;
58
+ var normB = 0;
59
+ for (var i = 0; i < a.length; i++) {
60
+ dot += a[i] * b[i];
61
+ normA += a[i] * a[i];
62
+ normB += b[i] * b[i];
63
+ }
64
+ var dNormA = Math.sqrt(normA);
65
+ var dNormB = Math.sqrt(normB);
66
+ if (dNormA === 0 || dNormB === 0) {
67
+ return NEUTRAL_SCORE;
68
+ }
69
+ return (1 + dot / (dNormA * dNormB)) / 2;
70
+ }
71
+
72
+ // ─── Stage 1: Semantic + Frequency ──────────────────────────
73
+
74
+ function scoreStage1(candidate, contextVector, getWordVector, maxTenantFreq) {
75
+ // 1. Calculate Base Global Score (Normalized Log)
76
+ var maxPossibleLog = Math.log10(maxTenantFreq + 1);
77
+
78
+ // Diversity Adjustment
79
+ var diversityRaw = (Math.log10(candidate.tenantFreq + 1) * 0.50 + Math.log10(candidate.docFreq + 1) * 0.25 + Math.log10(candidate.authorFreq + 1) * 0.25) / maxPossibleLog;
80
+ var sessionMultiplier = candidate.sessionFreq > 0 ? 1 + Math.log10(candidate.sessionFreq + 1) * 2.5 : 1;
81
+
82
+ // Apply multiplier; capped at L1_SESSION_CAP (default 1.2) to prevent excessive over-indexing
83
+ var freqScore = Math.min(diversityRaw * sessionMultiplier, L1_SESSION_CAP);
84
+
85
+ // 3. Semantic Scoring
86
+ var semanticScore = NEUTRAL_SCORE;
87
+ if (contextVector) {
88
+ var wordVec = getWordVector(candidate.word);
89
+ semanticScore = wordVec ? cosineSimilarity(contextVector, wordVec) : NEUTRAL_SCORE;
90
+ }
91
+ return {
92
+ semanticScore: semanticScore,
93
+ freqScore: freqScore,
94
+ stage1Score: ALPHA * semanticScore + BETA * freqScore
95
+ };
96
+ }
97
+
98
+ // ─── Grammar Filter ─────────────────────────────────────────
99
+
100
+ /**
101
+ * GHOST POS DICTIONARY
102
+ * A hardcoded mapping of common structural English words that were stripped
103
+ * from the main domain vocabulary. This allows the grammar filter to understand
104
+ * context without suggesting these words to the user.
105
+ */
106
+ var ghostPosTags = _ghost_pos_tags.default;
107
+ function applyGrammarFilter(candidates, previousWord) {
108
+ if (!previousWord) return {
109
+ filtered: candidates,
110
+ grammarMeta: null
111
+ };
112
+ var lowerPrev = previousWord.toLowerCase();
113
+ var prevTags = ghostPosTags[lowerPrev] || posTags.get(lowerPrev);
114
+ if (!prevTags || prevTags.length === 0) {
115
+ return {
116
+ filtered: candidates,
117
+ grammarMeta: null
118
+ };
119
+ }
120
+ var allowedNextTags;
121
+ if (prevTags.length === 1) {
122
+ var _precomputedAllowedBy;
123
+ // Common case: single POS tag — reuse the precomputed Set directly (no allocation)
124
+ allowedNextTags = (_precomputedAllowedBy = precomputedAllowedByPos.get(prevTags[0])) !== null && _precomputedAllowedBy !== void 0 ? _precomputedAllowedBy : new Set();
125
+ } else {
126
+ allowedNextTags = new Set();
127
+ var _iterator = _createForOfIteratorHelper(prevTags),
128
+ _step;
129
+ try {
130
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
131
+ var pt = _step.value;
132
+ var allowed = precomputedAllowedByPos.get(pt);
133
+ if (allowed) allowed.forEach(function (tag) {
134
+ return allowedNextTags.add(tag);
135
+ });
136
+ }
137
+ } catch (err) {
138
+ _iterator.e(err);
139
+ } finally {
140
+ _iterator.f();
141
+ }
142
+ }
143
+ var filtered = [];
144
+ var dropped = [];
145
+ var _iterator2 = _createForOfIteratorHelper(candidates),
146
+ _step2;
147
+ try {
148
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
149
+ var entry = _step2.value;
150
+ var candidateTags = posTags.get(entry.candidate.word.toLowerCase());
151
+
152
+ // If candidate has no tags (unknown word), let it pass to be safe
153
+ if (!candidateTags || candidateTags.length === 0) {
154
+ filtered.push(entry);
155
+ continue;
156
+ }
157
+ if (candidateTags.some(function (ct) {
158
+ return allowedNextTags.has(ct);
159
+ })) {
160
+ filtered.push(entry);
161
+ } else {
162
+ dropped.push(entry.candidate.word);
163
+ }
164
+ }
165
+ } catch (err) {
166
+ _iterator2.e(err);
167
+ } finally {
168
+ _iterator2.f();
169
+ }
170
+ var finalFiltered = filtered.length > 0 ? filtered : candidates;
171
+ return {
172
+ filtered: finalFiltered,
173
+ grammarMeta: {
174
+ prevWord: lowerPrev,
175
+ prevTags: prevTags,
176
+ before: candidates.length,
177
+ after: finalFiltered.length,
178
+ dropped: filtered.length > 0 ? dropped : []
179
+ }
180
+ };
181
+ }
182
+
183
+ // ─── Stage 2: LM Re-ranking ────────────────────────────────
184
+ function getLmScore(word, lmLogits) {
185
+ if (!lmLogits) return 0;
186
+
187
+ // Look up the word directly! No more tokens.
188
+ var val = lmLogits[word.toLowerCase()];
189
+ if (typeof val === 'number') {
190
+ return val;
191
+ }
192
+ return 0;
193
+ }
194
+
195
+ // ─── Public API ─────────────────────────────────────────────
196
+
197
+ function rankCandidates(candidates, contextVector, getWordVector, lmLogits, maxTenantFreq, previousWord) {
198
+ // Stage 1
199
+ var stage1Results = candidates.map(function (candidate) {
200
+ var _scoreStage = scoreStage1(candidate, contextVector, getWordVector, maxTenantFreq),
201
+ semanticScore = _scoreStage.semanticScore,
202
+ freqScore = _scoreStage.freqScore,
203
+ stage1Score = _scoreStage.stage1Score;
204
+ return {
205
+ candidate: candidate,
206
+ semanticScore: semanticScore,
207
+ freqScore: freqScore,
208
+ stage1Score: stage1Score
209
+ };
210
+ });
211
+ var stage1Survivors = stage1Results.filter(function (entry) {
212
+ return entry.stage1Score >= MIN_STAGE1_SCORE;
213
+ });
214
+
215
+ // Grammar Filter
216
+ var _applyGrammarFilter = applyGrammarFilter(stage1Survivors, previousWord),
217
+ filtered = _applyGrammarFilter.filtered,
218
+ grammarMeta = _applyGrammarFilter.grammarMeta;
219
+
220
+ // Stage 2 + final assembly
221
+ var lmMax = 0;
222
+ if (lmLogits && Object.keys(lmLogits).length > 0) {
223
+ var values = Object.values(lmLogits);
224
+ lmMax = Math.max.apply(Math, values);
225
+ }
226
+ var scored = filtered.map(function (entry) {
227
+ var lmScore = 0;
228
+ var finalScore = entry.stage1Score;
229
+ if (lmLogits && Object.keys(lmLogits).length > 0) {
230
+ var rawLm = getLmScore(entry.candidate.word, lmLogits);
231
+ if (rawLm !== 0) {
232
+ // The word was in the top_k! Score it normally.
233
+ var logitDiff = Math.log(rawLm) - Math.log(lmMax);
234
+ lmScore = Math.exp(logitDiff);
235
+ } else {
236
+ lmScore = 0.05;
237
+ }
238
+ finalScore = STAGE1_WEIGHT * entry.stage1Score + STAGE2_WEIGHT * lmScore;
239
+ }
240
+ return {
241
+ word: entry.candidate.word,
242
+ freqScore: entry.freqScore,
243
+ semanticScore: entry.semanticScore,
244
+ lmScore: lmScore,
245
+ finalScore: finalScore
246
+ };
247
+ });
248
+ scored.sort(function (a, b) {
249
+ if (b.finalScore !== a.finalScore) {
250
+ return b.finalScore - a.finalScore;
251
+ }
252
+ return a.word.length - b.word.length;
253
+ });
254
+ return {
255
+ candidates: scored,
256
+ grammarMeta: grammarMeta
257
+ };
258
+ }
@@ -0,0 +1,197 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.setDefaultSlowLaneClient = exports.isWordBoundary = exports.getStoredLmLogits = exports.getStoredContextVector = exports.createSlowLaneClient = void 0;
8
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
+ var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
10
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
11
+ /**
12
+ * Slow Lane Client: Backend context encoding for autocomplete.
13
+ *
14
+ * Fires a BE request on word boundaries to encode document context.
15
+ * Expects the typeahead-encodings API format:
16
+ * Request: { text, session_id }
17
+ * Response: { semantic_vector: number[], lm_logits: Record<string, number> }
18
+ */
19
+
20
+ // ─── Types ───────────────────────────────────────────────────────────────────
21
+
22
+ /** Request payload for typeahead-encodings endpoint. */
23
+
24
+ /** Response from typeahead-encodings endpoint. */
25
+
26
+ // ─── Constants ───────────────────────────────────────────────────────────────
27
+
28
+ var WORD_BOUNDARY_CHARS = /[\t-\r !,\.:;\?\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]/;
29
+ var DEFAULT_DEBOUNCE_MS = 300;
30
+
31
+ /**
32
+ * Check if text ends with a word boundary character (space or punctuation).
33
+ */
34
+ var isWordBoundary = exports.isWordBoundary = function isWordBoundary(text) {
35
+ if (!text || text.length === 0) {
36
+ return false;
37
+ }
38
+ var lastChar = text[text.length - 1];
39
+ return WORD_BOUNDARY_CHARS.test(lastChar);
40
+ };
41
+
42
+ // ─── Slow Lane Client ────────────────────────────────────────────────────────
43
+
44
+ var createSlowLaneClient = exports.createSlowLaneClient = function createSlowLaneClient(config) {
45
+ var baseUrl = config.baseUrl,
46
+ configSessionId = config.sessionId,
47
+ _config$productKey = config.productKey,
48
+ productKey = _config$productKey === void 0 ? 'confluence' : _config$productKey,
49
+ _config$endpoint = config.endpoint,
50
+ endpoint = _config$endpoint === void 0 ? '/gateway/api/v1/autocomplete/typeahead-encodings' : _config$endpoint,
51
+ _config$debounceMs = config.debounceMs,
52
+ debounceMs = _config$debounceMs === void 0 ? DEFAULT_DEBOUNCE_MS : _config$debounceMs,
53
+ _config$fetchFn = config.fetchFn,
54
+ fetchFn = _config$fetchFn === void 0 ? fetch : _config$fetchFn,
55
+ onUpdate = config.onUpdate;
56
+ var sessionId = configSessionId !== null && configSessionId !== void 0 ? configSessionId : crypto.randomUUID();
57
+ var headers = {
58
+ 'Content-Type': 'application/json',
59
+ 'x-experience-id': 'confluence-smart-typeahead-encodings',
60
+ 'x-product': productKey
61
+ };
62
+ var debounceTimer = null;
63
+ var lastRequestedText = '';
64
+ var storedContextVector = null;
65
+ var storedLmLogits = null;
66
+ var doUpdateContext = /*#__PURE__*/function () {
67
+ var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(text) {
68
+ var url, payload, res, data;
69
+ return _regenerator.default.wrap(function _callee$(_context) {
70
+ while (1) switch (_context.prev = _context.next) {
71
+ case 0:
72
+ if (!(!text || text.trim().length === 0)) {
73
+ _context.next = 2;
74
+ break;
75
+ }
76
+ return _context.abrupt("return");
77
+ case 2:
78
+ url = "".concat(baseUrl.replace(/\/$/, '')).concat(endpoint);
79
+ payload = {
80
+ text: text,
81
+ session_id: sessionId
82
+ }; // Log the exact payload being sent so the comment/reply structure is visible
83
+ // eslint-disable-next-line no-console
84
+ console.groupCollapsed("%c[SlowLane] %c\uD83D\uDCE4 Sending context | ".concat(text.length, " chars"), 'color: #9c27b0; font-weight: bold;', 'color: inherit;');
85
+ text.split('\n').forEach(function (line, i, arr) {
86
+ // eslint-disable-next-line no-console
87
+ console.log(" ".concat(i === arr.length - 1 ? '▶' : ' ', " ").concat(line));
88
+ });
89
+ // eslint-disable-next-line no-console
90
+ console.groupEnd();
91
+ _context.prev = 7;
92
+ _context.next = 10;
93
+ return fetchFn(url, {
94
+ method: 'POST',
95
+ headers: headers,
96
+ body: JSON.stringify(payload)
97
+ });
98
+ case 10:
99
+ res = _context.sent;
100
+ if (res.ok) {
101
+ _context.next = 16;
102
+ break;
103
+ }
104
+ storedContextVector = null;
105
+ storedLmLogits = null;
106
+ // eslint-disable-next-line no-console
107
+ console.log("%c[SlowLane] %c\u274C Request failed (".concat(res.status, ")"), 'color: #9c27b0; font-weight: bold;', 'color: #f44336;');
108
+ return _context.abrupt("return");
109
+ case 16:
110
+ _context.next = 18;
111
+ return res.json();
112
+ case 18:
113
+ data = _context.sent;
114
+ if (data.semantic_vector && Array.isArray(data.semantic_vector)) {
115
+ storedContextVector = new Float32Array(data.semantic_vector);
116
+ } else {
117
+ storedContextVector = null;
118
+ }
119
+ if (data.lm_logits && (0, _typeof2.default)(data.lm_logits) === 'object') {
120
+ storedLmLogits = data.lm_logits;
121
+ } else {
122
+ storedLmLogits = null;
123
+ }
124
+
125
+ // Log what came back so it can be correlated with the next prediction group
126
+ // eslint-disable-next-line no-console
127
+ console.groupCollapsed("%c[SlowLane] %c\uD83D\uDCE5 Response received", 'color: #9c27b0; font-weight: bold;', 'color: inherit;');
128
+ // eslint-disable-next-line no-console
129
+ console.log(storedContextVector ? "\u2705 semantic_vector: ".concat(storedContextVector.length, " dims") : '❌ No semantic_vector');
130
+ // eslint-disable-next-line no-console
131
+ console.log(storedLmLogits ? "\u2705 lm_logits: ".concat(Object.keys(storedLmLogits).length, " tokens") : '❌ No lm_logits');
132
+ // eslint-disable-next-line no-console
133
+ console.groupEnd();
134
+ onUpdate === null || onUpdate === void 0 || onUpdate({
135
+ textLength: text.length,
136
+ hasVector: storedContextVector !== null,
137
+ hasLmLogits: storedLmLogits !== null
138
+ });
139
+ // eslint-disable-next-line no-unused-vars
140
+ _context.next = 33;
141
+ break;
142
+ case 28:
143
+ _context.prev = 28;
144
+ _context.t0 = _context["catch"](7);
145
+ storedContextVector = null;
146
+ storedLmLogits = null;
147
+ // eslint-disable-next-line no-console
148
+ console.log('%c[SlowLane] %c❌ Network error — context cleared', 'color: #9c27b0; font-weight: bold;', 'color: #f44336;');
149
+ case 33:
150
+ case "end":
151
+ return _context.stop();
152
+ }
153
+ }, _callee, null, [[7, 28]]);
154
+ }));
155
+ return function doUpdateContext(_x) {
156
+ return _ref.apply(this, arguments);
157
+ };
158
+ }();
159
+ var updateContextDebounced = function updateContextDebounced(text) {
160
+ if (debounceTimer) {
161
+ clearTimeout(debounceTimer);
162
+ }
163
+ lastRequestedText = text;
164
+ debounceTimer = setTimeout(function () {
165
+ debounceTimer = null;
166
+ doUpdateContext(lastRequestedText);
167
+ }, debounceMs);
168
+ };
169
+ return {
170
+ updateContext: updateContextDebounced,
171
+ getContextVector: function getContextVector() {
172
+ return storedContextVector;
173
+ },
174
+ getLmLogits: function getLmLogits() {
175
+ return storedLmLogits;
176
+ },
177
+ setContextVector: function setContextVector(vector) {
178
+ storedContextVector = vector;
179
+ },
180
+ setLmLogits: function setLmLogits(logits) {
181
+ storedLmLogits = logits;
182
+ },
183
+ isWordBoundary: isWordBoundary
184
+ };
185
+ };
186
+ var defaultSlowLaneClient = null;
187
+ var setDefaultSlowLaneClient = exports.setDefaultSlowLaneClient = function setDefaultSlowLaneClient(client) {
188
+ defaultSlowLaneClient = client;
189
+ };
190
+ var getStoredContextVector = exports.getStoredContextVector = function getStoredContextVector() {
191
+ var _defaultSlowLaneClien, _defaultSlowLaneClien2;
192
+ return (_defaultSlowLaneClien = (_defaultSlowLaneClien2 = defaultSlowLaneClient) === null || _defaultSlowLaneClien2 === void 0 ? void 0 : _defaultSlowLaneClien2.getContextVector()) !== null && _defaultSlowLaneClien !== void 0 ? _defaultSlowLaneClien : null;
193
+ };
194
+ var getStoredLmLogits = exports.getStoredLmLogits = function getStoredLmLogits() {
195
+ var _defaultSlowLaneClien3, _defaultSlowLaneClien4;
196
+ return (_defaultSlowLaneClien3 = (_defaultSlowLaneClien4 = defaultSlowLaneClient) === null || _defaultSlowLaneClien4 === void 0 ? void 0 : _defaultSlowLaneClien4.getLmLogits()) !== null && _defaultSlowLaneClien3 !== void 0 ? _defaultSlowLaneClien3 : null;
197
+ };