@lde/search-typesense 0.25.0 → 0.26.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.
@@ -45,7 +45,8 @@ export interface BuildSearchParamsOptions {
45
45
  * usable bound. Skipping keeps a malformed clause from reaching the engine
46
46
  * as garbage; supply this to log it instead of losing it silently. Through
47
47
  * the engine, a structurally invalid query throws up front
48
- * (`assertValidQuery`), so there only the vacuous clauses reach this.
48
+ * (`assertValidQuery`), so there only the clauses that state no constraint
49
+ * reach this.
49
50
  */
50
51
  readonly onIgnoredFilter?: (filter: Filter) => void;
51
52
  }
@@ -1 +1 @@
1
- {"version":3,"file":"query-compiler.d.ts","sourceRoot":"","sources":["../src/query-compiler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AAEzE,OAAO,EAGL,KAAK,MAAM,EACX,KAAK,QAAQ,EAEb,KAAK,WAAW,EAChB,KAAK,UAAU,EAEhB,MAAM,aAAa,CAAC;AAarB;mDACmD;AACnD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,CACvB,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,SAAS,MAAM,EAAE,KACpB,UAAU,GAAG,SAAS,CAAC;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;;;;;;;;OAQG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACrD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,WAAW,EAClB,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,wBAA6B,GACrC,YAAY,CAAC,MAAM,CAAC,CA8BtB;AAsSD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvD"}
1
+ {"version":3,"file":"query-compiler.d.ts","sourceRoot":"","sources":["../src/query-compiler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AAEzE,OAAO,EAGL,KAAK,MAAM,EACX,KAAK,QAAQ,EAEb,KAAK,WAAW,EAChB,KAAK,UAAU,EAEhB,MAAM,aAAa,CAAC;AAarB;mDACmD;AACnD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,CACvB,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,SAAS,MAAM,EAAE,KACpB,UAAU,GAAG,SAAS,CAAC;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;;;;;;;;;OASG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACrD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,WAAW,EAClB,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,wBAA6B,GACrC,YAAY,CAAC,MAAM,CAAC,CA8BtB;AAuTD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvD"}
@@ -134,8 +134,15 @@ function compileFilterBy(where, searchType, options) {
134
134
  * unknown field, an operator that mismatches the field’s kind) is *false*, and
135
135
  * `false || X` is X, so it drops out and its siblings still stand.
136
136
  *
137
- * A clause left with no terms either way is skipped and reported to
138
- * `onIgnoredFilter`.
137
+ * Both readings hold **within** a clause. Neither survives a clause left with
138
+ * no terms: it is skipped and reported to `onIgnoredFilter`, and a clause
139
+ * missing from the conjunction constrains nothing – so a *false* criterion
140
+ * alone in its clause still WIDENS the query. `filter_by` has no term meaning
141
+ * “matches nothing” to compile it to instead. The engine never meets this
142
+ * (`assertValidQuery` rejects every malformed criterion, and `isUnsatisfiable`
143
+ * short-circuits the empty `id` membership before a query is dispatched); a
144
+ * direct caller should read `onIgnoredFilter` firing as “this query no longer
145
+ * asks what you asked”.
139
146
  */
140
147
  function compileFilter(filter, searchType, options) {
141
148
  const terms = [];
@@ -237,11 +244,21 @@ function compileMembership(field, values) {
237
244
  ? `${field.name}:=${list}`
238
245
  : `${field.name}:${list}`;
239
246
  }
240
- /** An inclusive Typesense range clause, or `undefined` when neither bound is set. */
247
+ /** An inclusive Typesense range clause, or `undefined` when neither bound is
248
+ * usable. Which of the two readings that is – the caller set no bounds, or the
249
+ * codec rejected the ones they set – is deliberately NOT decided here: a
250
+ * criterion dropped from a clause narrows the query while a clause dropped
251
+ * from the conjunction widens it, so the same reading cannot be right in both
252
+ * positions. `validateQuery` rejects an unreadable bound outright instead,
253
+ * which is the only answer that neither widens nor narrows. */
241
254
  function compileRange(field, range) {
242
255
  const name = field.name;
243
- const min = storedBound(field, range.min);
244
- const max = storedBound(field, range.max);
256
+ // A bound a caller sent as `null` – a GraphQL variable left unfilled, which
257
+ // the surface passes through – is a bound NOT SET, not a bound of `null`.
258
+ // Read literally it reaches the engine as `datePosted:[null..…]`, which
259
+ // Typesense rejects outright.
260
+ const min = storedBound(field, range.min ?? undefined);
261
+ const max = storedBound(field, range.max ?? undefined);
245
262
  if (min !== undefined && max !== undefined) {
246
263
  return `${name}:[${min}..${max}]`;
247
264
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lde/search-typesense",
3
- "version": "0.25.0",
3
+ "version": "0.26.0",
4
4
  "description": "Typesense implementation of the @lde/search SearchEngine port: collection-schema builder, query compiler, label-resolving result reconstruction, and blue/green index lifecycle. Engine-specific (Typesense) but domain-agnostic.",
5
5
  "repository": {
6
6
  "url": "git+https://github.com/ldelements/lde.git",
@@ -25,7 +25,7 @@
25
25
  "!**/*.tsbuildinfo"
26
26
  ],
27
27
  "dependencies": {
28
- "@lde/search": "^0.22.0",
28
+ "@lde/search": "^0.23.0",
29
29
  "@lde/text-normalization": "^0.1.2",
30
30
  "tslib": "^2.3.0",
31
31
  "typesense": "^3.0.6"