@yoch/frozenminisearch 1.2.3 → 1.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.
@@ -164,11 +164,10 @@ type BinaryCompression = 'auto' | 'raw' | 'zstd' | 'zlib';
164
164
  type SaveBinaryOptions = {
165
165
  /**
166
166
  * Compression codec for the payload.
167
- * - `auto`: one pass; payloads under 64 B stay raw; otherwise zstd when available
168
- * (else zlib on Node < 22.15), kept only when strictly smaller than raw
167
+ * - `auto`: one pass; payloads under 64 B stay raw; otherwise zlib when it shrinks
169
168
  * - `raw`: never compress
170
- * - `zstd`: always zstd-compress, even when larger than raw; requires Node 22.15+ to write
171
- * - `zlib`: always deflate, even when larger than raw; readable on Node 20+
169
+ * - `zstd`: always zstd-compress; requires Node 22.15+ to write
170
+ * - `zlib`: always deflate; readable on Node 20+ and in the browser build
172
171
  */
173
172
  compression?: BinaryCompression;
174
173
  };
@@ -247,9 +246,57 @@ type VacuumConditions = {
247
246
  */
248
247
  type AutoVacuumOptions = VacuumOptions & VacuumConditions;
249
248
 
249
+ /**
250
+ * Runtime stored fields. Single store field → one column (no per-doc Record at rest).
251
+ * Wire format stays row JSON; encode/decode can skip intermediate row arrays when layout is known.
252
+ */
253
+ type StoredFieldsLayout = {
254
+ kind: 'none';
255
+ } | {
256
+ kind: 'single';
257
+ field: string;
258
+ values: unknown[];
259
+ } | {
260
+ kind: 'multi';
261
+ rows: (Record<string, unknown> | undefined)[];
262
+ };
263
+
250
264
  declare const OR: LowercaseCombinationOperator;
251
265
  declare const AND: LowercaseCombinationOperator;
252
266
  declare const AND_NOT: LowercaseCombinationOperator;
267
+ interface RawResultValue {
268
+ score: number;
269
+ terms: string[];
270
+ match: MatchInfo;
271
+ }
272
+ type RawResult = Map<number, RawResultValue>;
273
+ /** Posting list for one (term, field): docId -> term frequency */
274
+ interface PostingListLike {
275
+ readonly size: number;
276
+ forEachDoc(callback: (docId: number, termFreq: number) => void): void;
277
+ }
278
+ /** term -> fieldId -> posting list */
279
+ interface FieldTermDataLike {
280
+ get(fieldId: number): PostingListLike | undefined;
281
+ }
282
+ interface FinalizeSearchParams {
283
+ rawResults: RawResult;
284
+ getExternalId: (docId: number) => unknown;
285
+ getStoredFields?: (docId: number) => Record<string, unknown> | undefined;
286
+ /** When set, copies stored fields in place (no per-doc row allocation for single-column layouts). */
287
+ storedFieldsLayout?: StoredFieldsLayout;
288
+ filter?: (result: SearchResult) => boolean;
289
+ skipSort?: boolean;
290
+ }
291
+ /** Merge search options, apply wildcard skipSort, then {@link finalizeSearchResults}. */
292
+ declare function finalizeRawSearchResults(rawResults: RawResult, query: Query, searchOptions: SearchOptions, globalSearchOptions: SearchOptionsWithDefaults, getExternalId: (docId: number) => unknown, getStoredFields?: (docId: number) => Record<string, unknown> | undefined, storedFieldsLayout?: StoredFieldsLayout): SearchResult[];
293
+ declare function finalizeSearchResults(params: FinalizeSearchParams): SearchResult[];
294
+
295
+ type SuggestionHit = Pick<SearchResult, 'score' | 'terms'>;
296
+ /** Aggregate search hits into ranked phrase suggestions. */
297
+ declare function suggestFromSearchResults(hits: Iterable<SuggestionHit>): Suggestion[];
298
+ /** Build suggestions from raw search hits without materializing full public results. */
299
+ declare function suggestFromRawResults(rawResults: RawResult): Suggestion[];
253
300
 
254
301
  /**
255
302
  * Smallest unsigned typed array that can hold the structure's indices. Widths
@@ -421,25 +468,14 @@ interface FrozenPostingsLayout {
421
468
  sparseOffsets: Uint32Array | null;
422
469
  sparseLengths: Uint32Array | null;
423
470
  }
471
+ /** Single rebindable {@link FieldTermDataLike} per frozen index (O(1) RAM). */
472
+ type FrozenFieldTermFlyweight = FieldTermDataLike & {
473
+ bind(termIndex: number): FrozenFieldTermFlyweight;
474
+ };
424
475
 
425
476
  /** Adaptive-width unsigned column (1/2/4 bytes per element) for field lengths and packed radix columns. */
426
477
  type FieldLengthArray = PackedIndexArray;
427
478
 
428
- /**
429
- * Runtime stored fields. Single store field → one column (no per-doc Record at rest).
430
- * Wire format stays row JSON; encode/decode can skip intermediate row arrays when layout is known.
431
- */
432
- type StoredFieldsLayout = {
433
- kind: 'none';
434
- } | {
435
- kind: 'single';
436
- field: string;
437
- values: unknown[];
438
- } | {
439
- kind: 'multi';
440
- rows: (Record<string, unknown> | undefined)[];
441
- };
442
-
443
479
  interface FrozenMemoryBreakdown {
444
480
  termCount: number;
445
481
  documentCount: number;
@@ -540,6 +576,7 @@ declare class FrozenIndexBuilder<T> {
540
576
  private readonly _avgFieldLength;
541
577
  private readonly _seenIds;
542
578
  private readonly _fieldTermFreqScratch;
579
+ private readonly _rawTokenScratch;
543
580
  private readonly _tokenScratch;
544
581
  private _nextId;
545
582
  private _frozen;
@@ -577,27 +614,25 @@ declare class FrozenIndexBuilder<T> {
577
614
  /** Create an incremental builder for {@link FrozenMiniSearch}. */
578
615
  declare function createFrozenIndexBuilder<T>(options: Options<T>, hints?: FrozenIndexBuilderHints): FrozenIndexBuilder<T>;
579
616
 
580
- declare function frozenMemoryBreakdown(frozen: FrozenMiniSearch): FrozenMemoryBreakdown;
581
- /** Instantiate {@link FrozenMiniSearch} from pre-built flat index parts (full validation). */
582
- declare function assembleFrozen<T>(params: FrozenAssembleParams<T>): FrozenMiniSearch<T>;
583
- declare function buildFrozenFromDocuments<T>(documents: readonly T[], options: Options<T>): FrozenMiniSearch<T>;
584
- /** Finalize a {@link FrozenIndexBuilder} into a read-only index. */
585
- declare function freezeFrozenIndexBuilder<T>(builder: FrozenIndexBuilder<T>): FrozenMiniSearch<T>;
586
- declare class FrozenMiniSearch<T = any> {
587
- private readonly _options;
588
- private readonly _index;
589
- private readonly _documentCount;
590
- private readonly _nextId;
591
- private readonly _externalIds;
592
- private readonly _idLookup;
593
- private readonly _fieldIds;
594
- private readonly _fieldCount;
595
- private readonly _fieldLengthMatrix;
596
- private readonly _avgFieldLength;
597
- private readonly _storedFields;
598
- private readonly _termCount;
599
- private readonly _postings;
600
- private readonly _fieldTermFlyweight;
617
+ declare function frozenMemoryBreakdown(frozen: FrozenMiniSearchCore): FrozenMemoryBreakdown;
618
+ type FrozenMiniSearchCtor<T, I extends FrozenMiniSearchCore<T>> = new (params: FrozenAssembleParams<T>) => I;
619
+ declare class FrozenMiniSearchCore<T = any> {
620
+ protected readonly _options: OptionsWithDefaults<T>;
621
+ protected readonly _index: FrozenTermIndex;
622
+ protected readonly _documentCount: number;
623
+ protected readonly _nextId: number;
624
+ protected readonly _externalIds: unknown[];
625
+ protected readonly _idLookup: IdToShortIdLookup;
626
+ protected readonly _fieldIds: {
627
+ [field: string]: number;
628
+ };
629
+ protected readonly _fieldCount: number;
630
+ protected readonly _fieldLengthMatrix: FieldLengthArray;
631
+ protected readonly _avgFieldLength: Float32Array;
632
+ protected readonly _storedFields: StoredFieldsLayout;
633
+ protected readonly _termCount: number;
634
+ protected readonly _postings: FrozenPostingsLayout;
635
+ protected readonly _fieldTermFlyweight: FrozenFieldTermFlyweight;
601
636
  private readonly _aggregateContext;
602
637
  private readonly _queryEngineParams;
603
638
  private readonly _hasStoredFields;
@@ -609,42 +644,35 @@ declare class FrozenMiniSearch<T = any> {
609
644
  has(id: unknown): boolean;
610
645
  getStoredFields(id: unknown): Record<string, unknown> | undefined;
611
646
  search(query: Query, searchOptions?: SearchOptions): SearchResult[];
647
+ /**
648
+ * Without a `filter`, aggregates suggestions from raw query hits (no full result materialization).
649
+ * With a `filter`, uses {@link search} so stored fields are available to the predicate.
650
+ */
612
651
  autoSuggest(queryString: string, options?: SearchOptions): Suggestion[];
613
- /** Serialize this index as a frozen binary snapshot (synchronous). */
614
- saveBinarySync(saveOptions?: SaveBinaryOptions): Buffer;
615
- /** Non-blocking snapshot serialization with the selected compression codec. */
616
- saveBinaryAsync(saveOptions?: SaveBinaryOptions): Promise<Buffer>;
617
- /** Load a frozen binary snapshot. */
618
- static loadBinarySync<T>(buffer: Buffer, options?: Options<T>): FrozenMiniSearch<T>;
619
- /** Load a frozen binary snapshot with streaming decompression when needed (bounded memory). */
620
- static loadBinaryAsync<T>(buffer: Buffer, options?: Options<T>): Promise<FrozenMiniSearch<T>>;
621
- private static fromBinarySnapshot;
622
652
  /** Build a read-only index in one pass from documents. */
623
- static fromDocuments<T>(documents: readonly T[], options: Options<T>): FrozenMiniSearch<T>;
653
+ static fromDocuments<T, I extends FrozenMiniSearchCore<T>>(this: FrozenMiniSearchCtor<T, I>, documents: readonly T[], options: Options<T>): I;
624
654
  /**
625
655
  * Export this index as a MiniSearch wire snapshot (`serializationVersion: 2`).
626
656
  * Use for migration or interchange with the `minisearch` package (`JSON.stringify` works via this method).
627
- * Not the primary persistence format — prefer {@link saveBinarySync} for production (size and load time).
628
657
  * Term order in `index` may differ from MiniSearch native `toJSON`; search scores stay equivalent.
629
658
  */
630
659
  toJSON(): MiniSearchSnapshot;
631
660
  /**
632
661
  * Build a new frozen index **from** a MiniSearch JSON snapshot string (import / migration).
633
662
  * Accepts the wire format produced by MiniSearch `toJSON` or by {@link toJSON} on this class.
634
- * Distinct from {@link loadBinarySync}: JSON is MiniSearch interchange, not the native frozen binary.
635
663
  * No runtime dependency on the `minisearch` package.
636
664
  */
637
- static fromJson<T>(json: string, options?: Options<T>): FrozenMiniSearch<T>;
665
+ static fromJson<T, I extends FrozenMiniSearchCore<T>>(this: FrozenMiniSearchCtor<T, I>, json: string, options?: Options<T>): I;
638
666
  /**
639
667
  * Same as {@link fromJson} with a pre-parsed snapshot object.
640
668
  * `storedFields` are shallow-copied; callers must not mutate nested values
641
669
  * after load if they intend to keep the index immutable.
642
670
  */
643
- static fromMiniSearchSnapshot<T>(snapshot: MiniSearchSnapshot, options?: Options<T>): FrozenMiniSearch<T>;
671
+ static fromMiniSearchSnapshot<T, I extends FrozenMiniSearchCore<T>>(this: FrozenMiniSearchCtor<T, I>, snapshot: MiniSearchSnapshot, options?: Options<T>): I;
644
672
  /** Accepts any object exposing `toJSON()` in MiniSearch snapshot shape. */
645
- static fromMiniSearch<T>(source: {
673
+ static fromMiniSearch<T, I extends FrozenMiniSearchCore<T>>(this: FrozenMiniSearchCtor<T, I>, source: {
646
674
  toJSON(): MiniSearchSnapshot;
647
- }, options?: Options<T>): FrozenMiniSearch<T>;
675
+ }, options?: Options<T>): I;
648
676
  /**
649
677
  * Build a read-only index from an async stream of documents (e.g. CSV parser).
650
678
  * For sync iterables, use {@link createFrozenIndexBuilder} with `for...of` instead.
@@ -652,10 +680,29 @@ declare class FrozenMiniSearch<T = any> {
652
680
  * @param hints Optional builder hints; `estimatedDocumentCount` pre-allocates
653
681
  * per-document arrays when the final document count is known upfront.
654
682
  */
655
- static fromAsyncIterable<T>(iterable: AsyncIterable<T>, options: Options<T>, hints?: FrozenIndexBuilderHints): Promise<FrozenMiniSearch<T>>;
683
+ static fromAsyncIterable<T, I extends FrozenMiniSearchCore<T>>(this: FrozenMiniSearchCtor<T, I>, iterable: AsyncIterable<T>, options: Options<T>, hints?: FrozenIndexBuilderHints): Promise<I>;
656
684
  private getFieldLength;
657
685
  private executeQuery;
658
686
  }
659
687
 
660
- export { AND, AND_NOT, FrozenIndexBuilder, FrozenMiniSearch, OR, assembleFrozen, buildFrozenFromDocuments, createFrozenIndexBuilder, FrozenMiniSearch as default, freezeFrozenIndexBuilder, frozenMemoryBreakdown };
688
+ /** Build a read-only Node index in one pass from documents. */
689
+ declare function buildFrozenFromDocuments<T>(documents: readonly T[], options: Options<T>): FrozenMiniSearch<T>;
690
+ /** Finalize a {@link FrozenIndexBuilder} into a read-only Node index. */
691
+ declare function freezeFrozenIndexBuilder<T>(builder: FrozenIndexBuilder<T>): FrozenMiniSearch<T>;
692
+ /** Instantiate {@link FrozenMiniSearch} from pre-built flat index parts (full validation). */
693
+ declare function assembleFrozen<T>(params: FrozenAssembleParams<T>): FrozenMiniSearch<T>;
694
+ declare class FrozenMiniSearch<T = any> extends FrozenMiniSearchCore<T> {
695
+ /** Serialize this index as a frozen binary snapshot (synchronous). */
696
+ saveBinarySync(saveOptions?: SaveBinaryOptions): Buffer;
697
+ /** Non-blocking snapshot serialization with the selected compression codec. */
698
+ saveBinaryAsync(saveOptions?: SaveBinaryOptions): Promise<Buffer>;
699
+ private binarySnapshotInput;
700
+ /** Load a frozen binary snapshot. */
701
+ static loadBinarySync<T>(buffer: Buffer, options?: Options<T>): FrozenMiniSearch<T>;
702
+ /** Load a frozen binary snapshot with streaming decompression when needed (bounded memory). */
703
+ static loadBinaryAsync<T>(buffer: Buffer, options?: Options<T>): Promise<FrozenMiniSearch<T>>;
704
+ private static fromBinarySnapshot;
705
+ }
706
+
707
+ export { AND, AND_NOT, FrozenIndexBuilder, FrozenMiniSearch, OR, assembleFrozen, buildFrozenFromDocuments, createFrozenIndexBuilder, FrozenMiniSearch as default, finalizeRawSearchResults, finalizeSearchResults, freezeFrozenIndexBuilder, frozenMemoryBreakdown, suggestFromRawResults, suggestFromSearchResults };
661
708
  export type { BM25Params, BinaryCompression, CombinationOperator, FrozenAssembleParams, FrozenIndexBuilderHints, FrozenMemoryBreakdown, LogLevel, LowercaseCombinationOperator, MatchInfo, MiniSearchSnapshot, Options, Query, QueryCombination, SaveBinaryOptions, SearchOptions, SearchResult, SerializedIndexEntry, Suggestion, Wildcard };