@geodedb/client 1.0.0-alpha.21 → 1.0.0-alpha.25

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
@@ -73,6 +73,8 @@ interface GeodeConfig {
73
73
  keepAliveInterval?: number;
74
74
  /** Maximum idle time in milliseconds (default: 30000) */
75
75
  maxIdleTime?: number;
76
+ /** Inline receive timeout in milliseconds (default: 5000) */
77
+ inlineTimeout?: number;
76
78
  /** Enable TLS for gRPC (default: true) */
77
79
  tls?: boolean;
78
80
  }
@@ -271,13 +273,24 @@ declare class StateError extends Error implements GeodeError {
271
273
  * Connection state enumeration.
272
274
  */
273
275
  type ConnectionState = 'idle' | 'executing' | 'in_transaction' | 'fetching' | 'closed' | 'error';
274
- declare const ErrClosed: Error;
275
- declare const ErrQueryInProgress: Error;
276
- declare const ErrTxInProgress: Error;
277
- declare const ErrNoTx: Error;
278
- declare const ErrTxDone: Error;
279
- declare const ErrRowsClosed: Error;
280
- declare const ErrBadConn: Error;
276
+ declare const ERR_CLOSED_MESSAGE = "geode: connection closed";
277
+ declare const ERR_QUERY_IN_PROGRESS_MESSAGE = "geode: query already in progress";
278
+ declare const ERR_TX_IN_PROGRESS_MESSAGE = "geode: transaction already in progress";
279
+ declare const ERR_NO_TX_MESSAGE = "geode: no transaction in progress";
280
+ declare const ERR_TX_DONE_MESSAGE = "geode: transaction already committed or rolled back";
281
+ declare const ERR_ROWS_CLOSED_MESSAGE = "geode: rows closed";
282
+ declare const ERR_BAD_CONN_MESSAGE = "geode: bad connection";
283
+ declare function ErrClosed(): Error;
284
+ declare function ErrQueryInProgress(): Error;
285
+ declare function ErrTxInProgress(): Error;
286
+ declare function ErrNoTx(): Error;
287
+ declare function ErrTxDone(): Error;
288
+ declare function ErrRowsClosed(): Error;
289
+ declare function ErrBadConn(): Error;
290
+ /**
291
+ * Check if an error is a specific sentinel error by message.
292
+ */
293
+ declare function isSentinelError(err: unknown, message: string): boolean;
281
294
  /**
282
295
  * Type guard for DriverError.
283
296
  */
@@ -555,6 +568,12 @@ interface QuicServerMessage {
555
568
  restore?: unknown;
556
569
  uploadBackup?: unknown;
557
570
  }
571
+ /**
572
+ * Initialize protobuf types synchronously.
573
+ * Safe to call multiple times; only loads on first call.
574
+ * Prefer ensureProtoInitialized() in async contexts to avoid blocking the event loop.
575
+ */
576
+ declare function initProtoSync(): void;
558
577
  /**
559
578
  * Ensure proto is initialized.
560
579
  */
@@ -679,9 +698,12 @@ declare abstract class BaseTransport implements Transport {
679
698
  declare class QuicTransport extends BaseTransport {
680
699
  private _client;
681
700
  private _stream;
682
- private _protoBuffer;
701
+ private _chunks;
702
+ private _totalLength;
703
+ private _maxMessageSize;
704
+ private _maxBufferBytes;
683
705
  private _pendingProtoReads;
684
- constructor(address: string);
706
+ constructor(address: string, maxMessageSize?: number, maxBufferBytes?: number);
685
707
  /**
686
708
  * Connect to the Geode server using QUIC.
687
709
  */
@@ -694,10 +716,22 @@ declare class QuicTransport extends BaseTransport {
694
716
  * Reject all pending reads with an error.
695
717
  */
696
718
  private rejectPendingReads;
719
+ /**
720
+ * Consolidate the chunk list into a single buffer.
721
+ * Called only when we know we have enough data for at least one operation.
722
+ */
723
+ private consolidateChunks;
697
724
  /**
698
725
  * Process received data (length-prefixed protobuf messages).
726
+ *
727
+ * Uses a chunk list pattern instead of Buffer.concat on every call
728
+ * to avoid O(n^2) copying of the accumulated buffer.
699
729
  */
700
730
  private processData;
731
+ /**
732
+ * Handle oversized data by closing the transport.
733
+ */
734
+ private handleOversize;
701
735
  /**
702
736
  * Send a protobuf message with length prefix.
703
737
  */
@@ -741,6 +775,80 @@ declare class MockTransport extends BaseTransport {
741
775
  */
742
776
  declare function createTransport(cfg: GeodeConfig): Promise<Transport>;
743
777
 
778
+ /**
779
+ * GQL Value Class
780
+ *
781
+ * Type-safe wrapper for GQL values in the ISO/IEC 39075:2024 type system.
782
+ * Extracted from types.ts for file size management.
783
+ */
784
+
785
+ /**
786
+ * GQL Value wrapper for type-safe value handling.
787
+ */
788
+ declare class GQLValue {
789
+ readonly kind: GQLValueKind;
790
+ private _intValue?;
791
+ private _floatValue?;
792
+ private _boolValue?;
793
+ private _stringValue?;
794
+ private _decimalValue?;
795
+ private _arrayValue?;
796
+ private _objectValue?;
797
+ private _bytesValue?;
798
+ private _dateValue?;
799
+ private _rangeValue?;
800
+ private _nodeValue?;
801
+ private _edgeValue?;
802
+ private _pathValue?;
803
+ private _rawValue?;
804
+ private constructor();
805
+ static null(): GQLValue;
806
+ static bool(value: boolean): GQLValue;
807
+ static int(value: number | bigint): GQLValue;
808
+ static float(value: number): GQLValue;
809
+ static string(value: string): GQLValue;
810
+ static decimal(value: string | number | Decimal): GQLValue;
811
+ static array(values: GQLValue[]): GQLValue;
812
+ static object(values: Map<string, GQLValue> | Record<string, GQLValue>): GQLValue;
813
+ static bytes(value: Uint8Array | Buffer): GQLValue;
814
+ static date(value: Date): GQLValue;
815
+ static time(value: Date): GQLValue;
816
+ static timestamp(value: Date): GQLValue;
817
+ static uuid(value: string): GQLValue;
818
+ static json(value: unknown): GQLValue;
819
+ static node(value: GQLNode): GQLValue;
820
+ static edge(value: GQLEdge): GQLValue;
821
+ static path(value: GQLPath): GQLValue;
822
+ static range<T>(value: GQLRange<T>): GQLValue;
823
+ static unknown(value: unknown): GQLValue;
824
+ get isNull(): boolean;
825
+ get asBool(): boolean;
826
+ get asInt(): bigint;
827
+ get asNumber(): number;
828
+ get asFloat(): number;
829
+ get asString(): string;
830
+ get asDecimal(): Decimal;
831
+ get asArray(): GQLValue[];
832
+ get asObject(): Map<string, GQLValue>;
833
+ get asBytes(): Uint8Array;
834
+ get asDate(): Date;
835
+ get asNode(): GQLNode;
836
+ get asEdge(): GQLEdge;
837
+ get asPath(): GQLPath;
838
+ get asRange(): GQLRange;
839
+ get asJSON(): unknown;
840
+ get raw(): unknown;
841
+ toString(): string;
842
+ /**
843
+ * Convert to a plain JavaScript value.
844
+ */
845
+ toJS(): unknown;
846
+ /**
847
+ * Convert to JSON-serializable format.
848
+ */
849
+ toJSON(): unknown;
850
+ }
851
+
744
852
  /**
745
853
  * GQL Type System
746
854
  *
@@ -820,72 +928,6 @@ interface GQLPath {
820
928
  nodes: GQLNode[];
821
929
  edges: GQLEdge[];
822
930
  }
823
- /**
824
- * GQL Value wrapper for type-safe value handling.
825
- */
826
- declare class GQLValue {
827
- readonly kind: GQLValueKind;
828
- private _intValue;
829
- private _floatValue;
830
- private _boolValue;
831
- private _stringValue;
832
- private _decimalValue?;
833
- private _arrayValue;
834
- private _objectValue;
835
- private _bytesValue;
836
- private _dateValue?;
837
- private _rangeValue?;
838
- private _nodeValue?;
839
- private _edgeValue?;
840
- private _pathValue?;
841
- private _rawValue?;
842
- private constructor();
843
- static null(): GQLValue;
844
- static bool(value: boolean): GQLValue;
845
- static int(value: number | bigint): GQLValue;
846
- static float(value: number): GQLValue;
847
- static string(value: string): GQLValue;
848
- static decimal(value: string | number | Decimal): GQLValue;
849
- static array(values: GQLValue[]): GQLValue;
850
- static object(values: Map<string, GQLValue> | Record<string, GQLValue>): GQLValue;
851
- static bytes(value: Uint8Array | Buffer): GQLValue;
852
- static date(value: Date): GQLValue;
853
- static time(value: Date): GQLValue;
854
- static timestamp(value: Date): GQLValue;
855
- static uuid(value: string): GQLValue;
856
- static json(value: unknown): GQLValue;
857
- static node(value: GQLNode): GQLValue;
858
- static edge(value: GQLEdge): GQLValue;
859
- static path(value: GQLPath): GQLValue;
860
- static range<T>(value: GQLRange<T>): GQLValue;
861
- static unknown(value: unknown): GQLValue;
862
- get isNull(): boolean;
863
- get asBool(): boolean;
864
- get asInt(): bigint;
865
- get asNumber(): number;
866
- get asFloat(): number;
867
- get asString(): string;
868
- get asDecimal(): Decimal;
869
- get asArray(): GQLValue[];
870
- get asObject(): Map<string, GQLValue>;
871
- get asBytes(): Uint8Array;
872
- get asDate(): Date;
873
- get asNode(): GQLNode;
874
- get asEdge(): GQLEdge;
875
- get asPath(): GQLPath;
876
- get asRange(): GQLRange;
877
- get asJSON(): unknown;
878
- get raw(): unknown;
879
- toString(): string;
880
- /**
881
- * Convert to a plain JavaScript value.
882
- */
883
- toJS(): unknown;
884
- /**
885
- * Convert to JSON-serializable format.
886
- */
887
- toJSON(): unknown;
888
- }
889
931
  /**
890
932
  * Parse a GQL type string to GQLValueKind.
891
933
  */
@@ -917,6 +959,7 @@ type Row = Map<string, GQLValue>;
917
959
  * Convert raw row data to typed Row.
918
960
  */
919
961
  declare function parseRow(raw: Record<string, unknown>, columns: ColumnInfo[]): Row;
962
+
920
963
  /**
921
964
  * Convert Row to plain object.
922
965
  *
@@ -982,6 +1025,11 @@ declare class QueryResult implements AsyncIterable<Row> {
982
1025
  * Async iterator implementation.
983
1026
  */
984
1027
  [Symbol.asyncIterator](): AsyncIterator<Row>;
1028
+ /**
1029
+ * Collect all remaining rows as raw records without GQLValue conversion.
1030
+ * This is the fast path used by queryAll() to avoid double-conversion.
1031
+ */
1032
+ _collectRawRecords(): Promise<Record<string, unknown>[]>;
985
1033
  /**
986
1034
  * Get all remaining rows as an array.
987
1035
  */
@@ -1157,12 +1205,17 @@ declare class PreparedStatement {
1157
1205
  private _query;
1158
1206
  private _parameters;
1159
1207
  private _closed;
1208
+ private _onClose?;
1160
1209
  /**
1161
1210
  * Create a new prepared statement.
1162
1211
  *
1212
+ * @param conn - Connection to use for execution
1213
+ * @param query - Query text with parameters
1214
+ * @param onClose - Optional callback invoked when close() is called (e.g., to release a pooled connection)
1215
+ *
1163
1216
  * @internal Use Connection.prepare() instead.
1164
1217
  */
1165
- constructor(conn: Connection, query: string);
1218
+ constructor(conn: Connection, query: string, onClose?: () => void);
1166
1219
  /**
1167
1220
  * Get the query text.
1168
1221
  */
@@ -1221,6 +1274,8 @@ declare class PreparedStatement {
1221
1274
  * Close the prepared statement.
1222
1275
  *
1223
1276
  * After closing, the statement cannot be executed.
1277
+ * If a release callback was provided (e.g., to return a pooled connection),
1278
+ * it is invoked exactly once on the first call to close().
1224
1279
  */
1225
1280
  close(): void;
1226
1281
  /**
@@ -1415,6 +1470,14 @@ interface BatchOptions {
1415
1470
  * By default, queries are executed sequentially and all results are collected.
1416
1471
  * Set stopOnError to true to abort on the first failure.
1417
1472
  *
1473
+ * When `options.concurrency` is greater than 1, the batch delegates to
1474
+ * {@link batchParallel} for concurrent execution. Note that a single
1475
+ * `Connection` can only execute one query at a time due to the connection
1476
+ * state machine, so `batchParallel` will automatically fall back to
1477
+ * sequential execution (concurrency=1) when given a single connection.
1478
+ * For true parallelism, use a `ConnectionPool` to acquire separate
1479
+ * connections per concurrent query.
1480
+ *
1418
1481
  * @param conn - Connection to use
1419
1482
  * @param queries - Array of queries to execute
1420
1483
  * @param options - Batch execution options
@@ -1479,12 +1542,22 @@ declare function batchMap(conn: Connection, queryTemplate: string, items: QueryP
1479
1542
  * Unlike the sequential batch(), this executes multiple queries concurrently
1480
1543
  * up to the specified limit.
1481
1544
  *
1482
- * Note: Results may be returned out of order.
1545
+ * **Important:** A single `Connection` can only execute one query at a time
1546
+ * (the connection state machine throws `ErrQueryInProgress` for concurrent
1547
+ * queries). When a single connection is provided with concurrency > 1, this
1548
+ * function automatically falls back to sequential execution (concurrency=1)
1549
+ * to prevent runtime errors.
1483
1550
  *
1484
- * @param conn - Connection to use
1551
+ * For true parallel execution, use a connection pool or connection factory
1552
+ * that provides separate connections per concurrent query.
1553
+ *
1554
+ * Note: When executing concurrently, results may arrive out of order but
1555
+ * are sorted by index before returning.
1556
+ *
1557
+ * @param conn - Connection to use (single connection forces sequential execution)
1485
1558
  * @param queries - Array of queries to execute
1486
1559
  * @param options - Batch execution options with concurrency
1487
- * @returns Batch summary (results in completion order)
1560
+ * @returns Batch summary (results sorted by query index)
1488
1561
  */
1489
1562
  declare function batchParallel(conn: Connection, queries: BatchQuery[], options?: BatchOptions & {
1490
1563
  concurrency: number;
@@ -1532,109 +1605,67 @@ declare class Connection {
1532
1605
  * Create a connection with a custom transport (for testing).
1533
1606
  */
1534
1607
  static connectWithTransport(config: GeodeConfig, transport: Transport): Promise<Connection>;
1535
- /**
1536
- * Get connection configuration.
1537
- */
1608
+ /** Get connection configuration. */
1538
1609
  get config(): Readonly<GeodeConfig>;
1539
- /**
1540
- * Get current connection state.
1541
- */
1610
+ /** Get current connection state. */
1542
1611
  get state(): ConnectionState;
1543
- /**
1544
- * Check if connection is in a transaction.
1545
- */
1612
+ /** Check if connection is in a transaction. */
1546
1613
  get inTransaction(): boolean;
1547
- /**
1548
- * Check if connection is closed.
1549
- */
1614
+ /** Check if connection is closed. */
1550
1615
  get isClosed(): boolean;
1551
- /**
1552
- * Get session ID.
1553
- */
1616
+ /** Get session ID. */
1554
1617
  get sessionId(): string;
1555
- /**
1556
- * Perform the HELLO handshake.
1557
- */
1618
+ /** Perform the HELLO handshake. */
1558
1619
  private hello;
1559
- /**
1560
- * Execute a query that returns rows.
1561
- */
1620
+ /** Execute a query that returns rows. */
1562
1621
  query(query: string, options?: QueryOptions): Promise<QueryResult>;
1563
- /**
1564
- * Execute a query and return all rows as an array.
1565
- */
1622
+ /** Execute a query and return all rows as an array. */
1566
1623
  queryAll(query: string, options?: QueryOptions): Promise<Record<string, unknown>[]>;
1567
- /**
1568
- * Execute a query that doesn't return rows.
1569
- */
1624
+ /** Execute a query that doesn't return rows. */
1570
1625
  exec(query: string, options?: QueryOptions): Promise<void>;
1571
- /**
1572
- * Fetch the next page of results (internal).
1573
- */
1626
+ /** @internal Fetch the next page of results. Called by QueryResult. */
1574
1627
  _fetchNextPage(pageSize: number, signal?: AbortSignal): Promise<{
1575
1628
  rows: Record<string, unknown>[];
1576
1629
  final: boolean;
1577
1630
  }>;
1578
- /**
1579
- * Try to receive an inline response with short timeout.
1580
- */
1631
+ /** Try to receive an inline response with short timeout. */
1581
1632
  private _tryReceiveInline;
1582
- /**
1583
- * Release active result (internal).
1584
- */
1633
+ /** Drain remaining data pages until final=true to prevent query corruption (QUAL-T7). */
1634
+ private _drainRemainingPages;
1635
+ /** @internal Release the active result, returning the connection to idle. */
1585
1636
  _releaseResult(result: QueryResult): void;
1586
- /**
1587
- * Begin a transaction.
1588
- */
1637
+ /** Begin a transaction. */
1589
1638
  begin(signal?: AbortSignal): Promise<Transaction>;
1590
- /**
1591
- * Commit the current transaction (internal).
1592
- */
1639
+ /** @internal Commit the current transaction. Called by Transaction. */
1593
1640
  _commit(signal?: AbortSignal): Promise<void>;
1594
- /**
1595
- * Rollback the current transaction (internal).
1596
- */
1641
+ /** @internal Rollback the current transaction. Called by Transaction. */
1597
1642
  _rollback(signal?: AbortSignal): Promise<void>;
1598
- /**
1599
- * Create a savepoint (internal).
1600
- */
1643
+ /** @internal Create a named savepoint. Called by Transaction. */
1601
1644
  _savepoint(name: string, signal?: AbortSignal): Promise<void>;
1602
- /**
1603
- * Rollback to a savepoint (internal).
1604
- */
1645
+ /** @internal Rollback to a previously created savepoint. Called by Transaction. */
1605
1646
  _rollbackTo(name: string, signal?: AbortSignal): Promise<void>;
1606
- /**
1607
- * Ping the server to check connection health.
1608
- */
1647
+ /** Ping the server to check connection health. */
1609
1648
  ping(signal?: AbortSignal): Promise<void>;
1610
- /**
1611
- * Reset the connection session.
1612
- */
1649
+ /** Reset the connection session. */
1613
1650
  reset(signal?: AbortSignal): Promise<void>;
1614
- /**
1615
- * Close the connection.
1616
- */
1651
+ /** Close the connection. */
1617
1652
  close(): Promise<void>;
1618
- /**
1619
- * Create a prepared statement.
1620
- */
1653
+ /** Create a prepared statement. */
1621
1654
  prepare(query: string): Promise<PreparedStatement>;
1622
- /**
1623
- * Get the query execution plan without executing.
1624
- */
1655
+ /** Get the query execution plan without executing. */
1625
1656
  explain(query: string, options?: ExplainOptions): Promise<QueryPlan>;
1626
- /**
1627
- * Execute a query with profiling.
1628
- */
1657
+ /** Execute a query with profiling. */
1629
1658
  profile(query: string, options?: ExplainOptions): Promise<QueryProfile>;
1630
- /**
1631
- * Execute multiple queries in a batch.
1632
- */
1659
+ /** Execute multiple queries in a batch. */
1633
1660
  batch(queries: BatchQuery[], options?: BatchOptions): Promise<BatchSummary>;
1634
- /**
1635
- * Check connection state before operation.
1636
- */
1661
+ /** Check connection state before operation. */
1637
1662
  private checkState;
1663
+ /** Send a protobuf message with request timeout enforcement. */
1664
+ private _sendWithTimeout;
1665
+ /** Receive a protobuf message with request timeout enforcement. */
1666
+ private _receiveWithTimeout;
1667
+ /** Create a combined abort signal from requestTimeout and optional caller signal (CWE-703). */
1668
+ private _withRequestTimeout;
1638
1669
  }
1639
1670
 
1640
1671
  /**
@@ -1777,13 +1808,23 @@ interface PasswordPolicy {
1777
1808
  declare class AuthClient {
1778
1809
  private _conn;
1779
1810
  private _passwordPolicy;
1811
+ private _onClose?;
1812
+ private _closed;
1780
1813
  /**
1781
1814
  * Create a new auth client.
1782
1815
  *
1783
1816
  * @param conn - Connection to use
1784
1817
  * @param passwordPolicy - Optional password policy configuration
1818
+ * @param onClose - Optional callback invoked when close() is called (e.g., to release a pooled connection)
1819
+ */
1820
+ constructor(conn: Connection, passwordPolicy?: PasswordPolicy, onClose?: () => void);
1821
+ /**
1822
+ * Close the auth client and release the underlying connection.
1823
+ *
1824
+ * If a release callback was provided (e.g., to return a pooled connection),
1825
+ * it is invoked exactly once on the first call to close().
1785
1826
  */
1786
- constructor(conn: Connection, passwordPolicy?: PasswordPolicy);
1827
+ close(): void;
1787
1828
  /**
1788
1829
  * Get the current password policy.
1789
1830
  */
@@ -1792,104 +1833,35 @@ declare class AuthClient {
1792
1833
  * Update the password policy.
1793
1834
  */
1794
1835
  setPasswordPolicy(policy: PasswordPolicy): void;
1795
- /**
1796
- * Create a new user.
1797
- *
1798
- * @param username - Username for the new user
1799
- * @param options - User creation options
1800
- */
1836
+ /** Create a new user. */
1801
1837
  createUser(username: string, options: CreateUserOptions): Promise<void>;
1802
- /**
1803
- * Delete a user.
1804
- *
1805
- * @param username - Username to delete
1806
- */
1838
+ /** Delete a user. */
1807
1839
  deleteUser(username: string): Promise<void>;
1808
- /**
1809
- * Get user information.
1810
- *
1811
- * @param username - Username to look up
1812
- * @returns User information or null if not found
1813
- */
1840
+ /** Get user information, or null if not found. */
1814
1841
  getUser(username: string): Promise<User | null>;
1815
- /**
1816
- * List all users.
1817
- *
1818
- * @returns Array of users
1819
- */
1842
+ /** List all users. */
1820
1843
  listUsers(): Promise<User[]>;
1821
- /**
1822
- * Change a user's password.
1823
- *
1824
- * @param username - Username
1825
- * @param newPassword - New password
1826
- */
1844
+ /** Change a user's password. */
1827
1845
  changePassword(username: string, newPassword: string): Promise<void>;
1828
- /**
1829
- * Activate a user.
1830
- *
1831
- * @param username - Username to activate
1832
- */
1846
+ /** Activate a user. */
1833
1847
  activateUser(username: string): Promise<void>;
1834
- /**
1835
- * Deactivate a user.
1836
- *
1837
- * @param username - Username to deactivate
1838
- */
1848
+ /** Deactivate a user. */
1839
1849
  deactivateUser(username: string): Promise<void>;
1840
- /**
1841
- * Create a new role.
1842
- *
1843
- * @param name - Role name
1844
- * @param options - Role creation options
1845
- */
1850
+ /** Create a new role. */
1846
1851
  createRole(name: string, options?: CreateRoleOptions): Promise<void>;
1847
- /**
1848
- * Delete a role.
1849
- *
1850
- * @param name - Role name to delete
1851
- */
1852
+ /** Delete a role. */
1852
1853
  deleteRole(name: string): Promise<void>;
1853
- /**
1854
- * Get role information.
1855
- *
1856
- * @param name - Role name
1857
- * @returns Role information or null if not found
1858
- */
1854
+ /** Get role information, or null if not found. */
1859
1855
  getRole(name: string): Promise<Role | null>;
1860
- /**
1861
- * List all roles.
1862
- *
1863
- * @returns Array of roles
1864
- */
1856
+ /** List all roles. */
1865
1857
  listRoles(): Promise<Role[]>;
1866
- /**
1867
- * Assign a role to a user.
1868
- *
1869
- * @param username - Username
1870
- * @param roleName - Role to assign
1871
- */
1858
+ /** Assign a role to a user. */
1872
1859
  assignRole(username: string, roleName: string): Promise<void>;
1873
- /**
1874
- * Revoke a role from a user.
1875
- *
1876
- * @param username - Username
1877
- * @param roleName - Role to revoke
1878
- */
1860
+ /** Revoke a role from a user. */
1879
1861
  revokeRole(username: string, roleName: string): Promise<void>;
1880
- /**
1881
- * Grant a permission to a role.
1882
- *
1883
- * @param roleName - Role name
1884
- * @param permission - Permission to grant
1885
- */
1862
+ /** Grant a permission to a role. */
1886
1863
  grantPermission(roleName: string, permission: Permission): Promise<void>;
1887
- /**
1888
- * Revoke a permission from a role.
1889
- *
1890
- * @param roleName - Role name
1891
- * @param permission - Permission to revoke
1892
- */
1864
+ /** Revoke a permission from a role. */
1893
1865
  revokePermission(roleName: string, permission: Permission): Promise<void>;
1894
1866
  /**
1895
1867
  * Create an RLS policy.
@@ -1957,9 +1929,7 @@ declare class AuthClient {
1957
1929
  * @returns Whether permission is granted
1958
1930
  */
1959
1931
  hasPermission(resource: string, action: string, label?: string): Promise<boolean>;
1960
- private validateUsername;
1961
1932
  private validatePassword;
1962
- private validateRoleName;
1963
1933
  private validatePolicyName;
1964
1934
  }
1965
1935
  /**
@@ -2045,6 +2015,14 @@ declare class GeodeClient {
2045
2015
  exec(query: string, options?: QueryOptions): Promise<void>;
2046
2016
  /**
2047
2017
  * Execute multiple statements.
2018
+ *
2019
+ * When a connection pool is available, all queries are executed within a
2020
+ * single transaction to reduce round-trips (one BEGIN + N queries + COMMIT
2021
+ * instead of N independent round-trips with connection acquire/release).
2022
+ *
2023
+ * For non-pooled (single connection) clients, queries are executed
2024
+ * sequentially without an implicit transaction wrapper, preserving the
2025
+ * caller's control over transaction boundaries.
2048
2026
  */
2049
2027
  execBatch(queries: Array<{
2050
2028
  query: string;
@@ -2327,7 +2305,13 @@ declare class GrpcTransport implements Transport {
2327
2305
  private _closed;
2328
2306
  private _address;
2329
2307
  private _pendingResponses;
2308
+ private _pendingProtoReads;
2330
2309
  private _activeStream;
2310
+ private _streamPaused;
2311
+ private _backpressureThreshold;
2312
+ private _streamTimeoutMs;
2313
+ private _streamTimeoutTimer;
2314
+ private _streamComplete;
2331
2315
  constructor(address: string);
2332
2316
  /**
2333
2317
  * Connect to the Geode server using gRPC.
@@ -2340,16 +2324,9 @@ declare class GrpcTransport implements Transport {
2340
2324
  sendProto(msg: QuicClientMessage, signal?: AbortSignal): Promise<void>;
2341
2325
  /**
2342
2326
  * Receive a protobuf message from the queue.
2327
+ * If no response is buffered, waits for the next streamed message.
2343
2328
  */
2344
2329
  receiveProto(signal?: AbortSignal): Promise<QuicServerMessage>;
2345
- /**
2346
- * Legacy JSON send (not supported for gRPC).
2347
- */
2348
- send(_msg: Record<string, unknown>, _signal?: AbortSignal): Promise<void>;
2349
- /**
2350
- * Legacy JSON receive (not supported for gRPC).
2351
- */
2352
- receive(_signal?: AbortSignal): Promise<Buffer>;
2353
2330
  /**
2354
2331
  * Close the transport.
2355
2332
  */
@@ -2362,15 +2339,30 @@ declare class GrpcTransport implements Transport {
2362
2339
  * Get remote address.
2363
2340
  */
2364
2341
  getAddress(): string;
2342
+ /**
2343
+ * Enqueue a response, resolving a pending read if one exists.
2344
+ */
2345
+ private enqueueResponse;
2365
2346
  /**
2366
2347
  * Make a unary RPC call.
2367
2348
  */
2368
2349
  private callUnary;
2369
2350
  /**
2370
2351
  * Call the server-streaming Execute RPC.
2371
- * Collects all streamed ExecutionResponse messages into _pendingResponses.
2352
+ * Uses backpressure to prevent unbounded buffering: pauses the stream when
2353
+ * the pending response buffer exceeds the threshold, resumes when drained.
2354
+ * Enforces a configurable timeout that fires when no data arrives within the period.
2372
2355
  */
2373
2356
  private callServerStream;
2357
+ /**
2358
+ * Reset the stream inactivity timeout. If no data arrives within
2359
+ * _streamTimeoutMs, the stream is cancelled and the promise rejected.
2360
+ */
2361
+ private resetStreamTimeout;
2362
+ /**
2363
+ * Clear any active stream inactivity timeout.
2364
+ */
2365
+ private clearStreamTimeout;
2374
2366
  /**
2375
2367
  * Check if closed and throw if so.
2376
2368
  */
@@ -2429,6 +2421,124 @@ declare function validateSavepointName(name: string): void;
2429
2421
  */
2430
2422
  declare function sanitizeForLog(value: string): string;
2431
2423
 
2424
+ /**
2425
+ * Predicate Builder
2426
+ *
2427
+ * Fluent API for building WHERE clause predicates in GQL queries.
2428
+ * Extracted from query-builder.ts for file size management.
2429
+ */
2430
+
2431
+ /**
2432
+ * Predicate operator.
2433
+ */
2434
+ type PredicateOp = '=' | '<>' | '!=' | '<' | '<=' | '>' | '>=' | 'IN' | 'NOT IN' | 'CONTAINS' | 'STARTS WITH' | 'ENDS WITH' | 'IS NULL' | 'IS NOT NULL';
2435
+ /**
2436
+ * Build a predicate for WHERE clauses.
2437
+ */
2438
+ declare class PredicateBuilder {
2439
+ private _predicates;
2440
+ private _params;
2441
+ private _paramCounter;
2442
+ /**
2443
+ * Add a comparison predicate.
2444
+ */
2445
+ compare(left: string, op: PredicateOp, right: unknown): this;
2446
+ /**
2447
+ * Add an equality predicate.
2448
+ */
2449
+ eq(left: string, right: unknown): this;
2450
+ /**
2451
+ * Add a not-equal predicate.
2452
+ */
2453
+ neq(left: string, right: unknown): this;
2454
+ /**
2455
+ * Add a less-than predicate.
2456
+ */
2457
+ lt(left: string, right: unknown): this;
2458
+ /**
2459
+ * Add a less-than-or-equal predicate.
2460
+ */
2461
+ lte(left: string, right: unknown): this;
2462
+ /**
2463
+ * Add a greater-than predicate.
2464
+ */
2465
+ gt(left: string, right: unknown): this;
2466
+ /**
2467
+ * Add a greater-than-or-equal predicate.
2468
+ */
2469
+ gte(left: string, right: unknown): this;
2470
+ /**
2471
+ * Add an IN predicate.
2472
+ */
2473
+ in(left: string, values: unknown[]): this;
2474
+ /**
2475
+ * Add a NOT IN predicate.
2476
+ */
2477
+ notIn(left: string, values: unknown[]): this;
2478
+ /**
2479
+ * Add a CONTAINS predicate.
2480
+ */
2481
+ contains(left: string, value: string): this;
2482
+ /**
2483
+ * Add a STARTS WITH predicate.
2484
+ */
2485
+ startsWith(left: string, value: string): this;
2486
+ /**
2487
+ * Add an ENDS WITH predicate.
2488
+ */
2489
+ endsWith(left: string, value: string): this;
2490
+ /**
2491
+ * Add an IS NULL predicate.
2492
+ */
2493
+ isNull(expr: string): this;
2494
+ /**
2495
+ * Add an IS NOT NULL predicate.
2496
+ */
2497
+ isNotNull(expr: string): this;
2498
+ /**
2499
+ * Add a raw predicate expression.
2500
+ *
2501
+ * **SECURITY WARNING: This method bypasses all input validation.**
2502
+ *
2503
+ * Using raw() with user-supplied input can lead to GQL injection attacks.
2504
+ * Only use this method when:
2505
+ * 1. The expression is entirely constructed from trusted, hardcoded strings
2506
+ * 2. All dynamic values are passed via the `params` argument (using $paramName syntax)
2507
+ *
2508
+ * @example
2509
+ * ```typescript
2510
+ * // SAFE: Using parameters for dynamic values
2511
+ * predicate().raw('n.custom_field CONTAINS $pattern', { pattern: userInput })
2512
+ *
2513
+ * // UNSAFE: Never interpolate user input directly
2514
+ * predicate().raw(`n.name = '${userInput}'`) // VULNERABLE TO INJECTION!
2515
+ * ```
2516
+ *
2517
+ * Consider using the typed predicate methods (eq, gt, contains, etc.) instead.
2518
+ *
2519
+ * @param expr - Raw predicate expression (MUST be trusted input)
2520
+ * @param params - Parameters to bind (safe for user input)
2521
+ * @deprecated Consider using typed predicate methods instead for better security.
2522
+ */
2523
+ raw(expr: string, params?: QueryParams): this;
2524
+ /**
2525
+ * Combine predicates with AND.
2526
+ */
2527
+ and(builder: PredicateBuilder): this;
2528
+ /**
2529
+ * Combine predicates with OR.
2530
+ */
2531
+ or(builder: PredicateBuilder): this;
2532
+ /**
2533
+ * Build the predicate.
2534
+ */
2535
+ build(): {
2536
+ predicate: string;
2537
+ params: QueryParams;
2538
+ };
2539
+ private nextParam;
2540
+ }
2541
+
2432
2542
  /**
2433
2543
  * Query Builder
2434
2544
  *
@@ -2443,10 +2553,6 @@ type EdgeDirection = 'outgoing' | 'incoming' | 'both';
2443
2553
  * Sort direction.
2444
2554
  */
2445
2555
  type SortDirection = 'ASC' | 'DESC';
2446
- /**
2447
- * Predicate operator.
2448
- */
2449
- type PredicateOp = '=' | '<>' | '!=' | '<' | '<=' | '>' | '>=' | 'IN' | 'NOT IN' | 'CONTAINS' | 'STARTS WITH' | 'ENDS WITH' | 'IS NULL' | 'IS NOT NULL';
2450
2556
  /**
2451
2557
  * Node pattern for MATCH clauses.
2452
2558
  */
@@ -2593,112 +2699,6 @@ declare class PatternBuilder {
2593
2699
  */
2594
2700
  toGQL(): string;
2595
2701
  }
2596
- /**
2597
- * Build a predicate for WHERE clauses.
2598
- */
2599
- declare class PredicateBuilder {
2600
- private _predicates;
2601
- private _params;
2602
- private _paramCounter;
2603
- /**
2604
- * Add a comparison predicate.
2605
- */
2606
- compare(left: string, op: PredicateOp, right: unknown): this;
2607
- /**
2608
- * Add an equality predicate.
2609
- */
2610
- eq(left: string, right: unknown): this;
2611
- /**
2612
- * Add a not-equal predicate.
2613
- */
2614
- neq(left: string, right: unknown): this;
2615
- /**
2616
- * Add a less-than predicate.
2617
- */
2618
- lt(left: string, right: unknown): this;
2619
- /**
2620
- * Add a less-than-or-equal predicate.
2621
- */
2622
- lte(left: string, right: unknown): this;
2623
- /**
2624
- * Add a greater-than predicate.
2625
- */
2626
- gt(left: string, right: unknown): this;
2627
- /**
2628
- * Add a greater-than-or-equal predicate.
2629
- */
2630
- gte(left: string, right: unknown): this;
2631
- /**
2632
- * Add an IN predicate.
2633
- */
2634
- in(left: string, values: unknown[]): this;
2635
- /**
2636
- * Add a NOT IN predicate.
2637
- */
2638
- notIn(left: string, values: unknown[]): this;
2639
- /**
2640
- * Add a CONTAINS predicate.
2641
- */
2642
- contains(left: string, value: string): this;
2643
- /**
2644
- * Add a STARTS WITH predicate.
2645
- */
2646
- startsWith(left: string, value: string): this;
2647
- /**
2648
- * Add an ENDS WITH predicate.
2649
- */
2650
- endsWith(left: string, value: string): this;
2651
- /**
2652
- * Add an IS NULL predicate.
2653
- */
2654
- isNull(expr: string): this;
2655
- /**
2656
- * Add an IS NOT NULL predicate.
2657
- */
2658
- isNotNull(expr: string): this;
2659
- /**
2660
- * Add a raw predicate expression.
2661
- *
2662
- * **⚠️ SECURITY WARNING: This method bypasses all input validation.**
2663
- *
2664
- * Using raw() with user-supplied input can lead to GQL injection attacks.
2665
- * Only use this method when:
2666
- * 1. The expression is entirely constructed from trusted, hardcoded strings
2667
- * 2. All dynamic values are passed via the `params` argument (using $paramName syntax)
2668
- *
2669
- * @example
2670
- * ```typescript
2671
- * // SAFE: Using parameters for dynamic values
2672
- * predicate().raw('n.custom_field CONTAINS $pattern', { pattern: userInput })
2673
- *
2674
- * // UNSAFE: Never interpolate user input directly
2675
- * predicate().raw(`n.name = '${userInput}'`) // VULNERABLE TO INJECTION!
2676
- * ```
2677
- *
2678
- * Consider using the typed predicate methods (eq, gt, contains, etc.) instead.
2679
- *
2680
- * @param expr - Raw predicate expression (MUST be trusted input)
2681
- * @param params - Parameters to bind (safe for user input)
2682
- * @deprecated Consider using typed predicate methods instead for better security.
2683
- */
2684
- raw(expr: string, params?: QueryParams): this;
2685
- /**
2686
- * Combine predicates with AND.
2687
- */
2688
- and(builder: PredicateBuilder): this;
2689
- /**
2690
- * Combine predicates with OR.
2691
- */
2692
- or(builder: PredicateBuilder): this;
2693
- /**
2694
- * Build the predicate.
2695
- */
2696
- build(): {
2697
- predicate: string;
2698
- params: QueryParams;
2699
- };
2700
- private nextParam;
2701
- }
2702
2702
  /**
2703
2703
  * GQL Query Builder.
2704
2704
  */
@@ -2715,26 +2715,6 @@ declare class QueryBuilder {
2715
2715
  optionalMatch(pattern: string | PatternBuilder): this;
2716
2716
  /**
2717
2717
  * Add a WHERE clause.
2718
- *
2719
- * **⚠️ SECURITY WARNING when using string predicates:**
2720
- *
2721
- * When passing a string predicate, this method does NOT validate or sanitize input.
2722
- * Using string predicates with user-supplied data can lead to GQL injection attacks.
2723
- *
2724
- * @example
2725
- * ```typescript
2726
- * // RECOMMENDED: Use PredicateBuilder for type-safe, injection-resistant queries
2727
- * query().where(predicate().eq('n.name', userInput))
2728
- *
2729
- * // SAFE: Using parameters with string predicates
2730
- * query().where('n.name = $name', { name: userInput })
2731
- *
2732
- * // UNSAFE: Never interpolate user input directly in string predicates
2733
- * query().where(`n.name = '${userInput}'`) // VULNERABLE TO INJECTION!
2734
- * ```
2735
- *
2736
- * @param predicate - A PredicateBuilder (recommended) or raw predicate string
2737
- * @param params - Parameters to bind when using string predicates
2738
2718
  */
2739
2719
  where(predicate: string | PredicateBuilder, params?: QueryParams): this;
2740
2720
  /**
@@ -2788,23 +2768,7 @@ declare class QueryBuilder {
2788
2768
  /**
2789
2769
  * Add a raw GQL clause.
2790
2770
  *
2791
- * **⚠️ SECURITY WARNING: This method bypasses all input validation.**
2792
- *
2793
- * Using raw() with user-supplied input can lead to GQL injection attacks.
2794
- * Only use this method when:
2795
- * 1. The clause is entirely constructed from trusted, hardcoded strings
2796
- * 2. All dynamic values are passed via the `params` argument (using $paramName syntax)
2797
- *
2798
- * @example
2799
- * ```typescript
2800
- * // SAFE: Using parameters for dynamic values
2801
- * query().raw('CALL db.index.fulltext.queryNodes("idx", $term)', { term: userInput })
2802
- *
2803
- * // UNSAFE: Never interpolate user input directly
2804
- * query().raw(`MATCH (n:${userLabel})`) // VULNERABLE TO INJECTION!
2805
- * ```
2806
- *
2807
- * Consider using the typed query builder methods instead.
2771
+ * **SECURITY WARNING: This method bypasses all input validation.**
2808
2772
  *
2809
2773
  * @param clause - Raw GQL clause (MUST be trusted input)
2810
2774
  * @param params - Parameters to bind (safe for user input)
@@ -2856,4 +2820,4 @@ declare function node(): NodePatternBuilder;
2856
2820
  */
2857
2821
  declare function edge(): EdgePatternBuilder;
2858
2822
 
2859
- export { AuthClient, BaseTransport, type BatchOptions, type BatchQuery, type BatchResult, type BatchSummary, type BeginRequest, type BeginResponse, type ClientOptions, type ColumnDef, type ColumnDefinition, type ColumnInfo, type CommitRequest, type CommitResponse, ConfigError, Connection, ConnectionPool, type ConnectionState, type CreateRLSPolicyOptions, type CreateRoleOptions, type CreateUserOptions, DEFAULT_CONFORMANCE, DEFAULT_GRPC_PORT, DEFAULT_HELLO_NAME, DEFAULT_HELLO_VERSION, DEFAULT_PAGE_SIZE, DEFAULT_PORT, type DSNScheme, type DataPage, DriverError, type EdgeDirection, type EdgePattern, EdgePatternBuilder, ErrBadConn, ErrClosed, ErrNoTx, ErrQueryInProgress, ErrRowsClosed, ErrTxDone, ErrTxInProgress, type ExecuteRequest, type ExecutionResponse, type ExplainOptions, type GQLEdge, type GQLId, type GQLNode, type GQLPath, type GQLRange, type GQLType, GQLValue, type GQLValueKind, GeodeClient, type GeodeConfig, type GeodeError, GrpcTransport, type HelloRequest, type HelloResponse, MAX_PAGE_SIZE, MAX_QUERY_LENGTH, MockTransport, type NodePattern, NodePatternBuilder, type OperationTiming, type Param, type ParameterInfo, PatternBuilder, type PatternElement, type Permission, type PingRequest, type PingResponse, type PlanOperation, type PoolConfig, PredicateBuilder, type PredicateOp, PreparedStatement, type ProtoError, type Row$1 as ProtoRow, type ProtoValue, type PullRequest, type PullResponse, QueryBuilder, type QueryOptions, type QueryParams, type QueryPlan, type QueryProfile, QueryResult, QueryResultIterator, type QuicClientMessage, type QuicServerMessage, QuicTransport, QuicTransport as QuicheTransport, type RLSPolicy, type RawEdge, type Role, type RollbackRequest, type RollbackResponse, type Row, SUPPORTED_SCHEMES, type SchemaDefinition, SecurityError, type SortDirection, StateError, type Status, StatusClass, type StatusClassType, Transaction, type Transport, TransportError, type TransportType, type User, batch, batchAll, batchFirst, batchMap, batchParallel, buildBeginRequest, buildCommitRequest, buildExecuteRequest, buildHelloRequest, buildPingRequest, buildPullRequest, buildRollbackRequest, buildRollbackToRequest, buildSavepointRequest, buildTLSConfig, cloneConfig, createAuthClient, createClient, createClientWithConfig, createTransport, decodeLengthPrefix, decodeQuicServerMessage, defaultConfig, edge, encodeQuicClientMessage, encodeWithLengthPrefix, ensureProtoInitialized, explain, extractParameters, formatPlan, formatProfile, fromJSON, getAddress, getProtoPath, isDriverError, isGeodeError, isRetryableError, jsToProtoValue, node, parseDSN, parseGQLType, parseRow, pattern, predicate, prepare, profile, protoValueToJS, query, redactConfig, redactDSN, rowToObject, rowToRecord, sanitizeForLog, validateConfig, validateHostname, validatePageSize, validateParamName, validateParamValue, validatePort, validateQuery, validateSavepointName, withTransaction };
2823
+ export { AuthClient, BaseTransport, type BatchOptions, type BatchQuery, type BatchResult, type BatchSummary, type BeginRequest, type BeginResponse, type ClientOptions, type ColumnDef, type ColumnDefinition, type ColumnInfo, type CommitRequest, type CommitResponse, ConfigError, Connection, ConnectionPool, type ConnectionState, type CreateRLSPolicyOptions, type CreateRoleOptions, type CreateUserOptions, DEFAULT_CONFORMANCE, DEFAULT_GRPC_PORT, DEFAULT_HELLO_NAME, DEFAULT_HELLO_VERSION, DEFAULT_PAGE_SIZE, DEFAULT_PORT, type DSNScheme, type DataPage, DriverError, ERR_BAD_CONN_MESSAGE, ERR_CLOSED_MESSAGE, ERR_NO_TX_MESSAGE, ERR_QUERY_IN_PROGRESS_MESSAGE, ERR_ROWS_CLOSED_MESSAGE, ERR_TX_DONE_MESSAGE, ERR_TX_IN_PROGRESS_MESSAGE, type EdgeDirection, type EdgePattern, EdgePatternBuilder, ErrBadConn, ErrClosed, ErrNoTx, ErrQueryInProgress, ErrRowsClosed, ErrTxDone, ErrTxInProgress, type ExecuteRequest, type ExecutionResponse, type ExplainOptions, type GQLEdge, type GQLId, type GQLNode, type GQLPath, type GQLRange, type GQLType, GQLValue, type GQLValueKind, GeodeClient, type GeodeConfig, type GeodeError, GrpcTransport, type HelloRequest, type HelloResponse, MAX_PAGE_SIZE, MAX_QUERY_LENGTH, MockTransport, type NodePattern, NodePatternBuilder, type OperationTiming, type Param, type ParameterInfo, PatternBuilder, type PatternElement, type Permission, type PingRequest, type PingResponse, type PlanOperation, type PoolConfig, PredicateBuilder, type PredicateOp, PreparedStatement, type ProtoError, type Row$1 as ProtoRow, type ProtoValue, type PullRequest, type PullResponse, QueryBuilder, type QueryOptions, type QueryParams, type QueryPlan, type QueryProfile, QueryResult, QueryResultIterator, type QuicClientMessage, type QuicServerMessage, QuicTransport, QuicTransport as QuicheTransport, type RLSPolicy, type RawEdge, type Role, type RollbackRequest, type RollbackResponse, type Row, SUPPORTED_SCHEMES, type SchemaDefinition, SecurityError, type SortDirection, StateError, type Status, StatusClass, type StatusClassType, Transaction, type Transport, TransportError, type TransportType, type User, batch, batchAll, batchFirst, batchMap, batchParallel, buildBeginRequest, buildCommitRequest, buildExecuteRequest, buildHelloRequest, buildPingRequest, buildPullRequest, buildRollbackRequest, buildRollbackToRequest, buildSavepointRequest, buildTLSConfig, cloneConfig, createAuthClient, createClient, createClientWithConfig, createTransport, decodeLengthPrefix, decodeQuicServerMessage, defaultConfig, edge, encodeQuicClientMessage, encodeWithLengthPrefix, ensureProtoInitialized, explain, extractParameters, formatPlan, formatProfile, fromJSON, getAddress, getProtoPath, initProtoSync, isDriverError, isGeodeError, isRetryableError, isSentinelError, jsToProtoValue, node, parseDSN, parseGQLType, parseRow, pattern, predicate, prepare, profile, protoValueToJS, query, redactConfig, redactDSN, rowToObject, rowToRecord, sanitizeForLog, validateConfig, validateHostname, validatePageSize, validateParamName, validateParamValue, validatePort, validateQuery, validateSavepointName, withTransaction };