Repository navigation
Conversation
Callers can request verses, topics, and images together. Image hits are id and passageId. Verse and topic hits stay the existing types.
🦋 Changeset detectedLatest commit: 99e5d80 The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Keep the UI barrel aligned with new core runtime exports so check-public-exports passes.
Measured brotlied barrel is 21.55 kB. Set the limit to measured size plus ~10% headroom per CONTRIBUTING.
Default omitted verses/topics/images wire keys to empty arrays, drop invalid image hits per item (structural USFM on passage_id), and replace the runtime field-coverage object with a type-only check.
Use the repo @ts-expect-error pattern for an invalid fields[] value instead of a typed assertion plus SAFETY comment.
Use false instead of never in the false branch so Record<..., true> rejects non-array field mappings.
Wire a vite-react page that calls SearchClient.searchUnified for images alone or with verses, and renders thin hits plus empty/error states.
Results was reading the live Fields control, so flipping mode after an images-only search showed a false empty verses section. Co-authored-by: cameron.b.llewellyn <cameron.b.llewellyn@gmail.com>
Build on PR446 core search with an additive React hook, image-aware coverage, and documented backend availability. Validate request intents and required response fields without requiring images on the wire. Amp-Thread-ID: https://ampcode.com/threads/T-01a15a0f-f2cd-72cf-a270-2102b3d073b2
Set the hooks full-barrel budget to measured 27.044 kB plus approximately 10% headroom, following CONTRIBUTING. Leave all narrow-import budgets unchanged. Amp-Thread-ID: https://ampcode.com/threads/T-01a15a0f-f2cd-72cf-a270-2102b3d073b2
Preserve verse/topic unified search, useUnifiedSearch, and contract validation while deferring Images types, mapping, tests, and smoke page. Amp-Thread-ID: https://ampcode.com/threads/T-01a15a0f-f2cd-72cf-a270-2102b3d073b2
|
request: Could you review the unified-search-only scope on this PR? The Images work has been separated because that API is still beta. All exact-head checks are green. |
Looks like you made the changes in this PR right? |
Yep to use your existing PR and not re-create it |
Cool wanted to make sure before I had the bots review it. |
camrun91
left a comment
There was a problem hiding this comment.
requesting changes. nothing here is a big rewrite, but each item is a rule in this repo or a common practice for public sdk code. details are inline. the main risk is #1: a filtered search can fail if the api leaves out a key.
| export type SearchUnifiedOptions = z.infer<typeof SearchUnifiedOptionsSchema>; | ||
|
|
||
| export const SearchUnifiedWireSchema = z.object({ | ||
| verses: z.array(SearchVerseHitWireSchema), |
There was a problem hiding this comment.
verses and topics are required again. Commit dc951f8 undid the fix for Dustin's blocking comment. If the API leaves out a kind you did not request, fields: ['topics'] throws. user_intent and search_instead_for (lines 289 and 291) have the same problem. The other search schemas make them optional. Make these keys optional, and default them to [] or null. If the API always sends every key, add a live smoke test that proves it, and reply on Dustin's thread.
|
|
||
| export const SearchUnifiedWireSchema = z.object({ | ||
| verses: z.array(SearchVerseHitWireSchema), | ||
| topics: z.array(z.extend(SearchTopicWireSchema, { id: z.nullable(z.int()) })), |
There was a problem hiding this comment.
One bad verse hit or topic makes the whole response fail. The JSDoc says the code removes bad references, but a null reference throws. Parse each hit by itself and drop the hits that fail. #454 needs this for images too.
|
|
||
| export type SearchUnifiedWire = z.infer<typeof SearchUnifiedWireSchema>; | ||
|
|
||
| export const SearchUnifiedResponseSchema = z.object({ |
There was a problem hiding this comment.
#454 adds a required images field to this type. After this PR ships, that change will break the types for consumers, because they build this type in HookOverrides and in mocks. Decide now: add images as an optional field, and write that in the JSDoc.
| error: 'Search field must be verses or topics', | ||
| }); | ||
|
|
||
| const SearchUnifiedFieldsSchema = z.pipe( |
There was a problem hiding this comment.
fields and languageRanges do not accept readonly arrays. fields: ['topics'] as const does not compile. Use readonly SearchUnifiedField[] and string | readonly string[], as useBibleSearch does. Please do the same in the hook props.
| import { useSearchClient } from './useSearchClient'; | ||
| import type { UseQueryResult } from './useQueryResult'; | ||
|
|
||
| export type UseUnifiedSearchProps = Readonly< |
There was a problem hiding this comment.
These props have no JSDoc. Add JSDoc for each prop. Include the 1 to 100 character limit, the versionId to bible_id mapping, and how the code normalizes language ranges. Also say that fields must not be empty. review-guidelines.md requires this for public props.
| 'fields[]'?: SearchUnifiedField[]; | ||
| }; | ||
|
|
||
| export async function searchUnified( |
There was a problem hiding this comment.
This exported function has no JSDoc. Add JSDoc, as SearchClient.searchUnified has.
| [...keyBase, 'searchUnified', query, versionId, languageRanges, userIntent, fields], | ||
| () => client.searchUnified(query, versionId, languageRanges, { userIntent, fields }), | ||
| { | ||
| enabled: !override && apiOptions?.enabled !== false, |
There was a problem hiding this comment.
The hook sends a request when the query is empty, and it returns a validation error. useBibleSearch turns itself off for an invalid query. Do the same here: enable the query only when the trimmed query and the language ranges are valid. Then remove the enabled workaround from the README.
| parseUsfmReference, | ||
| removeStorageItem, | ||
| searchTopics, | ||
| searchUnified, |
There was a problem hiding this comment.
This line adds a public export, but no changeset lists @youversion/platform-react-ui. The UI changelog will not show it. Add a minor changeset for the UI package. CONTRIBUTING requires changesets for new features.
| { versionId: 2 }, | ||
| { languageRanges: ['es'] }, | ||
| { fields: ['topics'] }, | ||
| { userIntent: 'topical' }, |
There was a problem hiding this comment.
This test checks only the final data after an input changes. ADR 0006 says the hook keeps the previous data and shows loading: true while the new query loads. docs/testing.md says tests must check this middle state. Make the stub wait until the test releases it. Check the previous data with loading: true, then release the stub.
Summary
Add the live unified-search endpoint to core and React hooks so apps can load top verse references and related topics in one unpaginated request. Existing search methods and the Bible reader flow stay unchanged.
Scope
searchUnified,SearchClient.searchUnified,useUnifiedSearch, and their public types.Verification
Hold merge until Cam authorizes it. YPE-6188 / YPE-6182.


Confidence Score: 5/5
The code appears safe to merge once Cam authorizes it.Summary
Adds
searchUnifiedanduseUnifiedSearchfor one unpaginated request returning verse references and related topics.Diagram
Reviews (9) · Last reviewed commit: "Merge branch 'main' into caml/ype-6188-s..." · Reviewed by Greptile