@lunora/sql-store 1.0.0-alpha.20 → 1.0.0-alpha.22

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.mjs CHANGED
@@ -1,2 +1,2 @@
1
- export { createSqlCtxDb, decodeGlobalRow, readSqlCdcChanges, runSqlAggregateMigrations, runSqlCdcMigration, runSqlGlobalTableMigrations, runSqlRankMigrations, runSqlSearchMigrations, trimSqlCdcChanges } from './packem_shared/createSqlCtxDb-BDqIfMnS.mjs';
1
+ export { createSqlCtxDb, decodeGlobalRow, readSqlCdcChanges, runSqlAggregateMigrations, runSqlCdcMigration, runSqlGlobalTableMigrations, runSqlRankMigrations, runSqlSearchMigrations, trimSqlCdcChanges } from './packem_shared/createSqlCtxDb-CuoIlIqO.mjs';
2
2
  export { decodeBigint, effectiveColumnKind, sqliteDecode, sqliteEncode, tryJsonParse } from './packem_shared/decodeBigint-Dedu92k4.mjs';
@@ -1,4 +1,5 @@
1
1
  import { aggregateTableName, rankTableName, ftsTableName, hasTrigger, runRowValidators, assertFlatPredicate, mergeWhere, sortColumnName, resolveRankPartition, encodePartitionKey, decodeCursor, RANK_TIEBREAK, CountRlsUnsupportedError, normalizeIdStructurally, assertValidClientId, aggregateSqlFunction, softDeleteScope, compileWhereSql, normalizeOrderKeys, buildSeekWhere, resolveRelationPredicates, resolveWith, applySelect, encodeCursor, NotFoundError, applyOnDelete, ConflictError, normalizeCountArgument, selectIndexForCount, encodeAggregateKey, selectIndexForAggregate, readAggregateValue, renderSql, runTriggers, matchesRankStaticWhere, stringifySearchText, selectIndexForGroupBy, fanOutScalarCounts, matchesStaticWhere, coerceAggregateNumber, foldAggregateTally, NotUniqueError, throwingScheduler, tokenizeSearch, buildFtsMatch, scoreDocument } from '@lunora/do';
2
+ import { LunoraError } from '@lunora/errors';
2
3
  import { sql } from 'drizzle-orm';
3
4
  import { sqliteDecode, sqliteEncode, effectiveColumnKind } from './decodeBigint-Dedu92k4.mjs';
4
5
 
