@lde/search-typesense 0.7.0 → 0.8.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
@@ -4,14 +4,14 @@
4
4
  domain-agnostic [`@lde/search`](../search) core. **Engine-specific (Typesense) but
5
5
  domain-agnostic** – you supply a `SearchType`; this package never names your
6
6
  domain. It is the Typesense implementation of the `SearchEngine` port: it derives
7
- a collection schema from the field model, compiles the neutral `SearchQuery` into
7
+ a collection definition from the field model, compiles the neutral `SearchQuery` into
8
8
  Typesense search params, runs it, reconstructs the engine-neutral `SearchResult`,
9
9
  and manages the search index lifecycle as transactional `@lde/pipeline`
10
10
  writers (Blue/green Rebuild and In-place Rebuild).
11
11
 
12
12
  ## Collection schema and engine
13
13
 
14
- `buildCollectionSchema(searchType, { name, defaultSortingField, … })` derives a
14
+ `buildCollectionDefinition(searchType, { name, defaultSortingField, … })` derives a
15
15
  Typesense collection from the unified `SearchField` model — the Typesense field
16
16
  type comes from each field’s `kind`, and the physical fanout (per-locale
17
17
  search/sort keys) matches what the projection writes, via
@@ -20,7 +20,7 @@ search/sort keys) matches what the projection writes, via
20
20
  **Memory lever.** Typesense keeps the index in RAM (with a raw copy of each
21
21
  document on disk), so RAM tracks the _indexed_ surface – roughly 2–3× the size
22
22
  of the fields you search, facet or sort on – not the full document.
23
- `buildCollectionSchema` keeps that surface minimal: the `output` display labels
23
+ `buildCollectionDefinition` keeps that surface minimal: the `output` display labels
24
24
  fan out to `index: false` fields, stored on disk and fetched only for a hit, so
25
25
  they cost no RAM; only the folded `*_search_${locale}`, facet/reference and
26
26
  `*_sort_${locale}` companions are indexed. Keeping retrieval-only fields
@@ -67,9 +67,9 @@ Indexing runs through two transactional writers, one per update mode – the
67
67
  Both implement `@lde/pipeline`’s `Writer` – each run is
68
68
  `openRun(context)` → `write` per dataset → `commit()` or `abort(error)` – so
69
69
  an `@lde/pipeline` `Pipeline` drives them without branching on the mode. Both
