@topgunbuild/core 0.3.0 → 0.5.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/dist/index.d.ts CHANGED
@@ -402,6 +402,706 @@ declare function hashORMapRecord<V>(record: ORMapRecord<V>): number;
402
402
  */
403
403
  declare function compareTimestamps(a: Timestamp, b: Timestamp): number;
404
404
 
405
+ /**
406
+ * State of a PN Counter CRDT.
407
+ * Tracks positive and negative increments per node for convergence.
408
+ */
409
+ interface PNCounterState {
410
+ /** Positive increments per node */
411
+ positive: Map<string, number>;
412
+ /** Negative increments per node */
413
+ negative: Map<string, number>;
414
+ }
415
+ /**
416
+ * Serializable form of PNCounterState for network/storage.
417
+ */
418
+ interface PNCounterStateObject {
419
+ /** Positive increments per node as object */
420
+ p: Record<string, number>;
421
+ /** Negative increments per node as object */
422
+ n: Record<string, number>;
423
+ }
424
+ /**
425
+ * Configuration for creating a PN Counter.
426
+ */
427
+ interface PNCounterConfig {
428
+ /** Unique node identifier for this counter instance */
429
+ nodeId: string;
430
+ /** Initial state to restore from */
431
+ initialState?: PNCounterState;
432
+ }
433
+ /**
434
+ * Interface for PN Counter CRDT.
435
+ */
436
+ interface PNCounter {
437
+ /** Get current value */
438
+ get(): number;
439
+ /** Increment by 1, return new value */
440
+ increment(): number;
441
+ /** Decrement by 1, return new value */
442
+ decrement(): number;
443
+ /** Add delta (positive or negative), return new value */
444
+ addAndGet(delta: number): number;
445
+ /** Get state for sync */
446
+ getState(): PNCounterState;
447
+ /** Merge remote state */
448
+ merge(remote: PNCounterState): void;
449
+ /** Subscribe to value changes */
450
+ subscribe(listener: (value: number) => void): () => void;
451
+ }
452
+ /**
453
+ * Positive-Negative Counter CRDT implementation.
454
+ *
455
+ * A PN Counter is a CRDT that supports increment and decrement operations
456
+ * on any node, works offline, and guarantees convergence without coordination.
457
+ *
458
+ * How it works:
459
+ * - Tracks positive increments per node in a G-Counter
460
+ * - Tracks negative increments per node in another G-Counter
461
+ * - Value = sum(positive) - sum(negative)
462
+ * - Merge takes max for each node in both counters
463
+ *
464
+ * @example
465
+ * ```typescript
466
+ * const counter = new PNCounterImpl({ nodeId: 'node-1' });
467
+ * counter.increment(); // 1
468
+ * counter.increment(); // 2
469
+ * counter.decrement(); // 1
470
+ * counter.addAndGet(5); // 6
471
+ * ```
472
+ */
473
+ declare class PNCounterImpl implements PNCounter {
474
+ private readonly nodeId;
475
+ private state;
476
+ private listeners;
477
+ constructor(config: PNCounterConfig);
478
+ /**
479
+ * Get the current counter value.
480
+ * Value = sum(positive) - sum(negative)
481
+ */
482
+ get(): number;
483
+ /**
484
+ * Increment by 1 and return the new value.
485
+ */
486
+ increment(): number;
487
+ /**
488
+ * Decrement by 1 and return the new value.
489
+ */
490
+ decrement(): number;
491
+ /**
492
+ * Add a delta (positive or negative) and return the new value.
493
+ * @param delta The amount to add (can be negative)
494
+ */
495
+ addAndGet(delta: number): number;
496
+ /**
497
+ * Get a copy of the current state for synchronization.
498
+ */
499
+ getState(): PNCounterState;
500
+ /**
501
+ * Merge remote state into this counter.
502
+ * Takes the maximum value for each node in both positive and negative counters.
503
+ * This operation is commutative, associative, and idempotent (CRDT properties).
504
+ *
505
+ * @param remote The remote state to merge
506
+ */
507
+ merge(remote: PNCounterState): void;
508
+ /**
509
+ * Subscribe to value changes.
510
+ * The listener is immediately called with the current value.
511
+ *
512
+ * @param listener Callback function receiving the new value
513
+ * @returns Unsubscribe function
514
+ */
515
+ subscribe(listener: (value: number) => void): () => void;
516
+ private notifyListeners;
517
+ /**
518
+ * Get the node ID of this counter instance.
519
+ */
520
+ getNodeId(): string;
521
+ /**
522
+ * Serialize state to binary format (msgpack).
523
+ */
524
+ static serialize(state: PNCounterState): Uint8Array;
525
+ /**
526
+ * Deserialize binary data to state.
527
+ */
528
+ static deserialize(data: Uint8Array): PNCounterState;
529
+ /**
530
+ * Convert state to plain object (for JSON/network).
531
+ */
532
+ static stateToObject(state: PNCounterState): PNCounterStateObject;
533
+ /**
534
+ * Convert plain object to state.
535
+ */
536
+ static objectToState(obj: PNCounterStateObject): PNCounterState;
537
+ }
538
+
539
+ /**
540
+ * Fixed-size circular buffer with sequence numbers.
541
+ * Older entries are overwritten when capacity is reached.
542
+ *
543
+ * @template T - Type of items stored in the buffer
544
+ */
545
+ declare class Ringbuffer<T> {
546
+ private buffer;
547
+ private readonly _capacity;
548
+ private headSequence;
549
+ private tailSequence;
550
+ constructor(capacity: number);
551
+ /**
552
+ * Add item to buffer, returns sequence number.
553
+ */
554
+ add(item: T): bigint;
555
+ /**
556
+ * Read item at sequence.
557
+ * Returns undefined if sequence is out of range.
558
+ */
559
+ read(sequence: bigint): T | undefined;
560
+ /**
561
+ * Read range of items (inclusive).
562
+ * Automatically clamps to available range.
563
+ */
564
+ readRange(startSeq: bigint, endSeq: bigint): T[];
565
+ /**
566
+ * Read from sequence with limit.
567
+ */
568
+ readFrom(startSeq: bigint, limit?: number): T[];
569
+ /**
570
+ * Get the oldest available sequence number.
571
+ */
572
+ getHeadSequence(): bigint;
573
+ /**
574
+ * Get the next sequence number to be written.
575
+ */
576
+ getTailSequence(): bigint;
577
+ /**
578
+ * Get the number of items currently in the buffer.
579
+ */
580
+ size(): number;
581
+ /**
582
+ * Get the maximum capacity of the buffer.
583
+ */
584
+ getCapacity(): number;
585
+ /**
586
+ * Clear all items from the buffer.
587
+ */
588
+ clear(): void;
589
+ /**
590
+ * Check if a sequence is available in the buffer.
591
+ */
592
+ isAvailable(sequence: bigint): boolean;
593
+ /**
594
+ * Get remaining capacity before oldest entries are overwritten.
595
+ */
596
+ remainingCapacity(): number;
597
+ }
598
+
599
+ /**
600
+ * Type of journal event.
601
+ */
602
+ type JournalEventType = 'PUT' | 'UPDATE' | 'DELETE';
603
+ /**
604
+ * Single event in the journal.
605
+ */
606
+ interface JournalEvent<V = unknown> {
607
+ /** Monotonically increasing sequence number */
608
+ sequence: bigint;
609
+ /** Event type */
610
+ type: JournalEventType;
611
+ /** Map name */
612
+ mapName: string;
613
+ /** Entry key */
614
+ key: string;
615
+ /** New value (undefined for DELETE) */
616
+ value?: V;
617
+ /** Previous value (for UPDATE and DELETE) */
618
+ previousValue?: V;
619
+ /** HLC timestamp */
620
+ timestamp: Timestamp;
621
+ /** Node that made the change */
622
+ nodeId: string;
623
+ /** Optional metadata */
624
+ metadata?: Record<string, unknown>;
625
+ }
626
+ /**
627
+ * Input for appending events (without sequence).
628
+ */
629
+ type JournalEventInput<V = unknown> = Omit<JournalEvent<V>, 'sequence'>;
630
+ /**
631
+ * Event Journal configuration.
632
+ */
633
+ interface EventJournalConfig {
634
+ /** Maximum number of events to keep in memory */
635
+ capacity: number;
636
+ /** Time-to-live for events (ms), 0 = infinite */
637
+ ttlMs: number;
638
+ /** Persist to storage adapter */
639
+ persistent: boolean;
640
+ /** Maps to include (empty = all) */
641
+ includeMaps?: string[];
642
+ /** Maps to exclude */
643
+ excludeMaps?: string[];
644
+ }
645
+ /**
646
+ * Default configuration for Event Journal.
647
+ */
648
+ declare const DEFAULT_EVENT_JOURNAL_CONFIG: EventJournalConfig;
649
+ /**
650
+ * Event Journal interface.
651
+ */
652
+ interface EventJournal {
653
+ /** Append event to journal */
654
+ append<V>(event: JournalEventInput<V>): JournalEvent<V>;
655
+ /** Read events from sequence (inclusive) */
656
+ readFrom(sequence: bigint, limit?: number): JournalEvent[];
657
+ /** Read events in range */
658
+ readRange(startSeq: bigint, endSeq: bigint): JournalEvent[];
659
+ /** Get latest sequence number */
660
+ getLatestSequence(): bigint;
661
+ /** Get oldest sequence number (after compaction) */
662
+ getOldestSequence(): bigint;
663
+ /** Subscribe to new events */
664
+ subscribe(listener: (event: JournalEvent) => void, fromSequence?: bigint): () => void;
665
+ /** Get capacity info */
666
+ getCapacity(): {
667
+ used: number;
668
+ total: number;
669
+ };
670
+ /** Force compaction */
671
+ compact(): Promise<void>;
672
+ /** Dispose resources */
673
+ dispose(): void;
674
+ }
675
+ /**
676
+ * Journal event listener type.
677
+ */
678
+ type JournalEventListener = (event: JournalEvent) => void;
679
+ /**
680
+ * Event Journal implementation using Ringbuffer.
681
+ * Records all Map changes as an append-only log.
682
+ */
683
+ declare class EventJournalImpl implements EventJournal {
684
+ private readonly config;
685
+ private readonly buffer;
686
+ private readonly listeners;
687
+ private ttlTimer?;
688
+ constructor(config?: Partial<EventJournalConfig>);
689
+ /**
690
+ * Append event to journal.
691
+ * Returns the event with assigned sequence number.
692
+ * Returns event with sequence -1n if map is filtered out.
693
+ */
694
+ append<V>(eventData: JournalEventInput<V>): JournalEvent<V>;
695
+ /**
696
+ * Read events from sequence with optional limit.
697
+ */
698
+ readFrom(sequence: bigint, limit?: number): JournalEvent[];
699
+ /**
700
+ * Read events in range (inclusive).
701
+ */
702
+ readRange(startSeq: bigint, endSeq: bigint): JournalEvent[];
703
+ /**
704
+ * Get latest sequence number.
705
+ * Returns 0n if no events have been added.
706
+ */
707
+ getLatestSequence(): bigint;
708
+ /**
709
+ * Get oldest available sequence number.
710
+ */
711
+ getOldestSequence(): bigint;
712
+ /**
713
+ * Subscribe to new events.
714
+ * Optionally replay events from a specific sequence.
715
+ *
716
+ * @param listener Callback for each event
717
+ * @param fromSequence Optional sequence to start replay from
718
+ * @returns Unsubscribe function
719
+ */
720
+ subscribe(listener: JournalEventListener, fromSequence?: bigint): () => void;
721
+ /**
722
+ * Get capacity information.
723
+ */
724
+ getCapacity(): {
725
+ used: number;
726
+ total: number;
727
+ };
728
+ /**
729
+ * Force compaction.
730
+ * Note: The ringbuffer handles eviction automatically.
731
+ * This method is provided for explicit cleanup of old events.
732
+ */
733
+ compact(): Promise<void>;
734
+ /**
735
+ * Check if a map should be captured.
736
+ */
737
+ private shouldCapture;
738
+ /**
739
+ * Start TTL cleanup timer.
740
+ */
741
+ private startTTLCleanup;
742
+ /**
743
+ * Dispose resources.
744
+ */
745
+ dispose(): void;
746
+ /**
747
+ * Get all current listeners count (for testing).
748
+ */
749
+ getListenerCount(): number;
750
+ /**
751
+ * Get configuration (for testing).
752
+ */
753
+ getConfig(): EventJournalConfig;
754
+ }
755
+
756
+ /**
757
+ * Function executed on the server against a single entry.
758
+ * Receives the current value (or undefined if key doesn't exist).
759
+ * Returns the new value (or undefined to delete the entry).
760
+ */
761
+ type EntryProcessorFn<V, R = V> = (value: V | undefined, key: string, args?: unknown) => {
762
+ value: V | undefined;
763
+ result?: R;
764
+ };
765
+ /**
766
+ * Zod schema for entry processor definition validation.
767
+ */
768
+ declare const EntryProcessorDefSchema: z.ZodObject<{
769
+ name: z.ZodString;
770
+ code: z.ZodString;
771
+ args: z.ZodOptional<z.ZodUnknown>;
772
+ }, z.core.$strip>;
773
+ /**
774
+ * Serializable entry processor definition.
775
+ * Code is sent as string and executed in isolated sandbox.
776
+ */
777
+ interface EntryProcessorDef<V = unknown, R = V> {
778
+ /** Unique processor name for caching compiled code */
779
+ name: string;
780
+ /** JavaScript function body as string */
781
+ code: string;
782
+ /** Optional arguments passed to the processor */
783
+ args?: unknown;
784
+ /** Type markers (not serialized) */
785
+ __valueType?: V;
786
+ __resultType?: R;
787
+ }
788
+ /**
789
+ * Result of entry processor execution.
790
+ */
791
+ interface EntryProcessorResult<R = unknown> {
792
+ /** Whether the operation succeeded */
793
+ success: boolean;
794
+ /** Custom result returned by processor */
795
+ result?: R;
796
+ /** Error message if failed */
797
+ error?: string;
798
+ /** New value after processing (for client cache update) */
799
+ newValue?: unknown;
800
+ }
801
+ /**
802
+ * Patterns that are denied in processor code for security reasons.
803
+ */
804
+ declare const FORBIDDEN_PATTERNS: RegExp[];
805
+ /**
806
+ * Validates processor code against forbidden patterns.
807
+ * Returns true if code is safe, false otherwise.
808
+ */
809
+ declare function validateProcessorCode(code: string): {
810
+ valid: boolean;
811
+ error?: string;
812
+ };
813
+ /**
814
+ * Built-in processors for common operations.
815
+ * These are type-safe and pre-validated.
816
+ */
817
+ declare const BuiltInProcessors: {
818
+ /**
819
+ * Increment numeric value by delta.
820
+ * If value doesn't exist, starts from 0.
821
+ */
822
+ INCREMENT: (delta?: number) => EntryProcessorDef<number, number>;
823
+ /**
824
+ * Decrement numeric value by delta.
825
+ * If value doesn't exist, starts from 0.
826
+ */
827
+ DECREMENT: (delta?: number) => EntryProcessorDef<number, number>;
828
+ /**
829
+ * Decrement with floor (won't go below 0).
830
+ * Returns both the new value and whether it was floored.
831
+ */
832
+ DECREMENT_FLOOR: (delta?: number) => EntryProcessorDef<number, {
833
+ newValue: number;
834
+ wasFloored: boolean;
835
+ }>;
836
+ /**
837
+ * Multiply numeric value by factor.
838
+ * If value doesn't exist, starts from 1.
839
+ */
840
+ MULTIPLY: (factor: number) => EntryProcessorDef<number, number>;
841
+ /**
842
+ * Set value only if key doesn't exist.
843
+ * Returns true if value was set, false if key already existed.
844
+ */
845
+ PUT_IF_ABSENT: <V>(newValue: V) => EntryProcessorDef<V, boolean>;
846
+ /**
847
+ * Replace value only if key exists.
848
+ * Returns the old value if replaced, undefined otherwise.
849
+ */
850
+ REPLACE: <V>(newValue: V) => EntryProcessorDef<V, V | undefined>;
851
+ /**
852
+ * Replace value only if it matches expected value.
853
+ * Returns true if replaced, false otherwise.
854
+ */
855
+ REPLACE_IF_EQUALS: <V>(expectedValue: V, newValue: V) => EntryProcessorDef<V, boolean>;
856
+ /**
857
+ * Delete entry only if value matches.
858
+ * Returns true if deleted, false otherwise.
859
+ */
860
+ DELETE_IF_EQUALS: <V>(expectedValue: V) => EntryProcessorDef<V, boolean>;
861
+ /**
862
+ * Append item to array.
863
+ * Creates array if it doesn't exist.
864
+ * Returns new array length.
865
+ */
866
+ ARRAY_PUSH: <T>(item: T) => EntryProcessorDef<T[], number>;
867
+ /**
868
+ * Remove last item from array.
869
+ * Returns the removed item or undefined.
870
+ */
871
+ ARRAY_POP: <T>() => EntryProcessorDef<T[], T | undefined>;
872
+ /**
873
+ * Remove item from array by value (first occurrence).
874
+ * Returns true if item was found and removed.
875
+ */
876
+ ARRAY_REMOVE: <T>(item: T) => EntryProcessorDef<T[], boolean>;
877
+ /**
878
+ * Update nested property using dot notation path.
879
+ * Creates intermediate objects if they don't exist.
880
+ */
881
+ SET_PROPERTY: <V>(path: string, propValue: unknown) => EntryProcessorDef<V, V>;
882
+ /**
883
+ * Delete nested property using dot notation path.
884
+ * Returns the deleted value or undefined.
885
+ */
886
+ DELETE_PROPERTY: <V>(path: string) => EntryProcessorDef<V, unknown>;
887
+ /**
888
+ * Get current value without modifying it.
889
+ * Useful for conditional reads.
890
+ */
891
+ GET: <V>() => EntryProcessorDef<V, V | undefined>;
892
+ /**
893
+ * Conditional update based on version/timestamp.
894
+ * Only updates if current version matches expected.
895
+ * Useful for optimistic locking.
896
+ */
897
+ CONDITIONAL_UPDATE: <V extends {
898
+ version?: number;
899
+ }>(expectedVersion: number, newData: Partial<V>) => EntryProcessorDef<V, {
900
+ updated: boolean;
901
+ conflict: boolean;
902
+ }>;
903
+ /**
904
+ * Merge object properties into existing value.
905
+ * Shallow merge only.
906
+ */
907
+ MERGE: <V extends Record<string, unknown>>(properties: Partial<V>) => EntryProcessorDef<V, V>;
908
+ };
909
+ /**
910
+ * Rate limiting configuration for processor execution.
911
+ */
912
+ interface ProcessorRateLimitConfig {
913
+ /** Max processor executions per second per client */
914
+ maxExecutionsPerSecond: number;
915
+ /** Max processor code size in bytes */
916
+ maxCodeSizeBytes: number;
917
+ /** Max args size in bytes (JSON stringified) */
918
+ maxArgsSizeBytes: number;
919
+ }
920
+ /**
921
+ * Default rate limit configuration.
922
+ */
923
+ declare const DEFAULT_PROCESSOR_RATE_LIMITS: ProcessorRateLimitConfig;
924
+
925
+ /**
926
+ * Context provided to a conflict resolver during merge operations.
927
+ */
928
+ interface MergeContext<V = unknown> {
929
+ /** Map name being modified */
930
+ mapName: string;
931
+ /** Entry key being modified */
932
+ key: string;
933
+ /** Current server/local value (undefined if key doesn't exist) */
934
+ localValue: V | undefined;
935
+ /** Incoming client/remote value */
936
+ remoteValue: V;
937
+ /** Local HLC timestamp (undefined if key doesn't exist) */
938
+ localTimestamp?: Timestamp;
939
+ /** Remote HLC timestamp */
940
+ remoteTimestamp: Timestamp;
941
+ /** Client/node ID that sent the update */
942
+ remoteNodeId: string;
943
+ /** Authentication context (optional) */
944
+ auth?: {
945
+ userId?: string;
946
+ roles?: string[];
947
+ metadata?: Record<string, unknown>;
948
+ };
949
+ /** Read other entries for cross-key validation */
950
+ readEntry: (key: string) => V | undefined;
951
+ }
952
+ /**
953
+ * Result of conflict resolution.
954
+ */
955
+ type MergeResult<V = unknown> = {
956
+ action: 'accept';
957
+ value: V;
958
+ } | {
959
+ action: 'reject';
960
+ reason: string;
961
+ } | {
962
+ action: 'merge';
963
+ value: V;
964
+ } | {
965
+ action: 'local';
966
+ };
967
+ /**
968
+ * Conflict resolver function signature.
969
+ */
970
+ type ConflictResolverFn<V = unknown> = (context: MergeContext<V>) => MergeResult<V> | Promise<MergeResult<V>>;
971
+ /**
972
+ * Conflict resolver definition (can be native function or sandboxed code).
973
+ */
974
+ interface ConflictResolverDef<V = unknown> {
975
+ /** Unique resolver name */
976
+ name: string;
977
+ /** JavaScript function body as string (for sandboxed execution) */
978
+ code?: string;
979
+ /** Native function (for trusted server-side resolvers) */
980
+ fn?: ConflictResolverFn<V>;
981
+ /** Priority (higher = runs first, default 50) */
982
+ priority?: number;
983
+ /** Apply only to specific keys (glob pattern) */
984
+ keyPattern?: string;
985
+ }
986
+ /**
987
+ * Zod schema for validating conflict resolver definitions from network.
988
+ */
989
+ declare const ConflictResolverDefSchema: z.ZodObject<{
990
+ name: z.ZodString;
991
+ code: z.ZodOptional<z.ZodString>;
992
+ priority: z.ZodDefault<z.ZodNumber>;
993
+ keyPattern: z.ZodOptional<z.ZodString>;
994
+ }, z.core.$strip>;
995
+ /**
996
+ * Patterns that are denied in resolver code for security reasons.
997
+ * Same patterns as EntryProcessor for consistency.
998
+ */
999
+ declare const RESOLVER_FORBIDDEN_PATTERNS: RegExp[];
1000
+ /**
1001
+ * Validates resolver code against forbidden patterns.
1002
+ */
1003
+ declare function validateResolverCode(code: string): {
1004
+ valid: boolean;
1005
+ error?: string;
1006
+ };
1007
+ /**
1008
+ * Rate limiting configuration for resolver registration.
1009
+ */
1010
+ interface ResolverRateLimitConfig {
1011
+ /** Max resolver registrations per client */
1012
+ maxResolversPerClient: number;
1013
+ /** Max resolver code size in bytes */
1014
+ maxCodeSizeBytes: number;
1015
+ }
1016
+ /**
1017
+ * Default rate limit configuration.
1018
+ */
1019
+ declare const DEFAULT_RESOLVER_RATE_LIMITS: ResolverRateLimitConfig;
1020
+ /**
1021
+ * Compares two HLC timestamps.
1022
+ * Returns negative if a < b, positive if a > b, 0 if equal.
1023
+ */
1024
+ declare function compareHLCTimestamps(a: Timestamp, b: Timestamp): number;
1025
+ /**
1026
+ * Deep merges two objects.
1027
+ * Remote values take precedence at each level.
1028
+ */
1029
+ declare function deepMerge<T extends object>(target: T, source: T): T;
1030
+ /**
1031
+ * Built-in conflict resolvers for common patterns.
1032
+ * These are type-safe and pre-validated.
1033
+ */
1034
+ declare const BuiltInResolvers: {
1035
+ /**
1036
+ * Standard Last-Write-Wins - accept if remote timestamp is newer.
1037
+ */
1038
+ LWW: <V>() => ConflictResolverDef<V>;
1039
+ /**
1040
+ * First-Write-Wins - reject if local value exists.
1041
+ * Useful for booking systems, unique constraints.
1042
+ */
1043
+ FIRST_WRITE_WINS: <V>() => ConflictResolverDef<V>;
1044
+ /**
1045
+ * Numeric minimum - keep lowest value.
1046
+ * Useful for auction systems (lowest bid wins).
1047
+ */
1048
+ NUMERIC_MIN: () => ConflictResolverDef<number>;
1049
+ /**
1050
+ * Numeric maximum - keep highest value.
1051
+ * Useful for high score tracking.
1052
+ */
1053
+ NUMERIC_MAX: () => ConflictResolverDef<number>;
1054
+ /**
1055
+ * Non-negative - reject if value would be negative.
1056
+ * Useful for inventory systems.
1057
+ */
1058
+ NON_NEGATIVE: () => ConflictResolverDef<number>;
1059
+ /**
1060
+ * Array union - merge arrays by taking union of elements.
1061
+ * Useful for tags, categories.
1062
+ */
1063
+ ARRAY_UNION: <T>() => ConflictResolverDef<T[]>;
1064
+ /**
1065
+ * Deep merge - recursively merge objects.
1066
+ * Remote values take precedence at leaf level.
1067
+ */
1068
+ DEEP_MERGE: <V extends object>() => ConflictResolverDef<V>;
1069
+ /**
1070
+ * Server-only - reject all client writes.
1071
+ * Useful for server-controlled state.
1072
+ */
1073
+ SERVER_ONLY: <V>() => ConflictResolverDef<V>;
1074
+ /**
1075
+ * Owner-only - only the original creator can modify.
1076
+ * Requires value to have an `ownerId` property.
1077
+ */
1078
+ OWNER_ONLY: <V extends {
1079
+ ownerId?: string;
1080
+ }>() => ConflictResolverDef<V>;
1081
+ /**
1082
+ * Immutable - reject any modifications after initial write.
1083
+ */
1084
+ IMMUTABLE: <V>() => ConflictResolverDef<V>;
1085
+ /**
1086
+ * Version check - only accept if version increments by 1.
1087
+ * Useful for optimistic locking.
1088
+ */
1089
+ VERSION_INCREMENT: <V extends {
1090
+ version?: number;
1091
+ }>() => ConflictResolverDef<V>;
1092
+ };
1093
+ /**
1094
+ * Event emitted when a merge is rejected.
1095
+ */
1096
+ interface MergeRejection {
1097
+ mapName: string;
1098
+ key: string;
1099
+ attemptedValue: unknown;
1100
+ reason: string;
1101
+ timestamp: Timestamp;
1102
+ nodeId: string;
1103
+ }
1104
+
405
1105
  /**
406
1106
  * Hash utilities for TopGun
407
1107
  *
@@ -461,7 +1161,7 @@ declare function serialize(data: unknown): Uint8Array;
461
1161
  */