@@ -260,14 +261,17 @@ const createSearchBuilder = (search, tableName) => {
260
261
  const builder = {
261
262
  eq: (field, value) => {
262
263
  if (!search.definition.filterFields?.includes(field)) {
263
- throw new Error(`field "${field}" is not a filter field of search index "${search.indexName}" on table "${tableName}"`);
264
+ throw new LunoraError("INTERNAL", `field "${field}" is not a filter field of search index "${search.indexName}" on table "${tableName}"`);
264
265
  }
265
266
  search.filters.push({ field, value });
266
267
  return builder;
267
268
  },
268
269
  search: (field, query) => {
269
270
  if (field !== search.definition.field) {
270
- throw new Error(`search index "${search.indexName}" on table "${tableName}" indexes "${search.definition.field}", not "${field}"`);
271
+ throw new LunoraError(
272
+ "INTERNAL",
273
+ `search index "${search.indexName}" on table "${tableName}" indexes "${search.definition.field}", not "${field}"`
274
+ );
271
275
  }
272
276
  const stage = search;
273
277
  stage.field = field;
@@ -315,7 +319,7 @@ const buildRankCursorSeek = (engine, columns, decoded) => {
315
319
  };
316
320
  const rankPageColumns = (index, sortColumns) => {
317
321
  if (index.sortBy.length === 0) {
318
- throw new Error(`rankIndex "${index.name}" requires at least one "sortBy" column for stable pagination`);
322
+ throw new LunoraError("INTERNAL", `rankIndex "${index.name}" requires at least one "sortBy" column for stable pagination`);
319
323
  }
320
324
  const columns = [{ column: "__partition__", direction: "asc" }];
321
325
  for (const [i, sortKey] of index.sortBy.entries()) {
@@ -1105,7 +1109,8 @@ const createSqlCtxDb = (options) => {
1105
1109
  return kind === "shardBy" || kind === "root";
1106
1110
  };
1107
1111
  const crossBackendUnsupported = (childTable) => {
1108
- throw new Error(
1112
+ throw new LunoraError(
1113
+ "INTERNAL",
1109
1114
  `cross-backend relation: a global table cannot load the shard-local relation '${childTable}' (it spans every shard) — wire a cross-shard reader to support it`
1110
1115
  );
1111
1116
  };
@@ -1127,7 +1132,7 @@ const createSqlCtxDb = (options) => {
1127
1132
  async aggregate(tableName, aggOptions) {
1128
1133
  const definition = schema.tables[tableName];
1129
1134
  if (!definition) {
1130
- throw new Error(`unknown table: ${tableName}`);
1135
+ throw new LunoraError("INTERNAL", `unknown table: ${tableName}`);
1131
1136
  }
1132
1137
  await ensureMigrated();
1133
1138
  aggregateSqlFunction(aggOptions.op);
@@ -1140,7 +1145,7 @@ const createSqlCtxDb = (options) => {
1140
1145
  });
1141
1146
  }
1142
1147
  if (!aggOptions.field) {
1143
- throw new Error(`aggregate(${tableName}, { op: "${aggOptions.op}" }): "field" is required for non-count reducers`);
1148
+ throw new LunoraError("INTERNAL", `aggregate(${tableName}, { op: "${aggOptions.op}" }): "field" is required for non-count reducers`);
1144
1149
  }
1145
1150
  const aggScope = softDeleteScope(definition.softDeleteMode, void 0);
1146
1151
  const effective = mergeWhere(mergeWhere(aggOptions.baseWhere, aggOptions.where), aggScope);
@@ -1173,7 +1178,7 @@ const createSqlCtxDb = (options) => {
1173
1178
  async count(tableName, whereOrOptions) {
1174
1179
  const definition = schema.tables[tableName];
1175
1180
  if (!definition) {
1176
- throw new Error(`unknown table: ${tableName}`);
1181
+ throw new LunoraError("INTERNAL", `unknown table: ${tableName}`);
1177
1182
  }
1178
1183
  await ensureMigrated();
1179
1184
  const countOptions = normalizeCountArgument(whereOrOptions);
@@ -1229,7 +1234,8 @@ const createSqlCtxDb = (options) => {
1229
1234
  deletedReference: (references) => existing?.[references],
1230
1235
  findHolders: async (holderTable, field, value) => {
1231
1236
  if (schema.tables[holderTable]?.shardMode?.kind === "shardBy") {
1232
- throw new Error(
1237
+ throw new LunoraError(
1238
+ "INTERNAL",
1233
1239
  `cross-backend cascade from global '${tableName}' into shardBy '${holderTable}' is not supported — would require Query Coordinator fan-out across shards`
1234
1240
  );
1235
1241
  }
@@ -1288,7 +1294,7 @@ const createSqlCtxDb = (options) => {
1288
1294
  async findMany(tableName, args = {}) {
1289
1295
  const definition = schema.tables[tableName];
1290
1296
  if (!definition) {
1291
- throw new Error(`unknown table: ${tableName}`);
1297
+ throw new LunoraError("INTERNAL", `unknown table: ${tableName}`);
1292
1298
  }
1293
1299
  await ensureMigrated();
1294
1300
  const orderKeys = normalizeOrderKeys(args.orderBy);
@@ -1303,7 +1309,7 @@ const createSqlCtxDb = (options) => {
1303
1309
  }
1304
1310
  const childDefinition = schema.tables[childTable];
1305
1311
  if (!childDefinition) {
1306
- throw new Error(`unknown table: ${childTable}`);
1312
+ throw new LunoraError("INTERNAL", `unknown table: ${childTable}`);
1307
1313
  }
1308
1314
  const softScope = softDeleteScope(childDefinition.softDeleteMode, void 0);
1309
1315
  const inFilter = { [whereField]: { in: values } };
@@ -1391,13 +1397,13 @@ const createSqlCtxDb = (options) => {
1391
1397
  async groupBy(tableName, groupOptions) {
1392
1398
  const definition = schema.tables[tableName];
1393
1399
  if (!definition) {
1394
- throw new Error(`unknown table: ${tableName}`);
1400
+ throw new LunoraError("INTERNAL", `unknown table: ${tableName}`);
1395
1401
  }
1396
1402
  await ensureMigrated();
1397
1403
  const agg = groupOptions.agg ?? { op: "count" };
1398
1404
  aggregateSqlFunction(agg.op);
1399
1405
  if (agg.op !== "count" && !agg.field) {
1400
- throw new Error(`groupBy(${tableName}, { agg: { op: "${agg.op}" } }): "field" is required for non-count reducers`);
1406
+ throw new LunoraError("INTERNAL", `groupBy(${tableName}, { agg: { op: "${agg.op}" } }): "field" is required for non-count reducers`);
1401
1407
  }
1402
1408
  const groupScope = softDeleteScope(definition.softDeleteMode, void 0);
1403
1409
  const effective = mergeWhere(mergeWhere(groupOptions.baseWhere, groupOptions.where), groupScope);
@@ -1415,7 +1421,7 @@ const createSqlCtxDb = (options) => {
1415
1421
  select.push(sql`COUNT(*) AS value`);
1416
1422
  } else {
1417
1423
  if (!agg.field) {
1418
- throw new Error(`groupBy(${tableName}, { agg: { op: "${agg.op}" } }): "field" is required for non-count reducers`);
1424
+ throw new LunoraError("INTERNAL", `groupBy(${tableName}, { agg: { op: "${agg.op}" } }): "field" is required for non-count reducers`);
1419
1425
  }
1420
1426
  select.push(sql`${sql.raw(aggregateSqlFunction(agg.op))}(${columnRefSql(agg.field)}) AS value`);
1421
1427
  }
@@ -1445,7 +1451,7 @@ const createSqlCtxDb = (options) => {
1445
1451
  async insert(tableName, document, insertOptions) {
1446
1452
  const definition = schema.tables[tableName];
1447
1453
  if (!definition) {
1448
- throw new Error(`unknown table: ${tableName}`);
1454
+ throw new LunoraError("INTERNAL", `unknown table: ${tableName}`);
1449
1455
  }
1450
1456
  await ensureMigrated();
1451
1457
  const withDefaults = applyInsertDefaults(definition, document, auth);
@@ -1496,16 +1502,16 @@ const createSqlCtxDb = (options) => {
1496
1502
  async patch(id, patch, expectedTable) {
1497
1503
  const tableName = await resolveTableName(id, expectedTable);
1498
1504
  if (!tableName) {
1499
- throw new Error(`document not found: ${id}`);
1505
+ throw new LunoraError("INTERNAL", `document not found: ${id}`);
1500
1506
  }
1501
1507
  const definition = schema.tables[tableName];
1502
1508
  if (!definition) {
1503
- throw new Error(`document not found: ${id}`);
1509
+ throw new LunoraError("INTERNAL", `document not found: ${id}`);
1504
1510
  }
1505
1511
  const snapshot = await rawRow(tableName, id);
1506
1512
  const existing = decodeRow(definition, snapshot);
1507
1513
  if (!existing) {
1508
- throw new Error(`document not found: ${id}`);
1514
+ throw new LunoraError("INTERNAL", `document not found: ${id}`);
1509
1515
  }
1510
1516
  const merged = { ...existing, ...patch, _id: id };
1511
1517
  applyOnUpdate(definition, patch, merged, auth);
@@ -1533,12 +1539,12 @@ const createSqlCtxDb = (options) => {
1533
1539
  async restore(id, expectedTable) {
1534
1540
  const tableName = await resolveTableName(id, expectedTable);
1535
1541
  if (!tableName) {
1536
- throw new Error(`document not found: ${id}`);
1542
+ throw new LunoraError("INTERNAL", `document not found: ${id}`);
1537
1543
  }
1538
1544
  const definition = schema.tables[tableName];
1539
1545
  const field = definition?.softDeleteMode?.field;
1540
1546
  if (!definition || !field) {
1541
- throw new Error(`ctx.db.restore: table "${tableName}" is not a .softDelete() table`);
1547
+ throw new LunoraError("INTERNAL", `ctx.db.restore: table "${tableName}" is not a .softDelete() table`);
1542
1548
  }
1543
1549
  const snapshot = await rawRow(tableName, id);
1544
1550
  const wasDeleted = snapshot?.[field] !== null && snapshot?.[field] !== void 0;
@@ -1553,7 +1559,7 @@ const createSqlCtxDb = (options) => {
1553
1559
  query(tableName) {
1554
1560
  const definition = schema.tables[tableName];
1555
1561
  if (!definition) {
1556
- throw new Error(`unknown table: ${tableName}`);
1562
+ throw new LunoraError("INTERNAL", `unknown table: ${tableName}`);
1557
1563
  }
1558
1564
  const LEGACY_READER_ERROR = "the legacy query()/withIndex() reader is not available on the D1 (global) backend; use findMany";
1559
1565
  const runSearch = async (stage, limit) => {
@@ -1564,16 +1570,16 @@ const createSqlCtxDb = (options) => {
1564
1570
  const reader = {
1565
1571
  async collect() {
1566
1572
  if (!stage) {
1567
- throw new Error(LEGACY_READER_ERROR);
1573
+ throw new LunoraError("INTERNAL", LEGACY_READER_ERROR);
1568
1574
  }
1569
1575
  return runSearch(stage, void 0);
1570
1576
  },
1571
1577
  filter() {
1572
- throw new Error(LEGACY_READER_ERROR);
1578
+ throw new LunoraError("INTERNAL", LEGACY_READER_ERROR);
1573
1579
  },
1574
1580
  async first() {
1575
1581
  if (!stage) {
1576
- throw new Error(LEGACY_READER_ERROR);
1582
+ throw new LunoraError("INTERNAL", LEGACY_READER_ERROR);
1577
1583
  }
1578
1584
  const rows = await runSearch(stage, 1);
1579
1585
  return rows[0] ?? null;
@@ -1584,19 +1590,19 @@ const createSqlCtxDb = (options) => {
1584
1590
  // eslint-disable-next-line @typescript-eslint/require-await -- TableReaderLike.paginate returns a Promise; search queries don't support pagination on either backend
1585
1591
  async paginate() {
1586
1592
  if (stage) {
1587
- throw new Error("pagination is not supported on search queries; use .take(n) or .collect()");
1593
+ throw new LunoraError("INTERNAL", "pagination is not supported on search queries; use .take(n) or .collect()");
1588
1594
  }
1589
- throw new Error(LEGACY_READER_ERROR);
1595
+ throw new LunoraError("INTERNAL", LEGACY_READER_ERROR);
1590
1596
  },
1591
1597
  async take(limit) {
1592
1598
  if (!stage) {
1593
- throw new Error(LEGACY_READER_ERROR);
1599
+ throw new LunoraError("INTERNAL", LEGACY_READER_ERROR);
1594
1600
  }
1595
1601
  return runSearch(stage, limit);
1596
1602
  },
1597
1603
  async unique() {
1598
1604
  if (!stage) {
1599
- throw new Error(LEGACY_READER_ERROR);
1605
+ throw new LunoraError("INTERNAL", LEGACY_READER_ERROR);
1600
1606
  }
1601
1607
  const rows = await runSearch(stage, 2);
1602
1608
  if (rows.length > 1) {
@@ -1605,12 +1611,12 @@ const createSqlCtxDb = (options) => {
1605
1611
  return rows[0] ?? null;
1606
1612
  },
1607
1613
  withIndex() {
1608
- throw new Error(LEGACY_READER_ERROR);
1614
+ throw new LunoraError("INTERNAL", LEGACY_READER_ERROR);
1609
1615
  },
1610
1616
  withSearchIndex(indexName, search) {
1611
1617
  const searchDefinition = (definition.searchIndexes ?? []).find((index) => index.name === indexName);
1612
1618
  if (!searchDefinition) {
1613
- throw new Error(`unknown search index "${indexName}" on table "${tableName}"`);
1619
+ throw new LunoraError("INTERNAL", `unknown search index "${indexName}" on table "${tableName}"`);
1614
1620
  }
1615
1621
  const searchStage = {
1616
1622
  definition: searchDefinition,
@@ -1622,7 +1628,7 @@ const createSqlCtxDb = (options) => {
1622
1628
  };
1623
1629
  search(createSearchBuilder(searchStage, tableName));
1624
1630
  if (!searchStage.hasQuery) {
1625
- throw new Error(`search index "${indexName}" on table "${tableName}" requires a .search(field, query) call`);
1631
+ throw new LunoraError("INTERNAL", `search index "${indexName}" on table "${tableName}" requires a .search(field, query) call`);
1626
1632
  }
1627
1633
  return buildReader(searchStage);
1628
1634
  }
@@ -1634,11 +1640,11 @@ const createSqlCtxDb = (options) => {
1634
1640
  async rank(tableName, indexName, rankOptions) {
1635
1641
  const definition = schema.tables[tableName];
1636
1642
  if (!definition) {
1637
- throw new Error(`unknown table: ${tableName}`);
1643
+ throw new LunoraError("INTERNAL", `unknown table: ${tableName}`);
1638
1644
  }
1639
1645
  const index = definition.rankIndexes?.find((i) => i.name === indexName);
1640
1646
  if (!index) {
1641
- throw new Error(`unknown rankIndex "${indexName}" on table "${tableName}"`);
1647
+ throw new LunoraError("INTERNAL", `unknown rankIndex "${indexName}" on table "${tableName}"`);
1642
1648
  }
1643
1649
  if (rankOptions.restrictsCounts) {
1644
1650
  throw new CountRlsUnsupportedError(tableName);
@@ -1691,11 +1697,11 @@ const createSqlCtxDb = (options) => {
1691
1697
  assertFlatPredicate(mergeWhere(rankPageOptions.baseWhere, rankPageOptions.where), schema, tableName, "rankPage");
1692
1698
  const definition = schema.tables[tableName];
1693
1699
  if (!definition) {
1694
- throw new Error(`unknown table: ${tableName}`);
1700
+ throw new LunoraError("INTERNAL", `unknown table: ${tableName}`);
1695
1701
  }
1696
1702
  const index = definition.rankIndexes?.find((i) => i.name === indexName);
1697
1703
  if (!index) {
1698
- throw new Error(`unknown rankIndex "${indexName}" on table "${tableName}"`);
1704
+ throw new LunoraError("INTERNAL", `unknown rankIndex "${indexName}" on table "${tableName}"`);
1699
1705
  }
1700
1706
  await ensureMigrated();
1701
1707
  const counterReady = await ensureRankBackfilled(tableName, index);
@@ -1751,15 +1757,15 @@ const createSqlCtxDb = (options) => {
1751
1757
  async replace(id, document, expectedTable) {
1752
1758
  const tableName = await resolveTableName(id, expectedTable);
1753
1759
  if (!tableName) {
1754
- throw new Error(`document not found: ${id}`);
1760
+ throw new LunoraError("INTERNAL", `document not found: ${id}`);
1755
1761
  }
1756
1762
  const definition = schema.tables[tableName];
1757
1763
  if (!definition) {
1758
- throw new Error(`document not found: ${id}`);
1764
+ throw new LunoraError("INTERNAL", `document not found: ${id}`);
1759
1765
  }
1760
1766
  const snapshot = await rawRow(tableName, id);
1761
1767
  if (snapshot === void 0) {
1762
- throw new Error(`document not found: ${id}`);
1768
+ throw new LunoraError("INTERNAL", `document not found: ${id}`);
1763
1769
  }
1764
1770
  const needsPrevious = hasTrigger(schema, tableName, "update") || (definition.aggregateIndexes ?? []).length > 0 || (definition.rankIndexes ?? []).length > 0;
1765
1771
  const previous = needsPrevious ? decodeRow(definition, snapshot) ?? void 0 : void 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/sql-store",
3
- "version": "1.0.0-alpha.20",
3
+ "version": "1.0.0-alpha.22",
4
4
  "description": "Internal dialect-parameterized SQL store core for Lunora .global() backends (D1, PlanetScale)",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -50,7 +50,8 @@
50
50
  "access": "public"
51
51
  },
52
52
  "dependencies": {
53
- "@lunora/do": "1.0.0-alpha.20",
53
+ "@lunora/do": "1.0.0-alpha.22",
54
+ "@lunora/errors": "1.0.0-alpha.1",
54
55
  "drizzle-orm": "^0.45.2"
55
56
  },
56
57
  "engines": {