@@ -1450,11 +1450,10 @@ class NameTrie {
14501450
14511451class DocSearch {
14521452 /**
1453- * @param {Map<string, rustdoc.RawSearchIndexCrate> } rawSearchIndex
14541453 * @param {string } rootPath
14551454 * @param {rustdoc.SearchState } searchState
14561455 */
1457- constructor ( rawSearchIndex , rootPath , searchState ) {
1456+ constructor ( rootPath , searchState ) {
14581457 /**
14591458 * @type {Map<String, RoaringBitmap> }
14601459 */
@@ -1585,7 +1584,7 @@ class DocSearch {
15851584 /**
15861585 * @type {Array<rustdoc.Row> }
15871586 */
1588- this . searchIndex = this . buildIndex ( rawSearchIndex ) ;
1587+ this . searchIndex = [ ] ;
15891588 }
15901589
15911590 /**
@@ -1911,9 +1910,9 @@ class DocSearch {
19111910 * Convert raw search index into in-memory search index.
19121911 *
19131912 * @param {Map<string, rustdoc.RawSearchIndexCrate> } rawSearchIndex
1914- * @returns {rustdoc.Row[] }
1913+ * @returns {Promise< rustdoc.Row[]> }
19151914 */
1916- buildIndex ( rawSearchIndex ) {
1915+ async buildIndex ( rawSearchIndex ) {
19171916 /**
19181917 * Convert from RawFunctionSearchType to FunctionSearchType.
19191918 *
@@ -2177,6 +2176,20 @@ class DocSearch {
21772176 paths [ i ] = { ty, name, path, exactPath, unboxFlag } ;
21782177 }
21792178
2179+ // Throttlers are used to yield to the JavaScript event loop
2180+ // while this is being built.
2181+ // They're generated up-front to avoid the "nesting level"
2182+ // limit that limits our speed to 4ms per tick.
2183+ // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html
2184+ const throttlers = [ ] ;
2185+ len = itemTypes . length ;
2186+ for ( let i = 0 ; i < len ; ++ i ) {
2187+ if ( ( i & 0xFF ) === 0 ) { // 256 - 1
2188+ throttlers . push ( new Promise ( resolve => {
2189+ setTimeout ( resolve , 0 ) ;
2190+ } ) ) ;
2191+ }
2192+ }
21802193 // convert `item*` into an object form, and construct word indices.
21812194 //
21822195 // before any analysis is performed lets gather the search terms to
@@ -2189,6 +2202,9 @@ class DocSearch {
21892202 let lastName = "" ;
21902203 let lastWord = "" ;
21912204 for ( let i = 0 ; i < len ; ++ i ) {
2205+ if ( ( i & 0xFF ) === 0 ) { // 256 - 1
2206+ await throttlers [ i >> 8 ] ;
2207+ }
21922208 const bitIndex = i + 1 ;
21932209 if ( descIndex >= descShard . len &&
21942210 // @ts -expect-error
@@ -5377,20 +5393,26 @@ function updateCrate(ev) {
53775393 search ( true ) ;
53785394}
53795395
5380- // @ts -expect-error
5381- function initSearch ( searchIndx ) {
5396+ /**
5397+ * @param {Map<string, import("./rustdoc").RawSearchIndexCrate> } searchIndx
5398+ */
5399+ async function initSearch ( searchIndx ) {
5400+ if ( ROOT_PATH === null ) {
5401+ return ;
5402+ }
53825403 rawSearchIndex = searchIndx ;
53835404 if ( typeof window !== "undefined" ) {
5384- // @ts -expect-error
5385- docSearch = new DocSearch ( rawSearchIndex , ROOT_PATH , searchState ) ;
5405+ docSearch = new DocSearch ( ROOT_PATH , window . searchState ) ;
5406+ docSearch . searchIndex = await docSearch . buildIndex ( rawSearchIndex ) ;
53865407 registerSearchEvents ( ) ;
53875408 // If there's a search term in the URL, execute the search now.
53885409 if ( window . searchState . getQueryStringParams ( ) . search !== undefined ) {
53895410 search ( ) ;
53905411 }
53915412 } else if ( typeof exports !== "undefined" ) {
5392- // @ts -expect-error
5393- docSearch = new DocSearch ( rawSearchIndex , ROOT_PATH , searchState ) ;
5413+ // @ts -ignore
5414+ docSearch = new DocSearch ( ROOT_PATH , searchState ) ;
5415+ docSearch . searchIndex = await docSearch . buildIndex ( rawSearchIndex ) ;
53945416 exports . docSearch = docSearch ;
53955417 exports . parseQuery = DocSearch . parseQuery ;
53965418 }
0 commit comments