@korajs/server 0.3.1 → 0.3.3

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.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { KoraEventEmitter, Operation, VersionVector } from '@korajs/core';
1
+ import { SchemaDefinition, KoraEventEmitter, Operation, VersionVector } from '@korajs/core';
2
2
  import * as _korajs_sync from '@korajs/sync';
3
3
  import { SyncStore, MessageSerializer, SyncMessage, ApplyResult } from '@korajs/sync';
4
4
  import { S as ServerTransport, a as ServerMessageHandler, b as ServerCloseHandler, c as ServerErrorHandler } from './server-transport-CU1BLWgr.cjs';
@@ -6,14 +6,85 @@ import { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
6
6
  import { BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';
7
7
 
8
8
  /**
9
- * Server-side store interface. Extends SyncStore with lifecycle
10
- * and introspection methods needed by the sync server.
9
+ * A materialized record reconstructed from the operation log
10
+ * or read from a materialized collection table.
11
+ */
12
+ interface MaterializedRecord {
13
+ id: string;
14
+ [key: string]: unknown;
15
+ }
16
+ /**
17
+ * Options for querying a materialized collection table.
18
+ */
19
+ interface CollectionQueryOptions {
20
+ /** Exact-match filters on field values */
21
+ where?: Record<string, unknown>;
22
+ /** Field name to order results by */
23
+ orderBy?: string;
24
+ /** Sort direction (default: 'asc') */
25
+ orderDirection?: 'asc' | 'desc';
26
+ /** Maximum number of records to return */
27
+ limit?: number;
28
+ /** Number of records to skip (for pagination) */
29
+ offset?: number;
30
+ /** Include soft-deleted records (default: false) */
31
+ includeDeleted?: boolean;
32
+ }
33
+ /**
34
+ * Server-side store interface. Extends SyncStore with lifecycle,
35
+ * introspection, and materialization methods needed by the sync server.
11
36
  */
12
37
  interface ServerStore extends SyncStore {
13
38
  /** Close the store and release resources */
14
39
  close(): Promise<void>;
15
40
  /** Get the total number of stored operations */
16
41
  getOperationCount(): Promise<number>;
42
+ /**
43
+ * Set the schema for materialized collection tables.
44
+ * Creates collection tables and indexes based on the schema definition.
45
+ * If operations already exist in the store, backfills the materialized
46
+ * tables from the operation log.
47
+ *
48
+ * @param schema - The schema definition describing all collections
49
+ */
50
+ setSchema(schema: SchemaDefinition): Promise<void>;
51
+ /**
52
+ * Get all records from a materialized collection.
53
+ * When schema is set, reads directly from the collection table (O(1) indexed).
54
+ * When schema is not set, falls back to replaying the operation log.
55
+ * Deleted records are excluded.
56
+ *
57
+ * @param collection - The collection name to query
58
+ * @returns Array of records with their current state
59
+ */
60
+ materializeCollection(collection: string): Promise<MaterializedRecord[]>;
61
+ /**
62
+ * Query records from a materialized collection with filtering, ordering,
63
+ * and pagination. Requires schema to be set via setSchema().
64
+ *
65
+ * @param collection - The collection name to query
66
+ * @param options - Query options (where, orderBy, limit, offset)
67
+ * @returns Array of matching records
68
+ */
69
+ queryCollection(collection: string, options?: CollectionQueryOptions): Promise<MaterializedRecord[]>;
70
+ /**
71
+ * Find a single record by ID from a materialized collection.
72
+ * Requires schema to be set via setSchema().
73
+ *
74
+ * @param collection - The collection name
75
+ * @param id - The record ID
76
+ * @returns The record or null if not found (or deleted)
77
+ */
78
+ findRecord(collection: string, id: string): Promise<MaterializedRecord | null>;
79
+ /**
80
+ * Count records in a materialized collection, optionally filtered.
81
+ * Requires schema to be set via setSchema().
82
+ *
83
+ * @param collection - The collection name
84
+ * @param where - Optional exact-match filters
85
+ * @returns Number of matching records
86
+ */
87
+ countCollection(collection: string, where?: Record<string, unknown>): Promise<number>;
17
88
  }
18
89
 
19
90
  /**
@@ -517,61 +588,100 @@ declare class KoraAuthProvider implements AuthProvider {
517
588
  /**
518
589
  * In-memory server store for testing and quick prototyping.
519
590
  * Not suitable for production — data does not survive process restart.
591
+ *
592
+ * When a schema is set via setSchema(), maintains materialized records
593
+ * in-memory for efficient queries.
520
594
  */
521
595
  declare class MemoryServerStore implements ServerStore {
522
596
  private readonly nodeId;
523
597
  private readonly operations;
524
598
  private readonly operationIndex;
525
599
  private readonly versionVector;
600
+ private schema;
601
+ /** Materialized records: collection -> recordId -> record data */
602
+ private readonly materializedRecords;
526
603
  private closed;
527
604
  constructor(nodeId?: string);
528
605
  getVersionVector(): VersionVector;
529
606
  getNodeId(): string;
607
+ setSchema(schema: SchemaDefinition): Promise<void>;
530
608
  applyRemoteOperation(op: Operation): Promise<ApplyResult>;
531
609
  getOperationRange(nodeId: string, fromSeq: number, toSeq: number): Promise<Operation[]>;
532
610
  getOperationCount(): Promise<number>;
611
+ materializeCollection(collection: string): Promise<MaterializedRecord[]>;
612
+ queryCollection(collection: string, options?: CollectionQueryOptions): Promise<MaterializedRecord[]>;
613
+ findRecord(collection: string, id: string): Promise<MaterializedRecord | null>;
614
+ countCollection(collection: string, where?: Record<string, unknown>): Promise<number>;
533
615
  close(): Promise<void>;
534
616
  /**
535
617
  * Get all stored operations (for test assertions).
536
618
  */
537
619
  getAllOperations(): Operation[];
620
+ private rebuildMaterializedRecord;
621
+ private backfillAllCollections;
622
+ private materializeFromOps;
538
623
  private assertOpen;
624
+ private assertSchema;
625
+ private assertCollection;
539
626
  }
540
627
 
541
628
  /**
542
629
  * PostgreSQL-backed server store using Drizzle ORM.
543
630
  * All reads and writes go through Drizzle's typed query builder.
544
- * DDL stays as raw SQL via Drizzle's sql template (standard practice without drizzle-kit).
631
+ *
632
+ * When a schema is set via setSchema(), also maintains materialized
633
+ * collection tables for efficient indexed queries (dual-write).
545
634
  */
546
635
  declare class PostgresServerStore implements ServerStore {
547
636
  private readonly nodeId;
548
637
  private readonly db;
549
638
  private readonly versionVector;
550
639
  private readonly ready;
640
+ private schema;
551
641
  private closed;
552
642
  constructor(db: PostgresJsDatabase, nodeId?: string);
553
643
  getVersionVector(): VersionVector;
554
644
  getNodeId(): string;
645
+ setSchema(schema: SchemaDefinition): Promise<void>;
555
646
  applyRemoteOperation(op: Operation): Promise<ApplyResult>;
556
647
  getOperationRange(nodeId: string, fromSeq: number, toSeq: number): Promise<Operation[]>;
557
648
  getOperationCount(): Promise<number>;
649
+ materializeCollection(collection: string): Promise<MaterializedRecord[]>;
650
+ queryCollection(collection: string, options?: CollectionQueryOptions): Promise<MaterializedRecord[]>;
651
+ findRecord(collection: string, id: string): Promise<MaterializedRecord | null>;
652
+ countCollection(collection: string, where?: Record<string, unknown>): Promise<number>;
558
653
  close(): Promise<void>;
559
- private initialize;
560
654
  /**
561
- * Create tables if they don't exist.
562
- * Uses raw SQL via Drizzle's sql template — standard DDL practice without drizzle-kit.
655
+ * Rebuild a single record in the materialized collection table by replaying
656
+ * all operations for that record.
657
+ */
658
+ private rebuildMaterializedRecord;
659
+ /**
660
+ * UPSERT a record into the materialized collection table.
661
+ */
662
+ private upsertMaterializedRecord;
663
+ /**
664
+ * Backfill all materialized collection tables from the existing operation log.
563
665
  */
666
+ private backfillAllCollections;
667
+ /**
668
+ * Backfill a single collection's materialized table from operations.
669
+ */
670
+ private backfillCollection;
671
+ private buildSelectQuery;
672
+ private buildWhereClause;
673
+ private deserializeRow;
674
+ private materializeFromOpsLog;
675
+ private initialize;
564
676
  private ensureTables;
565
677
  private serializeOperation;
566
678
  private deserializeOperation;
567
679
  private assertOpen;
680
+ private assertSchema;
681
+ private assertCollection;
568
682
  }
569
683
  /**
570
684
  * Creates a PostgresServerStore from a PostgreSQL connection string.
571
- *
572
- * Uses runtime dynamic imports so projects that do not use PostgreSQL
573
- * do not need to install `postgres`. Wraps the postgres client with
574
- * Drizzle ORM for typed query building.
575
685
  */
576
686
  declare function createPostgresServerStore(options: {
577
687
  connectionString: string;
@@ -582,26 +692,60 @@ declare function createPostgresServerStore(options: {
582
692
  * SQLite-backed server store using Drizzle ORM.
583
693
  * Persists operations and version vectors to a real database file,
584
694
  * surviving process restarts.
695
+ *
696
+ * When a schema is set via setSchema(), also maintains materialized
697
+ * collection tables for efficient indexed queries (dual-write).
585
698
  */
586
699
  declare class SqliteServerStore implements ServerStore {
587
700
  private readonly nodeId;
588
701
  private readonly db;
702
+ private schema;
589
703
  private closed;
590
704
  constructor(db: BetterSQLite3Database, nodeId?: string);
591
705
  getVersionVector(): VersionVector;
592
706
  getNodeId(): string;
707
+ setSchema(schema: SchemaDefinition): Promise<void>;
593
708
  applyRemoteOperation(op: Operation): Promise<ApplyResult>;
594
709
  getOperationRange(nodeId: string, fromSeq: number, toSeq: number): Promise<Operation[]>;
595
710
  getOperationCount(): Promise<number>;
711
+ materializeCollection(collection: string): Promise<MaterializedRecord[]>;
712
+ queryCollection(collection: string, options?: CollectionQueryOptions): Promise<MaterializedRecord[]>;
713
+ findRecord(collection: string, id: string): Promise<MaterializedRecord | null>;
714
+ countCollection(collection: string, where?: Record<string, unknown>): Promise<number>;
596
715
  close(): Promise<void>;
716
+ /**
717
+ * Rebuild a single record in the materialized collection table by replaying
718
+ * all operations for that record. Called within the applyRemoteOperation
719
+ * transaction for atomic dual-write.
720
+ */
721
+ private rebuildMaterializedRecord;
722
+ /**
723
+ * UPSERT a record into the materialized collection table.
724
+ * Uses INSERT ... ON CONFLICT (id) DO UPDATE SET for atomic upsert.
725
+ */
726
+ private upsertMaterializedRecord;
727
+ /**
728
+ * Backfill all materialized collection tables from the existing operation log.
729
+ * Called when setSchema() is invoked and operations already exist.
730
+ */
731
+ private backfillAllCollections;
732
+ /**
733
+ * Backfill a single collection's materialized table from operations.
734
+ */
735
+ private backfillCollection;
736
+ private buildSelectQuery;
737
+ private buildWhereClause;
738
+ private deserializeRow;
739
+ private materializeFromOpsLog;
597
740
  /**
598
741
  * Create the operations and sync_state tables if they don't exist.
599
- * Uses raw SQL via Drizzle's sql template — standard practice for DDL without drizzle-kit.
600
742
  */
601
743
  private ensureTables;
602
744
  private serializeOperation;
603
745
  private deserializeOperation;
604
746
  private assertOpen;
747
+ private assertSchema;
748
+ private assertCollection;
605
749
  }
606
750
  /**
607
751
  * Creates a SqliteServerStore with a file-backed or in-memory database.
@@ -617,6 +761,10 @@ declare class SqliteServerStore implements ServerStore {
617
761
  * import { createSqliteServerStore } from '@korajs/server'
618
762
  *
619
763
  * const store = createSqliteServerStore({ filename: './kora-server.db' })
764
+ *
765
+ * // Optional: enable materialized collection tables for fast queries
766
+ * await store.setSchema(mySchema)
767
+ *
620
768
  * const server = createKoraServer({ store, port: 3001 })
621
769
  * ```
622
770
  */
@@ -651,4 +799,4 @@ declare class NoAuthProvider implements AuthProvider {
651
799
  */
652
800
  declare function createKoraServer(config: KoraSyncServerConfig): KoraSyncServer;
653
801
 
654
- export { type AuthContext, type AuthProvider, ClientSession, type ClientSessionOptions, type HttpPollResponse, HttpServerTransport, type HttpSyncRequest, type HttpSyncResponse, KoraAuthProvider, type KoraAuthProviderOptions, KoraSyncServer, type KoraSyncServerConfig, MemoryServerStore, NoAuthProvider, PostgresServerStore, type ProductionServer, type ProductionServerConfig, type RelayCallback, ServerCloseHandler, ServerErrorHandler, ServerMessageHandler, type ServerStatus, type ServerStore, ServerTransport, type SessionState, SqliteServerStore, TokenAuthProvider, type TokenAuthProviderOptions, type WsServerConstructor, type WsServerLike, WsServerTransport, type WsServerTransportOptions, type WsWebSocket, createKoraServer, createPostgresServerStore, createProductionServer, createSqliteServerStore };
802
+ export { type AuthContext, type AuthProvider, ClientSession, type ClientSessionOptions, type CollectionQueryOptions, type HttpPollResponse, HttpServerTransport, type HttpSyncRequest, type HttpSyncResponse, KoraAuthProvider, type KoraAuthProviderOptions, KoraSyncServer, type KoraSyncServerConfig, type MaterializedRecord, MemoryServerStore, NoAuthProvider, PostgresServerStore, type ProductionServer, type ProductionServerConfig, type RelayCallback, ServerCloseHandler, ServerErrorHandler, ServerMessageHandler, type ServerStatus, type ServerStore, ServerTransport, type SessionState, SqliteServerStore, TokenAuthProvider, type TokenAuthProviderOptions, type WsServerConstructor, type WsServerLike, WsServerTransport, type WsServerTransportOptions, type WsWebSocket, createKoraServer, createPostgresServerStore, createProductionServer, createSqliteServerStore };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { KoraEventEmitter, Operation, VersionVector } from '@korajs/core';
1
+ import { SchemaDefinition, KoraEventEmitter, Operation, VersionVector } from '@korajs/core';
2
2
  import * as _korajs_sync from '@korajs/sync';
3
3
  import { SyncStore, MessageSerializer, SyncMessage, ApplyResult } from '@korajs/sync';
4
4
  import { S as ServerTransport, a as ServerMessageHandler, b as ServerCloseHandler, c as ServerErrorHandler } from './server-transport-CU1BLWgr.js';
@@ -6,14 +6,85 @@ import { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
6
6
  import { BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';
7
7
 
8
8
  /**
9
- * Server-side store interface. Extends SyncStore with lifecycle
10
- * and introspection methods needed by the sync server.
9
+ * A materialized record reconstructed from the operation log
10
+ * or read from a materialized collection table.
11
+ */
12
+ interface MaterializedRecord {
13
+ id: string;
14
+ [key: string]: unknown;
15
+ }
16
+ /**
17
+ * Options for querying a materialized collection table.
18
+ */
19
+ interface CollectionQueryOptions {
20
+ /** Exact-match filters on field values */
21
+ where?: Record<string, unknown>;
22
+ /** Field name to order results by */
23
+ orderBy?: string;
24
+ /** Sort direction (default: 'asc') */
25
+ orderDirection?: 'asc' | 'desc';
26
+ /** Maximum number of records to return */
27
+ limit?: number;
28
+ /** Number of records to skip (for pagination) */
29
+ offset?: number;
30
+ /** Include soft-deleted records (default: false) */
31
+ includeDeleted?: boolean;
32
+ }
33
+ /**
34
+ * Server-side store interface. Extends SyncStore with lifecycle,
35
+ * introspection, and materialization methods needed by the sync server.
11
36
  */
12
37
  interface ServerStore extends SyncStore {
13
38
  /** Close the store and release resources */
14
39
  close(): Promise<void>;
15
40
  /** Get the total number of stored operations */
16
41
  getOperationCount(): Promise<number>;
42
+ /**
43
+ * Set the schema for materialized collection tables.
44
+ * Creates collection tables and indexes based on the schema definition.
45
+ * If operations already exist in the store, backfills the materialized
46
+ * tables from the operation log.
47
+ *
48
+ * @param schema - The schema definition describing all collections
49
+ */
50
+ setSchema(schema: SchemaDefinition): Promise<void>;
51
+ /**
52
+ * Get all records from a materialized collection.
53
+ * When schema is set, reads directly from the collection table (O(1) indexed).
54
+ * When schema is not set, falls back to replaying the operation log.
55
+ * Deleted records are excluded.
56
+ *
57
+ * @param collection - The collection name to query
58
+ * @returns Array of records with their current state
59
+ */
60
+ materializeCollection(collection: string): Promise<MaterializedRecord[]>;
61
+ /**
62
+ * Query records from a materialized collection with filtering, ordering,
63
+ * and pagination. Requires schema to be set via setSchema().
64
+ *
65
+ * @param collection - The collection name to query
66
+ * @param options - Query options (where, orderBy, limit, offset)
67
+ * @returns Array of matching records
68
+ */
69
+ queryCollection(collection: string, options?: CollectionQueryOptions): Promise<MaterializedRecord[]>;
70
+ /**
71
+ * Find a single record by ID from a materialized collection.
72
+ * Requires schema to be set via setSchema().
73
+ *
74
+ * @param collection - The collection name
75
+ * @param id - The record ID
76
+ * @returns The record or null if not found (or deleted)
77
+ */
78
+ findRecord(collection: string, id: string): Promise<MaterializedRecord | null>;
79
+ /**
80
+ * Count records in a materialized collection, optionally filtered.
81
+ * Requires schema to be set via setSchema().
82
+ *
83
+ * @param collection - The collection name
84
+ * @param where - Optional exact-match filters
85
+ * @returns Number of matching records
86
+ */
87
+ countCollection(collection: string, where?: Record<string, unknown>): Promise<number>;
17
88
  }
18
89
 
19
90
  /**
@@ -517,61 +588,100 @@ declare class KoraAuthProvider implements AuthProvider {
517
588
  /**
518
589
  * In-memory server store for testing and quick prototyping.
519
590
  * Not suitable for production — data does not survive process restart.
591
+ *
592
+ * When a schema is set via setSchema(), maintains materialized records
593
+ * in-memory for efficient queries.
520
594
  */
521
595
  declare class MemoryServerStore implements ServerStore {
522
596
  private readonly nodeId;
523
597
  private readonly operations;
524
598
  private readonly operationIndex;
525
599
  private readonly versionVector;
600
+ private schema;
601
+ /** Materialized records: collection -> recordId -> record data */
602
+ private readonly materializedRecords;
526
603
  private closed;
527
604
  constructor(nodeId?: string);
528
605
  getVersionVector(): VersionVector;
529
606
  getNodeId(): string;
607
+ setSchema(schema: SchemaDefinition): Promise<void>;
530
608
  applyRemoteOperation(op: Operation): Promise<ApplyResult>;
531
609
  getOperationRange(nodeId: string, fromSeq: number, toSeq: number): Promise<Operation[]>;
532
610
  getOperationCount(): Promise<number>;
611
+ materializeCollection(collection: string): Promise<MaterializedRecord[]>;
612
+ queryCollection(collection: string, options?: CollectionQueryOptions): Promise<MaterializedRecord[]>;
613
+ findRecord(collection: string, id: string): Promise<MaterializedRecord | null>;
614
+ countCollection(collection: string, where?: Record<string, unknown>): Promise<number>;
533
615
  close(): Promise<void>;
534
616
  /**
535
617
  * Get all stored operations (for test assertions).
536
618
  */
537
619
  getAllOperations(): Operation[];
620
+ private rebuildMaterializedRecord;
621
+ private backfillAllCollections;
622
+ private materializeFromOps;
538
623
  private assertOpen;
624
+ private assertSchema;
625
+ private assertCollection;
539
626
  }
540
627
 
541
628
  /**
542
629
  * PostgreSQL-backed server store using Drizzle ORM.
543
630
  * All reads and writes go through Drizzle's typed query builder.
544
- * DDL stays as raw SQL via Drizzle's sql template (standard practice without drizzle-kit).
631
+ *
632
+ * When a schema is set via setSchema(), also maintains materialized
633
+ * collection tables for efficient indexed queries (dual-write).
545
634
  */
546
635
  declare class PostgresServerStore implements ServerStore {
547
636
  private readonly nodeId;
548
637
  private readonly db;
549
638
  private readonly versionVector;
550
639
  private readonly ready;
640
+ private schema;
551
641
  private closed;
552
642
  constructor(db: PostgresJsDatabase, nodeId?: string);
553
643
  getVersionVector(): VersionVector;
554
644
  getNodeId(): string;
645
+ setSchema(schema: SchemaDefinition): Promise<void>;
555
646
  applyRemoteOperation(op: Operation): Promise<ApplyResult>;
556
647
  getOperationRange(nodeId: string, fromSeq: number, toSeq: number): Promise<Operation[]>;
557
648
  getOperationCount(): Promise<number>;
649
+ materializeCollection(collection: string): Promise<MaterializedRecord[]>;
650
+ queryCollection(collection: string, options?: CollectionQueryOptions): Promise<MaterializedRecord[]>;
651
+ findRecord(collection: string, id: string): Promise<MaterializedRecord | null>;
652
+ countCollection(collection: string, where?: Record<string, unknown>): Promise<number>;
558
653
  close(): Promise<void>;
559
- private initialize;
560
654
  /**
561
- * Create tables if they don't exist.
562
- * Uses raw SQL via Drizzle's sql template — standard DDL practice without drizzle-kit.
655
+ * Rebuild a single record in the materialized collection table by replaying
656
+ * all operations for that record.
657
+ */
658
+ private rebuildMaterializedRecord;
659
+ /**
660
+ * UPSERT a record into the materialized collection table.
661
+ */
662
+ private upsertMaterializedRecord;
663
+ /**
664
+ * Backfill all materialized collection tables from the existing operation log.
563
665
  */
666
+ private backfillAllCollections;
667
+ /**
668
+ * Backfill a single collection's materialized table from operations.
669
+ */
670
+ private backfillCollection;
671
+ private buildSelectQuery;
672
+ private buildWhereClause;
673
+ private deserializeRow;
674
+ private materializeFromOpsLog;
675
+ private initialize;
564
676
  private ensureTables;
565
677
  private serializeOperation;
566
678
  private deserializeOperation;
567
679
  private assertOpen;
680
+ private assertSchema;
681
+ private assertCollection;
568
682
  }
569
683
  /**
570
684
  * Creates a PostgresServerStore from a PostgreSQL connection string.
571
- *
572
- * Uses runtime dynamic imports so projects that do not use PostgreSQL
573
- * do not need to install `postgres`. Wraps the postgres client with
574
- * Drizzle ORM for typed query building.
575
685
  */
576
686
  declare function createPostgresServerStore(options: {
577
687
  connectionString: string;
@@ -582,26 +692,60 @@ declare function createPostgresServerStore(options: {
582
692
  * SQLite-backed server store using Drizzle ORM.
583
693
  * Persists operations and version vectors to a real database file,
584
694
  * surviving process restarts.
695
+ *
696
+ * When a schema is set via setSchema(), also maintains materialized
697
+ * collection tables for efficient indexed queries (dual-write).
585
698
  */
586
699
  declare class SqliteServerStore implements ServerStore {
587
700
  private readonly nodeId;
588
701
  private readonly db;
702
+ private schema;
589
703
  private closed;
590
704
  constructor(db: BetterSQLite3Database, nodeId?: string);
591
705
  getVersionVector(): VersionVector;
592
706
  getNodeId(): string;
707
+ setSchema(schema: SchemaDefinition): Promise<void>;
593
708
  applyRemoteOperation(op: Operation): Promise<ApplyResult>;
594
709
  getOperationRange(nodeId: string, fromSeq: number, toSeq: number): Promise<Operation[]>;
595
710
  getOperationCount(): Promise<number>;
711
+ materializeCollection(collection: string): Promise<MaterializedRecord[]>;
712
+ queryCollection(collection: string, options?: CollectionQueryOptions): Promise<MaterializedRecord[]>;
713
+ findRecord(collection: string, id: string): Promise<MaterializedRecord | null>;
714
+ countCollection(collection: string, where?: Record<string, unknown>): Promise<number>;
596
715
  close(): Promise<void>;
716
+ /**
717
+ * Rebuild a single record in the materialized collection table by replaying
718
+ * all operations for that record. Called within the applyRemoteOperation
719
+ * transaction for atomic dual-write.
720
+ */
721
+ private rebuildMaterializedRecord;
722
+ /**
723
+ * UPSERT a record into the materialized collection table.
724
+ * Uses INSERT ... ON CONFLICT (id) DO UPDATE SET for atomic upsert.
725
+ */
726
+ private upsertMaterializedRecord;
727
+ /**
728
+ * Backfill all materialized collection tables from the existing operation log.
729
+ * Called when setSchema() is invoked and operations already exist.
730
+ */
731
+ private backfillAllCollections;
732
+ /**
733
+ * Backfill a single collection's materialized table from operations.
734
+ */
735
+ private backfillCollection;
736
+ private buildSelectQuery;
737
+ private buildWhereClause;
738
+ private deserializeRow;
739
+ private materializeFromOpsLog;
597
740
  /**
598
741
  * Create the operations and sync_state tables if they don't exist.
599
- * Uses raw SQL via Drizzle's sql template — standard practice for DDL without drizzle-kit.
600
742
  */
601
743
  private ensureTables;
602
744
  private serializeOperation;
603
745
  private deserializeOperation;
604
746
  private assertOpen;
747
+ private assertSchema;
748
+ private assertCollection;
605
749
  }
606
750
  /**
607
751
  * Creates a SqliteServerStore with a file-backed or in-memory database.
@@ -617,6 +761,10 @@ declare class SqliteServerStore implements ServerStore {
617
761
  * import { createSqliteServerStore } from '@korajs/server'
618
762
  *
619
763
  * const store = createSqliteServerStore({ filename: './kora-server.db' })
764
+ *
765
+ * // Optional: enable materialized collection tables for fast queries
766
+ * await store.setSchema(mySchema)
767
+ *
620
768
  * const server = createKoraServer({ store, port: 3001 })
621
769
  * ```
622
770
  */
@@ -651,4 +799,4 @@ declare class NoAuthProvider implements AuthProvider {
651
799
  */
652
800
  declare function createKoraServer(config: KoraSyncServerConfig): KoraSyncServer;
653
801
 
654
- export { type AuthContext, type AuthProvider, ClientSession, type ClientSessionOptions, type HttpPollResponse, HttpServerTransport, type HttpSyncRequest, type HttpSyncResponse, KoraAuthProvider, type KoraAuthProviderOptions, KoraSyncServer, type KoraSyncServerConfig, MemoryServerStore, NoAuthProvider, PostgresServerStore, type ProductionServer, type ProductionServerConfig, type RelayCallback, ServerCloseHandler, ServerErrorHandler, ServerMessageHandler, type ServerStatus, type ServerStore, ServerTransport, type SessionState, SqliteServerStore, TokenAuthProvider, type TokenAuthProviderOptions, type WsServerConstructor, type WsServerLike, WsServerTransport, type WsServerTransportOptions, type WsWebSocket, createKoraServer, createPostgresServerStore, createProductionServer, createSqliteServerStore };
802
+ export { type AuthContext, type AuthProvider, ClientSession, type ClientSessionOptions, type CollectionQueryOptions, type HttpPollResponse, HttpServerTransport, type HttpSyncRequest, type HttpSyncResponse, KoraAuthProvider, type KoraAuthProviderOptions, KoraSyncServer, type KoraSyncServerConfig, type MaterializedRecord, MemoryServerStore, NoAuthProvider, PostgresServerStore, type ProductionServer, type ProductionServerConfig, type RelayCallback, ServerCloseHandler, ServerErrorHandler, ServerMessageHandler, type ServerStatus, type ServerStore, ServerTransport, type SessionState, SqliteServerStore, TokenAuthProvider, type TokenAuthProviderOptions, type WsServerConstructor, type WsServerLike, WsServerTransport, type WsServerTransportOptions, type WsWebSocket, createKoraServer, createPostgresServerStore, createProductionServer, createSqliteServerStore };