@mindstudio-ai/agent 0.1.10 → 0.1.12
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/cli.js +178 -47
- package/dist/index.d.ts +69 -7
- package/dist/index.js +173 -43
- package/dist/index.js.map +1 -1
- package/dist/postinstall.js +178 -47
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1523,7 +1523,15 @@ var init_sql = __esm({
|
|
|
1523
1523
|
"src/db/sql.ts"() {
|
|
1524
1524
|
"use strict";
|
|
1525
1525
|
USER_PREFIX = "@@user@@";
|
|
1526
|
-
SYSTEM_COLUMNS = /* @__PURE__ */ new Set([
|
|
1526
|
+
SYSTEM_COLUMNS = /* @__PURE__ */ new Set([
|
|
1527
|
+
"id",
|
|
1528
|
+
"created_at",
|
|
1529
|
+
"createdAt",
|
|
1530
|
+
"updated_at",
|
|
1531
|
+
"updatedAt",
|
|
1532
|
+
"last_updated_by",
|
|
1533
|
+
"lastUpdatedBy"
|
|
1534
|
+
]);
|
|
1527
1535
|
}
|
|
1528
1536
|
});
|
|
1529
1537
|
|
|
@@ -1968,8 +1976,7 @@ var init_predicate = __esm({
|
|
|
1968
1976
|
return PARSE_FAILED;
|
|
1969
1977
|
}
|
|
1970
1978
|
/**
|
|
1971
|
-
* Attempt to resolve a closure variable
|
|
1972
|
-
* with a recording Proxy and inspecting what values it compares against.
|
|
1979
|
+
* Attempt to resolve a closure variable's value.
|
|
1973
1980
|
*
|
|
1974
1981
|
* This handles the common pattern:
|
|
1975
1982
|
* ```ts
|
|
@@ -1977,40 +1984,28 @@ var init_predicate = __esm({
|
|
|
1977
1984
|
* orders.filter(o => o.requestedBy === userId)
|
|
1978
1985
|
* ```
|
|
1979
1986
|
*
|
|
1980
|
-
*
|
|
1981
|
-
*
|
|
1982
|
-
*
|
|
1983
|
-
*
|
|
1987
|
+
* Closure variable resolution is fundamentally limited in JavaScript —
|
|
1988
|
+
* we can't access another function's closure scope from outside without
|
|
1989
|
+
* `eval`. The `===` operator can't be overridden via Proxy or
|
|
1990
|
+
* Symbol.toPrimitive, so we can't intercept comparisons.
|
|
1991
|
+
*
|
|
1992
|
+
* For now, this falls back to JS execution. The predicate still works
|
|
1993
|
+
* correctly — it just scans all rows instead of generating SQL.
|
|
1994
|
+
* This is the most common reason for JS fallback in practice, since
|
|
1995
|
+
* almost every real-world filter references a variable like `userId`.
|
|
1996
|
+
*
|
|
1997
|
+
* A future improvement could accept an explicit `vars` argument:
|
|
1998
|
+
* ```ts
|
|
1999
|
+
* orders.filter(o => o.requestedBy === $userId, { $userId: auth.userId })
|
|
2000
|
+
* ```
|
|
1984
2001
|
*/
|
|
1985
2002
|
resolveClosureVariable() {
|
|
1986
|
-
|
|
1987
|
-
let closureExpr = identToken.value;
|
|
2003
|
+
this.advance();
|
|
1988
2004
|
while (this.match("dot") && this.tokens[this.pos + 1]?.type === "identifier") {
|
|
1989
2005
|
this.advance();
|
|
1990
|
-
|
|
1991
|
-
}
|
|
1992
|
-
try {
|
|
1993
|
-
const MARKER = /* @__PURE__ */ Symbol("field_access_marker");
|
|
1994
|
-
const accessed = [];
|
|
1995
|
-
const proxy = new Proxy(
|
|
1996
|
-
{},
|
|
1997
|
-
{
|
|
1998
|
-
get(_, prop) {
|
|
1999
|
-
accessed.push(prop);
|
|
2000
|
-
return new Proxy(() => MARKER, {
|
|
2001
|
-
get(_2, nestedProp) {
|
|
2002
|
-
accessed.push(nestedProp);
|
|
2003
|
-
return MARKER;
|
|
2004
|
-
}
|
|
2005
|
-
});
|
|
2006
|
-
}
|
|
2007
|
-
}
|
|
2008
|
-
);
|
|
2009
|
-
void proxy;
|
|
2010
|
-
return PARSE_FAILED;
|
|
2011
|
-
} catch {
|
|
2012
|
-
return PARSE_FAILED;
|
|
2006
|
+
this.advance();
|
|
2013
2007
|
}
|
|
2008
|
+
return PARSE_FAILED;
|
|
2014
2009
|
}
|
|
2015
2010
|
/**
|
|
2016
2011
|
* Look ahead to check if the next tokens form `.includes(`.
|
|
@@ -2169,6 +2164,76 @@ var init_query = __esm({
|
|
|
2169
2164
|
return map;
|
|
2170
2165
|
}
|
|
2171
2166
|
// -------------------------------------------------------------------------
|
|
2167
|
+
// Batch compilation — used by db.batch() to extract SQL without executing
|
|
2168
|
+
// -------------------------------------------------------------------------
|
|
2169
|
+
/**
|
|
2170
|
+
* @internal Compile this query into a SqlQuery for batch execution.
|
|
2171
|
+
*
|
|
2172
|
+
* Returns the compiled SQL query (if all predicates compile to SQL),
|
|
2173
|
+
* or null (if JS fallback is needed). In the fallback case, a bare
|
|
2174
|
+
* `SELECT *` is returned as `fallbackQuery` so the batch can fetch
|
|
2175
|
+
* all rows and this query can filter them in JS post-fetch.
|
|
2176
|
+
*/
|
|
2177
|
+
_compile() {
|
|
2178
|
+
const compiled = this._compilePredicates();
|
|
2179
|
+
const sortField = this._sortAccessor ? extractFieldName(this._sortAccessor) : void 0;
|
|
2180
|
+
if (compiled.allSql) {
|
|
2181
|
+
const query = buildSelect(this._config.tableName, {
|
|
2182
|
+
where: compiled.sqlWhere || void 0,
|
|
2183
|
+
orderBy: sortField ?? void 0,
|
|
2184
|
+
desc: this._reversed,
|
|
2185
|
+
limit: this._limit,
|
|
2186
|
+
offset: this._offset
|
|
2187
|
+
});
|
|
2188
|
+
return { query, fallbackQuery: null, config: this._config };
|
|
2189
|
+
}
|
|
2190
|
+
const fallbackQuery = buildSelect(this._config.tableName);
|
|
2191
|
+
return {
|
|
2192
|
+
query: null,
|
|
2193
|
+
fallbackQuery,
|
|
2194
|
+
config: this._config,
|
|
2195
|
+
predicates: this._predicates,
|
|
2196
|
+
sortAccessor: this._sortAccessor,
|
|
2197
|
+
reversed: this._reversed,
|
|
2198
|
+
limit: this._limit,
|
|
2199
|
+
offset: this._offset
|
|
2200
|
+
};
|
|
2201
|
+
}
|
|
2202
|
+
/**
|
|
2203
|
+
* @internal Process raw SQL results into typed rows. Used by db.batch()
|
|
2204
|
+
* after executing the compiled query.
|
|
2205
|
+
*
|
|
2206
|
+
* For SQL-compiled queries: just deserialize the rows.
|
|
2207
|
+
* For JS-fallback queries: filter, sort, and slice in JS.
|
|
2208
|
+
*/
|
|
2209
|
+
static _processResults(result, compiled) {
|
|
2210
|
+
const rows = result.rows.map(
|
|
2211
|
+
(row) => deserializeRow(
|
|
2212
|
+
row,
|
|
2213
|
+
compiled.config.columns
|
|
2214
|
+
)
|
|
2215
|
+
);
|
|
2216
|
+
if (compiled.query) return rows;
|
|
2217
|
+
let filtered = compiled.predicates ? rows.filter((row) => compiled.predicates.every((pred) => pred(row))) : rows;
|
|
2218
|
+
if (compiled.sortAccessor) {
|
|
2219
|
+
const accessor = compiled.sortAccessor;
|
|
2220
|
+
const reversed = compiled.reversed ?? false;
|
|
2221
|
+
filtered.sort((a, b) => {
|
|
2222
|
+
const aVal = accessor(a);
|
|
2223
|
+
const bVal = accessor(b);
|
|
2224
|
+
if (aVal < bVal) return reversed ? 1 : -1;
|
|
2225
|
+
if (aVal > bVal) return reversed ? -1 : 1;
|
|
2226
|
+
return 0;
|
|
2227
|
+
});
|
|
2228
|
+
}
|
|
2229
|
+
if (compiled.offset != null || compiled.limit != null) {
|
|
2230
|
+
const start = compiled.offset ?? 0;
|
|
2231
|
+
const end = compiled.limit != null ? start + compiled.limit : void 0;
|
|
2232
|
+
filtered = filtered.slice(start, end);
|
|
2233
|
+
}
|
|
2234
|
+
return filtered;
|
|
2235
|
+
}
|
|
2236
|
+
// -------------------------------------------------------------------------
|
|
2172
2237
|
// PromiseLike
|
|
2173
2238
|
// -------------------------------------------------------------------------
|
|
2174
2239
|
then(onfulfilled, onrejected) {
|
|
@@ -2418,7 +2483,49 @@ function createDb(databases, executeBatch) {
|
|
|
2418
2483
|
hours: (n) => n * 36e5,
|
|
2419
2484
|
minutes: (n) => n * 6e4,
|
|
2420
2485
|
ago: (ms) => Date.now() - ms,
|
|
2421
|
-
fromNow: (ms) => Date.now() + ms
|
|
2486
|
+
fromNow: (ms) => Date.now() + ms,
|
|
2487
|
+
// --- Batch execution ---
|
|
2488
|
+
batch: ((...queries) => {
|
|
2489
|
+
return (async () => {
|
|
2490
|
+
const compiled = queries.map((q) => {
|
|
2491
|
+
if (!(q instanceof Query)) {
|
|
2492
|
+
throw new MindStudioError(
|
|
2493
|
+
"db.batch() only accepts Query objects (from .filter(), .sortBy(), etc.)",
|
|
2494
|
+
"invalid_batch_query",
|
|
2495
|
+
400
|
|
2496
|
+
);
|
|
2497
|
+
}
|
|
2498
|
+
return q._compile();
|
|
2499
|
+
});
|
|
2500
|
+
const groups = /* @__PURE__ */ new Map();
|
|
2501
|
+
for (let i = 0; i < compiled.length; i++) {
|
|
2502
|
+
const c = compiled[i];
|
|
2503
|
+
const dbId = c.config.databaseId;
|
|
2504
|
+
const sqlQuery = c.query ?? c.fallbackQuery;
|
|
2505
|
+
if (!groups.has(dbId)) groups.set(dbId, []);
|
|
2506
|
+
groups.get(dbId).push({ index: i, sqlQuery });
|
|
2507
|
+
}
|
|
2508
|
+
const allResults = new Array(compiled.length);
|
|
2509
|
+
await Promise.all(
|
|
2510
|
+
Array.from(groups.entries()).map(async ([dbId, entries]) => {
|
|
2511
|
+
const sqlQueries = entries.map((e) => e.sqlQuery);
|
|
2512
|
+
const results = await executeBatch(dbId, sqlQueries);
|
|
2513
|
+
for (let i = 0; i < entries.length; i++) {
|
|
2514
|
+
allResults[entries[i].index] = results[i];
|
|
2515
|
+
}
|
|
2516
|
+
})
|
|
2517
|
+
);
|
|
2518
|
+
return compiled.map((c, i) => {
|
|
2519
|
+
const result = allResults[i];
|
|
2520
|
+
if (!c.query && c.predicates?.length) {
|
|
2521
|
+
console.warn(
|
|
2522
|
+
`[mindstudio] db.batch(): filter on ${c.config.tableName} could not be compiled to SQL \u2014 processing in JS`
|
|
2523
|
+
);
|
|
2524
|
+
}
|
|
2525
|
+
return Query._processResults(result, c);
|
|
2526
|
+
});
|
|
2527
|
+
})();
|
|
2528
|
+
})
|
|
2422
2529
|
};
|
|
2423
2530
|
}
|
|
2424
2531
|
function resolveTable(databases, tableName, databaseHint) {
|
|
@@ -2473,6 +2580,7 @@ var init_db = __esm({
|
|
|
2473
2580
|
"use strict";
|
|
2474
2581
|
init_errors();
|
|
2475
2582
|
init_table();
|
|
2583
|
+
init_query();
|
|
2476
2584
|
init_table();
|
|
2477
2585
|
}
|
|
2478
2586
|
});
|
|
@@ -3238,10 +3346,12 @@ var init_client = __esm({
|
|
|
3238
3346
|
);
|
|
3239
3347
|
}
|
|
3240
3348
|
if (!res.ok) {
|
|
3349
|
+
const errorBody = await res.json().catch(() => ({}));
|
|
3241
3350
|
throw new MindStudioError(
|
|
3242
|
-
`Poll request failed: ${res.status} ${res.statusText}`,
|
|
3243
|
-
"poll_error",
|
|
3244
|
-
res.status
|
|
3351
|
+
errorBody.message ?? errorBody.error ?? `Poll request failed: ${res.status} ${res.statusText}`,
|
|
3352
|
+
errorBody.code ?? "poll_error",
|
|
3353
|
+
res.status,
|
|
3354
|
+
errorBody
|
|
3245
3355
|
);
|
|
3246
3356
|
}
|
|
3247
3357
|
const poll = await res.json();
|
|
@@ -3506,12 +3616,24 @@ var init_client = __esm({
|
|
|
3506
3616
|
});
|
|
3507
3617
|
if (!res.ok) {
|
|
3508
3618
|
let message = `Database query failed: ${res.status} ${res.statusText}`;
|
|
3619
|
+
let code = "db_query_error";
|
|
3509
3620
|
try {
|
|
3510
|
-
const
|
|
3511
|
-
|
|
3621
|
+
const text = await res.text();
|
|
3622
|
+
try {
|
|
3623
|
+
const body = JSON.parse(text);
|
|
3624
|
+
const errMsg = body.error ?? body.message ?? body.details;
|
|
3625
|
+
if (errMsg) message = errMsg;
|
|
3626
|
+
if (body.code) code = body.code;
|
|
3627
|
+
} catch {
|
|
3628
|
+
if (text && text.length < 500) message = text;
|
|
3629
|
+
}
|
|
3512
3630
|
} catch {
|
|
3513
3631
|
}
|
|
3514
|
-
throw new MindStudioError(
|
|
3632
|
+
throw new MindStudioError(
|
|
3633
|
+
`[db] ${message}`,
|
|
3634
|
+
code,
|
|
3635
|
+
res.status
|
|
3636
|
+
);
|
|
3515
3637
|
}
|
|
3516
3638
|
const data = await res.json();
|
|
3517
3639
|
return data.results;
|
|
@@ -3556,7 +3678,14 @@ var init_client = __esm({
|
|
|
3556
3678
|
hours: (n) => n * 36e5,
|
|
3557
3679
|
minutes: (n) => n * 6e4,
|
|
3558
3680
|
ago: (ms) => Date.now() - ms,
|
|
3559
|
-
fromNow: (ms) => Date.now() + ms
|
|
3681
|
+
fromNow: (ms) => Date.now() + ms,
|
|
3682
|
+
// Batch needs context — hydrate first, then delegate to real db
|
|
3683
|
+
batch: ((...queries) => {
|
|
3684
|
+
return (async () => {
|
|
3685
|
+
await agent.ensureContext();
|
|
3686
|
+
return agent._db.batch(...queries);
|
|
3687
|
+
})();
|
|
3688
|
+
})
|
|
3560
3689
|
};
|
|
3561
3690
|
}
|
|
3562
3691
|
// -------------------------------------------------------------------------
|
|
@@ -3688,10 +3817,12 @@ var init_client = __esm({
|
|
|
3688
3817
|
headers: options.type ? { "Content-Type": options.type } : {}
|
|
3689
3818
|
});
|
|
3690
3819
|
if (!res.ok) {
|
|
3820
|
+
const errorBody = await res.json().catch(() => ({}));
|
|
3691
3821
|
throw new MindStudioError(
|
|
3692
|
-
`Upload failed: ${res.status} ${res.statusText}`,
|
|
3693
|
-
"upload_error",
|
|
3694
|
-
res.status
|
|
3822
|
+
errorBody.message ?? errorBody.error ?? `Upload failed: ${res.status} ${res.statusText}`,
|
|
3823
|
+
errorBody.code ?? "upload_error",
|
|
3824
|
+
res.status,
|
|
3825
|
+
errorBody
|
|
3695
3826
|
);
|
|
3696
3827
|
}
|
|
3697
3828
|
return { url: data.url };
|
|
@@ -3761,7 +3892,7 @@ async function startMcpServer(options) {
|
|
|
3761
3892
|
capabilities: { tools: {} },
|
|
3762
3893
|
serverInfo: {
|
|
3763
3894
|
name: "mindstudio-agent",
|
|
3764
|
-
version: "0.1.
|
|
3895
|
+
version: "0.1.12"
|
|
3765
3896
|
},
|
|
3766
3897
|
instructions: "Welcome to MindStudio \u2014 a platform with 200+ AI models, 850+ third-party integrations, and pre-built agents.\n\nGetting started:\n1. Call `listAgents` to verify your connection and see available agents.\n2. Call `changeName` to set your display name \u2014 use your name or whatever your user calls you. This is how you'll appear in MindStudio request logs.\n3. If you have a profile picture or icon, call `uploadFile` to upload it, then `changeProfilePicture` with the returned URL. This helps users identify your requests in their logs.\n4. Call `listActions` to discover all available actions.\n\nThen use the tools to generate text, images, video, audio, search the web, work with data sources, run agents, and more.\n\nImportant:\n- AI-powered actions (text generation, image generation, video, audio, etc.) cost money. Before running these, call `estimateActionCost` and confirm with the user before proceeding \u2014 unless they've explicitly told you to go ahead.\n- Not all agents from `listAgents` are configured for API use. Do not try to run an agent just because it appears in the list \u2014 it will likely fail. Only run agents the user specifically asks you to run."
|
|
3767
3898
|
});
|
|
@@ -4669,7 +4800,7 @@ function isNewerVersion(current, latest) {
|
|
|
4669
4800
|
return false;
|
|
4670
4801
|
}
|
|
4671
4802
|
async function checkForUpdate() {
|
|
4672
|
-
const currentVersion = "0.1.
|
|
4803
|
+
const currentVersion = "0.1.12";
|
|
4673
4804
|
if (!currentVersion) return null;
|
|
4674
4805
|
try {
|
|
4675
4806
|
const { loadConfig: loadConfig2, saveConfig: saveConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
@@ -4698,7 +4829,7 @@ async function checkForUpdate() {
|
|
|
4698
4829
|
}
|
|
4699
4830
|
}
|
|
4700
4831
|
function printUpdateNotice(latestVersion) {
|
|
4701
|
-
const currentVersion = "0.1.
|
|
4832
|
+
const currentVersion = "0.1.12";
|
|
4702
4833
|
process.stderr.write(
|
|
4703
4834
|
`
|
|
4704
4835
|
${ansi.cyanBright("Update available")} ${ansi.gray(currentVersion + " \u2192")} ${ansi.cyanBold(latestVersion)}
|
|
@@ -4773,7 +4904,7 @@ async function cmdLogin(options) {
|
|
|
4773
4904
|
process.stderr.write("\n");
|
|
4774
4905
|
printLogo();
|
|
4775
4906
|
process.stderr.write("\n");
|
|
4776
|
-
const ver = "0.1.
|
|
4907
|
+
const ver = "0.1.12";
|
|
4777
4908
|
process.stderr.write(
|
|
4778
4909
|
` ${ansi.bold("MindStudio Agent")} ${ver ? " " + ansi.gray("v" + ver) : ""}
|
|
4779
4910
|
`
|
package/dist/index.d.ts
CHANGED
|
@@ -156,9 +156,7 @@ interface UserInfoResult {
|
|
|
156
156
|
* }
|
|
157
157
|
* ```
|
|
158
158
|
*/
|
|
159
|
-
type User = string
|
|
160
|
-
readonly __brand: 'User';
|
|
161
|
-
};
|
|
159
|
+
type User = string;
|
|
162
160
|
/**
|
|
163
161
|
* Resolved display info for a platform user. Returned by `resolveUser()`
|
|
164
162
|
* and `resolveUsers()`.
|
|
@@ -537,11 +535,14 @@ declare const Roles: Record<string, string>;
|
|
|
537
535
|
* Names of columns that the platform manages automatically.
|
|
538
536
|
*
|
|
539
537
|
* - `id`: UUID primary key, generated on INSERT
|
|
540
|
-
* - `
|
|
541
|
-
* - `
|
|
542
|
-
* - `
|
|
538
|
+
* - `created_at`: unix timestamp (ms), set on INSERT
|
|
539
|
+
* - `updated_at`: unix timestamp (ms), set on INSERT and every UPDATE
|
|
540
|
+
* - `last_updated_by`: reference to the run ID that last wrote this row
|
|
541
|
+
*
|
|
542
|
+
* Both snake_case (platform convention) and camelCase (legacy) are
|
|
543
|
+
* stripped to support either naming convention in table interfaces.
|
|
543
544
|
*/
|
|
544
|
-
type SystemFields = 'id' | 'createdAt' | 'updatedAt' | 'lastUpdatedBy';
|
|
545
|
+
type SystemFields = 'id' | 'created_at' | 'createdAt' | 'updated_at' | 'updatedAt' | 'last_updated_by' | 'lastUpdatedBy';
|
|
545
546
|
/**
|
|
546
547
|
* Input type for `Table.push()`. Excludes system-managed fields.
|
|
547
548
|
* Optional fields in T remain optional.
|
|
@@ -682,12 +683,51 @@ declare class Query<T> implements PromiseLike<T[]> {
|
|
|
682
683
|
min(accessor: Accessor<T, number>): Promise<T | null>;
|
|
683
684
|
max(accessor: Accessor<T, number>): Promise<T | null>;
|
|
684
685
|
groupBy<K extends string | number>(accessor: Accessor<T, K>): Promise<Map<K, T[]>>;
|
|
686
|
+
/**
|
|
687
|
+
* @internal Compile this query into a SqlQuery for batch execution.
|
|
688
|
+
*
|
|
689
|
+
* Returns the compiled SQL query (if all predicates compile to SQL),
|
|
690
|
+
* or null (if JS fallback is needed). In the fallback case, a bare
|
|
691
|
+
* `SELECT *` is returned as `fallbackQuery` so the batch can fetch
|
|
692
|
+
* all rows and this query can filter them in JS post-fetch.
|
|
693
|
+
*/
|
|
694
|
+
_compile(): CompiledQuery<T>;
|
|
695
|
+
/**
|
|
696
|
+
* @internal Process raw SQL results into typed rows. Used by db.batch()
|
|
697
|
+
* after executing the compiled query.
|
|
698
|
+
*
|
|
699
|
+
* For SQL-compiled queries: just deserialize the rows.
|
|
700
|
+
* For JS-fallback queries: filter, sort, and slice in JS.
|
|
701
|
+
*/
|
|
702
|
+
static _processResults<T>(result: SqlResult, compiled: CompiledQuery<T>): T[];
|
|
685
703
|
then<TResult1 = T[], TResult2 = never>(onfulfilled?: ((value: T[]) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
686
704
|
private _execute;
|
|
687
705
|
private _compilePredicates;
|
|
688
706
|
private _fetchAndFilterInJs;
|
|
689
707
|
private _fetchAllRows;
|
|
690
708
|
}
|
|
709
|
+
/**
|
|
710
|
+
* Result of Query._compile(). Contains either a compiled SQL query
|
|
711
|
+
* (fast path) or a fallback SELECT * with JS processing metadata.
|
|
712
|
+
*/
|
|
713
|
+
interface CompiledQuery<T> {
|
|
714
|
+
/** Compiled SQL query, or null if JS fallback needed. */
|
|
715
|
+
query: SqlQuery | null;
|
|
716
|
+
/** SELECT * fallback query, or null if SQL compiled. */
|
|
717
|
+
fallbackQuery: SqlQuery | null;
|
|
718
|
+
/** Table config for deserialization. */
|
|
719
|
+
config: TableConfig;
|
|
720
|
+
/** JS predicates (only for fallback). */
|
|
721
|
+
predicates?: Predicate<T>[];
|
|
722
|
+
/** Sort accessor (only for fallback). */
|
|
723
|
+
sortAccessor?: Accessor<T>;
|
|
724
|
+
/** Sort direction (only for fallback). */
|
|
725
|
+
reversed?: boolean;
|
|
726
|
+
/** Limit (only for fallback). */
|
|
727
|
+
limit?: number;
|
|
728
|
+
/** Offset (only for fallback). */
|
|
729
|
+
offset?: number;
|
|
730
|
+
}
|
|
691
731
|
|
|
692
732
|
/**
|
|
693
733
|
* Table<T> — a typed persistent collection backed by SQLite.
|
|
@@ -848,6 +888,28 @@ interface Db {
|
|
|
848
888
|
ago(ms: number): number;
|
|
849
889
|
/** Returns a unix timestamp for (now + duration). Use with days/hours/minutes. */
|
|
850
890
|
fromNow(ms: number): number;
|
|
891
|
+
/**
|
|
892
|
+
* Execute multiple queries in a single round trip. All queries run on
|
|
893
|
+
* the same database connection, eliminating per-query HTTP overhead.
|
|
894
|
+
*
|
|
895
|
+
* Accepts Query objects (lazy, not yet executed). Compiles them to SQL,
|
|
896
|
+
* sends all in one batch request, and returns typed results.
|
|
897
|
+
*
|
|
898
|
+
* @example
|
|
899
|
+
* ```ts
|
|
900
|
+
* const [orders, approvals, vendors] = await db.batch(
|
|
901
|
+
* Orders.filter(o => o.status === 'active').take(10),
|
|
902
|
+
* Approvals.filter(a => a.status === 'pending').take(25),
|
|
903
|
+
* Vendors.sortBy(v => v.createdAt).reverse().take(5),
|
|
904
|
+
* );
|
|
905
|
+
* ```
|
|
906
|
+
*/
|
|
907
|
+
batch<A>(q1: PromiseLike<A>): Promise<[A]>;
|
|
908
|
+
batch<A, B>(q1: PromiseLike<A>, q2: PromiseLike<B>): Promise<[A, B]>;
|
|
909
|
+
batch<A, B, C>(q1: PromiseLike<A>, q2: PromiseLike<B>, q3: PromiseLike<C>): Promise<[A, B, C]>;
|
|
910
|
+
batch<A, B, C, D>(q1: PromiseLike<A>, q2: PromiseLike<B>, q3: PromiseLike<C>, q4: PromiseLike<D>): Promise<[A, B, C, D]>;
|
|
911
|
+
batch<A, B, C, D, E>(q1: PromiseLike<A>, q2: PromiseLike<B>, q3: PromiseLike<C>, q4: PromiseLike<D>, q5: PromiseLike<E>): Promise<[A, B, C, D, E]>;
|
|
912
|
+
batch(...queries: PromiseLike<unknown>[]): Promise<unknown[]>;
|
|
851
913
|
}
|
|
852
914
|
|
|
853
915
|
/**
|