462
1162
  declare function deserialize<T = unknown>(data: Uint8Array | ArrayBuffer): T;
463
1163
 
464
- type PredicateOp = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'like' | 'regex' | 'and' | 'or' | 'not';
1164
+ type PredicateOp = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'like' | 'regex' | 'contains' | 'containsAll' | 'containsAny' | 'and' | 'or' | 'not';
465
1165
  interface PredicateNode {
466
1166
  op: PredicateOp;
467
1167
  attribute?: string;
@@ -481,14 +1181,38 @@ declare class Predicates {
481
1181
  static and(...predicates: PredicateNode[]): PredicateNode;
482
1182
  static or(...predicates: PredicateNode[]): PredicateNode;
483
1183
  static not(predicate: PredicateNode): PredicateNode;
484
- }
485
- declare function evaluatePredicate(predicate: PredicateNode, data: any): boolean;
486
-
487
- type PermissionType = 'READ' | 'PUT' | 'REMOVE' | 'ALL';
488
- interface PermissionPolicy {
489
- role: string;
490
- mapNamePattern: string;
491
- actions: PermissionType[];
1184
+ /**
1185
+ * Create a 'contains' predicate for text search.
1186
+ * Matches if attribute value contains the search text.
1187
+ *
1188
+ * @param attribute - Attribute name
1189
+ * @param value - Text to search for
1190
+ */
1191
+ static contains(attribute: string, value: string): PredicateNode;
1192
+ /**
1193
+ * Create a 'containsAll' predicate for text search.
1194
+ * Matches if attribute value contains ALL search values.
1195
+ *
1196
+ * @param attribute - Attribute name
1197
+ * @param values - Text values that must all be present
1198
+ */
1199
+ static containsAll(attribute: string, values: string[]): PredicateNode;
1200
+ /**
1201
+ * Create a 'containsAny' predicate for text search.
1202
+ * Matches if attribute value contains ANY search value.
1203
+ *
1204
+ * @param attribute - Attribute name
1205
+ * @param values - Text values, any of which can match
1206
+ */
1207
+ static containsAny(attribute: string, values: string[]): PredicateNode;
1208
+ }
1209
+ declare function evaluatePredicate(predicate: PredicateNode, data: any): boolean;
1210
+
1211
+ type PermissionType = 'READ' | 'PUT' | 'REMOVE' | 'ALL';
1212
+ interface PermissionPolicy {
1213
+ role: string;
1214
+ mapNamePattern: string;
1215
+ actions: PermissionType[];
492
1216
  allowedFields?: string[];
493
1217
  }
494
1218
  interface Principal {
@@ -796,6 +1520,46 @@ declare const TopicMessageEventSchema: z.ZodObject<{
796
1520
  timestamp: z.ZodNumber;
797
1521
  }, z.core.$strip>;
798
1522
  }, z.core.$strip>;
1523
+ declare const PNCounterStateObjectSchema: z.ZodObject<{
1524
+ p: z.ZodRecord<z.ZodString, z.ZodNumber>;
1525
+ n: z.ZodRecord<z.ZodString, z.ZodNumber>;
1526
+ }, z.core.$strip>;
1527
+ declare const CounterRequestSchema: z.ZodObject<{
1528
+ type: z.ZodLiteral<"COUNTER_REQUEST">;
1529
+ payload: z.ZodObject<{
1530
+ name: z.ZodString;
1531
+ }, z.core.$strip>;
1532
+ }, z.core.$strip>;
1533
+ declare const CounterSyncSchema: z.ZodObject<{
1534
+ type: z.ZodLiteral<"COUNTER_SYNC">;
1535
+ payload: z.ZodObject<{
1536
+ name: z.ZodString;
1537
+ state: z.ZodObject<{
1538
+ p: z.ZodRecord<z.ZodString, z.ZodNumber>;
1539
+ n: z.ZodRecord<z.ZodString, z.ZodNumber>;
1540
+ }, z.core.$strip>;
1541
+ }, z.core.$strip>;
1542
+ }, z.core.$strip>;
1543
+ declare const CounterResponseSchema: z.ZodObject<{
1544
+ type: z.ZodLiteral<"COUNTER_RESPONSE">;
1545
+ payload: z.ZodObject<{
1546
+ name: z.ZodString;
1547
+ state: z.ZodObject<{
1548
+ p: z.ZodRecord<z.ZodString, z.ZodNumber>;
1549
+ n: z.ZodRecord<z.ZodString, z.ZodNumber>;
1550
+ }, z.core.$strip>;
1551
+ }, z.core.$strip>;
1552
+ }, z.core.$strip>;
1553
+ declare const CounterUpdateSchema: z.ZodObject<{
1554
+ type: z.ZodLiteral<"COUNTER_UPDATE">;
1555
+ payload: z.ZodObject<{
1556
+ name: z.ZodString;
1557
+ state: z.ZodObject<{
1558
+ p: z.ZodRecord<z.ZodString, z.ZodNumber>;
1559
+ n: z.ZodRecord<z.ZodString, z.ZodNumber>;
1560
+ }, z.core.$strip>;
1561
+ }, z.core.$strip>;
1562
+ }, z.core.$strip>;
799
1563
  declare const PingMessageSchema: z.ZodObject<{
800
1564
  type: z.ZodLiteral<"PING">;
801
1565
  timestamp: z.ZodNumber;
@@ -951,6 +1715,274 @@ declare const PartitionMapRequestSchema: z.ZodObject<{
951
1715
  currentVersion: z.ZodOptional<z.ZodNumber>;
952
1716
  }, z.core.$strip>>;
953
1717
  }, z.core.$strip>;
1718
+ /**
1719
+ * Entry processor definition schema.
1720
+ */
1721
+ declare const EntryProcessorSchema: z.ZodObject<{
1722
+ name: z.ZodString;
1723
+ code: z.ZodString;
1724
+ args: z.ZodOptional<z.ZodUnknown>;
1725
+ }, z.core.$strip>;
1726
+ /**
1727
+ * ENTRY_PROCESS: Client requests atomic operation on single key.
1728
+ */
1729
+ declare const EntryProcessRequestSchema: z.ZodObject<{
1730
+ type: z.ZodLiteral<"ENTRY_PROCESS">;
1731
+ requestId: z.ZodString;
1732
+ mapName: z.ZodString;
1733
+ key: z.ZodString;
1734
+ processor: z.ZodObject<{
1735
+ name: z.ZodString;
1736
+ code: z.ZodString;
1737
+ args: z.ZodOptional<z.ZodUnknown>;
1738
+ }, z.core.$strip>;
1739
+ }, z.core.$strip>;
1740
+ /**
1741
+ * ENTRY_PROCESS_BATCH: Client requests atomic operation on multiple keys.
1742
+ */
1743
+ declare const EntryProcessBatchRequestSchema: z.ZodObject<{
1744
+ type: z.ZodLiteral<"ENTRY_PROCESS_BATCH">;
1745
+ requestId: z.ZodString;
1746
+ mapName: z.ZodString;
1747
+ keys: z.ZodArray<z.ZodString>;
1748
+ processor: z.ZodObject<{
1749
+ name: z.ZodString;
1750
+ code: z.ZodString;
1751
+ args: z.ZodOptional<z.ZodUnknown>;
1752
+ }, z.core.$strip>;
1753
+ }, z.core.$strip>;
1754
+ /**
1755
+ * ENTRY_PROCESS_RESPONSE: Server responds to single-key processor request.
1756
+ */
1757
+ declare const EntryProcessResponseSchema: z.ZodObject<{
1758
+ type: z.ZodLiteral<"ENTRY_PROCESS_RESPONSE">;
1759
+ requestId: z.ZodString;
1760
+ success: z.ZodBoolean;
1761
+ result: z.ZodOptional<z.ZodUnknown>;
1762
+ newValue: z.ZodOptional<z.ZodUnknown>;
1763
+ error: z.ZodOptional<z.ZodString>;
1764
+ }, z.core.$strip>;
1765
+ /**
1766
+ * Individual key result in batch response.
1767
+ */
1768
+ declare const EntryProcessKeyResultSchema: z.ZodObject<{
1769
+ success: z.ZodBoolean;
1770
+ result: z.ZodOptional<z.ZodUnknown>;
1771
+ newValue: z.ZodOptional<z.ZodUnknown>;
1772
+ error: z.ZodOptional<z.ZodString>;
1773
+ }, z.core.$strip>;
1774
+ /**
1775
+ * ENTRY_PROCESS_BATCH_RESPONSE: Server responds to multi-key processor request.
1776
+ */
1777
+ declare const EntryProcessBatchResponseSchema: z.ZodObject<{
1778
+ type: z.ZodLiteral<"ENTRY_PROCESS_BATCH_RESPONSE">;
1779
+ requestId: z.ZodString;
1780
+ results: z.ZodRecord<z.ZodString, z.ZodObject<{
1781
+ success: z.ZodBoolean;
1782
+ result: z.ZodOptional<z.ZodUnknown>;
1783
+ newValue: z.ZodOptional<z.ZodUnknown>;
1784
+ error: z.ZodOptional<z.ZodString>;
1785
+ }, z.core.$strip>>;
1786
+ }, z.core.$strip>;
1787
+ /**
1788
+ * Journal event type schema.
1789
+ */
1790
+ declare const JournalEventTypeSchema: z.ZodEnum<{
1791
+ PUT: "PUT";
1792
+ UPDATE: "UPDATE";
1793
+ DELETE: "DELETE";
1794
+ }>;
1795
+ /**
1796
+ * Journal event data (serialized for network).
1797
+ */
1798
+ declare const JournalEventDataSchema: z.ZodObject<{
1799
+ sequence: z.ZodString;
1800
+ type: z.ZodEnum<{
1801
+ PUT: "PUT";
1802
+ UPDATE: "UPDATE";
1803
+ DELETE: "DELETE";
1804
+ }>;
1805
+ mapName: z.ZodString;
1806
+ key: z.ZodString;
1807
+ value: z.ZodOptional<z.ZodUnknown>;
1808
+ previousValue: z.ZodOptional<z.ZodUnknown>;
1809
+ timestamp: z.ZodObject<{
1810
+ millis: z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodBigInt]>, z.ZodTransform<number, number | bigint>>;
1811
+ counter: z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodBigInt]>, z.ZodTransform<number, number | bigint>>;
1812
+ nodeId: z.ZodString;
1813
+ }, z.core.$strip>;
1814
+ nodeId: z.ZodString;
1815
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1816
+ }, z.core.$strip>;
1817
+ /**
1818
+ * JOURNAL_SUBSCRIBE: Client subscribes to journal events.
1819
+ */
1820
+ declare const JournalSubscribeRequestSchema: z.ZodObject<{
1821
+ type: z.ZodLiteral<"JOURNAL_SUBSCRIBE">;
1822
+ requestId: z.ZodString;
1823
+ fromSequence: z.ZodOptional<z.ZodString>;
1824
+ mapName: z.ZodOptional<z.ZodString>;
1825
+ types: z.ZodOptional<z.ZodArray<z.ZodEnum<{
1826
+ PUT: "PUT";
1827
+ UPDATE: "UPDATE";
1828
+ DELETE: "DELETE";
1829
+ }>>>;
1830
+ }, z.core.$strip>;
1831
+ /**
1832
+ * JOURNAL_UNSUBSCRIBE: Client unsubscribes from journal events.
1833
+ */
1834
+ declare const JournalUnsubscribeRequestSchema: z.ZodObject<{
1835
+ type: z.ZodLiteral<"JOURNAL_UNSUBSCRIBE">;
1836
+ subscriptionId: z.ZodString;
1837
+ }, z.core.$strip>;
1838
+ /**
1839
+ * JOURNAL_EVENT: Server sends journal event to client.
1840
+ */
1841
+ declare const JournalEventMessageSchema: z.ZodObject<{
1842
+ type: z.ZodLiteral<"JOURNAL_EVENT">;
1843
+ event: z.ZodObject<{
1844
+ sequence: z.ZodString;
1845
+ type: z.ZodEnum<{
1846
+ PUT: "PUT";
1847
+ UPDATE: "UPDATE";
1848
+ DELETE: "DELETE";
1849
+ }>;
1850
+ mapName: z.ZodString;
1851
+ key: z.ZodString;
1852
+ value: z.ZodOptional<z.ZodUnknown>;
1853
+ previousValue: z.ZodOptional<z.ZodUnknown>;
1854
+ timestamp: z.ZodObject<{
1855
+ millis: z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodBigInt]>, z.ZodTransform<number, number | bigint>>;
1856
+ counter: z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodBigInt]>, z.ZodTransform<number, number | bigint>>;
1857
+ nodeId: z.ZodString;
1858
+ }, z.core.$strip>;
1859
+ nodeId: z.ZodString;
1860
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1861
+ }, z.core.$strip>;
1862
+ }, z.core.$strip>;
1863
+ /**
1864
+ * JOURNAL_READ: Client requests events from journal.
1865
+ */
1866
+ declare const JournalReadRequestSchema: z.ZodObject<{
1867
+ type: z.ZodLiteral<"JOURNAL_READ">;
1868
+ requestId: z.ZodString;
1869
+ fromSequence: z.ZodString;
1870
+ limit: z.ZodOptional<z.ZodNumber>;
1871
+ mapName: z.ZodOptional<z.ZodString>;
1872
+ }, z.core.$strip>;
1873
+ /**
1874
+ * JOURNAL_READ_RESPONSE: Server responds with journal events.
1875
+ */
1876
+ declare const JournalReadResponseSchema: z.ZodObject<{
1877
+ type: z.ZodLiteral<"JOURNAL_READ_RESPONSE">;
1878
+ requestId: z.ZodString;
1879
+ events: z.ZodArray<z.ZodObject<{
1880
+ sequence: z.ZodString;
1881
+ type: z.ZodEnum<{
1882
+ PUT: "PUT";
1883
+ UPDATE: "UPDATE";
1884
+ DELETE: "DELETE";
1885
+ }>;
1886
+ mapName: z.ZodString;
1887
+ key: z.ZodString;
1888
+ value: z.ZodOptional<z.ZodUnknown>;
1889
+ previousValue: z.ZodOptional<z.ZodUnknown>;
1890
+ timestamp: z.ZodObject<{
1891
+ millis: z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodBigInt]>, z.ZodTransform<number, number | bigint>>;
1892
+ counter: z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodBigInt]>, z.ZodTransform<number, number | bigint>>;
1893
+ nodeId: z.ZodString;
1894
+ }, z.core.$strip>;
1895
+ nodeId: z.ZodString;
1896
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1897
+ }, z.core.$strip>>;
1898
+ hasMore: z.ZodBoolean;
1899
+ }, z.core.$strip>;
1900
+ /**
1901
+ * Conflict resolver definition schema (wire format).
1902
+ */
1903
+ declare const ConflictResolverSchema: z.ZodObject<{
1904
+ name: z.ZodString;
1905
+ code: z.ZodString;
1906
+ priority: z.ZodOptional<z.ZodNumber>;
1907
+ keyPattern: z.ZodOptional<z.ZodString>;
1908
+ }, z.core.$strip>;
1909
+ /**
1910
+ * REGISTER_RESOLVER: Client registers a conflict resolver on server.
1911
+ */
1912
+ declare const RegisterResolverRequestSchema: z.ZodObject<{
1913
+ type: z.ZodLiteral<"REGISTER_RESOLVER">;
1914
+ requestId: z.ZodString;
1915
+ mapName: z.ZodString;
1916
+ resolver: z.ZodObject<{
1917
+ name: z.ZodString;
1918
+ code: z.ZodString;
1919
+ priority: z.ZodOptional<z.ZodNumber>;
1920
+ keyPattern: z.ZodOptional<z.ZodString>;
1921
+ }, z.core.$strip>;
1922
+ }, z.core.$strip>;
1923
+ /**
1924
+ * REGISTER_RESOLVER_RESPONSE: Server acknowledges resolver registration.
1925
+ */
1926
+ declare const RegisterResolverResponseSchema: z.ZodObject<{
1927
+ type: z.ZodLiteral<"REGISTER_RESOLVER_RESPONSE">;
1928
+ requestId: z.ZodString;
1929
+ success: z.ZodBoolean;
1930
+ error: z.ZodOptional<z.ZodString>;
1931
+ }, z.core.$strip>;
1932
+ /**
1933
+ * UNREGISTER_RESOLVER: Client unregisters a conflict resolver.
1934
+ */
1935
+ declare const UnregisterResolverRequestSchema: z.ZodObject<{
1936
+ type: z.ZodLiteral<"UNREGISTER_RESOLVER">;
1937
+ requestId: z.ZodString;
1938
+ mapName: z.ZodString;
1939
+ resolverName: z.ZodString;
1940
+ }, z.core.$strip>;
1941
+ /**
1942
+ * UNREGISTER_RESOLVER_RESPONSE: Server acknowledges resolver unregistration.
1943
+ */
1944
+ declare const UnregisterResolverResponseSchema: z.ZodObject<{
1945
+ type: z.ZodLiteral<"UNREGISTER_RESOLVER_RESPONSE">;
1946
+ requestId: z.ZodString;
1947
+ success: z.ZodBoolean;
1948
+ error: z.ZodOptional<z.ZodString>;
1949
+ }, z.core.$strip>;
1950
+ /**
1951
+ * MERGE_REJECTED: Server notifies client that a merge was rejected.
1952
+ */
1953
+ declare const MergeRejectedMessageSchema: z.ZodObject<{
1954
+ type: z.ZodLiteral<"MERGE_REJECTED">;
1955
+ mapName: z.ZodString;
1956
+ key: z.ZodString;
1957
+ attemptedValue: z.ZodUnknown;
1958
+ reason: z.ZodString;
1959
+ timestamp: z.ZodObject<{
1960
+ millis: z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodBigInt]>, z.ZodTransform<number, number | bigint>>;
1961
+ counter: z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodBigInt]>, z.ZodTransform<number, number | bigint>>;
1962
+ nodeId: z.ZodString;
1963
+ }, z.core.$strip>;
1964
+ }, z.core.$strip>;
1965
+ /**
1966
+ * LIST_RESOLVERS: Client requests list of registered resolvers.
1967
+ */
1968
+ declare const ListResolversRequestSchema: z.ZodObject<{
1969
+ type: z.ZodLiteral<"LIST_RESOLVERS">;
1970
+ requestId: z.ZodString;
1971
+ mapName: z.ZodOptional<z.ZodString>;
1972
+ }, z.core.$strip>;
1973
+ /**
1974
+ * LIST_RESOLVERS_RESPONSE: Server responds with registered resolvers.
1975
+ */
1976
+ declare const ListResolversResponseSchema: z.ZodObject<{
1977
+ type: z.ZodLiteral<"LIST_RESOLVERS_RESPONSE">;
1978
+ requestId: z.ZodString;
1979
+ resolvers: z.ZodArray<z.ZodObject<{
1980
+ mapName: z.ZodString;
1981
+ name: z.ZodString;
1982
+ priority: z.ZodOptional<z.ZodNumber>;
1983
+ keyPattern: z.ZodOptional<z.ZodString>;
1984
+ }, z.core.$strip>>;
1985
+ }, z.core.$strip>;
954
1986
  /**
955
1987
  * Individual operation result within a batch ACK
956
1988
  */
@@ -1294,8 +2326,170 @@ declare const MessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1294
2326
  payload: z.ZodOptional<z.ZodObject<{
1295
2327
  currentVersion: z.ZodOptional<z.ZodNumber>;
1296
2328
  }, z.core.$strip>>;
