@topgunbuild/server 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _topgunbuild_core from '@topgunbuild/core';
2
- import { Timestamp, LWWRecord, ORMapRecord, Principal, EventJournalImpl, EventJournalConfig, JournalEvent, PermissionPolicy, ConsistencyLevel, ReplicationConfig, LWWMap, ORMap, PermissionType, MigrationConfig, MigrationStatus, MigrationMetrics, PartitionMap, PartitionInfo, PartitionChange, ReplicationLag, ReplicationHealth, ReplicationResult, ClusterReadOptions, MerkleTree, EntryProcessorDef, EntryProcessorResult, HLC, MergeRejection, ConflictResolverDef, MergeContext, MergeResult, IndexedLWWMap, IndexedORMap } from '@topgunbuild/core';
2
+ import { Timestamp, LWWRecord, ORMapRecord, Principal, EventJournalImpl, EventJournalConfig, JournalEvent, PermissionPolicy, ConsistencyLevel, ReplicationConfig, FullTextIndexConfig, LWWMap, ORMap, PermissionType, MigrationConfig, MigrationStatus, MigrationMetrics, PartitionMap, PartitionInfo, PartitionChange, ReplicationLag, ReplicationHealth, ReplicationResult, ClusterReadOptions, MerkleTree, EntryProcessorDef, EntryProcessorResult, HLC, MergeRejection, ConflictResolverDef, MergeContext, MergeResult, IndexedLWWMap, IndexedORMap, SearchUpdateType, FTSSearchOptions, SearchRespPayload, SearchOptions } from '@topgunbuild/core';
3
3
  import { WebSocket } from 'ws';
4
4
  import { Pool, PoolConfig } from 'pg';
5
5
  import pino from 'pino';
@@ -1858,6 +1858,8 @@ interface ServerCoordinatorConfig {
1858
1858
  eventJournalEnabled?: boolean;
1859
1859
  /** Event journal configuration */
1860
1860
  eventJournalConfig?: Partial<Omit<EventJournalServiceConfig, 'pool'>>;
1861
+ /** Enable full-text search for specific maps */
1862
+ fullTextSearch?: Record<string, FullTextIndexConfig>;
1861
1863
  }
