@lde/search 0.2.0 → 0.3.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.
package/README.md CHANGED
@@ -285,6 +285,14 @@ result.hits[0].document.title; // typed: only DATASET’s output fields are keys
285
285
  await engine.search(OTHER_TYPE, query); // compile error: not in this schema
286
286
  ```
287
287
 
288
+ `searchFacets(type, queries)` is the port’s **batch entry point**: several
289
+ facet-only queries – e.g. a faceted sidebar’s skip-own-filter variants –
290
+ answered in one engine round-trip (Typesense: a single `multi_search`), one
291
+ outcome per query, positionally aligned – its facet map, or an in-place error,
292
+ so one failed query never discards its siblings’ facets. The same schema
293
+ binding, per-query validation and typed facet keys apply to every query in
294
+ the batch.
295
+
288
296
  This only works when the types were declared with `defineSearchType` (or
289
297
  captured `as const satisfies SearchType`) and composed with `searchSchema()`;
290
298
  a plain `: SearchSchema` annotation widens gracefully to string keys.
package/dist/engine.d.ts CHANGED
@@ -35,7 +35,37 @@ export interface SearchEngine<Types extends readonly SearchType[] = readonly Sea
35
35
  * a caller can enumerate the searchable types. */
36
36
  readonly schema: SearchSchema<Types>;
37
37
  search<T extends Types[number]>(searchType: T, query: SearchQuery): Promise<SearchResult<FacetFieldsOf<T>, OutputFieldsOf<T>>>;
38
+ /**
39
+ * The batch entry point: answer several facet-only queries against one type
40
+ * in a single engine round-trip (where the engine supports one, e.g.
41
+ * Typesense `multi_search`), returning one {@link FacetsOutcome} per query,
42
+ * positionally aligned with `queries`. This is what keeps a faceted
43
+ * sidebar – one skip-own-filter query variant per filtered facet – from
44
+ * fanning out into per-facet engine calls. Only facet buckets come back: an
45
+ * engine answers every query in the batch facet-only (as if `limit: 0` and
46
+ * without ordering, whatever the query carries), so hits are never
47
+ * transferred. Reference-facet buckets carry resolved labels exactly as in
48
+ * {@link search}. A failure of one query is reported in place
49
+ * (`{ error }`) rather than by rejecting, so it never discards its
50
+ * siblings’ facets; the returned promise rejects only for batch-level
51
+ * failures (a foreign `searchType`, a structurally invalid query, the
52
+ * transport itself). The port contract holds for every query in the batch;
53
+ * an empty `queries` resolves to `[]` without touching the engine.
54
+ */
55
+ searchFacets<T extends Types[number]>(searchType: T, queries: readonly SearchQuery[]): Promise<readonly FacetsOutcome<FacetFieldsOf<T>>[]>;
38
56
  }
57
+ /**
58
+ * One query’s outcome in a {@link SearchEngine.searchFacets} batch – its
59
+ * facet buckets, or the error that failed it. The `allSettled`-style shape
60
+ * keeps one failed query (e.g. one failed `multi_search` entry) from
61
+ * discarding its siblings’ results: a caller degrades exactly the facets of
62
+ * the failed query. Discriminate with `'error' in outcome`.
63
+ */
64
+ export type FacetsOutcome<FacetField extends string = string> = {
65
+ readonly facets: FacetMap<FacetField>;
66
+ } | {
67
+ readonly error: unknown;
68
+ };
39
69
  /** What an engine returns: logical hits, a total, and the requested facets. */
40
70
  export interface SearchResult<FacetField extends string = string, OutputField extends string = string> {
41
71
  readonly hits: readonly SearchHit<OutputField>[];
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -3,6 +3,6 @@ export type { SearchDocument } from './project.js';
3
3
  export { defineSearchType, searchSchema, validateSearchType, assertValidSearchType, } from './schema.js';
4
4
  export type { FieldKind, SearchField, SearchFieldBase, TextField, KeywordField, ReferenceField, NumericField, BooleanField, SearchType, SearchTypeIssue, SearchSchema, FacetRange, } from './schema.js';
5
5
  export type { SearchQuery, Filter, Sort } from './query.js';
6
- export type { SearchEngine, SearchResult, SearchHit, ResultDocument, SearchValue, LocalizedValue, Reference, FacetBucket, FacetMap, FacetFieldsOf, OutputFieldsOf, } from './engine.js';
6
+ export type { SearchEngine, SearchResult, SearchHit, ResultDocument, SearchValue, LocalizedValue, Reference, FacetBucket, FacetMap, FacetsOutcome, FacetFieldsOf, OutputFieldsOf, } from './engine.js';
7
7
  export type { FramedNode } from './frame-by-type.js';
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAChF,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAKnD,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,SAAS,EACT,WAAW,EACX,eAAe,EACf,SAAS,EACT,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,eAAe,EACf,YAAY,EACZ,UAAU,GACX,MAAM,aAAa,CAAC;AAIrB,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAI5D,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,cAAc,EACd,WAAW,EACX,cAAc,EACd,SAAS,EACT,WAAW,EACX,QAAQ,EACR,aAAa,EACb,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAChF,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAKnD,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,SAAS,EACT,WAAW,EACX,eAAe,EACf,SAAS,EACT,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,eAAe,EACf,YAAY,EACZ,UAAU,GACX,MAAM,aAAa,CAAC;AAIrB,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAI5D,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,cAAc,EACd,WAAW,EACX,cAAc,EACd,SAAS,EACT,WAAW,EACX,QAAQ,EACR,aAAa,EACb,aAAa,EACb,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/testing.d.ts CHANGED
@@ -5,8 +5,8 @@ import type { SearchEngine } from './engine.js';
5
5
  * live instance of itself, so the port rules hold by test rather than by
6
6
  * prose. Covers schema binding (a type outside the bound schema is rejected),
7
7
  * the always-on query validation (a structurally invalid query is rejected
8
- * before it reaches the engine) and the result shape of a browse query — for
9
- * every type in the schema.
8
+ * before it reaches the engine) and the result shape of a browse query and a
9
+ * `searchFacets` batch – for every type in the schema.
10
10
  *
11
11
  * ```ts