2329
+ }, z.core.$strip>, z.ZodObject<{
2330
+ type: z.ZodLiteral<"COUNTER_REQUEST">;
2331
+ payload: z.ZodObject<{
2332
+ name: z.ZodString;
2333
+ }, z.core.$strip>;
2334
+ }, z.core.$strip>, z.ZodObject<{
2335
+ type: z.ZodLiteral<"COUNTER_SYNC">;
2336
+ payload: z.ZodObject<{
2337
+ name: z.ZodString;
2338
+ state: z.ZodObject<{
2339
+ p: z.ZodRecord<z.ZodString, z.ZodNumber>;
2340
+ n: z.ZodRecord<z.ZodString, z.ZodNumber>;
2341
+ }, z.core.$strip>;
2342
+ }, z.core.$strip>;
2343
+ }, z.core.$strip>, z.ZodObject<{
2344
+ type: z.ZodLiteral<"ENTRY_PROCESS">;
2345
+ requestId: z.ZodString;
2346
+ mapName: z.ZodString;
2347
+ key: z.ZodString;
2348
+ processor: z.ZodObject<{
2349
+ name: z.ZodString;
2350
+ code: z.ZodString;
2351
+ args: z.ZodOptional<z.ZodUnknown>;
2352
+ }, z.core.$strip>;
2353
+ }, z.core.$strip>, z.ZodObject<{
2354
+ type: z.ZodLiteral<"ENTRY_PROCESS_BATCH">;
2355
+ requestId: z.ZodString;
2356
+ mapName: z.ZodString;
2357
+ keys: z.ZodArray<z.ZodString>;
2358
+ processor: z.ZodObject<{
2359
+ name: z.ZodString;
2360
+ code: z.ZodString;
2361
+ args: z.ZodOptional<z.ZodUnknown>;
2362
+ }, z.core.$strip>;
2363
+ }, z.core.$strip>, z.ZodObject<{
2364
+ type: z.ZodLiteral<"ENTRY_PROCESS_RESPONSE">;
2365
+ requestId: z.ZodString;
2366
+ success: z.ZodBoolean;
2367
+ result: z.ZodOptional<z.ZodUnknown>;
2368
+ newValue: z.ZodOptional<z.ZodUnknown>;
2369
+ error: z.ZodOptional<z.ZodString>;
2370
+ }, z.core.$strip>, z.ZodObject<{
2371
+ type: z.ZodLiteral<"ENTRY_PROCESS_BATCH_RESPONSE">;
2372
+ requestId: z.ZodString;
2373
+ results: z.ZodRecord<z.ZodString, z.ZodObject<{
2374
+ success: z.ZodBoolean;
2375
+ result: z.ZodOptional<z.ZodUnknown>;
2376
+ newValue: z.ZodOptional<z.ZodUnknown>;
2377
+ error: z.ZodOptional<z.ZodString>;
2378
+ }, z.core.$strip>>;
2379
+ }, z.core.$strip>, z.ZodObject<{
2380
+ type: z.ZodLiteral<"JOURNAL_SUBSCRIBE">;
2381
+ requestId: z.ZodString;
2382
+ fromSequence: z.ZodOptional<z.ZodString>;
2383
+ mapName: z.ZodOptional<z.ZodString>;
2384
+ types: z.ZodOptional<z.ZodArray<z.ZodEnum<{
2385
+ PUT: "PUT";
2386
+ UPDATE: "UPDATE";
2387
+ DELETE: "DELETE";
2388
+ }>>>;
2389
+ }, z.core.$strip>, z.ZodObject<{
2390
+ type: z.ZodLiteral<"JOURNAL_UNSUBSCRIBE">;
2391
+ subscriptionId: z.ZodString;
2392
+ }, z.core.$strip>, z.ZodObject<{
2393
+ type: z.ZodLiteral<"JOURNAL_EVENT">;
2394
+ event: z.ZodObject<{
2395
+ sequence: z.ZodString;
2396
+ type: z.ZodEnum<{
2397
+ PUT: "PUT";
2398
+ UPDATE: "UPDATE";
2399
+ DELETE: "DELETE";
2400
+ }>;
2401
+ mapName: z.ZodString;
2402
+ key: z.ZodString;
2403
+ value: z.ZodOptional<z.ZodUnknown>;
2404
+ previousValue: z.ZodOptional<z.ZodUnknown>;
2405
+ timestamp: z.ZodObject<{
2406
+ millis: z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodBigInt]>, z.ZodTransform<number, number | bigint>>;
2407
+ counter: z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodBigInt]>, z.ZodTransform<number, number | bigint>>;
2408
+ nodeId: z.ZodString;
2409
+ }, z.core.$strip>;
2410
+ nodeId: z.ZodString;
2411
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2412
+ }, z.core.$strip>;
2413
+ }, z.core.$strip>, z.ZodObject<{
2414
+ type: z.ZodLiteral<"JOURNAL_READ">;
2415
+ requestId: z.ZodString;
2416
+ fromSequence: z.ZodString;
2417
+ limit: z.ZodOptional<z.ZodNumber>;
2418
+ mapName: z.ZodOptional<z.ZodString>;
2419
+ }, z.core.$strip>, z.ZodObject<{
2420
+ type: z.ZodLiteral<"JOURNAL_READ_RESPONSE">;
2421
+ requestId: z.ZodString;
2422
+ events: z.ZodArray<z.ZodObject<{
2423
+ sequence: z.ZodString;
2424
+ type: z.ZodEnum<{
2425
+ PUT: "PUT";
2426
+ UPDATE: "UPDATE";
2427
+ DELETE: "DELETE";
2428
+ }>;
2429
+ mapName: z.ZodString;
2430
+ key: z.ZodString;
2431
+ value: z.ZodOptional<z.ZodUnknown>;
2432
+ previousValue: z.ZodOptional<z.ZodUnknown>;
2433
+ timestamp: z.ZodObject<{
2434
+ millis: z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodBigInt]>, z.ZodTransform<number, number | bigint>>;
2435
+ counter: z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodBigInt]>, z.ZodTransform<number, number | bigint>>;
2436
+ nodeId: z.ZodString;
2437
+ }, z.core.$strip>;
2438
+ nodeId: z.ZodString;
2439
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2440
+ }, z.core.$strip>>;
2441
+ hasMore: z.ZodBoolean;
2442
+ }, z.core.$strip>, z.ZodObject<{
2443
+ type: z.ZodLiteral<"REGISTER_RESOLVER">;
2444
+ requestId: z.ZodString;
2445
+ mapName: z.ZodString;
2446
+ resolver: z.ZodObject<{
2447
+ name: z.ZodString;
2448
+ code: z.ZodString;
2449
+ priority: z.ZodOptional<z.ZodNumber>;
2450
+ keyPattern: z.ZodOptional<z.ZodString>;
2451
+ }, z.core.$strip>;
2452
+ }, z.core.$strip>, z.ZodObject<{
2453
+ type: z.ZodLiteral<"REGISTER_RESOLVER_RESPONSE">;
2454
+ requestId: z.ZodString;
2455
+ success: z.ZodBoolean;
2456
+ error: z.ZodOptional<z.ZodString>;
2457
+ }, z.core.$strip>, z.ZodObject<{
2458
+ type: z.ZodLiteral<"UNREGISTER_RESOLVER">;
2459
+ requestId: z.ZodString;
2460
+ mapName: z.ZodString;
2461
+ resolverName: z.ZodString;
2462
+ }, z.core.$strip>, z.ZodObject<{
2463
+ type: z.ZodLiteral<"UNREGISTER_RESOLVER_RESPONSE">;
2464
+ requestId: z.ZodString;
2465
+ success: z.ZodBoolean;
2466
+ error: z.ZodOptional<z.ZodString>;
2467
+ }, z.core.$strip>, z.ZodObject<{
2468
+ type: z.ZodLiteral<"MERGE_REJECTED">;
2469
+ mapName: z.ZodString;
2470
+ key: z.ZodString;
2471
+ attemptedValue: z.ZodUnknown;
2472
+ reason: z.ZodString;
2473
+ timestamp: z.ZodObject<{
2474
+ millis: z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodBigInt]>, z.ZodTransform<number, number | bigint>>;
2475
+ counter: z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodBigInt]>, z.ZodTransform<number, number | bigint>>;
2476
+ nodeId: z.ZodString;
2477
+ }, z.core.$strip>;
2478
+ }, z.core.$strip>, z.ZodObject<{
2479
+ type: z.ZodLiteral<"LIST_RESOLVERS">;
2480
+ requestId: z.ZodString;
2481
+ mapName: z.ZodOptional<z.ZodString>;
2482
+ }, z.core.$strip>, z.ZodObject<{
2483
+ type: z.ZodLiteral<"LIST_RESOLVERS_RESPONSE">;
2484
+ requestId: z.ZodString;
2485
+ resolvers: z.ZodArray<z.ZodObject<{
2486
+ mapName: z.ZodString;
2487
+ name: z.ZodString;
2488
+ priority: z.ZodOptional<z.ZodNumber>;
2489
+ keyPattern: z.ZodOptional<z.ZodString>;
2490
+ }, z.core.$strip>>;
1297
2491
  }, z.core.$strip>], "type">;
1298
- type Query = z.infer<typeof QuerySchema>;
2492
+ type Query$1 = z.infer<typeof QuerySchema>;
1299
2493
  type ClientOp = z.infer<typeof ClientOpSchema>;
1300
2494
  type Message = z.infer<typeof MessageSchema>;
1301
2495
  type PingMessage = z.infer<typeof PingMessageSchema>;
@@ -1304,6 +2498,25 @@ type BatchMessage = z.infer<typeof BatchMessageSchema>;
1304
2498
  type OpAckMessage = z.infer<typeof OpAckMessageSchema>;
1305
2499
  type OpRejectedMessage = z.infer<typeof OpRejectedMessageSchema>;
1306
2500
  type OpResult = z.infer<typeof OpResultSchema>;
2501
+ type EntryProcessRequest = z.infer<typeof EntryProcessRequestSchema>;
2502
+ type EntryProcessBatchRequest = z.infer<typeof EntryProcessBatchRequestSchema>;
2503
+ type EntryProcessResponse = z.infer<typeof EntryProcessResponseSchema>;
2504
+ type EntryProcessBatchResponse = z.infer<typeof EntryProcessBatchResponseSchema>;
2505
+ type EntryProcessKeyResult = z.infer<typeof EntryProcessKeyResultSchema>;
2506
+ type JournalEventData = z.infer<typeof JournalEventDataSchema>;
2507
+ type JournalSubscribeRequest = z.infer<typeof JournalSubscribeRequestSchema>;
2508
+ type JournalUnsubscribeRequest = z.infer<typeof JournalUnsubscribeRequestSchema>;
2509
+ type JournalEventMessage = z.infer<typeof JournalEventMessageSchema>;
2510
+ type JournalReadRequest = z.infer<typeof JournalReadRequestSchema>;
2511
+ type JournalReadResponse = z.infer<typeof JournalReadResponseSchema>;
2512
+ type ConflictResolver = z.infer<typeof ConflictResolverSchema>;
2513
+ type RegisterResolverRequest = z.infer<typeof RegisterResolverRequestSchema>;
2514
+ type RegisterResolverResponse = z.infer<typeof RegisterResolverResponseSchema>;
2515
+ type UnregisterResolverRequest = z.infer<typeof UnregisterResolverRequestSchema>;
2516
+ type UnregisterResolverResponse = z.infer<typeof UnregisterResolverResponseSchema>;
2517
+ type MergeRejectedMessage = z.infer<typeof MergeRejectedMessageSchema>;
2518
+ type ListResolversRequest = z.infer<typeof ListResolversRequestSchema>;
2519
+ type ListResolversResponse = z.infer<typeof ListResolversResponseSchema>;
1307
2520
 