70
- derive the collection schema from your `SearchType` (via
71
- `buildCollectionSchema`), and their options accept everything
72
- `buildCollectionSchema` does (`defaultLocale`, `defaultSortingField`,
70
+ derive the collection definition from your `SearchType` (via
71
+ `buildCollectionDefinition`), and their options accept everything
72
+ `buildCollectionDefinition` does (`defaultLocale`, `defaultSortingField`,
73
73
  `synonymSets`) plus the tuning knobs (`batchSize`, `lockTtlMs`).
74
74
 
75
75
  ### Blue/green Rebuild
@@ -2,7 +2,7 @@ import type { Client } from 'typesense';
2
2
  import type { SearchType } from '@lde/search';
3
3
  import type { RunContext, RunWriter, Writer } from '@lde/pipeline';
4
4
  import { type RebuildOptions } from './rebuild-support.js';
5
- /** {@link BlueGreenRebuild} options: the collection-schema options (`name` is
5
+ /** {@link BlueGreenRebuild} options: the collection-definition options (`name` is
6
6
  * the logical index name the alias is kept on) plus the rebuild tuning knobs. */
7
7
  export type BlueGreenRebuildOptions = RebuildOptions;
8
8
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"blue-green-rebuild.d.ts","sourceRoot":"","sources":["../src/blue-green-rebuild.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAEV,UAAU,EACV,SAAS,EACT,MAAM,EACP,MAAM,eAAe,CAAC;AAMvB,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,sBAAsB,CAAC;AAE9B;kFACkF;AAClF,MAAM,MAAM,uBAAuB,GAAG,cAAc,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,gBAAgB,CAC3B,SAAS,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAChC,YAAW,MAAM,CAAC,SAAS,CAAC;IAE1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAFP,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,uBAAuB;IAM7C,OAAO,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IA2FjE,4EAA4E;YAC9D,WAAW;CAW1B"}
1
+ {"version":3,"file":"blue-green-rebuild.d.ts","sourceRoot":"","sources":["../src/blue-green-rebuild.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAEV,UAAU,EACV,SAAS,EACT,MAAM,EACP,MAAM,eAAe,CAAC;AAMvB,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,sBAAsB,CAAC;AAE9B;kFACkF;AAClF,MAAM,MAAM,uBAAuB,GAAG,cAAc,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,gBAAgB,CAC3B,SAAS,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAChC,YAAW,MAAM,CAAC,SAAS,CAAC;IAE1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAFP,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,uBAAuB;IAM7C,OAAO,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IA6FjE,4EAA4E;YAC9D,WAAW;CAW1B"}
@@ -1,4 +1,4 @@
1
- import { buildCollectionSchema } from './collection-schema.js';
1
+ import { buildCollectionDefinition } from './collection-definition.js';
2
2
  import { BatchImporter } from './import.js';
3
3
  import { httpStatus, openLockedRun, releaseLock } from './lock.js';
4
4
  import { SOURCE_FIELD, sourceDocumentsFilter } from './sweep.js';
@@ -42,19 +42,19 @@ export class BlueGreenRebuild {
42
42
  assertNoReservedFields(searchType, [SOURCE_FIELD]);
43
43
  }
44
44
  async openRun(context) {
45
- const { name, batchSize, lockTtlMs, schemaOptions } = resolveRebuildOptions(this.options);
45
+ const { name, batchSize, lockTtlMs, definitionOptions } = resolveRebuildOptions(this.options);
46
46
  return openLockedRun(this.client, name, lockTtlMs, async () => {
47
47
  // Create the fresh (blue) collection up front, so a failure surfaces
48
48
  // before any dataset is processed. startedAt orders the versioned names;
49
49
  // concurrent same-name runs are excluded by the lock.
50
50
  const collection = `${name}_${Date.parse(context.startedAt)}`;
51
51
  const previous = await this.aliasTarget(name);
52
- const schema = buildCollectionSchema(this.searchType, schemaOptions);
52
+ const definition = buildCollectionDefinition(this.searchType, definitionOptions);
53
53
  await this.client.collections().create({
54
- ...schema,
54
+ ...definition,
55
55
  name: collection,
56
56
  fields: [
57
- ...(schema.fields ?? []),
57
+ ...(definition.fields ?? []),
58
58
  { name: SOURCE_FIELD, type: 'string' },
59
59
  ],
60
60
  });
@@ -1,7 +1,7 @@
1
1
  import type { CollectionCreateSchema } from 'typesense';
2
2
  import { type SearchType } from '@lde/search';
3
3
  /** Deployment-specific options the generic field model does not carry. */
4
- export interface CollectionSchemaOptions {
4
+ export interface CollectionDefinitionOptions {
5
5
  /** The Typesense collection (or alias) name. */
6
6
  readonly name: string;
7
7
  /** Snowball stemming locale for non-localized searchable fields (e.g. `en`).
@@ -15,7 +15,7 @@ export interface CollectionSchemaOptions {
15
15
  readonly synonymSets?: readonly string[];
16
16
  }
17
17
  /**
18
- * Build a Typesense collection schema from the unified {@link SearchType}, so
18
+ * Build a Typesense collection definition from the unified {@link SearchType}, so
19
19
  * the index and the projection are driven by one declarative source and cannot
20
20
  * drift. Each field fans out into the same physical fields the projection writes
21
21
  * ({@link physicalFields}); the Typesense field type is derived from the field
@@ -35,5 +35,5 @@ export interface CollectionSchemaOptions {
35
35
  * `*_sort_${locale}` companions are indexed. Keeping retrieval-only fields
36
36
  * un-indexed is the lever for holding a large index’s RAM down.
37
37
  */
38
- export declare function buildCollectionSchema(searchType: SearchType, options: CollectionSchemaOptions): CollectionCreateSchema;
39
- //# sourceMappingURL=collection-schema.d.ts.map
38
+ export declare function buildCollectionDefinition(searchType: SearchType, options: CollectionDefinitionOptions): CollectionCreateSchema;
39
+ //# sourceMappingURL=collection-definition.d.ts.map
@@ -0,0 +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,EAAoB,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAGhE,0EAA0E;AAC1E,MAAM,WAAW,2BAA2B;IAC1C,gDAAgD;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;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;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,2BAA2B,GACnC,sBAAsB,CAexB"}
@@ -1,6 +1,6 @@
1
1
  import { physicalFields } from '@lde/search/adapter';
2
2
  /**
3
- * Build a Typesense collection schema from the unified {@link SearchType}, so
3
+ * Build a Typesense collection definition from the unified {@link SearchType}, so
4
4
  * the index and the projection are driven by one declarative source and cannot
5
5
  * drift. Each field fans out into the same physical fields the projection writes
6
6
  * ({@link physicalFields}); the Typesense field type is derived from the field
@@ -20,7 +20,7 @@ import { physicalFields } from '@lde/search/adapter';
20
20
  * `*_sort_${locale}` companions are indexed. Keeping retrieval-only fields
21
21
  * un-indexed is the lever for holding a large index’s RAM down.
22
22
  */
23
- export function buildCollectionSchema(searchType, options) {
23
+ export function buildCollectionDefinition(searchType, options) {
24
24
  const { defaultLocale } = options;
25
25
  const collection = {
26
26
  name: options.name,
@@ -1 +1 @@
1
- {"version":3,"file":"in-place-rebuild.d.ts","sourceRoot":"","sources":["../src/in-place-rebuild.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,KAAK,EAEV,UAAU,EACV,SAAS,EACT,MAAM,EACP,MAAM,eAAe,CAAC;AAYvB,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,sBAAsB,CAAC;AAa9B;gCACgC;AAChC,MAAM,WAAW,qBAAsB,SAAQ,cAAc;IAC3D;sEACkE;IAClE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;CACvC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,qBAAa,cAAc,CACzB,SAAS,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAChC,YAAW,MAAM,CAAC,SAAS,CAAC;IAE1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAFP,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,qBAAqB;IAK3C,OAAO,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAuFjE;;;;;;OAMG;YACW,cAAc;CAsB7B"}
1
+ {"version":3,"file":"in-place-rebuild.d.ts","sourceRoot":"","sources":["../src/in-place-rebuild.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,KAAK,EAEV,UAAU,EACV,SAAS,EACT,MAAM,EACP,MAAM,eAAe,CAAC;AAYvB,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,sBAAsB,CAAC;AAa9B;gCACgC;AAChC,MAAM,WAAW,qBAAsB,SAAQ,cAAc;IAC3D;sEACkE;IAClE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;CACvC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,qBAAa,cAAc,CACzB,SAAS,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAChC,YAAW,MAAM,CAAC,SAAS,CAAC;IAE1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAFP,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,qBAAqB;IAK3C,OAAO,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IA0FjE;;;;;;OAMG;YACW,cAAc;CAsB7B"}
@@ -1,4 +1,4 @@
1
- import { buildCollectionSchema } from './collection-schema.js';
1
+ import { buildCollectionDefinition } from './collection-definition.js';
2
2
  import { BatchImporter } from './import.js';
3
3
  import { ensureCollectionExists, openLockedRun, releaseLock } from './lock.js';
4
4
  import { LAST_SEEN_FIELD, SOURCE_FIELD, departedSources, membershipSweepFilters, staleDocumentsFilter, thisRunDocumentsFilter, } from './sweep.js';
@@ -58,20 +58,20 @@ export class InPlaceRebuild {
58
58
  }
59
59
  async openRun(context) {
60
60
  const { maxSweepableSources = DEFAULT_MAX_SWEEPABLE_SOURCES, ...rebuildOptions } = this.options;
61
- const { name, batchSize, lockTtlMs, schemaOptions } = resolveRebuildOptions(rebuildOptions);
61
+ const { name, batchSize, lockTtlMs, definitionOptions } = resolveRebuildOptions(rebuildOptions);
62
62
  return openLockedRun(this.client, name, lockTtlMs, async () => {
63
63
  // Create the collection on demand: SearchType schema + the bookkeeping
64
64
  // fields, `source` faceted so the membership sweep can enumerate the
65
65
  // distinct sources.
66
66
  await ensureCollectionExists(this.client, name, () => {
67
- const schema = buildCollectionSchema(this.searchType, schemaOptions);
67
+ const definition = buildCollectionDefinition(this.searchType, definitionOptions);
68
68
  const bookkeeping = [
69
69
  { name: SOURCE_FIELD, type: 'string', facet: true },
70
70
  { name: LAST_SEEN_FIELD, type: 'string' },
71
71
  ];
72
72
  return {
73
- ...schema,
74
- fields: [...(schema.fields ?? []), ...bookkeeping],
73
+ ...definition,
74
+ fields: [...(definition.fields ?? []), ...bookkeeping],
75
75
  };
76
76
  });
77
77
  const importer = new BatchImporter(this.client, name, batchSize);
package/dist/index.d.ts CHANGED
@@ -4,8 +4,8 @@ export { InPlaceRebuild } from './in-place-rebuild.js';
4
4
  export type { InPlaceRebuildOptions } from './in-place-rebuild.js';
5
5
  export { RebuildAlreadyRunning } from './lock.js';
6
6
  export { departedSources, membershipSweepFilters, sourceDocumentsFilter, staleDocumentsFilter, } from './sweep.js';
7
- export { buildCollectionSchema } from './collection-schema.js';
8
- export type { CollectionSchemaOptions } from './collection-schema.js';
7
+ export { buildCollectionDefinition } from './collection-definition.js';
8
+ export type { CollectionDefinitionOptions } from './collection-definition.js';
9
9
  export { buildSearchParams } from './query-compiler.js';
10
10
  export type { BuildSearchParamsOptions } from './query-compiler.js';
11
11
  export { createTypesenseSearchEngine, parseSearchResponse } from './search.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,YAAY,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,YAAY,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC/E,YAAY,EACV,4BAA4B,EAC5B,uBAAuB,GACxB,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,YAAY,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,YAAY,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC/E,YAAY,EACV,4BAA4B,EAC5B,uBAAuB,GACxB,MAAM,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -2,6 +2,6 @@ export { BlueGreenRebuild } from './blue-green-rebuild.js';
2
2
  export { InPlaceRebuild } from './in-place-rebuild.js';
3
3
  export { RebuildAlreadyRunning } from './lock.js';
4
4
  export { departedSources, membershipSweepFilters, sourceDocumentsFilter, staleDocumentsFilter, } from './sweep.js';
5
- export { buildCollectionSchema } from './collection-schema.js';
5
+ export { buildCollectionDefinition } from './collection-definition.js';
6
6
  export { buildSearchParams } from './query-compiler.js';
7
7
  export { createTypesenseSearchEngine, parseSearchResponse } from './search.js';
@@ -1,23 +1,23 @@
1
1
  import type { Client } from 'typesense';
2
2
  import type { SearchType } from '@lde/search';
3
- import type { CollectionSchemaOptions } from './collection-schema.js';
3
+ import type { CollectionDefinitionOptions } from './collection-definition.js';
4
4
  /**
5
- * The tuning knobs both rebuild writers share, on top of the collection-schema
5
+ * The tuning knobs both rebuild writers share, on top of the collection-definition
6
6
  * options. Each writer may add its own (In-place adds `maxSweepableSources`).
7
7
  */
8
- export interface RebuildOptions extends CollectionSchemaOptions {
8
+ export interface RebuildOptions extends CollectionDefinitionOptions {
9
9
  /** Documents imported per Typesense request (default 1000). */
10
10
  readonly batchSize?: number;
11
11
  /** A held lock older than this (ms) is reclaimed (default 10 minutes). */
12
12
  readonly lockTtlMs?: number;
13
13
  }
14
14
  /** The shared options resolved to concrete values plus the residual
15
- * collection-schema options a writer passes to {@link buildCollectionSchema}. */
15
+ * collection-definition options a writer passes to {@link buildCollectionDefinition}. */
16
16
  export interface ResolvedRebuildOptions {
17
17
  readonly name: string;
18
18
  readonly batchSize: number;
19
19
  readonly lockTtlMs: number;
20
- readonly schemaOptions: CollectionSchemaOptions;
20
+ readonly definitionOptions: CollectionDefinitionOptions;
21
21
  }
22
22
  /** Apply the shared defaults, once, so neither writer restates them. */
23
23
  export declare function resolveRebuildOptions(options: RebuildOptions): ResolvedRebuildOptions;
@@ -1 +1 @@
1
- {"version":3,"file":"rebuild-support.d.ts","sourceRoot":"","sources":["../src/rebuild-support.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAItE;;;GAGG;AACH,MAAM,WAAW,cAAe,SAAQ,uBAAuB;IAC7D,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,0EAA0E;IAC1E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;kFACkF;AAClF,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,uBAAuB,CAAC;CACjD;AAED,wEAAwE;AACxE,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,cAAc,GACtB,sBAAsB,CAOxB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,SAAS,MAAM,EAAE,GAC1B,IAAI,CAWN;AAED,4EAA4E;AAC5E,wBAAuB,cAAc,CAAC,SAAS,EAC7C,SAAS,EAAE,aAAa,CAAC,SAAS,CAAC,EACnC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GACtC,aAAa,CAAC,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAInD;AAED,mEAAmE;AACnE,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAKf"}
1
+ {"version":3,"file":"rebuild-support.d.ts","sourceRoot":"","sources":["../src/rebuild-support.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAI9E;;;GAGG;AACH,MAAM,WAAW,cAAe,SAAQ,2BAA2B;IACjE,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,0EAA0E;IAC1E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;0FAC0F;AAC1F,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,iBAAiB,EAAE,2BAA2B,CAAC;CACzD;AAED,wEAAwE;AACxE,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,cAAc,GACtB,sBAAsB,CAYxB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,SAAS,MAAM,EAAE,GAC1B,IAAI,CAWN;AAED,4EAA4E;AAC5E,wBAAuB,cAAc,CAAC,SAAS,EAC7C,SAAS,EAAE,aAAa,CAAC,SAAS,CAAC,EACnC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GACtC,aAAa,CAAC,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAInD;AAED,mEAAmE;AACnE,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAKf"}
@@ -2,8 +2,13 @@ import { DEFAULT_LOCK_TTL_MS } from './lock.js';
2
2
  import { DEFAULT_BATCH_SIZE } from './import.js';
3
3
  /** Apply the shared defaults, once, so neither writer restates them. */
4
4
  export function resolveRebuildOptions(options) {
5
- const { batchSize = DEFAULT_BATCH_SIZE, lockTtlMs = DEFAULT_LOCK_TTL_MS, ...schemaOptions } = options;
6
- return { name: schemaOptions.name, batchSize, lockTtlMs, schemaOptions };
5
+ const { batchSize = DEFAULT_BATCH_SIZE, lockTtlMs = DEFAULT_LOCK_TTL_MS, ...definitionOptions } = options;
6
+ return {
7
+ name: definitionOptions.name,
8
+ batchSize,
9
+ lockTtlMs,
10
+ definitionOptions,
11
+ };
7
12
  }
8
13
  /**
9
14
  * Reject a {@link SearchType} that declares any of the bookkeeping field names
package/dist/search.js CHANGED
@@ -28,14 +28,14 @@ export function createTypesenseSearchEngine(client, schema, options) {
28
28
  if (collection === undefined) {
29
29
  throw new Error(`No collection configured for search type “${searchType.name}”; set options.collections.${searchType.name}.`);
30
30
  }
31
- return [searchType.type, collection];
31
+ return [searchType.class, collection];
32
32
  }));
33
33
  // Resolve every reference field's label source ONCE at construction. The
34
34
  // schema already guarantees the named type exists and serves labels
35
35
  // (`searchSchema`/`labelFieldOf`), and `collections` is exhaustive per type.
36
36
  const typesByName = new Map([...schema.values()].map((searchType) => [searchType.name, searchType]));
37
37
  const labelSources = new Map([...schema.values()].map((searchType) => [
38
- searchType.type,
38
+ searchType.class,
39
39
  new Map(referenceFields(searchType)
40
40
  .filter((field) => field.labelSource !== undefined)
41
41
  .map((field) => {
@@ -44,7 +44,7 @@ export function createTypesenseSearchEngine(client, schema, options) {
44
44
  return [
45
45
  field.name,
46
46
  {
47
- collection: collections.get(source.type),
47
+ collection: collections.get(source.class),
48
48
  labelField,
49
49
  queryBy: physicalFields(labelField).search.join(','),
50
50
  },
@@ -63,9 +63,9 @@ export function createTypesenseSearchEngine(client, schema, options) {
63
63
  // resolved label source – fixed at construction, so labelLookupGroups need
64
64
  // not re-derive or re-resolve them on every search.
65
65
  const outputReferenceSources = new Map([...schema.values()].map((searchType) => {
66
- const sources = labelSources.get(searchType.type);
66
+ const sources = labelSources.get(searchType.class);
67
67
  return [
68
- searchType.type,
68
+ searchType.class,
69
69
  referenceFields(searchType)
70
70
  .filter((field) => field.output === true && sources?.has(field.name))
71
71
  .map((field) => ({
@@ -129,14 +129,14 @@ export function createTypesenseSearchEngine(client, schema, options) {
129
129
  // cannot leave an unhandled rejection behind if the search itself fails.
130
130
  // `undefined` when the cache is off or the type has no label sources.
131
131
  function startCachedLabels(searchType) {
132
- const sources = distinctLabelSources.get(searchType.type);
132
+ const sources = distinctLabelSources.get(searchType.class);
133
133
  if (options.labelCacheTtlMs === undefined ||
134
134
  sources === undefined ||
135
135
  sources.length === 0) {
136
136
  return undefined;
137
137
  }
138
138
  const ttlMs = options.labelCacheTtlMs;
139
- return Promise.all(sources.map((source) => cachedAllLabels(source, ttlMs))).then((maps) => mergeCachedLabels(searchType.type, maps));
139
+ return Promise.all(sources.map((source) => cachedAllLabels(source, ttlMs))).then((maps) => mergeCachedLabels(searchType.class, maps));
140
140
  }
141
141
  // Labels are supplementary: a failed lookup (e.g. a label-source collection
142
142
  // mid-rebuild) degrades to id-only references rather than failing the whole
@@ -165,10 +165,10 @@ export function createTypesenseSearchEngine(client, schema, options) {
165
165
  const params = buildSearchParams(query, searchType, options);
166
166
  const cachedLabelsPromise = startCachedLabels(searchType);
167
167
  const response = (await client
168
- .collections(collections.get(searchType.type))
168
+ .collections(collections.get(searchType.class))
169
169
  .documents()
170
170
  .search(params));
171
- const labels = await resolveLabels(cachedLabelsPromise, () => labelLookupGroups([response], labelSources.get(searchType.type), outputReferenceSources.get(searchType.type) ?? []));
171
+ const labels = await resolveLabels(cachedLabelsPromise, () => labelLookupGroups([response], labelSources.get(searchType.class), outputReferenceSources.get(searchType.class) ?? []));
172
172
  return parseSearchResponse(response, searchType, labels);
173
173
  },
174
174
  async searchFacets(searchType, queries) {
@@ -179,7 +179,7 @@ export function createTypesenseSearchEngine(client, schema, options) {
179
179
  if (queries.length === 0) {
180
180
  return [];
181
181
  }
182
- const collection = collections.get(searchType.type);
182
+ const collection = collections.get(searchType.class);
183
183
  const cachedLabelsPromise = startCachedLabels(searchType);
184
184
  // The whole batch travels as ONE multi_search round-trip. Each query
185
185
  // compiles as facet-only regardless of what it carries: no hits
@@ -193,7 +193,7 @@ export function createTypesenseSearchEngine(client, schema, options) {
193
193
  }));
194
194
  // One label lookup serves every successful facet result in the batch.
195
195
  const responses = results.filter((result) => !('error' in result));
196
- const labels = await resolveLabels(cachedLabelsPromise, () => labelLookupGroups(responses, labelSources.get(searchType.type), outputReferenceSources.get(searchType.type) ?? []));
196
+ const labels = await resolveLabels(cachedLabelsPromise, () => labelLookupGroups(responses, labelSources.get(searchType.class), outputReferenceSources.get(searchType.class) ?? []));
197
197
  // multi_search reports a failed entry inline instead of rejecting the
198
198
  // call; pass that through as a per-query outcome – naming the facets,
199
199
  // not the position, since the batch order is the caller's internal –
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lde/search-typesense",
3
- "version": "0.7.0",
3
+ "version": "0.8.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.5.0",
28
+ "@lde/search": "^0.6.0",
29
29
  "@lde/text-normalization": "^0.1.1",
30
30
  "tslib": "^2.3.0",
31
31
  "typesense": "^3.0.6"
@@ -35,6 +35,6 @@
35
35
  },
36
36
  "peerDependencies": {
37
37
  "@lde/dataset": "^0.7.8",
38
- "@lde/pipeline": "^0.34.0"
38
+ "@lde/pipeline": "^0.34.1"
39
39
  }
40
40
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"collection-schema.d.ts","sourceRoot":"","sources":["../src/collection-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAExD,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAGhE,0EAA0E;AAC1E,MAAM,WAAW,uBAAuB;IACtC,gDAAgD;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;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;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,uBAAuB,GAC/B,sBAAsB,CAexB"}