better-convex 0.7.3 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/aggregate/index.d.ts +1 -1
- package/dist/aggregate/index.js +1 -1
- package/dist/auth/http/index.d.ts +1 -1
- package/dist/auth/index.d.ts +10 -10
- package/dist/auth/index.js +5 -5
- package/dist/auth/nextjs/index.d.ts +2 -2
- package/dist/auth/nextjs/index.js +2 -2
- package/dist/{caller-factory-4uND4vnj.js → caller-factory-CCsm4Dut.js} +2 -2
- package/dist/cli.mjs +1 -0
- package/dist/{create-schema-orm-DtuyK2RB.js → create-schema-orm-OcyA0apQ.js} +10 -13
- package/dist/crpc/index.d.ts +2 -2
- package/dist/crpc/index.js +3 -3
- package/dist/{customFunctions-C_i_0joT.js → customFunctions-RnzME_cJ.js} +1 -1
- package/dist/{http-types-BsnDV7Je.d.ts → http-types-BK7FuIcR.d.ts} +1 -1
- package/dist/id-BcBb900m.js +121 -0
- package/dist/orm/index.d.ts +4 -4
- package/dist/orm/index.js +60 -222
- package/dist/plugins/index.d.ts +9 -0
- package/dist/plugins/index.js +3 -0
- package/dist/plugins/ratelimit/index.d.ts +222 -0
- package/dist/plugins/ratelimit/index.js +846 -0
- package/dist/plugins/ratelimit/react/index.d.ts +76 -0
- package/dist/plugins/ratelimit/react/index.js +294 -0
- package/dist/{procedure-caller-Cj_lgUev.d.ts → procedure-caller-DYjpq7rG.d.ts} +2 -2
- package/dist/rsc/index.d.ts +3 -3
- package/dist/rsc/index.js +4 -4
- package/dist/runtime-C0WcYGY0.js +1028 -0
- package/dist/schema-Bx6j2doh.js +204 -0
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +4 -4
- package/dist/{runtime-B9xQFY8W.js → table-B7yzBihE.js} +3 -1088
- package/dist/text-enum-CFdcLUuw.js +30 -0
- package/dist/{types-DZFvhoPJ.d.ts → types-f53SgpBL.d.ts} +1 -1
- package/dist/{where-clause-compiler-HUa2223D.d.ts → where-clause-compiler-BIjTkVVJ.d.ts} +34 -2
- package/package.json +4 -1
- /package/dist/{create-schema-DE9ZtH8n.js → create-schema-BsN0jL5S.js} +0 -0
- /package/dist/{error-C7AOPlv2.js → error-CAGGSN5H.js} +0 -0
- /package/dist/{meta-utils-C9_6WIzj.js → meta-utils-NRyocOSc.js} +0 -0
- /package/dist/{query-context-yQVARct0.js → query-context-DEUFBhXS.js} +0 -0
- /package/dist/{query-context-BMXt2TKe.d.ts → query-context-ji7By8u0.d.ts} +0 -0
- /package/dist/{query-options-Bjo6j5cC.js → query-options-CSCmKYdJ.js} +0 -0
- /package/dist/{transformer-BsX4RWes.js → transformer-ogg-4d78.js} +0 -0
- /package/dist/{types-kgwiK-xe.d.ts → types-BTb_4BaU.d.ts} +0 -0
- /package/dist/{types-DarApWtO.d.ts → types-CM67ko7K.d.ts} +0 -0
- /package/dist/{validators-BDrWGp4M.d.ts → validators-BcQFm1oY.d.ts} +0 -0
- /package/dist/{validators-B7oIJCAp.js → validators-D_i3BK7v.js} +0 -0
|
@@ -1,42 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { v } from "convex/values";
|
|
2
2
|
|
|
3
|
-
//#region src/aggregate-core/compare.ts
|
|
4
|
-
function compareValues$1(k1, k2) {
|
|
5
|
-
return compareAsTuples(makeComparable(k1), makeComparable(k2));
|
|
6
|
-
}
|
|
7
|
-
function compareAsTuples(a, b) {
|
|
8
|
-
if (a[0] === b[0]) return compareSameTypeValues(a[1], b[1]);
|
|
9
|
-
if (a[0] < b[0]) return -1;
|
|
10
|
-
return 1;
|
|
11
|
-
}
|
|
12
|
-
function compareSameTypeValues(v1, v2) {
|
|
13
|
-
if (v1 === void 0 || v1 === null) return 0;
|
|
14
|
-
if (typeof v1 === "bigint" || typeof v1 === "number" || typeof v1 === "boolean" || typeof v1 === "string") return v1 < v2 ? -1 : v1 === v2 ? 0 : 1;
|
|
15
|
-
if (!Array.isArray(v1) || !Array.isArray(v2)) throw new Error(`Unexpected type ${v1}`);
|
|
16
|
-
for (let i = 0; i < v1.length && i < v2.length; i++) {
|
|
17
|
-
const cmp = compareAsTuples(v1[i], v2[i]);
|
|
18
|
-
if (cmp !== 0) return cmp;
|
|
19
|
-
}
|
|
20
|
-
if (v1.length < v2.length) return -1;
|
|
21
|
-
if (v1.length > v2.length) return 1;
|
|
22
|
-
return 0;
|
|
23
|
-
}
|
|
24
|
-
function makeComparable(v) {
|
|
25
|
-
if (v === void 0) return [0, void 0];
|
|
26
|
-
if (v === null) return [1, null];
|
|
27
|
-
if (typeof v === "bigint") return [2, v];
|
|
28
|
-
if (typeof v === "number") {
|
|
29
|
-
if (Number.isNaN(v)) return [3.5, 0];
|
|
30
|
-
return [3, v];
|
|
31
|
-
}
|
|
32
|
-
if (typeof v === "boolean") return [4, v];
|
|
33
|
-
if (typeof v === "string") return [5, v];
|
|
34
|
-
if (v instanceof ArrayBuffer) return [6, Array.from(new Uint8Array(v)).map(makeComparable)];
|
|
35
|
-
if (Array.isArray(v)) return [7, v.map(makeComparable)];
|
|
36
|
-
return [8, Object.keys(v).sort().map((k) => [k, v[k]]).map(makeComparable)];
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
//#endregion
|
|
40
3
|
//#region src/orm/builders/column-builder.ts
|
|
41
4
|
/**
|
|
42
5
|
* entityKind symbol for runtime type checking
|
|
@@ -167,69 +130,6 @@ var ConvexColumnBuilder = class extends ColumnBuilder {
|
|
|
167
130
|
static [entityKind] = "ConvexColumnBuilder";
|
|
168
131
|
};
|
|
169
132
|
|
|
170
|
-
//#endregion
|
|
171
|
-
//#region src/orm/builders/custom.ts
|
|
172
|
-
var ConvexCustomBuilder = class extends ConvexColumnBuilder {
|
|
173
|
-
static [entityKind] = "ConvexCustomBuilder";
|
|
174
|
-
constructor(name, validator) {
|
|
175
|
-
super(name, "any", "ConvexCustom");
|
|
176
|
-
this.config.validator = validator;
|
|
177
|
-
}
|
|
178
|
-
get convexValidator() {
|
|
179
|
-
const validator = this.config.validator;
|
|
180
|
-
if (this.config.notNull) return validator;
|
|
181
|
-
return v.optional(v.union(v.null(), validator));
|
|
182
|
-
}
|
|
183
|
-
build() {
|
|
184
|
-
return this.convexValidator;
|
|
185
|
-
}
|
|
186
|
-
};
|
|
187
|
-
function custom(a, b) {
|
|
188
|
-
if (b !== void 0) return new ConvexCustomBuilder(a, b);
|
|
189
|
-
return new ConvexCustomBuilder("", a);
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* Convenience wrapper for Convex "JSON" values.
|
|
193
|
-
*
|
|
194
|
-
* Note: This is Convex JSON (runtime `v.any()`), not SQL JSON/JSONB.
|
|
195
|
-
*/
|
|
196
|
-
function json() {
|
|
197
|
-
return custom(v.any()).$type();
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
//#endregion
|
|
201
|
-
//#region src/orm/builders/id.ts
|
|
202
|
-
/**
|
|
203
|
-
* ID column builder class
|
|
204
|
-
* Compiles to v.id(tableName) or v.optional(v.id(tableName))
|
|
205
|
-
*/
|
|
206
|
-
var ConvexIdBuilder = class extends ConvexColumnBuilder {
|
|
207
|
-
static [entityKind] = "ConvexIdBuilder";
|
|
208
|
-
constructor(name, tableName) {
|
|
209
|
-
super(name, "string", "ConvexId");
|
|
210
|
-
this.tableName = tableName;
|
|
211
|
-
this.config.referenceTable = tableName;
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* Expose Convex validator for schema integration
|
|
215
|
-
*/
|
|
216
|
-
get convexValidator() {
|
|
217
|
-
if (this.config.notNull) return v.id(this.tableName);
|
|
218
|
-
return v.optional(v.union(v.null(), v.id(this.tableName)));
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* Compile to Convex validator
|
|
222
|
-
* .notNull() → v.id(tableName)
|
|
223
|
-
* nullable → v.optional(v.id(tableName))
|
|
224
|
-
*/
|
|
225
|
-
build() {
|
|
226
|
-
return this.convexValidator;
|
|
227
|
-
}
|
|
228
|
-
};
|
|
229
|
-
function id(tableName) {
|
|
230
|
-
return new ConvexIdBuilder("", tableName);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
133
|
//#endregion
|
|
234
134
|
//#region src/orm/builders/number.ts
|
|
235
135
|
/**
|
|
@@ -631,6 +531,7 @@ const EnableRLS = Symbol.for("better-convex:EnableRLS");
|
|
|
631
531
|
const TableDeleteConfig = Symbol.for("better-convex:TableDeleteConfig");
|
|
632
532
|
const OrmSchemaOptions = Symbol.for("better-convex:OrmSchemaOptions");
|
|
633
533
|
const OrmSchemaDefinition = Symbol.for("better-convex:OrmSchemaDefinition");
|
|
534
|
+
const OrmSchemaPluginTables = Symbol.for("better-convex:OrmSchemaPluginTables");
|
|
634
535
|
|
|
635
536
|
//#endregion
|
|
636
537
|
//#region src/orm/table.ts
|
|
@@ -1291,990 +1192,4 @@ const convexTableWithRLS = (name, columns, extraConfig) => {
|
|
|
1291
1192
|
const convexTable = Object.assign(convexTableInternal, { withRLS: convexTableWithRLS });
|
|
1292
1193
|
|
|
1293
1194
|
//#endregion
|
|
1294
|
-
|
|
1295
|
-
const AGGREGATE_TREE_TABLE = "aggregate_rank_tree";
|
|
1296
|
-
const AGGREGATE_NODE_TABLE = "aggregate_rank_node";
|
|
1297
|
-
const aggregateCounterValidator = v.object({
|
|
1298
|
-
count: v.number(),
|
|
1299
|
-
sum: v.number()
|
|
1300
|
-
});
|
|
1301
|
-
const aggregateItemValidator = v.object({
|
|
1302
|
-
k: v.any(),
|
|
1303
|
-
v: v.any(),
|
|
1304
|
-
s: v.number()
|
|
1305
|
-
});
|
|
1306
|
-
const aggregateTreeTable = convexTable(AGGREGATE_TREE_TABLE, {
|
|
1307
|
-
aggregateName: text().notNull(),
|
|
1308
|
-
maxNodeSize: integer().notNull(),
|
|
1309
|
-
namespace: custom(v.any()),
|
|
1310
|
-
root: id(AGGREGATE_NODE_TABLE).notNull()
|
|
1311
|
-
}, (tree) => [index("by_namespace").on(tree.namespace), index("by_aggregate_name").on(tree.aggregateName)]);
|
|
1312
|
-
const aggregateNodeTable = convexTable(AGGREGATE_NODE_TABLE, {
|
|
1313
|
-
aggregate: custom(aggregateCounterValidator),
|
|
1314
|
-
items: custom(v.array(aggregateItemValidator)).notNull(),
|
|
1315
|
-
subtrees: custom(v.array(v.string())).notNull()
|
|
1316
|
-
});
|
|
1317
|
-
const aggregateStorageTables = {
|
|
1318
|
-
[AGGREGATE_NODE_TABLE]: aggregateNodeTable,
|
|
1319
|
-
[AGGREGATE_TREE_TABLE]: aggregateTreeTable
|
|
1320
|
-
};
|
|
1321
|
-
|
|
1322
|
-
//#endregion
|
|
1323
|
-
//#region src/aggregate-core/btree.ts
|
|
1324
|
-
const DEFAULT_MAX_NODE_SIZE = 16;
|
|
1325
|
-
const LEGACY_AGGREGATE_NAME = "__legacy__";
|
|
1326
|
-
function p(v) {
|
|
1327
|
-
try {
|
|
1328
|
-
return JSON.stringify(v);
|
|
1329
|
-
} catch {
|
|
1330
|
-
return String(v);
|
|
1331
|
-
}
|
|
1332
|
-
}
|
|
1333
|
-
function log(s) {}
|
|
1334
|
-
function aggregateNameFromNamespace(namespace) {
|
|
1335
|
-
if (Array.isArray(namespace) && namespace.length === 3 && typeof namespace[0] === "string" && (namespace[2] === 0 || namespace[2] === 1)) return namespace[0];
|
|
1336
|
-
return LEGACY_AGGREGATE_NAME;
|
|
1337
|
-
}
|
|
1338
|
-
async function insertHandler(ctx, args) {
|
|
1339
|
-
const tree = await getOrCreateTree(ctx.db, args.namespace, DEFAULT_MAX_NODE_SIZE, true);
|
|
1340
|
-
const summand = args.summand ?? 0;
|
|
1341
|
-
const pushUp = await insertIntoNode(ctx, args.namespace, tree.root, {
|
|
1342
|
-
k: args.key,
|
|
1343
|
-
v: args.value,
|
|
1344
|
-
s: summand
|
|
1345
|
-
});
|
|
1346
|
-
if (pushUp) {
|
|
1347
|
-
const total = pushUp.leftSubtreeCount && pushUp.rightSubtreeCount && add(add(pushUp.leftSubtreeCount, pushUp.rightSubtreeCount), itemAggregate(pushUp.item));
|
|
1348
|
-
const newRoot = await ctx.db.insert(AGGREGATE_NODE_TABLE, {
|
|
1349
|
-
items: [pushUp.item],
|
|
1350
|
-
subtrees: [pushUp.leftSubtree, pushUp.rightSubtree],
|
|
1351
|
-
aggregate: total
|
|
1352
|
-
});
|
|
1353
|
-
await ctx.db.patch(tree._id, { root: newRoot });
|
|
1354
|
-
}
|
|
1355
|
-
}
|
|
1356
|
-
async function deleteHandler(ctx, args) {
|
|
1357
|
-
const tree = await getOrCreateTree(ctx.db, args.namespace, DEFAULT_MAX_NODE_SIZE, true);
|
|
1358
|
-
await deleteFromNode(ctx, args.namespace, tree.root, args.key);
|
|
1359
|
-
const root = await ctx.db.get(tree.root);
|
|
1360
|
-
if (root.items.length === 0 && root.subtrees.length === 1) {
|
|
1361
|
-
log(`collapsing root ${root._id} because its only child is ${root.subtrees[0]}`);
|
|
1362
|
-
await ctx.db.patch(tree._id, { root: root.subtrees[0] });
|
|
1363
|
-
if (root.aggregate === void 0) await ctx.db.patch(root.subtrees[0], { aggregate: void 0 });
|
|
1364
|
-
await ctx.db.delete(root._id);
|
|
1365
|
-
}
|
|
1366
|
-
}
|
|
1367
|
-
async function MAX_NODE_SIZE(ctx, namespace) {
|
|
1368
|
-
return (await mustGetTree(ctx.db, namespace)).maxNodeSize;
|
|
1369
|
-
}
|
|
1370
|
-
async function MIN_NODE_SIZE(ctx, namespace) {
|
|
1371
|
-
const max = await MAX_NODE_SIZE(ctx, namespace);
|
|
1372
|
-
if (max % 2 !== 0 || max < 4) throw new Error("MAX_NODE_SIZE must be even and at least 4");
|
|
1373
|
-
return max / 2;
|
|
1374
|
-
}
|
|
1375
|
-
async function aggregateBetweenHandler(ctx, args) {
|
|
1376
|
-
const tree = await getTree(ctx.db, args.namespace);
|
|
1377
|
-
if (tree === null) return {
|
|
1378
|
-
count: 0,
|
|
1379
|
-
sum: 0
|
|
1380
|
-
};
|
|
1381
|
-
return await aggregateBetweenInNode(ctx.db, tree.root, args.k1, args.k2);
|
|
1382
|
-
}
|
|
1383
|
-
async function filterBetween(db, node, k1, k2) {
|
|
1384
|
-
const n = await db.get(node);
|
|
1385
|
-
const included = [];
|
|
1386
|
-
function includeSubtree(i, unboundedRight) {
|
|
1387
|
-
const unboundedLeft = k1 === void 0 || included.length > 0;
|
|
1388
|
-
if (unboundedLeft && unboundedRight) included.push({
|
|
1389
|
-
type: "subtree",
|
|
1390
|
-
subtree: n.subtrees[i]
|
|
1391
|
-
});
|
|
1392
|
-
else included.push(filterBetween(db, n.subtrees[i], unboundedLeft ? void 0 : k1, unboundedRight ? void 0 : k2));
|
|
1393
|
-
}
|
|
1394
|
-
let done = false;
|
|
1395
|
-
for (let i = 0; i < n.items.length; i++) {
|
|
1396
|
-
const k1IsLeft = k1 === void 0 || compareKeys(k1, n.items[i].k) === -1;
|
|
1397
|
-
const k2IsRight = k2 === void 0 || compareKeys(k2, n.items[i].k) === 1;
|
|
1398
|
-
if (k1IsLeft && n.subtrees.length > 0) includeSubtree(i, k2IsRight);
|
|
1399
|
-
if (!k2IsRight) {
|
|
1400
|
-
done = true;
|
|
1401
|
-
break;
|
|
1402
|
-
}
|
|
1403
|
-
if (k1IsLeft) included.push({
|
|
1404
|
-
type: "item",
|
|
1405
|
-
item: n.items[i]
|
|
1406
|
-
});
|
|
1407
|
-
}
|
|
1408
|
-
if (!done && n.subtrees.length > 0) includeSubtree(n.subtrees.length - 1, k2 === void 0);
|
|
1409
|
-
return (await Promise.all(included)).flat(1);
|
|
1410
|
-
}
|
|
1411
|
-
async function aggregateBetweenInNode(db, node, k1, k2) {
|
|
1412
|
-
const filtered = await filterBetween(db, node, k1, k2);
|
|
1413
|
-
const counts = await Promise.all(filtered.map(async (included) => {
|
|
1414
|
-
if (included.type === "item") return itemAggregate(included.item);
|
|
1415
|
-
return await nodeAggregate(db, await db.get(included.subtree));
|
|
1416
|
-
}));
|
|
1417
|
-
let count = {
|
|
1418
|
-
count: 0,
|
|
1419
|
-
sum: 0
|
|
1420
|
-
};
|
|
1421
|
-
for (const c of counts) count = add(count, c);
|
|
1422
|
-
return count;
|
|
1423
|
-
}
|
|
1424
|
-
async function atOffsetHandler(ctx, args) {
|
|
1425
|
-
if (args.offset < 0) throw new Error("offset must be non-negative");
|
|
1426
|
-
if (!Number.isInteger(args.offset)) throw new Error("offset must be an integer");
|
|
1427
|
-
const tree = await getTree(ctx.db, args.namespace);
|
|
1428
|
-
if (tree === null) throw new ConvexError("tree is empty");
|
|
1429
|
-
return await atOffsetInNode(ctx.db, tree.root, args.offset, args.k1, args.k2);
|
|
1430
|
-
}
|
|
1431
|
-
async function atNegativeOffsetHandler(ctx, args) {
|
|
1432
|
-
if (args.offset < 0) throw new Error("offset must be non-negative");
|
|
1433
|
-
if (!Number.isInteger(args.offset)) throw new Error("offset must be an integer");
|
|
1434
|
-
const tree = await getTree(ctx.db, args.namespace);
|
|
1435
|
-
if (tree === null) throw new ConvexError("tree is empty");
|
|
1436
|
-
return await negativeOffsetInNode(ctx.db, tree.root, args.offset, args.k1, args.k2);
|
|
1437
|
-
}
|
|
1438
|
-
async function offsetHandler(ctx, args) {
|
|
1439
|
-
return (await aggregateBetweenHandler(ctx, {
|
|
1440
|
-
k1: args.k1,
|
|
1441
|
-
k2: args.key,
|
|
1442
|
-
namespace: args.namespace
|
|
1443
|
-
})).count;
|
|
1444
|
-
}
|
|
1445
|
-
async function offsetUntilHandler(ctx, args) {
|
|
1446
|
-
return (await aggregateBetweenHandler(ctx, {
|
|
1447
|
-
k1: args.key,
|
|
1448
|
-
k2: args.k2,
|
|
1449
|
-
namespace: args.namespace
|
|
1450
|
-
})).count;
|
|
1451
|
-
}
|
|
1452
|
-
async function deleteFromNode(ctx, namespace, node, key) {
|
|
1453
|
-
let n = await ctx.db.get(node);
|
|
1454
|
-
let foundItem = null;
|
|
1455
|
-
let i = 0;
|
|
1456
|
-
for (; i < n.items.length; i++) {
|
|
1457
|
-
const compare = compareKeys(key, n.items[i].k);
|
|
1458
|
-
if (compare === -1) break;
|
|
1459
|
-
if (compare === 0) {
|
|
1460
|
-
log(`found key ${p(key)} in node ${n._id}`);
|
|
1461
|
-
if (n.subtrees.length === 0) {
|
|
1462
|
-
await ctx.db.patch(node, {
|
|
1463
|
-
items: [...n.items.slice(0, i), ...n.items.slice(i + 1)],
|
|
1464
|
-
aggregate: n.aggregate && sub(n.aggregate, itemAggregate(n.items[i]))
|
|
1465
|
-
});
|
|
1466
|
-
return n.items[i];
|
|
1467
|
-
}
|
|
1468
|
-
const predecessor = await negativeOffsetInNode(ctx.db, n.subtrees[i], 0);
|
|
1469
|
-
log(`replacing ${p(key)} with predecessor ${p(predecessor.k)}`);
|
|
1470
|
-
foundItem = n.items[i];
|
|
1471
|
-
await ctx.db.patch(node, {
|
|
1472
|
-
items: [
|
|
1473
|
-
...n.items.slice(0, i),
|
|
1474
|
-
predecessor,
|
|
1475
|
-
...n.items.slice(i + 1)
|
|
1476
|
-
],
|
|
1477
|
-
aggregate: n.aggregate && sub(add(n.aggregate, itemAggregate(predecessor)), itemAggregate(n.items[i]))
|
|
1478
|
-
});
|
|
1479
|
-
n = await ctx.db.get(node);
|
|
1480
|
-
key = predecessor.k;
|
|
1481
|
-
break;
|
|
1482
|
-
}
|
|
1483
|
-
}
|
|
1484
|
-
if (n.subtrees.length === 0) throw new ConvexError({
|
|
1485
|
-
code: "DELETE_MISSING_KEY",
|
|
1486
|
-
message: `key ${p(key)} not found in node ${n._id}`
|
|
1487
|
-
});
|
|
1488
|
-
const deleted = await deleteFromNode(ctx, namespace, n.subtrees[i], key);
|
|
1489
|
-
if (!deleted) return null;
|
|
1490
|
-
if (!foundItem) foundItem = deleted;
|
|
1491
|
-
const newAggregate = n.aggregate && sub(n.aggregate, itemAggregate(deleted));
|
|
1492
|
-
if (newAggregate) await ctx.db.patch(node, { aggregate: newAggregate });
|
|
1493
|
-
const deficientSubtree = await ctx.db.get(n.subtrees[i]);
|
|
1494
|
-
const minNodeSize = await MIN_NODE_SIZE(ctx, namespace);
|
|
1495
|
-
if (deficientSubtree.items.length < minNodeSize) {
|
|
1496
|
-
log(`deficient subtree ${deficientSubtree._id}`);
|
|
1497
|
-
if (i > 0) {
|
|
1498
|
-
const leftSibling = await ctx.db.get(n.subtrees[i - 1]);
|
|
1499
|
-
if (leftSibling.items.length > minNodeSize) {
|
|
1500
|
-
log(`rotating right with left sibling ${leftSibling._id}`);
|
|
1501
|
-
const grandchild = leftSibling.subtrees.length ? await ctx.db.get(leftSibling.subtrees[leftSibling.subtrees.length - 1]) : null;
|
|
1502
|
-
const grandchildCount = grandchild ? grandchild.aggregate : {
|
|
1503
|
-
count: 0,
|
|
1504
|
-
sum: 0
|
|
1505
|
-
};
|
|
1506
|
-
await ctx.db.patch(deficientSubtree._id, {
|
|
1507
|
-
items: [n.items[i - 1], ...deficientSubtree.items],
|
|
1508
|
-
subtrees: grandchild ? [grandchild._id, ...deficientSubtree.subtrees] : [],
|
|
1509
|
-
aggregate: deficientSubtree.aggregate && grandchildCount && add(add(deficientSubtree.aggregate, grandchildCount), itemAggregate(n.items[i - 1]))
|
|
1510
|
-
});
|
|
1511
|
-
await ctx.db.patch(leftSibling._id, {
|
|
1512
|
-
items: leftSibling.items.slice(0, leftSibling.items.length - 1),
|
|
1513
|
-
subtrees: grandchild ? leftSibling.subtrees.slice(0, leftSibling.subtrees.length - 1) : [],
|
|
1514
|
-
aggregate: leftSibling.aggregate && grandchildCount && sub(sub(leftSibling.aggregate, grandchildCount), itemAggregate(leftSibling.items[leftSibling.items.length - 1]))
|
|
1515
|
-
});
|
|
1516
|
-
await ctx.db.patch(node, { items: [
|
|
1517
|
-
...n.items.slice(0, i - 1),
|
|
1518
|
-
leftSibling.items[leftSibling.items.length - 1],
|
|
1519
|
-
...n.items.slice(i)
|
|
1520
|
-
] });
|
|
1521
|
-
return foundItem;
|
|
1522
|
-
}
|
|
1523
|
-
}
|
|
1524
|
-
if (i < n.subtrees.length - 1) {
|
|
1525
|
-
const rightSibling = await ctx.db.get(n.subtrees[i + 1]);
|
|
1526
|
-
if (rightSibling.items.length > minNodeSize) {
|
|
1527
|
-
log(`rotating left with right sibling ${rightSibling._id}`);
|
|
1528
|
-
const grandchild = rightSibling.subtrees.length ? await ctx.db.get(rightSibling.subtrees[0]) : null;
|
|
1529
|
-
const grandchildCount = grandchild ? grandchild.aggregate : {
|
|
1530
|
-
count: 0,
|
|
1531
|
-
sum: 0
|
|
1532
|
-
};
|
|
1533
|
-
await ctx.db.patch(deficientSubtree._id, {
|
|
1534
|
-
items: [...deficientSubtree.items, n.items[i]],
|
|
1535
|
-
subtrees: grandchild ? [...deficientSubtree.subtrees, grandchild._id] : [],
|
|
1536
|
-
aggregate: deficientSubtree.aggregate && grandchildCount && add(add(deficientSubtree.aggregate, grandchildCount), itemAggregate(n.items[i]))
|
|
1537
|
-
});
|
|
1538
|
-
await ctx.db.patch(rightSibling._id, {
|
|
1539
|
-
items: rightSibling.items.slice(1),
|
|
1540
|
-
subtrees: grandchild ? rightSibling.subtrees.slice(1) : [],
|
|
1541
|
-
aggregate: rightSibling.aggregate && grandchildCount && sub(sub(rightSibling.aggregate, grandchildCount), itemAggregate(rightSibling.items[0]))
|
|
1542
|
-
});
|
|
1543
|
-
await ctx.db.patch(node, { items: [
|
|
1544
|
-
...n.items.slice(0, i),
|
|
1545
|
-
rightSibling.items[0],
|
|
1546
|
-
...n.items.slice(i + 1)
|
|
1547
|
-
] });
|
|
1548
|
-
return foundItem;
|
|
1549
|
-
}
|
|
1550
|
-
}
|
|
1551
|
-
if (i > 0) {
|
|
1552
|
-
log("merging with left sibling");
|
|
1553
|
-
await mergeNodes(ctx.db, n, i - 1);
|
|
1554
|
-
} else {
|
|
1555
|
-
log("merging with right sibling");
|
|
1556
|
-
await mergeNodes(ctx.db, n, i);
|
|
1557
|
-
}
|
|
1558
|
-
}
|
|
1559
|
-
return foundItem;
|
|
1560
|
-
}
|
|
1561
|
-
async function mergeNodes(db, parent, leftIndex) {
|
|
1562
|
-
const left = await db.get(parent.subtrees[leftIndex]);
|
|
1563
|
-
const right = await db.get(parent.subtrees[leftIndex + 1]);
|
|
1564
|
-
log(`merging ${right._id} into ${left._id}`);
|
|
1565
|
-
await db.patch(left._id, {
|
|
1566
|
-
items: [
|
|
1567
|
-
...left.items,
|
|
1568
|
-
parent.items[leftIndex],
|
|
1569
|
-
...right.items
|
|
1570
|
-
],
|
|
1571
|
-
subtrees: [...left.subtrees, ...right.subtrees],
|
|
1572
|
-
aggregate: left.aggregate && right.aggregate && add(add(left.aggregate, right.aggregate), itemAggregate(parent.items[leftIndex]))
|
|
1573
|
-
});
|
|
1574
|
-
await db.patch(parent._id, {
|
|
1575
|
-
items: [...parent.items.slice(0, leftIndex), ...parent.items.slice(leftIndex + 1)],
|
|
1576
|
-
subtrees: [...parent.subtrees.slice(0, leftIndex + 1), ...parent.subtrees.slice(leftIndex + 2)]
|
|
1577
|
-
});
|
|
1578
|
-
await db.delete(right._id);
|
|
1579
|
-
}
|
|
1580
|
-
async function negativeOffsetInNode(db, node, index, k1, k2) {
|
|
1581
|
-
const filtered = await filterBetween(db, node, k1, k2);
|
|
1582
|
-
for (const included of filtered.reverse()) if (included.type === "item") {
|
|
1583
|
-
if (index === 0) return included.item;
|
|
1584
|
-
index -= 1;
|
|
1585
|
-
} else {
|
|
1586
|
-
const subtreeCount = (await nodeAggregate(db, await db.get(included.subtree))).count;
|
|
1587
|
-
if (index < subtreeCount) return await negativeOffsetInNode(db, included.subtree, index);
|
|
1588
|
-
index -= subtreeCount;
|
|
1589
|
-
}
|
|
1590
|
-
throw new ConvexError(`negative offset exceeded count by ${index} (in node ${node})`);
|
|
1591
|
-
}
|
|
1592
|
-
async function atOffsetInNode(db, node, index, k1, k2) {
|
|
1593
|
-
const filtered = await filterBetween(db, node, k1, k2);
|
|
1594
|
-
for (const included of filtered) if (included.type === "item") {
|
|
1595
|
-
if (index === 0) return included.item;
|
|
1596
|
-
index -= 1;
|
|
1597
|
-
} else {
|
|
1598
|
-
const subtreeCount = (await nodeAggregate(db, await db.get(included.subtree))).count;
|
|
1599
|
-
if (index < subtreeCount) return await atOffsetInNode(db, included.subtree, index);
|
|
1600
|
-
index -= subtreeCount;
|
|
1601
|
-
}
|
|
1602
|
-
throw new ConvexError(`offset exceeded count by ${index} (in node ${node})`);
|
|
1603
|
-
}
|
|
1604
|
-
function itemAggregate(item) {
|
|
1605
|
-
return {
|
|
1606
|
-
count: 1,
|
|
1607
|
-
sum: item.s
|
|
1608
|
-
};
|
|
1609
|
-
}
|
|
1610
|
-
function nodeCounts(node) {
|
|
1611
|
-
return node.items.map(itemAggregate);
|
|
1612
|
-
}
|
|
1613
|
-
async function subtreeCounts(db, node) {
|
|
1614
|
-
return await Promise.all(node.subtrees.map(async (subtree) => {
|
|
1615
|
-
return nodeAggregate(db, await db.get(subtree));
|
|
1616
|
-
}));
|
|
1617
|
-
}
|
|
1618
|
-
async function nodeAggregate(db, node) {
|
|
1619
|
-
if (node.aggregate !== void 0) return node.aggregate;
|
|
1620
|
-
const subCounts = await subtreeCounts(db, node);
|
|
1621
|
-
return add(accumulate(nodeCounts(node)), accumulate(subCounts));
|
|
1622
|
-
}
|
|
1623
|
-
function add(a, b) {
|
|
1624
|
-
return {
|
|
1625
|
-
count: a.count + b.count,
|
|
1626
|
-
sum: a.sum + b.sum
|
|
1627
|
-
};
|
|
1628
|
-
}
|
|
1629
|
-
function sub(a, b) {
|
|
1630
|
-
return {
|
|
1631
|
-
count: a.count - b.count,
|
|
1632
|
-
sum: a.sum - b.sum
|
|
1633
|
-
};
|
|
1634
|
-
}
|
|
1635
|
-
function accumulate(nums) {
|
|
1636
|
-
return nums.reduce(add, {
|
|
1637
|
-
count: 0,
|
|
1638
|
-
sum: 0
|
|
1639
|
-
});
|
|
1640
|
-
}
|
|
1641
|
-
async function insertIntoNode(ctx, namespace, node, item) {
|
|
1642
|
-
const n = await ctx.db.get(node);
|
|
1643
|
-
let i = 0;
|
|
1644
|
-
for (; i < n.items.length; i++) {
|
|
1645
|
-
const compare = compareKeys(item.k, n.items[i].k);
|
|
1646
|
-
if (compare === -1) break;
|
|
1647
|
-
if (compare === 0) throw new ConvexError(`key ${p(item.k)} already exists in node ${n._id}`);
|
|
1648
|
-
}
|
|
1649
|
-
if (n.subtrees.length > 0) {
|
|
1650
|
-
const pushUp = await insertIntoNode(ctx, namespace, n.subtrees[i], item);
|
|
1651
|
-
if (pushUp) await ctx.db.patch(node, {
|
|
1652
|
-
items: [
|
|
1653
|
-
...n.items.slice(0, i),
|
|
1654
|
-
pushUp.item,
|
|
1655
|
-
...n.items.slice(i)
|
|
1656
|
-
],
|
|
1657
|
-
subtrees: [
|
|
1658
|
-
...n.subtrees.slice(0, i),
|
|
1659
|
-
pushUp.leftSubtree,
|
|
1660
|
-
pushUp.rightSubtree,
|
|
1661
|
-
...n.subtrees.slice(i + 1)
|
|
1662
|
-
]
|
|
1663
|
-
});
|
|
1664
|
-
} else await ctx.db.patch(node, { items: [
|
|
1665
|
-
...n.items.slice(0, i),
|
|
1666
|
-
item,
|
|
1667
|
-
...n.items.slice(i)
|
|
1668
|
-
] });
|
|
1669
|
-
const newAggregate = n.aggregate && add(n.aggregate, itemAggregate(item));
|
|
1670
|
-
if (newAggregate) await ctx.db.patch(node, { aggregate: newAggregate });
|
|
1671
|
-
const newN = await ctx.db.get(node);
|
|
1672
|
-
const maxNodeSize = await MAX_NODE_SIZE(ctx, namespace);
|
|
1673
|
-
const minNodeSize = await MIN_NODE_SIZE(ctx, namespace);
|
|
1674
|
-
if (newN.items.length > maxNodeSize) {
|
|
1675
|
-
if (newN.items.length !== maxNodeSize + 1 || newN.items.length !== 2 * minNodeSize + 1) throw new Error(`bad ${newN.items.length}`);
|
|
1676
|
-
log(`splitting node ${newN._id} at ${newN.items[minNodeSize].k}`);
|
|
1677
|
-
const topLevel = nodeCounts(newN);
|
|
1678
|
-
const subCounts = await subtreeCounts(ctx.db, newN);
|
|
1679
|
-
const leftCount = add(accumulate(topLevel.slice(0, minNodeSize)), accumulate(subCounts.length ? subCounts.slice(0, minNodeSize + 1) : []));
|
|
1680
|
-
const rightCount = add(accumulate(topLevel.slice(minNodeSize + 1)), accumulate(subCounts.length ? subCounts.slice(minNodeSize + 1) : []));
|
|
1681
|
-
if (newN.aggregate && leftCount.count + rightCount.count + 1 !== newN.aggregate.count) throw new Error(`bad count split ${leftCount.count} ${rightCount.count} ${newN.aggregate.count}`);
|
|
1682
|
-
if (newN.aggregate && Math.abs(leftCount.sum + rightCount.sum + newN.items[minNodeSize].s - newN.aggregate.sum) > 1e-5) throw new Error(`bad sum split ${leftCount.sum} ${rightCount.sum} ${newN.items[minNodeSize].s} ${newN.aggregate.sum}`);
|
|
1683
|
-
await ctx.db.patch(node, {
|
|
1684
|
-
items: newN.items.slice(0, minNodeSize),
|
|
1685
|
-
subtrees: newN.subtrees.length ? newN.subtrees.slice(0, minNodeSize + 1) : [],
|
|
1686
|
-
aggregate: leftCount
|
|
1687
|
-
});
|
|
1688
|
-
const splitN = await ctx.db.insert(AGGREGATE_NODE_TABLE, {
|
|
1689
|
-
items: newN.items.slice(minNodeSize + 1),
|
|
1690
|
-
subtrees: newN.subtrees.length ? newN.subtrees.slice(minNodeSize + 1) : [],
|
|
1691
|
-
aggregate: rightCount
|
|
1692
|
-
});
|
|
1693
|
-
return {
|
|
1694
|
-
item: newN.items[minNodeSize],
|
|
1695
|
-
leftSubtree: node,
|
|
1696
|
-
rightSubtree: splitN,
|
|
1697
|
-
leftSubtreeCount: newN.aggregate && leftCount,
|
|
1698
|
-
rightSubtreeCount: newN.aggregate && rightCount
|
|
1699
|
-
};
|
|
1700
|
-
}
|
|
1701
|
-
return null;
|
|
1702
|
-
}
|
|
1703
|
-
function compareKeys(k1, k2) {
|
|
1704
|
-
return compareValues$1(k1, k2);
|
|
1705
|
-
}
|
|
1706
|
-
async function getTree(db, namespace) {
|
|
1707
|
-
return await db.query(AGGREGATE_TREE_TABLE).withIndex("by_namespace", (q) => q.eq("namespace", namespace)).unique();
|
|
1708
|
-
}
|
|
1709
|
-
async function mustGetTree(db, namespace) {
|
|
1710
|
-
const tree = await getTree(db, namespace);
|
|
1711
|
-
if (!tree) throw new Error("btree not initialized");
|
|
1712
|
-
return tree;
|
|
1713
|
-
}
|
|
1714
|
-
async function getOrCreateTree(db, namespace, maxNodeSize, rootLazy) {
|
|
1715
|
-
const originalTree = await getTree(db, namespace);
|
|
1716
|
-
const aggregateName = aggregateNameFromNamespace(namespace);
|
|
1717
|
-
if (originalTree) {
|
|
1718
|
-
if (originalTree.aggregateName !== aggregateName) {
|
|
1719
|
-
await db.patch(originalTree._id, { aggregateName });
|
|
1720
|
-
return {
|
|
1721
|
-
...originalTree,
|
|
1722
|
-
aggregateName
|
|
1723
|
-
};
|
|
1724
|
-
}
|
|
1725
|
-
return originalTree;
|
|
1726
|
-
}
|
|
1727
|
-
const root = await db.insert(AGGREGATE_NODE_TABLE, {
|
|
1728
|
-
items: [],
|
|
1729
|
-
subtrees: [],
|
|
1730
|
-
aggregate: {
|
|
1731
|
-
count: 0,
|
|
1732
|
-
sum: 0
|
|
1733
|
-
}
|
|
1734
|
-
});
|
|
1735
|
-
const effectiveMaxNodeSize = maxNodeSize ?? await MAX_NODE_SIZE({ db }, void 0) ?? DEFAULT_MAX_NODE_SIZE;
|
|
1736
|
-
const effectiveRootLazy = rootLazy ?? await isRootLazy(db, void 0) ?? true;
|
|
1737
|
-
const id = await db.insert(AGGREGATE_TREE_TABLE, {
|
|
1738
|
-
aggregateName,
|
|
1739
|
-
root,
|
|
1740
|
-
maxNodeSize: effectiveMaxNodeSize,
|
|
1741
|
-
namespace
|
|
1742
|
-
});
|
|
1743
|
-
const newTree = await db.get(id);
|
|
1744
|
-
await MIN_NODE_SIZE({ db }, namespace);
|
|
1745
|
-
if (effectiveRootLazy) await db.patch(root, { aggregate: void 0 });
|
|
1746
|
-
return newTree;
|
|
1747
|
-
}
|
|
1748
|
-
async function isRootLazy(db, namespace) {
|
|
1749
|
-
const tree = await getTree(db, namespace);
|
|
1750
|
-
if (!tree) return true;
|
|
1751
|
-
return (await db.get(tree.root))?.aggregate === void 0;
|
|
1752
|
-
}
|
|
1753
|
-
async function deleteTreeNodes(db, node) {
|
|
1754
|
-
const current = await db.get(node);
|
|
1755
|
-
if (!current) return;
|
|
1756
|
-
for (const subtree of current.subtrees) await deleteTreeNodes(db, subtree);
|
|
1757
|
-
await db.delete(node);
|
|
1758
|
-
}
|
|
1759
|
-
async function clearTree(db, args) {
|
|
1760
|
-
const tree = await getTree(db, args.namespace);
|
|
1761
|
-
let existingRootLazy = true;
|
|
1762
|
-
let existingMaxNodeSize = DEFAULT_MAX_NODE_SIZE;
|
|
1763
|
-
if (tree) {
|
|
1764
|
-
await db.delete(tree._id);
|
|
1765
|
-
const root = await db.get(tree.root);
|
|
1766
|
-
if (root) {
|
|
1767
|
-
existingRootLazy = root.aggregate === void 0;
|
|
1768
|
-
await deleteTreeNodes(db, tree.root);
|
|
1769
|
-
}
|
|
1770
|
-
existingMaxNodeSize = tree.maxNodeSize;
|
|
1771
|
-
}
|
|
1772
|
-
await getOrCreateTree(db, args.namespace, args.maxNodeSize ?? existingMaxNodeSize, args.rootLazy ?? existingRootLazy);
|
|
1773
|
-
}
|
|
1774
|
-
async function paginateHandler(ctx, args) {
|
|
1775
|
-
const tree = await getTree(ctx.db, args.namespace);
|
|
1776
|
-
if (tree === null) return {
|
|
1777
|
-
page: [],
|
|
1778
|
-
cursor: "",
|
|
1779
|
-
isDone: true
|
|
1780
|
-
};
|
|
1781
|
-
return await paginateInNode(ctx.db, tree.root, args.limit, args.order, args.cursor, args.k1, args.k2);
|
|
1782
|
-
}
|
|
1783
|
-
async function paginateInNode(db, node, limit, order, cursor, k1, k2) {
|
|
1784
|
-
if (limit <= 0) throw new ConvexError("limit must be positive");
|
|
1785
|
-
if (cursor !== void 0 && cursor.length === 0) return {
|
|
1786
|
-
page: [],
|
|
1787
|
-
cursor: "",
|
|
1788
|
-
isDone: true
|
|
1789
|
-
};
|
|
1790
|
-
const items = [];
|
|
1791
|
-
const filtered = await filterBetween(db, node, cursor === void 0 || order === "desc" ? k1 : jsonToConvex(JSON.parse(cursor)), cursor === void 0 || order === "asc" ? k2 : jsonToConvex(JSON.parse(cursor)));
|
|
1792
|
-
if (order === "desc") filtered.reverse();
|
|
1793
|
-
for (const included of filtered) {
|
|
1794
|
-
if (items.length >= limit) return {
|
|
1795
|
-
page: items,
|
|
1796
|
-
cursor: JSON.stringify(convexToJson(items[items.length - 1].k)),
|
|
1797
|
-
isDone: false
|
|
1798
|
-
};
|
|
1799
|
-
if (included.type === "item") items.push(included.item);
|
|
1800
|
-
else {
|
|
1801
|
-
const { page, cursor: newCursor, isDone } = await paginateInNode(db, included.subtree, limit - items.length, order);
|
|
1802
|
-
items.push(...page);
|
|
1803
|
-
if (!isDone) return {
|
|
1804
|
-
page: items,
|
|
1805
|
-
cursor: newCursor,
|
|
1806
|
-
isDone: false
|
|
1807
|
-
};
|
|
1808
|
-
}
|
|
1809
|
-
}
|
|
1810
|
-
return {
|
|
1811
|
-
page: items,
|
|
1812
|
-
cursor: "",
|
|
1813
|
-
isDone: true
|
|
1814
|
-
};
|
|
1815
|
-
}
|
|
1816
|
-
async function paginateNamespacesHandler(ctx, args) {
|
|
1817
|
-
if (args.cursor === "endcursor") return {
|
|
1818
|
-
page: [],
|
|
1819
|
-
cursor: "endcursor",
|
|
1820
|
-
isDone: true
|
|
1821
|
-
};
|
|
1822
|
-
const { page: trees, continueCursor, isDone } = await (args.aggregateName === void 0 ? ctx.db.query(AGGREGATE_TREE_TABLE) : ctx.db.query(AGGREGATE_TREE_TABLE).withIndex("by_aggregate_name", (q) => q.eq("aggregateName", args.aggregateName))).paginate({
|
|
1823
|
-
cursor: args.cursor ?? null,
|
|
1824
|
-
numItems: args.limit
|
|
1825
|
-
});
|
|
1826
|
-
return {
|
|
1827
|
-
page: trees.map((t) => t.namespace ?? null),
|
|
1828
|
-
cursor: isDone ? "endcursor" : continueCursor ?? "endcursor",
|
|
1829
|
-
isDone
|
|
1830
|
-
};
|
|
1831
|
-
}
|
|
1832
|
-
async function aggregateBetweenBatchHandler(ctx, args) {
|
|
1833
|
-
return await Promise.all(args.queries.map((query) => aggregateBetweenHandler(ctx, query)));
|
|
1834
|
-
}
|
|
1835
|
-
async function atOffsetBatchHandler(ctx, args) {
|
|
1836
|
-
return await Promise.all(args.queries.map((query) => query.offset >= 0 ? atOffsetHandler(ctx, query) : atNegativeOffsetHandler(ctx, {
|
|
1837
|
-
...query,
|
|
1838
|
-
offset: -query.offset - 1
|
|
1839
|
-
})));
|
|
1840
|
-
}
|
|
1841
|
-
|
|
1842
|
-
//#endregion
|
|
1843
|
-
//#region src/aggregate-core/positions.ts
|
|
1844
|
-
const BEFORE_ALL_IDS = null;
|
|
1845
|
-
const AFTER_ALL_IDS = [];
|
|
1846
|
-
function explodeKey(key) {
|
|
1847
|
-
if (Array.isArray(key)) {
|
|
1848
|
-
const exploded = [""];
|
|
1849
|
-
for (const item of key) {
|
|
1850
|
-
exploded.push(item);
|
|
1851
|
-
exploded.push("");
|
|
1852
|
-
}
|
|
1853
|
-
return exploded;
|
|
1854
|
-
}
|
|
1855
|
-
return key;
|
|
1856
|
-
}
|
|
1857
|
-
function implodeKey(k) {
|
|
1858
|
-
if (Array.isArray(k)) {
|
|
1859
|
-
const imploded = [];
|
|
1860
|
-
for (let i = 1; i < k.length; i += 2) imploded.push(k[i]);
|
|
1861
|
-
return imploded;
|
|
1862
|
-
}
|
|
1863
|
-
return k;
|
|
1864
|
-
}
|
|
1865
|
-
function keyToPosition(key, id) {
|
|
1866
|
-
return [
|
|
1867
|
-
explodeKey(key),
|
|
1868
|
-
id,
|
|
1869
|
-
""
|
|
1870
|
-
];
|
|
1871
|
-
}
|
|
1872
|
-
function positionToKey(position) {
|
|
1873
|
-
return {
|
|
1874
|
-
key: implodeKey(position[0]),
|
|
1875
|
-
id: position[1]
|
|
1876
|
-
};
|
|
1877
|
-
}
|
|
1878
|
-
function boundsToPositions(bounds) {
|
|
1879
|
-
if (bounds === void 0) return {};
|
|
1880
|
-
if ("eq" in bounds) return {
|
|
1881
|
-
k1: boundToPosition("lower", {
|
|
1882
|
-
key: bounds.eq,
|
|
1883
|
-
inclusive: true
|
|
1884
|
-
}),
|
|
1885
|
-
k2: boundToPosition("upper", {
|
|
1886
|
-
key: bounds.eq,
|
|
1887
|
-
inclusive: true
|
|
1888
|
-
})
|
|
1889
|
-
};
|
|
1890
|
-
if ("prefix" in bounds) {
|
|
1891
|
-
const prefix = bounds.prefix;
|
|
1892
|
-
const exploded = [];
|
|
1893
|
-
for (const item of prefix) {
|
|
1894
|
-
exploded.push("");
|
|
1895
|
-
exploded.push(item);
|
|
1896
|
-
}
|
|
1897
|
-
return {
|
|
1898
|
-
k1: [
|
|
1899
|
-
exploded.concat([BEFORE_ALL_IDS]),
|
|
1900
|
-
BEFORE_ALL_IDS,
|
|
1901
|
-
BEFORE_ALL_IDS
|
|
1902
|
-
],
|
|
1903
|
-
k2: [
|
|
1904
|
-
exploded.concat([AFTER_ALL_IDS]),
|
|
1905
|
-
AFTER_ALL_IDS,
|
|
1906
|
-
AFTER_ALL_IDS
|
|
1907
|
-
]
|
|
1908
|
-
};
|
|
1909
|
-
}
|
|
1910
|
-
return {
|
|
1911
|
-
k1: boundToPosition("lower", bounds.lower),
|
|
1912
|
-
k2: boundToPosition("upper", bounds.upper)
|
|
1913
|
-
};
|
|
1914
|
-
}
|
|
1915
|
-
function boundToPosition(direction, bound) {
|
|
1916
|
-
if (bound === void 0) return;
|
|
1917
|
-
if (direction === "lower") return [
|
|
1918
|
-
explodeKey(bound.key),
|
|
1919
|
-
bound.id ?? (bound.inclusive ? BEFORE_ALL_IDS : AFTER_ALL_IDS),
|
|
1920
|
-
bound.inclusive ? BEFORE_ALL_IDS : AFTER_ALL_IDS
|
|
1921
|
-
];
|
|
1922
|
-
return [
|
|
1923
|
-
explodeKey(bound.key),
|
|
1924
|
-
bound.id ?? (bound.inclusive ? AFTER_ALL_IDS : BEFORE_ALL_IDS),
|
|
1925
|
-
bound.inclusive ? AFTER_ALL_IDS : BEFORE_ALL_IDS
|
|
1926
|
-
];
|
|
1927
|
-
}
|
|
1928
|
-
|
|
1929
|
-
//#endregion
|
|
1930
|
-
//#region src/aggregate-core/runtime.ts
|
|
1931
|
-
const INTERNAL_NAMESPACE_MARKER_MISSING = 0;
|
|
1932
|
-
const INTERNAL_NAMESPACE_MARKER_PRESENT = 1;
|
|
1933
|
-
const encodeNamespace = (aggregateName, namespace) => [
|
|
1934
|
-
aggregateName,
|
|
1935
|
-
namespace === void 0 ? null : namespace,
|
|
1936
|
-
namespace === void 0 ? INTERNAL_NAMESPACE_MARKER_MISSING : INTERNAL_NAMESPACE_MARKER_PRESENT
|
|
1937
|
-
];
|
|
1938
|
-
const isInternalNamespace = (value) => Array.isArray(value) && value.length === 3 && typeof value[0] === "string" && (value[2] === INTERNAL_NAMESPACE_MARKER_MISSING || value[2] === INTERNAL_NAMESPACE_MARKER_PRESENT);
|
|
1939
|
-
const decodeNamespace = (namespace) => {
|
|
1940
|
-
if (namespace[2] === INTERNAL_NAMESPACE_MARKER_MISSING) return;
|
|
1941
|
-
return namespace[1];
|
|
1942
|
-
};
|
|
1943
|
-
const namespaceForOpts = (aggregateName, opts) => encodeNamespace(aggregateName, namespaceFromOpts(opts));
|
|
1944
|
-
const namespaceForArg = (aggregateName, args) => encodeNamespace(aggregateName, namespaceFromArg(args));
|
|
1945
|
-
/**
|
|
1946
|
-
* Write data to be aggregated, and read aggregated data.
|
|
1947
|
-
*/
|
|
1948
|
-
var Aggregate = class {
|
|
1949
|
-
constructor(aggregateName) {
|
|
1950
|
-
this.aggregateName = aggregateName;
|
|
1951
|
-
}
|
|
1952
|
-
async count(ctx, ...opts) {
|
|
1953
|
-
return (await aggregateBetweenHandler({ db: ctx.db }, {
|
|
1954
|
-
...boundsToPositions(opts[0]?.bounds),
|
|
1955
|
-
namespace: namespaceForOpts(this.aggregateName, opts)
|
|
1956
|
-
})).count;
|
|
1957
|
-
}
|
|
1958
|
-
async countBatch(ctx, queries) {
|
|
1959
|
-
return (await aggregateBetweenBatchHandler({ db: ctx.db }, { queries: queries.map((query) => {
|
|
1960
|
-
if (!query) throw new Error("You must pass bounds and/or namespace");
|
|
1961
|
-
return {
|
|
1962
|
-
...boundsToPositions(query.bounds),
|
|
1963
|
-
namespace: namespaceForArg(this.aggregateName, query)
|
|
1964
|
-
};
|
|
1965
|
-
}) })).map((result) => result.count);
|
|
1966
|
-
}
|
|
1967
|
-
async sum(ctx, ...opts) {
|
|
1968
|
-
return (await aggregateBetweenHandler({ db: ctx.db }, {
|
|
1969
|
-
...boundsToPositions(opts[0]?.bounds),
|
|
1970
|
-
namespace: namespaceForOpts(this.aggregateName, opts)
|
|
1971
|
-
})).sum;
|
|
1972
|
-
}
|
|
1973
|
-
async sumBatch(ctx, queries) {
|
|
1974
|
-
return (await aggregateBetweenBatchHandler({ db: ctx.db }, { queries: queries.map((query) => {
|
|
1975
|
-
if (!query) throw new Error("You must pass bounds and/or namespace");
|
|
1976
|
-
return {
|
|
1977
|
-
...boundsToPositions(query.bounds),
|
|
1978
|
-
namespace: namespaceForArg(this.aggregateName, query)
|
|
1979
|
-
};
|
|
1980
|
-
}) })).map((result) => result.sum);
|
|
1981
|
-
}
|
|
1982
|
-
async at(ctx, offset, ...opts) {
|
|
1983
|
-
const encodedNamespace = namespaceForOpts(this.aggregateName, opts);
|
|
1984
|
-
return btreeItemToAggregateItem(offset < 0 ? await atNegativeOffsetHandler({ db: ctx.db }, {
|
|
1985
|
-
...boundsToPositions(opts[0]?.bounds),
|
|
1986
|
-
namespace: encodedNamespace,
|
|
1987
|
-
offset: -offset - 1
|
|
1988
|
-
}) : await atOffsetHandler({ db: ctx.db }, {
|
|
1989
|
-
...boundsToPositions(opts[0]?.bounds),
|
|
1990
|
-
namespace: encodedNamespace,
|
|
1991
|
-
offset
|
|
1992
|
-
}));
|
|
1993
|
-
}
|
|
1994
|
-
async atBatch(ctx, queries) {
|
|
1995
|
-
return (await atOffsetBatchHandler({ db: ctx.db }, { queries: queries.map((query) => ({
|
|
1996
|
-
...boundsToPositions(query.bounds),
|
|
1997
|
-
namespace: namespaceForArg(this.aggregateName, query),
|
|
1998
|
-
offset: query.offset
|
|
1999
|
-
})) })).map(btreeItemToAggregateItem);
|
|
2000
|
-
}
|
|
2001
|
-
async indexOf(ctx, key, ...opts) {
|
|
2002
|
-
const { k1, k2 } = boundsToPositions(opts[0]?.bounds);
|
|
2003
|
-
const namespace = namespaceForOpts(this.aggregateName, opts);
|
|
2004
|
-
if (opts[0]?.order === "desc") return offsetUntilHandler({ db: ctx.db }, {
|
|
2005
|
-
k2,
|
|
2006
|
-
key: boundToPosition("upper", {
|
|
2007
|
-
id: opts[0]?.id,
|
|
2008
|
-
inclusive: true,
|
|
2009
|
-
key
|
|
2010
|
-
}),
|
|
2011
|
-
namespace
|
|
2012
|
-
});
|
|
2013
|
-
return offsetHandler({ db: ctx.db }, {
|
|
2014
|
-
k1,
|
|
2015
|
-
key: boundToPosition("lower", {
|
|
2016
|
-
id: opts[0]?.id,
|
|
2017
|
-
inclusive: true,
|
|
2018
|
-
key
|
|
2019
|
-
}),
|
|
2020
|
-
namespace
|
|
2021
|
-
});
|
|
2022
|
-
}
|
|
2023
|
-
async offsetOf(ctx, key, namespace, id, bounds) {
|
|
2024
|
-
return this.indexOf(ctx, key, {
|
|
2025
|
-
bounds,
|
|
2026
|
-
id,
|
|
2027
|
-
namespace,
|
|
2028
|
-
order: "asc"
|
|
2029
|
-
});
|
|
2030
|
-
}
|
|
2031
|
-
async offsetUntil(ctx, key, namespace, id, bounds) {
|
|
2032
|
-
return this.indexOf(ctx, key, {
|
|
2033
|
-
bounds,
|
|
2034
|
-
id,
|
|
2035
|
-
namespace,
|
|
2036
|
-
order: "desc"
|
|
2037
|
-
});
|
|
2038
|
-
}
|
|
2039
|
-
async min(ctx, ...opts) {
|
|
2040
|
-
const { page } = await this.paginate(ctx, {
|
|
2041
|
-
bounds: opts[0]?.bounds,
|
|
2042
|
-
namespace: namespaceFromOpts(opts),
|
|
2043
|
-
order: "asc",
|
|
2044
|
-
pageSize: 1
|
|
2045
|
-
});
|
|
2046
|
-
return page[0] ?? null;
|
|
2047
|
-
}
|
|
2048
|
-
async max(ctx, ...opts) {
|
|
2049
|
-
const { page } = await this.paginate(ctx, {
|
|
2050
|
-
bounds: opts[0]?.bounds,
|
|
2051
|
-
namespace: namespaceFromOpts(opts),
|
|
2052
|
-
order: "desc",
|
|
2053
|
-
pageSize: 1
|
|
2054
|
-
});
|
|
2055
|
-
return page[0] ?? null;
|
|
2056
|
-
}
|
|
2057
|
-
async random(ctx, ...opts) {
|
|
2058
|
-
const count = await this.count(ctx, ...opts);
|
|
2059
|
-
if (count === 0) return null;
|
|
2060
|
-
return this.at(ctx, Math.floor(Math.random() * count), ...opts);
|
|
2061
|
-
}
|
|
2062
|
-
async paginate(ctx, ...opts) {
|
|
2063
|
-
const result = await paginateHandler({ db: ctx.db }, {
|
|
2064
|
-
...boundsToPositions(opts[0]?.bounds),
|
|
2065
|
-
cursor: opts[0]?.cursor,
|
|
2066
|
-
limit: opts[0]?.pageSize ?? 100,
|
|
2067
|
-
namespace: namespaceForOpts(this.aggregateName, opts),
|
|
2068
|
-
order: opts[0]?.order ?? "asc"
|
|
2069
|
-
});
|
|
2070
|
-
return {
|
|
2071
|
-
cursor: result.cursor,
|
|
2072
|
-
isDone: result.isDone,
|
|
2073
|
-
page: result.page.map(btreeItemToAggregateItem)
|
|
2074
|
-
};
|
|
2075
|
-
}
|
|
2076
|
-
async *iter(ctx, ...opts) {
|
|
2077
|
-
const bounds = opts[0]?.bounds;
|
|
2078
|
-
const namespace = namespaceFromOpts(opts);
|
|
2079
|
-
const order = opts[0]?.order ?? "asc";
|
|
2080
|
-
const pageSize = opts[0]?.pageSize ?? 100;
|
|
2081
|
-
let cursor;
|
|
2082
|
-
let isDone = false;
|
|
2083
|
-
while (!isDone) {
|
|
2084
|
-
const page = await this.paginate(ctx, {
|
|
2085
|
-
bounds,
|
|
2086
|
-
cursor,
|
|
2087
|
-
namespace,
|
|
2088
|
-
order,
|
|
2089
|
-
pageSize
|
|
2090
|
-
});
|
|
2091
|
-
for (const item of page.page) yield item;
|
|
2092
|
-
cursor = page.cursor;
|
|
2093
|
-
isDone = page.isDone;
|
|
2094
|
-
}
|
|
2095
|
-
}
|
|
2096
|
-
async _insert(ctx, namespace, key, id, summand) {
|
|
2097
|
-
await insertHandler({ db: ctx.db }, {
|
|
2098
|
-
key: keyToPosition(key, id),
|
|
2099
|
-
namespace: namespaceForArg(this.aggregateName, { namespace }),
|
|
2100
|
-
summand,
|
|
2101
|
-
value: id
|
|
2102
|
-
});
|
|
2103
|
-
}
|
|
2104
|
-
async _delete(ctx, namespace, key, id) {
|
|
2105
|
-
await deleteHandler({ db: ctx.db }, {
|
|
2106
|
-
key: keyToPosition(key, id),
|
|
2107
|
-
namespace: namespaceForArg(this.aggregateName, { namespace })
|
|
2108
|
-
});
|
|
2109
|
-
}
|
|
2110
|
-
async _replace(ctx, currentNamespace, currentKey, newNamespace, newKey, id, summand) {
|
|
2111
|
-
await deleteHandler({ db: ctx.db }, {
|
|
2112
|
-
key: keyToPosition(currentKey, id),
|
|
2113
|
-
namespace: namespaceForArg(this.aggregateName, { namespace: currentNamespace })
|
|
2114
|
-
});
|
|
2115
|
-
await insertHandler({ db: ctx.db }, {
|
|
2116
|
-
key: keyToPosition(newKey, id),
|
|
2117
|
-
namespace: namespaceForArg(this.aggregateName, { namespace: newNamespace }),
|
|
2118
|
-
summand,
|
|
2119
|
-
value: id
|
|
2120
|
-
});
|
|
2121
|
-
}
|
|
2122
|
-
async _insertIfDoesNotExist(ctx, namespace, key, id, summand) {
|
|
2123
|
-
await this._replaceOrInsert(ctx, namespace, key, namespace, key, id, summand);
|
|
2124
|
-
}
|
|
2125
|
-
async _deleteIfExists(ctx, namespace, key, id) {
|
|
2126
|
-
try {
|
|
2127
|
-
await this._delete(ctx, namespace, key, id);
|
|
2128
|
-
} catch (error) {
|
|
2129
|
-
if (error instanceof ConvexError && error.data?.code === "DELETE_MISSING_KEY") return;
|
|
2130
|
-
throw error;
|
|
2131
|
-
}
|
|
2132
|
-
}
|
|
2133
|
-
async _replaceOrInsert(ctx, currentNamespace, currentKey, newNamespace, newKey, id, summand) {
|
|
2134
|
-
try {
|
|
2135
|
-
await this._delete(ctx, currentNamespace, currentKey, id);
|
|
2136
|
-
} catch (error) {
|
|
2137
|
-
if (!(error instanceof ConvexError && error.data?.code === "DELETE_MISSING_KEY")) throw error;
|
|
2138
|
-
}
|
|
2139
|
-
await this._insert(ctx, newNamespace, newKey, id, summand);
|
|
2140
|
-
}
|
|
2141
|
-
async clear(ctx, ...opts) {
|
|
2142
|
-
await clearTree(ctx.db, {
|
|
2143
|
-
maxNodeSize: opts[0]?.maxNodeSize,
|
|
2144
|
-
namespace: namespaceForOpts(this.aggregateName, opts),
|
|
2145
|
-
rootLazy: opts[0]?.rootLazy
|
|
2146
|
-
});
|
|
2147
|
-
}
|
|
2148
|
-
async makeRootLazy(ctx, namespace) {
|
|
2149
|
-
const tree = await getOrCreateTree(ctx.db, namespaceForArg(this.aggregateName, { namespace }));
|
|
2150
|
-
await ctx.db.patch(tree.root, { aggregate: void 0 });
|
|
2151
|
-
}
|
|
2152
|
-
async paginateNamespaces(ctx, cursor, pageSize = 100) {
|
|
2153
|
-
const result = await paginateNamespacesHandler({ db: ctx.db }, {
|
|
2154
|
-
aggregateName: this.aggregateName,
|
|
2155
|
-
cursor,
|
|
2156
|
-
limit: pageSize
|
|
2157
|
-
});
|
|
2158
|
-
const page = [];
|
|
2159
|
-
for (const namespace of result.page) {
|
|
2160
|
-
if (!isInternalNamespace(namespace)) continue;
|
|
2161
|
-
if (namespace[0] !== this.aggregateName) continue;
|
|
2162
|
-
page.push(decodeNamespace(namespace));
|
|
2163
|
-
}
|
|
2164
|
-
return {
|
|
2165
|
-
cursor: result.cursor,
|
|
2166
|
-
isDone: result.isDone,
|
|
2167
|
-
page
|
|
2168
|
-
};
|
|
2169
|
-
}
|
|
2170
|
-
async *iterNamespaces(ctx, pageSize = 100) {
|
|
2171
|
-
let cursor;
|
|
2172
|
-
let isDone = false;
|
|
2173
|
-
while (!isDone) {
|
|
2174
|
-
const page = await this.paginateNamespaces(ctx, cursor, pageSize);
|
|
2175
|
-
for (const namespace of page.page) yield namespace;
|
|
2176
|
-
cursor = page.cursor;
|
|
2177
|
-
isDone = page.isDone;
|
|
2178
|
-
}
|
|
2179
|
-
}
|
|
2180
|
-
async clearAll(ctx, opts) {
|
|
2181
|
-
for await (const namespace of this.iterNamespaces(ctx)) await this.clear(ctx, {
|
|
2182
|
-
...opts,
|
|
2183
|
-
namespace
|
|
2184
|
-
});
|
|
2185
|
-
await this.clear(ctx, {
|
|
2186
|
-
...opts,
|
|
2187
|
-
namespace: void 0
|
|
2188
|
-
});
|
|
2189
|
-
}
|
|
2190
|
-
async makeAllRootsLazy(ctx) {
|
|
2191
|
-
for await (const namespace of this.iterNamespaces(ctx)) await this.makeRootLazy(ctx, namespace);
|
|
2192
|
-
}
|
|
2193
|
-
};
|
|
2194
|
-
var DirectAggregate = class extends Aggregate {
|
|
2195
|
-
constructor(config) {
|
|
2196
|
-
super(config.name);
|
|
2197
|
-
}
|
|
2198
|
-
async insert(ctx, args) {
|
|
2199
|
-
await this._insert(ctx, namespaceFromArg(args), args.key, args.id, args.sumValue);
|
|
2200
|
-
}
|
|
2201
|
-
async delete(ctx, args) {
|
|
2202
|
-
await this._delete(ctx, namespaceFromArg(args), args.key, args.id);
|
|
2203
|
-
}
|
|
2204
|
-
async replace(ctx, currentItem, newItem) {
|
|
2205
|
-
await this._replace(ctx, namespaceFromArg(currentItem), currentItem.key, namespaceFromArg(newItem), newItem.key, currentItem.id, newItem.sumValue);
|
|
2206
|
-
}
|
|
2207
|
-
async insertIfDoesNotExist(ctx, args) {
|
|
2208
|
-
await this._insertIfDoesNotExist(ctx, namespaceFromArg(args), args.key, args.id, args.sumValue);
|
|
2209
|
-
}
|
|
2210
|
-
async deleteIfExists(ctx, args) {
|
|
2211
|
-
await this._deleteIfExists(ctx, namespaceFromArg(args), args.key, args.id);
|
|
2212
|
-
}
|
|
2213
|
-
async replaceOrInsert(ctx, currentItem, newItem) {
|
|
2214
|
-
await this._replaceOrInsert(ctx, namespaceFromArg(currentItem), currentItem.key, namespaceFromArg(newItem), newItem.key, currentItem.id, newItem.sumValue);
|
|
2215
|
-
}
|
|
2216
|
-
};
|
|
2217
|
-
var TableAggregate = class extends Aggregate {
|
|
2218
|
-
constructor(options) {
|
|
2219
|
-
super(options.name);
|
|
2220
|
-
this.options = options;
|
|
2221
|
-
}
|
|
2222
|
-
options;
|
|
2223
|
-
async insert(ctx, doc) {
|
|
2224
|
-
await this._insert(ctx, this.options.namespace?.(doc), this.options.sortKey(doc), doc._id, this.options.sumValue?.(doc));
|
|
2225
|
-
}
|
|
2226
|
-
async delete(ctx, doc) {
|
|
2227
|
-
await this._delete(ctx, this.options.namespace?.(doc), this.options.sortKey(doc), doc._id);
|
|
2228
|
-
}
|
|
2229
|
-
async replace(ctx, oldDoc, newDoc) {
|
|
2230
|
-
await this._replace(ctx, this.options.namespace?.(oldDoc), this.options.sortKey(oldDoc), this.options.namespace?.(newDoc), this.options.sortKey(newDoc), newDoc._id, this.options.sumValue?.(newDoc));
|
|
2231
|
-
}
|
|
2232
|
-
async insertIfDoesNotExist(ctx, doc) {
|
|
2233
|
-
await this._insertIfDoesNotExist(ctx, this.options.namespace?.(doc), this.options.sortKey(doc), doc._id, this.options.sumValue?.(doc));
|
|
2234
|
-
}
|
|
2235
|
-
async deleteIfExists(ctx, doc) {
|
|
2236
|
-
await this._deleteIfExists(ctx, this.options.namespace?.(doc), this.options.sortKey(doc), doc._id);
|
|
2237
|
-
}
|
|
2238
|
-
async replaceOrInsert(ctx, oldDoc, newDoc) {
|
|
2239
|
-
await this._replaceOrInsert(ctx, this.options.namespace?.(oldDoc), this.options.sortKey(oldDoc), this.options.namespace?.(newDoc), this.options.sortKey(newDoc), newDoc._id, this.options.sumValue?.(newDoc));
|
|
2240
|
-
}
|
|
2241
|
-
async indexOfDoc(ctx, doc, opts) {
|
|
2242
|
-
return this.indexOf(ctx, this.options.sortKey(doc), {
|
|
2243
|
-
namespace: this.options.namespace?.(doc),
|
|
2244
|
-
...opts
|
|
2245
|
-
});
|
|
2246
|
-
}
|
|
2247
|
-
trigger() {
|
|
2248
|
-
return async (ctx, change) => {
|
|
2249
|
-
if (change.operation === "insert") await this.insert(ctx, change.newDoc);
|
|
2250
|
-
else if (change.operation === "update") await this.replace(ctx, change.oldDoc, change.newDoc);
|
|
2251
|
-
else if (change.operation === "delete") await this.delete(ctx, change.oldDoc);
|
|
2252
|
-
};
|
|
2253
|
-
}
|
|
2254
|
-
idempotentTrigger() {
|
|
2255
|
-
return async (ctx, change) => {
|
|
2256
|
-
if (change.operation === "insert") await this.insertIfDoesNotExist(ctx, change.newDoc);
|
|
2257
|
-
else if (change.operation === "update") await this.replaceOrInsert(ctx, change.oldDoc, change.newDoc);
|
|
2258
|
-
else if (change.operation === "delete") await this.deleteIfExists(ctx, change.oldDoc);
|
|
2259
|
-
};
|
|
2260
|
-
}
|
|
2261
|
-
};
|
|
2262
|
-
function btreeItemToAggregateItem({ k, s }) {
|
|
2263
|
-
const { key, id } = positionToKey(k);
|
|
2264
|
-
return {
|
|
2265
|
-
id,
|
|
2266
|
-
key,
|
|
2267
|
-
sumValue: s
|
|
2268
|
-
};
|
|
2269
|
-
}
|
|
2270
|
-
function namespaceFromArg(args) {
|
|
2271
|
-
if ("namespace" in args) return args.namespace;
|
|
2272
|
-
}
|
|
2273
|
-
function namespaceFromOpts(opts) {
|
|
2274
|
-
if (opts.length === 0) return;
|
|
2275
|
-
const [{ namespace }] = opts;
|
|
2276
|
-
return namespace;
|
|
2277
|
-
}
|
|
2278
|
-
|
|
2279
|
-
//#endregion
|
|
2280
|
-
export { entityKind as A, text as C, custom as D, id as E, json as O, vectorIndex as S, integer as T, aggregateIndex as _, deletion as a, searchIndex as b, EnableRLS as c, OrmSchemaOptions as d, RlsPolicies as f, rlsPolicy as g, RlsPolicy as h, convexTable as i, ConvexColumnBuilder as k, OrmContext as l, TableName as m, TableAggregate as n, Brand as o, TableDeleteConfig as p, aggregateStorageTables as r, Columns as s, DirectAggregate as t, OrmSchemaDefinition as u, index as v, createSystemFields as w, uniqueIndex as x, rankIndex as y };
|
|
1195
|
+
export { integer as C, createSystemFields as S, entityKind as T, rankIndex as _, EnableRLS as a, vectorIndex as b, OrmSchemaOptions as c, TableDeleteConfig as d, TableName as f, index as g, aggregateIndex as h, Columns as i, OrmSchemaPluginTables as l, rlsPolicy as m, deletion as n, OrmContext as o, RlsPolicy as p, Brand as r, OrmSchemaDefinition as s, convexTable as t, RlsPolicies as u, searchIndex as v, ConvexColumnBuilder as w, text as x, uniqueIndex as y };
|