1308
2521
  /**
1309
2522
  * Write Concern - Configurable Acknowledgment Levels
@@ -1773,4 +2986,3282 @@ type ReplicationProtocolMessage = ReplicationMessage | ReplicationBatchMessage |
1773
2986
  declare const PARTITION_COUNT = 271;
1774
2987
  declare const DEFAULT_BACKUP_COUNT = 1;
1775
2988
 
1776
- export { AuthMessageSchema, type BatchMessage, BatchMessageSchema, type CircuitBreakerConfig, type ClientOp, ClientOpMessageSchema, ClientOpSchema, type ClusterClientConfig, type ClusterEvents, type ReadOptions as ClusterReadOptions, type WriteOptions as ClusterWriteOptions, type ConnectionPoolConfig, type ConnectionState, ConsistencyLevel, DEFAULT_BACKUP_COUNT, DEFAULT_CIRCUIT_BREAKER_CONFIG, DEFAULT_CONNECTION_POOL_CONFIG, DEFAULT_MIGRATION_CONFIG, DEFAULT_PARTITION_ROUTER_CONFIG, DEFAULT_REPLICATION_CONFIG, DEFAULT_WRITE_CONCERN_TIMEOUT, HLC, LWWMap, type LWWRecord, LWWRecordSchema, LockReleaseSchema, LockRequestSchema, type MergeKeyResult, MerkleReqBucketMessageSchema, MerkleTree, type Message, MessageSchema, type MigrationChunkAckMessage, type MigrationChunkMessage, type MigrationCompleteMessage, type MigrationConfig, type MigrationMessage, type MigrationMetrics, type MigrationStartMessage, type MigrationStatus, type MigrationVerifyMessage, type NodeHealth, type NodeInfo, type NodeStatus, type NotOwnerError, ORMap, ORMapDiffRequestSchema, ORMapDiffResponseSchema, type ORMapMerkleNode, ORMapMerkleReqBucketSchema, ORMapMerkleTree, ORMapPushDiffSchema, type ORMapRecord, ORMapRecordSchema, type ORMapSnapshot, ORMapSyncInitSchema, ORMapSyncRespBucketsSchema, ORMapSyncRespLeafSchema, ORMapSyncRespRootSchema, type OpAckMessage, OpAckMessageSchema, OpBatchMessageSchema, type OpRejectedMessage, OpRejectedMessageSchema, type OpResult, OpResultSchema, PARTITION_COUNT, type PartitionChange, type PartitionInfo, type PartitionMap, type PartitionMapDeltaMessage, type PartitionMapMessage, type PartitionMapRequestMessage, PartitionMapRequestSchema, type PartitionMigration, type PartitionRouterConfig, PartitionState, type PendingWrite, type PermissionPolicy, type PermissionType, type PingMessage, PingMessageSchema, type PongMessage, PongMessageSchema, type PredicateNode, PredicateNodeSchema, type PredicateOp, PredicateOpSchema, Predicates, type Principal, type Query, QuerySchema, QuerySubMessageSchema, QueryUnsubMessageSchema, type ReplicationAckMessage, type ReplicationBatchAckMessage, type ReplicationBatchMessage, type ReplicationConfig, type ReplicationHealth, type ReplicationLag, type ReplicationMessage, type ReplicationProtocolMessage, type ReplicationResult, type ReplicationTask, type RoutingError, type StaleMapError, SyncInitMessageSchema, SyncRespBucketsMessageSchema, SyncRespLeafMessageSchema, SyncRespRootMessageSchema, type Timestamp, TimestampSchema, TopicMessageEventSchema, TopicPubSchema, TopicSubSchema, TopicUnsubSchema, WRITE_CONCERN_ORDER, WriteConcern, WriteConcernSchema, type WriteConcernValue, type WriteOptions$1 as WriteOptions, type WriteResult, combineHashes, compareTimestamps, deserialize, disableNativeHash, evaluatePredicate, getHighestWriteConcernLevel, hashORMapEntry, hashORMapRecord, hashString, isUsingNativeHash, isWriteConcernAchieved, resetNativeHash, serialize, timestampToString };
2989
+ /**
2990
+ * Common types for sorted data structures
2991
+ */
2992
+ /**
2993
+ * Comparator function for ordering keys
2994
+ */
2995
+ type Comparator<K> = (a: K, b: K) => number;
2996
+ /**
2997
+ * Options for range queries
2998
+ */
2999
+ interface RangeOptions {
3000
+ /** Include the lower bound in results (default: true) */
3001
+ fromInclusive?: boolean;
3002
+ /** Include the upper bound in results (default: false) */
3003
+ toInclusive?: boolean;
3004
+ }
3005
+
3006
+ /**
3007
+ * Type-safe wrapper over sorted-btree for use in NavigableIndex
3008
+ *
3009
+ * Provides O(log N) operations for:
3010
+ * - set/get/delete
3011
+ * - range queries
3012
+ * - greaterThan/lessThan queries
3013
+ */
3014
+
3015
+ /**
3016
+ * A sorted map implementation backed by a B+ tree.
3017
+ * Provides efficient range queries and ordered iteration.
3018
+ *
3019
+ * @template K - Key type (must be comparable)
3020
+ * @template V - Value type
3021
+ */
3022
+ declare class SortedMap<K, V> {
3023
+ private readonly tree;
3024
+ private readonly comparator;
3025
+ constructor(comparator?: Comparator<K>);
3026
+ /**
3027
+ * Set a key-value pair. Updates existing key if present.
3028
+ * Time complexity: O(log N)
3029
+ */
3030
+ set(key: K, value: V): this;
3031
+ /**
3032
+ * Get the value for a key.
3033
+ * Time complexity: O(log N)
3034
+ */
3035
+ get(key: K): V | undefined;
3036
+ /**
3037
+ * Delete a key from the map.
3038
+ * Time complexity: O(log N)
3039
+ * @returns true if the key existed and was deleted
3040
+ */
3041
+ delete(key: K): boolean;
3042
+ /**
3043
+ * Check if a key exists in the map.
3044
+ * Time complexity: O(log N)
3045
+ */
3046
+ has(key: K): boolean;
3047
+ /**
3048
+ * Get the number of entries in the map.
3049
+ */
3050
+ get size(): number;
3051
+ /**
3052
+ * Check if the map is empty.
3053
+ */
3054
+ get isEmpty(): boolean;
3055
+ /**
3056
+ * Get the minimum key in the map.
3057
+ * Time complexity: O(log N)
3058
+ */
3059
+ minKey(): K | undefined;
3060
+ /**
3061
+ * Get the maximum key in the map.
3062
+ * Time complexity: O(log N)
3063
+ */
3064
+ maxKey(): K | undefined;
3065
+ /**
3066
+ * Iterate over entries in a range [from, to).
3067
+ * Time complexity: O(log N + K) where K is the number of results
3068
+ *
3069
+ * @param from - Lower bound
3070
+ * @param to - Upper bound
3071
+ * @param options - Range options for inclusive/exclusive bounds
3072
+ */
3073
+ range(from: K, to: K, options?: RangeOptions): IterableIterator<[K, V]>;
3074
+ /**
3075
+ * Iterate over entries where key > value (or >= if inclusive).
3076
+ * Time complexity: O(log N + K) where K is the number of results
3077
+ *
3078
+ * @param key - Lower bound
3079
+ * @param inclusive - Include the bound in results (default: false)
3080
+ */
3081
+ greaterThan(key: K, inclusive?: boolean): IterableIterator<[K, V]>;
3082
+ /**
3083
+ * Iterate over entries where key < value (or <= if inclusive).
3084
+ * Time complexity: O(log N + K) where K is the number of results
3085
+ *
3086
+ * Note: This method iterates from the beginning of the tree.
3087
+ * The O(log N) component is for finding the upper bound,
3088
+ * and O(K) is for yielding K results.
3089
+ *
3090
+ * @param key - Upper bound
3091
+ * @param inclusive - Include the bound in results (default: false)
3092
+ */
3093
+ lessThan(key: K, inclusive?: boolean): IterableIterator<[K, V]>;
3094
+ /**
3095
+ * Iterate over all entries in sorted order.
3096
+ * Time complexity: O(N)
3097
+ */
3098
+ entries(): IterableIterator<[K, V]>;
3099
+ /**
3100
+ * Iterate over all keys in sorted order.
3101
+ * Time complexity: O(N)
3102
+ */
3103
+ keys(): IterableIterator<K>;
3104
+ /**
3105
+ * Iterate over all values in sorted order.
3106
+ * Time complexity: O(N)
3107
+ */
3108
+ values(): IterableIterator<V>;
3109
+ /**
3110
+ * Iterate over entries in reverse sorted order.
3111
+ * Time complexity: O(N)
3112
+ */
3113
+ entriesReversed(): IterableIterator<[K, V]>;
3114
+ /**
3115
+ * Remove all entries from the map.
3116
+ */
3117
+ clear(): void;
3118
+ /**
3119
+ * Execute a callback for each entry in sorted order.
3120
+ */
3121
+ forEach(callback: (value: V, key: K, map: this) => void): void;
3122
+ /**
3123
+ * Create a new SortedMap from entries.
3124
+ */
3125
+ static from<K, V>(entries: Iterable<[K, V]>, comparator?: Comparator<K>): SortedMap<K, V>;
3126
+ /**
3127
+ * Get or set a value using a factory function.
3128
+ * If the key doesn't exist, the factory is called to create the value.
3129
+ */
3130
+ getOrSet(key: K, factory: () => V): V;
3131
+ /**
3132
+ * Update a value if the key exists.
3133
+ * @returns true if the key existed and was updated
3134
+ */
3135
+ update(key: K, updater: (value: V) => V): boolean;
3136
+ /**
3137
+ * Get the entry at a specific index (0-based).
3138
+ * Time complexity: O(N) - requires linear scan from the beginning.
3139
+ * Note: B+ trees do not support O(log N) index-based access.
3140
+ */
3141
+ at(index: number): [K, V] | undefined;
3142
+ /**
3143
+ * Find the greatest key less than the given key.
3144
+ * Time complexity: O(log N)
3145
+ */
3146
+ lowerKey(key: K): K | undefined;
3147
+ /**
3148
+ * Find the greatest key less than or equal to the given key.
3149
+ * Time complexity: O(log N)
3150
+ */
3151
+ floorKey(key: K): K | undefined;
3152
+ /**
3153
+ * Find the least key greater than the given key.
3154
+ * Time complexity: O(log N)
3155
+ */
3156
+ higherKey(key: K): K | undefined;
3157
+ /**
3158
+ * Find the least key greater than or equal to the given key.
3159
+ * Time complexity: O(log N)
3160
+ */
3161
+ ceilingKey(key: K): K | undefined;
3162
+ /**
3163
+ * Make the map iterable.
3164
+ */
3165
+ [Symbol.iterator](): IterableIterator<[K, V]>;
3166
+ }
3167
+
3168
+ /**
3169
+ * Attribute System for Query Engine
3170
+ *
3171
+ * Attributes extract value(s) from records for indexing and querying.
3172
+ * Inspired by CQEngine Attribute<O, A>.
3173
+ *
3174
+ * @module query/Attribute
3175
+ */
3176
+ /**
3177
+ * Attribute extracts value(s) from a record.
3178
+ * V = Record value type, A = Attribute value type
3179
+ */
3180
+ interface Attribute<V, A> {
3181
+ /** Unique attribute name */
3182
+ readonly name: string;
3183
+ /** Attribute value type */
3184
+ readonly type: 'simple' | 'multi';
3185
+ /**
3186
+ * Extract value from record.
3187
+ * Returns undefined if attribute doesn't exist.
3188
+ */
3189
+ getValue(record: V): A | undefined;
3190
+ /**
3191
+ * For multi-value attributes, returns all values.
3192
+ * For simple attributes, returns single-element array.
3193
+ */
3194
+ getValues(record: V): A[];
3195
+ }
3196
+ /**
3197
+ * Attribute that returns exactly one value per record.
3198
+ */
3199
+ declare class SimpleAttribute<V, A> implements Attribute<V, A> {
3200
+ readonly name: string;
3201
+ private readonly extractor;
3202
+ readonly type: "simple";
3203
+ constructor(name: string, extractor: (record: V) => A | undefined);
3204
+ getValue(record: V): A | undefined;
3205
+ getValues(record: V): A[];
3206
+ }
3207
+ /**
3208
+ * Factory function for SimpleAttribute.
3209
+ */
3210
+ declare function simpleAttribute<V, A>(name: string, extractor: (record: V) => A | undefined): SimpleAttribute<V, A>;
3211
+ /**
3212
+ * Attribute that returns zero or more values per record.
3213
+ * Example: tags, categories, roles.
3214
+ */
3215
+ declare class MultiValueAttribute<V, A> implements Attribute<V, A> {
3216
+ readonly name: string;
3217
+ private readonly extractor;
3218
+ readonly type: "multi";
3219
+ constructor(name: string, extractor: (record: V) => A[]);
3220
+ getValue(record: V): A | undefined;
3221
+ getValues(record: V): A[];
3222
+ }
3223
+ /**
3224
+ * Factory function for MultiValueAttribute.
3225
+ */
3226
+ declare function multiAttribute<V, A>(name: string, extractor: (record: V) => A[]): MultiValueAttribute<V, A>;
3227
+
3228
+ /**
3229
+ * ResultSet Interface
3230
+ *
3231
+ * Lazy result set from index queries.
3232
+ * Inspired by CQEngine ResultSet<O>.
3233
+ *
3234
+ * @module query/resultset/ResultSet
3235
+ */
3236
+ /**
3237
+ * Lazy result set from index query.
3238
+ * K = record key type
3239
+ */
3240
+ interface ResultSet<K> {
3241
+ /**
3242
+ * Iterate over matching keys.
3243
+ * Lazy evaluation where possible.
3244
+ */
3245
+ [Symbol.iterator](): Iterator<K>;
3246
+ /**
3247
+ * Cost of retrieving these results.
3248
+ * Used by QueryOptimizer for index selection.
3249
+ */
3250
+ getRetrievalCost(): number;
3251
+ /**
3252
+ * Estimated cost of merging/processing these results.
3253
+ * Usually based on result count.
3254
+ */
3255
+ getMergeCost(): number;
3256
+ /**
3257
+ * Check if result set contains key.
3258
+ */
3259
+ contains(key: K): boolean;
3260
+ /**
3261
+ * Get result count.
3262
+ * May require iteration for lazy result sets.
3263
+ */
3264
+ size(): number;
3265
+ /**
3266
+ * Materialize to array.
3267
+ */
3268
+ toArray(): K[];
3269
+ /**
3270
+ * Check if empty.
3271
+ */
3272
+ isEmpty(): boolean;
3273
+ }
3274
+
3275
+ /**
3276
+ * Base Index Interface
3277
+ *
3278
+ * Defines the contract for all index types in the Query Engine.
3279
+ * Inspired by CQEngine Index hierarchy.
3280
+ *
3281
+ * @module query/indexes/types
3282
+ */
3283
+
3284
+ /**
3285
+ * Base interface for all indexes.
3286
+ * K = record key type, V = record value type, A = attribute value type
3287
+ */
3288
+ interface Index<K, V, A = unknown> {
3289
+ /** Attribute this index is built on */
3290
+ readonly attribute: Attribute<V, A>;
3291
+ /** Index type identifier */
3292
+ readonly type: 'hash' | 'navigable' | 'compound' | 'standing' | 'inverted';
3293
+ /**
3294
+ * Cost of retrieving results from this index.
3295
+ * Lower is better. Used by QueryOptimizer.
3296
+ * CQEngine values: Standing=10, Compound=20, Hash=30, Navigable=40
3297
+ */
3298
+ getRetrievalCost(): number;
3299
+ /**
3300
+ * Check if this index supports the given query type.
3301
+ */
3302
+ supportsQuery(queryType: string): boolean;
3303
+ /**
3304
+ * Retrieve candidate keys matching the query.
3305
+ */
3306
+ retrieve(query: IndexQuery<A>): ResultSet<K>;
3307
+ /**
3308
+ * Add a record to the index.
3309
+ */
3310
+ add(key: K, record: V): void;
3311
+ /**
3312
+ * Remove a record from the index.
3313
+ */
3314
+ remove(key: K, record: V): void;
3315
+ /**
3316
+ * Update a record in the index.
3317
+ */
3318
+ update(key: K, oldRecord: V, newRecord: V): void;
3319
+ /**
3320
+ * Clear all entries from the index.
3321
+ */
3322
+ clear(): void;
3323
+ /**
3324
+ * Get statistics about the index.
3325
+ */
3326
+ getStats(): IndexStats;
3327
+ }
3328
+ /**
3329
+ * Query parameters for index retrieval.
3330
+ */
3331
+ interface IndexQuery<A> {
3332
+ /** Query type */
3333
+ type: 'equal' | 'in' | 'has' | 'gt' | 'gte' | 'lt' | 'lte' | 'between' | 'contains' | 'containsAll' | 'containsAny';
3334
+ /** Value for equality queries */
3335
+ value?: A;
3336
+ /** Values for 'in' queries */
3337
+ values?: A[];
3338
+ /** Lower bound for range queries */
3339
+ from?: A;
3340
+ /** Upper bound for range queries */
3341
+ to?: A;
3342
+ /** Include lower bound (default: true) */
3343
+ fromInclusive?: boolean;
3344
+ /** Include upper bound (default: false) */
3345
+ toInclusive?: boolean;
3346
+ }
3347
+ /**
3348
+ * Statistics about an index.
3349
+ */
3350
+ interface IndexStats {
3351
+ /** Number of distinct attribute values indexed */
3352
+ distinctValues: number;
3353
+ /** Total number of record references */
3354
+ totalEntries: number;
3355
+ /** Average entries per distinct value */
3356
+ avgEntriesPerValue: number;
3357
+ }
3358
+
3359
+ /**
3360
+ * HashIndex Implementation
3361
+ *
3362
+ * Hash-based index for O(1) equality lookups.
3363
+ * Supports: equal, in, has queries.
3364
+ *
3365
+ * Structure: Map<AttributeValue, Set<RecordKey>>
3366
+ *
3367
+ * CQEngine Reference: HashIndex.java (retrieval cost: 30)
3368
+ *
3369
+ * @module query/indexes/HashIndex
3370
+ */
3371
+
3372
+ /**
3373
+ * Hash-based index for O(1) equality lookups.
3374
+ *
3375
+ * K = record key type, V = record value type, A = attribute value type
3376
+ */
3377
+ declare class HashIndex<K, V, A> implements Index<K, V, A> {
3378
+ readonly attribute: Attribute<V, A>;
3379
+ readonly type: "hash";
3380
+ /** Map from attribute value to set of record keys */
3381
+ private data;
3382
+ /** Set of all keys with non-null attribute value */
3383
+ private allKeys;
3384
+ private static readonly RETRIEVAL_COST;
3385
+ private static readonly SUPPORTED_QUERIES;
3386
+ constructor(attribute: Attribute<V, A>);
3387
+ getRetrievalCost(): number;
3388
+ supportsQuery(queryType: string): boolean;
3389
+ retrieve(query: IndexQuery<A>): ResultSet<K>;
3390
+ private retrieveEqual;
3391
+ private retrieveIn;
3392
+ private retrieveHas;
3393
+ add(key: K, record: V): void;
3394
+ remove(key: K, record: V): void;
3395
+ update(key: K, oldRecord: V, newRecord: V): void;
3396
+ clear(): void;
3397
+ getStats(): IndexStats;
3398
+ private arraysEqual;
3399
+ }
3400
+
3401
+ /**
3402
+ * NavigableIndex Implementation
3403
+ *
3404
+ * Sorted index for O(log N) range queries.
3405
+ * Supports: equal, in, has, gt, gte, lt, lte, between queries.
3406
+ *
3407
+ * Structure: SortedMap<AttributeValue, Set<RecordKey>>
3408
+ *
3409
+ * CQEngine Reference: NavigableIndex.java (retrieval cost: 40)
3410
+ *
3411
+ * @module query/indexes/NavigableIndex
3412
+ */
3413
+
3414
+ /**
3415
+ * Sorted index for O(log N) range queries.
3416
+ *
3417
+ * K = record key type, V = record value type, A = attribute value type (must be orderable)
3418
+ */
3419
+ declare class NavigableIndex<K, V, A extends string | number> implements Index<K, V, A> {
3420
+ readonly attribute: Attribute<V, A>;
3421
+ readonly type: "navigable";
3422
+ /** Sorted map from attribute value to set of record keys */
3423
+ private data;
3424
+ /** Set of all keys with non-null attribute value */
3425
+ private allKeys;
3426
+ /** Retrieval cost as per CQEngine cost model */
3427
+ private static readonly RETRIEVAL_COST;
3428
+ /** Supported query types */
3429
+ private static readonly SUPPORTED_QUERIES;
3430
+ /**
3431
+ * Create a NavigableIndex.
3432
+ *
3433
+ * @param attribute - Attribute to index
3434
+ * @param comparator - Optional custom comparator for ordering
3435
+ */
3436
+ constructor(attribute: Attribute<V, A>, comparator?: Comparator<A>);
3437
+ getRetrievalCost(): number;
3438
+ supportsQuery(queryType: string): boolean;
3439
+ retrieve(query: IndexQuery<A>): ResultSet<K>;
3440
+ private retrieveEqual;
3441
+ private retrieveIn;
3442
+ private retrieveHas;
3443
+ private retrieveGreaterThan;
3444
+ private retrieveLessThan;
3445
+ private retrieveBetween;
3446
+ private iterateGreaterThan;
3447
+ private iterateLessThan;
3448
+ private iterateBetween;
3449
+ /**
3450
+ * Estimate size for gt/gte queries.
3451
+ * Uses rough estimate: assume uniform distribution, return half.
3452
+ */
3453
+ private estimateGreaterThanSize;
3454
+ /**
3455
+ * Estimate size for lt/lte queries.
3456
+ * Uses rough estimate: assume uniform distribution, return half.
3457
+ */
3458
+ private estimateLessThanSize;
3459
+ /**
3460
+ * Estimate size for between queries.
3461
+ * Uses rough estimate: assume uniform distribution, return quarter.
3462
+ */
3463
+ private estimateBetweenSize;
3464
+ add(key: K, record: V): void;
3465
+ remove(key: K, record: V): void;
3466
+ update(key: K, oldRecord: V, newRecord: V): void;
3467
+ clear(): void;
3468
+ getStats(): IndexStats;
3469
+ private arraysEqual;
3470
+ /**
3471
+ * Get the minimum indexed value.
3472
+ * Useful for debugging and range estimation.
3473
+ */
3474
+ getMinValue(): A | undefined;
3475
+ /**
3476
+ * Get the maximum indexed value.
3477
+ * Useful for debugging and range estimation.
3478
+ */
3479
+ getMaxValue(): A | undefined;
3480
+ }
3481
+
3482
+ /**
3483
+ * Fallback index that performs full scan.
3484
+ * Used when no suitable index exists for a query.
3485
+ *
3486
+ * K = record key type, V = record value type
3487
+ */
3488
+ declare class FallbackIndex<K, V> implements Index<K, V, unknown> {
3489
+ private readonly getAllKeys;
3490
+ private readonly getRecord;
3491
+ private readonly matchesPredicate;
3492
+ readonly type: "hash";
3493
+ /** Wildcard attribute for fallback */
3494
+ readonly attribute: SimpleAttribute<V, unknown>;
3495
+ /** Maximum retrieval cost ensures this is only used as fallback */
3496
+ private static readonly RETRIEVAL_COST;
3497
+ /**
3498
+ * Create a FallbackIndex.
3499
+ *
3500
+ * @param getAllKeys - Function to get all keys in the collection
3501
+ * @param getRecord - Function to get a record by key
3502
+ * @param matchesPredicate - Function to check if a record matches a query
3503
+ */
3504
+ constructor(getAllKeys: () => Iterable<K>, getRecord: (key: K) => V | undefined, matchesPredicate: (record: V, query: IndexQuery<unknown>) => boolean);
3505
+ getRetrievalCost(): number;
3506
+ /**
3507
+ * Supports any query type via full scan.
3508
+ */
3509
+ supportsQuery(): boolean;
3510
+ /**
3511
+ * Retrieve by performing full scan and applying predicate.
3512
+ */
3513
+ retrieve(query: IndexQuery<unknown>): ResultSet<K>;
3514
+ add(): void;
3515
+ remove(): void;
3516
+ update(): void;
3517
+ clear(): void;
3518
+ getStats(): IndexStats;
3519
+ }
3520
+ /**
3521
+ * Factory to create predicate matcher from query.
3522
+ * Used by FallbackIndex to evaluate queries against records.
3523
+ *
3524
+ * @param getAttribute - Function to get attribute value from record
3525
+ */
3526
+ declare function createPredicateMatcher<V>(getAttribute: (record: V, attrName: string) => unknown): (record: V, query: IndexQuery<unknown>) => boolean;
3527
+
3528
+ /**
3529
+ * Query Types and Plan Types for Query Engine
3530
+ *
3531
+ * Defines query node types for the cost-based optimizer
3532
+ * and execution plan types.
3533
+ *
3534
+ * @module query/QueryTypes
3535
+ */
3536
+
3537
+ /**
3538
+ * Base query node interface.
3539
+ * Compatible with existing PredicateNode from predicate.ts
3540
+ */
3541
+ interface QueryNode {
3542
+ type: string;
3543
+ }
3544
+ /**
3545
+ * Simple query node for attribute-based conditions.
3546
+ */
3547
+ interface SimpleQueryNode extends QueryNode {
3548
+ type: 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'between' | 'like' | 'regex' | 'in' | 'has' | 'contains' | 'containsAll' | 'containsAny';
3549
+ attribute: string;
3550
+ value?: unknown;
3551
+ values?: unknown[];
3552
+ /** For 'between' queries: lower bound */
3553
+ from?: unknown;
3554
+ /** For 'between' queries: upper bound */
3555
+ to?: unknown;
3556
+ /** For 'between' queries: include lower bound (default: true) */
3557
+ fromInclusive?: boolean;
3558
+ /** For 'between' queries: include upper bound (default: false) */
3559
+ toInclusive?: boolean;
3560
+ }
3561
+ /**
3562
+ * Logical query node for combining conditions.
3563
+ */
3564
+ interface LogicalQueryNode {
3565
+ type: 'and' | 'or' | 'not';
3566
+ children?: Query[];
3567
+ child?: Query;
3568
+ }
3569
+ /**
3570
+ * Union type for all query types.
3571
+ */
3572
+ type Query = SimpleQueryNode | LogicalQueryNode;
3573
+ /**
3574
+ * Query execution options for sort/limit/offset.
3575
+ */
3576
+ interface QueryOptions {
3577
+ /** Sort by field(s): field name -> direction */
3578
+ sort?: Record<string, 'asc' | 'desc'>;
3579
+ /** Maximum number of results to return */
3580
+ limit?: number;
3581
+ /** Number of results to skip */
3582
+ offset?: number;
3583
+ }
3584
+ /**
3585
+ * Execution plan step.
3586
+ * Represents a single operation in the query execution plan.
3587
+ */
3588
+ type PlanStep = IndexScanStep | FullScanStep | IntersectionStep | UnionStep | FilterStep | NotStep;
3589
+ /**
3590
+ * Index scan step - retrieves from an index.
3591
+ */
3592
+ interface IndexScanStep {
3593
+ type: 'index-scan';
3594
+ index: Index<unknown, unknown, unknown>;
3595
+ query: IndexQuery<unknown>;
3596
+ }
3597
+ /**
3598
+ * Full scan step - scans all records.
3599
+ */
3600
+ interface FullScanStep {
3601
+ type: 'full-scan';
3602
+ predicate: Query;
3603
+ }
3604
+ /**
3605
+ * Intersection step - AND of multiple result sets.
3606
+ */
3607
+ interface IntersectionStep {
3608
+ type: 'intersection';
3609
+ steps: PlanStep[];
3610
+ }
3611
+ /**
3612
+ * Union step - OR of multiple result sets.
3613
+ */
3614
+ interface UnionStep {
3615
+ type: 'union';
3616
+ steps: PlanStep[];
3617
+ }
3618
+ /**
3619
+ * Filter step - applies predicate to source results.
3620
+ */
3621
+ interface FilterStep {
3622
+ type: 'filter';
3623
+ source: PlanStep;
3624
+ predicate: Query;
3625
+ }
3626
+ /**
3627
+ * NOT step - negation (all keys minus matching keys).
3628
+ */
3629
+ interface NotStep {
3630
+ type: 'not';
3631
+ source: PlanStep;
3632
+ allKeys: () => Set<unknown>;
3633
+ }
3634
+ /**
3635
+ * Complete query execution plan.
3636
+ */
3637
+ interface QueryPlan {
3638
+ /** Root execution step */
3639
+ root: PlanStep;
3640
+ /** Estimated execution cost */
3641
+ estimatedCost: number;
3642
+ /** Whether any index is used */
3643
+ usesIndexes: boolean;
3644
+ /** Whether sort can use index order */
3645
+ indexedSort?: boolean;
3646
+ /** Sort configuration */
3647
+ sort?: {
3648
+ field: string;
3649
+ direction: 'asc' | 'desc';
3650
+ };
3651
+ /** Limit configuration */
3652
+ limit?: number;
3653
+ /** Offset configuration */
3654
+ offset?: number;
3655
+ }
3656
+ /**
3657
+ * Check if a query is a simple query node.
3658
+ */
3659
+ declare function isSimpleQuery(query: Query): query is SimpleQueryNode;
3660
+ /**
3661
+ * Check if a query is a logical query node.
3662
+ */
3663
+ declare function isLogicalQuery(query: Query): query is LogicalQueryNode;
3664
+
3665
+ /**
3666
+ * StandingQueryIndex Implementation
3667
+ *
3668
+ * Pre-computed index for a specific query.
3669
+ * Maintains result set incrementally as data changes.
3670
+ *
3671
+ * Lowest retrieval cost (10) - O(1) query execution.
3672
+ * Critical for Live Queries in TopGun where the same query
3673
+ * is executed repeatedly on every data change.
3674
+ *
3675
+ * CQEngine Reference: StandingQueryIndex.java (retrieval cost: 10)
3676
+ *
3677
+ * @module query/indexes/StandingQueryIndex
3678
+ */
3679
+
3680
+ /**
3681
+ * Change type for standing query updates.
3682
+ */
3683
+ type StandingQueryChange = 'added' | 'removed' | 'updated' | 'unchanged';
3684
+ /**
3685
+ * Options for creating a StandingQueryIndex.
3686
+ */
3687
+ interface StandingQueryIndexOptions<K, V> {
3688
+ /** Query this index answers */
3689
+ query: Query;
3690
+ /** Function to get record by key (optional, for validation) */
3691
+ getRecord?: (key: K) => V | undefined;
3692
+ }
3693
+ /**
3694
+ * Pre-computed index for a specific query.
3695
+ * Maintains result set incrementally as data changes.
3696
+ *
3697
+ * K = record key type, V = record value type
3698
+ */
3699
+ declare class StandingQueryIndex<K, V> implements Index<K, V, unknown> {
3700
+ readonly type: "standing";
3701
+ /**
3702
+ * Wildcard attribute - StandingQueryIndex doesn't index by attribute,
3703
+ * it indexes by query match.
3704
+ */
3705
+ readonly attribute: Attribute<V, unknown>;
3706
+ /** Pre-computed result set */
3707
+ private results;
3708
+ /** Query this index answers */
3709
+ private readonly query;
3710
+ /** Record accessor (optional) */
3711
+ private readonly getRecord?;
3712
+ /** Retrieval cost - lowest of all index types */
3713
+ private static readonly RETRIEVAL_COST;
3714
+ constructor(options: StandingQueryIndexOptions<K, V>);
3715
+ /**
3716
+ * Get the query this index answers.
3717
+ */
3718
+ getQuery(): Query;
3719
+ /**
3720
+ * Check if this index answers the given query.
3721
+ */
3722
+ answersQuery(query: Query): boolean;
3723
+ getRetrievalCost(): number;
3724
+ supportsQuery(_queryType: string): boolean;
3725
+ retrieve(_query: IndexQuery<unknown>): ResultSet<K>;
3726
+ /**
3727
+ * Get current result set (for live query updates).
3728
+ * Returns a copy to avoid external mutation.
3729
+ */
3730
+ getResults(): Set<K>;
3731
+ /**
3732
+ * Get result count.
3733
+ */
3734
+ getResultCount(): number;
3735
+ /**
3736
+ * Check if key is in results.
3737
+ */
3738
+ contains(key: K): boolean;
3739
+ add(key: K, record: V): void;
3740
+ remove(key: K, _record: V): void;
3741
+ update(key: K, oldRecord: V, newRecord: V): void;
3742
+ /**
3743
+ * Determine what changed for a record update.
3744
+ * Returns the type of change relative to the query results.
3745
+ *
3746
+ * @param key - Record key
3747
+ * @param oldRecord - Previous record value (undefined for new records)
3748
+ * @param newRecord - New record value (undefined for deleted records)
3749
+ * @returns Change type: 'added', 'removed', 'updated', or 'unchanged'
3750
+ */
3751
+ determineChange(_key: K, oldRecord: V | undefined, newRecord: V | undefined): StandingQueryChange;
3752
+ clear(): void;
3753
+ getStats(): IndexStats;
3754
+ /**
3755
+ * Build index from existing data.
3756
+ *
3757
+ * @param entries - Iterable of [key, record] pairs
3758
+ */
3759
+ buildFromData(entries: Iterable<[K, V]>): void;
3760
+ /**
3761
+ * Evaluate a record against the query predicate.
3762
+ *
3763
+ * @param record - Record to evaluate
3764
+ * @returns true if record matches the query
3765
+ */
3766
+ private evaluateRecord;
3767
+ /**
3768
+ * Evaluate a query node against a record.
3769
+ * Implements predicate evaluation logic.
3770
+ */
3771
+ private evaluateQuery;
3772
+ /**
3773
+ * Evaluate a simple query (attribute-based condition).
3774
+ */
3775
+ private evaluateSimpleQuery;
3776
+ /**
3777
+ * Evaluate a logical query (AND/OR/NOT).
3778
+ */
3779
+ private evaluateLogicalQuery;
3780
+ /**
3781
+ * Get attribute value from record using dot notation.
3782
+ */
3783
+ private getAttributeValue;
3784
+ /**
3785
+ * Match a value against a LIKE pattern.
3786
+ * Supports % as wildcard for any characters.
3787
+ */
3788
+ private matchLike;
3789
+ /**
3790
+ * Deep equality check for queries.
3791
+ */
3792
+ private queriesEqual;
3793
+ }
3794
+
3795
+ /**
3796
+ * Tokenizer Interface and Implementations
3797
+ *
3798
+ * Provides text tokenization for InvertedIndex full-text search.
3799
+ * Tokenizers split text into searchable tokens.
3800
+ *
3801
+ * @module query/tokenization/Tokenizer
3802
+ */
3803
+ /**
3804
+ * Interface for text tokenizers.
3805
+ * Tokenizers split text into an array of tokens (words, n-grams, etc.)
3806
+ */
3807
+ interface Tokenizer {
3808
+ /**
3809
+ * Split text into tokens.
3810
+ *
3811
+ * @param text - Text to tokenize
3812
+ * @returns Array of tokens
3813
+ */
3814
+ tokenize(text: string): string[];
3815
+ }
3816
+ /**
3817
+ * Tokenizer that splits on whitespace.
3818
+ * Simplest tokenizer - splits on any whitespace characters.
3819
+ *
3820
+ * Example: "hello world" → ["hello", "world"]
3821
+ */
3822
+ declare class WhitespaceTokenizer implements Tokenizer {
3823
+ tokenize(text: string): string[];
3824
+ }
3825
+ /**
3826
+ * Tokenizer that splits on word boundaries.
3827
+ * Splits on non-word characters (anything not [a-zA-Z0-9_]).
3828
+ *
3829
+ * Example: "hello-world! test123" → ["hello", "world", "test123"]
3830
+ */
3831
+ declare class WordBoundaryTokenizer implements Tokenizer {
3832
+ tokenize(text: string): string[];
3833
+ }
3834
+ /**
3835
+ * N-gram tokenizer for substring matching.
3836
+ * Creates overlapping character sequences of length n.
3837
+ *
3838
+ * Example (n=3): "hello" → ["hel", "ell", "llo"]
3839
+ *
3840
+ * Use cases:
3841
+ * - Fuzzy search (typo tolerance)
3842
+ * - Substring matching (contains anywhere)
3843
+ * - Partial word matching
3844
+ */
3845
+ declare class NGramTokenizer implements Tokenizer {
3846
+ private readonly n;
3847
+ /**
3848
+ * Create an N-gram tokenizer.
3849
+ *
3850
+ * @param n - Length of each n-gram (default: 3)
3851
+ */
3852
+ constructor(n?: number);
3853
+ tokenize(text: string): string[];
3854
+ /**
3855
+ * Get the n-gram size.
3856
+ */
3857
+ get size(): number;
3858
+ }
3859
+
3860
+ /**
3861
+ * Token Filter Interface and Implementations
3862
+ *
3863
+ * Token filters transform or filter tokens produced by tokenizers.
3864
+ * Common uses: lowercase normalization, stop word removal, length filtering.
3865
+ *
3866
+ * @module query/tokenization/TokenFilter
3867
+ */
3868
+ /**
3869
+ * Interface for token filters.
3870
+ * Filters transform an array of tokens into another array of tokens.
3871
+ */
3872
+ interface TokenFilter {
3873
+ /**
3874
+ * Apply filter to tokens.
3875
+ *
3876
+ * @param tokens - Input tokens
3877
+ * @returns Filtered tokens
3878
+ */
3879
+ apply(tokens: string[]): string[];
3880
+ }
3881
+ /**
3882
+ * Filter that converts all tokens to lowercase.
3883
+ * Essential for case-insensitive search.
3884
+ *
3885
+ * Example: ["Hello", "WORLD"] → ["hello", "world"]
3886
+ */
3887
+ declare class LowercaseFilter implements TokenFilter {
3888
+ apply(tokens: string[]): string[];
3889
+ }
3890
+ /**
3891
+ * Default English stop words.
3892
+ * Common words that don't add search value.
3893
+ */
3894
+ declare const DEFAULT_STOP_WORDS: string[];
3895
+ /**
3896
+ * Filter that removes stop words.
3897
+ * Stop words are common words that don't contribute to search relevance.
3898
+ *
3899
+ * Example: ["the", "quick", "brown", "fox"] → ["quick", "brown", "fox"]
3900
+ */
3901
+ declare class StopWordFilter implements TokenFilter {
3902
+ private readonly stopWords;
3903
+ /**
3904
+ * Create a stop word filter.
3905
+ *
3906
+ * @param stopWords - Array of stop words to remove (default: English stop words)
3907
+ */
3908
+ constructor(stopWords?: string[]);
3909
+ apply(tokens: string[]): string[];
3910
+ /**
3911
+ * Get the set of stop words.
3912
+ */
3913
+ getStopWords(): Set<string>;
3914
+ }
3915
+ /**
3916
+ * Filter that removes tokens shorter than a minimum length.
3917
+ * Useful for filtering out single characters or very short tokens.
3918
+ *
3919
+ * Example (minLength=3): ["a", "is", "the", "quick"] → ["the", "quick"]
3920
+ */
3921
+ declare class MinLengthFilter implements TokenFilter {
3922
+ private readonly minLength;
3923
+ /**
3924
+ * Create a minimum length filter.
3925
+ *
3926
+ * @param minLength - Minimum token length (default: 2)
3927
+ */
3928
+ constructor(minLength?: number);
3929
+ apply(tokens: string[]): string[];
3930
+ /**
3931
+ * Get the minimum length setting.
3932
+ */
3933
+ getMinLength(): number;
3934
+ }
3935
+ /**
3936
+ * Filter that removes tokens longer than a maximum length.
3937
+ * Useful for preventing very long tokens from being indexed.
3938
+ *
3939
+ * Example (maxLength=10): ["short", "verylongword"] → ["short"]
3940
+ */
3941
+ declare class MaxLengthFilter implements TokenFilter {
3942
+ private readonly maxLength;
3943
+ /**
3944
+ * Create a maximum length filter.
3945
+ *
3946
+ * @param maxLength - Maximum token length (default: 50)
3947
+ */
3948
+ constructor(maxLength?: number);
3949
+ apply(tokens: string[]): string[];
3950
+ /**
3951
+ * Get the maximum length setting.
3952
+ */
3953
+ getMaxLength(): number;
3954
+ }
3955
+ /**
3956
+ * Filter that trims whitespace from tokens.
3957
+ * Ensures clean tokens without leading/trailing spaces.
3958
+ */
3959
+ declare class TrimFilter implements TokenFilter {
3960
+ apply(tokens: string[]): string[];
3961
+ }
3962
+ /**
3963
+ * Filter that removes duplicate tokens.
3964
+ * Useful for reducing index size when tokens repeat.
3965
+ *
3966
+ * Example: ["hello", "world", "hello"] → ["hello", "world"]
3967
+ */
3968
+ declare class UniqueFilter implements TokenFilter {
3969
+ apply(tokens: string[]): string[];
3970
+ }
3971
+
3972
+ /**
3973
+ * Tokenization Pipeline
3974
+ *
3975
+ * Chains a tokenizer with multiple filters for text processing.
3976
+ * Provides factory methods for common configurations.
3977
+ *
3978
+ * @module query/tokenization/TokenizationPipeline
3979
+ */
3980
+
3981
+ /**
3982
+ * Pipeline configuration options.
3983
+ */
3984
+ interface TokenizationPipelineOptions {
3985
+ /** Tokenizer to use */
3986
+ tokenizer: Tokenizer;
3987
+ /** Filters to apply (in order) */
3988
+ filters?: TokenFilter[];
3989
+ }
3990
+ /**
3991
+ * Tokenization pipeline that chains a tokenizer with filters.
3992
+ *
3993
+ * Processing order:
3994
+ * 1. Tokenizer splits text into tokens
3995
+ * 2. Each filter transforms the token array in sequence
3996
+ *
3997
+ * Example:
3998
+ * ```typescript
3999
+ * const pipeline = TokenizationPipeline.simple();
4000
+ * pipeline.process("Hello World!"); // ["hello", "world"]
4001
+ * ```
4002
+ */
4003
+ declare class TokenizationPipeline {
4004
+ private readonly tokenizer;
4005
+ private readonly filters;
4006
+ /**
4007
+ * Create a tokenization pipeline.
4008
+ *
4009
+ * @param options - Pipeline configuration
4010
+ */
4011
+ constructor(options: TokenizationPipelineOptions);
4012
+ /**
4013
+ * Process text through the pipeline.
4014
+ *
4015
+ * @param text - Text to process
4016
+ * @returns Array of processed tokens
4017
+ */
4018
+ process(text: string): string[];
4019
+ /**
4020
+ * Get the tokenizer.
4021
+ */
4022
+ getTokenizer(): Tokenizer;
4023
+ /**
4024
+ * Get the filters.
4025
+ */
4026
+ getFilters(): TokenFilter[];
4027
+ /**
4028
+ * Create a simple pipeline with common defaults.
4029
+ * Uses word boundary tokenizer with lowercase and minimum length filters.
4030
+ *
4031
+ * Configuration:
4032
+ * - Tokenizer: WordBoundaryTokenizer
4033
+ * - Filters: LowercaseFilter, MinLengthFilter(2)
4034
+ *
4035
+ * @returns Simple tokenization pipeline
4036
+ */
4037
+ static simple(): TokenizationPipeline;
4038
+ /**
4039
+ * Create a pipeline optimized for search.
4040
+ * Includes stop word removal for better search relevance.
4041
+ *
4042
+ * Configuration:
4043
+ * - Tokenizer: WordBoundaryTokenizer
4044
+ * - Filters: LowercaseFilter, MinLengthFilter(2), StopWordFilter
4045
+ *
4046
+ * @returns Search-optimized tokenization pipeline
4047
+ */
4048
+ static search(): TokenizationPipeline;
4049
+ /**
4050
+ * Create a minimal pipeline with just tokenization and lowercase.
4051
+ * No filtering - preserves all tokens.
4052
+ *
4053
+ * Configuration:
4054
+ * - Tokenizer: WordBoundaryTokenizer
4055
+ * - Filters: LowercaseFilter
4056
+ *
4057
+ * @returns Minimal tokenization pipeline
4058
+ */
4059
+ static minimal(): TokenizationPipeline;
4060
+ /**
4061
+ * Create a custom pipeline from a tokenizer and filters.
4062
+ *
4063
+ * @param tokenizer - Tokenizer to use
4064
+ * @param filters - Filters to apply
4065
+ * @returns Custom tokenization pipeline
4066
+ */
4067
+ static custom(tokenizer: Tokenizer, filters?: TokenFilter[]): TokenizationPipeline;
4068
+ }
4069
+
4070
+ /**
4071
+ * InvertedIndex Implementation
4072
+ *
4073
+ * Full-text search index using inverted index structure.
4074
+ * Supports: contains, containsAll, containsAny, has queries.
4075
+ *
4076
+ * Structure:
4077
+ * tokenIndex: Map<Token, Set<RecordKey>>
4078
+ * reverseIndex: Map<RecordKey, Set<Token>>
4079
+ *
4080
+ * Retrieval cost: 50 (between NavigableIndex:40 and FallbackIndex)
4081
+ *
4082
+ * @module query/indexes/InvertedIndex
4083
+ */
4084
+
4085
+ /**
4086
+ * Extended statistics for InvertedIndex.
4087
+ */
4088
+ interface InvertedIndexStats extends IndexStats {
4089
+ /** Total unique tokens in the index */
4090
+ totalTokens: number;
4091
+ /** Average number of tokens per indexed document */
4092
+ avgTokensPerDocument: number;
4093
+ /** Maximum documents for any single token */
4094
+ maxDocumentsPerToken: number;
4095
+ }
4096
+ /**
4097
+ * Inverted index for full-text search.
4098
+ * Maps tokens to sets of document keys for O(K) query performance.
4099
+ *
4100
+ * K = record key type, V = record value type, A = attribute value type (should be string)
4101
+ */
4102
+ declare class InvertedIndex<K, V, A extends string = string> implements Index<K, V, A> {
4103
+ readonly attribute: Attribute<V, A>;
4104
+ private readonly pipeline;
4105
+ readonly type: "inverted";
4106
+ /** Token → Set of keys */
4107
+ private tokenIndex;
4108
+ /** Key → Set of tokens (for efficient removal/update) */
4109
+ private reverseIndex;
4110
+ /** All keys with indexed content */
4111
+ private allKeys;
4112
+ private static readonly RETRIEVAL_COST;
4113
+ private static readonly SUPPORTED_QUERIES;
4114
+ /**
4115
+ * Create an InvertedIndex.
4116
+ *
4117
+ * @param attribute - Attribute to index (should return string values)
4118
+ * @param pipeline - Tokenization pipeline (default: simple pipeline)
4119
+ */
4120
+ constructor(attribute: Attribute<V, A>, pipeline?: TokenizationPipeline);
4121
+ getRetrievalCost(): number;
4122
+ supportsQuery(queryType: string): boolean;
4123
+ retrieve(query: IndexQuery<A>): ResultSet<K>;
4124
+ /**
4125
+ * Retrieve documents containing all tokens from the search text.
4126
+ * Uses AND semantics - document must contain ALL tokens.
4127
+ */
4128
+ private retrieveContains;
4129
+ /**
4130
+ * Retrieve documents containing ALL specified values.
4131
+ * Each value is tokenized, and ALL resulting tokens must match.
4132
+ */
4133
+ private retrieveContainsAll;
4134
+ /**
4135
+ * Retrieve documents containing ANY of the specified values.
4136
+ * Uses OR semantics - document can contain any token from any value.
4137
+ */
4138
+ private retrieveContainsAny;
4139
+ /**
4140
+ * Retrieve all documents with indexed content.
4141
+ */
4142
+ private retrieveHas;
4143
+ add(key: K, record: V): void;
4144
+ remove(key: K, _record: V): void;
4145
+ update(key: K, oldRecord: V, newRecord: V): void;
4146
+ clear(): void;
4147
+ getStats(): IndexStats;
4148
+ /**
4149
+ * Get extended statistics for full-text index.
4150
+ */
4151
+ getExtendedStats(): InvertedIndexStats;
4152
+ /**
4153
+ * Get the tokenization pipeline.
4154
+ */
4155
+ getPipeline(): TokenizationPipeline;
4156
+ /**
4157
+ * Check if a specific token exists in the index.
4158
+ */
4159
+ hasToken(token: string): boolean;
4160
+ /**
4161
+ * Get the number of documents for a specific token.
4162
+ */
4163
+ getTokenDocumentCount(token: string): number;
4164
+ private valuesEqual;
4165
+ }
4166
+
4167
+ /**
4168
+ * SetResultSet Implementation
4169
+ *
4170
+ * ResultSet backed by a Set, used for HashIndex results.
4171
+ *
4172
+ * @module query/resultset/SetResultSet
4173
+ */
4174
+
4175
+ /**
4176
+ * ResultSet backed by a Set.
4177
+ * Provides O(1) contains() check and direct iteration.
4178
+ */
4179
+ declare class SetResultSet<K> implements ResultSet<K> {
4180
+ private readonly keys;
4181
+ private readonly retrievalCost;
4182
+ constructor(keys: Set<K>, retrievalCost: number);
4183
+ [Symbol.iterator](): Iterator<K>;
4184
+ getRetrievalCost(): number;
4185
+ getMergeCost(): number;
4186
+ contains(key: K): boolean;
4187
+ size(): number;
4188
+ toArray(): K[];
4189
+ isEmpty(): boolean;
4190
+ }
4191
+
4192
+ /**
4193
+ * LazyResultSet Implementation
4194
+ *
4195
+ * Lazily evaluated result set for range queries.
4196
+ * Used when materializing all results upfront would be expensive.
4197
+ *
4198
+ * @module query/resultset/LazyResultSet
4199
+ */
4200
+
4201
+ /**
4202
+ * Factory function type that creates a generator for lazy iteration.
4203
+ */
4204
+ type IteratorFactory<K> = () => Generator<K>;
4205
+ /**
4206
+ * Lazily evaluated result set.
4207
+ * Used for range queries where materializing all results upfront is expensive.
4208
+ *
4209
+ * K = record key type
4210
+ */
4211
+ declare class LazyResultSet<K> implements ResultSet<K> {
4212
+ private readonly iteratorFactory;
4213
+ private readonly retrievalCost;
4214
+ private readonly estimatedSize;
4215
+ /** Cached materialized results */
4216
+ private cached;
4217
+ /**
4218
+ * Create a LazyResultSet.
4219
+ *
4220
+ * @param iteratorFactory - Factory that creates a fresh generator each time
4221
+ * @param retrievalCost - Cost of retrieving results from the index
4222
+ * @param estimatedSize - Estimated result count for merge cost calculation
4223
+ */
4224
+ constructor(iteratorFactory: IteratorFactory<K>, retrievalCost: number, estimatedSize: number);
4225
+ [Symbol.iterator](): Generator<K>;
4226
+ getRetrievalCost(): number;
4227
+ getMergeCost(): number;
4228
+ contains(key: K): boolean;
4229
+ size(): number;
4230
+ toArray(): K[];
4231
+ isEmpty(): boolean;
4232
+ /**
4233
+ * Check if the result set has been materialized.
4234
+ * Useful for testing lazy evaluation behavior.
4235
+ */
4236
+ isMaterialized(): boolean;
4237
+ /**
4238
+ * Force materialization of the result set.
4239
+ * Returns the cached array.
4240
+ */
4241
+ materialize(): K[];
4242
+ /**
4243
+ * Get the estimated size before materialization.
4244
+ */
4245
+ getEstimatedSize(): number;
4246
+ }
4247
+
4248
+ /**
4249
+ * IntersectionResultSet Implementation
4250
+ *
4251
+ * Intersection of multiple result sets (AND logic).
4252
+ * Implements CQEngine "smallest first" strategy:
4253
+ * iterate the smallest set, check membership in others.
4254
+ *
4255
+ * @module query/resultset/IntersectionResultSet
4256
+ */
4257
+
4258
+ /**
4259
+ * Intersection of multiple result sets (AND logic).
4260
+ * CQEngine strategy: iterate smallest set, check membership in others.
4261
+ *
4262
+ * K = record key type
4263
+ */
4264
+ declare class IntersectionResultSet<K> implements ResultSet<K> {
4265
+ /** Cached materialized results */
4266
+ private cached;
4267
+ /** Result sets sorted by merge cost */
4268
+ private sortedResultSets;
4269
+ /**
4270
+ * Create an IntersectionResultSet.
4271
+ *
4272
+ * @param resultSets - Result sets to intersect
4273
+ */
4274
+ constructor(resultSets: ResultSet<K>[]);
4275
+ /**
4276
+ * Lazy iteration over intersection.
4277
+ * Iterates smallest set, yields only keys present in all sets.
4278
+ */
4279
+ [Symbol.iterator](): Generator<K>;
4280
+ /**
4281
+ * Retrieval cost is minimum of all (we only iterate smallest).
4282
+ */
4283
+ getRetrievalCost(): number;
4284
+ /**
4285
+ * Merge cost is estimated as smallest set size (upper bound).
4286
+ */
4287
+ getMergeCost(): number;
4288
+ /**
4289
+ * Check if key is in all result sets.
4290
+ */
4291
+ contains(key: K): boolean;
4292
+ /**
4293
+ * Get size by materializing results.
4294
+ */
4295
+ size(): number;
4296
+ /**
4297
+ * Materialize to array with caching.
4298
+ */
4299
+ toArray(): K[];
4300
+ /**
4301
+ * Check if empty (tries to avoid full materialization).
4302
+ */
4303
+ isEmpty(): boolean;
4304
+ /**
4305
+ * Check if results have been materialized.
4306
+ */
4307
+ isMaterialized(): boolean;
4308
+ }
4309
+
4310
+ /**
4311
+ * UnionResultSet Implementation
4312
+ *
4313
+ * Union of multiple result sets (OR logic).
4314
+ * Deduplicates results using a Set during iteration.
4315
+ *
4316
+ * @module query/resultset/UnionResultSet
4317
+ */
4318
+
4319
+ /**
4320
+ * Union of multiple result sets (OR logic).
4321
+ * Deduplicates results.
4322
+ *
4323
+ * K = record key type
4324
+ */
4325
+ declare class UnionResultSet<K> implements ResultSet<K> {
4326
+ private readonly resultSets;
4327
+ /** Cached materialized results */
4328
+ private cached;
4329
+ /**
4330
+ * Create a UnionResultSet.
4331
+ *
4332
+ * @param resultSets - Result sets to union
4333
+ */
4334
+ constructor(resultSets: ResultSet<K>[]);
4335
+ /**
4336
+ * Lazy iteration over union with deduplication.
4337
+ */
4338
+ [Symbol.iterator](): Generator<K>;
4339
+ /**
4340
+ * Retrieval cost is sum of all costs.
4341
+ */
4342
+ getRetrievalCost(): number;
4343
+ /**
4344
+ * Merge cost upper bound: sum of all sizes.
4345
+ */
4346
+ getMergeCost(): number;
4347
+ /**
4348
+ * Check if key is in any result set.
4349
+ */
4350
+ contains(key: K): boolean;
4351
+ /**
4352
+ * Get size by materializing results.
4353
+ */
4354
+ size(): number;
4355
+ /**
4356
+ * Materialize to array with caching.
4357
+ */
4358
+ toArray(): K[];
4359
+ /**
4360
+ * Check if empty (all sources must be empty).
4361
+ */
4362
+ isEmpty(): boolean;
4363
+ /**
4364
+ * Check if results have been materialized.
4365
+ */
4366
+ isMaterialized(): boolean;
4367
+ }
4368
+
4369
+ /**
4370
+ * FilteringResultSet Implementation
4371
+ *
4372
+ * Filters a source result set with a predicate.
4373
+ * Used when an index is available for part of a query,
4374
+ * but additional filtering is needed.
4375
+ *
4376
+ * @module query/resultset/FilteringResultSet
4377
+ */
4378
+
4379
+ /**
4380
+ * Predicate function for filtering records.
4381
+ */
4382
+ type PredicateFn<V> = (record: V) => boolean;
4383
+ /**
4384
+ * Filters a source result set with a predicate.
4385
+ *
4386
+ * K = record key type, V = record value type
4387
+ */
4388
+ declare class FilteringResultSet<K, V> implements ResultSet<K> {
4389
+ private readonly source;
4390
+ private readonly getRecord;
4391
+ private readonly predicate;
4392
+ /** Cached materialized results */
4393
+ private cached;
4394
+ /**
4395
+ * Create a FilteringResultSet.
4396
+ *
4397
+ * @param source - Source result set to filter
4398
+ * @param getRecord - Function to get record by key
4399
+ * @param predicate - Predicate function to filter records
4400
+ */
4401
+ constructor(source: ResultSet<K>, getRecord: (key: K) => V | undefined, predicate: PredicateFn<V>);
4402
+ /**
4403
+ * Lazy iteration with filtering.
4404
+ */
4405
+ [Symbol.iterator](): Generator<K>;
4406
+ /**
4407
+ * Retrieval cost: source cost + filter overhead.
4408
+ */
4409
+ getRetrievalCost(): number;
4410
+ /**
4411
+ * Merge cost: estimate half of source (pessimistic).
4412
+ */
4413
+ getMergeCost(): number;
4414
+ /**
4415
+ * Check if key is in source and passes predicate.
4416
+ */
4417
+ contains(key: K): boolean;
4418
+ /**
4419
+ * Get size by materializing results.
4420
+ */
4421
+ size(): number;
4422
+ /**
4423
+ * Materialize to array with caching.
4424
+ */
4425
+ toArray(): K[];
4426
+ /**
4427
+ * Check if empty (tries to find at least one match).
4428
+ */
4429
+ isEmpty(): boolean;
4430
+ /**
4431
+ * Check if results have been materialized.
4432
+ */
4433
+ isMaterialized(): boolean;
4434
+ }
4435
+
4436
+ /**
4437
+ * SortedResultSet Implementation
4438
+ *
4439
+ * ResultSet with sorting support.
4440
+ * If source is from NavigableIndex on sort field, results are already sorted.
4441
+ * Otherwise, performs in-memory sort.
4442
+ *
4443
+ * @module query/resultset/SortedResultSet
4444
+ */
4445
+
4446
+ /**
4447
+ * Comparator function for sorting.
4448
+ */
4449
+ type CompareFn<V> = (a: V, b: V) => number;
4450
+ /**
4451
+ * ResultSet with sorting support.
4452
+ *
4453
+ * K = record key type, V = record value type
4454
+ */
4455
+ declare class SortedResultSet<K, V> implements ResultSet<K> {
4456
+ private readonly source;
4457
+ private readonly getRecord;
4458
+ private readonly sortField;
4459
+ private readonly direction;
4460
+ private readonly isPreSorted;
4461
+ /** Cached sorted results */
4462
+ private cached;
4463
+ /**
4464
+ * Create a SortedResultSet.
4465
+ *
4466
+ * @param source - Source result set
4467
+ * @param getRecord - Function to get record by key
4468
+ * @param sortField - Field to sort by
4469
+ * @param direction - Sort direction ('asc' or 'desc')
4470
+ * @param isPreSorted - Whether source is already sorted (from NavigableIndex)
4471
+ */
4472
+ constructor(source: ResultSet<K>, getRecord: (key: K) => V | undefined, sortField: string, direction: 'asc' | 'desc', isPreSorted?: boolean);
4473
+ /**
4474
+ * Lazy iteration with sorting.
4475
+ */
4476
+ [Symbol.iterator](): Generator<K>;
4477
+ /**
4478
+ * Materialize to sorted array with caching.
4479
+ */
4480
+ toArray(): K[];
4481
+ /**
4482
+ * Retrieval cost: source cost + sort overhead.
4483
+ * Pre-sorted has minimal overhead.
4484
+ */
4485
+ getRetrievalCost(): number;
4486
+ /**
4487
+ * Merge cost: same as source (sorting doesn't change size).
4488
+ */
4489
+ getMergeCost(): number;
4490
+ /**
4491
+ * Check if key is in source.
4492
+ */
4493
+ contains(key: K): boolean;
4494
+ /**
4495
+ * Get size (same as source).
4496
+ */
4497
+ size(): number;
4498
+ /**
4499
+ * Check if empty.
4500
+ */
4501
+ isEmpty(): boolean;
4502
+ /**
4503
+ * Check if results have been materialized.
4504
+ */
4505
+ isMaterialized(): boolean;
4506
+ /**
4507
+ * Check if this result set is pre-sorted.
4508
+ */
4509
+ isIndexSorted(): boolean;
4510
+ /**
4511
+ * Get sort field.
4512
+ */
4513
+ getSortField(): string;
4514
+ /**
4515
+ * Get sort direction.
4516
+ */
4517
+ getSortDirection(): 'asc' | 'desc';
4518
+ }
4519
+ /**
4520
+ * Create a comparator function for a field.
4521
+ *
4522
+ * @param field - Field name to compare
4523
+ * @param direction - Sort direction
4524
+ */
4525
+ declare function createFieldComparator<V>(field: string, direction: 'asc' | 'desc'): CompareFn<V>;
4526
+
4527
+ /**
4528
+ * LimitResultSet Implementation
4529
+ *
4530
+ * Applies offset/limit to source ResultSet.
4531
+ * Implements early termination for efficiency.
4532
+ *
4533
+ * @module query/resultset/LimitResultSet
4534
+ */
4535
+
4536
+ /**
4537
+ * Applies offset/limit to source ResultSet.
4538
+ * Implements early termination for efficiency.
4539
+ *
4540
+ * K = record key type
4541
+ */
4542
+ declare class LimitResultSet<K> implements ResultSet<K> {
4543
+ private readonly source;
4544
+ private readonly offset;
4545
+ private readonly limit;
4546
+ /** Cached materialized results */
4547
+ private cached;
4548
+ /**
4549
+ * Create a LimitResultSet.
4550
+ *
4551
+ * @param source - Source result set
4552
+ * @param offset - Number of results to skip (default: 0)
4553
+ * @param limit - Maximum number of results (default: Infinity)
4554
+ */
4555
+ constructor(source: ResultSet<K>, offset?: number, limit?: number);
4556
+ /**
4557
+ * Lazy iteration with offset/limit and early termination.
4558
+ */
4559
+ [Symbol.iterator](): Generator<K>;
4560
+ /**
4561
+ * Retrieval cost: source cost (limit doesn't change retrieval cost).
4562
+ */
4563
+ getRetrievalCost(): number;
4564
+ /**
4565
+ * Merge cost: min(source size, offset + limit).
4566
+ */
4567
+ getMergeCost(): number;
4568
+ /**
4569
+ * Check if key is in result (with offset/limit constraints).
4570
+ * This is expensive as it requires iteration to determine position.
4571
+ */
4572
+ contains(key: K): boolean;
4573
+ /**
4574
+ * Get size by materializing results.
4575
+ */
4576
+ size(): number;
4577
+ /**
4578
+ * Materialize to array with caching.
4579
+ */
4580
+ toArray(): K[];
4581
+ /**
4582
+ * Check if empty.
4583
+ */
4584
+ isEmpty(): boolean;
4585
+ /**
4586
+ * Check if results have been materialized.
4587
+ */
4588
+ isMaterialized(): boolean;
4589
+ /**
4590
+ * Get the offset value.
4591
+ */
4592
+ getOffset(): number;
4593
+ /**
4594
+ * Get the limit value.
4595
+ */
4596
+ getLimit(): number;
4597
+ }
4598
+
4599
+ /**
4600
+ * IndexRegistry Implementation
4601
+ *
4602
+ * Central registry for managing indexes on a collection.
4603
+ * Provides index lookup, lifecycle management, and bulk operations.
4604
+ *
4605
+ * @module query/IndexRegistry
4606
+ */
4607
+
4608
+ /**
4609
+ * Registry for managing indexes on a collection.
4610
+ * Provides index lookup and lifecycle management.
4611
+ *
4612
+ * K = record key type, V = record value type
4613
+ */
4614
+ declare class IndexRegistry<K, V> {
4615
+ /** Indexes grouped by attribute name */
4616
+ private attributeIndexes;
4617
+ /** Fallback index for full scan (optional) */
4618
+ private fallbackIndex;
4619
+ /**
4620
+ * Register an index for an attribute.
4621
+ * Multiple indexes can be registered for the same attribute.
4622
+ *
4623
+ * @param index - Index to register
4624
+ */
4625
+ addIndex<A>(index: Index<K, V, A>): void;
4626
+ /**
4627
+ * Remove an index from the registry.
4628
+ *
4629
+ * @param index - Index to remove
4630
+ * @returns true if index was found and removed
4631
+ */
4632
+ removeIndex<A>(index: Index<K, V, A>): boolean;
4633
+ /**
4634
+ * Get all indexes for an attribute.
4635
+ *
4636
+ * @param attributeName - Attribute name
4637
+ * @returns Array of indexes (empty if none)
4638
+ */
4639
+ getIndexes(attributeName: string): Index<K, V, unknown>[];
4640
+ /**
4641
+ * Get all registered indexes across all attributes.
4642
+ *
4643
+ * @returns Array of all indexes
4644
+ */
4645
+ getAllIndexes(): Index<K, V, unknown>[];
4646
+ /**
4647
+ * Get all indexed attribute names.
4648
+ *
4649
+ * @returns Array of attribute names
4650
+ */
4651
+ getIndexedAttributes(): string[];
4652
+ /**
4653
+ * Check if an attribute has any indexes.
4654
+ *
4655
+ * @param attributeName - Attribute name
4656
+ * @returns true if attribute has indexes
4657
+ */
4658
+ hasIndex(attributeName: string): boolean;
4659
+ /**
4660
+ * Find the best index for a query type on an attribute.
4661
+ * Returns the index with lowest retrieval cost that supports the query type.
4662
+ *
4663
+ * @param attributeName - Attribute name to search on
4664
+ * @param queryType - Query type (e.g., 'equal', 'gt', 'between')
4665
+ * @returns Best matching index or null if none found
4666
+ */
4667
+ findBestIndex(attributeName: string, queryType: string): Index<K, V, unknown> | null;
4668
+ /**
4669
+ * Find all indexes that support a query type on an attribute.
4670
+ *
4671
+ * @param attributeName - Attribute name
4672
+ * @param queryType - Query type
4673
+ * @returns Array of matching indexes sorted by retrieval cost
4674
+ */
4675
+ findIndexes(attributeName: string, queryType: string): Index<K, V, unknown>[];
4676
+ /**
4677
+ * Set a fallback index for queries without a suitable index.
4678
+ * Typically a FallbackIndex that performs full scan.
4679
+ *
4680
+ * @param fallback - Fallback index
4681
+ */
4682
+ setFallbackIndex(fallback: Index<K, V, unknown>): void;
4683
+ /**
4684
+ * Get the fallback index.
4685
+ *
4686
+ * @returns Fallback index or null if not set
4687
+ */
4688
+ getFallbackIndex(): Index<K, V, unknown> | null;
4689
+ /**
4690
+ * Notify all indexes of a record addition.
4691
+ * Should be called when a new record is added to the collection.
4692
+ *
4693
+ * @param key - Record key
4694
+ * @param record - Record value
4695
+ */
4696
+ onRecordAdded(key: K, record: V): void;
4697
+ /**
4698
+ * Notify all indexes of a record update.
4699
+ * Should be called when a record's value changes.
4700
+ *
4701
+ * @param key - Record key
4702
+ * @param oldRecord - Previous record value
4703
+ * @param newRecord - New record value
4704
+ */
4705
+ onRecordUpdated(key: K, oldRecord: V, newRecord: V): void;
4706
+ /**
4707
+ * Notify all indexes of a record removal.
4708
+ * Should be called when a record is removed from the collection.
4709
+ *
4710
+ * @param key - Record key
4711
+ * @param record - Removed record value
4712
+ */
4713
+ onRecordRemoved(key: K, record: V): void;
4714
+ /**
4715
+ * Clear all indexes.
4716
+ * Does not remove index registrations, only clears their data.
4717
+ */
4718
+ clear(): void;
4719
+ /**
4720
+ * Get total number of registered indexes.
4721
+ */
4722
+ get size(): number;
4723
+ /**
4724
+ * Get statistics about the registry.
4725
+ */
4726
+ getStats(): IndexRegistryStats;
4727
+ }
4728
+ /**
4729
+ * Statistics about the IndexRegistry.
4730
+ */
4731
+ interface IndexRegistryStats {
4732
+ /** Total number of indexes */
4733
+ totalIndexes: number;
4734
+ /** Number of indexed attributes */
4735
+ indexedAttributes: number;
4736
+ /** Stats for each index */
4737
+ indexes: Array<{
4738
+ attribute: string;
4739
+ type: string;
4740
+ stats: {
4741
+ distinctValues: number;
4742
+ totalEntries: number;
4743
+ avgEntriesPerValue: number;
4744
+ };
4745
+ }>;
4746
+ }
4747
+
4748
+ /**
4749
+ * StandingQueryRegistry Implementation
4750
+ *
4751
+ * Registry for managing StandingQueryIndexes.
4752
+ * Used by Live Query system to maintain pre-computed results.
4753
+ *
4754
+ * Features:
4755
+ * - Reference counting for shared indexes
4756
+ * - Automatic cleanup when all subscribers unsubscribe
4757
+ * - Efficient update propagation to all indexes
4758
+ *
4759
+ * @module query/StandingQueryRegistry
4760
+ */
4761
+
4762
+ /**
4763
+ * Options for creating a StandingQueryRegistry.
4764
+ */
4765
+ interface StandingQueryRegistryOptions<K, V> {
4766
+ /** Function to get record by key */
4767
+ getRecord: (key: K) => V | undefined;
4768
+ /** Function to get all entries for building index */
4769
+ getAllEntries: () => Iterable<[K, V]>;
4770
+ }
4771
+ /**
4772
+ * Statistics about the StandingQueryRegistry.
4773
+ */
4774
+ interface StandingQueryRegistryStats {
4775
+ /** Number of registered indexes */
4776
+ indexCount: number;
4777
+ /** Total reference count across all indexes */
4778
+ totalRefCount: number;
4779
+ /** Total number of results across all indexes */
4780
+ totalResults: number;
4781
+ }
4782
+ /**
4783
+ * Registry for managing StandingQueryIndexes.
4784
+ * Provides reference counting and lifecycle management.
4785
+ *
4786
+ * K = record key type, V = record value type
4787
+ */
4788
+ declare class StandingQueryRegistry<K, V> {
4789
+ /** Map from query hash to StandingQueryIndex */
4790
+ private indexes;
4791
+ /** Reference count for each query (multiple subscriptions can use same index) */
4792
+ private refCounts;
4793
+ /** Record accessor */
4794
+ private readonly getRecord;
4795
+ /** All entries accessor (for building index) */
4796
+ private readonly getAllEntries;
4797
+ constructor(options: StandingQueryRegistryOptions<K, V>);
4798
+ /**
4799
+ * Register a standing query.
4800
+ * Creates new index or returns existing if query already registered.
4801
+ * Increments reference count.
4802
+ *
4803
+ * @param query - Query to register
4804
+ * @returns StandingQueryIndex for the query
4805
+ */
4806
+ register(query: Query): StandingQueryIndex<K, V>;
4807
+ /**
4808
+ * Unregister a standing query.
4809
+ * Decrements reference count. Only removes when refcount reaches 0.
4810
+ *
4811
+ * @param query - Query to unregister
4812
+ * @returns true if index was removed, false if still has references
4813
+ */
4814
+ unregister(query: Query): boolean;
4815
+ /**
4816
+ * Get index for a query if registered.
4817
+ *
4818
+ * @param query - Query to look up
4819
+ * @returns StandingQueryIndex or undefined if not registered
4820
+ */
4821
+ getIndex(query: Query): StandingQueryIndex<K, V> | undefined;
4822
+ /**
4823
+ * Get index by hash directly.
4824
+ *
4825
+ * @param hash - Query hash
4826
+ * @returns StandingQueryIndex or undefined if not registered
4827
+ */
4828
+ getIndexByHash(hash: string): StandingQueryIndex<K, V> | undefined;
4829
+ /**
4830
+ * Check if query has a standing index.
4831
+ *
4832
+ * @param query - Query to check
4833
+ * @returns true if index exists
4834
+ */
4835
+ hasIndex(query: Query): boolean;
4836
+ /**
4837
+ * Get reference count for a query.
4838
+ *
4839
+ * @param query - Query to check
4840
+ * @returns Reference count (0 if not registered)
4841
+ */
4842
+ getRefCount(query: Query): number;
4843
+ /**
4844
+ * Notify all indexes of record addition.
4845
+ * Returns map of query hash to change type for affected queries.
4846
+ *
4847
+ * @param key - Record key
4848
+ * @param record - New record value
4849
+ * @returns Map of query hash to change type
4850
+ */
4851
+ onRecordAdded(key: K, record: V): Map<string, StandingQueryChange>;
4852
+ /**
4853
+ * Notify all indexes of record update.
4854
+ * Returns map of query hash to change type for affected queries.
4855
+ *
4856
+ * @param key - Record key
4857
+ * @param oldRecord - Previous record value
4858
+ * @param newRecord - New record value
4859
+ * @returns Map of query hash to change type
4860
+ */
4861
+ onRecordUpdated(key: K, oldRecord: V, newRecord: V): Map<string, StandingQueryChange>;
4862
+ /**
4863
+ * Notify all indexes of record removal.
4864
+ * Returns map of query hash to change type for affected queries.
4865
+ *
4866
+ * @param key - Record key
4867
+ * @param record - Removed record value
4868
+ * @returns Map of query hash to change type
4869
+ */
4870
+ onRecordRemoved(key: K, record: V): Map<string, StandingQueryChange>;
4871
+ /**
4872
+ * Get all registered queries.
4873
+ *
4874
+ * @returns Array of registered queries
4875
+ */
4876
+ getRegisteredQueries(): Query[];
4877
+ /**
4878
+ * Get all query hashes.
4879
+ *
4880
+ * @returns Array of query hashes
4881
+ */
4882
+ getQueryHashes(): string[];
4883
+ /**
4884
+ * Get statistics about the registry.
4885
+ *
4886
+ * @returns Registry statistics
4887
+ */
4888
+ getStats(): StandingQueryRegistryStats;
4889
+ /**
4890
+ * Clear all indexes.
4891
+ */
4892
+ clear(): void;
4893
+ /**
4894
+ * Get number of registered indexes.
4895
+ */
4896
+ get size(): number;
4897
+ /**
4898
+ * Compute hash for a query.
4899
+ * Used as key in indexes map.
4900
+ */
4901
+ hashQuery(query: Query): string;
4902
+ }
4903
+
4904
+ /**
4905
+ * QueryOptimizer Implementation
4906
+ *
4907
+ * Cost-based query optimizer for the Query Engine.
4908
+ * Selects optimal index and execution strategy for queries.
4909
+ *
4910
+ * Algorithm based on CQEngine CollectionQueryEngine:
4911
+ * - StandingQueryIndex: Check first (lowest cost = 10)
4912
+ * - AND queries: "smallest first" strategy - sort by merge cost, iterate smallest
4913
+ * - OR queries: Union all results with deduplication
4914
+ * - NOT queries: Get all keys, subtract matching keys
4915
+ *
4916
+ * @module query/QueryOptimizer
4917
+ */
4918
+
4919
+ /**
4920
+ * Options for creating a QueryOptimizer.
4921
+ */
4922
+ interface QueryOptimizerOptions<K, V> {
4923
+ /** Index registry for attribute-based indexes */
4924
+ indexRegistry: IndexRegistry<K, V>;
4925
+ /** Standing query registry for pre-computed queries (optional) */
4926
+ standingQueryRegistry?: StandingQueryRegistry<K, V>;
4927
+ }
4928
+ /**
4929
+ * Cost-based query optimizer.
4930
+ * Selects optimal index and execution strategy for queries.
4931
+ *
4932
+ * K = record key type, V = record value type
4933
+ */
4934
+ declare class QueryOptimizer<K, V> {
4935
+ private readonly indexRegistry;
4936
+ private readonly standingQueryRegistry?;
4937
+ /**
4938
+ * Create a QueryOptimizer.
4939
+ *
4940
+ * @param indexRegistryOrOptions - IndexRegistry or options object
4941
+ * @param standingQueryRegistry - Optional StandingQueryRegistry (deprecated, use options)
4942
+ */
4943
+ constructor(indexRegistryOrOptions: IndexRegistry<K, V> | QueryOptimizerOptions<K, V>, standingQueryRegistry?: StandingQueryRegistry<K, V>);
4944
+ /**
4945
+ * Optimize a query and return an execution plan.
4946
+ *
4947
+ * Optimization order (by cost):
4948
+ * 1. StandingQueryIndex (cost: 10) - pre-computed results
4949
+ * 2. Other indexes via optimizeNode
4950
+ *
4951
+ * @param query - Query to optimize
4952
+ * @returns Query execution plan
4953
+ */
4954
+ optimize(query: Query): QueryPlan;
4955
+ /**
4956
+ * Optimize a query with sort/limit/offset options.
4957
+ *
4958
+ * @param query - Query to optimize
4959
+ * @param options - Query options (sort, limit, offset)
4960
+ * @returns Query execution plan with options
4961
+ */
4962
+ optimizeWithOptions(query: Query, options: QueryOptions): QueryPlan;
4963
+ /**
4964
+ * Optimize a single query node.
4965
+ */
4966
+ private optimizeNode;
4967
+ /**
4968
+ * Optimize a simple (attribute-based) query.
4969
+ */
4970
+ private optimizeSimple;
4971
+ /**
4972
+ * Optimize a logical (AND/OR/NOT) query.
4973
+ */
4974
+ private optimizeLogical;
4975
+ /**
4976
+ * Optimize AND query.
4977
+ * Strategy: Find child with lowest cost, use as base, filter with rest.
4978
+ *
4979
+ * CQEngine "smallest first" strategy:
4980
+ * 1. Sort children by merge cost
4981
+ * 2. Use intersection if multiple indexes available
4982
+ * 3. Apply remaining predicates as filters
4983
+ */
4984
+ private optimizeAnd;
4985
+ /**
4986
+ * Optimize OR query.
4987
+ * Strategy: Union of all child results with deduplication.
4988
+ */
4989
+ private optimizeOr;
4990
+ /**
4991
+ * Optimize NOT query.
4992
+ * Strategy: Get all keys, subtract matching keys.
4993
+ */
4994
+ private optimizeNot;
4995
+ /**
4996
+ * Map query type to index query type.
4997
+ * Some query types have different names in indexes.
4998
+ */
4999
+ private mapQueryType;
5000
+ /**
5001
+ * Build an IndexQuery from a SimpleQueryNode.
5002
+ */
5003
+ private buildIndexQuery;
5004
+ /**
5005
+ * Estimate the execution cost of a plan step.
5006
+ */
5007
+ private estimateCost;
5008
+ /**
5009
+ * Check if a plan step uses any indexes.
5010
+ */
5011
+ private usesIndexes;
5012
+ }
5013
+
5014
+ /**
5015
+ * LiveQueryManager Implementation
5016
+ *
5017
+ * Manages live query subscriptions using StandingQueryIndexes.
5018
+ * Provides reactive updates when data changes.
5019
+ *
5020
+ * Features:
5021
+ * - Initial results on subscribe
5022
+ * - Delta updates on record changes
5023
+ * - Shared indexes for identical queries
5024
+ * - Automatic cleanup on unsubscribe
5025
+ *
5026
+ * @module query/LiveQueryManager
5027
+ */
5028
+
5029
+ /**
5030
+ * Initial results event sent when subscribing.
5031
+ */
5032
+ interface LiveQueryInitialEvent<K> {
5033
+ type: 'initial';
5034
+ query: Query;
5035
+ results: K[];
5036
+ }
5037
+ /**
5038
+ * Delta event sent when data changes.
5039
+ */
5040
+ interface LiveQueryDeltaEvent<K, V> {
5041
+ type: 'delta';
5042
+ query: Query;
5043
+ key: K;
5044
+ record: V;
5045
+ change: StandingQueryChange;
5046
+ operation: 'added' | 'updated' | 'removed';
5047
+ newResultCount: number;
5048
+ }
5049
+ /**
5050
+ * Union type for all live query events.
5051
+ */
5052
+ type LiveQueryEvent<K, V> = LiveQueryInitialEvent<K> | LiveQueryDeltaEvent<K, V>;
5053
+ /**
5054
+ * Callback for live query events.
5055
+ */
5056
+ type LiveQueryCallback<K, V> = (event: LiveQueryEvent<K, V>) => void;
5057
+ /**
5058
+ * Options for creating a LiveQueryManager.
5059
+ */
5060
+ interface LiveQueryManagerOptions<K, V> {
5061
+ /** Function to get record by key */
5062
+ getRecord: (key: K) => V | undefined;
5063
+ /** Function to get all entries for building index */
5064
+ getAllEntries: () => Iterable<[K, V]>;
5065
+ }
5066
+ /**
5067
+ * Manages live query subscriptions using StandingQueryIndexes.
5068
+ * Provides reactive updates when data changes.
5069
+ *
5070
+ * K = record key type, V = record value type
5071
+ */
5072
+ declare class LiveQueryManager<K, V> {
5073
+ private registry;
5074
+ /** Subscription callbacks by query hash */
5075
+ private subscriptions;
5076
+ constructor(options: LiveQueryManagerOptions<K, V>);
5077
+ /**
5078
+ * Subscribe to a live query.
5079
+ * Sends initial results immediately, then delta updates on changes.
5080
+ *
5081
+ * @param query - Query to subscribe to
5082
+ * @param callback - Callback for query events
5083
+ * @returns Unsubscribe function
5084
+ */
5085
+ subscribe(query: Query, callback: LiveQueryCallback<K, V>): () => void;
5086
+ /**
5087
+ * Get current results for a query (snapshot).
5088
+ * Does not subscribe to updates.
5089
+ *
5090
+ * @param query - Query to execute
5091
+ * @returns Array of matching keys
5092
+ */
5093
+ getResults(query: Query): K[];
5094
+ /**
5095
+ * Check if a query has active subscriptions.
5096
+ *
5097
+ * @param query - Query to check
5098
+ * @returns true if query has subscribers
5099
+ */
5100
+ hasSubscribers(query: Query): boolean;
5101
+ /**
5102
+ * Get subscriber count for a query.
5103
+ *
5104
+ * @param query - Query to check
5105
+ * @returns Number of subscribers
5106
+ */
5107
+ getSubscriberCount(query: Query): number;
5108
+ /**
5109
+ * Notify of record addition.
5110
+ * Triggers subscription callbacks for affected queries.
5111
+ *
5112
+ * @param key - Record key
5113
+ * @param record - New record value
5114
+ */
5115
+ onRecordAdded(key: K, record: V): void;
5116
+ /**
5117
+ * Notify of record update.
5118
+ * Triggers subscription callbacks for affected queries.
5119
+ *
5120
+ * @param key - Record key
5121
+ * @param oldRecord - Previous record value
5122
+ * @param newRecord - New record value
5123
+ */
5124
+ onRecordUpdated(key: K, oldRecord: V, newRecord: V): void;
5125
+ /**
5126
+ * Notify of record removal.
5127
+ * Triggers subscription callbacks for affected queries.
5128
+ *
5129
+ * @param key - Record key
5130
+ * @param record - Removed record value
5131
+ */
5132
+ onRecordRemoved(key: K, record: V): void;
5133
+ /**
5134
+ * Notify subscribers of changes.
5135
+ */
5136
+ private notifySubscribers;
5137
+ /**
5138
+ * Get the underlying registry for direct access.
5139
+ * Useful for testing and debugging.
5140
+ *
5141
+ * @returns StandingQueryRegistry instance
5142
+ */
5143
+ getRegistry(): StandingQueryRegistry<K, V>;
5144
+ /**
5145
+ * Get all active query hashes.
5146
+ *
5147
+ * @returns Array of query hashes with active subscriptions
5148
+ */
5149
+ getActiveQueries(): string[];
5150
+ /**
5151
+ * Get statistics about the manager.
5152
+ *
5153
+ * @returns Statistics object
5154
+ */
5155
+ getStats(): LiveQueryManagerStats;
5156
+ /**
5157
+ * Clear all subscriptions and indexes.
5158
+ */
5159
+ clear(): void;
5160
+ }
5161
+ /**
5162
+ * Statistics about the LiveQueryManager.
5163
+ */
5164
+ interface LiveQueryManagerStats extends StandingQueryRegistryStats {
5165
+ /** Number of active queries with subscribers */
5166
+ activeQueries: number;
5167
+ /** Total number of subscribers across all queries */
5168
+ totalSubscribers: number;
5169
+ }
5170
+
5171
+ /**
5172
+ * Types for Adaptive Indexing System (Phase 8.02)
5173
+ *
5174
+ * Defines interfaces for query pattern tracking, index suggestions,
5175
+ * and auto-indexing configuration.
5176
+ *
5177
+ * @module query/adaptive/types
5178
+ */
5179
+ /**
5180
+ * Query type for pattern tracking.
5181
+ * Matches the query types from QueryTypes.ts and indexes/types.ts
5182
+ */
5183
+ type TrackedQueryType = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'between' | 'in' | 'has' | 'contains' | 'containsAll' | 'containsAny';
5184
+ /**
5185
+ * Statistics for a single attribute + query type combination.
5186
+ */
5187
+ interface QueryStatistics {
5188
+ /** Attribute name being queried */
5189
+ attribute: string;
5190
+ /** Type of query (eq, gt, between, etc.) */
5191
+ queryType: TrackedQueryType;
5192
+ /** Number of times this pattern was queried */
5193
+ queryCount: number;
5194
+ /** Cumulative execution time in milliseconds */
5195
+ totalCost: number;
5196
+ /** Average execution time per query */
5197
+ averageCost: number;
5198
+ /** Timestamp of last query */
5199
+ lastQueried: number;
5200
+ /** Estimated result size (max observed) */
5201
+ estimatedCardinality: number;
5202
+ /** Whether an index exists for this attribute */
5203
+ hasIndex: boolean;
5204
+ }
5205
+ /**
5206
+ * Index type recommendation.
5207
+ */
5208
+ type RecommendedIndexType = 'hash' | 'navigable' | 'inverted';
5209
+ /**
5210
+ * Priority level for index suggestions.
5211
+ */
5212
+ type SuggestionPriority = 'high' | 'medium' | 'low';
5213
+ /**
5214
+ * Index suggestion generated by IndexAdvisor.
5215
+ */
5216
+ interface IndexSuggestion {
5217
+ /** Attribute to index */
5218
+ attribute: string;
5219
+ /** Recommended index type */
5220
+ indexType: RecommendedIndexType;
5221
+ /** Human-readable explanation */
5222
+ reason: string;
5223
+ /** Expected performance improvement multiplier */
5224
+ estimatedBenefit: number;
5225
+ /** Estimated memory overhead in bytes */
5226
+ estimatedCost: number;
5227
+ /** Priority based on query patterns */
5228
+ priority: SuggestionPriority;
5229
+ /** Query count that triggered this suggestion */
5230
+ queryCount: number;
5231
+ /** Average query cost in milliseconds */
5232
+ averageCost: number;
5233
+ }
5234
+ /**
5235
+ * Options for getting index suggestions.
5236
+ */
5237
+ interface IndexSuggestionOptions {
5238
+ /** Minimum query count to consider (default: 10) */
5239
+ minQueryCount?: number;
5240
+ /** Minimum average cost in ms to consider (default: 1) */
5241
+ minAverageCost?: number;
5242
+ /** Whether to exclude already indexed attributes (default: true) */
5243
+ excludeExistingIndexes?: boolean;
5244
+ /** Maximum number of suggestions to return (default: unlimited) */
5245
+ maxSuggestions?: number;
5246
+ }
5247
+ /**
5248
+ * Configuration for Index Advisor.
5249
+ */
5250
+ interface AdvisorConfig {
5251
+ /** Enable advisor mode (default: true) */
5252
+ enabled: boolean;
5253
+ /** Minimum query count before suggesting (default: 10) */
5254
+ minQueryCount?: number;
5255
+ /** Minimum average cost in ms to suggest (default: 1) */
5256
+ minAverageCost?: number;
5257
+ }
5258
+ /**
5259
+ * Callback for index creation events.
5260
+ */
5261
+ type IndexCreatedCallback = (attribute: string, indexType: RecommendedIndexType) => void;
5262
+ /**
5263
+ * Configuration for Auto-Index Manager.
5264
+ */
5265
+ interface AutoIndexConfig {
5266
+ /** Enable auto-indexing (default: false) */
5267
+ enabled: boolean;
5268
+ /** Number of queries before auto-creating index (default: 10) */
5269
+ threshold?: number;
5270
+ /** Maximum number of auto-created indexes (default: 20) */
5271
+ maxIndexes?: number;
5272
+ /** Callback when index is automatically created */
5273
+ onIndexCreated?: IndexCreatedCallback;
5274
+ }
5275
+ /**
5276
+ * Default indexing strategy.
5277
+ * - 'none': No automatic indexing (default)
5278
+ * - 'scalar': Index all top-level scalar (primitive) fields
5279
+ * - 'all': Index all fields including nested (not recommended)
5280
+ */
5281
+ type DefaultIndexingStrategy = 'none' | 'scalar' | 'all';
5282
+ /**
5283
+ * Complete adaptive indexing configuration.
5284
+ */
5285
+ interface AdaptiveIndexingConfig {
5286
+ /** Index Advisor configuration */
5287
+ advisor?: AdvisorConfig;
5288
+ /** Auto-Index Manager configuration */
5289
+ autoIndex?: AutoIndexConfig;
5290
+ }
5291
+ /**
5292
+ * Extended options for IndexedLWWMap/IndexedORMap.
5293
+ */
5294
+ interface IndexedMapOptions {
5295
+ /** Adaptive indexing configuration */
5296
+ adaptiveIndexing?: AdaptiveIndexingConfig;
5297
+ /** Default indexing strategy (default: 'none') */
5298
+ defaultIndexing?: DefaultIndexingStrategy;
5299
+ }
5300
+
5301
+ /**
5302
+ * QueryPatternTracker (Phase 8.02.1)
5303
+ *
5304
+ * Collects runtime statistics on query execution patterns.
5305
+ * Used by IndexAdvisor to generate index suggestions.
5306
+ *
5307
+ * Features:
5308
+ * - Tracks query count, cost, and cardinality per attribute
5309
+ * - Low overhead (< 1% of query time)
5310
+ * - Optional sampling for high-throughput scenarios
5311
+ * - Memory-bounded (circular buffer for old stats)
5312
+ *
5313
+ * @module query/adaptive/QueryPatternTracker
5314
+ */
5315
+
5316
+ /**
5317
+ * Options for QueryPatternTracker.
5318
+ */
5319
+ interface QueryPatternTrackerOptions {
5320
+ /**
5321
+ * Sampling rate: 1 = track all queries, N = track 1 in N queries.
5322
+ * Higher values reduce overhead but decrease accuracy.
5323
+ * Default: 1 (track all)
5324
+ */
5325
+ samplingRate?: number;
5326
+ /**
5327
+ * Maximum number of unique attribute+queryType combinations to track.
5328
+ * Prevents unbounded memory growth.
5329
+ * Default: 1000
5330
+ */
5331
+ maxTrackedPatterns?: number;
5332
+ /**
5333
+ * Time-to-live for statistics in milliseconds.
5334
+ * Statistics older than this are considered stale.
5335
+ * Default: 24 hours
5336
+ */
5337
+ statsTtl?: number;
5338
+ }
5339
+ /**
5340
+ * QueryPatternTracker collects runtime statistics on query execution.
5341
+ *
5342
+ * @example
5343
+ * ```typescript
5344
+ * const tracker = new QueryPatternTracker();
5345
+ *
5346
+ * // Record queries during execution
5347
+ * tracker.recordQuery('category', 'eq', 5.2, 100, false);
5348
+ * tracker.recordQuery('category', 'eq', 4.8, 100, false);
5349
+ *
5350
+ * // Get statistics
5351
+ * const stats = tracker.getStatistics();
5352
+ * // [{ attribute: 'category', queryType: 'eq', queryCount: 2, averageCost: 5.0, ... }]
5353
+ * ```
5354
+ */
5355
+ declare class QueryPatternTracker {
5356
+ private stats;
5357
+ private queryCounter;
5358
+ private readonly samplingRate;
5359
+ private readonly maxTrackedPatterns;
5360
+ private readonly statsTtl;
5361
+ constructor(options?: QueryPatternTrackerOptions);
5362
+ /**
5363
+ * Record a query execution for pattern tracking.
5364
+ *
5365
+ * @param attribute - The attribute being queried
5366
+ * @param queryType - The type of query (eq, gt, between, etc.)
5367
+ * @param executionTime - Query execution time in milliseconds
5368
+ * @param resultSize - Number of results returned
5369
+ * @param hasIndex - Whether an index was used
5370
+ */
5371
+ recordQuery(attribute: string, queryType: TrackedQueryType, executionTime: number, resultSize: number, hasIndex: boolean): void;
5372
+ /**
5373
+ * Get all query statistics.
5374
+ *
5375
+ * @returns Array of query statistics, sorted by query count descending
5376
+ */
5377
+ getStatistics(): QueryStatistics[];
5378
+ /**
5379
+ * Get statistics for a specific attribute.
5380
+ *
5381
+ * @param attribute - The attribute name
5382
+ * @returns Array of query statistics for this attribute
5383
+ */
5384
+ getAttributeStats(attribute: string): QueryStatistics[];
5385
+ /**
5386
+ * Get statistics for a specific attribute and query type.
5387
+ *
5388
+ * @param attribute - The attribute name
5389
+ * @param queryType - The query type
5390
+ * @returns Query statistics or undefined
5391
+ */
5392
+ getStats(attribute: string, queryType: TrackedQueryType): QueryStatistics | undefined;
5393
+ /**
5394
+ * Check if an attribute has been queried.
5395
+ *
5396
+ * @param attribute - The attribute name
5397
+ * @returns True if the attribute has query statistics
5398
+ */
5399
+ hasStats(attribute: string): boolean;
5400
+ /**
5401
+ * Get the total number of queries recorded.
5402
+ *
5403
+ * @returns Total query count across all patterns
5404
+ */
5405
+ getTotalQueryCount(): number;
5406
+ /**
5407
+ * Get the number of unique attribute+queryType patterns tracked.
5408
+ *
5409
+ * @returns Number of unique patterns
5410
+ */
5411
+ getPatternCount(): number;
5412
+ /**
5413
+ * Update index status for an attribute.
5414
+ * Called when an index is added or removed.
5415
+ *
5416
+ * @param attribute - The attribute name
5417
+ * @param hasIndex - Whether an index now exists
5418
+ */
5419
+ updateIndexStatus(attribute: string, hasIndex: boolean): void;
5420
+ /**
5421
+ * Reset query count for an attribute after index creation.
5422
+ * This prevents immediate re-suggestion of the same index.
5423
+ *
5424
+ * @param attribute - The attribute name
5425
+ */
5426
+ resetAttributeStats(attribute: string): void;
5427
+ /**
5428
+ * Clear all statistics.
5429
+ */
5430
+ clear(): void;
5431
+ /**
5432
+ * Get a summary of tracking overhead.
5433
+ *
5434
+ * @returns Tracking overhead info
5435
+ */
5436
+ getTrackingInfo(): {
5437
+ patternsTracked: number;
5438
+ totalQueries: number;
5439
+ samplingRate: number;
5440
+ memoryEstimate: number;
5441
+ };
5442
+ /**
5443
+ * Evict the oldest (least recently queried) entry.
5444
+ */
5445
+ private evictOldest;
5446
+ /**
5447
+ * Prune stale statistics older than TTL.
5448
+ */
5449
+ private pruneStale;
5450
+ }
5451
+
5452
+ /**
5453
+ * IndexAdvisor (Phase 8.02.2)
5454
+ *
5455
+ * Analyzes query patterns and generates index suggestions.
5456
+ * Used in production mode to help developers optimize their indexes.
5457
+ *
5458
+ * Features:
5459
+ * - Cost/benefit analysis for index suggestions
5460
+ * - Automatic index type selection based on query type
5461
+ * - Priority-based ranking of suggestions
5462
+ * - Memory cost estimation
5463
+ *
5464
+ * @module query/adaptive/IndexAdvisor
5465
+ */
5466
+
5467
+ /**
5468
+ * IndexAdvisor analyzes query patterns and generates index suggestions.
5469
+ *
5470
+ * @example
5471
+ * ```typescript
5472
+ * const tracker = new QueryPatternTracker();
5473
+ * const advisor = new IndexAdvisor(tracker);
5474
+ *
5475
+ * // After application runs...
5476
+ * const suggestions = advisor.getSuggestions();
5477
+ * // [
5478
+ * // {
5479
+ * // attribute: 'category',
5480
+ * // indexType: 'hash',
5481
+ * // reason: 'Queried 1000× with average cost 5.2ms. Expected 500× speedup.',
5482
+ * // priority: 'high'
5483
+ * // }
5484
+ * // ]
5485
+ * ```
5486
+ */
5487
+ declare class IndexAdvisor {
5488
+ private readonly tracker;
5489
+ constructor(tracker: QueryPatternTracker);
5490
+ /**
5491
+ * Get index suggestions based on query patterns.
5492
+ *
5493
+ * @param options - Suggestion options
5494
+ * @returns Array of index suggestions sorted by priority
5495
+ */
5496
+ getSuggestions(options?: IndexSuggestionOptions): IndexSuggestion[];
5497
+ /**
5498
+ * Get a suggestion for a specific attribute.
5499
+ *
5500
+ * @param attribute - The attribute name
5501
+ * @returns Index suggestion or null if not recommended
5502
+ */
5503
+ getSuggestionForAttribute(attribute: string): IndexSuggestion | null;
5504
+ /**
5505
+ * Check if an attribute should be indexed based on patterns.
5506
+ *
5507
+ * @param attribute - The attribute name
5508
+ * @param threshold - Minimum query count threshold
5509
+ * @returns True if attribute should be indexed
5510
+ */
5511
+ shouldIndex(attribute: string, threshold?: number): boolean;
5512
+ /**
5513
+ * Get recommended index type for a query type.
5514
+ *
5515
+ * @param queryType - The query type
5516
+ * @returns Recommended index type or null if not indexable
5517
+ */
5518
+ getRecommendedIndexType(queryType: TrackedQueryType): RecommendedIndexType | null;
5519
+ /**
5520
+ * Group statistics by attribute.
5521
+ */
5522
+ private groupByAttribute;
5523
+ /**
5524
+ * Find the best (most beneficial) pattern for an attribute.
5525
+ */
5526
+ private findBestPattern;
5527
+ /**
5528
+ * Generate a suggestion for a query pattern.
5529
+ */
5530
+ private generateSuggestion;
5531
+ /**
5532
+ * Select appropriate index type based on query type.
5533
+ */
5534
+ private selectIndexType;
5535
+ /**
5536
+ * Count how many query patterns would benefit from an index type.
5537
+ */
5538
+ private countBenefitingPatterns;
5539
+ /**
5540
+ * Estimate performance benefit of adding an index.
5541
+ *
5542
+ * Heuristic based on:
5543
+ * - Full scan vs indexed: typically 100-1000× speedup
5544
+ * - Query frequency amplifies benefit
5545
+ */
5546
+ private estimateBenefit;
5547
+ /**
5548
+ * Estimate memory cost of adding an index.
5549
+ */
5550
+ private estimateMemoryCost;
5551
+ /**
5552
+ * Calculate priority based on query patterns and benefit.
5553
+ */
5554
+ private calculatePriority;
5555
+ /**
5556
+ * Generate human-readable reason for the suggestion.
5557
+ */
5558
+ private generateReason;
5559
+ }
5560
+
5561
+ /**
5562
+ * AutoIndexManager (Phase 8.02.3)
5563
+ *
5564
+ * Automatically creates indexes based on query patterns.
5565
+ * Intended for development mode to simplify index management.
5566
+ *
5567
+ * Features:
5568
+ * - Automatic index creation after threshold queries
5569
+ * - Safety limits to prevent memory exhaustion
5570
+ * - Callback notifications for index creation events
5571
+ * - Integration with IndexAdvisor for type selection
5572
+ *
5573
+ * @module query/adaptive/AutoIndexManager
5574
+ */
5575
+
5576
+ /**
5577
+ * Interface for indexed map operations.
5578
+ * Used to decouple AutoIndexManager from IndexedLWWMap/IndexedORMap.
5579
+ */
5580
+ interface IndexableMap<K, V> {
5581
+ /** Get all current indexes */
5582
+ getIndexes(): {
5583
+ attribute: {
5584
+ name: string;
5585
+ };
5586
+ type: string;
5587
+ }[];
5588
+ /** Check if attribute has an index */
5589
+ hasIndexOn(attributeName: string): boolean;
5590
+ /** Add a hash index */
5591
+ addHashIndex<A>(attribute: Attribute<V, A>): void;
5592
+ /** Add a navigable index */
5593
+ addNavigableIndex<A extends string | number>(attribute: Attribute<V, A>): void;
5594
+ /** Add an inverted index */
5595
+ addInvertedIndex<A extends string>(attribute: Attribute<V, A>): void;
5596
+ }
5597
+ /**
5598
+ * AutoIndexManager automatically creates indexes based on query patterns.
5599
+ *
5600
+ * @example
5601
+ * ```typescript
5602
+ * const manager = new AutoIndexManager(tracker, advisor, {
5603
+ * enabled: true,
5604
+ * threshold: 10,
5605
+ * maxIndexes: 20,
5606
+ * onIndexCreated: (attr, type) => console.log(`Created ${type} on ${attr}`)
5607
+ * });
5608
+ *
5609
+ * manager.registerAttribute(simpleAttribute('category', p => p.category));
5610
+ * manager.setMap(indexedMap);
5611
+ *
5612
+ * // After 10 queries on 'category', index is auto-created
5613
+ * ```
5614
+ */
5615
+ declare class AutoIndexManager<K, V> {
5616
+ private readonly tracker;
5617
+ private readonly advisor;
5618
+ private readonly config;
5619
+ private readonly attributeQueryCounts;
5620
+ private readonly registeredAttributes;
5621
+ private readonly createdIndexes;
5622
+ private map;
5623
+ constructor(tracker: QueryPatternTracker, advisor: IndexAdvisor, config: AutoIndexConfig);
5624
+ /**
5625
+ * Set the indexed map to create indexes on.
5626
+ */
5627
+ setMap(map: IndexableMap<K, V>): void;
5628
+ /**
5629
+ * Register an attribute that can be auto-indexed.
5630
+ *
5631
+ * @param attribute - The attribute to register
5632
+ * @param allowedIndexTypes - Optional list of allowed index types
5633
+ */
5634
+ registerAttribute<A>(attribute: Attribute<V, A>, allowedIndexTypes?: RecommendedIndexType[]): void;
5635
+ /**
5636
+ * Unregister an attribute.
5637
+ *
5638
+ * @param attributeName - Name of attribute to unregister
5639
+ */
5640
+ unregisterAttribute(attributeName: string): void;
5641
+ /**
5642
+ * Check if an attribute is registered.
5643
+ *
5644
+ * @param attributeName - Name of attribute to check
5645
+ * @returns True if attribute is registered
5646
+ */
5647
+ hasAttribute(attributeName: string): boolean;
5648
+ /**
5649
+ * Get a registered attribute.
5650
+ *
5651
+ * @param attributeName - Name of attribute
5652
+ * @returns The attribute or undefined
5653
+ */
5654
+ getAttribute(attributeName: string): Attribute<V, unknown> | undefined;
5655
+ /**
5656
+ * Get all registered attribute names.
5657
+ *
5658
+ * @returns Array of registered attribute names
5659
+ */
5660
+ getRegisteredAttributeNames(): string[];
5661
+ /**
5662
+ * Called when a query is executed. Tracks patterns and triggers auto-indexing.
5663
+ *
5664
+ * @param attribute - The attribute being queried
5665
+ * @param queryType - The type of query
5666
+ */
5667
+ onQueryExecuted(attribute: string, queryType: TrackedQueryType): void;
5668
+ /**
5669
+ * Check if we're at the index limit.
5670
+ *
5671
+ * @returns True if max indexes reached
5672
+ */
5673
+ isAtLimit(): boolean;
5674
+ /**
5675
+ * Get number of auto-created indexes.
5676
+ *
5677
+ * @returns Number of indexes created by this manager
5678
+ */
5679
+ getAutoCreatedIndexCount(): number;
5680
+ /**
5681
+ * Get remaining index capacity.
5682
+ *
5683
+ * @returns Number of indexes that can still be created
5684
+ */
5685
+ getRemainingCapacity(): number;
5686
+ /**
5687
+ * Reset query counts (e.g., after clearing data).
5688
+ */
5689
+ resetCounts(): void;
5690
+ /**
5691
+ * Get current configuration.
5692
+ */
5693
+ getConfig(): Readonly<AutoIndexConfig>;
5694
+ /**
5695
+ * Update configuration at runtime.
5696
+ *
5697
+ * @param updates - Partial config updates
5698
+ */
5699
+ updateConfig(updates: Partial<AutoIndexConfig>): void;
5700
+ /**
5701
+ * Try to create an index for the attribute.
5702
+ */
5703
+ private tryCreateIndex;
5704
+ /**
5705
+ * Create an index on the map.
5706
+ */
5707
+ private createIndex;
5708
+ }
5709
+
5710
+ /**
5711
+ * IndexedLWWMap Implementation
5712
+ *
5713
+ * LWWMap with index support for O(1) to O(log N) queries.
5714
+ * Wraps LWWMap with indexing capabilities using the Wrapper Pattern.
5715
+ *
5716
+ * Features:
5717
+ * - Hash and Navigable indexes for efficient queries
5718
+ * - Live queries with StandingQueryIndex
5719
+ * - Automatic index updates on CRDT operations
5720
+ * - Cost-based query optimization
5721
+ * - Adaptive indexing with query pattern tracking (Phase 8.02)
5722
+ *
5723
+ * @module IndexedLWWMap
5724
+ */
5725
+
5726
+ /**
5727
+ * LWWMap with index support for O(1) to O(log N) queries.
5728
+ *
5729
+ * K = key type (extends string for compatibility)
5730
+ * V = value type
5731
+ */
5732
+ declare class IndexedLWWMap<K extends string, V> extends LWWMap<K, V> {
5733
+ private indexRegistry;
5734
+ private standingQueryRegistry;
5735
+ private liveQueryManager;
5736
+ private queryOptimizer;
5737
+ private readonly queryTracker;
5738
+ private readonly indexAdvisor;
5739
+ private readonly autoIndexManager;
5740
+ private readonly defaultIndexingStrategy;
5741
+ private readonly options;
5742
+ constructor(hlc: HLC, options?: IndexedMapOptions);
5743
+ /**
5744
+ * Add a hash index on an attribute.
5745
+ *
5746
+ * @param attribute - Attribute to index
5747
+ * @returns Created HashIndex
5748
+ */
5749
+ addHashIndex<A>(attribute: Attribute<V, A>): HashIndex<K, V, A>;
5750
+ /**
5751
+ * Add a navigable index on an attribute.
5752
+ * Navigable indexes support range queries (gt, gte, lt, lte, between).
5753
+ *
5754
+ * @param attribute - Attribute to index
5755
+ * @param comparator - Optional custom comparator
5756
+ * @returns Created NavigableIndex
5757
+ */
5758
+ addNavigableIndex<A extends string | number>(attribute: Attribute<V, A>, comparator?: (a: A, b: A) => number): NavigableIndex<K, V, A>;
5759
+ /**
5760
+ * Add an inverted index for full-text search on an attribute.
5761
+ * Inverted indexes support text search queries (contains, containsAll, containsAny).
5762
+ *
5763
+ * @param attribute - Text attribute to index
5764
+ * @param pipeline - Optional custom tokenization pipeline
5765
+ * @returns Created InvertedIndex
5766
+ *
5767
+ * @example
5768
+ * ```typescript
5769
+ * const nameAttr = simpleAttribute<Product, string>('name', p => p.name);
5770
+ * products.addInvertedIndex(nameAttr);
5771
+ *
5772
+ * // Search for products containing "wireless"
5773
+ * products.query({ type: 'contains', attribute: 'name', value: 'wireless' });
5774
+ * ```
5775
+ */
5776
+ addInvertedIndex<A extends string = string>(attribute: Attribute<V, A>, pipeline?: TokenizationPipeline): InvertedIndex<K, V, A>;
5777
+ /**
5778
+ * Add a custom index.
5779
+ *
5780
+ * @param index - Index to add
5781
+ */
5782
+ addIndex<A>(index: Index<K, V, A>): void;
5783
+ /**
5784
+ * Remove an index.
5785
+ *
5786
+ * @param index - Index to remove
5787
+ * @returns true if index was found and removed
5788
+ */
5789
+ removeIndex<A>(index: Index<K, V, A>): boolean;
5790
+ /**
5791
+ * Get all indexes.
5792
+ *
5793
+ * @returns Array of all indexes
5794
+ */
5795
+ getIndexes(): Index<K, V, unknown>[];
5796
+ /**
5797
+ * Check if an attribute is indexed.
5798
+ *
5799
+ * @param attributeName - Attribute name
5800
+ * @returns true if attribute has indexes
5801
+ */
5802
+ hasIndexOn(attributeName: string): boolean;
5803
+ /**
5804
+ * Build index from existing data.
5805
+ */
5806
+ private buildIndex;
5807
+ /**
5808
+ * Execute a query using indexes.
5809
+ * Returns lazy ResultSet of matching keys.
5810
+ *
5811
+ * Also tracks query patterns for adaptive indexing (Phase 8.02).
5812
+ *
5813
+ * @param query - Query to execute
5814
+ * @returns ResultSet of matching keys
5815
+ */
5816
+ query(query: Query): ResultSet<K>;
5817
+ /**
5818
+ * Execute a query and return materialized results.
5819
+ * Returns array of [key, value] pairs.
5820
+ *
5821
+ * @param query - Query to execute
5822
+ * @returns Array of [key, value] pairs
5823
+ */
5824
+ queryEntries(query: Query): [K, V][];
5825
+ /**
5826
+ * Execute a query and return matching values.
5827
+ *
5828
+ * @param query - Query to execute
5829
+ * @returns Array of matching values
5830
+ */
5831
+ queryValues(query: Query): V[];
5832
+ /**
5833
+ * Count matching records without materializing results.
5834
+ *
5835
+ * @param query - Query to execute
5836
+ * @returns Number of matching records
5837
+ */
5838
+ count(query: Query): number;
5839
+ /**
5840
+ * Execute plan and return result set.
5841
+ */
5842
+ private executePlan;
5843
+ /**
5844
+ * Perform full scan with predicate evaluation.
5845
+ */
5846
+ private fullScan;
5847
+ /**
5848
+ * Check if record matches predicate.
5849
+ * Converts Query to PredicateNode format for evaluation.
5850
+ */
5851
+ private matchesPredicate;
5852
+ /**
5853
+ * Check if record matches IndexQuery (used by FallbackIndex).
5854
+ * This is a simplified matcher for full scan fallback.
5855
+ */
5856
+ private matchesIndexQuery;
5857
+ /**
5858
+ * Convert Query to PredicateNode format.
5859
+ */
5860
+ private queryToPredicate;
5861
+ /**
5862
+ * Subscribe to a live query.
5863
+ * Callback receives initial results and delta updates.
5864
+ *
5865
+ * @param query - Query to subscribe to
5866
+ * @param callback - Callback for query events
5867
+ * @returns Unsubscribe function
5868
+ */
5869
+ subscribeLiveQuery(query: Query, callback: LiveQueryCallback<K, V>): () => void;
5870
+ /**
5871
+ * Get current live query results (snapshot).
5872
+ *
5873
+ * @param query - Query to execute
5874
+ * @returns Array of matching keys
5875
+ */
5876
+ getLiveQueryResults(query: Query): K[];
5877
+ /**
5878
+ * Check if a query has active subscribers.
5879
+ *
5880
+ * @param query - Query to check
5881
+ * @returns true if query has subscribers
5882
+ */
5883
+ hasLiveQuerySubscribers(query: Query): boolean;
5884
+ /**
5885
+ * Set a value (with index updates).
5886
+ */
5887
+ set(key: K, value: V, ttlMs?: number): LWWRecord<V>;
5888
+ /**
5889
+ * Remove a value (with index updates).
5890
+ */
5891
+ remove(key: K): LWWRecord<V>;
5892
+ /**
5893
+ * Merge a remote record (with index updates).
5894
+ */
5895
+ merge(key: K, remote: LWWRecord<V>): boolean;
5896
+ /**
5897
+ * Clear all data (and indexes).
5898
+ */
5899
+ clear(): void;
5900
+ /**
5901
+ * Returns all keys (non-tombstoned, non-expired).
5902
+ */
5903
+ keys(): Iterable<K>;
5904
+ /**
5905
+ * Get index statistics.
5906
+ */
5907
+ getIndexStats(): Map<string, IndexStats>;
5908
+ /**
5909
+ * Get index registry statistics.
5910
+ */
5911
+ getIndexRegistryStats(): IndexRegistryStats;
5912
+ /**
5913
+ * Get query optimizer for plan inspection.
5914
+ */
5915
+ getQueryOptimizer(): QueryOptimizer<K, V>;
5916
+ /**
5917
+ * Get live query manager for direct access.
5918
+ */
5919
+ getLiveQueryManager(): LiveQueryManager<K, V>;
5920
+ /**
5921
+ * Get standing query registry for direct access.
5922
+ */
5923
+ getStandingQueryRegistry(): StandingQueryRegistry<K, V>;
5924
+ /**
5925
+ * Explain query execution plan.
5926
+ *
5927
+ * @param query - Query to explain
5928
+ * @returns Query execution plan
5929
+ */
5930
+ explainQuery(query: Query): QueryPlan;
5931
+ /**
5932
+ * Register an attribute for auto-indexing.
5933
+ * Required before auto-index can create indexes on this attribute.
5934
+ *
5935
+ * @param attribute - The attribute to register
5936
+ * @param allowedIndexTypes - Optional list of allowed index types
5937
+ */
5938
+ registerAttribute<A>(attribute: Attribute<V, A>, allowedIndexTypes?: RecommendedIndexType[]): void;
5939
+ /**
5940
+ * Unregister an attribute from auto-indexing.
5941
+ *
5942
+ * @param attributeName - Name of attribute to unregister
5943
+ */
5944
+ unregisterAttribute(attributeName: string): void;
5945
+ /**
5946
+ * Get index suggestions based on query patterns.
5947
+ * Use this in production to get recommendations for manual index creation.
5948
+ *
5949
+ * @param options - Suggestion options
5950
+ * @returns Array of index suggestions sorted by priority
5951
+ *
5952
+ * @example
5953
+ * ```typescript
5954
+ * const suggestions = products.getIndexSuggestions();
5955
+ * // [{ attribute: 'category', indexType: 'hash', priority: 'high', ... }]
5956
+ * ```
5957
+ */
5958
+ getIndexSuggestions(options?: IndexSuggestionOptions): IndexSuggestion[];
5959
+ /**
5960
+ * Get query pattern statistics.
5961
+ * Useful for debugging and understanding query patterns.
5962
+ *
5963
+ * @returns Array of query statistics
5964
+ */
5965
+ getQueryStatistics(): QueryStatistics[];
5966
+ /**
5967
+ * Reset query statistics.
5968
+ * Call this to clear accumulated query patterns.
5969
+ */
5970
+ resetQueryStatistics(): void;
5971
+ /**
5972
+ * Get query pattern tracker for advanced usage.
5973
+ */
5974
+ getQueryTracker(): QueryPatternTracker;
5975
+ /**
5976
+ * Get index advisor for advanced usage.
5977
+ */
5978
+ getIndexAdvisor(): IndexAdvisor;
5979
+ /**
5980
+ * Get auto-index manager (if enabled).
5981
+ */
5982
+ getAutoIndexManager(): AutoIndexManager<K, V> | null;
5983
+ /**
5984
+ * Check if auto-indexing is enabled.
5985
+ */
5986
+ isAutoIndexingEnabled(): boolean;
5987
+ /**
5988
+ * Track query pattern for adaptive indexing.
5989
+ */
5990
+ private trackQueryPattern;
5991
+ /**
5992
+ * Extract attribute name from query.
5993
+ */
5994
+ private extractAttribute;
5995
+ /**
5996
+ * Extract query type from query.
5997
+ */
5998
+ private extractQueryType;
5999
+ }
6000
+
6001
+ /**
6002
+ * IndexedORMap Implementation
6003
+ *
6004
+ * ORMap with index support for O(1) to O(log N) queries.
6005
+ * Wraps ORMap with indexing capabilities using the Wrapper Pattern.
6006
+ *
6007
+ * Note: ORMap stores multiple values per key (with tags).
6008
+ * Indexes track unique (key, tag) composite keys.
6009
+ *
6010
+ * Features:
6011
+ * - Hash and Navigable indexes for efficient queries
6012
+ * - Composite key indexing (key:tag)
6013
+ * - Automatic index updates on CRDT operations
6014
+ * - Lazy filtering for tombstones
6015
+ * - Adaptive indexing with query pattern tracking (Phase 8.02)
6016
+ *
6017
+ * @module IndexedORMap
6018
+ */
6019
+
6020
+ /**
6021
+ * Result of a query on IndexedORMap.
6022
+ */
6023
+ interface ORMapQueryResult<K, V> {
6024
+ key: K;
6025
+ tag: string;
6026
+ value: V;
6027
+ }
6028
+ /**
6029
+ * ORMap with index support.
6030
+ *
6031
+ * Note: ORMap stores multiple values per key (with tags).
6032
+ * Indexes track unique (key, tag) pairs using composite keys.
6033
+ *
6034
+ * K = key type (extends string for compatibility)
6035
+ * V = value type
6036
+ */
6037
+ declare class IndexedORMap<K extends string, V> extends ORMap<K, V> {
6038
+ private indexRegistry;
6039
+ private queryOptimizer;
6040
+ private readonly queryTracker;
6041
+ private readonly indexAdvisor;
6042
+ private readonly autoIndexManager;
6043
+ private readonly defaultIndexingStrategy;
6044
+ private readonly options;
6045
+ constructor(hlc: HLC, options?: IndexedMapOptions);
6046
+ /**
6047
+ * Add a hash index on an attribute.
6048
+ *
6049
+ * @param attribute - Attribute to index
6050
+ * @returns Created HashIndex
6051
+ */
6052
+ addHashIndex<A>(attribute: Attribute<V, A>): HashIndex<string, V, A>;
6053
+ /**
6054
+ * Add a navigable index on an attribute.
6055
+ * Navigable indexes support range queries (gt, gte, lt, lte, between).
6056
+ *
6057
+ * @param attribute - Attribute to index
6058
+ * @param comparator - Optional custom comparator
6059
+ * @returns Created NavigableIndex
6060
+ */
6061
+ addNavigableIndex<A extends string | number>(attribute: Attribute<V, A>, comparator?: (a: A, b: A) => number): NavigableIndex<string, V, A>;
6062
+ /**
6063
+ * Add an inverted index for full-text search on an attribute.
6064
+ * Inverted indexes support text search queries (contains, containsAll, containsAny).
6065
+ *
6066
+ * @param attribute - Text attribute to index
6067
+ * @param pipeline - Optional custom tokenization pipeline
6068
+ * @returns Created InvertedIndex
6069
+ */
6070
+ addInvertedIndex<A extends string = string>(attribute: Attribute<V, A>, pipeline?: TokenizationPipeline): InvertedIndex<string, V, A>;
6071
+ /**
6072
+ * Add a custom index.
6073
+ *
6074
+ * @param index - Index to add
6075
+ */
6076
+ addIndex<A>(index: Index<string, V, A>): void;
6077
+ /**
6078
+ * Remove an index.
6079
+ *
6080
+ * @param index - Index to remove
6081
+ * @returns true if index was found and removed
6082
+ */
6083
+ removeIndex<A>(index: Index<string, V, A>): boolean;
6084
+ /**
6085
+ * Get all indexes.
6086
+ *
6087
+ * @returns Array of all indexes
6088
+ */
6089
+ getIndexes(): Index<string, V, unknown>[];
6090
+ /**
6091
+ * Check if an attribute is indexed.
6092
+ *
6093
+ * @param attributeName - Attribute name
6094
+ * @returns true if attribute has indexes
6095
+ */
6096
+ hasIndexOn(attributeName: string): boolean;
6097
+ /**
6098
+ * Build index from existing data.
6099
+ */
6100
+ private buildIndexFromExisting;
6101
+ /**
6102
+ * Execute a query across all records.
6103
+ * Returns array of matching results with key, tag, and value.
6104
+ *
6105
+ * Also tracks query patterns for adaptive indexing (Phase 8.02).
6106
+ *
6107
+ * @param query - Query to execute
6108
+ * @returns Array of query results
6109
+ */
6110
+ query(query: Query): ORMapQueryResult<K, V>[];
6111
+ /**
6112
+ * Execute a query and return matching values only.
6113
+ *
6114
+ * @param query - Query to execute
6115
+ * @returns Array of matching values
6116
+ */
6117
+ queryValues(query: Query): V[];
6118
+ /**
6119
+ * Count matching records without materializing results.
6120
+ *
6121
+ * @param query - Query to execute
6122
+ * @returns Number of matching records
6123
+ */
6124
+ count(query: Query): number;
6125
+ /**
6126
+ * Execute plan and return result set.
6127
+ */
6128
+ private executePlan;
6129
+ /**
6130
+ * Perform full scan with predicate evaluation.
6131
+ */
6132
+ private fullScan;
6133
+ /**
6134
+ * Add a value (with index updates).
6135
+ */
6136
+ add(key: K, value: V, ttlMs?: number): ORMapRecord<V>;
6137
+ /**
6138
+ * Remove a value (with index updates).
6139
+ */
6140
+ remove(key: K, value: V): string[];
6141
+ /**
6142
+ * Apply a record from remote (with index updates).
6143
+ */
6144
+ apply(key: K, record: ORMapRecord<V>): boolean;
6145
+ /**
6146
+ * Apply a tombstone (with index updates).
6147
+ */
6148
+ applyTombstone(tag: string): void;
6149
+ /**
6150
+ * Clear all data (and indexes).
6151
+ */
6152
+ clear(): void;
6153
+ /**
6154
+ * Create composite key from map key and tag.
6155
+ * Uses '||' as separator since HLC tags contain ':'
6156
+ */
6157
+ private createCompositeKey;
6158
+ /**
6159
+ * Parse composite key into [key, tag].
6160
+ * Expects '||' separator.
6161
+ */
6162
+ private parseCompositeKey;
6163
+ /**
6164
+ * Get all composite keys from the map.
6165
+ */
6166
+ private getAllCompositeKeys;
6167
+ /**
6168
+ * Get record by composite key.
6169
+ */
6170
+ private getRecordByCompositeKey;
6171
+ /**
6172
+ * Check if record matches predicate.
6173
+ */
6174
+ private matchesPredicate;
6175
+ /**
6176
+ * Check if record matches IndexQuery (used by FallbackIndex).
6177
+ * This is a simplified matcher for full scan fallback.
6178
+ */
6179
+ private matchesIndexQuery;
6180
+ /**
6181
+ * Convert Query to PredicateNode format.
6182
+ */
6183
+ private queryToPredicate;
6184
+ /**
6185
+ * Get index statistics.
6186
+ */
6187
+ getIndexStats(): Map<string, IndexStats>;
6188
+ /**
6189
+ * Get index registry statistics.
6190
+ */
6191
+ getIndexRegistryStats(): IndexRegistryStats;
6192
+ /**
6193
+ * Get query optimizer for plan inspection.
6194
+ */
6195
+ getQueryOptimizer(): QueryOptimizer<string, V>;
6196
+ /**
6197
+ * Explain query execution plan.
6198
+ *
6199
+ * @param query - Query to explain
6200
+ * @returns Query execution plan
6201
+ */
6202
+ explainQuery(query: Query): QueryPlan;
6203
+ /**
6204
+ * Register an attribute for auto-indexing.
6205
+ * Required before auto-index can create indexes on this attribute.
6206
+ *
6207
+ * @param attribute - The attribute to register
6208
+ * @param allowedIndexTypes - Optional list of allowed index types
6209
+ */
6210
+ registerAttribute<A>(attribute: Attribute<V, A>, allowedIndexTypes?: RecommendedIndexType[]): void;
6211
+ /**
6212
+ * Unregister an attribute from auto-indexing.
6213
+ *
6214
+ * @param attributeName - Name of attribute to unregister
6215
+ */
6216
+ unregisterAttribute(attributeName: string): void;
6217
+ /**
6218
+ * Get index suggestions based on query patterns.
6219
+ * Use this in production to get recommendations for manual index creation.
6220
+ *
6221
+ * @param options - Suggestion options
6222
+ * @returns Array of index suggestions sorted by priority
6223
+ */
6224
+ getIndexSuggestions(options?: IndexSuggestionOptions): IndexSuggestion[];
6225
+ /**
6226
+ * Get query pattern statistics.
6227
+ * Useful for debugging and understanding query patterns.
6228
+ *
6229
+ * @returns Array of query statistics
6230
+ */
6231
+ getQueryStatistics(): QueryStatistics[];
6232
+ /**
6233
+ * Reset query statistics.
6234
+ * Call this to clear accumulated query patterns.
6235
+ */
6236
+ resetQueryStatistics(): void;
6237
+ /**
6238
+ * Get query pattern tracker for advanced usage.
6239
+ */
6240
+ getQueryTracker(): QueryPatternTracker;
6241
+ /**
6242
+ * Get index advisor for advanced usage.
6243
+ */
6244
+ getIndexAdvisor(): IndexAdvisor;
6245
+ /**
6246
+ * Get auto-index manager (if enabled).
6247
+ */
6248
+ getAutoIndexManager(): AutoIndexManager<string, V> | null;
6249
+ /**
6250
+ * Check if auto-indexing is enabled.
6251
+ */
6252
+ isAutoIndexingEnabled(): boolean;
6253
+ /**
6254
+ * Track query pattern for adaptive indexing.
6255
+ */
6256
+ private trackQueryPattern;
6257
+ /**
6258
+ * Extract attribute name from query.
6259
+ */
6260
+ private extractAttribute;
6261
+ /**
6262
+ * Extract query type from query.
6263
+ */
6264
+ private extractQueryType;
6265
+ }
6266
+
6267
+ export { type Attribute, AuthMessageSchema, type BatchMessage, BatchMessageSchema, BuiltInProcessors, BuiltInResolvers, type CircuitBreakerConfig, type ClientOp, ClientOpMessageSchema, ClientOpSchema, type ClusterClientConfig, type ClusterEvents, type ReadOptions as ClusterReadOptions, type WriteOptions as ClusterWriteOptions, type CompareFn, type ConflictResolver, type ConflictResolverDef, ConflictResolverDefSchema, type ConflictResolverFn, ConflictResolverSchema, type ConnectionPoolConfig, type ConnectionState, ConsistencyLevel, CounterRequestSchema, CounterResponseSchema, CounterSyncSchema, CounterUpdateSchema, DEFAULT_BACKUP_COUNT, DEFAULT_CIRCUIT_BREAKER_CONFIG, DEFAULT_CONNECTION_POOL_CONFIG, DEFAULT_EVENT_JOURNAL_CONFIG, DEFAULT_MIGRATION_CONFIG, DEFAULT_PARTITION_ROUTER_CONFIG, DEFAULT_PROCESSOR_RATE_LIMITS, DEFAULT_REPLICATION_CONFIG, DEFAULT_RESOLVER_RATE_LIMITS, DEFAULT_STOP_WORDS, DEFAULT_WRITE_CONCERN_TIMEOUT, type EntryProcessBatchRequest, EntryProcessBatchRequestSchema, type EntryProcessBatchResponse, EntryProcessBatchResponseSchema, type EntryProcessKeyResult, EntryProcessKeyResultSchema, type EntryProcessRequest, EntryProcessRequestSchema, type EntryProcessResponse, EntryProcessResponseSchema, type EntryProcessorDef, EntryProcessorDefSchema, type EntryProcessorFn, type EntryProcessorResult, EntryProcessorSchema, type EventJournal, type EventJournalConfig, EventJournalImpl, FORBIDDEN_PATTERNS, FallbackIndex, type FilterStep, FilteringResultSet, type FullScanStep, HLC, HashIndex, type Index, type IndexQuery, IndexRegistry, type IndexRegistryStats, type IndexScanStep, type IndexStats, IndexedLWWMap, IndexedORMap, IntersectionResultSet, type IntersectionStep, InvertedIndex, type InvertedIndexStats, type IteratorFactory, type JournalEvent, type JournalEventData, JournalEventDataSchema, type JournalEventInput, type JournalEventListener, type JournalEventMessage, JournalEventMessageSchema, type JournalEventType, JournalEventTypeSchema, type JournalReadRequest, JournalReadRequestSchema, type JournalReadResponse, JournalReadResponseSchema, type JournalSubscribeRequest, JournalSubscribeRequestSchema, type JournalUnsubscribeRequest, JournalUnsubscribeRequestSchema, LWWMap, type LWWRecord, LWWRecordSchema, LazyResultSet, LimitResultSet, type ListResolversRequest, ListResolversRequestSchema, type ListResolversResponse, ListResolversResponseSchema, type LiveQueryCallback, type LiveQueryDeltaEvent, type LiveQueryEvent, type LiveQueryInitialEvent, LiveQueryManager, type LiveQueryManagerOptions, type LiveQueryManagerStats, LockReleaseSchema, LockRequestSchema, type LogicalQueryNode, LowercaseFilter, MaxLengthFilter, type MergeContext, type MergeKeyResult, type MergeRejectedMessage, MergeRejectedMessageSchema, type MergeRejection, type MergeResult, MerkleReqBucketMessageSchema, MerkleTree, type Message, MessageSchema, type MigrationChunkAckMessage, type MigrationChunkMessage, type MigrationCompleteMessage, type MigrationConfig, type MigrationMessage, type MigrationMetrics, type MigrationStartMessage, type MigrationStatus, type MigrationVerifyMessage, MinLengthFilter, MultiValueAttribute, NGramTokenizer, NavigableIndex, type NodeHealth, type NodeInfo, type NodeStatus, type NotOwnerError, type NotStep, ORMap, ORMapDiffRequestSchema, ORMapDiffResponseSchema, type ORMapMerkleNode, ORMapMerkleReqBucketSchema, ORMapMerkleTree, ORMapPushDiffSchema, type ORMapQueryResult, type ORMapRecord, ORMapRecordSchema, type ORMapSnapshot, ORMapSyncInitSchema, ORMapSyncRespBucketsSchema, ORMapSyncRespLeafSchema, ORMapSyncRespRootSchema, type OpAckMessage, OpAckMessageSchema, OpBatchMessageSchema, type OpRejectedMessage, OpRejectedMessageSchema, type OpResult, OpResultSchema, PARTITION_COUNT, type PNCounter, type PNCounterConfig, PNCounterImpl, type PNCounterState, type PNCounterStateObject, PNCounterStateObjectSchema, type PartitionChange, type PartitionInfo, type PartitionMap, type PartitionMapDeltaMessage, type PartitionMapMessage, type PartitionMapRequestMessage, PartitionMapRequestSchema, type PartitionMigration, type PartitionRouterConfig, PartitionState, type PendingWrite, type PermissionPolicy, type PermissionType, type PingMessage, PingMessageSchema, type PlanStep, type PongMessage, PongMessageSchema, type PredicateFn, type PredicateNode, PredicateNodeSchema, type PredicateOp, PredicateOpSchema, Predicates, type Principal, type ProcessorRateLimitConfig, type Query$1 as Query, type Query as QueryExpression, type QueryNode, QueryOptimizer, type QueryOptimizerOptions, type QueryOptions, type QueryPlan, QuerySchema, QuerySubMessageSchema, QueryUnsubMessageSchema, RESOLVER_FORBIDDEN_PATTERNS, type RegisterResolverRequest, RegisterResolverRequestSchema, type RegisterResolverResponse, RegisterResolverResponseSchema, type ReplicationAckMessage, type ReplicationBatchAckMessage, type ReplicationBatchMessage, type ReplicationConfig, type ReplicationHealth, type ReplicationLag, type ReplicationMessage, type ReplicationProtocolMessage, type ReplicationResult, type ReplicationTask, type ResolverRateLimitConfig, type ResultSet, Ringbuffer, type RoutingError, SetResultSet, SimpleAttribute, type SimpleQueryNode, SortedMap, SortedResultSet, type StaleMapError, type StandingQueryChange, StandingQueryIndex, type StandingQueryIndexOptions, StandingQueryRegistry, type StandingQueryRegistryOptions, type StandingQueryRegistryStats, StopWordFilter, SyncInitMessageSchema, SyncRespBucketsMessageSchema, SyncRespLeafMessageSchema, SyncRespRootMessageSchema, type Timestamp, TimestampSchema, type TokenFilter, TokenizationPipeline, type TokenizationPipelineOptions, type Tokenizer, TopicMessageEventSchema, TopicPubSchema, TopicSubSchema, TopicUnsubSchema, TrimFilter, UnionResultSet, type UnionStep, UniqueFilter, type UnregisterResolverRequest, UnregisterResolverRequestSchema, type UnregisterResolverResponse, UnregisterResolverResponseSchema, WRITE_CONCERN_ORDER, WhitespaceTokenizer, WordBoundaryTokenizer, WriteConcern, WriteConcernSchema, type WriteConcernValue, type WriteOptions$1 as WriteOptions, type WriteResult, combineHashes, compareHLCTimestamps, compareTimestamps, createFieldComparator, createPredicateMatcher, deepMerge, deserialize, disableNativeHash, evaluatePredicate, getHighestWriteConcernLevel, hashORMapEntry, hashORMapRecord, hashString, isLogicalQuery, isSimpleQuery, isUsingNativeHash, isWriteConcernAchieved, multiAttribute, resetNativeHash, serialize, simpleAttribute, timestampToString, validateProcessorCode, validateResolverCode };