@atlaskit/editor-plugin-autocomplete 2.5.2 → 3.1.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/CANONICAL_FIX__DO_NOT_USE_ME_A/package.json +15 -0
- package/CANONICAL_FIX__DO_NOT_USE_ME_B/package.json +15 -0
- package/CANONICAL_FIX__DO_NOT_USE_ME_C/package.json +15 -0
- package/CHANGELOG.md +14 -0
- package/dist/cjs/pm-plugins/autocomplete-plugin.js +6 -22
- package/dist/cjs/pm-plugins/local-slow-lane-client.js +36 -36
- package/dist/cjs/pm-plugins/scoring-pipeline.js +5 -4
- package/dist/cjs/pm-plugins/slow-lane-client.js +20 -20
- package/dist/cjs/pm-plugins/text-predictor.js +175 -83
- package/dist/es2019/pm-plugins/autocomplete-plugin.js +6 -22
- package/dist/es2019/pm-plugins/scoring-pipeline.js +5 -4
- package/dist/es2019/pm-plugins/text-predictor.js +105 -50
- package/dist/esm/pm-plugins/autocomplete-plugin.js +6 -22
- package/dist/esm/pm-plugins/local-slow-lane-client.js +35 -35
- package/dist/esm/pm-plugins/scoring-pipeline.js +5 -4
- package/dist/esm/pm-plugins/slow-lane-client.js +20 -20
- package/dist/esm/pm-plugins/text-predictor.js +167 -83
- package/dist/types/pm-plugins/text-predictor.d.ts +1 -1
- package/dist/types-ts4.5/pm-plugins/text-predictor.d.ts +1 -1
- package/package.json +3 -3
- package/src/pm-plugins/autocomplete-plugin.ts +6 -16
- package/src/pm-plugins/data/word_index_10k.json +7761 -7759
- package/src/pm-plugins/scoring-pipeline.ts +4 -5
- package/src/pm-plugins/text-predictor.ts +124 -45
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
|
+
import _typeof from "@babel/runtime/helpers/typeof";
|
|
2
3
|
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
3
4
|
import _createClass from "@babel/runtime/helpers/createClass";
|
|
4
5
|
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
@@ -26,11 +27,9 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
|
|
|
26
27
|
|
|
27
28
|
import { EXPERIENCE_NAME, failExp, startExp, succeedExp } from '../analytics/ufo';
|
|
28
29
|
|
|
29
|
-
//
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
import wordIndexData from './data/word_index_10k.json';
|
|
33
|
-
// import { rankCandidates, isGrammarAllowed } from './scoring-pipeline';
|
|
30
|
+
// The vocabulary, L3 and word-index JSON payloads are dynamically imported in
|
|
31
|
+
// loadDefaultVocabulary / loadVectorsAsync so their (large) contents stay out of
|
|
32
|
+
// the editor's main chunk and only load when autocomplete is initialised.
|
|
34
33
|
import { isAutocompleteDebugEnabled } from './debug-mode';
|
|
35
34
|
import { rankCandidates, STAGE1_WEIGHT, STAGE2_WEIGHT, MIN_STAGE1_SCORE } from './scoring-pipeline';
|
|
36
35
|
import { getStoredContextVector, getStoredLmLogits } from './slow-lane-client';
|
|
@@ -42,7 +41,7 @@ var PUNCTUATION_BOUNDARY_REGEX = /^[.,;:!?()\[\]{}"'`]+|[.,;:!?()\[\]{}"'`]+$/g;
|
|
|
42
41
|
var MIN_PREFIX_LENGTH = 3;
|
|
43
42
|
var MAX_CANDIDATES = 200;
|
|
44
43
|
var CONTEXT_WORDS = 10;
|
|
45
|
-
var MIN_SCORE_THRESHOLD = 0.
|
|
44
|
+
var MIN_SCORE_THRESHOLD = 0.35;
|
|
46
45
|
var L3_BASELINE_FREQ = 0.001;
|
|
47
46
|
|
|
48
47
|
// ─── Types ───────────────────────────────────────────────────────────────────
|
|
@@ -206,7 +205,6 @@ var wordTrie = new WeightedWordTrie();
|
|
|
206
205
|
// L3 Trie (General English Fallback)
|
|
207
206
|
var l3Trie = new WeightedWordTrie();
|
|
208
207
|
|
|
209
|
-
// --- Initialization Function ---
|
|
210
208
|
/**
|
|
211
209
|
* Loads the General English vocabulary.
|
|
212
210
|
* expects a simple array of strings: ["about", "above", "actually", ...]
|
|
@@ -330,14 +328,11 @@ var tokenize = function tokenize(text) {
|
|
|
330
328
|
return tokens;
|
|
331
329
|
};
|
|
332
330
|
var extractPreviousWord = function extractPreviousWord(text) {
|
|
333
|
-
//
|
|
331
|
+
// Only consider the current sentence/line the user is typing in.
|
|
334
332
|
// eslint-disable-next-line require-unicode-regexp
|
|
335
333
|
var sentences = text.split(/[\n.?!]+/);
|
|
336
|
-
|
|
337
|
-
// 2. Only look at the current sentence/line the user is typing in
|
|
338
334
|
var currentSentence = sentences[sentences.length - 1];
|
|
339
335
|
|
|
340
|
-
// 3. Extract the previous word as normal
|
|
341
336
|
// eslint-disable-next-line require-unicode-regexp
|
|
342
337
|
var words = currentSentence.trimEnd().split(/\s+/);
|
|
343
338
|
return words.length >= 2 ? words[words.length - 2] : '';
|
|
@@ -400,7 +395,6 @@ export var incrementSessionFreq = function incrementSessionFreq(word) {
|
|
|
400
395
|
* Pass `undefined` (or omit the argument) to skip priming — useful when the
|
|
401
396
|
* calling context does not yet have a page value available.
|
|
402
397
|
*/
|
|
403
|
-
// NOTE: We ingest full page context here
|
|
404
398
|
export var ingestDocumentPage = function ingestDocumentPage(pageContent) {
|
|
405
399
|
if (!pageContent) {
|
|
406
400
|
return;
|
|
@@ -433,7 +427,11 @@ export var ingestDocumentPage = function ingestDocumentPage(pageContent) {
|
|
|
433
427
|
};
|
|
434
428
|
export var predict = function predict(textBefore) {
|
|
435
429
|
if (!isInitialized) {
|
|
436
|
-
|
|
430
|
+
// Vocabulary JSON is code-split and loads asynchronously. Kick off the load
|
|
431
|
+
// and skip this keystroke; the plugin also primes it on focus, so the tries
|
|
432
|
+
// are usually ready before the user types.
|
|
433
|
+
void loadDefaultVocabulary().catch(function () {});
|
|
434
|
+
return null;
|
|
437
435
|
}
|
|
438
436
|
var t0 = performance.now();
|
|
439
437
|
|
|
@@ -485,14 +483,11 @@ export var predict = function predict(textBefore) {
|
|
|
485
483
|
if (currentWord.length < MIN_PREFIX_LENGTH) {
|
|
486
484
|
return null;
|
|
487
485
|
}
|
|
488
|
-
|
|
489
|
-
// 1. Primary Query: Ask the L2 Domain Trie
|
|
490
486
|
var candidates = wordTrie.getCandidates(currentWord, MAX_CANDIDATES);
|
|
491
487
|
|
|
492
|
-
//
|
|
488
|
+
// Gap-fill from the L3 general-English trie, requesting a full buffer so
|
|
489
|
+
// enough survive de-duplication against the L2 results.
|
|
493
490
|
if (candidates.length < MAX_CANDIDATES) {
|
|
494
|
-
// Ask L3 for MAX_CANDIDATES to guarantee we have enough buffer
|
|
495
|
-
// to survive the deduplication process.
|
|
496
491
|
var l3Candidates = l3Trie.getCandidates(currentWord, MAX_CANDIDATES);
|
|
497
492
|
var existingWords = new Set(candidates.map(function (c) {
|
|
498
493
|
return c.word;
|
|
@@ -502,8 +497,7 @@ export var predict = function predict(textBefore) {
|
|
|
502
497
|
try {
|
|
503
498
|
for (_iterator0.s(); !(_step0 = _iterator0.n()).done;) {
|
|
504
499
|
var l3c = _step0.value;
|
|
505
|
-
if (candidates.length >= MAX_CANDIDATES) break;
|
|
506
|
-
|
|
500
|
+
if (candidates.length >= MAX_CANDIDATES) break;
|
|
507
501
|
if (!existingWords.has(l3c.word)) {
|
|
508
502
|
candidates.push(l3c);
|
|
509
503
|
}
|
|
@@ -687,53 +681,99 @@ export var predict = function predict(textBefore) {
|
|
|
687
681
|
|
|
688
682
|
// ─── Data Loading ────────────────────────────────────────────────────────────
|
|
689
683
|
|
|
684
|
+
/**
|
|
685
|
+
* Unwrap a dynamically imported JSON module to its parsed value, handling both
|
|
686
|
+
* interop modes AFM's bundler chain emits: a `.default`-wrapped namespace
|
|
687
|
+
* (classic webpack) and a named-exports namespace (webpack 5 / atlaspack JSON
|
|
688
|
+
* modules, where `default` can be a misleading scalar). Named exports are
|
|
689
|
+
* preferred when present. The caller declares the JSON `shape` because a dense
|
|
690
|
+
* array and a sparse numeric-keyed object are emitted identically as named
|
|
691
|
+
* exports. Kept in lock-step with the matching helper in local-slow-lane-client.ts.
|
|
692
|
+
*/
|
|
693
|
+
var unwrapJsonModule = function unwrapJsonModule(mod, shape) {
|
|
694
|
+
if (mod == null || _typeof(mod) !== 'object') {
|
|
695
|
+
return null;
|
|
696
|
+
}
|
|
697
|
+
var namespace = mod;
|
|
698
|
+
var ownKeys = Object.keys(namespace).filter(function (k) {
|
|
699
|
+
return k !== 'default' && k !== '__esModule';
|
|
700
|
+
});
|
|
701
|
+
if (ownKeys.length > 0) {
|
|
702
|
+
if (shape === 'array') {
|
|
703
|
+
var len = ownKeys.length;
|
|
704
|
+
var arr = new Array(len);
|
|
705
|
+
for (var i = 0; i < len; i++) {
|
|
706
|
+
arr[i] = namespace[String(i)];
|
|
707
|
+
}
|
|
708
|
+
return arr;
|
|
709
|
+
}
|
|
710
|
+
var obj = {};
|
|
711
|
+
var _iterator1 = _createForOfIteratorHelper(ownKeys),
|
|
712
|
+
_step1;
|
|
713
|
+
try {
|
|
714
|
+
for (_iterator1.s(); !(_step1 = _iterator1.n()).done;) {
|
|
715
|
+
var k = _step1.value;
|
|
716
|
+
obj[k] = namespace[k];
|
|
717
|
+
}
|
|
718
|
+
} catch (err) {
|
|
719
|
+
_iterator1.e(err);
|
|
720
|
+
} finally {
|
|
721
|
+
_iterator1.f();
|
|
722
|
+
}
|
|
723
|
+
return obj;
|
|
724
|
+
}
|
|
725
|
+
if ('default' in namespace && namespace.default != null) {
|
|
726
|
+
return namespace.default;
|
|
727
|
+
}
|
|
728
|
+
return null;
|
|
729
|
+
};
|
|
690
730
|
export var loadVectorsAsync = /*#__PURE__*/function () {
|
|
691
731
|
var _ref6 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(options) {
|
|
692
|
-
var url, res, buffer, float32, wordIndex, nWords, dim;
|
|
693
|
-
return _regeneratorRuntime.wrap(function
|
|
732
|
+
var url, _wordIndexOuter$index, res, buffer, float32, wordIndexModule, wordIndexOuter, wordIndex, nWords, dim, _t, _t2;
|
|
733
|
+
return _regeneratorRuntime.wrap(function (_context) {
|
|
694
734
|
while (1) switch (_context.prev = _context.next) {
|
|
695
735
|
case 0:
|
|
696
736
|
if (!(vectorStore || vectorsLoadStarted)) {
|
|
697
|
-
_context.next =
|
|
737
|
+
_context.next = 1;
|
|
698
738
|
break;
|
|
699
739
|
}
|
|
700
740
|
return _context.abrupt("return");
|
|
701
|
-
case
|
|
741
|
+
case 1:
|
|
702
742
|
if (options !== null && options !== void 0 && options.getBinaryUrl) {
|
|
703
|
-
_context.next =
|
|
743
|
+
_context.next = 2;
|
|
704
744
|
break;
|
|
705
745
|
}
|
|
706
746
|
// eslint-disable-next-line no-console
|
|
707
747
|
console.warn('[text-predictor] loadVectorsAsync called without a getBinaryUrl — vectors will not load. Pass getVectorsBinaryUrl via plugin options.');
|
|
708
748
|
return _context.abrupt("return");
|
|
709
|
-
case
|
|
749
|
+
case 2:
|
|
710
750
|
vectorsLoadStarted = true;
|
|
711
751
|
startExp(EXPERIENCE_NAME.LOAD_VECTORS, 'singleton');
|
|
712
|
-
_context.prev =
|
|
713
|
-
_context.next =
|
|
752
|
+
_context.prev = 3;
|
|
753
|
+
_context.next = 4;
|
|
714
754
|
return options.getBinaryUrl();
|
|
715
|
-
case
|
|
755
|
+
case 4:
|
|
716
756
|
url = _context.sent;
|
|
717
|
-
_context.next =
|
|
757
|
+
_context.next = 6;
|
|
718
758
|
break;
|
|
719
|
-
case
|
|
720
|
-
_context.prev =
|
|
721
|
-
|
|
759
|
+
case 5:
|
|
760
|
+
_context.prev = 5;
|
|
761
|
+
_t = _context["catch"](3);
|
|
722
762
|
vectorsLoadStarted = false;
|
|
723
763
|
failExp(EXPERIENCE_NAME.LOAD_VECTORS, 'singleton', {
|
|
724
764
|
errorType: 'resolve_url'
|
|
725
765
|
});
|
|
726
766
|
// eslint-disable-next-line no-console
|
|
727
|
-
console.warn('[text-predictor] Failed to resolve vectors URL:',
|
|
767
|
+
console.warn('[text-predictor] Failed to resolve vectors URL:', _t);
|
|
728
768
|
return _context.abrupt("return");
|
|
729
|
-
case
|
|
730
|
-
_context.prev =
|
|
731
|
-
_context.next =
|
|
769
|
+
case 6:
|
|
770
|
+
_context.prev = 6;
|
|
771
|
+
_context.next = 7;
|
|
732
772
|
return fetch(url);
|
|
733
|
-
case
|
|
773
|
+
case 7:
|
|
734
774
|
res = _context.sent;
|
|
735
775
|
if (res.ok) {
|
|
736
|
-
_context.next =
|
|
776
|
+
_context.next = 8;
|
|
737
777
|
break;
|
|
738
778
|
}
|
|
739
779
|
vectorsLoadStarted = false;
|
|
@@ -744,14 +784,25 @@ export var loadVectorsAsync = /*#__PURE__*/function () {
|
|
|
744
784
|
// eslint-disable-next-line no-console
|
|
745
785
|
console.warn("[text-predictor] Failed to load vectors: ".concat(res.status));
|
|
746
786
|
return _context.abrupt("return");
|
|
747
|
-
case
|
|
748
|
-
_context.next =
|
|
787
|
+
case 8:
|
|
788
|
+
_context.next = 9;
|
|
749
789
|
return res.arrayBuffer();
|
|
750
|
-
case
|
|
790
|
+
case 9:
|
|
751
791
|
buffer = _context.sent;
|
|
752
|
-
float32 = new Float32Array(buffer);
|
|
753
|
-
|
|
792
|
+
float32 = new Float32Array(buffer); // word_index_10k.json is wrapped as `{ "index": {…} }` so no real entry
|
|
793
|
+
// (e.g. the word "default") can shadow the synthetic ESM `default` export
|
|
794
|
+
// the bundler creates for dynamically-imported JSON.
|
|
795
|
+
_context.next = 10;
|
|
796
|
+
return import( /* webpackChunkName: "@atlaskit-internal_editor-plugin-autocomplete-word-index-10k" */'./data/word_index_10k.json');
|
|
797
|
+
case 10:
|
|
798
|
+
wordIndexModule = _context.sent;
|
|
799
|
+
wordIndexOuter = unwrapJsonModule(wordIndexModule, 'object');
|
|
800
|
+
wordIndex = (_wordIndexOuter$index = wordIndexOuter === null || wordIndexOuter === void 0 ? void 0 : wordIndexOuter.index) !== null && _wordIndexOuter$index !== void 0 ? _wordIndexOuter$index : {};
|
|
754
801
|
nWords = Object.keys(wordIndex).length;
|
|
802
|
+
if (nWords === 0) {
|
|
803
|
+
// eslint-disable-next-line no-console
|
|
804
|
+
console.warn('[text-predictor] word_index_10k.json missing its `index` wrapper — wordIndex is empty, semantic scoring will be a no-op.');
|
|
805
|
+
}
|
|
755
806
|
dim = float32.length / nWords;
|
|
756
807
|
vectorStore = {
|
|
757
808
|
float32: float32,
|
|
@@ -771,22 +822,22 @@ export var loadVectorsAsync = /*#__PURE__*/function () {
|
|
|
771
822
|
sizeBytes: float32.byteLength
|
|
772
823
|
});
|
|
773
824
|
}
|
|
774
|
-
_context.next =
|
|
825
|
+
_context.next = 12;
|
|
775
826
|
break;
|
|
776
|
-
case
|
|
777
|
-
_context.prev =
|
|
778
|
-
|
|
827
|
+
case 11:
|
|
828
|
+
_context.prev = 11;
|
|
829
|
+
_t2 = _context["catch"](6);
|
|
779
830
|
vectorsLoadStarted = false;
|
|
780
831
|
failExp(EXPERIENCE_NAME.LOAD_VECTORS, 'singleton', {
|
|
781
832
|
errorType: 'network'
|
|
782
833
|
});
|
|
783
834
|
// eslint-disable-next-line no-console
|
|
784
|
-
console.warn('[text-predictor] Failed to load vectors:',
|
|
785
|
-
case
|
|
835
|
+
console.warn('[text-predictor] Failed to load vectors:', _t2);
|
|
836
|
+
case 12:
|
|
786
837
|
case "end":
|
|
787
838
|
return _context.stop();
|
|
788
839
|
}
|
|
789
|
-
}, _callee, null, [[
|
|
840
|
+
}, _callee, null, [[3, 5], [6, 11]]);
|
|
790
841
|
}));
|
|
791
842
|
return function loadVectorsAsync(_x) {
|
|
792
843
|
return _ref6.apply(this, arguments);
|
|
@@ -795,40 +846,73 @@ export var loadVectorsAsync = /*#__PURE__*/function () {
|
|
|
795
846
|
export var initVectors = function initVectors(store) {
|
|
796
847
|
vectorStore = store;
|
|
797
848
|
};
|
|
849
|
+
var vocabularyLoadPromise;
|
|
798
850
|
export var loadDefaultVocabulary = function loadDefaultVocabulary() {
|
|
799
851
|
if (isInitialized) {
|
|
800
|
-
return;
|
|
852
|
+
return Promise.resolve();
|
|
801
853
|
}
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
// 1. Load the Atlassian Domain (L2)
|
|
805
|
-
var data = vocabularyData;
|
|
806
|
-
var terms = Object.entries(data.words).map(function (_ref7) {
|
|
807
|
-
var _ref8 = _slicedToArray(_ref7, 2),
|
|
808
|
-
word = _ref8[0],
|
|
809
|
-
stats = _ref8[1];
|
|
810
|
-
return {
|
|
811
|
-
word: word,
|
|
812
|
-
freq: stats.freq,
|
|
813
|
-
docFreq: stats.doc_freq,
|
|
814
|
-
authorFreq: stats.author_freq
|
|
815
|
-
};
|
|
816
|
-
});
|
|
817
|
-
initVocabulary({
|
|
818
|
-
terms: terms
|
|
819
|
-
});
|
|
820
|
-
|
|
821
|
-
// 2. Load General English (L3)
|
|
822
|
-
var l3Words = l3VocabularyData;
|
|
823
|
-
initL3Vocabulary(l3Words);
|
|
824
|
-
succeedExp(EXPERIENCE_NAME.LOAD_VOCABULARY, 'singleton', {
|
|
825
|
-
l2WordCount: terms.length,
|
|
826
|
-
l3WordCount: l3Words.length
|
|
827
|
-
});
|
|
828
|
-
} catch (e) {
|
|
829
|
-
failExp(EXPERIENCE_NAME.LOAD_VOCABULARY, 'singleton', {
|
|
830
|
-
errorType: 'parse_error'
|
|
831
|
-
});
|
|
832
|
-
throw e;
|
|
854
|
+
if (vocabularyLoadPromise) {
|
|
855
|
+
return vocabularyLoadPromise;
|
|
833
856
|
}
|
|
857
|
+
vocabularyLoadPromise = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
|
|
858
|
+
var _yield$Promise$all, _yield$Promise$all2, vocabularyModule, l3VocabularyModule, vocabularyData, l3VocabularyData, terms, _t3;
|
|
859
|
+
return _regeneratorRuntime.wrap(function (_context2) {
|
|
860
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
861
|
+
case 0:
|
|
862
|
+
startExp(EXPERIENCE_NAME.LOAD_VOCABULARY, 'singleton');
|
|
863
|
+
_context2.prev = 1;
|
|
864
|
+
_context2.next = 2;
|
|
865
|
+
return Promise.all([import( /* webpackChunkName: "@atlaskit-internal_editor-plugin-autocomplete-vocabulary-10k" */'./data/vocabulary_10k.json'), import( /* webpackChunkName: "@atlaskit-internal_editor-plugin-autocomplete-l3-vocabulary" */'./data/l3_vocabulary.json')]);
|
|
866
|
+
case 2:
|
|
867
|
+
_yield$Promise$all = _context2.sent;
|
|
868
|
+
_yield$Promise$all2 = _slicedToArray(_yield$Promise$all, 2);
|
|
869
|
+
vocabularyModule = _yield$Promise$all2[0];
|
|
870
|
+
l3VocabularyModule = _yield$Promise$all2[1];
|
|
871
|
+
vocabularyData = unwrapJsonModule(vocabularyModule, 'object');
|
|
872
|
+
l3VocabularyData = unwrapJsonModule(l3VocabularyModule, 'array');
|
|
873
|
+
if (!((vocabularyData === null || vocabularyData === void 0 ? void 0 : vocabularyData.words) == null || !Array.isArray(l3VocabularyData))) {
|
|
874
|
+
_context2.next = 3;
|
|
875
|
+
break;
|
|
876
|
+
}
|
|
877
|
+
throw new Error('[text-predictor] vocabulary JSON modules could not be unwrapped');
|
|
878
|
+
case 3:
|
|
879
|
+
terms = Object.entries(vocabularyData.words).map(function (_ref8) {
|
|
880
|
+
var _ref9 = _slicedToArray(_ref8, 2),
|
|
881
|
+
word = _ref9[0],
|
|
882
|
+
stats = _ref9[1];
|
|
883
|
+
return {
|
|
884
|
+
word: word,
|
|
885
|
+
freq: stats.freq,
|
|
886
|
+
docFreq: stats.doc_freq,
|
|
887
|
+
authorFreq: stats.author_freq
|
|
888
|
+
};
|
|
889
|
+
}); // Load L3 before L2: initVocabulary flips `isInitialized = true`, so it
|
|
890
|
+
// must run last — otherwise a throw in initL3Vocabulary would strand
|
|
891
|
+
// `isInitialized` true and the retry path could never reload L3.
|
|
892
|
+
initL3Vocabulary(l3VocabularyData);
|
|
893
|
+
initVocabulary({
|
|
894
|
+
terms: terms
|
|
895
|
+
});
|
|
896
|
+
succeedExp(EXPERIENCE_NAME.LOAD_VOCABULARY, 'singleton', {
|
|
897
|
+
l2WordCount: terms.length,
|
|
898
|
+
l3WordCount: l3VocabularyData.length
|
|
899
|
+
});
|
|
900
|
+
_context2.next = 5;
|
|
901
|
+
break;
|
|
902
|
+
case 4:
|
|
903
|
+
_context2.prev = 4;
|
|
904
|
+
_t3 = _context2["catch"](1);
|
|
905
|
+
failExp(EXPERIENCE_NAME.LOAD_VOCABULARY, 'singleton', {
|
|
906
|
+
errorType: 'parse_error'
|
|
907
|
+
});
|
|
908
|
+
// Allow a later call to retry the load rather than caching the failure.
|
|
909
|
+
vocabularyLoadPromise = undefined;
|
|
910
|
+
throw _t3;
|
|
911
|
+
case 5:
|
|
912
|
+
case "end":
|
|
913
|
+
return _context2.stop();
|
|
914
|
+
}
|
|
915
|
+
}, _callee2, null, [[1, 4]]);
|
|
916
|
+
}))();
|
|
917
|
+
return vocabularyLoadPromise;
|
|
834
918
|
};
|
|
@@ -84,5 +84,5 @@ export declare const loadVectorsAsync: (options?: {
|
|
|
84
84
|
getBinaryUrl?: () => Promise<string>;
|
|
85
85
|
}) => Promise<void>;
|
|
86
86
|
export declare const initVectors: (store: VectorStore) => void;
|
|
87
|
-
export declare const loadDefaultVocabulary: () => void
|
|
87
|
+
export declare const loadDefaultVocabulary: () => Promise<void>;
|
|
88
88
|
export {};
|
|
@@ -84,5 +84,5 @@ export declare const loadVectorsAsync: (options?: {
|
|
|
84
84
|
getBinaryUrl?: () => Promise<string>;
|
|
85
85
|
}) => Promise<void>;
|
|
86
86
|
export declare const initVectors: (store: VectorStore) => void;
|
|
87
|
-
export declare const loadDefaultVocabulary: () => void
|
|
87
|
+
export declare const loadDefaultVocabulary: () => Promise<void>;
|
|
88
88
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-autocomplete",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.1.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",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"wink-nlp": "^2.4.0"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"@atlaskit/editor-common": "^
|
|
39
|
-
"@atlaskit/editor-plugin-analytics": "^
|
|
38
|
+
"@atlaskit/editor-common": "^115.6.0",
|
|
39
|
+
"@atlaskit/editor-plugin-analytics": "^11.0.0",
|
|
40
40
|
"react": "^18.2.0"
|
|
41
41
|
},
|
|
42
42
|
"techstack": {
|
|
@@ -56,7 +56,6 @@ const getTextBeforeCursor = (state: EditorState): string => {
|
|
|
56
56
|
const { $from } = state.selection;
|
|
57
57
|
const maxChars = 200;
|
|
58
58
|
|
|
59
|
-
// 1. Get the perfectly flattened text of the current block up to the cursor
|
|
60
59
|
const blockNode = $from.parent;
|
|
61
60
|
const offsetInBlock = $from.parentOffset;
|
|
62
61
|
const blockText = blockNode.textContent.slice(0, offsetInBlock);
|
|
@@ -67,7 +66,7 @@ const getTextBeforeCursor = (state: EditorState): string => {
|
|
|
67
66
|
|
|
68
67
|
let fullText = blockText;
|
|
69
68
|
|
|
70
|
-
//
|
|
69
|
+
// Walk backwards through previous blocks until we have enough context.
|
|
71
70
|
let depth = $from.depth - 1;
|
|
72
71
|
|
|
73
72
|
while (fullText.length < maxChars && depth >= 0) {
|
|
@@ -309,7 +308,6 @@ export const createAutocompletePlugin = (
|
|
|
309
308
|
const { state } = view;
|
|
310
309
|
const { selection } = state;
|
|
311
310
|
|
|
312
|
-
// Only predict for cursor selections (not range selections)
|
|
313
311
|
if (!selection.empty) {
|
|
314
312
|
return;
|
|
315
313
|
}
|
|
@@ -323,12 +321,10 @@ export const createAutocompletePlugin = (
|
|
|
323
321
|
}
|
|
324
322
|
dismissedContext = null;
|
|
325
323
|
|
|
326
|
-
// Don't predict if there's not enough context
|
|
327
324
|
if (textBefore.trim().length < 3) {
|
|
328
325
|
return;
|
|
329
326
|
}
|
|
330
327
|
|
|
331
|
-
// Tier 1 prediction is synchronous -- no async needed
|
|
332
328
|
const prediction = predict(textBefore);
|
|
333
329
|
|
|
334
330
|
if (prediction && prediction.length > 0) {
|
|
@@ -402,8 +398,7 @@ export const createAutocompletePlugin = (
|
|
|
402
398
|
return { ...pluginState, ...meta };
|
|
403
399
|
}
|
|
404
400
|
|
|
405
|
-
//
|
|
406
|
-
// (new prediction will be scheduled from view.update)
|
|
401
|
+
// A new prediction is scheduled from view.update.
|
|
407
402
|
if (tr.docChanged) {
|
|
408
403
|
return {
|
|
409
404
|
...pluginState,
|
|
@@ -413,7 +408,6 @@ export const createAutocompletePlugin = (
|
|
|
413
408
|
};
|
|
414
409
|
}
|
|
415
410
|
|
|
416
|
-
// If selection changed without doc change, clear ghost text
|
|
417
411
|
if (tr.selectionSet && pluginState.ghostText) {
|
|
418
412
|
return {
|
|
419
413
|
...pluginState,
|
|
@@ -484,13 +478,11 @@ export const createAutocompletePlugin = (
|
|
|
484
478
|
return false;
|
|
485
479
|
},
|
|
486
480
|
focus: () => {
|
|
487
|
-
|
|
488
|
-
loadDefaultVocabulary();
|
|
489
|
-
} catch (error) {
|
|
481
|
+
loadDefaultVocabulary().catch((error) => {
|
|
490
482
|
logException(error as Error, {
|
|
491
483
|
location: 'editor-plugin-autocomplete/loadDefaultVocabulary',
|
|
492
484
|
});
|
|
493
|
-
}
|
|
485
|
+
});
|
|
494
486
|
loadVectorsAsync({ getBinaryUrl: options?.getVectorsBinaryUrl }).catch((error) => {
|
|
495
487
|
logException(error as Error, {
|
|
496
488
|
location: 'editor-plugin-autocomplete/loadVectorsAsync',
|
|
@@ -533,12 +525,10 @@ export const createAutocompletePlugin = (
|
|
|
533
525
|
if (justAccepted) {
|
|
534
526
|
justAccepted = false;
|
|
535
527
|
|
|
536
|
-
//
|
|
537
|
-
//
|
|
538
|
-
// block and abort until the user actually types a new character!
|
|
528
|
+
// Snapshot the post-acceptance text so follow-up transactions hit
|
|
529
|
+
// the dismissedContext guard and abort until the user types again.
|
|
539
530
|
dismissedContext = getTextBeforeCursor(view.state);
|
|
540
531
|
|
|
541
|
-
// Also clear any pending debounce timers from before the acceptance
|
|
542
532
|
if (debounceTimer) {
|
|
543
533
|
clearTimeout(debounceTimer);
|
|
544
534
|
}
|