@memberjunction/ng-search 6.2.0-edge.4 → 6.2.0-edge.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.
@@ -189,9 +189,9 @@ export declare class SearchOverlayComponent implements OnInit, OnDestroy {
189
189
  private subscribeToSearchState;
190
190
  private executeSearch;
191
191
  /**
192
- * Streaming variant of executeSearch — subscribes to `SearchService.StreamSearch` and
193
- * progressively updates the result list as each provider reports back. The 'final'
194
- * event carries the canonical fused/reranked list, which replaces the partials.
192
+ * Streaming variant of executeSearch — subscribes to `SearchService.StreamSearch`, shows each
193
+ * provider's count in the chip strip as it reports back, and renders the result list from the
194
+ * 'final' event. A 'provider' event carries no rows: they arrive before the server's permission pass.
195
195
  *
196
196
  * Cancellation: a new search invocation tears down the in-flight stream via
197
197
  * `searchVersion` and `currentStream.unsubscribe()`.
@@ -1 +1 @@
1
- {"version":3,"file":"search-overlay.component.d.ts","sourceRoot":"","sources":["../../src/lib/search-overlay.component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search-overlay.component.d.ts","sourceRoot":"","sources":["../../src/lib/search-overlay.component.ts"],"names":[],"mappings":"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"}
@@ -824,9 +824,9 @@ export class SearchOverlayComponent {
824
824
  this.cdr.detectChanges();
825
825
  }
826
826
  /**
827
- * Streaming variant of executeSearch — subscribes to `SearchService.StreamSearch` and
828
- * progressively updates the result list as each provider reports back. The 'final'
829
- * event carries the canonical fused/reranked list, which replaces the partials.
827
+ * Streaming variant of executeSearch — subscribes to `SearchService.StreamSearch`, shows each
828
+ * provider's count in the chip strip as it reports back, and renders the result list from the
829
+ * 'final' event. A 'provider' event carries no rows: they arrive before the server's permission pass.
830
830
  *
831
831
  * Cancellation: a new search invocation tears down the in-flight stream via
832
832
  * `searchVersion` and `currentStream.unsubscribe()`.
@@ -849,28 +849,19 @@ export class SearchOverlayComponent {
849
849
  if (version !== this.searchVersion)
850
850
  return;
851
851
  if (event.Phase === 'provider' && event.ProviderName) {
852
- const count = event.Results?.length ?? 0;
852
+ // Progress only: the count, never the rows (they precede the permission pass).
853
853
  this.StreamingProviders = [
854
854
  ...this.StreamingProviders,
855
855
  {
856
856
  Name: event.ProviderName,
857
- Count: count,
857
+ Count: event.ResultCount ?? 0,
858
858
  ElapsedMs: event.ElapsedMs ?? 0,
859
859
  State: 'Completed',
860
860
  },
861
861
  ];
862
- if (event.Results && event.Results.length > 0) {
863
- // Append partials so the user sees the list grow as providers return.
864
- this.AllResults = [...this.AllResults, ...event.Results];
865
- this.ResultGroups = this.searchService.GroupResults(this.AllResults);
866
- this.TotalCount = this.AllResults.length;
867
- if (this.HighlightedIndex < 0) {
868
- this.HighlightedIndex = 0;
869
- }
870
- }
871
862
  }
872
863
  else if (event.Phase === 'final' && event.Results) {
873
- // Replace the appended partials with the canonical fused/reranked list.
864
+ // The permission-filtered fused/reranked list.
874
865
  this.AllResults = event.Results;
875
866
  this.ResultGroups = this.searchService.GroupResults(this.AllResults);
876
867
  this.Filters = this.searchService.BuildFilters(this.AllResults);
@@ -1 +1 @@
1
- {"version":3,"file":"search-overlay.component.js","sourceRoot":"","sources":["../../src/lib/search-overlay.component.ts","../../src/lib/search-overlay.component.html"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EACH,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,KAAK,EAGL,MAAM,EACN,iBAAiB,EAEjB,SAAS,EACT,MAAM,EACT,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,EAAgB,MAAM,MAAM,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;;;;;;;;;;;ICAjC,8BAA4B;IACxB,wBAA2C;IAC/C,iBAAM;;;IAgBE,gCAAoD;IAChD,wBAAgD;IAChD,4BAAM;IAAA,+BAAU;IACpB,AADoB,iBAAO,EACpB;;;IAOC,wBAAiC;;;IAEjC,wBAAgD;;;IAIhD,gCAAmC;IAAA,YAAa;IAAA,iBAAO;IACvD,gCAAkC;IAAA,YAAoC;IAAA,iBAAO;;;;IAD1C,cAAa;IAAb,gCAAa;IACd,eAAoC;IAApC,8DAAoC;;;IAEtE,gCAAkC;IAAA,YAAoB;IAAA,iBAAO;;;IAA3B,cAAoB;IAApB,uCAAoB;;;IAb9D,gCAEiE;IAG3D,AAFF,0HAA+B,oGAEtB;IAGT,gCAAkC;IAAA,YAAY;IAAA,iBAAO;IAInD,AAHF,iHAA+B,uGAGF;IAGjC,iBAAO;;;IAbD,AADA,8DAAkD,wDACQ;IAC5D,cAIC;IAJD,oDAIC;IACiC,eAAY;IAAZ,+BAAY;IAC9C,cAKC;IALD,6EAKC;;;IAtBb,+BAAuD;IACnD,uHAAsD;IAMtD,wHAiBC;IACL,iBAAM;;;IAxBF,cAKC;IALD,uFAKC;IACD,cAiBC;IAjBD,wCAiBC;;;IAce,oBAA6B;;;IAA1B,6BAAqB;;;;IANhC,kCAIC;IADG,kSAAS,0DAA6C,KAAC;IAEvD,gIAAmB;IAGnB,4BAAM;IAAA,YAAkB;IAAA,iBAAO;IAC/B,gCAAgC;IAAA,YAAkB;IACtD,AADsD,iBAAO,EACpD;;;;;IARL,gGAA0E;IAG1E,cAEC;IAFD,yCAEC;IACK,eAAkB;IAAlB,qCAAkB;IACQ,eAAkB;IAAlB,qCAAkB;;;IAV1D,gIAYC;;;IAZD,gCAYC;;;;IAGD,kCAA6D;IAA5B,wNAAS,wBAAiB,KAAC;IACxD,wBAAiC;IAAC,uBACtC;IAAA,iBAAS;;;IAnBjB,+BAA+B;IAC3B,wHAcC;IACD,yHAA0B;IAK9B,iBAAM;;;IApBF,cAcC;IAdD,6BAcC;IACD,eAIC;IAJD,oDAIC;;;;IAWG,kCAAkF;IAA5B,wNAAS,wBAAiB,KAAC;IAC7E,wBAAiC;IACjC,YACJ;IAAA,iBAAS;;;IADL,eACJ;IADI,oDACJ;;;IARR,0CAG4D;IACxD,yHAAoB;IAMxB,iBAAiB;;;IANb,cAKC;IALD,8CAKC;;;;IAaW,+BAEsD;IAAlD,AADA,0RAAS,uCAA4B,KAAC,uRAC3B,gDAAqC,KAAC;IACjD,wBAAoD;IACpD,4BAAM;IAAA,YAAkB;IAAA,iBAAO;IAC/B,gCAAkC;IAAA,YAAgC;IACtE,AADsE,iBAAO,EACvE;;;IAFI,eAAkB;IAAlB,sCAAkB;IACU,eAAgC;IAAhC,6DAAgC;;;IAN1E,0IAAa;;;IAAb,8CAQC;;;IAXD,AADJ,+BAAkC,eACI;IAAA,+BAAe;IACrD,AADqD,iBAAO,EACtD;IACN,sIAUC;;;IAVD,eAUC;IAVD,yDAUC;;;IAED,qCAGqB;;;IApB7B,+BAA2B;IAgBrB,AAfF,2GAAsD,2GAe7C;IAMb,iBAAM;;;IArBF,cAoBC;IApBD,+EAoBC;;;IAoC+B,gCAAyB;IAAA,YAAS;IAAA,iBAAO;;;IAAhB,cAAS;IAAT,6BAAS;;;IADtC,uJAAc;;;IAAd,8CAEC;;;IAJT,+BAA8B;IAC1B,oKAIC;IACL,iBAAM;;;IALF,cAIC;IAJD,8BAIC;;;;IAvBjB,+BAUC;IADG,AADA,AADA,uPAAS,wCAA6B,KAAC,8PACX,+BAAoB,KAAC,wQAChB,+BAAoB,KAAC;IAEtD,+BAA8B;IAC1B,oBAAmC;IACvC,iBAAM;IAEF,AADJ,+BAAiC,cACE;IAAA,YAAkB;IAAA,iBAAM;IACvD,+BAAiC;IAAA,YAAoB;IAAA,iBAAM;IAC3D,kIAA8B;IASlC,iBAAM;IAEF,AADJ,+BAA+B,gBACD;IAAA,aAA+B;IAEjE,AADI,AAD6D,iBAAO,EAC9D,EACJ;;;;IAxBF,iFAA6D;;IAMtD,eAA2B;IAA3B,oCAA2B;IAGC,eAAkB;IAAlB,sCAAkB;IAChB,eAAoB;IAApB,wCAAoB;IACrD,cAQC;IARD,qDAQC;IAGyB,eAA+B;IAA/B,0DAA+B;;;IAlCrE,AADJ,+BAA8C,cACW;IACjD,oBAA4B;IAC5B,gCAAiC;IAAA,YAAiB;IAAA,iBAAO;IACzD,gCAAiC;IAAA,YAAsB;IAC3D,AAD2D,iBAAO,EAC5D;IACN,+HAgCC;IACL,iBAAM;;;IArCK,eAAoB;IAApB,6BAAoB;IACU,eAAiB;IAAjB,qCAAiB;IACjB,eAAsB;IAAtB,0CAAsB;IAE3D,cAgCC;IAhCD,gCAgCC;;;;IAgBG,kCAA8E;IAA5B,0NAAS,wBAAiB,KAAC;IACzE,wBAAiC;IACjC,YACJ;IAAA,iBAAS;;;IADL,eACJ;IADI,oDACJ;;;;IA3DZ,+BAA4E;IAC5E,uHAyCC;IACD,iBAAM;IAIF,AADJ,+BAA2B,eACW;IAC9B,YACJ;IAAA,iBAAO;IAEH,AADJ,+BAAmC,iBACqC;IAA1B,2MAAS,sBAAe,KAAC;IAC/D,iCACA;IAAA,wBAAuC;IAC3C,iBAAS;IACT,2HAAoB;IAO5B,AADI,iBAAM,EACJ;;;IA7DN,cAyCC;IAzCD,kCAyCC;IAMO,eACJ;IADI,8GACJ;IAMI,eAKC;IALD,+CAKC;;;;IAQb,+BAA0B;IACtB,wBAAiE;IACjE,gCAAgC;IAAA,YAAe;IAAA,iBAAO;IACtD,kCAA4E;IAA1B,2MAAS,sBAAe,KAAC;IAAC,YAAsB;IAAA,iBAAS;IAC3G,kCAAmH;IAA3B,2MAAS,uBAAgB,KAAC;IAC9G,uBAAiC;IAEzC,AADI,iBAAS,EACP;;;IAL8B,eAAe;IAAf,sCAAe;IAC6B,eAAsB;IAAtB,6CAAsB;;;;IAhN9G,8BAAyD;IAA5B,uLAAS,wBAAiB,KAAC;IAAC,iBAAM;IAG/D,8BAC+E;IAAvC,AAAnC,oHAAS,wBAAwB,IAAC,oLAAY,iCAA0B,KAAC;IAE1E,8BAA+B;IAC3B,uBAAwD;IACxD,mCAcE;IAHE,+LAAS,wCAAuC,KAAC;IAXrD,iBAcE;IACF,sGAAmB;IAMf,AADJ,8BAAkC,UACzB;IAAA,mBAAG;IACZ,AADY,iBAAM,EACZ;IACN,kCAAkG;IAAlB,2LAAS,cAAO,KAAC;IAC7F,wBAAiC;IAEzC,AADI,iBAAS,EACP;IAGN,gCAAiC;IAC7B,yGAAyE;IA6BzE,yGAAyC;IA0BzC,oHAA8D;IAe9D,yGAAoC;IA2BpC,+FAA6B;IAkEjC,iBAAM;IAGN,yGAA8B;IAUlC,iBAAM;;;IArMM,eAA2B;IAC3B,AADA,gDAA2B,uBACZ;;IAKnB,eAIC;IAJD,6CAIC;IAWD,eA4BC;IA5BD,kHA4BC;IACD,cAwBC;IAxBD,2EAwBC;IAED,cAaC;IAbD,uGAaC;IAED,cAyBC;IAzBD,sEAyBC;IAED,cAiEC;IAjED,wDAiEC;IAIL,cASC;IATD,gEASC;;AD1JT,MAAM,OAAO,sBAAsB;IACvB,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAC9B,aAAa,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;IACxC,QAAQ,GAAG,IAAI,OAAO,EAAQ,CAAC;IAC/B,YAAY,GAAG,IAAI,OAAO,EAAU,CAAC;IAEnB,cAAc,CAAgC;IAExE,8CAA8C;IAC9C,IAAI,cAAc;QACd,OAAO,IAAI,CAAC,cAAc,CAAC;IAC/B,CAAC;IACD,8CAA8C;IAC9C,IAAI,cAAc,CAAC,KAAmC;QAClD,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;IAChC,CAAC;IAED,+BAA+B;IAE/B,4CAA4C;IACnC,WAAW,GAAG,qCAAqC,CAAC;IAE7D;;;;;;OAMG;IACM,UAAU,GAAG,CAAC,CAAC;IAExB,+CAA+C;IACvC,OAAO,GAAG,KAAK,CAAC;IAExB,IACI,MAAM,CAAC,KAAc;QACrB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;YACjB,IAAI,CAAC,eAAe,EAAE,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;YACjB,IAAI,CAAC,eAAe,EAAE,CAAC;QAC3B,CAAC;IACL,CAAC;IACD,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,OAAO,CAAC;IACxB,CAAC;IAED,8CAA8C;IACrC,UAAU,GAAG,GAAG,CAAC;IAE1B,sCAAsC;IAC7B,cAAc,GAAyC,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;IAEjG,oCAAoC;IAC3B,WAAW,GAAG,IAAI,CAAC;IAE5B,oCAAoC;IAC3B,YAAY,GAAG,qBAAqB,CAAC;IAE9C,oCAAoC;IAC3B,YAAY,GAAG,IAAI,CAAC;IAE7B;;;;;OAKG;IACM,eAAe,GAAG,KAAK,CAAC;IAEjC;;;;;OAKG;IACM,oBAAoB,GAAG,IAAI,CAAC;IAErC;;;;;OAKG;IACM,SAAS,GAAG,KAAK,CAAC;IAE3B,kEAAkE;IACzD,SAAS,GAAG,EAAE,CAAC;IAExB,2CAA2C;IAClC,gBAAgB,GAAG,SAAS,CAAC;IAEtC,kBAAkB;IAER,YAAY,GAAG,IAAI,YAAY,EAAW,CAAC;IAC3C,cAAc,GAAG,IAAI,YAAY,EAA6B,CAAC;IAC/D,aAAa,GAAG,IAAI,YAAY,EAA2B,CAAC;IAC5D,cAAc,GAAG,IAAI,YAAY,EAAuB,CAAC;IACzD,eAAe,GAAG,IAAI,YAAY,EAAU,CAAC;IACvD;;;;;OAKG;IACO,eAAe,GAAG,IAAI,YAAY,EAAU,CAAC;IACvD,4EAA4E;IAClE,aAAa,GAAG,IAAI,YAAY,EAAU,CAAC;IACrD,0EAA0E;IAChE,cAAc,GAAG,IAAI,YAAY,EAAQ,CAAC;IAEpD,0BAA0B;IAEnB,KAAK,GAAG,EAAE,CAAC;IACX,WAAW,GAAG,KAAK,CAAC;IACpB,YAAY,GAAwB,EAAE,CAAC;IACvC,UAAU,GAAuB,EAAE,CAAC;IACpC,OAAO,GAAmB,EAAE,CAAC;IAC7B,aAAa,GAA6B,EAAE,CAAC;IAC7C,UAAU,GAAG,CAAC,CAAC;IACf,SAAS,GAAG,CAAC,CAAC;IACd,gBAAgB,GAAG,CAAC,CAAC,CAAC;IACtB,WAAW,GAAG,KAAK,CAAC;IACnB,aAAa,GAAG,CAAC,CAAC;IAE1B;;;;OAIG;IACI,kBAAkB,GAA8B,EAAE,CAAC;IAE1D,8EAA8E;IACtE,aAAa,GAAwB,IAAI,CAAC;IAElD,4EAA4E;IACpE,aAAa,GAAuB,IAAI,CAAC;IAEjD,oDAAoD;IACpD,IAAW,WAAW;QAClB,OAAO,IAAI,CAAC,UAAU,CAAC;IAC3B,CAAC;IAED,yEAAyE;IACzE,IAAW,kBAAkB;QACzB,OAAO,IAAI,CAAC,gBAAgB,IAAI,CAAC,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM;YAChF,CAAC,CAAC,UAAU,IAAI,CAAC,gBAAgB,EAAE;YACnC,CAAC,CAAC,IAAI,CAAC;IACf,CAAC;IAED,QAAQ;QACJ,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,sBAAsB,EAAE,CAAC;IAClC,CAAC;IAED,WAAW;QACP,IAAI,CAAC,aAAa,EAAE,WAAW,EAAE,CAAC;QAClC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;IAC7B,CAAC;IAED,6BAA6B;IAG7B,mBAAmB,CAAC,KAAoB;QACpC,IAAI,IAAI,CAAC,oBAAoB,IAAI,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5D,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,OAAO;QACX,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC;IACL,CAAC;IAED,qCAAqC;IAC9B,aAAa;QAChB,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;QAC5B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,uBAAuB;IAChB,IAAI;QACP,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACnB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;IACL,CAAC;IAED,wBAAwB;IACjB,KAAK;QACR,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;YACpB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC;IACL,CAAC;IAED,iCAAiC;IAC1B,YAAY,CAAC,KAAa;QAC7B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,+BAA+B;IACxB,aAAa,CAAC,MAAwB,EAAE,KAAiB;QAC5D,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;YACrB,MAAM,EAAE,MAAM;YACd,YAAY,EAAE,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO;SAC/C,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC;IAED,8CAA8C;IACvC,iBAAiB;QACpB,IAAI,IAAI,CAAC,gBAAgB,IAAI,CAAC,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;YAChF,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;gBACrB,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,gBAAgB,CAAC;gBAC/C,YAAY,EAAE,KAAK;aACtB,CAAC,CAAC;YACH,IAAI,CAAC,KAAK,EAAE,CAAC;QACjB,CAAC;IACL,CAAC;IAED,kCAAkC;IAC3B,cAAc,CAAC,QAAgB,EAAE,KAAa;QACjD,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YACb,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC7B,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC;QACvC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC;QACzE,IAAI,CAAC,aAAa,EAAE,CAAC;IACzB,CAAC;IAED,+BAA+B;IACxB,eAAe;QAClB,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;QACxB,IAAI,CAAC,aAAa,EAAE,CAAC;IACzB,CAAC;IAED,oCAAoC;IAC7B,eAAe;QAClB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC;IAED,4EAA4E;IACrE,aAAa;QAChB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3C,IAAI,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC;IAED,2EAA2E;IACpE,cAAc;QACjB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;IAC/B,CAAC;IAED,gFAAgF;IACzE,aAAa;QAChB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC;QACD,IAAI,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC;IAED,4CAA4C;IACrC,eAAe;QAClB,IAAI,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC;IAED,yCAAyC;IAClC,cAAc,CAAC,QAAgB,EAAE,KAAa;QACjD,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChE,CAAC;IAED,6CAA6C;IACtC,WAAW,CAAC,KAAa;QAC5B,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC;IACzC,CAAC;IAED,kCAAkC;IAC3B,iBAAiB,CAAC,EAAU;QAC/B,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;YACZ,OAAO,GAAG,EAAE,IAAI,CAAC;QACrB,CAAC;QACD,OAAO,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IACxC,CAAC;IAED,0BAA0B;IAElB,gBAAgB,CAAC,KAAoB;QACzC,OAAO,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC;IACjE,CAAC;IAEO,oBAAoB,CAAC,KAAoB;QAC7C,QAAQ,KAAK,CAAC,GAAG,EAAE,CAAC;YAChB,KAAK,QAAQ;gBACT,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,IAAI,CAAC,KAAK,EAAE,CAAC;gBACb,MAAM;YACV,KAAK,WAAW;gBACZ,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;gBACtB,MAAM;YACV,KAAK,SAAS;gBACV,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;gBACvB,MAAM;YACV,KAAK,OAAO,CAAC,CAAC,CAAC;gBACX,oEAAoE;gBACpE,8DAA8D;gBAC9D,0DAA0D;gBAC1D,2DAA2D;gBAC3D,8DAA8D;gBAC9D,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAmC,CAAC;gBAC5D,MAAM,UAAU,GAAG,MAAM,KAAK,IAAI,CAAC,cAAc,EAAE,aAAa;uBACzD,CAAC,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,CAAC;gBAC5D,IAAI,CAAC,UAAU,EAAE,CAAC;oBACd,OAAO;gBACX,CAAC;gBACD,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBACzB,MAAM;YACV,CAAC;QACL,CAAC;IACL,CAAC;IAEO,aAAa,CAAC,SAAiB;QACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;QAC7C,IAAI,QAAQ,GAAG,CAAC;YAAE,OAAO;QAEzB,0EAA0E;QAC1E,2EAA2E;QAC3E,MAAM,WAAW,GAAG,QAAQ,CAAC,aAAa,YAAY,WAAW;eAC1D,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;QAEhE,IAAI,CAAC,gBAAgB,IAAI,SAAS,CAAC;QACnC,IAAI,IAAI,CAAC,gBAAgB,GAAG,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC,gBAAgB,GAAG,QAAQ,CAAC;QACrC,CAAC;aAAM,IAAI,IAAI,CAAC,gBAAgB,GAAG,QAAQ,EAAE,CAAC;YAC1C,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC;QAC9B,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAEzB,2EAA2E;QAC3E,sEAAsE;QACtE,oEAAoE;QACpE,MAAM,GAAG,GAAG,QAAQ,CAAC,cAAc,CAAC,UAAU,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;QACvE,GAAG,EAAE,cAAc,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAC1C,IAAI,WAAW,EAAE,CAAC;YACd,GAAG,EAAE,KAAK,EAAE,CAAC;QACjB,CAAC;IACL,CAAC;IAED;;;;;;;;OAQG;IACI,kBAAkB,CAAC,KAAoB;QAC1C,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;YACtB,OAAO;QACX,CAAC;QACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAmC,CAAC;QAC9D,IAAI,QAAQ,EAAE,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;YAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;YACzC,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI,EAAE,CAAC;gBAClD,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,0CAA0C;gBACjE,OAAO;YACX,CAAC;YACD,IAAI,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,gBAAgB,GAAG,CAAC,EAAE,CAAC;gBAC9C,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;gBACvB,OAAO;YACX,CAAC;YACD,gEAAgE;QACpE,CAAC;QACD,MAAM,IAAI,GAAI,KAAK,CAAC,aAA6B,IAAI,IAAI,CAAC;QAC1D,IAAI,CAAC,IAAI,EAAE,CAAC;YACR,OAAO;QACX,CAAC;QACD,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CACzB,IAAI,CAAC,gBAAgB,CAAc,8EAA8E,CAAC,CACrH,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC;QAC3C,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO;QACX,CAAC;QACD,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAmC,CAAC;QAC5D,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,MAAM,KAAK,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;YAClE,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;QAC1B,CAAC;aAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YACpD,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;QAC9C,CAAC;IACL,CAAC;IAED;;;;OAIG;IACI,cAAc,CAAC,KAAa;QAC/B,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QACzB,IAAI,CAAC,cAAc,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;IAChD,CAAC;IAED,yEAAyE;IAClE,eAAe,CAAC,KAAoB,EAAE,KAAa;QACtD,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;YAC7C,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;IACL,CAAC;IAEO,mBAAmB;QACvB,IAAI,CAAC,YAAY;aACZ,IAAI,CACD,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,EAC7B,oBAAoB,EAAE,EACtB,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAC3B;aACA,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;IAC/C,CAAC;IAEO,sBAAsB;QAC1B,IAAI,CAAC,aAAa,CAAC,YAAY;aAC1B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;aAC9B,SAAS,CAAC,GAAG,CAAC,EAAE;YACb,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC,CAAC,CAAC;IACX,CAAC;IAEO,KAAK,CAAC,aAAa;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,OAAO;QACX,CAAC;QAED,MAAM,OAAO,GAAG,EAAE,IAAI,CAAC,aAAa,CAAC;QAErC,MAAM,OAAO,GAAkB;YAC3B,KAAK,EAAE,KAAK;YACZ,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,cAAc,EAAE,IAAI,CAAC,cAAc;SACtC,CAAC;QAEF,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACvB,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YACrD,OAAO;QACX,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAEjE,+EAA+E;QAC/E,IAAI,OAAO,KAAK,IAAI,CAAC,aAAa,EAAE,CAAC;YACjC,OAAO;QACX,CAAC;QAED,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC;QACnC,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC;QACpC,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;QAChC,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC;QACtC,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC;QACpC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAE7D,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;YACrB,KAAK,EAAE,KAAK;YACZ,OAAO,EAAE,IAAI,CAAC,aAAa;YAC3B,WAAW,EAAE,QAAQ,CAAC,UAAU;YAChC,SAAS,EAAE,QAAQ,CAAC,SAAS;SAChC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED;;;;;;;OAOG;IACK,sBAAsB,CAAC,KAAa,EAAE,OAAsB,EAAE,OAAe;QACjF,qFAAqF;QACrF,IAAI,CAAC,aAAa,EAAE,WAAW,EAAE,CAAC;QAClC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAE1B,0CAA0C;QAC1C,IAAI,CAAC,kBAAkB,GAAG,EAAE,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;QACrB,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;QACpB,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QACnB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAEzB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC;YACpE,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE;gBACZ,IAAI,OAAO,KAAK,IAAI,CAAC,aAAa;oBAAE,OAAO;gBAE3C,IAAI,KAAK,CAAC,KAAK,KAAK,UAAU,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;oBACnD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC,CAAC;oBACzC,IAAI,CAAC,kBAAkB,GAAG;wBACtB,GAAG,IAAI,CAAC,kBAAkB;wBAC1B;4BACI,IAAI,EAAE,KAAK,CAAC,YAAY;4BACxB,KAAK,EAAE,KAAK;4BACZ,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,CAAC;4BAC/B,KAAK,EAAE,WAAW;yBACrB;qBACJ,CAAC;oBACF,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC5C,sEAAsE;wBACtE,IAAI,CAAC,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;wBACzD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;wBACrE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;wBACzC,IAAI,IAAI,CAAC,gBAAgB,GAAG,CAAC,EAAE,CAAC;4BAC5B,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC;wBAC9B,CAAC;oBACL,CAAC;gBACL,CAAC;qBAAM,IAAI,KAAK,CAAC,KAAK,KAAK,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;oBAClD,wEAAwE;oBACxE,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC;oBAChC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;oBACrE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;oBAChE,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;oBACvC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC;oBACnD,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC9D,CAAC;gBAED,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YAC7B,CAAC;YACD,KAAK,EAAE,CAAC,GAAU,EAAE,EAAE;gBAClB,IAAI,OAAO,KAAK,IAAI,CAAC,aAAa;oBAAE,OAAO;gBAC3C,IAAI,CAAC,kBAAkB,GAAG;oBACtB,GAAG,IAAI,CAAC,kBAAkB;oBAC1B,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,CAAC,OAAO,EAAE;iBACxF,CAAC;gBACF,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YAC7B,CAAC;YACD,QAAQ,EAAE,GAAG,EAAE;gBACX,IAAI,OAAO,KAAK,IAAI,CAAC,aAAa;oBAAE,OAAO;gBAC3C,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;oBACrB,KAAK,EAAE,KAAK;oBACZ,OAAO,EAAE,IAAI,CAAC,aAAa;oBAC3B,WAAW,EAAE,IAAI,CAAC,UAAU;oBAC5B,SAAS,EAAE,IAAI,CAAC,SAAS;iBAC5B,CAAC,CAAC;gBACH,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YAC7B,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;IAEO,YAAY;QAChB,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;QACrB,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;QACpB,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QACnB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAEO,eAAe;QACnB,yEAAyE;QACzE,mEAAmE;QACnE,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC,aAAa,YAAY,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;QACnG,iCAAiC;QACjC,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;YACxB,IAAI,CAAC,cAAc,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;YAC5C,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,eAAe;QACnB,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC;QAC3B,IAAI,IAAI,CAAC,aAAa,EAAE,WAAW,EAAE,CAAC;YAClC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;QAC/B,CAAC;QACD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;IAC9B,CAAC;IAED,yDAAyD;IAClD,gBAAgB;QACnB,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACrE,CAAC;IAED,gDAAgD;IACzC,gBAAgB;QACnB,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACnC,CAAC;IAED,0DAA0D;IACnD,mBAAmB,CAAC,MAAwB;QAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAC5C,OAAO,SAAS,KAAK,IAAI,CAAC,gBAAgB,CAAC;IAC/C,CAAC;IAED,mDAAmD;IAC5C,mBAAmB,CAAC,MAAwB;QAC/C,OAAO,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;IAED,6DAA6D;IACtD,YAAY,CAAC,MAAwB;QACxC,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;IAED,4CAA4C;IACrC,YAAY,CAAC,MAAwB;QACxC,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;gHAxnBQ,sBAAsB;6DAAtB,sBAAsB;;;;;;YAAtB,qGAAA,+BAA2B,0BAAL;;YC7DnC,gFAAc;;YAAd,qCAyNC;;;iFD5JY,sBAAsB;cANlC,SAAS;6BACM,KAAK,YACP,mBAAmB;;kBAU5B,SAAS;mBAAC,aAAa;;kBAcvB,KAAK;;kBASL,KAAK;;kBAKL,KAAK;;kBAgBL,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAQL,KAAK;;kBAQL,KAAK;;kBAQL,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAIL,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBACN,MAAM;;kBAON,MAAM;;kBAEN,MAAM;;kBAEN,MAAM;;kBAuDN,YAAY;mBAAC,kBAAkB,EAAE,CAAC,QAAQ,CAAC;;kFAtKnC,sBAAsB","sourcesContent":["/**\n * @fileoverview Search Overlay Component\n *\n * A floating search overlay inspired by command palette / Spotlight style.\n * Triggered by Cmd+K (Mac) or Ctrl+K (Windows), appears as a centered\n * floating panel with backdrop blur, search input, and grouped results.\n *\n * Supports keyboard navigation (up/down/enter/escape), filter facets,\n * and responsive mobile layout.\n */\n\nimport {\n Component,\n EventEmitter,\n HostListener,\n Input,\n OnDestroy,\n OnInit,\n Output,\n ChangeDetectorRef,\n ElementRef,\n ViewChild,\n inject\n} from '@angular/core';\nimport { Subject, Subscription } from 'rxjs';\nimport { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';\nimport { SearchService } from './search.service';\nimport {\n SearchResultItem,\n SearchResultGroup,\n SearchFilter,\n SearchRequest,\n SearchResultSelectedEvent,\n SearchFilterChangeEvent,\n SearchExecutedEvent,\n} from './search-types';\n\n/**\n * Per-provider streaming status displayed above the results list while a streaming\n * search is in flight. One entry per provider that has reported back. Populated\n * progressively as `streamScopedSearch` emits 'provider' events.\n */\nexport interface StreamingProviderStatus {\n /** Provider name from the SearchEngine (e.g. 'Vector', 'FullText') */\n Name: string;\n /** Result count contributed by this provider */\n Count: number;\n /** Wall-clock latency for this provider's leg, in milliseconds */\n ElapsedMs: number;\n /** Reported state for this provider */\n State: 'Completed' | 'Error';\n /** Last error message if State is 'Error' */\n ErrorMessage?: string;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-search-overlay',\n templateUrl: './search-overlay.component.html',\n styleUrls: ['./search-overlay.component.css']\n})\nexport class SearchOverlayComponent implements OnInit, OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n protected searchService = inject(SearchService);\n private destroy$ = new Subject<void>();\n private searchInput$ = new Subject<string>();\n\n @ViewChild('searchInput') SearchInputRef!: ElementRef<HTMLInputElement>;\n\n /** @deprecated Use {@link SearchInputRef}. */\n get searchInputRef(): ElementRef<HTMLInputElement> {\n return this.SearchInputRef;\n }\n /** @deprecated Use {@link SearchInputRef}. */\n set searchInputRef(value: ElementRef<HTMLInputElement>) {\n this.SearchInputRef = value;\n }\n\n // --- Configuration Inputs ---\n\n /** Placeholder text for the search input */\n @Input() Placeholder = 'Search across all your knowledge...';\n\n /**\n * Maximum number of results to fetch and display. Deliberately small — the\n * overlay is a quick-jump surface; \"See all results\" hands off to the full\n * Search Results workspace for anything deeper. 8 matches the omnibar\n * palette's RESULT count (it fetches 9 rows = 8 results + its see-all row;\n * this overlay's see-all is a footer button, not a row).\n */\n @Input() MaxResults = 8;\n\n /** Whether the overlay is currently visible */\n private _isOpen = false;\n\n @Input()\n set IsOpen(value: boolean) {\n const prev = this._isOpen;\n this._isOpen = value;\n if (value && !prev) {\n this.onOverlayOpened();\n }\n if (!value && prev) {\n this.onOverlayClosed();\n }\n }\n get IsOpen(): boolean {\n return this._isOpen;\n }\n\n /** Debounce time in ms before search fires */\n @Input() DebounceMs = 400;\n\n /** Which search sources to include */\n @Input() IncludeSources: ('vector' | 'fulltext' | 'entity')[] = ['vector', 'fulltext', 'entity'];\n\n /** Whether to show filter facets */\n @Input() ShowFilters = true;\n\n /** Text for the agent CTA button */\n @Input() AgentCtaText = 'Ask Knowledge Agent';\n\n /** Whether to show the agent CTA */\n @Input() ShowAgentCta = true;\n\n /**\n * When true, the overlay subscribes to `SearchService.StreamSearch` instead of awaiting\n * `ExecuteSearch`. Results render progressively as each provider reports back. The\n * per-provider status chip strip becomes visible while the stream is in flight.\n * Defaults to false to preserve the request-response UX that shipped in Phase 1.\n */\n @Input() EnableStreaming = false;\n\n /**\n * When false, the overlay does NOT claim the global Ctrl/Cmd+K chord. For hosts\n * (e.g. the Explorer shell) that own that shortcut themselves and open the\n * overlay programmatically — two listeners on the same chord would double-toggle.\n * Escape/arrow handling while open is unaffected.\n */\n @Input() EnableGlobalShortcut = true;\n\n /**\n * Optional promo strip pinned to the overlay's bottom edge — a host-supplied\n * nudge (e.g. Explorer advertising its command palette). The component is\n * deliberately ignorant of WHAT is being promoted; the host provides the\n * copy and handles both outcomes.\n */\n @Input() ShowPromo = false;\n\n /** Promo copy (one sentence). Required when ShowPromo is true. */\n @Input() PromoText = '';\n\n /** Label for the promo's accept action. */\n @Input() PromoActionLabel = 'Turn on';\n\n // --- Outputs ---\n\n @Output() IsOpenChange = new EventEmitter<boolean>();\n @Output() ResultSelected = new EventEmitter<SearchResultSelectedEvent>();\n @Output() FilterChanged = new EventEmitter<SearchFilterChangeEvent>();\n @Output() SearchExecuted = new EventEmitter<SearchExecutedEvent>();\n @Output() AgentCtaClicked = new EventEmitter<string>();\n /**\n * Emitted when the user clicks \"See all results\" — carries the current query.\n * Hosts (e.g. the Explorer shell) open the full Search Results workspace,\n * which has scopes, relevance controls, and richer result actions than this\n * capped quick-jump overlay. The overlay closes itself after emitting.\n */\n @Output() SeeAllRequested = new EventEmitter<string>();\n /** Promo accept — carries the current query so the host can hand it off. */\n @Output() PromoAccepted = new EventEmitter<string>();\n /** Promo dismissed — the host should persist this and stop showing it. */\n @Output() PromoDismissed = new EventEmitter<void>();\n\n // --- Component State ---\n\n public Query = '';\n public IsSearching = false;\n public ResultGroups: SearchResultGroup[] = [];\n public AllResults: SearchResultItem[] = [];\n public Filters: SearchFilter[] = [];\n public ActiveFilters: Record<string, string[]> = {};\n public TotalCount = 0;\n public ElapsedMs = 0;\n public HighlightedIndex = -1;\n public HasSearched = false;\n private searchVersion = 0;\n\n /**\n * Per-provider status entries shown above the results list while a streaming search\n * is in flight. One entry per provider that has reported back. Empty when the user\n * is not running a streaming search (or when `EnableStreaming` is false).\n */\n public StreamingProviders: StreamingProviderStatus[] = [];\n\n /** Active stream subscription so we can cancel on a new search or destroy. */\n private currentStream: Subscription | null = null;\n\n /** Element focused before the overlay opened — restored on close (a11y). */\n private previousFocus: HTMLElement | null = null;\n\n /** All results flattened for keyboard navigation */\n public get FlatResults(): SearchResultItem[] {\n return this.AllResults;\n }\n\n /** id of the highlighted option, announced via aria-activedescendant. */\n public get ActiveDescendantId(): string | null {\n return this.HighlightedIndex >= 0 && this.HighlightedIndex < this.FlatResults.length\n ? `so-opt-${this.HighlightedIndex}`\n : null;\n }\n\n ngOnInit(): void {\n this.setupSearchDebounce();\n this.subscribeToSearchState();\n }\n\n ngOnDestroy(): void {\n this.currentStream?.unsubscribe();\n this.currentStream = null;\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // --- Keyboard shortcuts ---\n\n @HostListener('document:keydown', ['$event'])\n HandleGlobalKeydown(event: KeyboardEvent): void {\n if (this.EnableGlobalShortcut && this.isToggleShortcut(event)) {\n event.preventDefault();\n this.ToggleOverlay();\n return;\n }\n if (this._isOpen) {\n this.handleOverlayKeydown(event);\n }\n }\n\n /** Toggle the overlay open/closed */\n public ToggleOverlay(): void {\n this.IsOpen = !this._isOpen;\n this.IsOpenChange.emit(this._isOpen);\n }\n\n /** Open the overlay */\n public Open(): void {\n if (!this._isOpen) {\n this.IsOpen = true;\n this.IsOpenChange.emit(true);\n }\n }\n\n /** Close the overlay */\n public Close(): void {\n if (this._isOpen) {\n this.IsOpen = false;\n this.IsOpenChange.emit(false);\n }\n }\n\n /** Handle query input changes */\n public OnQueryInput(value: string): void {\n this.Query = value;\n this.searchInput$.next(value);\n }\n\n /** Handle clicking a result */\n public OnResultClick(result: SearchResultItem, event: MouseEvent): void {\n this.ResultSelected.emit({\n Result: result,\n OpenInNewTab: event.metaKey || event.ctrlKey\n });\n this.Close();\n }\n\n /** Handle selecting the highlighted result */\n public SelectHighlighted(): void {\n if (this.HighlightedIndex >= 0 && this.HighlightedIndex < this.FlatResults.length) {\n this.ResultSelected.emit({\n Result: this.FlatResults[this.HighlightedIndex],\n OpenInNewTab: false\n });\n this.Close();\n }\n }\n\n /** Handle filter option toggle */\n public OnFilterToggle(category: string, value: string): void {\n const current = this.ActiveFilters[category] ?? [];\n const index = current.indexOf(value);\n if (index >= 0) {\n current.splice(index, 1);\n } else {\n current.push(value);\n }\n this.ActiveFilters[category] = current;\n this.FilterChanged.emit({ Category: category, SelectedValues: current });\n this.executeSearch();\n }\n\n /** Clear all active filters */\n public ClearAllFilters(): void {\n this.ActiveFilters = {};\n this.executeSearch();\n }\n\n /** Handle clicking the agent CTA */\n public OnAgentCtaClick(): void {\n this.AgentCtaClicked.emit(this.Query);\n this.Close();\n }\n\n /** Promo accept: emit the current query and close — the host takes over. */\n public OnPromoAccept(): void {\n this.PromoAccepted.emit(this.Query.trim());\n this.Close();\n }\n\n /** Promo dismiss: the host persists the dismissal; hide it immediately. */\n public OnPromoDismiss(): void {\n this.ShowPromo = false;\n this.PromoDismissed.emit();\n }\n\n /** Handle clicking \"See all results\" — hand off to the full Search workspace */\n public OnSeeAllClick(): void {\n const query = this.Query.trim();\n if (query.length > 0) {\n this.SeeAllRequested.emit(query);\n }\n this.Close();\n }\n\n /** Handle clicking the backdrop to close */\n public OnBackdropClick(): void {\n this.Close();\n }\n\n /** Check if a filter option is active */\n public IsFilterActive(category: string, value: string): boolean {\n return (this.ActiveFilters[category] ?? []).includes(value);\n }\n\n /** Get a score display value (percentage) */\n public FormatScore(score: number): string {\n return `${Math.round(score * 100)}%`;\n }\n\n /** Format elapsed time display */\n public FormatElapsedTime(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n }\n return `${(ms / 1000).toFixed(1)}s`;\n }\n\n // --- Private Methods ---\n\n private isToggleShortcut(event: KeyboardEvent): boolean {\n return (event.metaKey || event.ctrlKey) && event.key === 'k';\n }\n\n private handleOverlayKeydown(event: KeyboardEvent): void {\n switch (event.key) {\n case 'Escape':\n event.preventDefault();\n this.Close();\n break;\n case 'ArrowDown':\n event.preventDefault();\n this.moveHighlight(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n this.moveHighlight(-1);\n break;\n case 'Enter': {\n // Only claim Enter when it belongs to the combobox model (typing in\n // the input / a focused result row). A focused BUTTON (close,\n // see-all, filter chip, promo) must keep its native Enter\n // activation — preventDefault here at document level would\n // silently swallow it, or worse, open the highlighted result.\n const active = document.activeElement as HTMLElement | null;\n const inCombobox = active === this.SearchInputRef?.nativeElement\n || (active?.classList.contains('result-item') ?? false);\n if (!inCombobox) {\n return;\n }\n event.preventDefault();\n this.SelectHighlighted();\n break;\n }\n }\n }\n\n private moveHighlight(direction: number): void {\n const maxIndex = this.FlatResults.length - 1;\n if (maxIndex < 0) return;\n\n // If a result row currently holds DOM focus (roving tabindex), keep focus\n // travelling with the highlight; from the input, only the highlight moves.\n const rowHadFocus = document.activeElement instanceof HTMLElement\n && document.activeElement.classList.contains('result-item');\n\n this.HighlightedIndex += direction;\n if (this.HighlightedIndex < 0) {\n this.HighlightedIndex = maxIndex;\n } else if (this.HighlightedIndex > maxIndex) {\n this.HighlightedIndex = 0;\n }\n this.cdr.detectChanges();\n\n // Keyboard-driven moves keep the highlighted row visible. Mouse hover sets\n // HighlightedIndex directly in the template and deliberately does NOT\n // scroll — auto-scrolling under the pointer fights the user's hand.\n const row = document.getElementById(`so-opt-${this.HighlightedIndex}`);\n row?.scrollIntoView({ block: 'nearest' });\n if (rowHadFocus) {\n row?.focus();\n }\n }\n\n /**\n * Tab behavior inside the dialog:\n * - On a result row, Tab / Shift+Tab step through the RESULTS themselves\n * (mirrors ArrowDown/Up) until walking off either end of the list — then\n * focus continues to the footer actions / back to the earlier controls.\n * - Everywhere else, Tab wraps within the dialog (focus trap): input → close\n * → filter chips → results → footer actions → back to the input.\n * Escape is handled by the document-level keydown.\n */\n public OnSpotlightKeydown(event: KeyboardEvent): void {\n if (event.key !== 'Tab') {\n return;\n }\n const activeEl = document.activeElement as HTMLElement | null;\n if (activeEl?.classList.contains('result-item')) {\n const last = this.FlatResults.length - 1;\n if (!event.shiftKey && this.HighlightedIndex < last) {\n event.preventDefault();\n this.moveHighlight(1); // row has focus, so focus travels with it\n return;\n }\n if (event.shiftKey && this.HighlightedIndex > 0) {\n event.preventDefault();\n this.moveHighlight(-1);\n return;\n }\n // At either end: fall through so Tab leaves the list naturally.\n }\n const root = (event.currentTarget as HTMLElement) ?? null;\n if (!root) {\n return;\n }\n const focusables = Array.from(\n root.querySelectorAll<HTMLElement>('input, button, .result-item[tabindex=\"0\"], .search-recent-item[tabindex=\"0\"]')\n ).filter((el) => el.offsetParent !== null);\n if (focusables.length === 0) {\n return;\n }\n const active = document.activeElement as HTMLElement | null;\n if (!event.shiftKey && active === focusables[focusables.length - 1]) {\n event.preventDefault();\n focusables[0].focus();\n } else if (event.shiftKey && active === focusables[0]) {\n event.preventDefault();\n focusables[focusables.length - 1].focus();\n }\n }\n\n /**\n * Recent-search row activated (click or Enter/Space). Re-runs the search AND\n * refocuses the input — the activated row leaves the DOM when recents are\n * replaced by results, which would otherwise drop focus to <body>.\n */\n public OnRecentSelect(query: string): void {\n this.OnQueryInput(query);\n this.SearchInputRef?.nativeElement?.focus();\n }\n\n /** Recent-search rows are keyboard-activatable (Enter/Space = click). */\n public OnRecentKeydown(event: KeyboardEvent, query: string): void {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this.OnRecentSelect(query);\n }\n }\n\n private setupSearchDebounce(): void {\n this.searchInput$\n .pipe(\n debounceTime(this.DebounceMs),\n distinctUntilChanged(),\n takeUntil(this.destroy$)\n )\n .subscribe(() => this.executeSearch());\n }\n\n private subscribeToSearchState(): void {\n this.searchService.IsSearching$\n .pipe(takeUntil(this.destroy$))\n .subscribe(val => {\n this.IsSearching = val;\n this.cdr.detectChanges();\n });\n }\n\n private async executeSearch(): Promise<void> {\n const query = this.Query.trim();\n if (!query) {\n this.clearResults();\n return;\n }\n\n const version = ++this.searchVersion;\n\n const request: SearchRequest = {\n Query: query,\n MaxResults: this.MaxResults,\n ActiveFilters: this.ActiveFilters,\n IncludeSources: this.IncludeSources,\n };\n\n if (this.EnableStreaming) {\n this.executeStreamingSearch(query, request, version);\n return;\n }\n\n const response = await this.searchService.ExecuteSearch(request);\n\n // Discard results if a newer search was triggered while this one was in-flight\n if (version !== this.searchVersion) {\n return;\n }\n\n this.AllResults = response.Results;\n this.ResultGroups = response.Groups;\n this.Filters = response.Filters;\n this.TotalCount = response.TotalCount;\n this.ElapsedMs = response.ElapsedMs;\n this.HasSearched = true;\n this.HighlightedIndex = response.Results.length > 0 ? 0 : -1;\n\n this.SearchExecuted.emit({\n Query: query,\n Filters: this.ActiveFilters,\n ResultCount: response.TotalCount,\n ElapsedMs: response.ElapsedMs,\n });\n\n this.cdr.detectChanges();\n }\n\n /**\n * Streaming variant of executeSearch — subscribes to `SearchService.StreamSearch` and\n * progressively updates the result list as each provider reports back. The 'final'\n * event carries the canonical fused/reranked list, which replaces the partials.\n *\n * Cancellation: a new search invocation tears down the in-flight stream via\n * `searchVersion` and `currentStream.unsubscribe()`.\n */\n private executeStreamingSearch(query: string, request: SearchRequest, version: number): void {\n // Tear down any prior stream so we don't get cross-talk between consecutive queries.\n this.currentStream?.unsubscribe();\n this.currentStream = null;\n\n // Reset visible state for a fresh stream.\n this.StreamingProviders = [];\n this.AllResults = [];\n this.ResultGroups = [];\n this.TotalCount = 0;\n this.ElapsedMs = 0;\n this.HasSearched = true;\n this.HighlightedIndex = -1;\n this.cdr.detectChanges();\n\n this.currentStream = this.searchService.StreamSearch(request).subscribe({\n next: (event) => {\n if (version !== this.searchVersion) return;\n\n if (event.Phase === 'provider' && event.ProviderName) {\n const count = event.Results?.length ?? 0;\n this.StreamingProviders = [\n ...this.StreamingProviders,\n {\n Name: event.ProviderName,\n Count: count,\n ElapsedMs: event.ElapsedMs ?? 0,\n State: 'Completed',\n },\n ];\n if (event.Results && event.Results.length > 0) {\n // Append partials so the user sees the list grow as providers return.\n this.AllResults = [...this.AllResults, ...event.Results];\n this.ResultGroups = this.searchService.GroupResults(this.AllResults);\n this.TotalCount = this.AllResults.length;\n if (this.HighlightedIndex < 0) {\n this.HighlightedIndex = 0;\n }\n }\n } else if (event.Phase === 'final' && event.Results) {\n // Replace the appended partials with the canonical fused/reranked list.\n this.AllResults = event.Results;\n this.ResultGroups = this.searchService.GroupResults(this.AllResults);\n this.Filters = this.searchService.BuildFilters(this.AllResults);\n this.TotalCount = event.Results.length;\n this.ElapsedMs = event.ElapsedMs ?? this.ElapsedMs;\n this.HighlightedIndex = event.Results.length > 0 ? 0 : -1;\n }\n\n this.cdr.detectChanges();\n },\n error: (err: Error) => {\n if (version !== this.searchVersion) return;\n this.StreamingProviders = [\n ...this.StreamingProviders,\n { Name: 'stream', Count: 0, ElapsedMs: 0, State: 'Error', ErrorMessage: err.message },\n ];\n this.cdr.detectChanges();\n },\n complete: () => {\n if (version !== this.searchVersion) return;\n this.SearchExecuted.emit({\n Query: query,\n Filters: this.ActiveFilters,\n ResultCount: this.TotalCount,\n ElapsedMs: this.ElapsedMs,\n });\n this.cdr.detectChanges();\n },\n });\n }\n\n private clearResults(): void {\n this.AllResults = [];\n this.ResultGroups = [];\n this.Filters = [];\n this.TotalCount = 0;\n this.ElapsedMs = 0;\n this.HasSearched = false;\n this.HighlightedIndex = -1;\n this.cdr.detectChanges();\n }\n\n private onOverlayOpened(): void {\n // Remember what had focus so Close() can hand it back (a11y: the overlay\n // is a modal dialog — focus must return to the summoning control).\n this.previousFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null;\n // Focus input after view updates\n Promise.resolve().then(() => {\n this.SearchInputRef?.nativeElement?.focus();\n this.cdr.detectChanges();\n });\n }\n\n private onOverlayClosed(): void {\n this.HighlightedIndex = -1;\n if (this.previousFocus?.isConnected) {\n this.previousFocus.focus();\n }\n this.previousFocus = null;\n }\n\n /** Check if any filters are active (used by template) */\n public HasActiveFilters(): boolean {\n return Object.values(this.ActiveFilters).some(v => v.length > 0);\n }\n\n /** @deprecated Use {@link HasActiveFilters}. */\n public hasActiveFilters(): boolean {\n return this.HasActiveFilters();\n }\n\n /** Check if a result is currently keyboard-highlighted */\n public IsResultHighlighted(result: SearchResultItem): boolean {\n const flatIndex = this.GetFlatIndex(result);\n return flatIndex === this.HighlightedIndex;\n }\n\n /** @deprecated Use {@link IsResultHighlighted}. */\n public isResultHighlighted(result: SearchResultItem): boolean {\n return this.IsResultHighlighted(result);\n }\n\n /** Get the flat index of a result for keyboard navigation */\n public GetFlatIndex(result: SearchResultItem): number {\n return this.FlatResults.indexOf(result);\n }\n\n /** @deprecated Use {@link GetFlatIndex}. */\n public getFlatIndex(result: SearchResultItem): number {\n return this.GetFlatIndex(result);\n }\n}\n","@if (IsOpen) {\n <!-- Backdrop -->\n <div class=\"search-backdrop\" (click)=\"OnBackdropClick()\"></div>\n\n <!-- Spotlight container -->\n <div class=\"search-spotlight\" role=\"dialog\" aria-modal=\"true\" aria-label=\"Search\"\n (click)=\"$event.stopPropagation()\" (keydown)=\"OnSpotlightKeydown($event)\">\n <!-- Search input area -->\n <div class=\"search-input-wrap\">\n <i class=\"fa-solid fa-magnifying-glass search-icon\"></i>\n <input\n #searchInput\n type=\"text\"\n class=\"search-input\"\n role=\"combobox\"\n aria-controls=\"search-overlay-listbox\"\n aria-autocomplete=\"list\"\n [attr.aria-expanded]=\"AllResults.length > 0\"\n [attr.aria-activedescendant]=\"ActiveDescendantId\"\n [placeholder]=\"Placeholder\"\n [value]=\"Query\"\n (input)=\"OnQueryInput($any($event.target).value)\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n @if (IsSearching) {\n <div class=\"search-spinner\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n </div>\n }\n <div class=\"search-shortcut-hint\">\n <kbd>ESC</kbd>\n </div>\n <button type=\"button\" class=\"search-close-btn\" aria-label=\"Close\" title=\"Close\" (click)=\"Close()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n <!-- Results area -->\n <div class=\"search-results-area\">\n @if (EnableStreaming && (IsSearching || StreamingProviders.length > 0)) {\n <!-- Streaming status strip — one chip per provider that has reported -->\n <div class=\"streaming-status-strip\" aria-live=\"polite\">\n @if (StreamingProviders.length === 0 && IsSearching) {\n <span class=\"streaming-chip streaming-chip-pending\">\n <i class=\"fa-solid fa-circle-notch fa-spin\"></i>\n <span>Searching…</span>\n </span>\n }\n @for (p of StreamingProviders; track p.Name) {\n <span class=\"streaming-chip\"\n [class.streaming-chip-error]=\"p.State === 'Error'\"\n [class.streaming-chip-completed]=\"p.State === 'Completed'\">\n @if (p.State === 'Completed') {\n <i class=\"fa-solid fa-check\"></i>\n } @else {\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n }\n <span class=\"streaming-chip-name\">{{ p.Name }}</span>\n @if (p.State === 'Completed') {\n <span class=\"streaming-chip-count\">{{ p.Count }}</span>\n <span class=\"streaming-chip-time\">{{ FormatElapsedTime(p.ElapsedMs) }}</span>\n } @else if (p.ErrorMessage) {\n <span class=\"streaming-chip-time\">{{ p.ErrorMessage }}</span>\n }\n </span>\n }\n </div>\n }\n @if (ShowFilters && Filters.length > 0) {\n <!-- Filter chips -->\n <div class=\"search-filter-bar\">\n @for (filter of Filters; track filter.Category) {\n @for (option of filter.Options; track option.Value) {\n <button\n class=\"filter-chip\"\n [class.filter-chip-active]=\"IsFilterActive(filter.Category, option.Value)\"\n (click)=\"OnFilterToggle(filter.Category, option.Value)\"\n >\n @if (option.Icon) {\n <i [class]=\"option.Icon\"></i>\n }\n <span>{{ option.Label }}</span>\n <span class=\"filter-chip-count\">{{ option.Count }}</span>\n </button>\n }\n }\n @if (hasActiveFilters()) {\n <button class=\"filter-clear-btn\" (click)=\"ClearAllFilters()\">\n <i class=\"fa-solid fa-times\"></i> Clear\n </button>\n }\n </div>\n }\n\n @if (HasSearched && AllResults.length === 0 && !IsSearching) {\n <!-- No results -->\n <mj-empty-state\n Variant=\"no-results\"\n Title=\"No results found\"\n Message=\"Try different keywords or remove some filters\">\n @if (ShowAgentCta) {\n <button ngProjectAs=\"[actions]\" class=\"agent-cta-btn\" (click)=\"OnAgentCtaClick()\">\n <i class=\"fa-solid fa-robot\"></i>\n {{ AgentCtaText }}\n </button>\n }\n </mj-empty-state>\n }\n\n @if (!HasSearched && !IsSearching) {\n <!-- Recent searches -->\n <div class=\"search-recent\">\n @if (searchService.RecentSearches$.value.length > 0) {\n <div class=\"search-recent-header\">\n <span class=\"search-recent-title\">Recent Searches</span>\n </div>\n @for (recent of searchService.RecentSearches$.value; track recent.Query; let i = $index) {\n @if (i < 5) {\n <div class=\"search-recent-item\" role=\"button\" tabindex=\"0\"\n (click)=\"OnRecentSelect(recent.Query)\"\n (keydown)=\"OnRecentKeydown($event, recent.Query)\">\n <i class=\"fa-solid fa-clock search-recent-icon\"></i>\n <span>{{ recent.Query }}</span>\n <span class=\"search-recent-count\">{{ recent.ResultCount }} results</span>\n </div>\n }\n }\n } @else {\n <mj-empty-state\n Variant=\"no-results\"\n Title=\"Start typing to search across all your knowledge\"\n Size=\"compact\" />\n }\n </div>\n }\n\n @if (AllResults.length > 0) {\n <!-- Grouped results -->\n <div id=\"search-overlay-listbox\" role=\"listbox\" aria-label=\"Search results\">\n @for (group of ResultGroups; track group.SourceType) {\n <div class=\"result-group\" role=\"presentation\">\n <div class=\"result-group-header\" role=\"presentation\">\n <i [class]=\"group.Icon\"></i>\n <span class=\"result-group-label\">{{ group.Label }}</span>\n <span class=\"result-group-count\">{{ group.TotalCount }}</span>\n </div>\n @for (result of group.Results; track result.ID; let ri = $index) {\n <div\n class=\"result-item\"\n role=\"option\"\n [attr.id]=\"'so-opt-' + getFlatIndex(result)\"\n [attr.tabindex]=\"isResultHighlighted(result) ? 0 : -1\"\n [attr.aria-selected]=\"isResultHighlighted(result)\"\n [class.result-item-highlighted]=\"isResultHighlighted(result)\"\n (click)=\"OnResultClick(result, $event)\"\n (focus)=\"HighlightedIndex = getFlatIndex(result)\"\n (mouseenter)=\"HighlightedIndex = getFlatIndex(result)\"\n >\n <div class=\"result-item-icon\">\n <i [class]=\"result.SourceIcon\"></i>\n </div>\n <div class=\"result-item-content\">\n <div class=\"result-item-title\">{{ result.Title }}</div>\n <div class=\"result-item-snippet\">{{ result.Snippet }}</div>\n @if (result.Tags.length > 0) {\n <div class=\"result-item-tags\">\n @for (tag of result.Tags; track tag; let ti = $index) {\n @if (ti < 3) {\n <span class=\"result-tag\">{{ tag }}</span>\n }\n }\n </div>\n }\n </div>\n <div class=\"result-item-score\">\n <span class=\"score-badge\">{{ FormatScore(result.Score) }}</span>\n </div>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Footer -->\n <div class=\"search-footer\">\n <span class=\"search-footer-count\">\n {{ TotalCount }} results in {{ FormatElapsedTime(ElapsedMs) }}\n </span>\n <div class=\"search-footer-actions\">\n <button type=\"button\" class=\"see-all-btn\" (click)=\"OnSeeAllClick()\">\n See all results\n <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n @if (ShowAgentCta) {\n <button class=\"agent-cta-btn agent-cta-btn-small\" (click)=\"OnAgentCtaClick()\">\n <i class=\"fa-solid fa-robot\"></i>\n {{ AgentCtaText }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Host-supplied promo strip (e.g. command palette nudge) -->\n @if (ShowPromo && PromoText) {\n <div class=\"search-promo\">\n <i class=\"fa-solid fa-wand-magic-sparkles search-promo-icon\"></i>\n <span class=\"search-promo-text\">{{ PromoText }}</span>\n <button type=\"button\" class=\"search-promo-action\" (click)=\"OnPromoAccept()\">{{ PromoActionLabel }}</button>\n <button type=\"button\" class=\"search-promo-dismiss\" aria-label=\"Dismiss\" title=\"Dismiss\" (click)=\"OnPromoDismiss()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n }\n </div>\n}\n"]}
1
+ {"version":3,"file":"search-overlay.component.js","sourceRoot":"","sources":["../../src/lib/search-overlay.component.ts","../../src/lib/search-overlay.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Search Overlay Component\n *\n * A floating search overlay inspired by command palette / Spotlight style.\n * Triggered by Cmd+K (Mac) or Ctrl+K (Windows), appears as a centered\n * floating panel with backdrop blur, search input, and grouped results.\n *\n * Supports keyboard navigation (up/down/enter/escape), filter facets,\n * and responsive mobile layout.\n */\n\nimport {\n Component,\n EventEmitter,\n HostListener,\n Input,\n OnDestroy,\n OnInit,\n Output,\n ChangeDetectorRef,\n ElementRef,\n ViewChild,\n inject\n} from '@angular/core';\nimport { Subject, Subscription } from 'rxjs';\nimport { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';\nimport { SearchService } from './search.service';\nimport {\n SearchResultItem,\n SearchResultGroup,\n SearchFilter,\n SearchRequest,\n SearchResultSelectedEvent,\n SearchFilterChangeEvent,\n SearchExecutedEvent,\n} from './search-types';\n\n/**\n * Per-provider streaming status displayed above the results list while a streaming\n * search is in flight. One entry per provider that has reported back. Populated\n * progressively as `streamScopedSearch` emits 'provider' events.\n */\nexport interface StreamingProviderStatus {\n /** Provider name from the SearchEngine (e.g. 'Vector', 'FullText') */\n Name: string;\n /** Result count contributed by this provider */\n Count: number;\n /** Wall-clock latency for this provider's leg, in milliseconds */\n ElapsedMs: number;\n /** Reported state for this provider */\n State: 'Completed' | 'Error';\n /** Last error message if State is 'Error' */\n ErrorMessage?: string;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-search-overlay',\n templateUrl: './search-overlay.component.html',\n styleUrls: ['./search-overlay.component.css']\n})\nexport class SearchOverlayComponent implements OnInit, OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n protected searchService = inject(SearchService);\n private destroy$ = new Subject<void>();\n private searchInput$ = new Subject<string>();\n\n @ViewChild('searchInput') SearchInputRef!: ElementRef<HTMLInputElement>;\n\n /** @deprecated Use {@link SearchInputRef}. */\n get searchInputRef(): ElementRef<HTMLInputElement> {\n return this.SearchInputRef;\n }\n /** @deprecated Use {@link SearchInputRef}. */\n set searchInputRef(value: ElementRef<HTMLInputElement>) {\n this.SearchInputRef = value;\n }\n\n // --- Configuration Inputs ---\n\n /** Placeholder text for the search input */\n @Input() Placeholder = 'Search across all your knowledge...';\n\n /**\n * Maximum number of results to fetch and display. Deliberately small — the\n * overlay is a quick-jump surface; \"See all results\" hands off to the full\n * Search Results workspace for anything deeper. 8 matches the omnibar\n * palette's RESULT count (it fetches 9 rows = 8 results + its see-all row;\n * this overlay's see-all is a footer button, not a row).\n */\n @Input() MaxResults = 8;\n\n /** Whether the overlay is currently visible */\n private _isOpen = false;\n\n @Input()\n set IsOpen(value: boolean) {\n const prev = this._isOpen;\n this._isOpen = value;\n if (value && !prev) {\n this.onOverlayOpened();\n }\n if (!value && prev) {\n this.onOverlayClosed();\n }\n }\n get IsOpen(): boolean {\n return this._isOpen;\n }\n\n /** Debounce time in ms before search fires */\n @Input() DebounceMs = 400;\n\n /** Which search sources to include */\n @Input() IncludeSources: ('vector' | 'fulltext' | 'entity')[] = ['vector', 'fulltext', 'entity'];\n\n /** Whether to show filter facets */\n @Input() ShowFilters = true;\n\n /** Text for the agent CTA button */\n @Input() AgentCtaText = 'Ask Knowledge Agent';\n\n /** Whether to show the agent CTA */\n @Input() ShowAgentCta = true;\n\n /**\n * When true, the overlay subscribes to `SearchService.StreamSearch` instead of awaiting\n * `ExecuteSearch`. Results render progressively as each provider reports back. The\n * per-provider status chip strip becomes visible while the stream is in flight.\n * Defaults to false to preserve the request-response UX that shipped in Phase 1.\n */\n @Input() EnableStreaming = false;\n\n /**\n * When false, the overlay does NOT claim the global Ctrl/Cmd+K chord. For hosts\n * (e.g. the Explorer shell) that own that shortcut themselves and open the\n * overlay programmatically — two listeners on the same chord would double-toggle.\n * Escape/arrow handling while open is unaffected.\n */\n @Input() EnableGlobalShortcut = true;\n\n /**\n * Optional promo strip pinned to the overlay's bottom edge — a host-supplied\n * nudge (e.g. Explorer advertising its command palette). The component is\n * deliberately ignorant of WHAT is being promoted; the host provides the\n * copy and handles both outcomes.\n */\n @Input() ShowPromo = false;\n\n /** Promo copy (one sentence). Required when ShowPromo is true. */\n @Input() PromoText = '';\n\n /** Label for the promo's accept action. */\n @Input() PromoActionLabel = 'Turn on';\n\n // --- Outputs ---\n\n @Output() IsOpenChange = new EventEmitter<boolean>();\n @Output() ResultSelected = new EventEmitter<SearchResultSelectedEvent>();\n @Output() FilterChanged = new EventEmitter<SearchFilterChangeEvent>();\n @Output() SearchExecuted = new EventEmitter<SearchExecutedEvent>();\n @Output() AgentCtaClicked = new EventEmitter<string>();\n /**\n * Emitted when the user clicks \"See all results\" — carries the current query.\n * Hosts (e.g. the Explorer shell) open the full Search Results workspace,\n * which has scopes, relevance controls, and richer result actions than this\n * capped quick-jump overlay. The overlay closes itself after emitting.\n */\n @Output() SeeAllRequested = new EventEmitter<string>();\n /** Promo accept — carries the current query so the host can hand it off. */\n @Output() PromoAccepted = new EventEmitter<string>();\n /** Promo dismissed — the host should persist this and stop showing it. */\n @Output() PromoDismissed = new EventEmitter<void>();\n\n // --- Component State ---\n\n public Query = '';\n public IsSearching = false;\n public ResultGroups: SearchResultGroup[] = [];\n public AllResults: SearchResultItem[] = [];\n public Filters: SearchFilter[] = [];\n public ActiveFilters: Record<string, string[]> = {};\n public TotalCount = 0;\n public ElapsedMs = 0;\n public HighlightedIndex = -1;\n public HasSearched = false;\n private searchVersion = 0;\n\n /**\n * Per-provider status entries shown above the results list while a streaming search\n * is in flight. One entry per provider that has reported back. Empty when the user\n * is not running a streaming search (or when `EnableStreaming` is false).\n */\n public StreamingProviders: StreamingProviderStatus[] = [];\n\n /** Active stream subscription so we can cancel on a new search or destroy. */\n private currentStream: Subscription | null = null;\n\n /** Element focused before the overlay opened — restored on close (a11y). */\n private previousFocus: HTMLElement | null = null;\n\n /** All results flattened for keyboard navigation */\n public get FlatResults(): SearchResultItem[] {\n return this.AllResults;\n }\n\n /** id of the highlighted option, announced via aria-activedescendant. */\n public get ActiveDescendantId(): string | null {\n return this.HighlightedIndex >= 0 && this.HighlightedIndex < this.FlatResults.length\n ? `so-opt-${this.HighlightedIndex}`\n : null;\n }\n\n ngOnInit(): void {\n this.setupSearchDebounce();\n this.subscribeToSearchState();\n }\n\n ngOnDestroy(): void {\n this.currentStream?.unsubscribe();\n this.currentStream = null;\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // --- Keyboard shortcuts ---\n\n @HostListener('document:keydown', ['$event'])\n HandleGlobalKeydown(event: KeyboardEvent): void {\n if (this.EnableGlobalShortcut && this.isToggleShortcut(event)) {\n event.preventDefault();\n this.ToggleOverlay();\n return;\n }\n if (this._isOpen) {\n this.handleOverlayKeydown(event);\n }\n }\n\n /** Toggle the overlay open/closed */\n public ToggleOverlay(): void {\n this.IsOpen = !this._isOpen;\n this.IsOpenChange.emit(this._isOpen);\n }\n\n /** Open the overlay */\n public Open(): void {\n if (!this._isOpen) {\n this.IsOpen = true;\n this.IsOpenChange.emit(true);\n }\n }\n\n /** Close the overlay */\n public Close(): void {\n if (this._isOpen) {\n this.IsOpen = false;\n this.IsOpenChange.emit(false);\n }\n }\n\n /** Handle query input changes */\n public OnQueryInput(value: string): void {\n this.Query = value;\n this.searchInput$.next(value);\n }\n\n /** Handle clicking a result */\n public OnResultClick(result: SearchResultItem, event: MouseEvent): void {\n this.ResultSelected.emit({\n Result: result,\n OpenInNewTab: event.metaKey || event.ctrlKey\n });\n this.Close();\n }\n\n /** Handle selecting the highlighted result */\n public SelectHighlighted(): void {\n if (this.HighlightedIndex >= 0 && this.HighlightedIndex < this.FlatResults.length) {\n this.ResultSelected.emit({\n Result: this.FlatResults[this.HighlightedIndex],\n OpenInNewTab: false\n });\n this.Close();\n }\n }\n\n /** Handle filter option toggle */\n public OnFilterToggle(category: string, value: string): void {\n const current = this.ActiveFilters[category] ?? [];\n const index = current.indexOf(value);\n if (index >= 0) {\n current.splice(index, 1);\n } else {\n current.push(value);\n }\n this.ActiveFilters[category] = current;\n this.FilterChanged.emit({ Category: category, SelectedValues: current });\n this.executeSearch();\n }\n\n /** Clear all active filters */\n public ClearAllFilters(): void {\n this.ActiveFilters = {};\n this.executeSearch();\n }\n\n /** Handle clicking the agent CTA */\n public OnAgentCtaClick(): void {\n this.AgentCtaClicked.emit(this.Query);\n this.Close();\n }\n\n /** Promo accept: emit the current query and close — the host takes over. */\n public OnPromoAccept(): void {\n this.PromoAccepted.emit(this.Query.trim());\n this.Close();\n }\n\n /** Promo dismiss: the host persists the dismissal; hide it immediately. */\n public OnPromoDismiss(): void {\n this.ShowPromo = false;\n this.PromoDismissed.emit();\n }\n\n /** Handle clicking \"See all results\" — hand off to the full Search workspace */\n public OnSeeAllClick(): void {\n const query = this.Query.trim();\n if (query.length > 0) {\n this.SeeAllRequested.emit(query);\n }\n this.Close();\n }\n\n /** Handle clicking the backdrop to close */\n public OnBackdropClick(): void {\n this.Close();\n }\n\n /** Check if a filter option is active */\n public IsFilterActive(category: string, value: string): boolean {\n return (this.ActiveFilters[category] ?? []).includes(value);\n }\n\n /** Get a score display value (percentage) */\n public FormatScore(score: number): string {\n return `${Math.round(score * 100)}%`;\n }\n\n /** Format elapsed time display */\n public FormatElapsedTime(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n }\n return `${(ms / 1000).toFixed(1)}s`;\n }\n\n // --- Private Methods ---\n\n private isToggleShortcut(event: KeyboardEvent): boolean {\n return (event.metaKey || event.ctrlKey) && event.key === 'k';\n }\n\n private handleOverlayKeydown(event: KeyboardEvent): void {\n switch (event.key) {\n case 'Escape':\n event.preventDefault();\n this.Close();\n break;\n case 'ArrowDown':\n event.preventDefault();\n this.moveHighlight(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n this.moveHighlight(-1);\n break;\n case 'Enter': {\n // Only claim Enter when it belongs to the combobox model (typing in\n // the input / a focused result row). A focused BUTTON (close,\n // see-all, filter chip, promo) must keep its native Enter\n // activation — preventDefault here at document level would\n // silently swallow it, or worse, open the highlighted result.\n const active = document.activeElement as HTMLElement | null;\n const inCombobox = active === this.SearchInputRef?.nativeElement\n || (active?.classList.contains('result-item') ?? false);\n if (!inCombobox) {\n return;\n }\n event.preventDefault();\n this.SelectHighlighted();\n break;\n }\n }\n }\n\n private moveHighlight(direction: number): void {\n const maxIndex = this.FlatResults.length - 1;\n if (maxIndex < 0) return;\n\n // If a result row currently holds DOM focus (roving tabindex), keep focus\n // travelling with the highlight; from the input, only the highlight moves.\n const rowHadFocus = document.activeElement instanceof HTMLElement\n && document.activeElement.classList.contains('result-item');\n\n this.HighlightedIndex += direction;\n if (this.HighlightedIndex < 0) {\n this.HighlightedIndex = maxIndex;\n } else if (this.HighlightedIndex > maxIndex) {\n this.HighlightedIndex = 0;\n }\n this.cdr.detectChanges();\n\n // Keyboard-driven moves keep the highlighted row visible. Mouse hover sets\n // HighlightedIndex directly in the template and deliberately does NOT\n // scroll — auto-scrolling under the pointer fights the user's hand.\n const row = document.getElementById(`so-opt-${this.HighlightedIndex}`);\n row?.scrollIntoView({ block: 'nearest' });\n if (rowHadFocus) {\n row?.focus();\n }\n }\n\n /**\n * Tab behavior inside the dialog:\n * - On a result row, Tab / Shift+Tab step through the RESULTS themselves\n * (mirrors ArrowDown/Up) until walking off either end of the list — then\n * focus continues to the footer actions / back to the earlier controls.\n * - Everywhere else, Tab wraps within the dialog (focus trap): input → close\n * → filter chips → results → footer actions → back to the input.\n * Escape is handled by the document-level keydown.\n */\n public OnSpotlightKeydown(event: KeyboardEvent): void {\n if (event.key !== 'Tab') {\n return;\n }\n const activeEl = document.activeElement as HTMLElement | null;\n if (activeEl?.classList.contains('result-item')) {\n const last = this.FlatResults.length - 1;\n if (!event.shiftKey && this.HighlightedIndex < last) {\n event.preventDefault();\n this.moveHighlight(1); // row has focus, so focus travels with it\n return;\n }\n if (event.shiftKey && this.HighlightedIndex > 0) {\n event.preventDefault();\n this.moveHighlight(-1);\n return;\n }\n // At either end: fall through so Tab leaves the list naturally.\n }\n const root = (event.currentTarget as HTMLElement) ?? null;\n if (!root) {\n return;\n }\n const focusables = Array.from(\n root.querySelectorAll<HTMLElement>('input, button, .result-item[tabindex=\"0\"], .search-recent-item[tabindex=\"0\"]')\n ).filter((el) => el.offsetParent !== null);\n if (focusables.length === 0) {\n return;\n }\n const active = document.activeElement as HTMLElement | null;\n if (!event.shiftKey && active === focusables[focusables.length - 1]) {\n event.preventDefault();\n focusables[0].focus();\n } else if (event.shiftKey && active === focusables[0]) {\n event.preventDefault();\n focusables[focusables.length - 1].focus();\n }\n }\n\n /**\n * Recent-search row activated (click or Enter/Space). Re-runs the search AND\n * refocuses the input — the activated row leaves the DOM when recents are\n * replaced by results, which would otherwise drop focus to <body>.\n */\n public OnRecentSelect(query: string): void {\n this.OnQueryInput(query);\n this.SearchInputRef?.nativeElement?.focus();\n }\n\n /** Recent-search rows are keyboard-activatable (Enter/Space = click). */\n public OnRecentKeydown(event: KeyboardEvent, query: string): void {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this.OnRecentSelect(query);\n }\n }\n\n private setupSearchDebounce(): void {\n this.searchInput$\n .pipe(\n debounceTime(this.DebounceMs),\n distinctUntilChanged(),\n takeUntil(this.destroy$)\n )\n .subscribe(() => this.executeSearch());\n }\n\n private subscribeToSearchState(): void {\n this.searchService.IsSearching$\n .pipe(takeUntil(this.destroy$))\n .subscribe(val => {\n this.IsSearching = val;\n this.cdr.detectChanges();\n });\n }\n\n private async executeSearch(): Promise<void> {\n const query = this.Query.trim();\n if (!query) {\n this.clearResults();\n return;\n }\n\n const version = ++this.searchVersion;\n\n const request: SearchRequest = {\n Query: query,\n MaxResults: this.MaxResults,\n ActiveFilters: this.ActiveFilters,\n IncludeSources: this.IncludeSources,\n };\n\n if (this.EnableStreaming) {\n this.executeStreamingSearch(query, request, version);\n return;\n }\n\n const response = await this.searchService.ExecuteSearch(request);\n\n // Discard results if a newer search was triggered while this one was in-flight\n if (version !== this.searchVersion) {\n return;\n }\n\n this.AllResults = response.Results;\n this.ResultGroups = response.Groups;\n this.Filters = response.Filters;\n this.TotalCount = response.TotalCount;\n this.ElapsedMs = response.ElapsedMs;\n this.HasSearched = true;\n this.HighlightedIndex = response.Results.length > 0 ? 0 : -1;\n\n this.SearchExecuted.emit({\n Query: query,\n Filters: this.ActiveFilters,\n ResultCount: response.TotalCount,\n ElapsedMs: response.ElapsedMs,\n });\n\n this.cdr.detectChanges();\n }\n\n /**\n * Streaming variant of executeSearch — subscribes to `SearchService.StreamSearch`, shows each\n * provider's count in the chip strip as it reports back, and renders the result list from the\n * 'final' event. A 'provider' event carries no rows: they arrive before the server's permission pass.\n *\n * Cancellation: a new search invocation tears down the in-flight stream via\n * `searchVersion` and `currentStream.unsubscribe()`.\n */\n private executeStreamingSearch(query: string, request: SearchRequest, version: number): void {\n // Tear down any prior stream so we don't get cross-talk between consecutive queries.\n this.currentStream?.unsubscribe();\n this.currentStream = null;\n\n // Reset visible state for a fresh stream.\n this.StreamingProviders = [];\n this.AllResults = [];\n this.ResultGroups = [];\n this.TotalCount = 0;\n this.ElapsedMs = 0;\n this.HasSearched = true;\n this.HighlightedIndex = -1;\n this.cdr.detectChanges();\n\n this.currentStream = this.searchService.StreamSearch(request).subscribe({\n next: (event) => {\n if (version !== this.searchVersion) return;\n\n if (event.Phase === 'provider' && event.ProviderName) {\n // Progress only: the count, never the rows (they precede the permission pass).\n this.StreamingProviders = [\n ...this.StreamingProviders,\n {\n Name: event.ProviderName,\n Count: event.ResultCount ?? 0,\n ElapsedMs: event.ElapsedMs ?? 0,\n State: 'Completed',\n },\n ];\n } else if (event.Phase === 'final' && event.Results) {\n // The permission-filtered fused/reranked list.\n this.AllResults = event.Results;\n this.ResultGroups = this.searchService.GroupResults(this.AllResults);\n this.Filters = this.searchService.BuildFilters(this.AllResults);\n this.TotalCount = event.Results.length;\n this.ElapsedMs = event.ElapsedMs ?? this.ElapsedMs;\n this.HighlightedIndex = event.Results.length > 0 ? 0 : -1;\n }\n\n this.cdr.detectChanges();\n },\n error: (err: Error) => {\n if (version !== this.searchVersion) return;\n this.StreamingProviders = [\n ...this.StreamingProviders,\n { Name: 'stream', Count: 0, ElapsedMs: 0, State: 'Error', ErrorMessage: err.message },\n ];\n this.cdr.detectChanges();\n },\n complete: () => {\n if (version !== this.searchVersion) return;\n this.SearchExecuted.emit({\n Query: query,\n Filters: this.ActiveFilters,\n ResultCount: this.TotalCount,\n ElapsedMs: this.ElapsedMs,\n });\n this.cdr.detectChanges();\n },\n });\n }\n\n private clearResults(): void {\n this.AllResults = [];\n this.ResultGroups = [];\n this.Filters = [];\n this.TotalCount = 0;\n this.ElapsedMs = 0;\n this.HasSearched = false;\n this.HighlightedIndex = -1;\n this.cdr.detectChanges();\n }\n\n private onOverlayOpened(): void {\n // Remember what had focus so Close() can hand it back (a11y: the overlay\n // is a modal dialog — focus must return to the summoning control).\n this.previousFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null;\n // Focus input after view updates\n Promise.resolve().then(() => {\n this.SearchInputRef?.nativeElement?.focus();\n this.cdr.detectChanges();\n });\n }\n\n private onOverlayClosed(): void {\n this.HighlightedIndex = -1;\n if (this.previousFocus?.isConnected) {\n this.previousFocus.focus();\n }\n this.previousFocus = null;\n }\n\n /** Check if any filters are active (used by template) */\n public HasActiveFilters(): boolean {\n return Object.values(this.ActiveFilters).some(v => v.length > 0);\n }\n\n /** @deprecated Use {@link HasActiveFilters}. */\n public hasActiveFilters(): boolean {\n return this.HasActiveFilters();\n }\n\n /** Check if a result is currently keyboard-highlighted */\n public IsResultHighlighted(result: SearchResultItem): boolean {\n const flatIndex = this.GetFlatIndex(result);\n return flatIndex === this.HighlightedIndex;\n }\n\n /** @deprecated Use {@link IsResultHighlighted}. */\n public isResultHighlighted(result: SearchResultItem): boolean {\n return this.IsResultHighlighted(result);\n }\n\n /** Get the flat index of a result for keyboard navigation */\n public GetFlatIndex(result: SearchResultItem): number {\n return this.FlatResults.indexOf(result);\n }\n\n /** @deprecated Use {@link GetFlatIndex}. */\n public getFlatIndex(result: SearchResultItem): number {\n return this.GetFlatIndex(result);\n }\n}\n","@if (IsOpen) {\n <!-- Backdrop -->\n <div class=\"search-backdrop\" (click)=\"OnBackdropClick()\"></div>\n\n <!-- Spotlight container -->\n <div class=\"search-spotlight\" role=\"dialog\" aria-modal=\"true\" aria-label=\"Search\"\n (click)=\"$event.stopPropagation()\" (keydown)=\"OnSpotlightKeydown($event)\">\n <!-- Search input area -->\n <div class=\"search-input-wrap\">\n <i class=\"fa-solid fa-magnifying-glass search-icon\"></i>\n <input\n #searchInput\n type=\"text\"\n class=\"search-input\"\n role=\"combobox\"\n aria-controls=\"search-overlay-listbox\"\n aria-autocomplete=\"list\"\n [attr.aria-expanded]=\"AllResults.length > 0\"\n [attr.aria-activedescendant]=\"ActiveDescendantId\"\n [placeholder]=\"Placeholder\"\n [value]=\"Query\"\n (input)=\"OnQueryInput($any($event.target).value)\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n @if (IsSearching) {\n <div class=\"search-spinner\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n </div>\n }\n <div class=\"search-shortcut-hint\">\n <kbd>ESC</kbd>\n </div>\n <button type=\"button\" class=\"search-close-btn\" aria-label=\"Close\" title=\"Close\" (click)=\"Close()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n <!-- Results area -->\n <div class=\"search-results-area\">\n @if (EnableStreaming && (IsSearching || StreamingProviders.length > 0)) {\n <!-- Streaming status strip — one chip per provider that has reported -->\n <div class=\"streaming-status-strip\" aria-live=\"polite\">\n @if (StreamingProviders.length === 0 && IsSearching) {\n <span class=\"streaming-chip streaming-chip-pending\">\n <i class=\"fa-solid fa-circle-notch fa-spin\"></i>\n <span>Searching…</span>\n </span>\n }\n @for (p of StreamingProviders; track p.Name) {\n <span class=\"streaming-chip\"\n [class.streaming-chip-error]=\"p.State === 'Error'\"\n [class.streaming-chip-completed]=\"p.State === 'Completed'\">\n @if (p.State === 'Completed') {\n <i class=\"fa-solid fa-check\"></i>\n } @else {\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n }\n <span class=\"streaming-chip-name\">{{ p.Name }}</span>\n @if (p.State === 'Completed') {\n <span class=\"streaming-chip-count\">{{ p.Count }}</span>\n <span class=\"streaming-chip-time\">{{ FormatElapsedTime(p.ElapsedMs) }}</span>\n } @else if (p.ErrorMessage) {\n <span class=\"streaming-chip-time\">{{ p.ErrorMessage }}</span>\n }\n </span>\n }\n </div>\n }\n @if (ShowFilters && Filters.length > 0) {\n <!-- Filter chips -->\n <div class=\"search-filter-bar\">\n @for (filter of Filters; track filter.Category) {\n @for (option of filter.Options; track option.Value) {\n <button\n class=\"filter-chip\"\n [class.filter-chip-active]=\"IsFilterActive(filter.Category, option.Value)\"\n (click)=\"OnFilterToggle(filter.Category, option.Value)\"\n >\n @if (option.Icon) {\n <i [class]=\"option.Icon\"></i>\n }\n <span>{{ option.Label }}</span>\n <span class=\"filter-chip-count\">{{ option.Count }}</span>\n </button>\n }\n }\n @if (hasActiveFilters()) {\n <button class=\"filter-clear-btn\" (click)=\"ClearAllFilters()\">\n <i class=\"fa-solid fa-times\"></i> Clear\n </button>\n }\n </div>\n }\n\n @if (HasSearched && AllResults.length === 0 && !IsSearching) {\n <!-- No results -->\n <mj-empty-state\n Variant=\"no-results\"\n Title=\"No results found\"\n Message=\"Try different keywords or remove some filters\">\n @if (ShowAgentCta) {\n <button ngProjectAs=\"[actions]\" class=\"agent-cta-btn\" (click)=\"OnAgentCtaClick()\">\n <i class=\"fa-solid fa-robot\"></i>\n {{ AgentCtaText }}\n </button>\n }\n </mj-empty-state>\n }\n\n @if (!HasSearched && !IsSearching) {\n <!-- Recent searches -->\n <div class=\"search-recent\">\n @if (searchService.RecentSearches$.value.length > 0) {\n <div class=\"search-recent-header\">\n <span class=\"search-recent-title\">Recent Searches</span>\n </div>\n @for (recent of searchService.RecentSearches$.value; track recent.Query; let i = $index) {\n @if (i < 5) {\n <div class=\"search-recent-item\" role=\"button\" tabindex=\"0\"\n (click)=\"OnRecentSelect(recent.Query)\"\n (keydown)=\"OnRecentKeydown($event, recent.Query)\">\n <i class=\"fa-solid fa-clock search-recent-icon\"></i>\n <span>{{ recent.Query }}</span>\n <span class=\"search-recent-count\">{{ recent.ResultCount }} results</span>\n </div>\n }\n }\n } @else {\n <mj-empty-state\n Variant=\"no-results\"\n Title=\"Start typing to search across all your knowledge\"\n Size=\"compact\" />\n }\n </div>\n }\n\n @if (AllResults.length > 0) {\n <!-- Grouped results -->\n <div id=\"search-overlay-listbox\" role=\"listbox\" aria-label=\"Search results\">\n @for (group of ResultGroups; track group.SourceType) {\n <div class=\"result-group\" role=\"presentation\">\n <div class=\"result-group-header\" role=\"presentation\">\n <i [class]=\"group.Icon\"></i>\n <span class=\"result-group-label\">{{ group.Label }}</span>\n <span class=\"result-group-count\">{{ group.TotalCount }}</span>\n </div>\n @for (result of group.Results; track result.ID; let ri = $index) {\n <div\n class=\"result-item\"\n role=\"option\"\n [attr.id]=\"'so-opt-' + getFlatIndex(result)\"\n [attr.tabindex]=\"isResultHighlighted(result) ? 0 : -1\"\n [attr.aria-selected]=\"isResultHighlighted(result)\"\n [class.result-item-highlighted]=\"isResultHighlighted(result)\"\n (click)=\"OnResultClick(result, $event)\"\n (focus)=\"HighlightedIndex = getFlatIndex(result)\"\n (mouseenter)=\"HighlightedIndex = getFlatIndex(result)\"\n >\n <div class=\"result-item-icon\">\n <i [class]=\"result.SourceIcon\"></i>\n </div>\n <div class=\"result-item-content\">\n <div class=\"result-item-title\">{{ result.Title }}</div>\n <div class=\"result-item-snippet\">{{ result.Snippet }}</div>\n @if (result.Tags.length > 0) {\n <div class=\"result-item-tags\">\n @for (tag of result.Tags; track tag; let ti = $index) {\n @if (ti < 3) {\n <span class=\"result-tag\">{{ tag }}</span>\n }\n }\n </div>\n }\n </div>\n <div class=\"result-item-score\">\n <span class=\"score-badge\">{{ FormatScore(result.Score) }}</span>\n </div>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Footer -->\n <div class=\"search-footer\">\n <span class=\"search-footer-count\">\n {{ TotalCount }} results in {{ FormatElapsedTime(ElapsedMs) }}\n </span>\n <div class=\"search-footer-actions\">\n <button type=\"button\" class=\"see-all-btn\" (click)=\"OnSeeAllClick()\">\n See all results\n <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n @if (ShowAgentCta) {\n <button class=\"agent-cta-btn agent-cta-btn-small\" (click)=\"OnAgentCtaClick()\">\n <i class=\"fa-solid fa-robot\"></i>\n {{ AgentCtaText }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Host-supplied promo strip (e.g. command palette nudge) -->\n @if (ShowPromo && PromoText) {\n <div class=\"search-promo\">\n <i class=\"fa-solid fa-wand-magic-sparkles search-promo-icon\"></i>\n <span class=\"search-promo-text\">{{ PromoText }}</span>\n <button type=\"button\" class=\"search-promo-action\" (click)=\"OnPromoAccept()\">{{ PromoActionLabel }}</button>\n <button type=\"button\" class=\"search-promo-dismiss\" aria-label=\"Dismiss\" title=\"Dismiss\" (click)=\"OnPromoDismiss()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n }\n </div>\n}\n"]}
@@ -44,8 +44,9 @@ export declare class SearchService {
44
44
  *
45
45
  * Consumers (typically the search composite component) should:
46
46
  * - render skeleton rows immediately when the Observable is created
47
- * - on each 'provider' event: append the rows for that source
48
- * - on 'final': replace the partials with the canonical fused list
47
+ * - on each 'provider' event: show progress — `ProviderName` and `ResultCount`. A 'provider'
48
+ * event never carries rows: they arrive before the server's permission pass.
49
+ * - on 'final': render the result list
49
50
  * - on error: show the failure message + clear the skeleton
50
51
  *
51
52
  * Returns rxjs Observable rather than awaiting a Promise — callers
@@ -57,6 +58,8 @@ export declare class SearchService {
57
58
  StreamSearch(request: SearchRequest): Observable<{
58
59
  Phase: string;
59
60
  ProviderName?: string;
61
+ /** Set on 'provider' events: how many hits that provider returned, capped at `MaxResults`. */
62
+ ResultCount?: number;
60
63
  Results?: SearchResultItem[];
61
64
  ElapsedMs?: number;
62
65
  ErrorMessage?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"search.service.d.ts","sourceRoot":"","sources":["../../src/lib/search.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search.service.d.ts","sourceRoot":"","sources":["../../src/lib/search.service.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,OAAO,EAAc,MAAM,MAAM,CAAC;AAExE,OAAO,EAAgB,iBAAiB,EAA4B,MAAM,sBAAsB,CAAC;AASjG,OAAO,EACH,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EAGZ,eAAe,EACf,gBAAgB,EACnB,MAAM,gBAAgB,CAAC;;AA8BxB,sCAAsC;AACtC,MAAM,WAAW,YAAY;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,IAAI,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACvB;AASD;;;GAGG;AACH,qBACa,aAAa;IACtB,OAAO,CAAC,SAAS,CAAkC;IACnD,IAAW,QAAQ,IAAI,iBAAiB,CAEvC;IACD,IAAW,QAAQ,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,EAElD;IAED,8BAA8B;IACvB,cAAc,yCAAoD;IAEzE,sCAAsC;IAC/B,YAAY,2BAAuC;IAE1D,2EAA2E;IACpE,eAAe,kCAA2C;IAEjE,mBAAmB;IACZ,OAAO,kBAAyB;IAEvC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAM;IACxC,OAAO,CAAC,oBAAoB,CAAS;IAErC,oFAAoF;IACpF,OAAO,CAAC,qBAAqB,CAAyC;IAEtE,0FAA0F;IACnF,OAAO,qCAA8C;IAC5D,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,kBAAkB,CAA2C;IAErE;;OAEG;IACU,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IAuB3E;;;;;;;;;;;;;;;;;;OAkBG;IACI,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,UAAU,CAAC;QACpD,KAAK,EAAE,MAAM,CAAC;QACd,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,8FAA8F;QAC9F,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAC;QAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IAwBF;;;;OAIG;IACU,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,GAAE,MAAU,GAAG,OAAO,CAAC,cAAc,CAAC;IAoB1F,uCAAuC;IAChC,YAAY,IAAI,IAAI;IAI3B,yDAAyD;IAClD,mBAAmB,IAAI,IAAI;IAKlC;;OAEG;IACI,YAAY,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,iBAAiB,EAAE;IA0BrE;;OAEG;IACI,YAAY,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,YAAY,EAAE;IAShE,2CAA2C;IACpC,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAIhD,OAAO,CAAC,qBAAqB;IAkB7B,OAAO,CAAC,qBAAqB;IAwC7B,OAAO,CAAC,mBAAmB;IAqB3B,OAAO,CAAC,cAAc;IAoBtB;;;OAGG;IACU,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IA6BhD;;;;;;OAMG;IACH;2EACuE;IACvE,OAAO,CAAC,qBAAqB,CAA6B;IAE1D;;;;;;OAMG;IACU,wBAAwB,CAAC,GAAG,SAAI,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IA8CpE,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,SAAI,GAAG,IAAI;IAO/D,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,qBAAqB;IAa7B,iFAAiF;IACjF,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,mBAAmB;IAc3B;;OAEG;YACW,oBAAoB;IAyBlC,wFAAwF;IACxF,OAAO,CAAC,iCAAiC;IAsCzC,gEAAgE;IAChE,OAAO,CAAC,mBAAmB;IAyC3B;;;OAGG;IACU,UAAU,CAAC,KAAK,GAAE,OAAe,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IA4B3E,6DAA6D;IAC7D,OAAO,CAAC,kBAAkB;yCArkBjB,aAAa;6CAAb,aAAa;CA6lBzB"}
@@ -96,8 +96,9 @@ export class SearchService {
96
96
  *
97
97
  * Consumers (typically the search composite component) should:
98
98
  * - render skeleton rows immediately when the Observable is created
99
- * - on each 'provider' event: append the rows for that source
100
- * - on 'final': replace the partials with the canonical fused list
99
+ * - on each 'provider' event: show progress — `ProviderName` and `ResultCount`. A 'provider'
100
+ * event never carries rows: they arrive before the server's permission pass.
101
+ * - on 'final': render the result list
101
102
  * - on error: show the failure message + clear the skeleton
102
103
  *
103
104
  * Returns rxjs Observable rather than awaiting a Promise — callers
@@ -123,6 +124,7 @@ export class SearchService {
123
124
  }).pipe(map((ev) => ({
124
125
  Phase: ev.Phase,
125
126
  ProviderName: ev.ProviderName,
127
+ ResultCount: ev.ResultCount,
126
128
  Results: ev.Results ? ev.Results.map(r => this.mapClientResultItem(r)) : undefined,
127
129
  ElapsedMs: ev.ElapsedMs,
128
130
  ErrorMessage: ev.ErrorMessage,
@@ -1 +1 @@
1
- {"version":3,"file":"search.service.js","sourceRoot":"","sources":["../../src/lib/search.service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Search service that connects to the UnifiedSearchService via GraphQL.\n *\n * Provides a reactive interface for executing searches, managing search history,\n * and transforming raw search responses into display-ready grouped results.\n */\n\nimport { Injectable } from '@angular/core';\nimport { BehaviorSubject, Observable, Subject, throwError } from 'rxjs';\nimport { map } from 'rxjs/operators';\nimport { CompositeKey, IMetadataProvider, Metadata, StartupManager } from '@memberjunction/core';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\nimport { MJEventType, MJGlobal } from '@memberjunction/global';\nimport {\n GraphQLSearchClient,\n GraphQLDataProvider,\n SearchClientResponse,\n SearchClientResultItem\n} from '@memberjunction/graphql-dataprovider';\nimport {\n SearchRequest,\n SearchResponse,\n SearchResultItem,\n SearchResultGroup,\n SearchFilter,\n SearchFilterOption,\n SearchProviderInfo,\n SearchScopeInfo,\n RecentRecordItem\n} from './search-types';\n\n/** Default minimum relevance score threshold (0-1). Results below this are filtered out. */\nconst DEFAULT_MIN_SCORE = 0.35;\n\n/** Fallback icon mapping for source types (used when provider metadata is not available) */\nconst FALLBACK_SOURCE_ICONS: Record<string, string> = {\n 'entity': 'fa-solid fa-database',\n 'vector': 'fa-solid fa-brain',\n 'fulltext': 'fa-solid fa-magnifying-glass',\n 'content-item': 'fa-solid fa-file-lines',\n 'file': 'fa-solid fa-file',\n 'web-page': 'fa-solid fa-globe',\n 'storage': 'fa-solid fa-folder-open',\n};\n\n/** Fallback labels for source types (used when provider metadata is not available) */\nconst FALLBACK_SOURCE_LABELS: Record<string, string> = {\n 'entity': 'Database',\n 'vector': 'Semantic Search',\n 'fulltext': 'Full-Text Search',\n 'content-item': 'Content Items',\n 'file': 'Documents',\n 'web-page': 'Web Pages',\n 'storage': 'File Storage',\n};\n\n/** User setting key for persisting recent searches */\nconst RECENT_SEARCHES_KEY = 'search.recentSearches';\n\n/** Recent search entry for history */\nexport interface RecentSearch {\n Query: string;\n Timestamp: Date;\n ResultCount: number;\n}\n\n/** JSON-safe shape for persistence (Date → ISO string) */\ninterface RecentSearchJson {\n Query: string;\n Timestamp: string;\n ResultCount: number;\n}\n\n/**\n * Multi-provider note: callers under a non-default provider should set\n * `service.Provider = component.ProviderToUse` before invoking any methods.\n */\n@Injectable({ providedIn: 'root' })\nexport class SearchService {\n private _provider: IMetadataProvider | null = null;\n public get Provider(): IMetadataProvider {\n return this._provider ?? Metadata.Provider;\n }\n public set Provider(value: IMetadataProvider | null) {\n this._provider = value;\n }\n\n /** Current search response */\n public SearchResults$ = new BehaviorSubject<SearchResponse | null>(null);\n\n /** Whether a search is in progress */\n public IsSearching$ = new BehaviorSubject<boolean>(false);\n\n /** Recent search history (persisted via UserInfoEngine, max 20 entries) */\n public RecentSearches$ = new BehaviorSubject<RecentSearch[]>([]);\n\n /** Error stream */\n public Errors$ = new Subject<string>();\n\n private readonly maxRecentSearches = 20;\n private recentSearchesLoaded = false;\n\n /** Cached provider metadata keyed by SourceType, populated from search responses */\n private providersBySourceType = new Map<string, SearchProviderInfo>();\n\n /** Cached list of scopes the current user can see. Populated lazily by `LoadScopes()`. */\n public Scopes$ = new BehaviorSubject<SearchScopeInfo[]>([]);\n private scopesLoaded = false;\n private scopesLoadInFlight: Promise<SearchScopeInfo[]> | null = null;\n\n /**\n * Execute a search request via the SearchKnowledge GraphQL mutation.\n */\n public async ExecuteSearch(request: SearchRequest): Promise<SearchResponse> {\n this.IsSearching$.next(true);\n const startTime = Date.now();\n\n try {\n const response = await this.executeGraphQLSearch(request);\n response.ElapsedMs = Date.now() - startTime;\n\n this.SearchResults$.next(response);\n this.addToRecentSearches(request.Query, response.TotalCount);\n\n return response;\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Search failed';\n this.Errors$.next(errorMessage);\n const errorResponse = this.createEmptyResponse(errorMessage);\n this.SearchResults$.next(errorResponse);\n return errorResponse;\n } finally {\n this.IsSearching$.next(false);\n }\n }\n\n /**\n * Phase 2C streaming search. Returns an Observable that emits one\n * notification per provider as it returns, plus a 'fused' / 'reranked'\n * / 'final' terminal event. Same auth + permission behavior as\n * ExecuteSearch — denials surface as an error on the Observable.\n *\n * Consumers (typically the search composite component) should:\n * - render skeleton rows immediately when the Observable is created\n * - on each 'provider' event: append the rows for that source\n * - on 'final': replace the partials with the canonical fused list\n * - on error: show the failure message + clear the skeleton\n *\n * Returns rxjs Observable rather than awaiting a Promise — callers\n * decide whether to subscribe + populate state, or unsubscribe on\n * navigation. The service does NOT update its own SearchResults$\n * subject for streaming calls; the caller owns the partial-render\n * state model.\n */\n public StreamSearch(request: SearchRequest): Observable<{\n Phase: string;\n ProviderName?: string;\n Results?: SearchResultItem[];\n ElapsedMs?: number;\n ErrorMessage?: string;\n }> {\n const provider = Metadata.Provider; // global-provider-ok: streaming search service consumes the GraphQL channel of the global default provider\n if (!(provider instanceof GraphQLDataProvider)) {\n return throwError(() => new Error('GraphQL provider not available'));\n }\n const client = new GraphQLSearchClient(provider);\n const filters = this.buildClientFilters(request);\n const minScore = request.MinScore ?? DEFAULT_MIN_SCORE;\n return client.StreamSearch({\n Query: request.Query,\n MaxResults: request.MaxResults || 20,\n MinScore: minScore > 0 ? minScore : undefined,\n Filters: filters,\n ScopeIDs: request.ScopeIDs && request.ScopeIDs.length > 0 ? request.ScopeIDs : undefined,\n }).pipe(map((ev) => ({\n Phase: ev.Phase,\n ProviderName: ev.ProviderName,\n Results: ev.Results ? ev.Results.map(r => this.mapClientResultItem(r)) : undefined,\n ElapsedMs: ev.ElapsedMs,\n ErrorMessage: ev.ErrorMessage,\n })));\n }\n\n /**\n * Lightweight preview search for autocomplete/typeahead.\n * Does NOT update SearchResults$ or IsSearching$ observables,\n * and does NOT add to recent search history.\n */\n public async PreviewSearch(query: string, maxResults: number = 8): Promise<SearchResponse> {\n try {\n if (!query.trim()) {\n return this.createEmptyResponse();\n }\n\n const provider = this.Provider;\n if (!(provider instanceof GraphQLDataProvider)) {\n return this.createEmptyResponse('GraphQL provider not available');\n }\n\n const client = new GraphQLSearchClient(provider);\n const clientResponse = await client.PreviewSearch(query, maxResults);\n return this.mapClientResponseToSearchResponse(clientResponse);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Preview search failed';\n return this.createEmptyResponse(errorMessage);\n }\n }\n\n /** Clear the current search results */\n public ClearResults(): void {\n this.SearchResults$.next(null);\n }\n\n /** Clear recent search history (memory and persisted) */\n public ClearRecentSearches(): void {\n this.RecentSearches$.next([]);\n this.persistRecentSearches([]);\n }\n\n /**\n * Group flat results by source type for display.\n */\n public GroupResults(results: SearchResultItem[]): SearchResultGroup[] {\n const groupMap = new Map<string, SearchResultItem[]>();\n\n for (const result of results) {\n const key = result.SourceType;\n const existing = groupMap.get(key);\n if (existing) {\n existing.push(result);\n } else {\n groupMap.set(key, [result]);\n }\n }\n\n return Array.from(groupMap.entries()).map(([sourceType, items]) => {\n // Priority: cached provider metadata > per-result metadata > fallback maps\n const cached = this.providersBySourceType.get(sourceType);\n return {\n Label: cached?.DisplayName ?? items[0]?.ProviderLabel ?? FALLBACK_SOURCE_LABELS[sourceType] ?? sourceType,\n Icon: cached?.Icon ?? items[0]?.ProviderIcon ?? FALLBACK_SOURCE_ICONS[sourceType] ?? 'fa-solid fa-circle',\n SourceType: sourceType,\n Results: items,\n TotalCount: items.length\n };\n });\n }\n\n /**\n * Build filter facets from a set of results.\n */\n public BuildFilters(results: SearchResultItem[]): SearchFilter[] {\n return [\n this.buildSourceTypeFilter(results),\n this.buildEntityNameFilter(results),\n this.buildFileTypeFilter(results),\n this.buildTagFilter(results)\n ].filter(f => f.Options.length > 0); // Hide categories with no options\n }\n\n /** Get the icon for a given source type */\n public GetSourceIcon(sourceType: string): string {\n return this.providersBySourceType.get(sourceType)?.Icon ?? FALLBACK_SOURCE_ICONS[sourceType] ?? 'fa-solid fa-circle';\n }\n\n private buildSourceTypeFilter(results: SearchResultItem[]): SearchFilter {\n const counts = new Map<string, number>();\n for (const r of results) {\n counts.set(r.SourceType, (counts.get(r.SourceType) ?? 0) + 1);\n }\n const options: SearchFilterOption[] = Array.from(counts.entries()).map(([type, count]) => {\n const cached = this.providersBySourceType.get(type);\n return {\n Label: cached?.DisplayName ?? FALLBACK_SOURCE_LABELS[type] ?? type,\n Value: type,\n Count: count,\n IsSelected: false,\n Icon: cached?.Icon ?? FALLBACK_SOURCE_ICONS[type]\n };\n });\n return { Category: 'Source', Options: options, MultiSelect: true };\n }\n\n private buildEntityNameFilter(results: SearchResultItem[]): SearchFilter {\n const counts = new Map<string, { count: number; displayName: string; icon?: string }>();\n let fileCount = 0;\n for (const r of results) {\n if (r.ResultType === 'storage-file') {\n fileCount++;\n } else {\n const existing = counts.get(r.EntityName);\n const displayName = r.EntityDisplayName || r.EntityName;\n if (existing) {\n existing.count++;\n } else {\n counts.set(r.EntityName, { count: 1, displayName, icon: r.EntityIcon });\n }\n }\n }\n const options: SearchFilterOption[] = Array.from(counts.entries())\n .sort((a, b) => b[1].count - a[1].count)\n .map(([name, data]) => ({\n Label: data.displayName,\n Value: name,\n Count: data.count,\n IsSelected: false,\n Icon: data.icon ?? 'fa-solid fa-table'\n }));\n\n // Add a single \"Files\" entry for all storage file results\n if (fileCount > 0) {\n options.push({\n Label: 'Files',\n Value: '__storage-files__',\n Count: fileCount,\n IsSelected: false,\n Icon: 'fa-solid fa-file'\n });\n }\n\n return { Category: 'Entity', Options: options, MultiSelect: true };\n }\n\n private buildFileTypeFilter(results: SearchResultItem[]): SearchFilter {\n const counts = new Map<string, number>();\n for (const r of results) {\n if (r.ResultType !== 'storage-file') continue;\n const ext = r.Title?.split('.').pop()?.toUpperCase();\n if (ext && ext.length <= 6) {\n counts.set(ext, (counts.get(ext) ?? 0) + 1);\n }\n }\n const options: SearchFilterOption[] = Array.from(counts.entries())\n .sort((a, b) => b[1] - a[1])\n .map(([ext, count]) => ({\n Label: ext,\n Value: ext,\n Count: count,\n IsSelected: false,\n Icon: 'fa-solid fa-file'\n }));\n return { Category: 'File Type', Options: options, MultiSelect: true };\n }\n\n private buildTagFilter(results: SearchResultItem[]): SearchFilter {\n const counts = new Map<string, number>();\n for (const r of results) {\n for (const tag of r.Tags) {\n counts.set(tag, (counts.get(tag) ?? 0) + 1);\n }\n }\n const options: SearchFilterOption[] = Array.from(counts.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, 15)\n .map(([tag, count]) => ({\n Label: tag,\n Value: tag,\n Count: count,\n IsSelected: false,\n Icon: 'fa-solid fa-tag'\n }));\n return { Category: 'Tags', Options: options, MultiSelect: true };\n }\n\n /**\n * Load persisted recent searches from UserInfoEngine.\n * Safe to call multiple times — only loads once.\n */\n public async LoadRecentSearches(): Promise<void> {\n if (this.recentSearchesLoaded) return;\n\n try {\n MJGlobal.Instance.GetEventListener(true).subscribe(async (event) => {\n if (event.event === MJEventType.LoggedIn) {\n await StartupManager.Instance.Startup();\n\n const engine = UserInfoEngine.Instance;\n\n const json = engine.GetSetting(RECENT_SEARCHES_KEY);\n\n if (json) {\n const parsed = JSON.parse(json) as RecentSearchJson[];\n const searches: RecentSearch[] = parsed.map(s => ({\n Query: s.Query,\n Timestamp: new Date(s.Timestamp),\n ResultCount: s.ResultCount\n }));\n this.RecentSearches$.next(searches);\n }\n }\n });\n } catch (err) {\n console.error('[SearchService] LoadRecentSearches error:', err);\n }\n this.recentSearchesLoaded = true;\n }\n\n /**\n * Record a query into recent searches WITHOUT running a search. For surfaces\n * (e.g. the omnibar palette) where the user types a query but executes a\n * suggestion that navigates directly — no full ExecuteSearch ever runs, so\n * the automatic recording inside ExecuteSearch never fires for that query.\n * Deduplicates by query text and persists via UserInfoEngine like all recents.\n */\n /** Resolved record-name memo — GetEntityRecordNames round-trips are cosmetic\n and stable, so resolve each entity/record pair once per session. */\n private recentRecordNameCache = new Map<string, string>();\n\n /**\n * Recently opened records for search empty states, newest first — same\n * source as the omnibar's '#' empty state (MJ: User Record Logs, queried\n * through UserInfoEngine.LoadRecentRecordLogs). Fail-soft: any error yields [] rather than blocking\n * the surface. Display names resolve via GetEntityRecordNames with the\n * record ID as fallback.\n */\n public async GetRecentlyOpenedRecords(max = 3): Promise<RecentRecordItem[]> {\n try {\n const logs = await UserInfoEngine.Instance.LoadRecentRecordLogs(max, this.Provider.CurrentUser ?? undefined, this.Provider);\n if (logs.length === 0) {\n return [];\n }\n const unresolved = logs.filter((l) => !this.recentRecordNameCache.has(`${l.Entity}||${l.RecordID}`));\n if (unresolved.length > 0) {\n try {\n // Recents span arbitrary entities whose key column can have any name; `FromID`\n // assumed `ID` and left those records showing a raw id instead of a name.\n const results = await this.Provider.GetEntityRecordNames(\n unresolved.map((l) => ({\n EntityName: l.Entity,\n CompositeKey: CompositeKey.FromURLSegment(this.Provider.EntityByName(l.Entity), l.RecordID),\n })),\n this.Provider.CurrentUser ?? undefined,\n );\n for (const r of results ?? []) {\n if (r.Success && r.RecordName) {\n this.recentRecordNameCache.set(`${r.EntityName}||${r.CompositeKey.GetValueByIndex(0)}`, r.RecordName);\n }\n }\n } catch {\n // name lookup is cosmetic — IDs are an acceptable fallback\n }\n }\n return logs.map((log) => {\n let entityInfo;\n try {\n entityInfo = this.Provider?.EntityByName ? this.Provider.EntityByName(log.Entity) : undefined;\n } catch {\n // Non-fatal if metadata cache is uninitialized\n }\n return {\n EntityName: log.Entity,\n EntityDisplayName: entityInfo?.DisplayName || log.Entity,\n RecordID: log.RecordID,\n RecordName: this.recentRecordNameCache.get(`${log.Entity}||${log.RecordID}`) ?? log.RecordID,\n };\n });\n } catch {\n return [];\n }\n }\n\n public RecordRecentSearch(query: string, resultCount = 0): void {\n const trimmed = query.trim();\n if (trimmed.length > 0) {\n this.addToRecentSearches(trimmed, resultCount);\n }\n }\n\n private addToRecentSearches(query: string, resultCount: number): void {\n const current = this.RecentSearches$.value;\n const filtered = current.filter(s => s.Query !== query);\n const updated = [\n { Query: query, Timestamp: new Date(), ResultCount: resultCount },\n ...filtered\n ].slice(0, this.maxRecentSearches);\n this.RecentSearches$.next(updated);\n this.persistRecentSearches(updated);\n }\n\n private persistRecentSearches(searches: RecentSearch[]): void {\n try {\n const json: RecentSearchJson[] = searches.map(s => ({\n Query: s.Query,\n Timestamp: s.Timestamp.toISOString(),\n ResultCount: s.ResultCount\n }));\n UserInfoEngine.Instance.SetSettingDebounced(RECENT_SEARCHES_KEY, JSON.stringify(json));\n } catch {\n // Silently fail if UserInfoEngine not available\n }\n }\n\n /** Cache provider metadata by SourceType for use in GroupResults/BuildFilters */\n private cacheProviders(providers: SearchProviderInfo[]): void {\n for (const p of providers) {\n this.providersBySourceType.set(p.SourceType, p);\n }\n }\n\n private createEmptyResponse(errorMessage?: string): SearchResponse {\n return {\n Success: !errorMessage,\n Results: [],\n Groups: [],\n Filters: [],\n TotalCount: 0,\n ElapsedMs: 0,\n SourceCounts: { Vector: 0, FullText: 0, Entity: 0, Storage: 0 },\n Providers: [],\n ErrorMessage: errorMessage\n };\n }\n\n /**\n * Execute search via the GraphQLSearchClient.\n */\n private async executeGraphQLSearch(request: SearchRequest): Promise<SearchResponse> {\n if (!request.Query.trim()) {\n return this.createEmptyResponse();\n }\n\n const provider = this.Provider;\n if (!(provider instanceof GraphQLDataProvider)) {\n return this.createEmptyResponse('GraphQL provider not available');\n }\n\n const client = new GraphQLSearchClient(provider);\n const filters = this.buildClientFilters(request);\n const minScore = request.MinScore ?? DEFAULT_MIN_SCORE;\n\n const clientResponse = await client.ExecuteSearch({\n Query: request.Query,\n MaxResults: request.MaxResults || 20,\n MinScore: minScore > 0 ? minScore : undefined,\n Filters: filters,\n ScopeIDs: request.ScopeIDs && request.ScopeIDs.length > 0 ? request.ScopeIDs : undefined\n });\n\n return this.mapClientResponseToSearchResponse(clientResponse);\n }\n\n /** Convert a SearchClientResponse into the SearchResponse shape used by this service */\n private mapClientResponseToSearchResponse(clientResponse: SearchClientResponse): SearchResponse {\n if (!clientResponse.Success) {\n return this.createEmptyResponse(clientResponse.ErrorMessage ?? 'Search failed');\n }\n\n // Cache provider metadata for use in GroupResults/BuildFilters\n const providers: SearchProviderInfo[] = (clientResponse.Providers ?? []).map(p => ({\n ID: p.ID,\n Name: p.Name,\n DisplayName: p.DisplayName,\n Icon: p.Icon,\n SourceType: p.SourceType,\n Priority: p.Priority,\n }));\n this.cacheProviders(providers);\n\n const results: SearchResultItem[] = (clientResponse.Results ?? []).map(r => this.mapClientResultItem(r));\n\n const groups = this.GroupResults(results);\n const filters = this.BuildFilters(results);\n\n return {\n Success: true,\n Results: results,\n Groups: groups,\n Filters: filters,\n TotalCount: clientResponse.TotalCount,\n ElapsedMs: clientResponse.ElapsedMs,\n SourceCounts: {\n Vector: clientResponse.SourceCounts.Vector,\n FullText: clientResponse.SourceCounts.FullText,\n Entity: clientResponse.SourceCounts.Entity,\n Storage: clientResponse.SourceCounts.Storage\n },\n Providers: providers,\n };\n }\n\n /** Map a single SearchClientResultItem to a SearchResultItem */\n private mapClientResultItem(r: SearchClientResultItem): SearchResultItem {\n let entityDisplayName = r.EntityDisplayName;\n let entityIcon = r.EntityIcon;\n try {\n const entity = this.Provider?.EntityByName?.(r.EntityName);\n if (!entityDisplayName && entity) {\n entityDisplayName = entity.DisplayName || entity.Name;\n }\n if (!entityIcon && entity?.Icon) {\n entityIcon = entity.Icon;\n }\n } catch {\n // Non-fatal if metadata cache is uninitialized (e.g. in unit tests)\n }\n if (!entityDisplayName) {\n entityDisplayName = r.EntityName;\n }\n\n return {\n ID: r.ID,\n Title: r.RecordName || r.Title,\n Snippet: r.Snippet,\n EntityName: r.EntityName,\n EntityDisplayName: entityDisplayName,\n RecordID: r.RecordID,\n SourceType: (r.SourceType as SearchResultItem['SourceType']) || 'entity',\n ResultType: r.ResultType,\n Score: r.Score,\n ScoreBreakdown: r.ScoreBreakdown ?? {},\n Tags: r.Tags ?? [],\n SourceIcon: entityIcon || r.ProviderIcon || FALLBACK_SOURCE_ICONS[r.SourceType] || 'fa-solid fa-database',\n EntityIcon: entityIcon,\n RecordName: r.RecordName,\n MatchedAt: new Date(r.MatchedAt),\n RawMetadata: r.RawMetadata,\n ProviderId: r.ProviderId,\n ProviderLabel: r.ProviderLabel,\n ProviderIcon: r.ProviderIcon,\n };\n }\n\n /**\n * Load the list of search scopes available to the current user.\n * Cached after the first successful call; pass `force=true` to reload.\n */\n public async LoadScopes(force: boolean = false): Promise<SearchScopeInfo[]> {\n if (this.scopesLoaded && !force) return this.Scopes$.value;\n if (this.scopesLoadInFlight && !force) return this.scopesLoadInFlight;\n\n const load = (async (): Promise<SearchScopeInfo[]> => {\n try {\n const provider = Metadata.Provider; // global-provider-ok: scope discovery consumes the GraphQL channel of the global default provider\n if (!(provider instanceof GraphQLDataProvider)) {\n this.Scopes$.next([]);\n return [];\n }\n const client = new GraphQLSearchClient(provider);\n const scopes = await client.GetSearchScopes();\n this.Scopes$.next(scopes);\n this.scopesLoaded = true;\n return scopes;\n } catch {\n this.Scopes$.next([]);\n return [];\n } finally {\n this.scopesLoadInFlight = null;\n }\n })();\n\n this.scopesLoadInFlight = load;\n return load;\n }\n\n /** Build the client filters from active filter selections */\n private buildClientFilters(request: SearchRequest): { EntityNames?: string[]; SourceTypes?: string[]; Tags?: string[] } | undefined {\n if (!request.ActiveFilters || Object.keys(request.ActiveFilters).length === 0) {\n return undefined;\n }\n\n const result: { EntityNames?: string[]; SourceTypes?: string[]; Tags?: string[] } = {};\n\n const entityFilters = request.ActiveFilters['Entity'];\n if (entityFilters?.length) {\n result.EntityNames = entityFilters;\n }\n\n const sourceFilters = request.ActiveFilters['Source'];\n if (sourceFilters?.length) {\n result.SourceTypes = sourceFilters;\n }\n\n const tagFilters = request.ActiveFilters['Tags'];\n if (tagFilters?.length) {\n result.Tags = tagFilters;\n }\n\n return Object.keys(result).length > 0 ? result : undefined;\n }\n}\n"]}
1
+ {"version":3,"file":"search.service.js","sourceRoot":"","sources":["../../src/lib/search.service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Search service that connects to the UnifiedSearchService via GraphQL.\n *\n * Provides a reactive interface for executing searches, managing search history,\n * and transforming raw search responses into display-ready grouped results.\n */\n\nimport { Injectable } from '@angular/core';\nimport { BehaviorSubject, Observable, Subject, throwError } from 'rxjs';\nimport { map } from 'rxjs/operators';\nimport { CompositeKey, IMetadataProvider, Metadata, StartupManager } from '@memberjunction/core';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\nimport { MJEventType, MJGlobal } from '@memberjunction/global';\nimport {\n GraphQLSearchClient,\n GraphQLDataProvider,\n SearchClientResponse,\n SearchClientResultItem\n} from '@memberjunction/graphql-dataprovider';\nimport {\n SearchRequest,\n SearchResponse,\n SearchResultItem,\n SearchResultGroup,\n SearchFilter,\n SearchFilterOption,\n SearchProviderInfo,\n SearchScopeInfo,\n RecentRecordItem\n} from './search-types';\n\n/** Default minimum relevance score threshold (0-1). Results below this are filtered out. */\nconst DEFAULT_MIN_SCORE = 0.35;\n\n/** Fallback icon mapping for source types (used when provider metadata is not available) */\nconst FALLBACK_SOURCE_ICONS: Record<string, string> = {\n 'entity': 'fa-solid fa-database',\n 'vector': 'fa-solid fa-brain',\n 'fulltext': 'fa-solid fa-magnifying-glass',\n 'content-item': 'fa-solid fa-file-lines',\n 'file': 'fa-solid fa-file',\n 'web-page': 'fa-solid fa-globe',\n 'storage': 'fa-solid fa-folder-open',\n};\n\n/** Fallback labels for source types (used when provider metadata is not available) */\nconst FALLBACK_SOURCE_LABELS: Record<string, string> = {\n 'entity': 'Database',\n 'vector': 'Semantic Search',\n 'fulltext': 'Full-Text Search',\n 'content-item': 'Content Items',\n 'file': 'Documents',\n 'web-page': 'Web Pages',\n 'storage': 'File Storage',\n};\n\n/** User setting key for persisting recent searches */\nconst RECENT_SEARCHES_KEY = 'search.recentSearches';\n\n/** Recent search entry for history */\nexport interface RecentSearch {\n Query: string;\n Timestamp: Date;\n ResultCount: number;\n}\n\n/** JSON-safe shape for persistence (Date → ISO string) */\ninterface RecentSearchJson {\n Query: string;\n Timestamp: string;\n ResultCount: number;\n}\n\n/**\n * Multi-provider note: callers under a non-default provider should set\n * `service.Provider = component.ProviderToUse` before invoking any methods.\n */\n@Injectable({ providedIn: 'root' })\nexport class SearchService {\n private _provider: IMetadataProvider | null = null;\n public get Provider(): IMetadataProvider {\n return this._provider ?? Metadata.Provider;\n }\n public set Provider(value: IMetadataProvider | null) {\n this._provider = value;\n }\n\n /** Current search response */\n public SearchResults$ = new BehaviorSubject<SearchResponse | null>(null);\n\n /** Whether a search is in progress */\n public IsSearching$ = new BehaviorSubject<boolean>(false);\n\n /** Recent search history (persisted via UserInfoEngine, max 20 entries) */\n public RecentSearches$ = new BehaviorSubject<RecentSearch[]>([]);\n\n /** Error stream */\n public Errors$ = new Subject<string>();\n\n private readonly maxRecentSearches = 20;\n private recentSearchesLoaded = false;\n\n /** Cached provider metadata keyed by SourceType, populated from search responses */\n private providersBySourceType = new Map<string, SearchProviderInfo>();\n\n /** Cached list of scopes the current user can see. Populated lazily by `LoadScopes()`. */\n public Scopes$ = new BehaviorSubject<SearchScopeInfo[]>([]);\n private scopesLoaded = false;\n private scopesLoadInFlight: Promise<SearchScopeInfo[]> | null = null;\n\n /**\n * Execute a search request via the SearchKnowledge GraphQL mutation.\n */\n public async ExecuteSearch(request: SearchRequest): Promise<SearchResponse> {\n this.IsSearching$.next(true);\n const startTime = Date.now();\n\n try {\n const response = await this.executeGraphQLSearch(request);\n response.ElapsedMs = Date.now() - startTime;\n\n this.SearchResults$.next(response);\n this.addToRecentSearches(request.Query, response.TotalCount);\n\n return response;\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Search failed';\n this.Errors$.next(errorMessage);\n const errorResponse = this.createEmptyResponse(errorMessage);\n this.SearchResults$.next(errorResponse);\n return errorResponse;\n } finally {\n this.IsSearching$.next(false);\n }\n }\n\n /**\n * Phase 2C streaming search. Returns an Observable that emits one\n * notification per provider as it returns, plus a 'fused' / 'reranked'\n * / 'final' terminal event. Same auth + permission behavior as\n * ExecuteSearch — denials surface as an error on the Observable.\n *\n * Consumers (typically the search composite component) should:\n * - render skeleton rows immediately when the Observable is created\n * - on each 'provider' event: show progress — `ProviderName` and `ResultCount`. A 'provider'\n * event never carries rows: they arrive before the server's permission pass.\n * - on 'final': render the result list\n * - on error: show the failure message + clear the skeleton\n *\n * Returns rxjs Observable rather than awaiting a Promise — callers\n * decide whether to subscribe + populate state, or unsubscribe on\n * navigation. The service does NOT update its own SearchResults$\n * subject for streaming calls; the caller owns the partial-render\n * state model.\n */\n public StreamSearch(request: SearchRequest): Observable<{\n Phase: string;\n ProviderName?: string;\n /** Set on 'provider' events: how many hits that provider returned, capped at `MaxResults`. */\n ResultCount?: number;\n Results?: SearchResultItem[];\n ElapsedMs?: number;\n ErrorMessage?: string;\n }> {\n const provider = Metadata.Provider; // global-provider-ok: streaming search service consumes the GraphQL channel of the global default provider\n if (!(provider instanceof GraphQLDataProvider)) {\n return throwError(() => new Error('GraphQL provider not available'));\n }\n const client = new GraphQLSearchClient(provider);\n const filters = this.buildClientFilters(request);\n const minScore = request.MinScore ?? DEFAULT_MIN_SCORE;\n return client.StreamSearch({\n Query: request.Query,\n MaxResults: request.MaxResults || 20,\n MinScore: minScore > 0 ? minScore : undefined,\n Filters: filters,\n ScopeIDs: request.ScopeIDs && request.ScopeIDs.length > 0 ? request.ScopeIDs : undefined,\n }).pipe(map((ev) => ({\n Phase: ev.Phase,\n ProviderName: ev.ProviderName,\n ResultCount: ev.ResultCount,\n Results: ev.Results ? ev.Results.map(r => this.mapClientResultItem(r)) : undefined,\n ElapsedMs: ev.ElapsedMs,\n ErrorMessage: ev.ErrorMessage,\n })));\n }\n\n /**\n * Lightweight preview search for autocomplete/typeahead.\n * Does NOT update SearchResults$ or IsSearching$ observables,\n * and does NOT add to recent search history.\n */\n public async PreviewSearch(query: string, maxResults: number = 8): Promise<SearchResponse> {\n try {\n if (!query.trim()) {\n return this.createEmptyResponse();\n }\n\n const provider = this.Provider;\n if (!(provider instanceof GraphQLDataProvider)) {\n return this.createEmptyResponse('GraphQL provider not available');\n }\n\n const client = new GraphQLSearchClient(provider);\n const clientResponse = await client.PreviewSearch(query, maxResults);\n return this.mapClientResponseToSearchResponse(clientResponse);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Preview search failed';\n return this.createEmptyResponse(errorMessage);\n }\n }\n\n /** Clear the current search results */\n public ClearResults(): void {\n this.SearchResults$.next(null);\n }\n\n /** Clear recent search history (memory and persisted) */\n public ClearRecentSearches(): void {\n this.RecentSearches$.next([]);\n this.persistRecentSearches([]);\n }\n\n /**\n * Group flat results by source type for display.\n */\n public GroupResults(results: SearchResultItem[]): SearchResultGroup[] {\n const groupMap = new Map<string, SearchResultItem[]>();\n\n for (const result of results) {\n const key = result.SourceType;\n const existing = groupMap.get(key);\n if (existing) {\n existing.push(result);\n } else {\n groupMap.set(key, [result]);\n }\n }\n\n return Array.from(groupMap.entries()).map(([sourceType, items]) => {\n // Priority: cached provider metadata > per-result metadata > fallback maps\n const cached = this.providersBySourceType.get(sourceType);\n return {\n Label: cached?.DisplayName ?? items[0]?.ProviderLabel ?? FALLBACK_SOURCE_LABELS[sourceType] ?? sourceType,\n Icon: cached?.Icon ?? items[0]?.ProviderIcon ?? FALLBACK_SOURCE_ICONS[sourceType] ?? 'fa-solid fa-circle',\n SourceType: sourceType,\n Results: items,\n TotalCount: items.length\n };\n });\n }\n\n /**\n * Build filter facets from a set of results.\n */\n public BuildFilters(results: SearchResultItem[]): SearchFilter[] {\n return [\n this.buildSourceTypeFilter(results),\n this.buildEntityNameFilter(results),\n this.buildFileTypeFilter(results),\n this.buildTagFilter(results)\n ].filter(f => f.Options.length > 0); // Hide categories with no options\n }\n\n /** Get the icon for a given source type */\n public GetSourceIcon(sourceType: string): string {\n return this.providersBySourceType.get(sourceType)?.Icon ?? FALLBACK_SOURCE_ICONS[sourceType] ?? 'fa-solid fa-circle';\n }\n\n private buildSourceTypeFilter(results: SearchResultItem[]): SearchFilter {\n const counts = new Map<string, number>();\n for (const r of results) {\n counts.set(r.SourceType, (counts.get(r.SourceType) ?? 0) + 1);\n }\n const options: SearchFilterOption[] = Array.from(counts.entries()).map(([type, count]) => {\n const cached = this.providersBySourceType.get(type);\n return {\n Label: cached?.DisplayName ?? FALLBACK_SOURCE_LABELS[type] ?? type,\n Value: type,\n Count: count,\n IsSelected: false,\n Icon: cached?.Icon ?? FALLBACK_SOURCE_ICONS[type]\n };\n });\n return { Category: 'Source', Options: options, MultiSelect: true };\n }\n\n private buildEntityNameFilter(results: SearchResultItem[]): SearchFilter {\n const counts = new Map<string, { count: number; displayName: string; icon?: string }>();\n let fileCount = 0;\n for (const r of results) {\n if (r.ResultType === 'storage-file') {\n fileCount++;\n } else {\n const existing = counts.get(r.EntityName);\n const displayName = r.EntityDisplayName || r.EntityName;\n if (existing) {\n existing.count++;\n } else {\n counts.set(r.EntityName, { count: 1, displayName, icon: r.EntityIcon });\n }\n }\n }\n const options: SearchFilterOption[] = Array.from(counts.entries())\n .sort((a, b) => b[1].count - a[1].count)\n .map(([name, data]) => ({\n Label: data.displayName,\n Value: name,\n Count: data.count,\n IsSelected: false,\n Icon: data.icon ?? 'fa-solid fa-table'\n }));\n\n // Add a single \"Files\" entry for all storage file results\n if (fileCount > 0) {\n options.push({\n Label: 'Files',\n Value: '__storage-files__',\n Count: fileCount,\n IsSelected: false,\n Icon: 'fa-solid fa-file'\n });\n }\n\n return { Category: 'Entity', Options: options, MultiSelect: true };\n }\n\n private buildFileTypeFilter(results: SearchResultItem[]): SearchFilter {\n const counts = new Map<string, number>();\n for (const r of results) {\n if (r.ResultType !== 'storage-file') continue;\n const ext = r.Title?.split('.').pop()?.toUpperCase();\n if (ext && ext.length <= 6) {\n counts.set(ext, (counts.get(ext) ?? 0) + 1);\n }\n }\n const options: SearchFilterOption[] = Array.from(counts.entries())\n .sort((a, b) => b[1] - a[1])\n .map(([ext, count]) => ({\n Label: ext,\n Value: ext,\n Count: count,\n IsSelected: false,\n Icon: 'fa-solid fa-file'\n }));\n return { Category: 'File Type', Options: options, MultiSelect: true };\n }\n\n private buildTagFilter(results: SearchResultItem[]): SearchFilter {\n const counts = new Map<string, number>();\n for (const r of results) {\n for (const tag of r.Tags) {\n counts.set(tag, (counts.get(tag) ?? 0) + 1);\n }\n }\n const options: SearchFilterOption[] = Array.from(counts.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, 15)\n .map(([tag, count]) => ({\n Label: tag,\n Value: tag,\n Count: count,\n IsSelected: false,\n Icon: 'fa-solid fa-tag'\n }));\n return { Category: 'Tags', Options: options, MultiSelect: true };\n }\n\n /**\n * Load persisted recent searches from UserInfoEngine.\n * Safe to call multiple times — only loads once.\n */\n public async LoadRecentSearches(): Promise<void> {\n if (this.recentSearchesLoaded) return;\n\n try {\n MJGlobal.Instance.GetEventListener(true).subscribe(async (event) => {\n if (event.event === MJEventType.LoggedIn) {\n await StartupManager.Instance.Startup();\n\n const engine = UserInfoEngine.Instance;\n\n const json = engine.GetSetting(RECENT_SEARCHES_KEY);\n\n if (json) {\n const parsed = JSON.parse(json) as RecentSearchJson[];\n const searches: RecentSearch[] = parsed.map(s => ({\n Query: s.Query,\n Timestamp: new Date(s.Timestamp),\n ResultCount: s.ResultCount\n }));\n this.RecentSearches$.next(searches);\n }\n }\n });\n } catch (err) {\n console.error('[SearchService] LoadRecentSearches error:', err);\n }\n this.recentSearchesLoaded = true;\n }\n\n /**\n * Record a query into recent searches WITHOUT running a search. For surfaces\n * (e.g. the omnibar palette) where the user types a query but executes a\n * suggestion that navigates directly — no full ExecuteSearch ever runs, so\n * the automatic recording inside ExecuteSearch never fires for that query.\n * Deduplicates by query text and persists via UserInfoEngine like all recents.\n */\n /** Resolved record-name memo — GetEntityRecordNames round-trips are cosmetic\n and stable, so resolve each entity/record pair once per session. */\n private recentRecordNameCache = new Map<string, string>();\n\n /**\n * Recently opened records for search empty states, newest first — same\n * source as the omnibar's '#' empty state (MJ: User Record Logs, queried\n * through UserInfoEngine.LoadRecentRecordLogs). Fail-soft: any error yields [] rather than blocking\n * the surface. Display names resolve via GetEntityRecordNames with the\n * record ID as fallback.\n */\n public async GetRecentlyOpenedRecords(max = 3): Promise<RecentRecordItem[]> {\n try {\n const logs = await UserInfoEngine.Instance.LoadRecentRecordLogs(max, this.Provider.CurrentUser ?? undefined, this.Provider);\n if (logs.length === 0) {\n return [];\n }\n const unresolved = logs.filter((l) => !this.recentRecordNameCache.has(`${l.Entity}||${l.RecordID}`));\n if (unresolved.length > 0) {\n try {\n // Recents span arbitrary entities whose key column can have any name; `FromID`\n // assumed `ID` and left those records showing a raw id instead of a name.\n const results = await this.Provider.GetEntityRecordNames(\n unresolved.map((l) => ({\n EntityName: l.Entity,\n CompositeKey: CompositeKey.FromURLSegment(this.Provider.EntityByName(l.Entity), l.RecordID),\n })),\n this.Provider.CurrentUser ?? undefined,\n );\n for (const r of results ?? []) {\n if (r.Success && r.RecordName) {\n this.recentRecordNameCache.set(`${r.EntityName}||${r.CompositeKey.GetValueByIndex(0)}`, r.RecordName);\n }\n }\n } catch {\n // name lookup is cosmetic — IDs are an acceptable fallback\n }\n }\n return logs.map((log) => {\n let entityInfo;\n try {\n entityInfo = this.Provider?.EntityByName ? this.Provider.EntityByName(log.Entity) : undefined;\n } catch {\n // Non-fatal if metadata cache is uninitialized\n }\n return {\n EntityName: log.Entity,\n EntityDisplayName: entityInfo?.DisplayName || log.Entity,\n RecordID: log.RecordID,\n RecordName: this.recentRecordNameCache.get(`${log.Entity}||${log.RecordID}`) ?? log.RecordID,\n };\n });\n } catch {\n return [];\n }\n }\n\n public RecordRecentSearch(query: string, resultCount = 0): void {\n const trimmed = query.trim();\n if (trimmed.length > 0) {\n this.addToRecentSearches(trimmed, resultCount);\n }\n }\n\n private addToRecentSearches(query: string, resultCount: number): void {\n const current = this.RecentSearches$.value;\n const filtered = current.filter(s => s.Query !== query);\n const updated = [\n { Query: query, Timestamp: new Date(), ResultCount: resultCount },\n ...filtered\n ].slice(0, this.maxRecentSearches);\n this.RecentSearches$.next(updated);\n this.persistRecentSearches(updated);\n }\n\n private persistRecentSearches(searches: RecentSearch[]): void {\n try {\n const json: RecentSearchJson[] = searches.map(s => ({\n Query: s.Query,\n Timestamp: s.Timestamp.toISOString(),\n ResultCount: s.ResultCount\n }));\n UserInfoEngine.Instance.SetSettingDebounced(RECENT_SEARCHES_KEY, JSON.stringify(json));\n } catch {\n // Silently fail if UserInfoEngine not available\n }\n }\n\n /** Cache provider metadata by SourceType for use in GroupResults/BuildFilters */\n private cacheProviders(providers: SearchProviderInfo[]): void {\n for (const p of providers) {\n this.providersBySourceType.set(p.SourceType, p);\n }\n }\n\n private createEmptyResponse(errorMessage?: string): SearchResponse {\n return {\n Success: !errorMessage,\n Results: [],\n Groups: [],\n Filters: [],\n TotalCount: 0,\n ElapsedMs: 0,\n SourceCounts: { Vector: 0, FullText: 0, Entity: 0, Storage: 0 },\n Providers: [],\n ErrorMessage: errorMessage\n };\n }\n\n /**\n * Execute search via the GraphQLSearchClient.\n */\n private async executeGraphQLSearch(request: SearchRequest): Promise<SearchResponse> {\n if (!request.Query.trim()) {\n return this.createEmptyResponse();\n }\n\n const provider = this.Provider;\n if (!(provider instanceof GraphQLDataProvider)) {\n return this.createEmptyResponse('GraphQL provider not available');\n }\n\n const client = new GraphQLSearchClient(provider);\n const filters = this.buildClientFilters(request);\n const minScore = request.MinScore ?? DEFAULT_MIN_SCORE;\n\n const clientResponse = await client.ExecuteSearch({\n Query: request.Query,\n MaxResults: request.MaxResults || 20,\n MinScore: minScore > 0 ? minScore : undefined,\n Filters: filters,\n ScopeIDs: request.ScopeIDs && request.ScopeIDs.length > 0 ? request.ScopeIDs : undefined\n });\n\n return this.mapClientResponseToSearchResponse(clientResponse);\n }\n\n /** Convert a SearchClientResponse into the SearchResponse shape used by this service */\n private mapClientResponseToSearchResponse(clientResponse: SearchClientResponse): SearchResponse {\n if (!clientResponse.Success) {\n return this.createEmptyResponse(clientResponse.ErrorMessage ?? 'Search failed');\n }\n\n // Cache provider metadata for use in GroupResults/BuildFilters\n const providers: SearchProviderInfo[] = (clientResponse.Providers ?? []).map(p => ({\n ID: p.ID,\n Name: p.Name,\n DisplayName: p.DisplayName,\n Icon: p.Icon,\n SourceType: p.SourceType,\n Priority: p.Priority,\n }));\n this.cacheProviders(providers);\n\n const results: SearchResultItem[] = (clientResponse.Results ?? []).map(r => this.mapClientResultItem(r));\n\n const groups = this.GroupResults(results);\n const filters = this.BuildFilters(results);\n\n return {\n Success: true,\n Results: results,\n Groups: groups,\n Filters: filters,\n TotalCount: clientResponse.TotalCount,\n ElapsedMs: clientResponse.ElapsedMs,\n SourceCounts: {\n Vector: clientResponse.SourceCounts.Vector,\n FullText: clientResponse.SourceCounts.FullText,\n Entity: clientResponse.SourceCounts.Entity,\n Storage: clientResponse.SourceCounts.Storage\n },\n Providers: providers,\n };\n }\n\n /** Map a single SearchClientResultItem to a SearchResultItem */\n private mapClientResultItem(r: SearchClientResultItem): SearchResultItem {\n let entityDisplayName = r.EntityDisplayName;\n let entityIcon = r.EntityIcon;\n try {\n const entity = this.Provider?.EntityByName?.(r.EntityName);\n if (!entityDisplayName && entity) {\n entityDisplayName = entity.DisplayName || entity.Name;\n }\n if (!entityIcon && entity?.Icon) {\n entityIcon = entity.Icon;\n }\n } catch {\n // Non-fatal if metadata cache is uninitialized (e.g. in unit tests)\n }\n if (!entityDisplayName) {\n entityDisplayName = r.EntityName;\n }\n\n return {\n ID: r.ID,\n Title: r.RecordName || r.Title,\n Snippet: r.Snippet,\n EntityName: r.EntityName,\n EntityDisplayName: entityDisplayName,\n RecordID: r.RecordID,\n SourceType: (r.SourceType as SearchResultItem['SourceType']) || 'entity',\n ResultType: r.ResultType,\n Score: r.Score,\n ScoreBreakdown: r.ScoreBreakdown ?? {},\n Tags: r.Tags ?? [],\n SourceIcon: entityIcon || r.ProviderIcon || FALLBACK_SOURCE_ICONS[r.SourceType] || 'fa-solid fa-database',\n EntityIcon: entityIcon,\n RecordName: r.RecordName,\n MatchedAt: new Date(r.MatchedAt),\n RawMetadata: r.RawMetadata,\n ProviderId: r.ProviderId,\n ProviderLabel: r.ProviderLabel,\n ProviderIcon: r.ProviderIcon,\n };\n }\n\n /**\n * Load the list of search scopes available to the current user.\n * Cached after the first successful call; pass `force=true` to reload.\n */\n public async LoadScopes(force: boolean = false): Promise<SearchScopeInfo[]> {\n if (this.scopesLoaded && !force) return this.Scopes$.value;\n if (this.scopesLoadInFlight && !force) return this.scopesLoadInFlight;\n\n const load = (async (): Promise<SearchScopeInfo[]> => {\n try {\n const provider = Metadata.Provider; // global-provider-ok: scope discovery consumes the GraphQL channel of the global default provider\n if (!(provider instanceof GraphQLDataProvider)) {\n this.Scopes$.next([]);\n return [];\n }\n const client = new GraphQLSearchClient(provider);\n const scopes = await client.GetSearchScopes();\n this.Scopes$.next(scopes);\n this.scopesLoaded = true;\n return scopes;\n } catch {\n this.Scopes$.next([]);\n return [];\n } finally {\n this.scopesLoadInFlight = null;\n }\n })();\n\n this.scopesLoadInFlight = load;\n return load;\n }\n\n /** Build the client filters from active filter selections */\n private buildClientFilters(request: SearchRequest): { EntityNames?: string[]; SourceTypes?: string[]; Tags?: string[] } | undefined {\n if (!request.ActiveFilters || Object.keys(request.ActiveFilters).length === 0) {\n return undefined;\n }\n\n const result: { EntityNames?: string[]; SourceTypes?: string[]; Tags?: string[] } = {};\n\n const entityFilters = request.ActiveFilters['Entity'];\n if (entityFilters?.length) {\n result.EntityNames = entityFilters;\n }\n\n const sourceFilters = request.ActiveFilters['Source'];\n if (sourceFilters?.length) {\n result.SourceTypes = sourceFilters;\n }\n\n const tagFilters = request.ActiveFilters['Tags'];\n if (tagFilters?.length) {\n result.Tags = tagFilters;\n }\n\n return Object.keys(result).length > 0 ? result : undefined;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-search",
3
- "version": "6.2.0-edge.4",
3
+ "version": "6.2.0-edge.5",
4
4
  "description": "MemberJunction: Reusable search overlay and results components - command palette / Spotlight style search",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -13,7 +13,7 @@
13
13
  "devDependencies": {
14
14
  "@angular/compiler": "21.2.22",
15
15
  "@angular/compiler-cli": "21.2.22",
16
- "@memberjunction/ng-test-utils": "6.2.0-edge.4",
16
+ "@memberjunction/ng-test-utils": "6.2.0-edge.5",
17
17
  "vitest": "^4.0.18"
18
18
  },
19
19
  "peerDependencies": {
@@ -22,13 +22,13 @@
22
22
  "@angular/forms": "^21.2.22"
23
23
  },
24
24
  "dependencies": {
25
- "@memberjunction/ng-ui-components": "6.2.0-edge.4",
26
- "@memberjunction/core": "6.2.0-edge.4",
27
- "@memberjunction/ng-base-types": "6.2.0-edge.4",
28
- "@memberjunction/global": "6.2.0-edge.4",
29
- "@memberjunction/graphql-dataprovider": "6.2.0-edge.4",
30
- "@memberjunction/core-entities": "6.2.0-edge.4",
31
- "@memberjunction/ng-shared-generic": "6.2.0-edge.4",
25
+ "@memberjunction/ng-ui-components": "6.2.0-edge.5",
26
+ "@memberjunction/core": "6.2.0-edge.5",
27
+ "@memberjunction/ng-base-types": "6.2.0-edge.5",
28
+ "@memberjunction/global": "6.2.0-edge.5",
29
+ "@memberjunction/graphql-dataprovider": "6.2.0-edge.5",
30
+ "@memberjunction/core-entities": "6.2.0-edge.5",
31
+ "@memberjunction/ng-shared-generic": "6.2.0-edge.5",
32
32
  "rxjs": "^7.8.2",
33
33
  "tslib": "^2.8.1"
34
34
  },