@memberjunction/ng-search 5.32.0 → 5.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/__tests__/search.service.test.js +101 -0
  2. package/dist/__tests__/search.service.test.js.map +1 -1
  3. package/dist/lib/module.d.ts +6 -4
  4. package/dist/lib/module.d.ts.map +1 -1
  5. package/dist/lib/module.js +14 -4
  6. package/dist/lib/module.js.map +1 -1
  7. package/dist/lib/search-composite.component.d.ts +29 -2
  8. package/dist/lib/search-composite.component.d.ts.map +1 -1
  9. package/dist/lib/search-composite.component.js +72 -7
  10. package/dist/lib/search-composite.component.js.map +1 -1
  11. package/dist/lib/search-overlay.component.d.ts +42 -1
  12. package/dist/lib/search-overlay.component.d.ts.map +1 -1
  13. package/dist/lib/search-overlay.component.js +301 -128
  14. package/dist/lib/search-overlay.component.js.map +1 -1
  15. package/dist/lib/search-scope-child-grid.component.d.ts +166 -0
  16. package/dist/lib/search-scope-child-grid.component.d.ts.map +1 -0
  17. package/dist/lib/search-scope-child-grid.component.js +575 -0
  18. package/dist/lib/search-scope-child-grid.component.js.map +1 -0
  19. package/dist/lib/search-scope-selector.component.d.ts +71 -0
  20. package/dist/lib/search-scope-selector.component.d.ts.map +1 -0
  21. package/dist/lib/search-scope-selector.component.js +354 -0
  22. package/dist/lib/search-scope-selector.component.js.map +1 -0
  23. package/dist/lib/search-types.d.ts +18 -0
  24. package/dist/lib/search-types.d.ts.map +1 -1
  25. package/dist/lib/search-types.js.map +1 -1
  26. package/dist/lib/search.service.d.ts +36 -2
  27. package/dist/lib/search.service.d.ts.map +1 -1
  28. package/dist/lib/search.service.js +81 -2
  29. package/dist/lib/search.service.js.map +1 -1
  30. package/dist/public-api.d.ts +2 -0
  31. package/dist/public-api.d.ts.map +1 -1
  32. package/dist/public-api.js +2 -0
  33. package/dist/public-api.js.map +1 -1
  34. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"search-types.d.ts","sourceRoot":"","sources":["../../src/lib/search-types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search-types.d.ts","sourceRoot":"","sources":["../../src/lib/search-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,6CAA6C;AAC7C,MAAM,WAAW,gBAAgB;IAC7B,wBAAwB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,0CAA0C;IAC1C,UAAU,EAAE,QAAQ,GAAG,cAAc,GAAG,MAAM,GAAG,UAAU,CAAC;IAC5D,yFAAyF;IACzF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,cAAc,EAAE,cAAc,CAAC;IAC/B,0BAA0B;IAC1B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,kDAAkD;IAClD,UAAU,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mCAAmC;IACnC,SAAS,EAAE,IAAI,CAAC;IAChB,oFAAoF;IACpF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2FAA2F;IAC3F,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,8DAA8D;AAC9D,MAAM,WAAW,cAAc;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,4CAA4C;AAC5C,MAAM,WAAW,iBAAiB;IAC9B,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,4BAA4B;IAC5B,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,2EAA2E;IAC3E,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,mCAAmC;AACnC,MAAM,WAAW,YAAY;IACzB,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,0CAA0C;IAC1C,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,+CAA+C;IAC/C,WAAW,EAAE,OAAO,CAAC;CACxB;AAED,6CAA6C;AAC7C,MAAM,WAAW,kBAAkB;IAC/B,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,UAAU,EAAE,OAAO,CAAC;IACpB,8BAA8B;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,gCAAgC;AAChC,MAAM,WAAW,aAAa;IAC1B,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACxC,sCAAsC;IACtC,cAAc,EAAE,CAAC,QAAQ,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,CAAC,EAAE,CAAC;IACjE;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,+EAA+E;AAC/E,MAAM,WAAW,eAAe;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,sFAAsF;IACtF,UAAU,EAAE,OAAO,CAAC;CACvB;AAED,+DAA+D;AAC/D,MAAM,WAAW,kBAAkB;IAC/B,+BAA+B;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,uCAAuC;AACvC,MAAM,WAAW,cAAc;IAC3B,mCAAmC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,yBAAyB;IACzB,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,qCAAqC;IACrC,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,yCAAyC;IACzC,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,YAAY,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACpF,iEAAiE;IACjE,SAAS,EAAE,kBAAkB,EAAE,CAAC;IAChC,wCAAwC;IACxC,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qDAAqD;AACrD,MAAM,WAAW,yBAAyB;IACtC,+BAA+B;IAC/B,MAAM,EAAE,gBAAgB,CAAC;IACzB,mCAAmC;IACnC,YAAY,EAAE,OAAO,CAAC;CACzB;AAED,wCAAwC;AACxC,MAAM,WAAW,uBAAuB;IACpC,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,cAAc,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,4CAA4C;AAC5C,MAAM,WAAW,mBAAmB;IAChC,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAClC,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;CACrB"}
@@ -1 +1 @@
1
- {"version":3,"file":"search-types.js","sourceRoot":"","sources":["../../src/lib/search-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG","sourcesContent":["/**\n * @fileoverview Shared types for the ng-search package.\n *\n * Defines the data contracts for search results, filters,\n * and events used across all search components.\n */\n\n/** Represents a single search result item */\nexport interface SearchResultItem {\n /** Unique identifier */\n ID: string;\n /** Display title */\n Title: string;\n /** Short text snippet showing match context */\n Snippet: string;\n /** The entity name this result belongs to */\n EntityName: string;\n /** The primary key of the source record */\n RecordID: string;\n /** Classification of the result source */\n SourceType: 'entity' | 'content-item' | 'file' | 'web-page';\n /** Discriminator for UI rendering: 'entity-record', 'storage-file', or 'content-item' */\n ResultType?: string;\n /** Relevance score between 0 and 1 */\n Score: number;\n /** Breakdown of how the score was computed */\n ScoreBreakdown: ScoreBreakdown;\n /** Human-readable tags */\n Tags: string[];\n /** Font Awesome icon class for the source type */\n SourceIcon: string;\n /** Entity-specific icon from EntityInfo.Icon (e.g., \"fa-solid fa-robot\") */\n EntityIcon?: string;\n /** Human-readable record name resolved from EntityRecordName */\n RecordName?: string;\n /** When this result was matched */\n MatchedAt: Date;\n /** Raw vector metadata JSON — contains all entity fields stored in the vector DB */\n RawMetadata?: string;\n /** ID of the SearchProvider metadata record that produced this result */\n ProviderId?: string;\n /** Display label from the SearchProvider metadata (e.g., \"Database\", \"Semantic Search\") */\n ProviderLabel?: string;\n /** Font Awesome icon class from the SearchProvider metadata */\n ProviderIcon?: string;\n}\n\n/** Breakdown of score contribution from each search source */\nexport interface ScoreBreakdown {\n Vector?: number;\n FullText?: number;\n Entity?: number;\n}\n\n/** Grouped search results by source type */\nexport interface SearchResultGroup {\n /** The source type label */\n Label: string;\n /** Font Awesome icon class */\n Icon: string;\n /** The source type key */\n SourceType: string;\n /** Results in this group */\n Results: SearchResultItem[];\n /** Total count for this source (may exceed Results.length if paginated) */\n TotalCount: number;\n}\n\n/** Faceted filter configuration */\nexport interface SearchFilter {\n /** Filter category name */\n Category: string;\n /** Filter options within this category */\n Options: SearchFilterOption[];\n /** Whether multiple options can be selected */\n MultiSelect: boolean;\n}\n\n/** Single filter option within a category */\nexport interface SearchFilterOption {\n /** Display label */\n Label: string;\n /** Value to filter by */\n Value: string;\n /** Count of results matching this option */\n Count: number;\n /** Whether this option is currently selected */\n IsSelected: boolean;\n /** Font Awesome icon class */\n Icon?: string;\n}\n\n/** Search request parameters */\nexport interface SearchRequest {\n /** The search query string */\n Query: string;\n /** Maximum number of results to return */\n MaxResults: number;\n /** Active filter selections */\n ActiveFilters: Record<string, string[]>;\n /** Which search sources to include */\n IncludeSources: ('vector' | 'fulltext' | 'entity' | 'storage')[];\n /**\n * Minimum relevance score (0-1) to include in results.\n * Results below this threshold are filtered out.\n * Default: 0.35 (35%).\n */\n MinScore?: number;\n}\n\n/** Metadata about an active search provider from the server */\nexport interface SearchProviderInfo {\n /** SearchProvider record ID */\n ID: string;\n /** Provider name */\n Name: string;\n /** UI display label */\n DisplayName: string;\n /** Font Awesome icon class */\n Icon: string;\n /** The SourceType key this provider uses */\n SourceType: string;\n /** Priority (lower = higher) */\n Priority: number;\n}\n\n/** Search response from the service */\nexport interface SearchResponse {\n /** Whether the search succeeded */\n Success: boolean;\n /** The search results */\n Results: SearchResultItem[];\n /** Grouped results by source type */\n Groups: SearchResultGroup[];\n /** Available filters based on results */\n Filters: SearchFilter[];\n /** Total result count across all sources */\n TotalCount: number;\n /** Time taken in milliseconds */\n ElapsedMs: number;\n /** Count of results from each source */\n SourceCounts: { Vector: number; FullText: number; Entity: number; Storage: number };\n /** Active search providers metadata (for UI labels and icons) */\n Providers: SearchProviderInfo[];\n /** Error message if Success is false */\n ErrorMessage?: string;\n}\n\n/** Event emitted when a search result is selected */\nexport interface SearchResultSelectedEvent {\n /** The selected result item */\n Result: SearchResultItem;\n /** Whether to open in a new tab */\n OpenInNewTab: boolean;\n}\n\n/** Event emitted when filters change */\nexport interface SearchFilterChangeEvent {\n /** The filter category that changed */\n Category: string;\n /** The new selected values */\n SelectedValues: string[];\n}\n\n/** Event emitted when search is executed */\nexport interface SearchExecutedEvent {\n /** The search query */\n Query: string;\n /** Active filters */\n Filters: Record<string, string[]>;\n /** Number of results returned */\n ResultCount: number;\n /** Time taken in ms */\n ElapsedMs: number;\n}\n"]}
1
+ {"version":3,"file":"search-types.js","sourceRoot":"","sources":["../../src/lib/search-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG","sourcesContent":["/**\n * @fileoverview Shared types for the ng-search package.\n *\n * Defines the data contracts for search results, filters,\n * and events used across all search components.\n */\n\n/** Represents a single search result item */\nexport interface SearchResultItem {\n /** Unique identifier */\n ID: string;\n /** Display title */\n Title: string;\n /** Short text snippet showing match context */\n Snippet: string;\n /** The entity name this result belongs to */\n EntityName: string;\n /** The primary key of the source record */\n RecordID: string;\n /** Classification of the result source */\n SourceType: 'entity' | 'content-item' | 'file' | 'web-page';\n /** Discriminator for UI rendering: 'entity-record', 'storage-file', or 'content-item' */\n ResultType?: string;\n /** Relevance score between 0 and 1 */\n Score: number;\n /** Breakdown of how the score was computed */\n ScoreBreakdown: ScoreBreakdown;\n /** Human-readable tags */\n Tags: string[];\n /** Font Awesome icon class for the source type */\n SourceIcon: string;\n /** Entity-specific icon from EntityInfo.Icon (e.g., \"fa-solid fa-robot\") */\n EntityIcon?: string;\n /** Human-readable record name resolved from EntityRecordName */\n RecordName?: string;\n /** When this result was matched */\n MatchedAt: Date;\n /** Raw vector metadata JSON — contains all entity fields stored in the vector DB */\n RawMetadata?: string;\n /** ID of the SearchProvider metadata record that produced this result */\n ProviderId?: string;\n /** Display label from the SearchProvider metadata (e.g., \"Database\", \"Semantic Search\") */\n ProviderLabel?: string;\n /** Font Awesome icon class from the SearchProvider metadata */\n ProviderIcon?: string;\n}\n\n/** Breakdown of score contribution from each search source */\nexport interface ScoreBreakdown {\n Vector?: number;\n FullText?: number;\n Entity?: number;\n}\n\n/** Grouped search results by source type */\nexport interface SearchResultGroup {\n /** The source type label */\n Label: string;\n /** Font Awesome icon class */\n Icon: string;\n /** The source type key */\n SourceType: string;\n /** Results in this group */\n Results: SearchResultItem[];\n /** Total count for this source (may exceed Results.length if paginated) */\n TotalCount: number;\n}\n\n/** Faceted filter configuration */\nexport interface SearchFilter {\n /** Filter category name */\n Category: string;\n /** Filter options within this category */\n Options: SearchFilterOption[];\n /** Whether multiple options can be selected */\n MultiSelect: boolean;\n}\n\n/** Single filter option within a category */\nexport interface SearchFilterOption {\n /** Display label */\n Label: string;\n /** Value to filter by */\n Value: string;\n /** Count of results matching this option */\n Count: number;\n /** Whether this option is currently selected */\n IsSelected: boolean;\n /** Font Awesome icon class */\n Icon?: string;\n}\n\n/** Search request parameters */\nexport interface SearchRequest {\n /** The search query string */\n Query: string;\n /** Maximum number of results to return */\n MaxResults: number;\n /** Active filter selections */\n ActiveFilters: Record<string, string[]>;\n /** Which search sources to include */\n IncludeSources: ('vector' | 'fulltext' | 'entity' | 'storage')[];\n /**\n * Minimum relevance score (0-1) to include in results.\n * Results below this threshold are filtered out.\n * Default: 0.35 (35%).\n */\n MinScore?: number;\n /**\n * Optional array of `MJ: Search Scopes` record IDs selected in the UI scope selector.\n * When provided, the server resolves each scope and runs only those constrained providers.\n * When omitted (or all selected scopes are `IsGlobal`), behavior is equivalent to the\n * pre-scope unconstrained search.\n */\n ScopeIDs?: string[];\n}\n\n/** Lightweight scope metadata returned by the `SearchScopes` GraphQL query. */\nexport interface SearchScopeInfo {\n ID: string;\n Name: string;\n Description?: string;\n Icon?: string;\n IsGlobal: boolean;\n IsDefault: boolean;\n /** True when the scope has an OwnerUserID — renders as a personal scope in the UI. */\n IsPersonal: boolean;\n}\n\n/** Metadata about an active search provider from the server */\nexport interface SearchProviderInfo {\n /** SearchProvider record ID */\n ID: string;\n /** Provider name */\n Name: string;\n /** UI display label */\n DisplayName: string;\n /** Font Awesome icon class */\n Icon: string;\n /** The SourceType key this provider uses */\n SourceType: string;\n /** Priority (lower = higher) */\n Priority: number;\n}\n\n/** Search response from the service */\nexport interface SearchResponse {\n /** Whether the search succeeded */\n Success: boolean;\n /** The search results */\n Results: SearchResultItem[];\n /** Grouped results by source type */\n Groups: SearchResultGroup[];\n /** Available filters based on results */\n Filters: SearchFilter[];\n /** Total result count across all sources */\n TotalCount: number;\n /** Time taken in milliseconds */\n ElapsedMs: number;\n /** Count of results from each source */\n SourceCounts: { Vector: number; FullText: number; Entity: number; Storage: number };\n /** Active search providers metadata (for UI labels and icons) */\n Providers: SearchProviderInfo[];\n /** Error message if Success is false */\n ErrorMessage?: string;\n}\n\n/** Event emitted when a search result is selected */\nexport interface SearchResultSelectedEvent {\n /** The selected result item */\n Result: SearchResultItem;\n /** Whether to open in a new tab */\n OpenInNewTab: boolean;\n}\n\n/** Event emitted when filters change */\nexport interface SearchFilterChangeEvent {\n /** The filter category that changed */\n Category: string;\n /** The new selected values */\n SelectedValues: string[];\n}\n\n/** Event emitted when search is executed */\nexport interface SearchExecutedEvent {\n /** The search query */\n Query: string;\n /** Active filters */\n Filters: Record<string, string[]>;\n /** Number of results returned */\n ResultCount: number;\n /** Time taken in ms */\n ElapsedMs: number;\n}\n"]}
@@ -1,6 +1,6 @@
1
- import { BehaviorSubject, Subject } from 'rxjs';
1
+ import { BehaviorSubject, Observable, Subject } from 'rxjs';
2
2
  import { IMetadataProvider } from '@memberjunction/core';
3
- import { SearchRequest, SearchResponse, SearchResultItem, SearchResultGroup, SearchFilter } from './search-types';
3
+ import { SearchRequest, SearchResponse, SearchResultItem, SearchResultGroup, SearchFilter, SearchScopeInfo } from './search-types';
4
4
  import * as i0 from "@angular/core";
5
5
  /** Recent search entry for history */
6
6
  export interface RecentSearch {
@@ -28,10 +28,39 @@ export declare class SearchService {
28
28
  private recentSearchesLoaded;
29
29
  /** Cached provider metadata keyed by SourceType, populated from search responses */
30
30
  private providersBySourceType;
31
+ /** Cached list of scopes the current user can see. Populated lazily by `LoadScopes()`. */
32
+ Scopes$: BehaviorSubject<SearchScopeInfo[]>;
33
+ private scopesLoaded;
34
+ private scopesLoadInFlight;
31
35
  /**
32
36
  * Execute a search request via the SearchKnowledge GraphQL mutation.
33
37
  */
34
38
  ExecuteSearch(request: SearchRequest): Promise<SearchResponse>;
39
+ /**
40
+ * Phase 2C streaming search. Returns an Observable that emits one
41
+ * notification per provider as it returns, plus a 'fused' / 'reranked'
42
+ * / 'final' terminal event. Same auth + permission behavior as
43
+ * ExecuteSearch — denials surface as an error on the Observable.
44
+ *
45
+ * Consumers (typically the search composite component) should:
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
49
+ * - on error: show the failure message + clear the skeleton
50
+ *
51
+ * Returns rxjs Observable rather than awaiting a Promise — callers
52
+ * decide whether to subscribe + populate state, or unsubscribe on
53
+ * navigation. The service does NOT update its own SearchResults$
54
+ * subject for streaming calls; the caller owns the partial-render
55
+ * state model.
56
+ */
57
+ StreamSearch(request: SearchRequest): Observable<{
58
+ Phase: string;
59
+ ProviderName?: string;
60
+ Results?: SearchResultItem[];
61
+ ElapsedMs?: number;
62
+ ErrorMessage?: string;
63
+ }>;
35
64
  /**
36
65
  * Lightweight preview search for autocomplete/typeahead.
37
66
  * Does NOT update SearchResults$ or IsSearching$ observables,
@@ -74,6 +103,11 @@ export declare class SearchService {
74
103
  private mapClientResponseToSearchResponse;
75
104
  /** Map a single SearchClientResultItem to a SearchResultItem */
76
105
  private mapClientResultItem;
106
+ /**
107
+ * Load the list of search scopes available to the current user.
108
+ * Cached after the first successful call; pass `force=true` to reload.
109
+ */
110
+ LoadScopes(force?: boolean): Promise<SearchScopeInfo[]>;
77
111
  /** Build the client filters from active filter selections */
78
112
  private buildClientFilters;
79
113
  static ɵfac: i0.ɵɵFactoryDeclaration<SearchService, never>;
@@ -1 +1 @@
1
- {"version":3,"file":"search.service.d.ts","sourceRoot":"","sources":["../../src/lib/search.service.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAA4B,MAAM,sBAAsB,CAAC;AASnF,OAAO,EACH,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EAGf,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;;OAEG;IACU,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IAuB3E;;;;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;IAkC7B,OAAO,CAAC,mBAAmB;IAqB3B,OAAO,CAAC,cAAc;IAoBtB;;;OAGG;IACU,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IA6BhD,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,qBAAqB;IAa7B,iFAAiF;IACjF,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,mBAAmB;IAc3B;;OAEG;YACW,oBAAoB;IAwBlC,wFAAwF;IACxF,OAAO,CAAC,iCAAiC;IAsCzC,gEAAgE;IAChE,OAAO,CAAC,mBAAmB;IAuB3B,6DAA6D;IAC7D,OAAO,CAAC,kBAAkB;yCA7YjB,aAAa;6CAAb,aAAa;CAqazB"}
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,EAAE,iBAAiB,EAA4B,MAAM,sBAAsB,CAAC;AASnF,OAAO,EACH,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EAGZ,eAAe,EAClB,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;;;;;;;;;;;;;;;;;OAiBG;IACI,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,UAAU,CAAC;QACpD,KAAK,EAAE,MAAM,CAAC;QACd,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAC;QAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IAuBF;;;;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;IAkC7B,OAAO,CAAC,mBAAmB;IAqB3B,OAAO,CAAC,cAAc;IAoBtB;;;OAGG;IACU,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IA6BhD,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;IAuB3B;;;OAGG;IACU,UAAU,CAAC,KAAK,GAAE,OAAe,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IA4B3E,6DAA6D;IAC7D,OAAO,CAAC,kBAAkB;yCAlejB,aAAa;6CAAb,aAAa;CA0fzB"}
@@ -5,7 +5,8 @@
5
5
  * and transforming raw search responses into display-ready grouped results.
6
6
  */
7
7
  import { Injectable } from '@angular/core';
8
- import { BehaviorSubject, Subject } from 'rxjs';
8
+ import { BehaviorSubject, Subject, throwError } from 'rxjs';
9
+ import { map } from 'rxjs/operators';
9
10
  import { Metadata, StartupManager } from '@memberjunction/core';
10
11
  import { UserInfoEngine } from '@memberjunction/core-entities';
11
12
  import { MJEventType, MJGlobal } from '@memberjunction/global';
@@ -59,6 +60,10 @@ export class SearchService {
59
60
  recentSearchesLoaded = false;
60
61
  /** Cached provider metadata keyed by SourceType, populated from search responses */
61
62
  providersBySourceType = new Map();
63
+ /** Cached list of scopes the current user can see. Populated lazily by `LoadScopes()`. */
64
+ Scopes$ = new BehaviorSubject([]);
65
+ scopesLoaded = false;
66
+ scopesLoadInFlight = null;
62
67
  /**
63
68
  * Execute a search request via the SearchKnowledge GraphQL mutation.
64
69
  */
@@ -83,6 +88,46 @@ export class SearchService {
83
88
  this.IsSearching$.next(false);
84
89
  }
85
90
  }
91
+ /**
92
+ * Phase 2C streaming search. Returns an Observable that emits one
93
+ * notification per provider as it returns, plus a 'fused' / 'reranked'
94
+ * / 'final' terminal event. Same auth + permission behavior as
95
+ * ExecuteSearch — denials surface as an error on the Observable.
96
+ *
97
+ * Consumers (typically the search composite component) should:
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
101
+ * - on error: show the failure message + clear the skeleton
102
+ *
103
+ * Returns rxjs Observable rather than awaiting a Promise — callers
104
+ * decide whether to subscribe + populate state, or unsubscribe on
105
+ * navigation. The service does NOT update its own SearchResults$
106
+ * subject for streaming calls; the caller owns the partial-render
107
+ * state model.
108
+ */
109
+ StreamSearch(request) {
110
+ const provider = Metadata.Provider; // global-provider-ok: streaming search service consumes the GraphQL channel of the global default provider
111
+ if (!(provider instanceof GraphQLDataProvider)) {
112
+ return throwError(() => new Error('GraphQL provider not available'));
113
+ }
114
+ const client = new GraphQLSearchClient(provider);
115
+ const filters = this.buildClientFilters(request);
116
+ const minScore = request.MinScore ?? DEFAULT_MIN_SCORE;
117
+ return client.StreamSearch({
118
+ Query: request.Query,
119
+ MaxResults: request.MaxResults || 20,
120
+ MinScore: minScore > 0 ? minScore : undefined,
121
+ Filters: filters,
122
+ ScopeIDs: request.ScopeIDs && request.ScopeIDs.length > 0 ? request.ScopeIDs : undefined,
123
+ }).pipe(map((ev) => ({
124
+ Phase: ev.Phase,
125
+ ProviderName: ev.ProviderName,
126
+ Results: ev.Results ? ev.Results.map(r => this.mapClientResultItem(r)) : undefined,
127
+ ElapsedMs: ev.ElapsedMs,
128
+ ErrorMessage: ev.ErrorMessage,
129
+ })));
130
+ }
86
131
  /**
87
132
  * Lightweight preview search for autocomplete/typeahead.
88
133
  * Does NOT update SearchResults$ or IsSearching$ observables,
@@ -336,7 +381,8 @@ export class SearchService {
336
381
  Query: request.Query,
337
382
  MaxResults: request.MaxResults || 20,
338
383
  MinScore: minScore > 0 ? minScore : undefined,
339
- Filters: filters
384
+ Filters: filters,
385
+ ScopeIDs: request.ScopeIDs && request.ScopeIDs.length > 0 ? request.ScopeIDs : undefined
340
386
  });
341
387
  return this.mapClientResponseToSearchResponse(clientResponse);
342
388
  }
@@ -397,6 +443,39 @@ export class SearchService {
397
443
  ProviderIcon: r.ProviderIcon,
398
444
  };
399
445
  }
446
+ /**
447
+ * Load the list of search scopes available to the current user.
448
+ * Cached after the first successful call; pass `force=true` to reload.
449
+ */
450
+ async LoadScopes(force = false) {
451
+ if (this.scopesLoaded && !force)
452
+ return this.Scopes$.value;
453
+ if (this.scopesLoadInFlight && !force)
454
+ return this.scopesLoadInFlight;
455
+ const load = (async () => {
456
+ try {
457
+ const provider = Metadata.Provider; // global-provider-ok: scope discovery consumes the GraphQL channel of the global default provider
458
+ if (!(provider instanceof GraphQLDataProvider)) {
459
+ this.Scopes$.next([]);
460
+ return [];
461
+ }
462
+ const client = new GraphQLSearchClient(provider);
463
+ const scopes = await client.GetSearchScopes();
464
+ this.Scopes$.next(scopes);
465
+ this.scopesLoaded = true;
466
+ return scopes;
467
+ }
468
+ catch {
469
+ this.Scopes$.next([]);
470
+ return [];
471
+ }
472
+ finally {
473
+ this.scopesLoadInFlight = null;
474
+ }
475
+ })();
476
+ this.scopesLoadInFlight = load;
477
+ return load;
478
+ }
400
479
  /** Build the client filters from active filter selections */
401
480
  buildClientFilters(request) {
402
481
  if (!request.ActiveFilters || Object.keys(request.ActiveFilters).length === 0) {
@@ -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, Subject } from 'rxjs';\nimport { 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} 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 /**\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 * 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, number>();\n let fileCount = 0;\n for (const r of results) {\n if (r.ResultType === 'storage-file') {\n fileCount++;\n } else {\n counts.set(r.EntityName, (counts.get(r.EntityName) ?? 0) + 1);\n }\n }\n const options: SearchFilterOption[] = Array.from(counts.entries())\n .sort((a, b) => b[1] - a[1])\n .map(([name, count]) => ({\n Label: name,\n Value: name,\n Count: count,\n IsSelected: false,\n 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 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 });\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 return {\n ID: r.ID,\n Title: r.RecordName || r.Title,\n Snippet: r.Snippet,\n EntityName: r.EntityName,\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: r.EntityIcon || r.ProviderIcon || FALLBACK_SOURCE_ICONS[r.SourceType] || 'fa-solid fa-database',\n EntityIcon: r.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 /** 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 { 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} 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, number>();\n let fileCount = 0;\n for (const r of results) {\n if (r.ResultType === 'storage-file') {\n fileCount++;\n } else {\n counts.set(r.EntityName, (counts.get(r.EntityName) ?? 0) + 1);\n }\n }\n const options: SearchFilterOption[] = Array.from(counts.entries())\n .sort((a, b) => b[1] - a[1])\n .map(([name, count]) => ({\n Label: name,\n Value: name,\n Count: count,\n IsSelected: false,\n 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 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 return {\n ID: r.ID,\n Title: r.RecordName || r.Title,\n Snippet: r.Snippet,\n EntityName: r.EntityName,\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: r.EntityIcon || r.ProviderIcon || FALLBACK_SOURCE_ICONS[r.SourceType] || 'fa-solid fa-database',\n EntityIcon: r.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"]}
@@ -6,5 +6,7 @@ export * from './lib/search-filter.component';
6
6
  export * from './lib/search-input.component';
7
7
  export * from './lib/search-suggest.component';
8
8
  export * from './lib/search-composite.component';
9
+ export * from './lib/search-scope-selector.component';
10
+ export * from './lib/search-scope-child-grid.component';
9
11
  export * from './lib/module';
10
12
  //# sourceMappingURL=public-api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAIA,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAIA,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,uCAAuC,CAAC;AACtD,cAAc,yCAAyC,CAAC;AACxD,cAAc,cAAc,CAAC"}
@@ -9,5 +9,7 @@ export * from './lib/search-filter.component';
9
9
  export * from './lib/search-input.component';
10
10
  export * from './lib/search-suggest.component';
11
11
  export * from './lib/search-composite.component';
12
+ export * from './lib/search-scope-selector.component';
13
+ export * from './lib/search-scope-child-grid.component';
12
14
  export * from './lib/module';
13
15
  //# sourceMappingURL=public-api.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"public-api.js","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,cAAc,CAAC","sourcesContent":["/*\n * Public API Surface of @memberjunction/ng-search\n */\n\nexport * from './lib/search-types';\nexport * from './lib/search.service';\nexport * from './lib/search-overlay.component';\nexport * from './lib/search-results.component';\nexport * from './lib/search-filter.component';\nexport * from './lib/search-input.component';\nexport * from './lib/search-suggest.component';\nexport * from './lib/search-composite.component';\nexport * from './lib/module';\n"]}
1
+ {"version":3,"file":"public-api.js","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,uCAAuC,CAAC;AACtD,cAAc,yCAAyC,CAAC;AACxD,cAAc,cAAc,CAAC","sourcesContent":["/*\n * Public API Surface of @memberjunction/ng-search\n */\n\nexport * from './lib/search-types';\nexport * from './lib/search.service';\nexport * from './lib/search-overlay.component';\nexport * from './lib/search-results.component';\nexport * from './lib/search-filter.component';\nexport * from './lib/search-input.component';\nexport * from './lib/search-suggest.component';\nexport * from './lib/search-composite.component';\nexport * from './lib/search-scope-selector.component';\nexport * from './lib/search-scope-child-grid.component';\nexport * from './lib/module';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-search",
3
- "version": "5.32.0",
3
+ "version": "5.34.0",
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",
@@ -27,12 +27,12 @@
27
27
  "@angular/forms": "21.1.3"
28
28
  },
29
29
  "dependencies": {
30
- "@memberjunction/core": "5.32.0",
31
- "@memberjunction/ng-base-types": "5.32.0",
32
- "@memberjunction/global": "5.32.0",
33
- "@memberjunction/graphql-dataprovider": "5.32.0",
34
- "@memberjunction/core-entities": "5.32.0",
35
- "@memberjunction/ng-shared-generic": "5.32.0",
30
+ "@memberjunction/core": "5.34.0",
31
+ "@memberjunction/ng-base-types": "5.34.0",
32
+ "@memberjunction/global": "5.34.0",
33
+ "@memberjunction/graphql-dataprovider": "5.34.0",
34
+ "@memberjunction/core-entities": "5.34.0",
35
+ "@memberjunction/ng-shared-generic": "5.34.0",
36
36
  "rxjs": "^7.8.2",
37
37
  "tslib": "^2.8.1"
38
38
  },