@mindstudio-ai/agent 0.1.162 → 0.1.164

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
@@ -1045,10 +1045,11 @@ type UpdateInput<T> = Partial<Omit<T, SystemFields>>;
1045
1045
  * returns a boolean.
1046
1046
  *
1047
1047
  * The SDK attempts to compile the predicate to a SQL WHERE clause for
1048
- * performance. Simple expressions (field comparisons, &&/||, .includes())
1049
- * compile to efficient SQL. If the predicate can't be compiled (function
1050
- * calls, regex, computed expressions), the SDK falls back to fetching all
1051
- * rows and evaluating in JS. Both paths produce identical results.
1048
+ * performance. Simple expressions (field comparisons, &&/||, .includes(),
1049
+ * constant right-hand sides like `db.ago(db.days(7))`) compile to efficient
1050
+ * SQL. If the predicate can't be compiled (function calls, regex, computed
1051
+ * fields), the SDK falls back to fetching all rows and evaluating in JS. Both
1052
+ * paths select the same rows, NULL columns included.
1052
1053
  *
1053
1054
  * For predicates that compare to outer-scope values (e.g.
1054
1055
  * `o => o.companyId === input.companyId`), prefer the explicit-bindings
@@ -1180,10 +1181,10 @@ interface PredicateEntry<T> {
1180
1181
  *
1181
1182
  * ## Parameterized queries
1182
1183
  *
1183
- * All builders return `{ sql, params }` tuples. Values are passed as
1184
- * positional bind params (`?` placeholders) rather than inlined into the
1185
- * SQL string. This is safer and works naturally with the batch endpoint
1186
- * which accepts `{ sql, params }` per query.
1184
+ * All builders return `{ sql, params }` tuples. Every value is a positional
1185
+ * bind param (`?`), never inlined into the SQL string, the compiled filters'
1186
+ * included (`predicate.ts`), so a statement's shape doesn't change with its
1187
+ * values. Only identifiers (table and column names) are written into the SQL.
1187
1188
  *
1188
1189
  * ## RETURNING support
1189
1190
  *
@@ -1297,18 +1298,26 @@ interface NormalizedAggregateSpec {
1297
1298
  *
1298
1299
  * ## Execution strategy (SQL fast path vs JS fallback)
1299
1300
  *
1300
- * When a Query is executed, it attempts to compile all predicates to SQL:
1301
+ * When a Query is executed, it compiles as much of the chain to SQL as it
1302
+ * can say exactly:
1301
1303
  *
1302
- * - **Fast path**: All predicates compile → single SQL query with WHERE,
1303
- * ORDER BY, LIMIT, OFFSET. Efficient, minimal data transfer.
1304
+ * - **All of it**: every predicate compiles, and the sort is a bare field
1305
+ * (`o => o.createdAt`) or there's none → one statement with WHERE, ORDER
1306
+ * BY, LIMIT, OFFSET and the selected columns.
1304
1307
  *
1305
- * - **Fallback path**: Any predicate fails to compile → fetch ALL rows
1306
- * from the table (SELECT *), then apply the entire chain as native JS
1307
- * array operations (Array.filter, Array.sort, Array.slice, etc.).
1308
- * A warning is logged so developers can optimize if needed.
1308
+ * - **The filter, not the sort**: the predicates compile but the sort is
1309
+ * computed (`o => o.a.b`, `o => o.name.toLowerCase()`) → SQL selects the
1310
+ * matching rows, and JS sorts, skips and takes them. A limit can't go into
1311
+ * SQL without its order, so all the matching rows are read.
1309
1312
  *
1310
- * Both paths produce identical results. The SQL path is a transparent
1311
- * performance optimization.
1313
+ * - **None of it**: a predicate doesn't compile → every row is read (SELECT
1314
+ * *), and the chain runs as JS array operations.
1315
+ *
1316
+ * A warning is logged whenever JS does part of the work, so developers can
1317
+ * optimize. All three select the same rows in the same order; JS orders as
1318
+ * SQLite does (`compareAsSqlite`). Without a sortBy, the order is SQLite's
1319
+ * own: unspecified, except that `reverse()` and `last()` mean the reverse of
1320
+ * the order rows were written in (`rowid`).
1312
1321
  */
1313
1322
 
1314
1323
  type AggregateState<T> = {
@@ -1331,6 +1340,8 @@ declare class Query<T, TResult = T[]> implements PromiseLike<TResult> {
1331
1340
  private readonly _rawWhereParams;
1332
1341
  /** @internal See AggregateState — set by aggregate terminals. */
1333
1342
  private readonly _aggregate;
1343
+ /** @internal The columns `select()` named; every column when unset. */
1344
+ private readonly _columns;
1334
1345
  /** @internal Post-process transform applied after row deserialization. */
1335
1346
  readonly _postProcess: ((rows: T[]) => TResult) | undefined;
1336
1347
  constructor(config: TableConfig, options?: {
@@ -1343,6 +1354,7 @@ declare class Query<T, TResult = T[]> implements PromiseLike<TResult> {
1343
1354
  rawWhere?: string;
1344
1355
  rawWhereParams?: unknown[];
1345
1356
  aggregate?: AggregateState<T>;
1357
+ columns?: string[];
1346
1358
  });
1347
1359
  private _clone;
1348
1360
  filter(predicate: Predicate<T>): Query<T>;
@@ -1351,6 +1363,19 @@ declare class Query<T, TResult = T[]> implements PromiseLike<TResult> {
1351
1363
  reverse(): Query<T>;
1352
1364
  take(n: number): Query<T>;
1353
1365
  skip(n: number): Query<T>;
1366
+ /**
1367
+ * Return only these columns: `SELECT id, name` rather than every column of
1368
+ * a wide row. Chain it before a terminal (`first()`, `take()`); filters and
1369
+ * sorts still see the whole row.
1370
+ *
1371
+ * ```ts
1372
+ * const names = await Companies
1373
+ * .filter((c, $) => c.firmId === $.firmId, { firmId })
1374
+ * .select('id', 'name');
1375
+ * // Array<{ id: string; name: string }>
1376
+ * ```
1377
+ */
1378
+ select<K extends keyof T & string>(...columns: K[]): Query<Pick<T, K>>;
1354
1379
  first(): Query<T, T | null>;
1355
1380
  last(): Query<T, T | null>;
1356
1381
  count(): Query<T, number>;
@@ -1422,22 +1447,21 @@ declare class Query<T, TResult = T[]> implements PromiseLike<TResult> {
1422
1447
  max(accessor: Accessor<T, number>): Query<T, T | null>;
1423
1448
  groupBy<K extends string | number>(accessor: Accessor<T, K>): Query<T, Map<K, T[]>>;
1424
1449
  /**
1425
- * @internal Compile this query into a SqlQuery for batch execution.
1426
- *
1427
- * Returns the compiled SQL query (if all predicates compile to SQL),
1428
- * or null (if JS fallback is needed). In the fallback case, a bare
1429
- * `SELECT *` is returned as `fallbackQuery` so the batch can fetch
1430
- * all rows and this query can filter them in JS post-fetch.
1450
+ * @internal Compile this query into the statement to run, plus whatever
1451
+ * JS has to do with its rows (see the module header's three cases). Used by
1452
+ * db.batch() and by a standalone await alike.
1431
1453
  */
1432
1454
  _compile(): CompiledQuery<T, TResult>;
1433
1455
  /**
1434
1456
  * @internal Process raw SQL results into typed rows. Used by db.batch()
1435
- * after executing the compiled query.
1457
+ * after executing the compiled query, and by a standalone await.
1436
1458
  *
1437
- * For SQL-compiled queries: just deserialize the rows.
1438
- * For JS-fallback queries: filter, sort, and slice in JS.
1459
+ * Deserializes the rows, then does in JS whatever the SQL couldn't
1460
+ * (`inJs`): the filter, the sort, the page, the projection.
1439
1461
  */
1440
1462
  static _processResults<T, R = T[]>(result: SqlResult, compiled: CompiledQuery<T, R>): R;
1463
+ /** @internal Say that part of a query ran in JS, and why. */
1464
+ static _warnInJs<T, R>(compiled: CompiledQuery<T, R>, rowsRead?: number): void;
1441
1465
  then<TResult1 = TResult, TResult2 = never>(onfulfilled?: ((value: TResult) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
1442
1466
  private _run;
1443
1467
  /**
@@ -1451,33 +1475,32 @@ declare class Query<T, TResult = T[]> implements PromiseLike<TResult> {
1451
1475
  */
1452
1476
  private _compileAggregateSql;
1453
1477
  catch<TResult2 = never>(onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult | TResult2>;
1454
- private _execute;
1455
1478
  private _compilePredicates;
1456
- private _fetchAndFilterInJs;
1457
1479
  private _fetchAllRows;
1458
1480
  }
1459
1481
  /**
1460
- * Result of Query._compile(). Contains either a compiled SQL query
1461
- * (fast path) or a fallback SELECT * with JS processing metadata.
1482
+ * Result of Query._compile(): the statement to run, and what's left to do in
1483
+ * JS over its rows when SQL couldn't do all of it.
1462
1484
  */
1463
1485
  interface CompiledQuery<T, TResult = T[]> {
1464
1486
  type: 'query';
1465
- /** Compiled SQL query, or null if JS fallback needed. */
1466
- query: SqlQuery | null;
1467
- /** SELECT * fallback query, or null if SQL compiled. */
1468
- fallbackQuery: SqlQuery | null;
1487
+ /** The statement to run. */
1488
+ query: SqlQuery;
1469
1489
  /** Table config for deserialization. */
1470
1490
  config: TableConfig;
1471
- /** JS predicates (only for fallback). */
1472
- predicates?: PredicateEntry<T>[];
1473
- /** Sort accessor (only for fallback). */
1474
- sortAccessor?: Accessor<T>;
1475
- /** Sort direction (only for fallback). */
1476
- reversed?: boolean;
1477
- /** Limit (only for fallback). */
1478
- limit?: number;
1479
- /** Offset (only for fallback). */
1480
- offset?: number;
1491
+ /** What JS does to the statement's rows, in order, when SQL couldn't. */
1492
+ inJs?: {
1493
+ /** Why, for the warning. */
1494
+ why: string;
1495
+ /** Filters SQL couldn't run (the statement then reads every row). */
1496
+ predicates?: PredicateEntry<T>[];
1497
+ sortAccessor?: Accessor<T>;
1498
+ reversed: boolean;
1499
+ limit?: number;
1500
+ offset?: number;
1501
+ /** The columns `select()` named, kept once the rest is done. */
1502
+ columns?: string[];
1503
+ };
1481
1504
  /** Post-process transform (e.g. first() extracts [0] ?? null). */
1482
1505
  postProcess?: (rows: T[]) => TResult;
1483
1506
  /** When set, the SQL result rows ARE the answer (aggregate values, not
@@ -1510,9 +1533,12 @@ interface CompiledQuery<T, TResult = T[]> {
1510
1533
  * ## Non-batchable mutations
1511
1534
  *
1512
1535
  * Some mutations (e.g. `removeAll` with a JS-fallback predicate) require
1513
- * multi-step execution that can't be expressed as a fixed SQL batch.
1514
- * These are created via `Mutation.fromExecutor()` and work fine when
1515
- * awaited standalone, but throw if passed to `db.batch()`.
1536
+ * multi-step execution that can't be expressed as a fixed SQL batch. A
1537
+ * builder says so by returning null, and the mutation runs its `fallback`
1538
+ * instead: fine when awaited standalone, but it throws if passed to
1539
+ * `db.batch()`. Whether it can be expressed may depend on the table's
1540
+ * columns, so it's decided when the SQL is built, not when the write method
1541
+ * was called.
1516
1542
  */
1517
1543
 
1518
1544
  interface CompiledMutation<TResult> {
@@ -1524,30 +1550,20 @@ interface CompiledMutation<TResult> {
1524
1550
  declare class Mutation<TResult> implements PromiseLike<TResult> {
1525
1551
  /** @internal */
1526
1552
  private readonly _config;
1527
- /** @internal */
1553
+ /** @internal The statements, or null when the write can't be one batch. */
1528
1554
  private readonly _build;
1529
1555
  /** @internal */
1530
1556
  private readonly _processResult;
1531
- /** @internal Non-batchable executor for complex mutations (e.g. removeAll JS fallback). */
1532
- private readonly _executor;
1533
- constructor(config: TableConfig, build: () => SqlQuery[], processResult: (results: SqlResult[]) => TResult);
1534
- /**
1535
- * Create a non-batchable mutation that wraps an async executor.
1536
- * Used for operations that require multi-step execution (e.g. removeAll
1537
- * with a JS-fallback predicate: fetch all rows → filter → delete).
1538
- *
1539
- * Works fine when awaited standalone. Throws if passed to db.batch().
1540
- *
1541
- * @internal
1542
- */
1543
- static fromExecutor<T>(config: TableConfig, executor: () => Promise<T>): Mutation<T>;
1557
+ /** @internal What runs when `_build` returns null (e.g. removeAll's JS fallback). */
1558
+ private readonly _fallback;
1559
+ constructor(config: TableConfig, build: () => SqlQuery[] | null, processResult: (results: SqlResult[]) => TResult, fallback?: () => Promise<TResult>);
1544
1560
  then<T1 = TResult, T2 = never>(onfulfilled?: ((value: TResult) => T1 | PromiseLike<T1>) | null, onrejected?: ((reason: unknown) => T2 | PromiseLike<T2>) | null): Promise<T1 | T2>;
1545
1561
  catch<T2 = never>(onrejected?: ((reason: unknown) => T2 | PromiseLike<T2>) | null): Promise<TResult | T2>;
1546
1562
  /**
1547
1563
  * @internal Compile this mutation into SQL for batch execution.
1548
1564
  * Returns the queries and a result processor.
1549
1565
  *
1550
- * Throws if this is a non-batchable mutation (created via fromExecutor).
1566
+ * Throws if it can't be expressed as SQL (its builder returned null).
1551
1567
  */
1552
1568
  _compile(): CompiledMutation<TResult>;
1553
1569
  /**
@@ -1639,6 +1655,8 @@ declare class Table<T> {
1639
1655
  filter<B extends PredicateBindings>(predicate: (row: T, bindings: B) => boolean, bindings: B): Query<T>;
1640
1656
  /** Sort rows by a field. Returns a chainable Query. */
1641
1657
  sortBy(accessor: Accessor<T>): Query<T>;
1658
+ /** Every row, with only these columns. See Query.select(). */
1659
+ select<K extends keyof T & string>(...columns: K[]): Query<Pick<T, K>>;
1642
1660
  /**
1643
1661
  * Insert one or more rows. Returns the created row(s) with system fields
1644
1662
  * populated (id, createdAt, updatedAt, lastUpdatedBy).
@@ -4945,15 +4963,21 @@ declare class MindStudioAgent$1 {
4945
4963
  * can't drift between them.
4946
4964
  */
4947
4965
  private _brokeredRequest;
4966
+ /** @internal Reads started together share a round trip (`db/readBatching.ts`). */
4967
+ private readonly _dbReads;
4948
4968
  /**
4949
4969
  * @internal Execute a batch of SQL queries against a managed database.
4950
- * Used as the `executeBatch` callback for Table/Query instances.
4951
- *
4952
- * Calls `POST /_internal/v2/db/query` directly with the hook token
4953
- * (raw, no Bearer prefix). All queries run on a single SQLite connection,
4954
- * enabling RETURNING clauses and multi-statement batches.
4970
+ * Used as the `executeBatch` callback for Table/Query instances. Reads one
4971
+ * request starts in the same tick go to the platform as one batch.
4955
4972
  */
4956
4973
  private _executeDbBatch;
4974
+ /**
4975
+ * @internal Send one batch: `POST /_internal/v2/db/query` directly with the
4976
+ * hook token (raw, no Bearer prefix), or its DB WebSocket. All queries run
4977
+ * on a single SQLite connection, enabling RETURNING clauses and
4978
+ * multi-statement batches.
4979
+ */
4980
+ private _sendDbBatch;
4957
4981
  /**
4958
4982
  * @internal Sync a user's roles to the platform after a successful
4959
4983
  * auth table write. Calls POST /_internal/v2/auth/sync-user.