11// ignore-tidy-filelength
2- /* global addClass, getNakedUrl, getSettingValue */
2+ /* global addClass, getNakedUrl, getSettingValue, getVar */
33/* global onEachLazy, removeClass, searchState, browserSupportsHistoryApi, exports */
44
55"use strict" ;
@@ -1298,7 +1298,7 @@ class NameTrie {
12981298}
12991299
13001300class DocSearch {
1301- constructor ( rawSearchIndex , rootPath , searchState ) {
1301+ constructor ( rootPath , searchState ) {
13021302 /**
13031303 * @type {Map<String, RoaringBitmap> }
13041304 */
@@ -1417,7 +1417,7 @@ class DocSearch {
14171417 /**
14181418 * @type {Array<Row> }
14191419 */
1420- this . searchIndex = this . buildIndex ( rawSearchIndex ) ;
1420+ this . searchIndex = [ ] ;
14211421 }
14221422
14231423 /**
@@ -1695,7 +1695,7 @@ class DocSearch {
16951695 *
16961696 * @param {[string, RawSearchIndexCrate][] } rawSearchIndex
16971697 */
1698- buildIndex ( rawSearchIndex ) {
1698+ async buildIndex ( rawSearchIndex ) {
16991699 /**
17001700 * Convert from RawFunctionSearchType to FunctionSearchType.
17011701 *
@@ -1903,6 +1903,20 @@ class DocSearch {
19031903 paths [ i ] = { ty, name, path, exactPath, unboxFlag } ;
19041904 }
19051905
1906+ // Throttlers are used to yield to the JavaScript event loop
1907+ // while this is being built.
1908+ // They're generated up-front to avoid the "nesting level"
1909+ // limit that limits our speed to 4ms per tick.
1910+ // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html
1911+ const throttlers = [ ] ;
1912+ len = itemTypes . length ;
1913+ for ( let i = 0 ; i < len ; ++ i ) {
1914+ if ( ( i & 0xFF ) === 0 ) { // 256 - 1
1915+ throttlers . push ( new Promise ( resolve => {
1916+ setTimeout ( resolve , 0 ) ;
1917+ } ) ) ;
1918+ }
1919+ }
19061920 // convert `item*` into an object form, and construct word indices.
19071921 //
19081922 // before any analysis is performed lets gather the search terms to
@@ -1915,6 +1929,9 @@ class DocSearch {
19151929 let lastName = "" ;
19161930 let lastWord = "" ;
19171931 for ( let i = 0 ; i < len ; ++ i ) {
1932+ if ( ( i & 0xFF ) === 0 ) { // 256 - 1
1933+ await throttlers [ i >> 8 ] ;
1934+ }
19181935 const bitIndex = i + 1 ;
19191936 if ( descIndex >= descShard . len &&
19201937 ! this . searchIndexEmptyDesc . get ( crate ) . contains ( bitIndex ) ) {
@@ -4864,17 +4881,19 @@ function updateCrate(ev) {
48644881 search ( true ) ;
48654882}
48664883
4867- function initSearch ( searchIndx ) {
4884+ async function initSearch ( searchIndx ) {
48684885 rawSearchIndex = searchIndx ;
48694886 if ( typeof window !== "undefined" ) {
4870- docSearch = new DocSearch ( rawSearchIndex , ROOT_PATH , searchState ) ;
4887+ docSearch = new DocSearch ( ROOT_PATH , searchState ) ;
4888+ docSearch . searchIndex = await docSearch . buildIndex ( rawSearchIndex ) ;
48714889 registerSearchEvents ( ) ;
48724890 // If there's a search term in the URL, execute the search now.
48734891 if ( window . searchState . getQueryStringParams ( ) . search !== undefined ) {
48744892 search ( ) ;
48754893 }
48764894 } else if ( typeof exports !== "undefined" ) {
4877- docSearch = new DocSearch ( rawSearchIndex , ROOT_PATH , searchState ) ;
4895+ docSearch = new DocSearch ( ROOT_PATH , searchState ) ;
4896+ docSearch . searchIndex = await docSearch . buildIndex ( rawSearchIndex ) ;
48784897 exports . docSearch = docSearch ;
48794898 exports . parseQuery = DocSearch . parseQuery ;
48804899 }
0 commit comments