@redocly/realm 0.138.0-next.5 → 0.138.0-next.6

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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # @redocly/realm
2
2
 
3
+ ## 0.138.0-next.6
4
+
5
+ ### Patch Changes
6
+
7
+ - c634df4a861: Fixed an issue where search returned an error on built projects with a very large search index.
8
+
3
9
  ## 0.138.0-next.5
4
10
 
5
11
  ### Minor Changes
@@ -1 +1,2 @@
1
- import{readFile as R,readdir as F,appendFile as I}from"node:fs/promises";import h from"node:path";import{existsSync as C}from"node:fs";import{SEARCH_GROUP_FACET_FIELD as S,SEARCH_PRODUCT_FIELD as v,SEARCH_VERSION_FIELD as w}from"../../../../../constants/common.js";import{SEARCH_INDEX_FIELDS as $,SEARCH_DATA_EXPORT_FOLDER as D,SEARCH_MAX_INMEMORY_DOCUMENTS_COUNT as O}from"../../../../constants/plugins/search.js";import{telemetryTraceStep as j}from"../../../../telemetry/helpers/trace-step.js";import{envConfig as N}from"../../../../config/env-config.js";import{ensureDir as m}from"../../../../utils/index.js";import{FlexSearchIndex as b}from"./search-index.js";class J{#e=new Map;#s;#t=0;async initIndexSchema(t){this.#s={document:{id:"id",tag:"tags",index:$},worker:!1,tokenize:"forward",context:{depth:2,resolution:9}}}#o(t,o){const i=this.#e.get(t);if(i)return i.find(s=>s.id===o)}#i(t,o){let i=this.#o(t,o);return i||(i=new b(o,this.#s),this.#e.set(t,[...this.#e.get(t)??[],i])),i}async addDocuments(t,o){if(t.length){const{group:i,locale:s,outDir:c}=o,n=this.#i(s,i);for(const r of t)n.add(r),N.isBuildMode&&(this.#t++,this.#t>=O&&await this.exportDocuments(c))}}getIndexesSize(){return this.#e.size}async search(t,o,i){return await j("com.redocly.search.performed",async s=>{s?.setAttribute("id","searchQueryId"),s?.setAttribute("object","searchQuery"),s?.setAttribute("uri","urn:redocly:realm:api:searchQuery:searchQueryId");const{query:c,locale:n,filter:r,loadMore:a}=t,l=this.#e.get(n)??[];let f=[],d="",x=["v:default"];if(s?.setAttribute("locale",n),r)for(const e of r)e.field===S?f=[...f,...e.values]:e.field===v?d=`p:${e.values[0]}`:e.field===w&&e.values.length&&e.values.length===2&&(x=[...x,`v:${e.values[0]}:${e.values[1]}`]);const g={auth:o,query:c,offset:0,SEARCH_GROUP_FACET_FIELD:S,product:d,versions:x},p=[];let u={facets:{},documents:{}};if(a){const e=this.#o(n,a.groupKey);e&&p.push(e.search({...g,offset:a.offset}))}else for(const e of l)f&&f.length?f.includes(e.id)&&p.push(e.search(g)):p.push(e.search(g));const _=await Promise.all(p),A=_.some(e=>e.hasCoveringHit);for(const e of _)if(!(A&&!e.hasCoveringHit)){u.documents={...u.documents,...e.documents};for(const[y,E]of Object.entries(e.facets))u.facets[y]?u.facets[y]=[...u.facets[y],...E]:u.facets[y]=E}return u})}async exportDocuments(t){const o='{"documents":[',i=m(h.join(t,D));for(const[s,c]of this.#e){const n=m(h.join(i,s));for(const r of c){const a=Array.from(r.documents);if(a.length===0)continue;const l=m(h.join(n,`${r.id}.json`)),f=!C(l),d=JSON.stringify(a).substring(1).slice(0,-1),x=f?o+d:","+d;await I(l,x,{encoding:"utf8"}),r.clearDocuments()}}this.#t=0}async exportIndexes(t){const o=m(h.join(t,D));for(const[i,s]of this.#e){const c=m(h.join(o,i));for(const n of s){const r=m(h.join(c,`${n.id}.json`)),a={};await n.export((f,d)=>{a[f]=d});const l=`],"index":${JSON.stringify(a)}}`;await I(r,l,{encoding:"utf8"})}}this.#e.clear()}async import(t){const o=`${t}/${D}`;if(!C(o))return;const i=await F(o);for(const s of i){const c=await F(`${o}/${s}`);for(const n of c){const r=`${o}/${s}/${n}`,a=JSON.parse(await R(r,"utf-8")),l=h.parse(n).name;await this.#i(s,l).import(a)}}}countFacets(t,o,i){const s={};for(const[c,n]of i)s[c]=n.values.map(r=>({value:r,count:0,isCounterVisible:!1}));return s}cleanupFacetValues(t){}}export{J as FlexSearch};
1
+ import{readdir as S,appendFile as A}from"node:fs/promises";import l from"node:path";import{createReadStream as v,existsSync as w}from"node:fs";import{createInterface as O}from"node:readline";import{SEARCH_GROUP_FACET_FIELD as C,SEARCH_PRODUCT_FIELD as N,SEARCH_VERSION_FIELD as j}from"../../../../../constants/common.js";import{SEARCH_INDEX_FIELDS as H,SEARCH_DATA_EXPORT_FOLDER as g,SEARCH_MAX_INMEMORY_DOCUMENTS_COUNT as L}from"../../../../constants/plugins/search.js";import{telemetryTraceStep as T}from"../../../../telemetry/helpers/trace-step.js";import{envConfig as M}from"../../../../config/env-config.js";import{ensureDir as u}from"../../../../utils/index.js";import{FlexSearchIndex as b}from"./search-index.js";const F=".jsonl";function R(m){return`${JSON.stringify(m)}
2
+ `}async function*P(m){const t=O({input:v(m,{encoding:"utf8"}),crlfDelay:1/0});for await(const s of t)s&&(yield JSON.parse(s))}class K{#e=new Map;#s;#t=0;async initIndexSchema(t){this.#s={document:{id:"id",tag:"tags",index:H},worker:!1,tokenize:"forward",context:{depth:2,resolution:9}}}#i(t,s){const n=this.#e.get(t);if(n)return n.find(i=>i.id===s)}#n(t,s){let n=this.#i(t,s);return n||(n=new b(s,this.#s),this.#e.set(t,[...this.#e.get(t)??[],n])),n}async addDocuments(t,s){if(t.length){const{group:n,locale:i,outDir:c}=s,o=this.#n(i,n);for(const r of t)o.add(r),M.isBuildMode&&(this.#t++,this.#t>=L&&await this.exportDocuments(c))}}getIndexesSize(){return this.#e.size}async search(t,s,n){return await T("com.redocly.search.performed",async i=>{i?.setAttribute("id","searchQueryId"),i?.setAttribute("object","searchQuery"),i?.setAttribute("uri","urn:redocly:realm:api:searchQuery:searchQueryId");const{query:c,locale:o,filter:r,loadMore:a}=t,d=this.#e.get(o)??[];let h=[],D="",y=["v:default"];if(i?.setAttribute("locale",o),r)for(const e of r)e.field===C?h=[...h,...e.values]:e.field===N?D=`p:${e.values[0]}`:e.field===j&&e.values.length&&e.values.length===2&&(y=[...y,`v:${e.values[0]}:${e.values[1]}`]);const _={auth:s,query:c,offset:0,SEARCH_GROUP_FACET_FIELD:C,product:D,versions:y},x=[];let f={facets:{},documents:{}};if(a){const e=this.#i(o,a.groupKey);e&&x.push(e.search({..._,offset:a.offset}))}else for(const e of d)h&&h.length?h.includes(e.id)&&x.push(e.search(_)):x.push(e.search(_));const E=await Promise.all(x),$=E.some(e=>e.hasCoveringHit);for(const e of E)if(!($&&!e.hasCoveringHit)){f.documents={...f.documents,...e.documents};for(const[p,I]of Object.entries(e.facets))f.facets[p]?f.facets[p]=[...f.facets[p],...I]:f.facets[p]=I}return f})}async exportDocuments(t){const s=u(l.join(t,g));for(const[n,i]of this.#e){const c=u(l.join(s,n));for(const o of i){const r=Array.from(o.documents,d=>R({document:d}));if(r.length===0)continue;const a=u(l.join(c,`${o.id}${F}`));await A(a,r.join(""),{encoding:"utf8"}),o.clearDocuments()}}this.#t=0}async exportIndexes(t){const s=u(l.join(t,g));for(const[n,i]of this.#e){const c=u(l.join(s,n));for(const o of i){const r=u(l.join(c,`${o.id}${F}`));await o.export((a,d)=>A(r,R({index:[String(a),d]}),{encoding:"utf8"}))}}this.#e.clear()}async import(t){const s=`${t}/${g}`;if(!w(s))return;const n=await S(s);for(const i of n){const c=await S(`${s}/${i}`);for(const o of c){const r=`${s}/${i}/${o}`,a=l.parse(o).name;await this.#n(i,a).import(P(r))}}}countFacets(t,s,n){const i={};for(const[c,o]of n)i[c]=o.values.map(r=>({value:r,count:0,isCounterVisible:!1}));return i}cleanupFacetValues(t){}}export{K as FlexSearch};
@@ -1,5 +1,5 @@
1
1
  import type { ExportHandler, IndexOptionsForDocumentSearch } from 'flexsearch';
2
- import type { FlexSearchData, IndexedSearchDocument, SearchIndex, SearchParameters, SearchDocument } from '../../../../types';
2
+ import type { FlexSearchDataEntry, IndexedSearchDocument, SearchIndex, SearchParameters, SearchDocument } from '../../../../types';
3
3
  import type { SearchResponse } from '../../../../../types/index.js';
4
4
  /** One group's results plus whether any of them holds every query word in a single value. */
5
5
  export type IndexSearchResponse = SearchResponse & {
@@ -13,7 +13,7 @@ export declare class FlexSearchIndex implements SearchIndex {
13
13
  get documentsCount(): number;
14
14
  clearDocuments(): void;
15
15
  export(handler: ExportHandler<string | IndexedSearchDocument>): Promise<void>;
16
- import(searchData: FlexSearchData): Promise<void>;
16
+ import(entries: AsyncIterable<FlexSearchDataEntry>): Promise<void>;
17
17
  add(document: SearchDocument): void;
18
18
  search(params: SearchParameters): Promise<IndexSearchResponse>;
19
19
  }
@@ -1 +1 @@
1
- import _ from"flexsearch";import{REDOCLY_TEAMS_RBAC as L}from"@redocly/config";import{DISABLE_DEEP_LINK_IF_FIELDS_EXIST as b,SEARCH_LIMIT as R}from"../../../../constants/plugins/search.js";import{telemetryTraceStep as j}from"../../../../telemetry/helpers/trace-step.js";import{highlightTextForSearch as m,markMatchedValue as D}from"../../../../utils/search/highlight-text-for-search.js";import{MIN_QUERY_WORD_LENGTH as M,containsQueryWord as S,matchableQueryWords as C}from"../../../../utils/search/text-match.js";function k(I){const{name:e,description:t,place:r,path:i,deepLink:s,example:n,enum:a}=I,o=s?.indexOf("#")??-1;return{name:e,description:t,place:r,...i&&{path:i},...s&&{deepLink:o>=0?s.slice(o+1):s},example:n,enum:a}}class T{#t;#e=new Map;#s=1;id;constructor(e,t){this.id=e,this.#t=new _.Document(t)}get documents(){return this.#e.entries()}get documentsCount(){return this.#s}clearDocuments(){this.#e.clear()}async export(e){await this.#t.export(e)}async import(e){const{documents:t,index:r}=e;this.#e.clear();for(const[i,s]of t)this.#e.set(i,s);for(const[i,s]of Object.entries(r))await this.#t.import(i,s)}add(e){const t={...e,tags:e.tags??[],[L]:e[L],...e.parameters&&{parameters:e.parameters.map(k)}};this.#e.set(this.#s,t),this.#t.add(this.#s,t),this.#s++}async search(e){return await j("com.redocly.search.performed",async t=>{t?.setAttribute("id","searchQueryId"),t?.setAttribute("object","searchQuery"),t?.setAttribute("uri","urn:redocly:realm:api:searchQuery:searchQueryId");const{query:r,offset:i,auth:s,product:n,versions:a}=e,o=[],l=s.teams,p={limit:R,offset:i},c=this.#r(r);if(!c.length&&r.trim())return{documents:{[this.id]:[]},facets:{},hasCoveringHit:!1};let d=new Map,g=await this.#t.searchAsync(r,{...p,tag:l});if(n){const h=await this.#t.searchAsync(r,{...p,tag:n});g=this.#a(g,h),t?.setAttribute("product",n)}if(a&&a.length){const h=await this.#t.searchAsync(r,{...p,tag:a});g=this.#a(g,h),t?.setAttribute("versions",a.join(","))}for(const h of g)for(const u of h.result){const f=d.get(u)?.fields||[];d.set(u,{fields:h.field?[...f,h.field]:[...f]})}!i&&c.length&&!d.size&&(d=this.#l(c,l,n,a));const x=[];for(const[h,u]of d.entries()){const f=this.#e.get(h);f&&!this.#d(f,a)&&x.push({document:f,fields:u.fields,score:this.#m(c,f)})}const y=x.filter(h=>h.score>=c.length),A=y.length?y:x;A.sort((h,u)=>u.score-h.score);for(const h of A.slice(0,R))o.push({document:this.#o(h.document,r,h.fields),highlight:this.#h(h.document,r,h.fields)});return{documents:{[this.id]:o},facets:{},hasCoveringHit:y.length>0}})}#o(e,t,r){return this.#g(e,t,r)}#h(e,t,r){const i={};let s=!1;for(const n of r)if(n==="path")i.path=e.path?e.path.map(a=>m(t,a)):[];else if(n.includes("parameters")){if(!s){const a=n.split(":")[1],o=this.#n(t,a,e.parameters);o&&(i.parameters=[{name:m(t,o.name),description:m(t,o.description),place:m(t,o.place),path:o.path?o.path.map(l=>m(t,l)):[],...this.#c(t,o)}],s=!0)}}else n!=="httpMethod"&&(i[n]=m(t,e[n]));return i}#c(e,t){return{enum:D(e,(t.enum??[]).join(", ")),example:D(e,t.example??"")}}#r(e){return C(e)}#l(e,t,r,i){const s=new Map;if(!e.length)return s;for(const[n,a]of this.#e)this.#p(a,t,r,i)&&this.#f(e,a)&&s.set(n,{fields:this.#u(e,a)});return s}#f(e,t){const r=i=>{if(i==null)return!1;const s=(Array.isArray(i)?i.join(" "):String(i)).toLowerCase();return!!s&&e.every(n=>S(s,n))};return r(t.title)||r(t.text)||r(t.httpPath)||r(t.path)?!0:(t.parameters??[]).some(i=>r(i.name)||r(i.description)||r(i.example)||r(i.enum))}#p(e,t,r,i){const s=new Set(e.tags??[]);return!(t.length&&!t.some(n=>s.has(n))||r&&!s.has(r)||i&&i.length&&!i.some(n=>s.has(n)))}#u(e,t){const r=s=>{if(s==null)return!1;const n=(Array.isArray(s)?s.join(" "):String(s)).toLowerCase();return e.some(a=>S(n,a))},i=[];r(t.title)&&i.push("title"),r(t.text)&&i.push("text"),r(t.path)&&i.push("path"),t.httpMethod&&e.some(s=>s.length>=M&&t.httpMethod?.toLowerCase().startsWith(s))&&i.push("httpMethod"),r(t.httpPath)&&i.push("httpPath");for(const s of["name","description","path","example","enum"])t.parameters?.some(n=>r(n[s]))&&i.push(`parameters[]:${s}`);return i}#i(e,t){const r=t.toLowerCase().replace(/\s+/g," "),i=e.filter(n=>S(r,n)).length;let s=0;for(let n=1;n<e.length;n++)r.includes(`${e[n-1]} ${e[n]}`)&&s++;return i+s/e.length}#m(e,t){let r=0;const i=s=>{if(s==null)return;const n=this.#i(e,String(s));n>r&&(r=n)};if(i(t.title),i(t.text),i(t.httpPath),i(t.path?.join(" ")),t.httpMethod){const s=t.httpMethod.toLowerCase(),n=e.filter(a=>a.length>=M&&s.startsWith(a)).length;n>r&&(r=n)}for(const s of t.parameters??[])i([s.name,s.description,s.place,s.example,s.enum?.join(" ")].filter(Boolean).join(" "));return r}#n(e,t,r){const i=this.#r(e);let s,n=0;for(const a of r??[]){const o=a[t],l=(Array.isArray(o)?o:[o]).filter(c=>c!=null).map(c=>String(c)).join(" "),p=this.#i(i,l);p>n&&(n=p,s=a)}return s}#a(e,t){const r=[];for(const i of e){const s=[];for(const n of t)for(const a of i.result){const o=n.result.find(l=>l===a);o&&s.push(o)}s.length&&r.push({result:s,field:i.field})}return r}#d(e,t){return!!(t&&t.length&&e.isDefaultVersion&&e.versionFolderId&&e.version&&t.some(r=>r.includes(e.versionFolderId??""))&&!t.some(r=>r.includes(e.version??"")))}#g(e,t,r){for(const s of b)if(r.some(n=>n===s))return e;let i;for(const s of r)if(s.includes("parameters")){const n=s.split(":")[1],a=this.#n(t,n,e.parameters);if(a){i=a.deepLink;break}}return i?{...e,url:`${e.url}#${i}`}:e}}export{T as FlexSearchIndex};
1
+ import _ from"flexsearch";import{REDOCLY_TEAMS_RBAC as L}from"@redocly/config";import{DISABLE_DEEP_LINK_IF_FIELDS_EXIST as C,SEARCH_LIMIT as R}from"../../../../constants/plugins/search.js";import{telemetryTraceStep as b}from"../../../../telemetry/helpers/trace-step.js";import{highlightTextForSearch as m,markMatchedValue as D}from"../../../../utils/search/highlight-text-for-search.js";import{MIN_QUERY_WORD_LENGTH as M,containsQueryWord as S,matchableQueryWords as j}from"../../../../utils/search/text-match.js";function k(I){const{name:e,description:t,place:s,path:i,deepLink:r,example:n,enum:a}=I,o=r?.indexOf("#")??-1;return{name:e,description:t,place:s,...i&&{path:i},...r&&{deepLink:o>=0?r.slice(o+1):r},example:n,enum:a}}class T{#t;#e=new Map;#s=1;id;constructor(e,t){this.id=e,this.#t=new _.Document(t)}get documents(){return this.#e.entries()}get documentsCount(){return this.#s}clearDocuments(){this.#e.clear()}async export(e){await this.#t.export(e)}async import(e){this.#e.clear();for await(const t of e)if("document"in t){const[s,i]=t.document;this.#e.set(s,i)}else{const[s,i]=t.index;await this.#t.import(s,i)}}add(e){const t={...e,tags:e.tags??[],[L]:e[L],...e.parameters&&{parameters:e.parameters.map(k)}};this.#e.set(this.#s,t),this.#t.add(this.#s,t),this.#s++}async search(e){return await b("com.redocly.search.performed",async t=>{t?.setAttribute("id","searchQueryId"),t?.setAttribute("object","searchQuery"),t?.setAttribute("uri","urn:redocly:realm:api:searchQuery:searchQueryId");const{query:s,offset:i,auth:r,product:n,versions:a}=e,o=[],l=r.teams,p={limit:R,offset:i},c=this.#r(s);if(!c.length&&s.trim())return{documents:{[this.id]:[]},facets:{},hasCoveringHit:!1};let d=new Map,g=await this.#t.searchAsync(s,{...p,tag:l});if(n){const h=await this.#t.searchAsync(s,{...p,tag:n});g=this.#a(g,h),t?.setAttribute("product",n)}if(a&&a.length){const h=await this.#t.searchAsync(s,{...p,tag:a});g=this.#a(g,h),t?.setAttribute("versions",a.join(","))}for(const h of g)for(const u of h.result){const f=d.get(u)?.fields||[];d.set(u,{fields:h.field?[...f,h.field]:[...f]})}!i&&c.length&&!d.size&&(d=this.#l(c,l,n,a));const x=[];for(const[h,u]of d.entries()){const f=this.#e.get(h);f&&!this.#d(f,a)&&x.push({document:f,fields:u.fields,score:this.#m(c,f)})}const y=x.filter(h=>h.score>=c.length),A=y.length?y:x;A.sort((h,u)=>u.score-h.score);for(const h of A.slice(0,R))o.push({document:this.#o(h.document,s,h.fields),highlight:this.#h(h.document,s,h.fields)});return{documents:{[this.id]:o},facets:{},hasCoveringHit:y.length>0}})}#o(e,t,s){return this.#g(e,t,s)}#h(e,t,s){const i={};let r=!1;for(const n of s)if(n==="path")i.path=e.path?e.path.map(a=>m(t,a)):[];else if(n.includes("parameters")){if(!r){const a=n.split(":")[1],o=this.#n(t,a,e.parameters);o&&(i.parameters=[{name:m(t,o.name),description:m(t,o.description),place:m(t,o.place),path:o.path?o.path.map(l=>m(t,l)):[],...this.#c(t,o)}],r=!0)}}else n!=="httpMethod"&&(i[n]=m(t,e[n]));return i}#c(e,t){return{enum:D(e,(t.enum??[]).join(", ")),example:D(e,t.example??"")}}#r(e){return j(e)}#l(e,t,s,i){const r=new Map;if(!e.length)return r;for(const[n,a]of this.#e)this.#p(a,t,s,i)&&this.#f(e,a)&&r.set(n,{fields:this.#u(e,a)});return r}#f(e,t){const s=i=>{if(i==null)return!1;const r=(Array.isArray(i)?i.join(" "):String(i)).toLowerCase();return!!r&&e.every(n=>S(r,n))};return s(t.title)||s(t.text)||s(t.httpPath)||s(t.path)?!0:(t.parameters??[]).some(i=>s(i.name)||s(i.description)||s(i.example)||s(i.enum))}#p(e,t,s,i){const r=new Set(e.tags??[]);return!(t.length&&!t.some(n=>r.has(n))||s&&!r.has(s)||i&&i.length&&!i.some(n=>r.has(n)))}#u(e,t){const s=r=>{if(r==null)return!1;const n=(Array.isArray(r)?r.join(" "):String(r)).toLowerCase();return e.some(a=>S(n,a))},i=[];s(t.title)&&i.push("title"),s(t.text)&&i.push("text"),s(t.path)&&i.push("path"),t.httpMethod&&e.some(r=>r.length>=M&&t.httpMethod?.toLowerCase().startsWith(r))&&i.push("httpMethod"),s(t.httpPath)&&i.push("httpPath");for(const r of["name","description","path","example","enum"])t.parameters?.some(n=>s(n[r]))&&i.push(`parameters[]:${r}`);return i}#i(e,t){const s=t.toLowerCase().replace(/\s+/g," "),i=e.filter(n=>S(s,n)).length;let r=0;for(let n=1;n<e.length;n++)s.includes(`${e[n-1]} ${e[n]}`)&&r++;return i+r/e.length}#m(e,t){let s=0;const i=r=>{if(r==null)return;const n=this.#i(e,String(r));n>s&&(s=n)};if(i(t.title),i(t.text),i(t.httpPath),i(t.path?.join(" ")),t.httpMethod){const r=t.httpMethod.toLowerCase(),n=e.filter(a=>a.length>=M&&r.startsWith(a)).length;n>s&&(s=n)}for(const r of t.parameters??[])i([r.name,r.description,r.place,r.example,r.enum?.join(" ")].filter(Boolean).join(" "));return s}#n(e,t,s){const i=this.#r(e);let r,n=0;for(const a of s??[]){const o=a[t],l=(Array.isArray(o)?o:[o]).filter(c=>c!=null).map(c=>String(c)).join(" "),p=this.#i(i,l);p>n&&(n=p,r=a)}return r}#a(e,t){const s=[];for(const i of e){const r=[];for(const n of t)for(const a of i.result){const o=n.result.find(l=>l===a);o&&r.push(o)}r.length&&s.push({result:r,field:i.field})}return s}#d(e,t){return!!(t&&t.length&&e.isDefaultVersion&&e.versionFolderId&&e.version&&t.some(s=>s.includes(e.versionFolderId??""))&&!t.some(s=>s.includes(e.version??"")))}#g(e,t,s){for(const r of C)if(s.some(n=>n===r))return e;let i;for(const r of s)if(r.includes("parameters")){const n=r.split(":")[1],a=this.#n(t,n,e.parameters);if(a){i=a.deepLink;break}}return i?{...e,url:`${e.url}#${i}`}:e}}export{T as FlexSearchIndex};
@@ -31,7 +31,7 @@ export type SearchIndex = {
31
31
  add(document: SearchDocument): void;
32
32
  search(params: SearchParameters): Promise<SearchResponse>;
33
33
  export(handler: ExportHandler<string | IndexedSearchDocument>): void;
34
- import(searchData: FlexSearchData): void;
34
+ import(entries: AsyncIterable<FlexSearchDataEntry>): Promise<void>;
35
35
  clearDocuments(): void;
36
36
  };
37
37
  export type AddDocumentsParams = {
@@ -39,9 +39,11 @@ export type AddDocumentsParams = {
39
39
  locale: string;
40
40
  outDir: string;
41
41
  };
42
- export type FlexSearchData = {
43
- documents: [number, IndexedSearchDocument][];
44
- index: Record<string, any>;
42
+ /** One line of an exported FlexSearch group file: a stored document or one FlexSearch export key. */
43
+ export type FlexSearchDataEntry = {
44
+ document: [number, IndexedSearchDocument];
45
+ } | {
46
+ index: [string, string];
45
47
  };
46
48
  export type TypesenseSearchData = {
47
49
  documents: SearchDocument[];
@@ -1 +1 @@
1
- import{DEFAULT_SEARCH_ENGINE as t}from"@redocly/config";import{logger as c}from"../../tools/notifiers/logger.js";import{SearchEngine as o}from"../../plugins/search/engines/search-engine.js";function f(a){let e;const r=async()=>{c.info("Loading search data...");const i=a.config?.search?.engine??t,n=new o(i,a.globalData.l10n);await n.initIndexSchema(a.searchFacets),await n.import(a.outdir),a.setSearchEngine(n),c.info("Search data loaded")};return async(i,n)=>{!a.searchEngine&&!a.config?.search?.hide&&(e??=r().finally(()=>{e=void 0}),await e),await n()}}export{f as ensureSearchData};
1
+ import{DEFAULT_SEARCH_ENGINE as o}from"@redocly/config";import{logger as e}from"../../tools/notifiers/logger.js";import{SearchEngine as h}from"../../plugins/search/engines/search-engine.js";function l(a){let i;const c=async()=>{e.info("Loading search data...");const t=e.startTiming();try{const n=a.config?.search?.engine??o,r=new h(n,a.globalData.l10n);await r.initIndexSchema(a.searchFacets),await r.import(a.outdir),a.setSearchEngine(r),e.infoTime(t,"Search data loaded")}catch(n){throw e.error("Failed to load search data: %s",n),n}};return async(t,n)=>{!a.searchEngine&&!a.config?.search?.hide&&(i??=c().finally(()=>{i=void 0}),await i),await n()}}export{l as ensureSearchData};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/realm",
3
- "version": "0.138.0-next.5",
3
+ "version": "0.138.0-next.6",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "bin": {