@atlaskit/editor-plugin-autocomplete 4.0.4 → 4.0.5
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 +8 -0
- package/dist/cjs/pm-plugins/autocomplete-plugin.js +8 -7
- package/dist/cjs/pm-plugins/local-slow-lane-client.js +3 -3
- package/dist/cjs/pm-plugins/slow-lane-client.js +3 -2
- package/dist/cjs/pm-plugins/text-predictor.js +11 -9
- package/dist/es2019/pm-plugins/autocomplete-plugin.js +8 -7
- package/dist/es2019/pm-plugins/local-slow-lane-client.js +3 -3
- package/dist/es2019/pm-plugins/slow-lane-client.js +3 -3
- package/dist/es2019/pm-plugins/text-predictor.js +11 -9
- package/dist/esm/pm-plugins/autocomplete-plugin.js +8 -7
- package/dist/esm/pm-plugins/local-slow-lane-client.js +3 -3
- package/dist/esm/pm-plugins/slow-lane-client.js +3 -2
- package/dist/esm/pm-plugins/text-predictor.js +11 -9
- package/package.json +2 -2
- package/src/pm-plugins/autocomplete-plugin.ts +8 -6
- package/src/pm-plugins/local-slow-lane-client.ts +3 -2
- package/src/pm-plugins/slow-lane-client.ts +3 -2
- package/src/pm-plugins/text-predictor.ts +11 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-autocomplete
|
|
2
2
|
|
|
3
|
+
## 4.0.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`73743eb8b36e6`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/73743eb8b36e6) -
|
|
8
|
+
CLeanup prefer static regex violations
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
|
|
3
11
|
## 4.0.4
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
|
@@ -38,6 +38,11 @@ var MAX_INGESTED_CONTEXT_TEXTS = 50;
|
|
|
38
38
|
// non-comment editors (where parentCommentContent never arrives) don't refetch
|
|
39
39
|
// on every word boundary for the plugin's lifetime.
|
|
40
40
|
var MAX_CONTEXT_REFRESH_ATTEMPTS = 5;
|
|
41
|
+
|
|
42
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
43
|
+
var TRAILING_NON_BOUNDARY_TOKEN_REGEX = /([^\s.,;:!?]*)$/;
|
|
44
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
45
|
+
var WORD_BOUNDARY_CHARS_REGEX = /[\s.,;:!?]/;
|
|
41
46
|
var hasDestroy = function hasDestroy(client) {
|
|
42
47
|
return 'destroy' in client && typeof client.destroy === 'function';
|
|
43
48
|
};
|
|
@@ -225,9 +230,7 @@ var getTypedLengthForPrediction = function getTypedLengthForPrediction(textBefor
|
|
|
225
230
|
if ((0, _slowLaneClient.isWordBoundary)(textBefore)) {
|
|
226
231
|
return 0;
|
|
227
232
|
}
|
|
228
|
-
|
|
229
|
-
// eslint-disable-next-line require-unicode-regexp
|
|
230
|
-
var trailingToken = (_textBefore$match$ = (_textBefore$match = textBefore.match(/([^\s.,;:!?]*)$/)) === null || _textBefore$match === void 0 ? void 0 : _textBefore$match[1]) !== null && _textBefore$match$ !== void 0 ? _textBefore$match$ : '';
|
|
233
|
+
var trailingToken = (_textBefore$match$ = (_textBefore$match = textBefore.match(TRAILING_NON_BOUNDARY_TOKEN_REGEX)) === null || _textBefore$match === void 0 ? void 0 : _textBefore$match[1]) !== null && _textBefore$match$ !== void 0 ? _textBefore$match$ : '';
|
|
231
234
|
return trailingToken.length;
|
|
232
235
|
};
|
|
233
236
|
var isEnglishLocale = function isEnglishLocale(locale) {
|
|
@@ -539,16 +542,14 @@ var createAutocompletePlugin = exports.createAutocompletePlugin = function creat
|
|
|
539
542
|
return;
|
|
540
543
|
}
|
|
541
544
|
var lastChar = newText[newText.length - 1];
|
|
542
|
-
|
|
543
|
-
if (!/[\s.,;:!?]/.test(lastChar)) {
|
|
545
|
+
if (!WORD_BOUNDARY_CHARS_REGEX.test(lastChar)) {
|
|
544
546
|
return;
|
|
545
547
|
}
|
|
546
548
|
|
|
547
549
|
// Only fire if the previous state did not already end on a boundary,
|
|
548
550
|
// so we don't double-count when multiple boundary chars are inserted.
|
|
549
551
|
var prevLastChar = prevText[prevText.length - 1];
|
|
550
|
-
|
|
551
|
-
if (prevLastChar && /[\s.,;:!?]/.test(prevLastChar)) {
|
|
552
|
+
if (prevLastChar && WORD_BOUNDARY_CHARS_REGEX.test(prevLastChar)) {
|
|
552
553
|
return;
|
|
553
554
|
}
|
|
554
555
|
var beforeBoundary = newText.slice(0, -1).trimEnd();
|
|
@@ -78,6 +78,8 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
|
|
|
78
78
|
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
79
79
|
|
|
80
80
|
var DEFAULT_DEBOUNCE_MS = 300;
|
|
81
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
82
|
+
var OOM_REGEX = /\boom\b/;
|
|
81
83
|
var LOCAL_MLC_CAUSAL_MODEL_ID = exports.LOCAL_MLC_CAUSAL_MODEL_ID = 'SmolLM2-135M-Instruct-q0f16-MLC';
|
|
82
84
|
|
|
83
85
|
/**
|
|
@@ -766,9 +768,7 @@ var createLocalSlowLaneClient = exports.createLocalSlowLaneClient = function cre
|
|
|
766
768
|
if (lower.includes('loading chunk') || lower.includes('dynamically imported module') || lower.includes('dynamic import')) {
|
|
767
769
|
return 'module_load_failed';
|
|
768
770
|
}
|
|
769
|
-
if (lower.includes('out of memory') ||
|
|
770
|
-
// eslint-disable-next-line require-unicode-regexp
|
|
771
|
-
/\boom\b/.test(lower) || lower.includes('allocation') || lower.includes('exceeds') || lower.includes('buffer size') || lower.includes('not enough memory')) {
|
|
771
|
+
if (lower.includes('out of memory') || OOM_REGEX.test(lower) || lower.includes('allocation') || lower.includes('exceeds') || lower.includes('buffer size') || lower.includes('not enough memory')) {
|
|
772
772
|
return 'insufficient_memory';
|
|
773
773
|
}
|
|
774
774
|
// Pre-flight already returns missing_shader_f16 when the feature is absent,
|
|
@@ -29,6 +29,8 @@ var _debugMode = require("./debug-mode");
|
|
|
29
29
|
|
|
30
30
|
// eslint-disable-next-line require-unicode-regexp
|
|
31
31
|
var WORD_BOUNDARY_CHARS = /[\s.,;:!?]/;
|
|
32
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
33
|
+
var TRAILING_SLASH_REGEX = /\/$/;
|
|
32
34
|
var DEFAULT_DEBOUNCE_MS = 300;
|
|
33
35
|
|
|
34
36
|
/**
|
|
@@ -80,8 +82,7 @@ var createSlowLaneClient = exports.createSlowLaneClient = function createSlowLan
|
|
|
80
82
|
}
|
|
81
83
|
return _context.abrupt("return");
|
|
82
84
|
case 1:
|
|
83
|
-
|
|
84
|
-
url = "".concat(baseUrl.replace(/\/$/, '')).concat(endpoint);
|
|
85
|
+
url = "".concat(baseUrl.replace(TRAILING_SLASH_REGEX, '')).concat(endpoint);
|
|
85
86
|
payload = {
|
|
86
87
|
text: text,
|
|
87
88
|
session_id: sessionId
|
|
@@ -42,6 +42,12 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
|
|
|
42
42
|
|
|
43
43
|
// eslint-disable-next-line require-unicode-regexp
|
|
44
44
|
var PUNCTUATION_BOUNDARY_REGEX = /^[.,;:!?()\[\]{}"'`]+|[.,;:!?()\[\]{}"'`]+$/g;
|
|
45
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
46
|
+
var WHITESPACE_SPLIT_REGEX = /\s+/;
|
|
47
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
48
|
+
var SENTENCE_BOUNDARY_REGEX = /[\n.?!]+/;
|
|
49
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
50
|
+
var TRAILING_WHITESPACE_REGEX = /\s$/;
|
|
45
51
|
var MIN_PREFIX_LENGTH = 3;
|
|
46
52
|
var MAX_CANDIDATES = 200;
|
|
47
53
|
var CONTEXT_WORDS = 10;
|
|
@@ -312,8 +318,8 @@ var getContextVectorForScoring = function getContextVectorForScoring(textBefore)
|
|
|
312
318
|
};
|
|
313
319
|
var tokenize = function tokenize(text) {
|
|
314
320
|
var tokens = [];
|
|
315
|
-
// eslint-disable-next-line
|
|
316
|
-
var _iterator7 = _createForOfIteratorHelper(text.toLowerCase().split(
|
|
321
|
+
// eslint-disable-next-line @atlassian/perf-linting/no-expensive-split-replace
|
|
322
|
+
var _iterator7 = _createForOfIteratorHelper(text.toLowerCase().split(WHITESPACE_SPLIT_REGEX)),
|
|
317
323
|
_step7;
|
|
318
324
|
try {
|
|
319
325
|
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
|
|
@@ -333,12 +339,9 @@ var tokenize = function tokenize(text) {
|
|
|
333
339
|
};
|
|
334
340
|
var extractPreviousWord = function extractPreviousWord(text) {
|
|
335
341
|
// Only consider the current sentence/line the user is typing in.
|
|
336
|
-
|
|
337
|
-
var sentences = text.split(/[\n.?!]+/);
|
|
342
|
+
var sentences = text.split(SENTENCE_BOUNDARY_REGEX);
|
|
338
343
|
var currentSentence = sentences[sentences.length - 1];
|
|
339
|
-
|
|
340
|
-
// eslint-disable-next-line require-unicode-regexp
|
|
341
|
-
var words = currentSentence.trimEnd().split(/\s+/);
|
|
344
|
+
var words = currentSentence.trimEnd().split(WHITESPACE_SPLIT_REGEX);
|
|
342
345
|
return words.length >= 2 ? words[words.length - 2] : '';
|
|
343
346
|
};
|
|
344
347
|
|
|
@@ -477,8 +480,7 @@ var predict = exports.predict = function predict(textBefore) {
|
|
|
477
480
|
// }
|
|
478
481
|
|
|
479
482
|
// ── Step 2: Prefix completion (≥3 chars typed) ──────────────────────────
|
|
480
|
-
|
|
481
|
-
if (textBefore.length > 0 && /\s$/.test(textBefore)) {
|
|
483
|
+
if (textBefore.length > 0 && TRAILING_WHITESPACE_REGEX.test(textBefore)) {
|
|
482
484
|
return null;
|
|
483
485
|
}
|
|
484
486
|
var trimmed = textBefore.trimEnd();
|
|
@@ -24,6 +24,11 @@ const MAX_INGESTED_CONTEXT_TEXTS = 50;
|
|
|
24
24
|
// non-comment editors (where parentCommentContent never arrives) don't refetch
|
|
25
25
|
// on every word boundary for the plugin's lifetime.
|
|
26
26
|
const MAX_CONTEXT_REFRESH_ATTEMPTS = 5;
|
|
27
|
+
|
|
28
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
29
|
+
const TRAILING_NON_BOUNDARY_TOKEN_REGEX = /([^\s.,;:!?]*)$/;
|
|
30
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
31
|
+
const WORD_BOUNDARY_CHARS_REGEX = /[\s.,;:!?]/;
|
|
27
32
|
const hasDestroy = client => 'destroy' in client && typeof client.destroy === 'function';
|
|
28
33
|
const createInitialState = () => ({
|
|
29
34
|
ghostText: '',
|
|
@@ -213,9 +218,7 @@ const getTypedLengthForPrediction = textBefore => {
|
|
|
213
218
|
if (isWordBoundary(textBefore)) {
|
|
214
219
|
return 0;
|
|
215
220
|
}
|
|
216
|
-
|
|
217
|
-
// eslint-disable-next-line require-unicode-regexp
|
|
218
|
-
const trailingToken = (_textBefore$match$ = (_textBefore$match = textBefore.match(/([^\s.,;:!?]*)$/)) === null || _textBefore$match === void 0 ? void 0 : _textBefore$match[1]) !== null && _textBefore$match$ !== void 0 ? _textBefore$match$ : '';
|
|
221
|
+
const trailingToken = (_textBefore$match$ = (_textBefore$match = textBefore.match(TRAILING_NON_BOUNDARY_TOKEN_REGEX)) === null || _textBefore$match === void 0 ? void 0 : _textBefore$match[1]) !== null && _textBefore$match$ !== void 0 ? _textBefore$match$ : '';
|
|
219
222
|
return trailingToken.length;
|
|
220
223
|
};
|
|
221
224
|
const isEnglishLocale = locale => {
|
|
@@ -523,16 +526,14 @@ export const createAutocompletePlugin = (options, api) => {
|
|
|
523
526
|
return;
|
|
524
527
|
}
|
|
525
528
|
const lastChar = newText[newText.length - 1];
|
|
526
|
-
|
|
527
|
-
if (!/[\s.,;:!?]/.test(lastChar)) {
|
|
529
|
+
if (!WORD_BOUNDARY_CHARS_REGEX.test(lastChar)) {
|
|
528
530
|
return;
|
|
529
531
|
}
|
|
530
532
|
|
|
531
533
|
// Only fire if the previous state did not already end on a boundary,
|
|
532
534
|
// so we don't double-count when multiple boundary chars are inserted.
|
|
533
535
|
const prevLastChar = prevText[prevText.length - 1];
|
|
534
|
-
|
|
535
|
-
if (prevLastChar && /[\s.,;:!?]/.test(prevLastChar)) {
|
|
536
|
+
if (prevLastChar && WORD_BOUNDARY_CHARS_REGEX.test(prevLastChar)) {
|
|
536
537
|
return;
|
|
537
538
|
}
|
|
538
539
|
const beforeBoundary = newText.slice(0, -1).trimEnd();
|
|
@@ -60,6 +60,8 @@ import { isWordBoundary } from './slow-lane-client';
|
|
|
60
60
|
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
61
61
|
|
|
62
62
|
const DEFAULT_DEBOUNCE_MS = 300;
|
|
63
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
64
|
+
const OOM_REGEX = /\boom\b/;
|
|
63
65
|
export const LOCAL_MLC_CAUSAL_MODEL_ID = 'SmolLM2-135M-Instruct-q0f16-MLC';
|
|
64
66
|
|
|
65
67
|
/**
|
|
@@ -587,9 +589,7 @@ export const createLocalSlowLaneClient = (config = {}) => {
|
|
|
587
589
|
if (lower.includes('loading chunk') || lower.includes('dynamically imported module') || lower.includes('dynamic import')) {
|
|
588
590
|
return 'module_load_failed';
|
|
589
591
|
}
|
|
590
|
-
if (lower.includes('out of memory') ||
|
|
591
|
-
// eslint-disable-next-line require-unicode-regexp
|
|
592
|
-
/\boom\b/.test(lower) || lower.includes('allocation') || lower.includes('exceeds') || lower.includes('buffer size') || lower.includes('not enough memory')) {
|
|
592
|
+
if (lower.includes('out of memory') || OOM_REGEX.test(lower) || lower.includes('allocation') || lower.includes('exceeds') || lower.includes('buffer size') || lower.includes('not enough memory')) {
|
|
593
593
|
return 'insufficient_memory';
|
|
594
594
|
}
|
|
595
595
|
// Pre-flight already returns missing_shader_f16 when the feature is absent,
|
|
@@ -20,6 +20,8 @@ import { isAutocompleteDebugEnabled } from './debug-mode';
|
|
|
20
20
|
|
|
21
21
|
// eslint-disable-next-line require-unicode-regexp
|
|
22
22
|
const WORD_BOUNDARY_CHARS = /[\s.,;:!?]/;
|
|
23
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
24
|
+
const TRAILING_SLASH_REGEX = /\/$/;
|
|
23
25
|
const DEFAULT_DEBOUNCE_MS = 300;
|
|
24
26
|
|
|
25
27
|
/**
|
|
@@ -61,9 +63,7 @@ export const createSlowLaneClient = config => {
|
|
|
61
63
|
if (!text || text.trim().length === 0) {
|
|
62
64
|
return;
|
|
63
65
|
}
|
|
64
|
-
|
|
65
|
-
// eslint-disable-next-line require-unicode-regexp
|
|
66
|
-
const url = `${baseUrl.replace(/\/$/, '')}${endpoint}`;
|
|
66
|
+
const url = `${baseUrl.replace(TRAILING_SLASH_REGEX, '')}${endpoint}`;
|
|
67
67
|
const payload = {
|
|
68
68
|
text,
|
|
69
69
|
session_id: sessionId
|
|
@@ -29,6 +29,12 @@ import { getStoredContextVector, getStoredLmLogits } from './slow-lane-client';
|
|
|
29
29
|
|
|
30
30
|
// eslint-disable-next-line require-unicode-regexp
|
|
31
31
|
const PUNCTUATION_BOUNDARY_REGEX = /^[.,;:!?()\[\]{}"'`]+|[.,;:!?()\[\]{}"'`]+$/g;
|
|
32
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
33
|
+
const WHITESPACE_SPLIT_REGEX = /\s+/;
|
|
34
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
35
|
+
const SENTENCE_BOUNDARY_REGEX = /[\n.?!]+/;
|
|
36
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
37
|
+
const TRAILING_WHITESPACE_REGEX = /\s$/;
|
|
32
38
|
const MIN_PREFIX_LENGTH = 3;
|
|
33
39
|
const MAX_CANDIDATES = 200;
|
|
34
40
|
const CONTEXT_WORDS = 10;
|
|
@@ -235,8 +241,8 @@ const getContextVectorForScoring = textBefore => {
|
|
|
235
241
|
};
|
|
236
242
|
const tokenize = text => {
|
|
237
243
|
const tokens = [];
|
|
238
|
-
// eslint-disable-next-line
|
|
239
|
-
for (const raw of text.toLowerCase().split(
|
|
244
|
+
// eslint-disable-next-line @atlassian/perf-linting/no-expensive-split-replace
|
|
245
|
+
for (const raw of text.toLowerCase().split(WHITESPACE_SPLIT_REGEX)) {
|
|
240
246
|
// eslint-disable-next-line @atlassian/perf-linting/no-expensive-split-replace
|
|
241
247
|
const clean = raw.replace(PUNCTUATION_BOUNDARY_REGEX, '');
|
|
242
248
|
if (clean.length >= 2) {
|
|
@@ -247,12 +253,9 @@ const tokenize = text => {
|
|
|
247
253
|
};
|
|
248
254
|
const extractPreviousWord = text => {
|
|
249
255
|
// Only consider the current sentence/line the user is typing in.
|
|
250
|
-
|
|
251
|
-
const sentences = text.split(/[\n.?!]+/);
|
|
256
|
+
const sentences = text.split(SENTENCE_BOUNDARY_REGEX);
|
|
252
257
|
const currentSentence = sentences[sentences.length - 1];
|
|
253
|
-
|
|
254
|
-
// eslint-disable-next-line require-unicode-regexp
|
|
255
|
-
const words = currentSentence.trimEnd().split(/\s+/);
|
|
258
|
+
const words = currentSentence.trimEnd().split(WHITESPACE_SPLIT_REGEX);
|
|
256
259
|
return words.length >= 2 ? words[words.length - 2] : '';
|
|
257
260
|
};
|
|
258
261
|
|
|
@@ -373,8 +376,7 @@ export const predict = textBefore => {
|
|
|
373
376
|
// }
|
|
374
377
|
|
|
375
378
|
// ── Step 2: Prefix completion (≥3 chars typed) ──────────────────────────
|
|
376
|
-
|
|
377
|
-
if (textBefore.length > 0 && /\s$/.test(textBefore)) {
|
|
379
|
+
if (textBefore.length > 0 && TRAILING_WHITESPACE_REGEX.test(textBefore)) {
|
|
378
380
|
return null;
|
|
379
381
|
}
|
|
380
382
|
const trimmed = textBefore.trimEnd();
|
|
@@ -31,6 +31,11 @@ var MAX_INGESTED_CONTEXT_TEXTS = 50;
|
|
|
31
31
|
// non-comment editors (where parentCommentContent never arrives) don't refetch
|
|
32
32
|
// on every word boundary for the plugin's lifetime.
|
|
33
33
|
var MAX_CONTEXT_REFRESH_ATTEMPTS = 5;
|
|
34
|
+
|
|
35
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
36
|
+
var TRAILING_NON_BOUNDARY_TOKEN_REGEX = /([^\s.,;:!?]*)$/;
|
|
37
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
38
|
+
var WORD_BOUNDARY_CHARS_REGEX = /[\s.,;:!?]/;
|
|
34
39
|
var hasDestroy = function hasDestroy(client) {
|
|
35
40
|
return 'destroy' in client && typeof client.destroy === 'function';
|
|
36
41
|
};
|
|
@@ -218,9 +223,7 @@ var getTypedLengthForPrediction = function getTypedLengthForPrediction(textBefor
|
|
|
218
223
|
if (isWordBoundary(textBefore)) {
|
|
219
224
|
return 0;
|
|
220
225
|
}
|
|
221
|
-
|
|
222
|
-
// eslint-disable-next-line require-unicode-regexp
|
|
223
|
-
var trailingToken = (_textBefore$match$ = (_textBefore$match = textBefore.match(/([^\s.,;:!?]*)$/)) === null || _textBefore$match === void 0 ? void 0 : _textBefore$match[1]) !== null && _textBefore$match$ !== void 0 ? _textBefore$match$ : '';
|
|
226
|
+
var trailingToken = (_textBefore$match$ = (_textBefore$match = textBefore.match(TRAILING_NON_BOUNDARY_TOKEN_REGEX)) === null || _textBefore$match === void 0 ? void 0 : _textBefore$match[1]) !== null && _textBefore$match$ !== void 0 ? _textBefore$match$ : '';
|
|
224
227
|
return trailingToken.length;
|
|
225
228
|
};
|
|
226
229
|
var isEnglishLocale = function isEnglishLocale(locale) {
|
|
@@ -532,16 +535,14 @@ export var createAutocompletePlugin = function createAutocompletePlugin(options,
|
|
|
532
535
|
return;
|
|
533
536
|
}
|
|
534
537
|
var lastChar = newText[newText.length - 1];
|
|
535
|
-
|
|
536
|
-
if (!/[\s.,;:!?]/.test(lastChar)) {
|
|
538
|
+
if (!WORD_BOUNDARY_CHARS_REGEX.test(lastChar)) {
|
|
537
539
|
return;
|
|
538
540
|
}
|
|
539
541
|
|
|
540
542
|
// Only fire if the previous state did not already end on a boundary,
|
|
541
543
|
// so we don't double-count when multiple boundary chars are inserted.
|
|
542
544
|
var prevLastChar = prevText[prevText.length - 1];
|
|
543
|
-
|
|
544
|
-
if (prevLastChar && /[\s.,;:!?]/.test(prevLastChar)) {
|
|
545
|
+
if (prevLastChar && WORD_BOUNDARY_CHARS_REGEX.test(prevLastChar)) {
|
|
545
546
|
return;
|
|
546
547
|
}
|
|
547
548
|
var beforeBoundary = newText.slice(0, -1).trimEnd();
|
|
@@ -72,6 +72,8 @@ import { isWordBoundary } from './slow-lane-client';
|
|
|
72
72
|
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
73
73
|
|
|
74
74
|
var DEFAULT_DEBOUNCE_MS = 300;
|
|
75
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
76
|
+
var OOM_REGEX = /\boom\b/;
|
|
75
77
|
export var LOCAL_MLC_CAUSAL_MODEL_ID = 'SmolLM2-135M-Instruct-q0f16-MLC';
|
|
76
78
|
|
|
77
79
|
/**
|
|
@@ -756,9 +758,7 @@ export var createLocalSlowLaneClient = function createLocalSlowLaneClient() {
|
|
|
756
758
|
if (lower.includes('loading chunk') || lower.includes('dynamically imported module') || lower.includes('dynamic import')) {
|
|
757
759
|
return 'module_load_failed';
|
|
758
760
|
}
|
|
759
|
-
if (lower.includes('out of memory') ||
|
|
760
|
-
// eslint-disable-next-line require-unicode-regexp
|
|
761
|
-
/\boom\b/.test(lower) || lower.includes('allocation') || lower.includes('exceeds') || lower.includes('buffer size') || lower.includes('not enough memory')) {
|
|
761
|
+
if (lower.includes('out of memory') || OOM_REGEX.test(lower) || lower.includes('allocation') || lower.includes('exceeds') || lower.includes('buffer size') || lower.includes('not enough memory')) {
|
|
762
762
|
return 'insufficient_memory';
|
|
763
763
|
}
|
|
764
764
|
// Pre-flight already returns missing_shader_f16 when the feature is absent,
|
|
@@ -23,6 +23,8 @@ import { isAutocompleteDebugEnabled } from './debug-mode';
|
|
|
23
23
|
|
|
24
24
|
// eslint-disable-next-line require-unicode-regexp
|
|
25
25
|
var WORD_BOUNDARY_CHARS = /[\s.,;:!?]/;
|
|
26
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
27
|
+
var TRAILING_SLASH_REGEX = /\/$/;
|
|
26
28
|
var DEFAULT_DEBOUNCE_MS = 300;
|
|
27
29
|
|
|
28
30
|
/**
|
|
@@ -74,8 +76,7 @@ export var createSlowLaneClient = function createSlowLaneClient(config) {
|
|
|
74
76
|
}
|
|
75
77
|
return _context.abrupt("return");
|
|
76
78
|
case 1:
|
|
77
|
-
|
|
78
|
-
url = "".concat(baseUrl.replace(/\/$/, '')).concat(endpoint);
|
|
79
|
+
url = "".concat(baseUrl.replace(TRAILING_SLASH_REGEX, '')).concat(endpoint);
|
|
79
80
|
payload = {
|
|
80
81
|
text: text,
|
|
81
82
|
session_id: sessionId
|
|
@@ -38,6 +38,12 @@ import { getStoredContextVector, getStoredLmLogits } from './slow-lane-client';
|
|
|
38
38
|
|
|
39
39
|
// eslint-disable-next-line require-unicode-regexp
|
|
40
40
|
var PUNCTUATION_BOUNDARY_REGEX = /^[.,;:!?()\[\]{}"'`]+|[.,;:!?()\[\]{}"'`]+$/g;
|
|
41
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
42
|
+
var WHITESPACE_SPLIT_REGEX = /\s+/;
|
|
43
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
44
|
+
var SENTENCE_BOUNDARY_REGEX = /[\n.?!]+/;
|
|
45
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
46
|
+
var TRAILING_WHITESPACE_REGEX = /\s$/;
|
|
41
47
|
var MIN_PREFIX_LENGTH = 3;
|
|
42
48
|
var MAX_CANDIDATES = 200;
|
|
43
49
|
var CONTEXT_WORDS = 10;
|
|
@@ -308,8 +314,8 @@ var getContextVectorForScoring = function getContextVectorForScoring(textBefore)
|
|
|
308
314
|
};
|
|
309
315
|
var tokenize = function tokenize(text) {
|
|
310
316
|
var tokens = [];
|
|
311
|
-
// eslint-disable-next-line
|
|
312
|
-
var _iterator7 = _createForOfIteratorHelper(text.toLowerCase().split(
|
|
317
|
+
// eslint-disable-next-line @atlassian/perf-linting/no-expensive-split-replace
|
|
318
|
+
var _iterator7 = _createForOfIteratorHelper(text.toLowerCase().split(WHITESPACE_SPLIT_REGEX)),
|
|
313
319
|
_step7;
|
|
314
320
|
try {
|
|
315
321
|
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
|
|
@@ -329,12 +335,9 @@ var tokenize = function tokenize(text) {
|
|
|
329
335
|
};
|
|
330
336
|
var extractPreviousWord = function extractPreviousWord(text) {
|
|
331
337
|
// Only consider the current sentence/line the user is typing in.
|
|
332
|
-
|
|
333
|
-
var sentences = text.split(/[\n.?!]+/);
|
|
338
|
+
var sentences = text.split(SENTENCE_BOUNDARY_REGEX);
|
|
334
339
|
var currentSentence = sentences[sentences.length - 1];
|
|
335
|
-
|
|
336
|
-
// eslint-disable-next-line require-unicode-regexp
|
|
337
|
-
var words = currentSentence.trimEnd().split(/\s+/);
|
|
340
|
+
var words = currentSentence.trimEnd().split(WHITESPACE_SPLIT_REGEX);
|
|
338
341
|
return words.length >= 2 ? words[words.length - 2] : '';
|
|
339
342
|
};
|
|
340
343
|
|
|
@@ -473,8 +476,7 @@ export var predict = function predict(textBefore) {
|
|
|
473
476
|
// }
|
|
474
477
|
|
|
475
478
|
// ── Step 2: Prefix completion (≥3 chars typed) ──────────────────────────
|
|
476
|
-
|
|
477
|
-
if (textBefore.length > 0 && /\s$/.test(textBefore)) {
|
|
479
|
+
if (textBefore.length > 0 && TRAILING_WHITESPACE_REGEX.test(textBefore)) {
|
|
478
480
|
return null;
|
|
479
481
|
}
|
|
480
482
|
var trimmed = textBefore.trimEnd();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-autocomplete",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.5",
|
|
4
4
|
"description": "Client-side text autocomplete plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"wink-nlp": "^2.4.0"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
|
-
"@atlaskit/editor-common": "^116.
|
|
30
|
+
"@atlaskit/editor-common": "^116.17.0",
|
|
31
31
|
"@atlaskit/editor-plugin-analytics": "^12.0.0",
|
|
32
32
|
"react": "^18.2.0"
|
|
33
33
|
},
|
|
@@ -48,6 +48,11 @@ const MAX_INGESTED_CONTEXT_TEXTS = 50;
|
|
|
48
48
|
// on every word boundary for the plugin's lifetime.
|
|
49
49
|
const MAX_CONTEXT_REFRESH_ATTEMPTS = 5;
|
|
50
50
|
|
|
51
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
52
|
+
const TRAILING_NON_BOUNDARY_TOKEN_REGEX = /([^\s.,;:!?]*)$/;
|
|
53
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
54
|
+
const WORD_BOUNDARY_CHARS_REGEX = /[\s.,;:!?]/;
|
|
55
|
+
|
|
51
56
|
const hasDestroy = (
|
|
52
57
|
client: ReturnType<typeof createSlowLaneClient> | LocalSlowLaneClient,
|
|
53
58
|
): client is LocalSlowLaneClient => 'destroy' in client && typeof client.destroy === 'function';
|
|
@@ -305,8 +310,7 @@ const getTypedLengthForPrediction = (textBefore: string): number => {
|
|
|
305
310
|
return 0;
|
|
306
311
|
}
|
|
307
312
|
|
|
308
|
-
|
|
309
|
-
const trailingToken = textBefore.match(/([^\s.,;:!?]*)$/)?.[1] ?? '';
|
|
313
|
+
const trailingToken = textBefore.match(TRAILING_NON_BOUNDARY_TOKEN_REGEX)?.[1] ?? '';
|
|
310
314
|
return trailingToken.length;
|
|
311
315
|
};
|
|
312
316
|
|
|
@@ -647,16 +651,14 @@ export const createAutocompletePlugin = (
|
|
|
647
651
|
}
|
|
648
652
|
|
|
649
653
|
const lastChar = newText[newText.length - 1];
|
|
650
|
-
|
|
651
|
-
if (!/[\s.,;:!?]/.test(lastChar)) {
|
|
654
|
+
if (!WORD_BOUNDARY_CHARS_REGEX.test(lastChar)) {
|
|
652
655
|
return;
|
|
653
656
|
}
|
|
654
657
|
|
|
655
658
|
// Only fire if the previous state did not already end on a boundary,
|
|
656
659
|
// so we don't double-count when multiple boundary chars are inserted.
|
|
657
660
|
const prevLastChar = prevText[prevText.length - 1];
|
|
658
|
-
|
|
659
|
-
if (prevLastChar && /[\s.,;:!?]/.test(prevLastChar)) {
|
|
661
|
+
if (prevLastChar && WORD_BOUNDARY_CHARS_REGEX.test(prevLastChar)) {
|
|
660
662
|
return;
|
|
661
663
|
}
|
|
662
664
|
|
|
@@ -174,6 +174,8 @@ interface MinimalGpu {
|
|
|
174
174
|
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
175
175
|
|
|
176
176
|
const DEFAULT_DEBOUNCE_MS = 300;
|
|
177
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
178
|
+
const OOM_REGEX = /\boom\b/;
|
|
177
179
|
|
|
178
180
|
export const LOCAL_MLC_CAUSAL_MODEL_ID = 'SmolLM2-135M-Instruct-q0f16-MLC';
|
|
179
181
|
|
|
@@ -769,8 +771,7 @@ export const createLocalSlowLaneClient = (
|
|
|
769
771
|
}
|
|
770
772
|
if (
|
|
771
773
|
lower.includes('out of memory') ||
|
|
772
|
-
|
|
773
|
-
/\boom\b/.test(lower) ||
|
|
774
|
+
OOM_REGEX.test(lower) ||
|
|
774
775
|
lower.includes('allocation') ||
|
|
775
776
|
lower.includes('exceeds') ||
|
|
776
777
|
lower.includes('buffer size') ||
|
|
@@ -29,6 +29,8 @@ export interface TypeaheadEncodingsResponse {
|
|
|
29
29
|
|
|
30
30
|
// eslint-disable-next-line require-unicode-regexp
|
|
31
31
|
const WORD_BOUNDARY_CHARS = /[\s.,;:!?]/;
|
|
32
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
33
|
+
const TRAILING_SLASH_REGEX = /\/$/;
|
|
32
34
|
const DEFAULT_DEBOUNCE_MS = 300;
|
|
33
35
|
|
|
34
36
|
/**
|
|
@@ -94,8 +96,7 @@ export const createSlowLaneClient = (
|
|
|
94
96
|
return;
|
|
95
97
|
}
|
|
96
98
|
|
|
97
|
-
|
|
98
|
-
const url = `${baseUrl.replace(/\/$/, '')}${endpoint}`;
|
|
99
|
+
const url = `${baseUrl.replace(TRAILING_SLASH_REGEX, '')}${endpoint}`;
|
|
99
100
|
const payload: TypeaheadEncodingsRequest = {
|
|
100
101
|
text,
|
|
101
102
|
session_id: sessionId,
|
|
@@ -29,6 +29,12 @@ import { getStoredContextVector, getStoredLmLogits } from './slow-lane-client';
|
|
|
29
29
|
|
|
30
30
|
// eslint-disable-next-line require-unicode-regexp
|
|
31
31
|
const PUNCTUATION_BOUNDARY_REGEX = /^[.,;:!?()\[\]{}"'`]+|[.,;:!?()\[\]{}"'`]+$/g;
|
|
32
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
33
|
+
const WHITESPACE_SPLIT_REGEX = /\s+/;
|
|
34
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
35
|
+
const SENTENCE_BOUNDARY_REGEX = /[\n.?!]+/;
|
|
36
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
37
|
+
const TRAILING_WHITESPACE_REGEX = /\s$/;
|
|
32
38
|
|
|
33
39
|
const MIN_PREFIX_LENGTH = 3;
|
|
34
40
|
const MAX_CANDIDATES = 200;
|
|
@@ -275,8 +281,8 @@ const getContextVectorForScoring = (textBefore: string): Float32Array | null =>
|
|
|
275
281
|
|
|
276
282
|
const tokenize = (text: string): string[] => {
|
|
277
283
|
const tokens: string[] = [];
|
|
278
|
-
// eslint-disable-next-line
|
|
279
|
-
for (const raw of text.toLowerCase().split(
|
|
284
|
+
// eslint-disable-next-line @atlassian/perf-linting/no-expensive-split-replace
|
|
285
|
+
for (const raw of text.toLowerCase().split(WHITESPACE_SPLIT_REGEX)) {
|
|
280
286
|
// eslint-disable-next-line @atlassian/perf-linting/no-expensive-split-replace
|
|
281
287
|
const clean = raw.replace(PUNCTUATION_BOUNDARY_REGEX, '');
|
|
282
288
|
if (clean.length >= 2) {
|
|
@@ -288,12 +294,10 @@ const tokenize = (text: string): string[] => {
|
|
|
288
294
|
|
|
289
295
|
const extractPreviousWord = (text: string): string => {
|
|
290
296
|
// Only consider the current sentence/line the user is typing in.
|
|
291
|
-
|
|
292
|
-
const sentences = text.split(/[\n.?!]+/);
|
|
297
|
+
const sentences = text.split(SENTENCE_BOUNDARY_REGEX);
|
|
293
298
|
const currentSentence = sentences[sentences.length - 1];
|
|
294
299
|
|
|
295
|
-
|
|
296
|
-
const words = currentSentence.trimEnd().split(/\s+/);
|
|
300
|
+
const words = currentSentence.trimEnd().split(WHITESPACE_SPLIT_REGEX);
|
|
297
301
|
return words.length >= 2 ? words[words.length - 2] : '';
|
|
298
302
|
};
|
|
299
303
|
|
|
@@ -442,8 +446,7 @@ export const predict = (textBefore: string): string | null => {
|
|
|
442
446
|
// }
|
|
443
447
|
|
|
444
448
|
// ── Step 2: Prefix completion (≥3 chars typed) ──────────────────────────
|
|
445
|
-
|
|
446
|
-
if (textBefore.length > 0 && /\s$/.test(textBefore)) {
|
|
449
|
+
if (textBefore.length > 0 && TRAILING_WHITESPACE_REGEX.test(textBefore)) {
|
|
447
450
|
return null;
|
|
448
451
|
}
|
|
449
452
|
|