12
12
  * describeSearchEngineContract('TypesenseSearchEngine', () => engine);
@@ -1 +1 @@
1
- {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAShD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,YAAY,GACzB,IAAI,CAqFN"}
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAahD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,YAAY,GACzB,IAAI,CAsJN"}
package/dist/testing.js CHANGED
@@ -1,14 +1,14 @@
1
1
  import { describe, expect, it } from 'vitest';
2
2
  import { filterOperatorFor, } from './query.js';
3
- import { filterableFields } from './schema.js';
3
+ import { facetableFields, filterableFields, } from './schema.js';
4
4
  /**
5
5
  * The executable {@link SearchEngine} port contract (import from
6
6
  * `@lde/search/testing`): a vitest suite every engine adapter runs against a
7
7
  * live instance of itself, so the port rules hold by test rather than by
8
8
  * prose. Covers schema binding (a type outside the bound schema is rejected),
9
9
  * the always-on query validation (a structurally invalid query is rejected
10
- * before it reaches the engine) and the result shape of a browse query — for
11
- * every type in the schema.
10
+ * before it reaches the engine) and the result shape of a browse query and a
11
+ * `searchFacets` batch – for every type in the schema.
12
12
  *
13
13
  * ```ts
14
14
  * describeSearchEngineContract('TypesenseSearchEngine', () => engine);
@@ -75,6 +75,59 @@ export function describeSearchEngineContract(name, engine) {
75
75
  await expect(engine().search(searchType, query)).rejects.toThrow(/operator-mismatch/);
76
76
  }
77
77
  });
78
+ it('rejects a searchFacets batch for a type outside its schema', async () => {
79
+ const foreign = {
80
+ name: 'NotInSchema',
81
+ type: 'urn:test:not-in-schema',
82
+ fields: [],
83
+ };
84
+ await expect(engine().searchFacets(foreign, [browse(foreign)])).rejects.toThrow(/not in this engine/);
85
+ });
86
+ it('rejects a structurally invalid query anywhere in a searchFacets batch', async () => {
87
+ for (const searchType of types()) {
88
+ const queries = [
89
+ { ...browse(searchType), limit: 0 },
90
+ {
91
+ ...browse(searchType),
92
+ limit: 0,
93
+ facets: ['fieldThatDoesNotExist'],
94
+ },
95
+ ];
96
+ await expect(engine().searchFacets(searchType, queries)).rejects.toThrow(/unknown-field/);
97
+ }
98
+ });
99
+ it('answers a searchFacets batch with one facets outcome per query, positionally', async () => {
100
+ for (const searchType of types()) {
101
+ const facets = facetableFields(searchType).map((field) => field.name);
102
+ const queries = [
103
+ { ...browse(searchType), limit: 0, facets },
104
+ // Facet-only regardless of the limit the query carries: this one
105
+ // keeps its non-zero browse limit and must be answered the same.
106
+ { ...browse(searchType), facets: [] },
107
+ ];
108
+ const outcomes = await engine().searchFacets(searchType, queries);
109
+ expect(outcomes).toHaveLength(queries.length);
110
+ for (const outcome of outcomes) {
111
+ // A valid query in a healthy engine yields facets, not an error.
112
+ expect('error' in outcome ? outcome.error : undefined).toBe(undefined);
113
+ if ('error' in outcome) {
114
+ continue;
115
+ }
116
+ expect(outcome.facets).toBeTypeOf('object');
117
+ for (const buckets of Object.values(outcome.facets)) {
118
+ for (const bucket of buckets ?? []) {
119
+ expect(typeof bucket.value).toBe('string');
120
+ expect(typeof bucket.count).toBe('number');
121
+ }
122
+ }
123
+ }
124
+ }
125
+ });
126
+ it('resolves an empty searchFacets batch to an empty list', async () => {
127
+ for (const searchType of types()) {
128
+ await expect(engine().searchFacets(searchType, [])).resolves.toEqual([]);
129
+ }
130
+ });
78
131
  it('answers a browse query with hits, a total and facets', async () => {
79
132
  for (const searchType of types()) {
80
133
  const result = await engine().search(searchType, browse(searchType));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lde/search",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Engine- and domain-agnostic core for RDF-backed search: a unified declarative field model (SearchField/SearchType/SearchSchema), a neutral query IR, the SearchEngine port with logical result types, and a streaming CONSTRUCT-to-document projection. Bakes in no engine, protocol, or domain.",
5
5
  "repository": {
6
6
  "url": "git+https://github.com/ldelements/lde.git",