MCPcopy
hub / github.com/angular/angular / Search

Class Search

adev/shared-docs/services/search.service.ts:44–217  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

42
43@Service()
44export class Search {
45 readonly searchQuery = signal('');
46
47 private readonly config = inject(ENVIRONMENT);
48 private readonly client = inject(ALGOLIA_CLIENT);
49
50 debounceParams = debounced(this.searchQuery, SEARCH_DELAY);
51
52 readonly resultsResource = resource({
53 params: () => this.debounceParams.value() || undefined, // coerces empty string to undefined
54 loader: async ({params}) => this.searchWithQuery(params),
55 });
56
57 readonly searchResults = linkedSignal<SearchResultItem[] | undefined, SearchResultItem[]>({
58 source: this.resultsResource.value,
59 computation: (next, prev) => (!next && this.searchQuery() ? prev?.value : next) ?? [],
60 });
61
62 private getUniqueSearchResultItems(items: SearchResult[]): SearchResult[] {
63 const uniqueUrls = new Set<string>();
64
65 return items.filter((item) => {
66 if (item.type === 'content' && !item._snippetResult.content) {
67 return false;
68 }
69 // Ensure that this result actually matched on the type.
70 // If not, this is going to be a duplicate. There should be another result in
71 // the list that already matched on its type.
72 // A lvl2 match will also return all its lvl3 results as well, even if those
73 // values don't also match the query.
74 if (
75 item.type.indexOf('lvl') === 0 &&
76 item._snippetResult.hierarchy?.[item.type as 'lvl1']?.matchLevel === 'none'
77 ) {
78 return false;
79 }
80
81 if (item['url'] && typeof item['url'] === 'string' && !uniqueUrls.has(item['url'])) {
82 uniqueUrls.add(item['url']);
83 return true;
84 }
85 return false;
86 });
87 }
88
89 private parseResult(response: SearchResponses<unknown>): SearchResultItem[] | undefined {
90 if (!response) {
91 return;
92 }
93
94 const result: AlgoliaSearchResult = response.results[0];
95 if (!result || !('hits' in result)) {
96 return;
97 }
98
99 const items = result.hits as unknown as SearchResult[];
100
101 return this.getUniqueSearchResultItems(items).map((hitItem: SearchResult): SearchResultItem => {

Callers

nothing calls this directly

Calls 7

searchWithQueryMethod · 0.95
signalFunction · 0.90
injectFunction · 0.90
debouncedFunction · 0.90
resourceFunction · 0.90
linkedSignalFunction · 0.90
valueMethod · 0.65

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…