1862
1864
  declare class ServerCoordinator {
1863
1865
  private httpServer;
@@ -1906,12 +1908,18 @@ declare class ServerCoordinator {
1906
1908
  private readReplicaHandler?;
1907
1909
  private merkleTreeManager?;
1908
1910
  private repairScheduler?;
1911
+ private searchCoordinator;
1909
1912
  private readonly _nodeId;
1910
1913
  private _actualPort;
1911
1914
  private _actualClusterPort;
1912
1915
  private _readyPromise;
1913
1916
  private _readyResolve;
1914
1917
  constructor(config: ServerCoordinatorConfig);
1918
+ /**
1919
+ * Populate FTS indexes from existing map data.
1920
+ * Called after storage initialization.
1921
+ */
1922
+ private backfillSearchIndexes;
1915
1923
  /** Wait for server to be fully ready (ports assigned) */
1916
1924
  ready(): Promise<void>;
1917
1925
  /**
@@ -1947,6 +1955,37 @@ declare class ServerCoordinator {
1947
1955
  getTaskletSchedulerStats(): TaskletSchedulerStats;
1948
1956
  /** Get tasklet scheduler for scheduling long-running operations */
1949
1957
  getTaskletScheduler(): TaskletScheduler;
1958
+ /**
1959
+ * Enable full-text search for a map.
1960
+ * Can be called at runtime to enable FTS dynamically.
1961
+ *
1962
+ * @param mapName - Name of the map to enable FTS for
1963
+ * @param config - FTS configuration (fields, tokenizer, bm25 options)
1964
+ */
1965
+ enableFullTextSearch(mapName: string, config: FullTextIndexConfig): void;
1966
+ /**
1967
+ * Disable full-text search for a map.
1968
+ *
1969
+ * @param mapName - Name of the map to disable FTS for
1970
+ */
1971
+ disableFullTextSearch(mapName: string): void;
1972
+ /**
1973
+ * Check if full-text search is enabled for a map.
1974
+ *
1975
+ * @param mapName - Name of the map to check
1976
+ * @returns True if FTS is enabled
1977
+ */
1978
+ isFullTextSearchEnabled(mapName: string): boolean;
1979
+ /**
1980
+ * Get FTS index statistics for a map.
1981
+ *
1982
+ * @param mapName - Name of the map
1983
+ * @returns Index stats or null if FTS not enabled
1984
+ */
1985
+ getFullTextSearchStats(mapName: string): {
1986
+ documentCount: number;
1987
+ fields: string[];
1988
+ } | null;
1950
1989
  /**
1951
1990
  * Phase 10.02: Graceful cluster departure
1952
1991
  *
@@ -4442,4 +4481,266 @@ declare class MapFactory {
4442
4481
  getConfig(): ServerIndexConfig;
4443
4482
  }
4444
4483
 
4445
- export { BufferPool, type BufferPoolConfig, type BufferPoolStats, type ClusterConfig, ClusterCoordinator, type ClusterCoordinatorConfig, type ClusterCoordinatorEvents, ClusterManager, type ClusterMember, type ClusterMessage, type CoalescingPreset, type CoalescingWriterMetrics, type CoalescingWriterOptions, ConflictResolverHandler, type ConflictResolverHandlerConfig, ConflictResolverService, type ConflictResolverServiceConfig, type ConnectionContext, ConnectionRateLimiter, DEFAULT_CLUSTER_COORDINATOR_CONFIG, DEFAULT_CONFLICT_RESOLVER_CONFIG, DEFAULT_FAILURE_DETECTOR_CONFIG, DEFAULT_INDEX_CONFIG, DEFAULT_JOURNAL_SERVICE_CONFIG, DEFAULT_LAG_TRACKER_CONFIG, DEFAULT_MERKLE_TREE_CONFIG, DEFAULT_READ_REPLICA_CONFIG, DEFAULT_REASSIGNER_CONFIG, DEFAULT_REPAIR_CONFIG, DEFAULT_SANDBOX_CONFIG, EntryProcessorHandler, type EntryProcessorHandlerConfig, EventJournalService, type EventJournalServiceConfig, type ExportOptions, type FailoverStatus, FailureDetector, type FailureDetectorConfig, type FailureDetectorEvents, FilterTasklet, ForEachTasklet, type IInterceptor, type IServerStorage, type IndexDefinition, IteratorTasklet, type IteratorTaskletConfig, type LagInfo, LagTracker, type LagTrackerConfig, LockManager, type Logger, MapFactory, type MapIndexConfig, MapTasklet, MapWithResolver, type MapWithResolverConfig, MemoryServerAdapter, type MergeWithResolverResult, type MerkleComparisonResult, MerkleTreeManager, type MerkleTreeManagerConfig, MigrationManager, type NativeModuleStatus, type NativeStats, type NodeState, type ORMapTombstones, type ORMapValue, ObjectPool, type ObjectPoolConfig, type ObjectPoolStats, type OpContext, type PartitionDistribution, type PartitionMerkleInfo, PartitionReassigner, type PartitionReassignerConfig, PartitionService, type PartitionServiceConfig, type PartitionServiceEvents, type PooledEventPayload, type PooledMessage, type PooledRecord, type PooledTimestamp, PostgresAdapter, type PostgresAdapterOptions, ProcessorSandbox, type ProcessorSandboxConfig, type ProgressState, RateLimitInterceptor, type RateLimiterConfig, type RateLimiterStats, type ReadReplicaConfig, ReadReplicaHandler, type ReadRequest, type ReadResult, type ReassignmentEvent, ReduceTasklet, type RepairConfig, type RepairMetrics, type RepairResult, RepairScheduler, type RepairTask, ReplicationPipeline, SecurityManager, ServerCoordinator, type ServerCoordinatorConfig, type ServerIndexConfig, type ServerOp, type SetWithResolverResult, type StorageValue, type Tasklet, TaskletScheduler, type TaskletSchedulerConfig, type TaskletSchedulerStats, TimestampInterceptor, coalescingPresets, createEventPayloadPool, createMessagePool, createRecordPool, createTimestampPool, getCoalescingPreset, getGlobalBufferPool, getGlobalEventPayloadPool, getGlobalMessagePool, getGlobalRecordPool, getGlobalTimestampPool, getNativeModuleStatus, getNativeStats, logNativeStatus, logger, mergeWithDefaults, setGlobalBufferPool, setGlobalEventPayloadPool, setGlobalMessagePool, setGlobalRecordPool, setGlobalTimestampPool, validateIndexConfig };
4484
+ /**
4485
+ * SearchCoordinator - Server-side Full-Text Search Handler
4486
+ *
4487
+ * Manages FullTextIndex instances per map and handles search requests.
4488
+ * Part of Phase 11.1a: Server-side BM25 Search.
4489
+ * Phase 11.1b: Live Search Subscriptions with delta updates.
4490
+ *
4491
+ * @module search/SearchCoordinator
4492
+ */
4493
+
4494
+ /**
4495
+ * Result item returned from server search.
4496
+ */
4497
+ interface ServerSearchResult {
4498
+ key: string;
4499
+ value: unknown;
4500
+ score: number;
4501
+ matchedTerms: string[];
4502
+ }
4503
+ /**
4504
+ * Configuration for enabling search on a map.
4505
+ */
4506
+ interface SearchConfig extends FullTextIndexConfig {
4507
+ }
4508
+ /**
4509
+ * Callback type for sending updates to clients.
4510
+ */
4511
+ type SendUpdateCallback = (clientId: string, subscriptionId: string, key: string, value: unknown, score: number, matchedTerms: string[], type: SearchUpdateType) => void;
4512
+ /**
4513
+ * Batched update for a single document change.
4514
+ */
4515
+ interface BatchedUpdate {
4516
+ key: string;
4517
+ value: unknown;
4518
+ score: number;
4519
+ matchedTerms: string[];
4520
+ type: SearchUpdateType;
4521
+ }
4522
+ /**
4523
+ * Callback type for sending batched updates to clients.
4524
+ */
4525
+ type SendBatchUpdateCallback = (clientId: string, subscriptionId: string, updates: BatchedUpdate[]) => void;
4526
+ /**
4527
+ * SearchCoordinator manages full-text search indexes for the server.
4528
+ *
4529
+ * Responsibilities:
4530
+ * - Maintain FullTextIndex per enabled map
4531
+ * - Execute one-shot search queries
4532
+ * - Update indexes when data changes
4533
+ *
4534
+ * @example
4535
+ * ```typescript
4536
+ * const searchCoordinator = new SearchCoordinator();
4537
+ *
4538
+ * // Enable FTS for a map
4539
+ * searchCoordinator.enableSearch('articles', {
4540
+ * fields: ['title', 'body'],
4541
+ * tokenizer: { minLength: 2 },
4542
+ * bm25: { k1: 1.2, b: 0.75 }
4543
+ * });
4544
+ *
4545
+ * // Search
4546
+ * const results = searchCoordinator.search('articles', 'machine learning', {
4547
+ * limit: 20,
4548
+ * boost: { title: 2.0 }
4549
+ * });
4550
+ * ```
4551
+ */
4552
+ declare class SearchCoordinator {
4553
+ /** Map name → FullTextIndex */
4554
+ private readonly indexes;
4555
+ /** Map name → FullTextIndexConfig (for reference) */
4556
+ private readonly configs;
4557
+ /** Callback to get document value by key (injected by ServerCoordinator) */
4558
+ private getDocumentValue?;
4559
+ /** Subscription ID → SearchSubscription */
4560
+ private readonly subscriptions;
4561
+ /** Map name → Set of subscription IDs */
4562
+ private readonly subscriptionsByMap;
4563
+ /** Client ID → Set of subscription IDs */
4564
+ private readonly subscriptionsByClient;
4565
+ /** Callback for sending updates to clients */
4566
+ private sendUpdate?;
4567
+ /** Callback for sending batched updates to clients */
4568
+ private sendBatchUpdate?;
4569
+ /** Queue of pending notifications per map */
4570
+ private readonly pendingNotifications;
4571
+ /** Timer for batching notifications */
4572
+ private notificationTimer;
4573
+ /** Batch interval in milliseconds (~1 frame at 60fps) */
4574
+ private readonly BATCH_INTERVAL;
4575
+ constructor();
4576
+ /**
4577
+ * Set the callback for sending updates to clients.
4578
+ * Called by ServerCoordinator during initialization.
4579
+ */
4580
+ setSendUpdateCallback(callback: SendUpdateCallback): void;
4581
+ /**
4582
+ * Set the callback for sending batched updates to clients.
4583
+ * When set, notifications are batched within BATCH_INTERVAL (16ms) window.
4584
+ * Called by ServerCoordinator during initialization.
4585
+ *
4586
+ * @param callback - Function to call with batched updates
4587
+ */
4588
+ setSendBatchUpdateCallback(callback: SendBatchUpdateCallback): void;
4589
+ /**
4590
+ * Set the callback for retrieving document values.
4591
+ * Called by ServerCoordinator during initialization.
4592
+ */
4593
+ setDocumentValueGetter(getter: (mapName: string, key: string) => unknown | undefined): void;
4594
+ /**
4595
+ * Enable full-text search for a map.
4596
+ *
4597
+ * @param mapName - Name of the map to enable FTS for
4598
+ * @param config - FTS configuration (fields, tokenizer, bm25 options)
4599
+ */
4600
+ enableSearch(mapName: string, config: SearchConfig): void;
4601
+ /**
4602
+ * Disable full-text search for a map.
4603
+ *
4604
+ * @param mapName - Name of the map to disable FTS for
4605
+ */
4606
+ disableSearch(mapName: string): void;
4607
+ /**
4608
+ * Check if FTS is enabled for a map.
4609
+ */
4610
+ isSearchEnabled(mapName: string): boolean;
4611
+ /**
4612
+ * Get enabled map names.
4613
+ */
4614
+ getEnabledMaps(): string[];
4615
+ /**
4616
+ * Execute a one-shot search query.
4617
+ *
4618
+ * @param mapName - Name of the map to search
4619
+ * @param query - Search query text
4620
+ * @param options - Search options (limit, minScore, boost)
4621
+ * @returns Search response payload
4622
+ */
4623
+ search(mapName: string, query: string, options?: FTSSearchOptions): SearchRespPayload;
4624
+ /**
4625
+ * Handle document set/update.
4626
+ * Called by ServerCoordinator when data changes.
4627
+ *
4628
+ * @param mapName - Name of the map
4629
+ * @param key - Document key
4630
+ * @param value - Document value
4631
+ */
4632
+ onDataChange(mapName: string, key: string, value: Record<string, unknown> | null | undefined, changeType: 'add' | 'update' | 'remove'): void;
4633
+ /**
4634
+ * Build index from existing map entries.
4635
+ * Called when FTS is enabled for a map that already has data.
4636
+ *
4637
+ * @param mapName - Name of the map
4638
+ * @param entries - Iterator of [key, value] tuples
4639
+ */
4640
+ buildIndexFromEntries(mapName: string, entries: Iterable<[string, Record<string, unknown> | null]>): void;
4641
+ /**
4642
+ * Get index statistics for monitoring.
4643
+ */
4644
+ getIndexStats(mapName: string): {
4645
+ documentCount: number;
4646
+ fields: string[];
4647
+ } | null;
4648
+ /**
4649
+ * Clear all indexes (for testing or shutdown).
4650
+ */
4651
+ clear(): void;
4652
+ /**
4653
+ * Subscribe to live search results.
4654
+ * Returns initial results and tracks the subscription for delta updates.
4655
+ *
4656
+ * @param clientId - ID of the subscribing client
4657
+ * @param subscriptionId - Unique subscription identifier
4658
+ * @param mapName - Name of the map to search
4659
+ * @param query - Search query text
4660
+ * @param options - Search options (limit, minScore, boost)
4661
+ * @returns Initial search results
4662
+ */
4663
+ subscribe(clientId: string, subscriptionId: string, mapName: string, query: string, options?: SearchOptions): ServerSearchResult[];
4664
+ /**
4665
+ * Unsubscribe from a live search.
4666
+ *
4667
+ * @param subscriptionId - Subscription to remove
4668
+ */
4669
+ unsubscribe(subscriptionId: string): void;
4670
+ /**
4671
+ * Unsubscribe all subscriptions for a client.
4672
+ * Called when a client disconnects.
4673
+ *
4674
+ * @param clientId - ID of the disconnected client
4675
+ */
4676
+ unsubscribeClient(clientId: string): void;
4677
+ /**
4678
+ * Get the number of active subscriptions.
4679
+ */
4680
+ getSubscriptionCount(): number;
4681
+ /**
4682
+ * Notify subscribers about a document change.
4683
+ * Computes delta (ENTER/UPDATE/LEAVE) for each affected subscription.
4684
+ *
4685
+ * @param mapName - Name of the map that changed
4686
+ * @param key - Document key that changed
4687
+ * @param value - New document value (null if removed)
4688
+ * @param changeType - Type of change
4689
+ */
4690
+ private notifySubscribers;
4691
+ /**
4692
+ * Score a single document against a subscription's query.
4693
+ *
4694
+ * OPTIMIZED: O(Q × D) complexity instead of O(N) full index scan.
4695
+ * Uses pre-tokenized queryTerms and FullTextIndex.scoreSingleDocument().
4696
+ *
4697
+ * @param subscription - The subscription containing query and cached queryTerms
4698
+ * @param key - Document key
4699
+ * @param value - Document value
4700
+ * @param index - The FullTextIndex for this map
4701
+ * @returns Scored result or null if document doesn't match
4702
+ */
4703
+ private scoreDocument;
4704
+ /**
4705
+ * Queue a notification for batched processing.
4706
+ * Notifications are collected and processed together after BATCH_INTERVAL.
4707
+ *
4708
+ * @param mapName - Name of the map that changed
4709
+ * @param key - Document key that changed
4710
+ * @param value - New document value (null if removed)
4711
+ * @param changeType - Type of change
4712
+ */
4713
+ queueNotification(mapName: string, key: string, value: Record<string, unknown> | null, changeType: 'add' | 'update' | 'remove'): void;
4714
+ /**
4715
+ * Schedule a flush of pending notifications.
4716
+ * Uses setTimeout to batch notifications within BATCH_INTERVAL window.
4717
+ */
4718
+ private scheduleNotificationFlush;
4719
+ /**
4720
+ * Flush all pending notifications.
4721
+ * Processes each map's notifications and sends batched updates.
4722
+ */
4723
+ flushNotifications(): void;
4724
+ /**
4725
+ * Process batched notifications for a single map.
4726
+ * Computes updates for each subscription and sends as a batch.
4727
+ *
4728
+ * @param mapName - Name of the map
4729
+ * @param notifications - Array of pending notifications
4730
+ */
4731
+ private processBatchedNotifications;
4732
+ /**
4733
+ * Compute the update for a single document change against a subscription.
4734
+ * Returns null if no update is needed.
4735
+ *
4736
+ * @param subscription - The subscription to check
4737
+ * @param key - Document key
4738
+ * @param value - Document value (null if removed)
4739
+ * @param changeType - Type of change
4740
+ * @param index - The FullTextIndex for this map
4741
+ * @returns BatchedUpdate or null
4742
+ */
4743
+ private computeSubscriptionUpdate;
4744
+ }
4745
+
4746
+ export { BufferPool, type BufferPoolConfig, type BufferPoolStats, type ClusterConfig, ClusterCoordinator, type ClusterCoordinatorConfig, type ClusterCoordinatorEvents, ClusterManager, type ClusterMember, type ClusterMessage, type CoalescingPreset, type CoalescingWriterMetrics, type CoalescingWriterOptions, ConflictResolverHandler, type ConflictResolverHandlerConfig, ConflictResolverService, type ConflictResolverServiceConfig, type ConnectionContext, ConnectionRateLimiter, DEFAULT_CLUSTER_COORDINATOR_CONFIG, DEFAULT_CONFLICT_RESOLVER_CONFIG, DEFAULT_FAILURE_DETECTOR_CONFIG, DEFAULT_INDEX_CONFIG, DEFAULT_JOURNAL_SERVICE_CONFIG, DEFAULT_LAG_TRACKER_CONFIG, DEFAULT_MERKLE_TREE_CONFIG, DEFAULT_READ_REPLICA_CONFIG, DEFAULT_REASSIGNER_CONFIG, DEFAULT_REPAIR_CONFIG, DEFAULT_SANDBOX_CONFIG, EntryProcessorHandler, type EntryProcessorHandlerConfig, EventJournalService, type EventJournalServiceConfig, type ExportOptions, type FailoverStatus, FailureDetector, type FailureDetectorConfig, type FailureDetectorEvents, FilterTasklet, ForEachTasklet, type IInterceptor, type IServerStorage, type IndexDefinition, IteratorTasklet, type IteratorTaskletConfig, type LagInfo, LagTracker, type LagTrackerConfig, LockManager, type Logger, MapFactory, type MapIndexConfig, MapTasklet, MapWithResolver, type MapWithResolverConfig, MemoryServerAdapter, type MergeWithResolverResult, type MerkleComparisonResult, MerkleTreeManager, type MerkleTreeManagerConfig, MigrationManager, type NativeModuleStatus, type NativeStats, type NodeState, type ORMapTombstones, type ORMapValue, ObjectPool, type ObjectPoolConfig, type ObjectPoolStats, type OpContext, type PartitionDistribution, type PartitionMerkleInfo, PartitionReassigner, type PartitionReassignerConfig, PartitionService, type PartitionServiceConfig, type PartitionServiceEvents, type PooledEventPayload, type PooledMessage, type PooledRecord, type PooledTimestamp, PostgresAdapter, type PostgresAdapterOptions, ProcessorSandbox, type ProcessorSandboxConfig, type ProgressState, RateLimitInterceptor, type RateLimiterConfig, type RateLimiterStats, type ReadReplicaConfig, ReadReplicaHandler, type ReadRequest, type ReadResult, type ReassignmentEvent, ReduceTasklet, type RepairConfig, type RepairMetrics, type RepairResult, RepairScheduler, type RepairTask, ReplicationPipeline, type SearchConfig, SearchCoordinator, SecurityManager, ServerCoordinator, type ServerCoordinatorConfig, type ServerIndexConfig, type ServerOp, type ServerSearchResult, type SetWithResolverResult, type StorageValue, type Tasklet, TaskletScheduler, type TaskletSchedulerConfig, type TaskletSchedulerStats, TimestampInterceptor, coalescingPresets, createEventPayloadPool, createMessagePool, createRecordPool, createTimestampPool, getCoalescingPreset, getGlobalBufferPool, getGlobalEventPayloadPool, getGlobalMessagePool, getGlobalRecordPool, getGlobalTimestampPool, getNativeModuleStatus, getNativeStats, logNativeStatus, logger, mergeWithDefaults, setGlobalBufferPool, setGlobalEventPayloadPool, setGlobalMessagePool, setGlobalRecordPool, setGlobalTimestampPool, validateIndexConfig };