@lde/search-typesense 0.54.0 → 0.55.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.
@@ -91,9 +91,10 @@ export interface CollectionDefinitionOptions {
91
91
  * the display labels; one that opts into `filterable` or `searchable` is
92
92
  * indexed, and its parent object with it (see {@link nestedFields}).
93
93
  *
94
- * An inline reference declaring `filterable` or `facetable` also emits its
95
- * {@link ReferenceStrategy.identity identity companion} – a flat id field the
96
- * engine can filter and facet, which a nested object is not
94
+ * An inline reference naming an {@link ReferenceStrategy.identity identity}
95
+ * filters and facets that identity’s leaf inside each entry, which a nested
96
+ * object is not; a `local` lookup that is `filterable` or `facetable` emits a
97
+ * flat id companion beside its endpoints instead
97
98
  * ({@link identityCompanionFields}).
98
99
  */
99
100
  export declare function buildCollectionDefinition(searchType: SearchType, options?: CollectionDefinitionOptions): CollectionCreateSchema;
@@ -1 +1 @@
1
- {"version":3,"file":"collection-definition.d.ts","sourceRoot":"","sources":["../src/collection-definition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAExD,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AAiBrB,0EAA0E;AAC1E,MAAM,WAAW,2BAA2B;IAC1C;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,MAAM,CAAC;IAChE;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;IAC/B;;;4BAGwB;IACxB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,kEAAkE;IAClE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,kEAAkE;IAClE,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,2BAAgC,GACxC,sBAAsB,CAwCxB"}
1
+ {"version":3,"file":"collection-definition.d.ts","sourceRoot":"","sources":["../src/collection-definition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAExD,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AAiBrB,0EAA0E;AAC1E,MAAM,WAAW,2BAA2B;IAC1C;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,MAAM,CAAC;IAChE;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;IAC/B;;;4BAGwB;IACxB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,kEAAkE;IAClE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,kEAAkE;IAClE,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,2BAAgC,GACxC,sBAAsB,CAuCxB"}
@@ -45,9 +45,10 @@ import { deriveCollectionName } from './collection-name.js';
45
45
  * the display labels; one that opts into `filterable` or `searchable` is
46
46
  * indexed, and its parent object with it (see {@link nestedFields}).
47
47
  *
48
- * An inline reference declaring `filterable` or `facetable` also emits its
49
- * {@link ReferenceStrategy.identity identity companion} – a flat id field the
50
- * engine can filter and facet, which a nested object is not
48
+ * An inline reference naming an {@link ReferenceStrategy.identity identity}
49
+ * filters and facets that identity’s leaf inside each entry, which a nested
50
+ * object is not; a `local` lookup that is `filterable` or `facetable` emits a
51
+ * flat id companion beside its endpoints instead
51
52
  * ({@link identityCompanionFields}).
52
53
  */
53
54
  export function buildCollectionDefinition(searchType, options = {}) {
@@ -56,11 +57,10 @@ export function buildCollectionDefinition(searchType, options = {}) {
56
57
  name: collectionNameFor(searchType),
57
58
  fields: searchType.fields.flatMap((field) => typesenseFields(searchType, field, defaultLocale, options.defaultSortingField, options.schema, collectionNameFor)),
58
59
  };
59
- // A faceted leaf is faceted on its nested path, which Typesense flattens
60
- // into one list per document – so a bucket counts documents, not entries.
61
- const facetedPaths = new Set(facetsOf(searchType, options.schema)
62
- .filter((facet) => facet.reference !== undefined)
63
- .map((facet) => facet.engineField));
60
+ // A faceted leaf, and an inline reference’s identity, are faceted on a
61
+ // nested path, which Typesense flattens into one list per document – so a
62
+ // bucket counts documents, not entries.
63
+ const facetedPaths = new Set(facetsOf(searchType, options.schema).map((facet) => facet.engineField));
64
64
  for (const field of collection.fields) {
65
65
  if (facetedPaths.has(field.name)) {
66
66
  field.facet = true;
@@ -459,30 +459,29 @@ function nestedFields(prefix, reference, nestedType, schema, defaultLocale, with
459
459
  ];
460
460
  }
461
461
  /**
462
- * The **identity companion** of an inline reference: the flat field holding the
463
- * ids its entries reference, which the engine filters and facets in place of
464
- * the nested object it cannot. Empty for an inline reference declaring no
465
- * `identity` – a display-only nesting keeps costing no RAM.
462
+ * The top-level companions of a field storing nested objects: a `local`
463
+ * lookup’s **identity companion**, the flat field holding the ids of its
464
+ * endpoints, which the engine filters and facets in place of the nested object
465
+ * it cannot. An inline reference needs none – it reads its identity’s leaf
466
+ * inside each entry – and a display-only nesting keeps costing no RAM.
466
467
  *
467
- * A second, narrowed field joins it where the target declares a facet policy,
468
+ * A narrowed field joins them where the target declares a facet policy,
468
469
  * exactly as it does for a top-level facetable reference: the facet then reads
469
470
  * the admitted subset, so an excluded id is never seen by the engine rather
470
471
  * than merely unlabelled.
471
472
  */
472
473
  function identityCompanionFields(field, schema) {
473
474
  const names = physicalFields(field, schema);
474
- if (names.identity === undefined) {
475
- return [];
476
- }
477
- const fields = [
478
- {
475
+ const fields = [];
476
+ if (names.identity !== undefined) {
477
+ fields.push({
479
478
  name: names.identity,
480
479
  type: 'string[]',
481
480
  facet: names.facet === names.identity,
482
481
  optional: true,
483
- },
484
- ];
485
- if (names.facet !== undefined && names.facet !== names.identity) {
482
+ });
483
+ }
484
+ if (names.facet !== undefined && names.facet !== names.filter) {
486
485
  fields.push({
487
486
  name: names.facet,
488
487
  type: 'string[]',
package/dist/documents.js CHANGED
@@ -159,7 +159,7 @@ export function assertWritableType(searchType, options) {
159
159
  }
160
160
  else if (options.requireFacetable &&
161
161
  physicalFields(declared, options.schema).facet !== declared.name) {
162
- problems.push('the engine facets a companion in its place – one narrowed by a facet policy inherited from the type it names, or the identity companion of a nested object – while the membership sweep enumerates the indexed datasets by faceting the field itself');
162
+ problems.push('the engine facets a companion in its place – one narrowed by a facet policy inherited from the type it names, or the id leaf of a nested object – while the membership sweep enumerates the indexed datasets by faceting the field itself');
163
163
  }
164
164
  if (problems.length > 0) {
165
165
  throw new Error(`SearchType “${searchType.name}” declares “${declared.name}” over the indexed dataset, which this writer keeps its provenance bookkeeping on, but ${problems.join('; and ')}.`);
@@ -176,7 +176,7 @@ function assertReferencesAndFacetCompanionsPresent(name, fields, facetCompanions
176
176
  if (missingCompanions.length > 0) {
177
177
  throw new Error(`Typesense collection “${name}” exists without the facet field(s) ${missingCompanions
178
178
  .map((companion) => `“${companion}”`)
179
- .join(', ')} its search type facets on in place of the field itself – an identity companion, one narrowed by a facet policy (“facetKeys”), or the nested path of a faceted leaf. A facet field cannot be added to a live collection here: drop “${name}” (and the collections that join to it) and let the next run rebuild them.`);
179
+ .join(', ')} its search type facets on in place of the field itself – the id leaf of a nested object, one narrowed by a facet policy (“facetKeys”), or the nested path of a faceted leaf. A facet field cannot be added to a live collection here: drop “${name}” (and the collections that join to it) and let the next run rebuild them.`);
180
180
  }
181
181
  }
182
182
  /** The fields a type’s facets read instead of the fields themselves – one per
@@ -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,YAAY,EACjB,KAAK,UAAU,EAIhB,MAAM,aAAa,CAAC;AAuBrB;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,MAAM,CAAC,EAAE,YAAY,CAAC;IAC/B;;;;;;;;;;;OAWG;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,CAkCtB;AAikBD;;;;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,YAAY,EACjB,KAAK,UAAU,EAIhB,MAAM,aAAa,CAAC;AAuBrB;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,MAAM,CAAC,EAAE,YAAY,CAAC;IAC/B;;;;;;;;;;;OAWG;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,CAkCtB;AAgkBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvD"}
@@ -433,11 +433,10 @@ function compileWelded(criterion, searchType, schema, prefix) {
433
433
  function compileMembership(field, values, schema, prefix = '') {
434
434
  const list = `[${values.map(escapeFilterValue).join(',')}]`;
435
435
  const names = physicalFields(field, schema);
436
- // An inline reference stores a nested object, which an engine cannot filter.
437
- // Its identity companion is the flat id field standing in for it – so the
438
- // logical name a consumer writes and the physical name the engine reads
439
- // differ here, and only here.
440
- const name = qualify(prefix, names.identity ?? field.name);
436
+ // A field storing a nested object, which an engine cannot filter, is read
437
+ // through an id leaf standing in for it – so the logical name a consumer
438
+ // writes and the physical name the engine reads differ here, and only here.
439
+ const name = qualify(prefix, names.filter);
441
440
  return names.facet === name ? `${name}:${list}` : `${name}:=${list}`;
442
441
  }
443
442
  /** An inclusive Typesense range clause; `UNUSABLE` for a range that ends
package/dist/search.js CHANGED
@@ -79,8 +79,8 @@ export function createTypesenseSearchEngine(client, schema, options = {}) {
79
79
  ...facetsOf(searchType, schema).filter((facet) => facet.reference !== undefined),
80
80
  ]
81
81
  // An INLINE reference names its label target one level in, through
82
- // its identity companion: the companion holds that field's ids, so
83
- // that field's target is what can label them.
82
+ // its identity: the facet counts that field's ids, so that field's
83
+ // target is what can label them.
84
84
  .filter(({ field }) => labelTargetNamesOf(field, schema).length > 0)
85
85
  .map(({ name, field }) => [
86
86
  name,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lde/search-typesense",
3
- "version": "0.54.0",
3
+ "version": "0.55.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.41.3",
28
+ "@lde/search": "^0.42.0",
29
29
  "@lde/text-normalization": "^0.3.0",
30
30
  "tslib": "^2.3.0",
31
31
  "typesense": "^3.2.0"