@peerbit/indexer-sqlite3 1.1.4 → 1.2.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.
Files changed (46) hide show
  1. package/dist/peerbit/sqlite3-bundler-friendly.mjs +7 -7
  2. package/dist/peerbit/sqlite3-node.mjs +7 -7
  3. package/dist/peerbit/sqlite3.js +7 -7
  4. package/dist/peerbit/sqlite3.min.js +688 -168
  5. package/dist/peerbit/sqlite3.mjs +7 -7
  6. package/dist/peerbit/sqlite3.wasm +0 -0
  7. package/dist/peerbit/sqlite3.worker.min.js +19 -5
  8. package/dist/src/engine.d.ts +4 -1
  9. package/dist/src/engine.d.ts.map +1 -1
  10. package/dist/src/engine.js +125 -48
  11. package/dist/src/engine.js.map +1 -1
  12. package/dist/src/query-planner.d.ts +47 -0
  13. package/dist/src/query-planner.d.ts.map +1 -0
  14. package/dist/src/query-planner.js +290 -0
  15. package/dist/src/query-planner.js.map +1 -0
  16. package/dist/src/schema.d.ts +31 -7
  17. package/dist/src/schema.d.ts.map +1 -1
  18. package/dist/src/schema.js +370 -123
  19. package/dist/src/schema.js.map +1 -1
  20. package/dist/src/sqlite3-messages.worker.d.ts +4 -1
  21. package/dist/src/sqlite3-messages.worker.d.ts.map +1 -1
  22. package/dist/src/sqlite3-messages.worker.js.map +1 -1
  23. package/dist/src/sqlite3.browser.d.ts.map +1 -1
  24. package/dist/src/sqlite3.browser.js +7 -0
  25. package/dist/src/sqlite3.browser.js.map +1 -1
  26. package/dist/src/sqlite3.d.ts.map +1 -1
  27. package/dist/src/sqlite3.js +24 -14
  28. package/dist/src/sqlite3.js.map +1 -1
  29. package/dist/src/sqlite3.wasm.d.ts +1 -0
  30. package/dist/src/sqlite3.wasm.d.ts.map +1 -1
  31. package/dist/src/sqlite3.wasm.js +9 -1
  32. package/dist/src/sqlite3.wasm.js.map +1 -1
  33. package/dist/src/sqlite3.worker.js +7 -0
  34. package/dist/src/sqlite3.worker.js.map +1 -1
  35. package/dist/src/types.d.ts +1 -0
  36. package/dist/src/types.d.ts.map +1 -1
  37. package/package.json +4 -4
  38. package/src/engine.ts +143 -68
  39. package/src/query-planner.ts +334 -0
  40. package/src/schema.ts +519 -164
  41. package/src/sqlite3-messages.worker.ts +5 -0
  42. package/src/sqlite3.browser.ts +8 -0
  43. package/src/sqlite3.ts +24 -13
  44. package/src/sqlite3.wasm.ts +11 -1
  45. package/src/sqlite3.worker.ts +6 -1
  46. package/src/types.ts +1 -0
@@ -7234,6 +7234,7 @@ function hashBlocks(w, v2, p, pos, len) {
7234
7234
 
7235
7235
  // ../../crypto/dist/src/utils.js
7236
7236
  var import_libsodium_wrappers = __toESM(require_libsodium_wrappers(), 1);
7237
+ var fromHexString = (hexString) => import_libsodium_wrappers.default.from_hex(hexString);
7237
7238
  var toHexString = (bytes) => import_libsodium_wrappers.default.to_hex(bytes);
7238
7239
  var toBase64 = (arr) => {
7239
7240
  return import_libsodium_wrappers.default.to_base64(arr, import_libsodium_wrappers.default.base64_variants.ORIGINAL);
@@ -7243,6 +7244,7 @@ var toBase58 = (arr) => {
7243
7244
  };
7244
7245
 
7245
7246
  // ../../crypto/dist/src/hash.browser.js
7247
+ var sha256Base64Sync = (bytes) => toBase64(new SHA256().update(bytes).digest());
7246
7248
  var sha256Sync = (bytes) => new SHA256().update(bytes).digest();
7247
7249
 
7248
7250
  // ../../../../node_modules/uint8-varint/dist/src/index.js
@@ -7409,7 +7411,7 @@ var UnsignedIntegerValue = class UnsignedIntegerValue2 extends IntegerValue {
7409
7411
  constructor(number) {
7410
7412
  super();
7411
7413
  if (!Number.isInteger(number) || number > 4294967295 || number < 0) {
7412
- throw new Error("Number is not u32");
7414
+ throw new Error("Number is not u32: " + number);
7413
7415
  }
7414
7416
  this.number = number;
7415
7417
  }
@@ -7516,6 +7518,25 @@ IntegerKey = __decorate([
7516
7518
  variant(2),
7517
7519
  __metadata("design:paramtypes", [Number])
7518
7520
  ], IntegerKey);
7521
+ var LargeIntegerKey = class LargeIntegerKey2 extends IdKey {
7522
+ key;
7523
+ constructor(key) {
7524
+ super();
7525
+ this.key = key;
7526
+ }
7527
+ get primitive() {
7528
+ return this.key;
7529
+ }
7530
+ };
7531
+ __decorate([
7532
+ field({ type: "u64" }),
7533
+ __metadata("design:type", BigInt)
7534
+ ], LargeIntegerKey.prototype, "key", void 0);
7535
+ LargeIntegerKey = __decorate([
7536
+ variant(3),
7537
+ __metadata("design:paramtypes", [BigInt])
7538
+ ], LargeIntegerKey);
7539
+ var u64Max = 18446744073709551615n;
7519
7540
  var toId = (obj) => {
7520
7541
  if (typeof obj === "string") {
7521
7542
  return new StringKey(obj);
@@ -7524,10 +7545,10 @@ var toId = (obj) => {
7524
7545
  return new IntegerKey(obj);
7525
7546
  }
7526
7547
  if (typeof obj === "bigint") {
7527
- if (obj <= Number.MAX_SAFE_INTEGER && obj >= 0n) {
7528
- return new IntegerKey(Number(obj));
7548
+ if (obj <= u64Max && obj >= 0n) {
7549
+ return new LargeIntegerKey(obj);
7529
7550
  }
7530
- throw new Error("BigInt is not less than 2^53. Max value is 9007199254740991");
7551
+ throw new Error("BigInt is not less than 2^64 - 1. Max value is " + (2 ** 64 - 1) + ". Provided value: " + obj);
7531
7552
  }
7532
7553
  if (obj instanceof Uint8Array) {
7533
7554
  return new Uint8ArrayKey(obj);
@@ -7851,7 +7872,7 @@ var Nested = class Nested2 extends Query {
7851
7872
  query;
7852
7873
  constructor(props) {
7853
7874
  super();
7854
- this.path = props.path;
7875
+ this.path = Array.isArray(props.path) ? props.path : [props.path];
7855
7876
  this.id = props.id ?? v4_default();
7856
7877
  this.query = toQuery(props.query);
7857
7878
  }
@@ -7861,8 +7882,8 @@ __decorate2([
7861
7882
  __metadata2("design:type", String)
7862
7883
  ], Nested.prototype, "id", void 0);
7863
7884
  __decorate2([
7864
- field({ type: "string" }),
7865
- __metadata2("design:type", String)
7885
+ field({ type: vec("string") }),
7886
+ __metadata2("design:type", Array)
7866
7887
  ], Nested.prototype, "path", void 0);
7867
7888
  __decorate2([
7868
7889
  field({ type: vec(Query) }),
@@ -7933,6 +7954,35 @@ var getIdProperty = (clazz) => {
7933
7954
  return [property];
7934
7955
  };
7935
7956
 
7957
+ // ../interface/dist/src/errors.js
7958
+ var NotStartedError = class extends Error {
7959
+ constructor() {
7960
+ super("Not started");
7961
+ }
7962
+ };
7963
+
7964
+ // ../../time/dist/src/hrtime.browser.js
7965
+ var hrtime = (previousTimestamp) => {
7966
+ const baseNow = Math.floor((Date.now() - performance.now()) * 1e-3);
7967
+ const clocktime = performance.now() * 1e-3;
7968
+ let seconds = Math.floor(clocktime) + baseNow;
7969
+ let nanoseconds = Math.floor(clocktime % 1 * 1e9);
7970
+ if (previousTimestamp) {
7971
+ seconds = seconds - previousTimestamp[0];
7972
+ nanoseconds = nanoseconds - previousTimestamp[1];
7973
+ if (nanoseconds < 0) {
7974
+ seconds--;
7975
+ nanoseconds += 1e9;
7976
+ }
7977
+ }
7978
+ return [seconds, nanoseconds];
7979
+ };
7980
+ var NS_PER_SEC = 1e9;
7981
+ hrtime.bigint = (time) => {
7982
+ const diff = hrtime(time);
7983
+ return BigInt(diff[0] * NS_PER_SEC + diff[1]);
7984
+ };
7985
+
7936
7986
  // dist/src/schema.js
7937
7987
  var __decorate3 = function(decorators, target, key, desc) {
7938
7988
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -7960,16 +8010,25 @@ var SQLConversionMap = {
7960
8010
  Date: "TEXT"
7961
8011
  };
7962
8012
  var WRAPPED_SIMPLE_VALUE_VARIANT = "wrapped";
8013
+ var JSON_GROUP_ARRAY = "json_group_array";
8014
+ var JSON_OBJECT = "distinct json_object";
8015
+ var u64ToI64 = (u64) => {
8016
+ return (typeof u64 === "number" ? BigInt(u64) : u64) - 9223372036854775808n;
8017
+ };
8018
+ var i64ToU64 = (i64) => (typeof i64 === "number" ? BigInt(i64) : i64) + 9223372036854775808n;
7963
8019
  var convertToSQLType = (value, type) => {
7964
8020
  if (value != null) {
7965
8021
  if (type === "bool") {
7966
8022
  return value ? 1 : 0;
7967
8023
  }
8024
+ if (type === "u64") {
8025
+ return u64ToI64(value);
8026
+ }
7968
8027
  }
7969
8028
  return value;
7970
8029
  };
7971
8030
  var nullAsUndefined = (value) => value === null ? void 0 : value;
7972
- var escapeColumnName = (name) => `"${name}"`;
8031
+ var escapeColumnName = (name, char = '"') => `${char}${name}${char}`;
7973
8032
  var MissingFieldError = class extends Error {
7974
8033
  constructor(message) {
7975
8034
  super(message);
@@ -7987,7 +8046,13 @@ var convertFromSQLType = (value, type) => {
7987
8046
  return typeof value === "bigint" || typeof value === "string" ? Number(value) : nullAsUndefined(value);
7988
8047
  }
7989
8048
  if (type === "u64") {
7990
- return typeof value === "number" || typeof value === "string" ? BigInt(value) : nullAsUndefined(value);
8049
+ if (typeof value === "number" || typeof value === "bigint") {
8050
+ return i64ToU64(value);
8051
+ }
8052
+ if (value == null) {
8053
+ return nullAsUndefined(value);
8054
+ }
8055
+ throw new Error(`Unexpected value type for value ${value} expected number or bigint for u64 field`);
7991
8056
  }
7992
8057
  return nullAsUndefined(value);
7993
8058
  };
@@ -8034,7 +8099,8 @@ var getSQLTable = (ctor, path, primary, inline, addJoinField, fromOptionalField
8034
8099
  parent: void 0,
8035
8100
  referencedInArray: false,
8036
8101
  isSimpleValue: false,
8037
- inline
8102
+ inline,
8103
+ indices: /* @__PURE__ */ new Set()
8038
8104
  };
8039
8105
  ret.push(table);
8040
8106
  for (const dep of dependencies) {
@@ -8060,8 +8126,18 @@ var getNameOfClass = (ctor) => {
8060
8126
  return name;
8061
8127
  };
8062
8128
  var getTableName = (path = [], clazz) => {
8129
+ let pathKey = path.length > 0 ? path.join("__") + "__" : "";
8130
+ if (typeof clazz !== "string") {
8131
+ const tableName = clazz["__table_" + pathKey];
8132
+ if (tableName) {
8133
+ return tableName;
8134
+ }
8135
+ }
8063
8136
  let name = typeof clazz === "string" ? clazz : getNameOfClass(clazz);
8064
- const ret = (path.length > 0 ? path.join("__") + "__" : "") + name.replace(/[^a-zA-Z0-9_]/g, "_");
8137
+ const ret = pathKey + name.replace(/[^a-zA-Z0-9_]/g, "_");
8138
+ if (typeof clazz !== "string") {
8139
+ clazz["__table_" + pathKey] = ret;
8140
+ }
8065
8141
  return ret;
8066
8142
  };
8067
8143
  var CHILD_TABLE_ID = "__id";
@@ -8081,9 +8157,9 @@ var getSQLFields = (tableName, path, ctor, primary, addJoinFieldFromParent, tabl
8081
8157
  const sqlConstraints = [];
8082
8158
  let foundPrimary = false;
8083
8159
  const addJoinFields = primary === false ? addJoinFieldFromParent : (fields2, contstraints) => {
8084
- const primaryField = primary != null ? sqlFields.find((field2) => field2.name === primary) : void 0;
8085
- const parentPrimaryFieldName = primaryField?.key || CHILD_TABLE_ID;
8086
- const parentPrimaryFieldType = primaryField ? primaryField.type : "INTEGER";
8160
+ const parentPrimaryField = primary != null ? sqlFields.find((field2) => field2.name === primary) : void 0;
8161
+ const parentPrimaryFieldName = parentPrimaryField?.key || CHILD_TABLE_ID;
8162
+ const parentPrimaryFieldType = parentPrimaryField ? parentPrimaryField.type : "INTEGER";
8087
8163
  fields2.unshift(
8088
8164
  {
8089
8165
  name: CHILD_TABLE_ID,
@@ -8092,6 +8168,7 @@ var getSQLFields = (tableName, path, ctor, primary, addJoinFieldFromParent, tabl
8092
8168
  type: "INTEGER",
8093
8169
  isPrimary: true,
8094
8170
  from: void 0,
8171
+ unwrappedType: void 0,
8095
8172
  path: [CHILD_TABLE_ID]
8096
8173
  },
8097
8174
  // foreign key parent document
@@ -8100,8 +8177,9 @@ var getSQLFields = (tableName, path, ctor, primary, addJoinFieldFromParent, tabl
8100
8177
  key: PARENT_TABLE_ID,
8101
8178
  definition: `${PARENT_TABLE_ID} ${parentPrimaryFieldType}`,
8102
8179
  type: parentPrimaryFieldType,
8180
+ from: parentPrimaryField?.from,
8181
+ unwrappedType: parentPrimaryField?.unwrappedType,
8103
8182
  isPrimary: false,
8104
- from: void 0,
8105
8183
  path: [PARENT_TABLE_ID]
8106
8184
  }
8107
8185
  );
@@ -8159,6 +8237,7 @@ var getSQLFields = (tableName, path, ctor, primary, addJoinFieldFromParent, tabl
8159
8237
  type: "INTEGER",
8160
8238
  isPrimary: false,
8161
8239
  from: void 0,
8240
+ unwrappedType: void 0,
8162
8241
  path: [ARRAY_INDEX_COLUMN]
8163
8242
  },
8164
8243
  ...table.fields.slice(2)
@@ -8181,6 +8260,7 @@ var getSQLFields = (tableName, path, ctor, primary, addJoinFieldFromParent, tabl
8181
8260
  type: fieldType,
8182
8261
  isPrimary,
8183
8262
  from: field2,
8263
+ unwrappedType: unwrapNestedType(field2.type),
8184
8264
  path: [...path.slice(1), key]
8185
8265
  });
8186
8266
  };
@@ -8242,6 +8322,7 @@ var getSQLFields = (tableName, path, ctor, primary, addJoinFieldFromParent, tabl
8242
8322
  type: "bool",
8243
8323
  isPrimary: false,
8244
8324
  from: void 0,
8325
+ unwrappedType: void 0,
8245
8326
  path: [...path.slice(1), key],
8246
8327
  describesExistenceOfAnother: path[path.length - 1]
8247
8328
  });
@@ -8326,7 +8407,7 @@ var getTableFromValue = (parentTable, tables, field2, value) => {
8326
8407
  continue;
8327
8408
  }
8328
8409
  if (ctor) {
8329
- clazzName = getNameOfClass(ctor);
8410
+ clazzName = ctor;
8330
8411
  break;
8331
8412
  }
8332
8413
  }
@@ -8405,14 +8486,14 @@ var insert = async (insertFn, obj, tables, table, fields, handleNestedCallback,
8405
8486
  for (const _field of subTable.fields) {
8406
8487
  bindableValues.push(null);
8407
8488
  }
8408
- bindableValues[bindableValues.length - 1] = false;
8489
+ bindableValues[bindableValues.length - 1] = 0;
8409
8490
  continue;
8410
8491
  }
8411
8492
  await insert((values, table2) => {
8412
8493
  if (table2.inline) {
8413
8494
  bindableValues.push(...values);
8414
8495
  if (field2.type instanceof OptionKind) {
8415
- bindableValues.push(true);
8496
+ bindableValues.push(1);
8416
8497
  }
8417
8498
  return void 0;
8418
8499
  } else {
@@ -8481,13 +8562,13 @@ var matchFieldInShape = (shape, path, field2) => {
8481
8562
  };
8482
8563
  var selectChildren = (childrenTable) => "select * from " + childrenTable.name + " where " + PARENT_TABLE_ID + " = ?";
8483
8564
  var generateSelectQuery = (table, selects) => {
8484
- return `SELECT ${selects.map((x) => `${x.from} as ${x.as}`).join(", ")} FROM ${table.name}`;
8565
+ return `select ${selects.map((x) => `${x.from} as ${x.as}`).join(", ")} FROM ${table.name}`;
8485
8566
  };
8486
8567
  var selectAllFieldsFromTables = (tables, shape) => {
8487
8568
  const selectsPerTable = [];
8488
8569
  for (const table of tables) {
8489
- const { selects, join: joinFromSelect } = selectAllFieldsFromTable(table, shape);
8490
- selectsPerTable.push({ selects, joins: joinFromSelect });
8570
+ const { selects, join: joinFromSelect, groupBy } = selectAllFieldsFromTable(table, shape);
8571
+ selectsPerTable.push({ selects, joins: joinFromSelect, groupBy });
8491
8572
  }
8492
8573
  let newSelects = [];
8493
8574
  for (const [i, selects] of selectsPerTable.entries()) {
@@ -8512,8 +8593,50 @@ var selectAllFieldsFromTable = (table, shape) => {
8512
8593
  let stack = [{ table, shape }];
8513
8594
  let join = /* @__PURE__ */ new Map();
8514
8595
  const fieldResolvers = [];
8596
+ let groupByParentId = false;
8515
8597
  for (const tableAndShape of stack) {
8516
- if (!tableAndShape.table.inline) {
8598
+ if (tableAndShape.table.referencedInArray) {
8599
+ let selectBuilder = `${JSON_GROUP_ARRAY}(${JSON_OBJECT}(`;
8600
+ groupByParentId = true;
8601
+ let first = false;
8602
+ const as = createReconstructReferenceName(tableAndShape.table);
8603
+ for (const field2 of tableAndShape.table.fields) {
8604
+ if ((field2.isPrimary || !tableAndShape.shape || matchFieldInShape(tableAndShape.shape, [], field2) || // also always include the index field
8605
+ field2.name === ARRAY_INDEX_COLUMN) && field2.name !== PARENT_TABLE_ID) {
8606
+ let resolveField = `${as}.${escapeColumnName(field2.name)}`;
8607
+ if (field2.unwrappedType === "u64") {
8608
+ resolveField = `CAST(${resolveField} AS TEXT)`;
8609
+ }
8610
+ if (field2.type === "BLOB") {
8611
+ resolveField = `HEX(${resolveField})`;
8612
+ }
8613
+ if (first) {
8614
+ selectBuilder += `, `;
8615
+ }
8616
+ first = true;
8617
+ selectBuilder += `${escapeColumnName(field2.name, "'")}, ${resolveField}`;
8618
+ }
8619
+ }
8620
+ selectBuilder += `)) `;
8621
+ fieldResolvers.push({
8622
+ from: selectBuilder,
8623
+ as
8624
+ });
8625
+ join.set(createReconstructReferenceName(tableAndShape.table), {
8626
+ as,
8627
+ table: tableAndShape.table,
8628
+ type: "left",
8629
+ columns: []
8630
+ });
8631
+ } else if (!tableAndShape.table.inline) {
8632
+ if (tableAndShape.table.parent != null) {
8633
+ join.set(createReconstructReferenceName(tableAndShape.table), {
8634
+ as: tableAndShape.table.name,
8635
+ table: tableAndShape.table,
8636
+ type: "left",
8637
+ columns: []
8638
+ });
8639
+ }
8517
8640
  for (const field2 of tableAndShape.table.fields) {
8518
8641
  if (field2.isPrimary || !tableAndShape.shape || matchFieldInShape(tableAndShape.shape, [], field2)) {
8519
8642
  fieldResolvers.push({
@@ -8524,9 +8647,6 @@ var selectAllFieldsFromTable = (table, shape) => {
8524
8647
  }
8525
8648
  }
8526
8649
  for (const child of tableAndShape.table.children) {
8527
- if (child.referencedInArray) {
8528
- continue;
8529
- }
8530
8650
  let childShape = void 0;
8531
8651
  if (tableAndShape.shape) {
8532
8652
  const parentPath = child.parentPath?.slice(1);
@@ -8537,15 +8657,13 @@ var selectAllFieldsFromTable = (table, shape) => {
8537
8657
  childShape = maybeShape === true ? void 0 : Array.isArray(maybeShape) ? maybeShape[0] : maybeShape;
8538
8658
  }
8539
8659
  stack.push({ table: child, shape: childShape });
8540
- if (!child.inline) {
8541
- join.set(child.name, { as: child.name, table: child });
8542
- }
8543
8660
  }
8544
8661
  }
8545
8662
  if (fieldResolvers.length === 0) {
8546
8663
  throw new Error("No fields to resolve");
8547
8664
  }
8548
8665
  return {
8666
+ groupBy: groupByParentId ? `${table.name}.${escapeColumnName(table.primary)}` || void 0 : void 0,
8549
8667
  selects: fieldResolvers,
8550
8668
  // `SELECT ${fieldResolvers.join(", ")} FROM ${table.name}`,
8551
8669
  join
@@ -8573,13 +8691,37 @@ var resolveInstanceFromValue = async (fromTablePrefixedValues, tables, table, re
8573
8691
  }
8574
8692
  let subshape = maybeShape === true ? void 0 : subshapeIsArray ? maybeShape[0] : maybeShape;
8575
8693
  if (isArray) {
8576
- let once = false;
8577
8694
  let resolvedArr = [];
8578
8695
  for (const subtable of subTables) {
8579
- let rootTable = getNonInlinedTable(table);
8580
- const arr = await resolveChildren(fromTablePrefixedValues[getTablePrefixedField(rootTable, rootTable.primary, !tablePrefixed)], subtable);
8581
- if (arr) {
8582
- once = true;
8696
+ let arr = void 0;
8697
+ const tableName = createReconstructReferenceName(subtable);
8698
+ if (fromTablePrefixedValues[tableName]) {
8699
+ arr = JSON.parse(fromTablePrefixedValues[tableName]);
8700
+ arr = arr.filter((x) => x[subtable.primary] != null);
8701
+ for (const field3 of subtable.fields) {
8702
+ if (field3.name === PARENT_TABLE_ID) {
8703
+ continue;
8704
+ }
8705
+ if (field3.unwrappedType === "u64") {
8706
+ for (const item of arr) {
8707
+ item[field3.name] = BigInt(item[field3.name]);
8708
+ }
8709
+ } else if (field3.type === "BLOB") {
8710
+ for (const item of arr) {
8711
+ item[field3.name] = fromHexString(item[field3.name]);
8712
+ }
8713
+ }
8714
+ }
8715
+ } else {
8716
+ if (subtable.children) {
8717
+ let rootTable = getNonInlinedTable(table);
8718
+ const parentId = fromTablePrefixedValues[getTablePrefixedField(rootTable, rootTable.primary, !tablePrefixed)];
8719
+ arr = await resolveChildren(parentId, subtable);
8720
+ } else {
8721
+ arr = [];
8722
+ }
8723
+ }
8724
+ if (arr && arr.length > 0) {
8583
8725
  for (const element of arr) {
8584
8726
  const resolved = await resolveInstanceFromValue(
8585
8727
  element,
@@ -8594,11 +8736,7 @@ var resolveInstanceFromValue = async (fromTablePrefixedValues, tables, table, re
8594
8736
  }
8595
8737
  }
8596
8738
  }
8597
- if (!once) {
8598
- obj[field2.key] = void 0;
8599
- } else {
8600
- obj[field2.key] = resolvedArr;
8601
- }
8739
+ obj[field2.key] = resolvedArr;
8602
8740
  } else {
8603
8741
  let subTable = void 0;
8604
8742
  if (subTables.length > 1) {
@@ -8656,14 +8794,14 @@ var resolveInstanceFromValue = async (fromTablePrefixedValues, tables, table, re
8656
8794
  return Object.assign(Object.create(table.ctor.prototype), obj);
8657
8795
  };
8658
8796
  var convertDeleteRequestToQuery = (request, tables, table) => {
8659
- const { query, bindable } = convertRequestToQuery("delete", request, tables, table);
8797
+ const { query, bindable } = convertRequestToQuery("delete", { query: toQuery(request.query) }, tables, table);
8660
8798
  return {
8661
8799
  sql: `DELETE FROM ${table.name} WHERE ${table.primary} IN (SELECT ${table.primary} from ${table.name} ${query}) returning ${table.primary}`,
8662
8800
  bindable
8663
8801
  };
8664
8802
  };
8665
8803
  var convertSumRequestToQuery = (request, tables, table) => {
8666
- const { query, bindable } = convertRequestToQuery("sum", request, tables, table);
8804
+ const { query, bindable } = convertRequestToQuery("sum", { query: toQuery(request.query), key: request.key }, tables, table);
8667
8805
  const inlineName = getInlineTableFieldName(request.key);
8668
8806
  const field2 = table.fields.find((x) => x.name === inlineName);
8669
8807
  if (unwrapNestedType(field2.from.type) === "u64") {
@@ -8676,12 +8814,41 @@ var convertSumRequestToQuery = (request, tables, table) => {
8676
8814
  };
8677
8815
  };
8678
8816
  var convertCountRequestToQuery = (request, tables, table) => {
8679
- const { query, bindable } = convertRequestToQuery("count", request, tables, table);
8817
+ const { query, bindable } = convertRequestToQuery("count", { query: request?.query ? toQuery(request.query) : void 0 }, tables, table);
8680
8818
  return {
8681
8819
  sql: `SELECT count(*) as count FROM ${table.name} ${query}`,
8682
8820
  bindable
8683
8821
  };
8684
8822
  };
8823
+ var buildOrderBy = (sort, tables, table, joinBuilder, resolverBuilder, path = [], options) => {
8824
+ let orderByBuilder = void 0;
8825
+ if ((!sort || Array.isArray(sort) && sort.length === 0) && !options?.fetchAll) {
8826
+ sort = table.primary && path.length === 0 ? [{ key: [table.primary], direction: SortDirection.ASC }] : void 0;
8827
+ }
8828
+ if (sort) {
8829
+ let sortArr = Array.isArray(sort) ? sort : [sort];
8830
+ if (sortArr.length > 0) {
8831
+ orderByBuilder = "";
8832
+ let once = false;
8833
+ for (const sort2 of sortArr) {
8834
+ const { foreignTables, queryKey } = resolveTableToQuery(table, tables, joinBuilder, [...path, ...sort2.key], void 0, true);
8835
+ for (const foreignTable of foreignTables) {
8836
+ if (once) {
8837
+ orderByBuilder += ", ";
8838
+ }
8839
+ once = true;
8840
+ foreignTable.columns.push(queryKey);
8841
+ orderByBuilder += `"${foreignTable.as}#${queryKey}" ${sort2.direction === SortDirection.ASC ? "ASC" : "DESC"}`;
8842
+ resolverBuilder.push({
8843
+ from: `${table.name}.${escapeColumnName(queryKey)}`,
8844
+ as: `'${foreignTable.as}#${queryKey}'`
8845
+ });
8846
+ }
8847
+ }
8848
+ }
8849
+ }
8850
+ return { orderByBuilder };
8851
+ };
8685
8852
  var convertSearchRequestToQuery = (request, tables, rootTables, options) => {
8686
8853
  let unionBuilder = "";
8687
8854
  let orderByClause = "";
@@ -8690,16 +8857,12 @@ var convertSearchRequestToQuery = (request, tables, rootTables, options) => {
8690
8857
  const selectsPerTable = selectAllFieldsFromTables(rootTables, options?.shape);
8691
8858
  let bindableBuilder = [];
8692
8859
  for (const [i, table] of rootTables.entries()) {
8693
- const { selects, joins: joinFromSelect } = selectsPerTable[i];
8694
- const selectQuery = generateSelectQuery(table, selects);
8860
+ const { selects, joins, groupBy } = selectsPerTable[i];
8695
8861
  try {
8696
- const { orderBy, query, bindable } = convertRequestToQuery("iterate", request, tables, table, joinFromSelect, [], {
8697
- stable: options?.stable
8698
- });
8699
- unionBuilder += `${unionBuilder.length > 0 ? " UNION ALL " : ""} ${selectQuery} ${query}`;
8700
- orderByClause = orderBy?.length > 0 ? orderByClause.length > 0 ? orderByClause + ", " + orderBy : orderBy : orderByClause;
8701
- matchedOnce = true;
8702
- bindableBuilder.push(...bindable);
8862
+ const { orderByBuilder } = buildOrderBy(request?.sort, tables, table, joins, selects, [], options);
8863
+ if (!orderByClause && orderByBuilder) {
8864
+ orderByClause = orderByBuilder.length > 0 ? orderByClause.length > 0 ? orderByClause + ", " + orderByBuilder : orderByBuilder : orderByClause;
8865
+ }
8703
8866
  } catch (error2) {
8704
8867
  if (error2 instanceof MissingFieldError) {
8705
8868
  lastError = error2;
@@ -8707,122 +8870,159 @@ var convertSearchRequestToQuery = (request, tables, rootTables, options) => {
8707
8870
  }
8708
8871
  throw error2;
8709
8872
  }
8873
+ const selectQuery = generateSelectQuery(table, selects);
8874
+ for (const flattenRequest of flattenQuery(request)) {
8875
+ try {
8876
+ const { query, bindable } = convertRequestToQuery(
8877
+ "iterate",
8878
+ flattenRequest,
8879
+ tables,
8880
+ table,
8881
+ new Map(joins),
8882
+ // copy the map, else we might might do unececessary joins
8883
+ [],
8884
+ options
8885
+ );
8886
+ unionBuilder += `${unionBuilder.length > 0 ? " UNION " : ""} ${selectQuery} ${query} ${groupBy ? "GROUP BY " + groupBy : ""}`;
8887
+ matchedOnce = true;
8888
+ bindableBuilder.push(...bindable);
8889
+ } catch (error2) {
8890
+ if (error2 instanceof MissingFieldError) {
8891
+ lastError = error2;
8892
+ orderByClause = "";
8893
+ continue;
8894
+ }
8895
+ throw error2;
8896
+ }
8897
+ }
8710
8898
  }
8711
8899
  if (!matchedOnce) {
8712
8900
  throw lastError;
8713
8901
  }
8714
8902
  return {
8715
- sql: `${unionBuilder} ${orderByClause ? "ORDER BY " + orderByClause : ""} limit ? offset ?`,
8903
+ sql: `${unionBuilder} ${orderByClause ? "ORDER BY " + orderByClause : ""} ${options?.fetchAll ? "" : "limit ? offset ?"}`,
8716
8904
  bindable: bindableBuilder
8717
8905
  };
8718
8906
  };
8719
- function isIterateRequest(request, type) {
8720
- return type === "iterate";
8721
- }
8907
+ var getOrSetRootTable = (joinBuilder, table) => {
8908
+ const refName = createQueryTableReferenceName(table);
8909
+ let ref = joinBuilder.get(refName);
8910
+ if (ref) {
8911
+ return ref;
8912
+ }
8913
+ const join = {
8914
+ // add the root as a join even though it is not, just so we can collect the columns it will be queried
8915
+ table,
8916
+ type: "root",
8917
+ as: table.name,
8918
+ columns: []
8919
+ };
8920
+ joinBuilder.set(refName, join);
8921
+ return join;
8922
+ };
8722
8923
  var convertRequestToQuery = (type, request, tables, table, extraJoin, path = [], options) => {
8723
8924
  let whereBuilder = "";
8724
8925
  let bindableBuilder = [];
8725
- let orderByBuilder = void 0;
8726
8926
  let joinBuilder = extraJoin || /* @__PURE__ */ new Map();
8927
+ getOrSetRootTable(joinBuilder, table);
8727
8928
  const coercedQuery = toQuery(request?.query);
8728
8929
  if (coercedQuery.length === 1) {
8729
- const { where: where2, bindable } = convertQueryToSQLQuery(coercedQuery[0], tables, table, joinBuilder, path);
8930
+ const { where: where2, bindable } = convertQueryToSQLQuery(coercedQuery[0], tables, table, joinBuilder, path, void 0, 0);
8730
8931
  whereBuilder += where2;
8731
8932
  bindableBuilder.push(...bindable);
8732
8933
  } else if (coercedQuery.length > 1) {
8733
- const { where: where2, bindable } = convertQueryToSQLQuery(new And(coercedQuery), tables, table, joinBuilder, path);
8934
+ const { where: where2, bindable } = convertQueryToSQLQuery(new And(coercedQuery), tables, table, joinBuilder, path, void 0, 0);
8734
8935
  whereBuilder += where2;
8735
8936
  bindableBuilder.push(...bindable);
8736
8937
  }
8737
- if (isIterateRequest(request, type)) {
8738
- let sort = request?.sort;
8739
- if (!sort && options?.stable) {
8740
- sort = table.primary && path.length === 0 ? [{ key: [table.primary], direction: SortDirection.ASC }] : void 0;
8741
- }
8742
- if (sort) {
8743
- let sortArr = Array.isArray(sort) ? sort : [sort];
8744
- if (sortArr.length > 0) {
8745
- orderByBuilder = "";
8746
- let once = false;
8747
- for (const sort2 of sortArr) {
8748
- const { foreignTables, queryKey } = resolveTableToQuery(table, tables, joinBuilder, [...path, ...sort2.key], void 0, true);
8749
- for (const table2 of foreignTables) {
8750
- if (once) {
8751
- orderByBuilder += ", ";
8752
- }
8753
- once = true;
8754
- orderByBuilder += `${table2.as}.${queryKey} ${sort2.direction === SortDirection.ASC ? "ASC" : "DESC"}`;
8755
- }
8756
- }
8757
- }
8758
- }
8759
- }
8760
8938
  const where = whereBuilder.length > 0 ? "where " + whereBuilder : void 0;
8761
8939
  if (extraJoin && extraJoin.size > 0) {
8762
8940
  insertMapIntoMap(joinBuilder, extraJoin);
8763
8941
  }
8764
- let join = buildJoin(joinBuilder, type === "iterate" ? true : false);
8942
+ let { join } = buildJoin(joinBuilder, options);
8765
8943
  const query = `${join ? join : ""} ${where ? where : ""}`;
8766
8944
  return {
8767
8945
  query,
8768
- orderBy: orderByBuilder,
8946
+ /* orderBy: orderByBuilder, */
8769
8947
  bindable: bindableBuilder
8770
8948
  };
8771
8949
  };
8772
- var buildJoin = (joinBuilder, resolveAllColumns) => {
8773
- let joinTypeDefault = resolveAllColumns ? (
8774
- /* "FULL OUTER JOIN" */
8775
- "LEFT OUTER JOIN"
8776
- ) : "JOIN";
8950
+ var buildJoin = (joinBuilder, options) => {
8777
8951
  let join = "";
8778
8952
  for (const [_key, table] of joinBuilder) {
8953
+ if (table.type !== "root") {
8954
+ continue;
8955
+ }
8956
+ const out = _buildJoin(table, options);
8957
+ join += out.join;
8958
+ }
8959
+ for (const [_key, table] of joinBuilder) {
8960
+ if (table.type === "root") {
8961
+ continue;
8962
+ }
8963
+ const out = _buildJoin(table, options);
8964
+ join += out.join;
8965
+ }
8966
+ return { join };
8967
+ };
8968
+ var _buildJoin = (table, options) => {
8969
+ let join = "";
8970
+ let indexedBy = void 0;
8971
+ if (table.type !== "root") {
8972
+ table.columns.push(PARENT_TABLE_ID);
8973
+ }
8974
+ if (table.columns.length > 0) {
8975
+ const usedColumns = removeDuplicatesOrdered(table.columns);
8976
+ indexedBy = options?.planner ? ` INDEXED BY ${options.planner.resolveIndex(table.table.name, usedColumns)} ` : "";
8977
+ }
8978
+ if (table.type !== "root") {
8779
8979
  let nonInlinedParent = table.table.parent && getNonInlinedTable(table.table.parent);
8780
8980
  if (!nonInlinedParent) {
8781
8981
  throw new Error("Unexpected: missing parent");
8782
8982
  }
8783
- let joinType = table.table.referencedInArray ? (
8784
- /* "FULL OUTER JOIN" */
8785
- "LEFT OUTER JOIN"
8786
- ) : joinTypeDefault;
8787
- join += `${joinType} ${table.table.name} AS ${table.as} ON ${nonInlinedParent.name}.${nonInlinedParent.primary} = ${table.as}.${PARENT_TABLE_ID} `;
8983
+ let joinType = table.type === "cross" ? "LEFT JOIN" : "LEFT JOIN";
8984
+ join += ` ${joinType} ${table.table.name} AS ${table.as} ${indexedBy} ON ${nonInlinedParent.name}.${nonInlinedParent.primary} = ${table.as}.${PARENT_TABLE_ID} `;
8985
+ } else if (indexedBy) {
8986
+ join += indexedBy;
8788
8987
  }
8789
- return join;
8988
+ return { join };
8790
8989
  };
8791
8990
  var insertMapIntoMap = (map, insert2) => {
8792
8991
  for (const [key, value] of insert2) {
8793
8992
  map.set(key, value);
8794
8993
  }
8795
8994
  };
8796
- var convertQueryToSQLQuery = (query, tables, table, joinBuilder, path = [], tableAlias = void 0) => {
8995
+ var convertQueryToSQLQuery = (query, tables, table, joinBuilder, path, tableAlias, skipKeys) => {
8797
8996
  let whereBuilder = "";
8798
8997
  let bindableBuilder = [];
8799
- const handleAnd = (queries, path2, tableAlias2) => {
8998
+ const handleAnd = (queries, path2, tableAlias2, keysOffset) => {
8800
8999
  for (const query2 of queries) {
8801
- const { where, bindable } = convertQueryToSQLQuery(query2, tables, table, joinBuilder, path2, tableAlias2);
9000
+ const { where, bindable } = convertQueryToSQLQuery(query2, tables, table, joinBuilder, path2, tableAlias2, keysOffset);
8802
9001
  whereBuilder = whereBuilder.length > 0 ? `(${whereBuilder}) AND (${where})` : where;
8803
9002
  bindableBuilder.push(...bindable);
8804
9003
  }
8805
9004
  };
8806
9005
  if (query instanceof StateFieldQuery) {
8807
- const { where, bindable } = convertStateFieldQuery(query, tables, table, joinBuilder, path, tableAlias);
9006
+ const { where, bindable } = convertStateFieldQuery(query, tables, table, joinBuilder, path, tableAlias, skipKeys);
8808
9007
  whereBuilder += where;
8809
9008
  bindableBuilder.push(...bindable);
8810
9009
  } else if (query instanceof Nested) {
8811
9010
  let joinPrefix = "__" + String(tables.size);
8812
- path = [...path, query.path];
8813
- handleAnd(query.query, path, joinPrefix);
9011
+ path = [...path, ...query.path];
9012
+ let newSkipKeys = skipKeys + query.path.length;
9013
+ handleAnd(query.query, path, joinPrefix, newSkipKeys);
8814
9014
  } else if (query instanceof LogicalQuery) {
8815
9015
  if (query instanceof And) {
8816
- handleAnd(query.and, path, tableAlias);
9016
+ handleAnd(query.and, path, tableAlias, skipKeys);
8817
9017
  } else if (query instanceof Or) {
8818
9018
  for (const subquery of query.or) {
8819
- const { where, bindable } = convertQueryToSQLQuery(subquery, tables, table, joinBuilder, path, tableAlias);
8820
- whereBuilder = whereBuilder.length > 0 ? `(${whereBuilder}) OR (${where})` : where;
9019
+ const { where, bindable } = convertQueryToSQLQuery(subquery, tables, table, joinBuilder, path, tableAlias, skipKeys);
9020
+ whereBuilder = whereBuilder.length > 0 ? `(${whereBuilder}) OR(${where})` : where;
8821
9021
  bindableBuilder.push(...bindable);
8822
9022
  }
8823
9023
  } else if (query instanceof Not) {
8824
- const { where, bindable } = convertQueryToSQLQuery(query.not, tables, table, joinBuilder, path, tableAlias);
8825
- whereBuilder = `NOT (${where})`;
9024
+ const { where, bindable } = convertQueryToSQLQuery(query.not, tables, table, joinBuilder, path, tableAlias, skipKeys);
9025
+ whereBuilder = `NOT(${where})`;
8826
9026
  bindableBuilder.push(...bindable);
8827
9027
  } else {
8828
9028
  throw new Error("Unsupported query type: " + query.constructor.name);
@@ -8838,13 +9038,11 @@ var convertQueryToSQLQuery = (query, tables, table, joinBuilder, path = [], tabl
8838
9038
  var cloneQuery = (query) => {
8839
9039
  return deserialize(serialize(query), StateFieldQuery);
8840
9040
  };
8841
- var createTableReferenceName = (table, alias, fieldType, joinSize) => {
8842
- if (!alias && (fieldType instanceof VecKind || fieldType instanceof OptionKind && fieldType.elementType instanceof VecKind)) {
8843
- let aliasSuffix = "_" + String(joinSize);
8844
- alias = aliasSuffix;
8845
- }
8846
- const tableNameAs = alias ? alias + "_" + table.name : table.name;
8847
- return tableNameAs;
9041
+ var createQueryTableReferenceName = (table) => {
9042
+ return table.parent == null ? table.name : "_query_" + table.name;
9043
+ };
9044
+ var createReconstructReferenceName = (table) => {
9045
+ return table.name;
8848
9046
  };
8849
9047
  var resolveTableToQuery = (table, tables, join, path, alias, searchSelf) => {
8850
9048
  if (searchSelf) {
@@ -8853,11 +9051,18 @@ var resolveTableToQuery = (table, tables, join, path, alias, searchSelf) => {
8853
9051
  if (field2) {
8854
9052
  return {
8855
9053
  queryKey: field2.name,
8856
- foreignTables: [{ table, as: table.name }]
9054
+ foreignTables: [getOrSetRootTable(join, table)]
8857
9055
  };
8858
9056
  }
8859
9057
  }
8860
- let currentTables = [{ table, as: alias || table.name }];
9058
+ let currentTables = [
9059
+ {
9060
+ table,
9061
+ as: alias || table.name,
9062
+ type: "cross",
9063
+ columns: []
9064
+ }
9065
+ ];
8861
9066
  let prevTables = void 0;
8862
9067
  for (const [_i, key] of path.entries()) {
8863
9068
  let newTables = [];
@@ -8865,13 +9070,18 @@ var resolveTableToQuery = (table, tables, join, path, alias, searchSelf) => {
8865
9070
  const schema = getSchema(currentTable.ctor);
8866
9071
  const field2 = schema.fields.find((x) => x.key === key);
8867
9072
  if (!field2 && currentTable.children.length > 0) {
8868
- throw new MissingFieldError(`Property with key "${key}" is not found in the schema ${JSON.stringify(schema.fields.map((x) => x.key))}`);
9073
+ throw new MissingFieldError(`Property with key "${key}" is not found in the schema ${JSON.stringify(schema.fields.map((x) => x.key))} `);
8869
9074
  }
8870
9075
  for (const child of currentTable.children) {
8871
- const tableNameAs = createTableReferenceName(child, alias, field2.type, join.size);
9076
+ const tableNameAs = createQueryTableReferenceName(child);
8872
9077
  let isMatching = child.parentPath[child.parentPath.length - 1] === key;
8873
9078
  if (isMatching) {
8874
- const tableWithAlias = { table: child, as: tableNameAs };
9079
+ const tableWithAlias = {
9080
+ columns: [],
9081
+ table: child,
9082
+ as: tableNameAs,
9083
+ type: currentTable.children.length > 1 ? "left" : "cross"
9084
+ };
8875
9085
  if (child.isSimpleValue) {
8876
9086
  if (!child.inline) {
8877
9087
  join.set(tableNameAs, tableWithAlias);
@@ -8911,12 +9121,16 @@ var resolveTableToQuery = (table, tables, join, path, alias, searchSelf) => {
8911
9121
  let queryKey = queryKeyPath.length > 0 ? getInlineTableFieldName(queryKeyPath) : FOREIGN_VALUE_PROPERTY;
8912
9122
  return { queryKey, foreignTables };
8913
9123
  };
8914
- var convertStateFieldQuery = (query, tables, table, join, path, tableAlias = void 0) => {
9124
+ var convertStateFieldQuery = (query, tables, table, join, path, tableAlias, skipKeys) => {
8915
9125
  const inlinedName = getInlineTableFieldName(query.key);
8916
9126
  const tableField = table.fields.find((x) => x.name === inlinedName);
8917
9127
  const isForeign = !tableField;
8918
9128
  if (isForeign) {
8919
- const { queryKey, foreignTables } = resolveTableToQuery(table, tables, join, [...path, ...query.key], tableAlias, false);
9129
+ const tablePath = [...path];
9130
+ for (let i = skipKeys; i < query.key.length; i++) {
9131
+ tablePath.push(query.key[i]);
9132
+ }
9133
+ const { queryKey, foreignTables } = resolveTableToQuery(table, tables, join, tablePath, tableAlias, false);
8920
9134
  query = cloneQuery(query);
8921
9135
  query.key = [queryKey];
8922
9136
  let whereBuilder = [];
@@ -8925,7 +9139,7 @@ var convertStateFieldQuery = (query, tables, table, join, path, tableAlias = voi
8925
9139
  if (ftable.table === table) {
8926
9140
  throw new Error("Unexpected");
8927
9141
  }
8928
- const { where: where2, bindable: bindable2 } = convertQueryToSQLQuery(query, tables, ftable.table, join, path, ftable.as);
9142
+ const { where: where2, bindable: bindable2 } = convertQueryToSQLQuery(query, tables, ftable.table, join, path, ftable.as, skipKeys);
8929
9143
  whereBuilder.push(where2);
8930
9144
  bindableBuilder.push(bindable2);
8931
9145
  }
@@ -8934,16 +9148,21 @@ var convertStateFieldQuery = (query, tables, table, join, path, tableAlias = voi
8934
9148
  bindable: bindableBuilder.flat()
8935
9149
  };
8936
9150
  }
9151
+ const columnAggregator = join.get(createQueryTableReferenceName(table));
9152
+ if (!columnAggregator) {
9153
+ throw new Error("Unexpected");
9154
+ }
9155
+ columnAggregator.columns.push(inlinedName);
8937
9156
  let bindable = [];
8938
9157
  const keyWithTable = (tableAlias || table.name) + "." + escapeColumnName(inlinedName);
8939
9158
  let where;
8940
9159
  if (query instanceof StringMatch) {
8941
9160
  let statement = "";
8942
9161
  if (query.method === StringMatchMethod.contains) {
8943
- statement = `${keyWithTable} LIKE ?`;
9162
+ statement = `${keyWithTable} LIKE ? `;
8944
9163
  bindable.push(`%${query.value}%`);
8945
9164
  } else if (query.method === StringMatchMethod.prefix) {
8946
- statement = `${keyWithTable} LIKE ?`;
9165
+ statement = `${keyWithTable} LIKE ? `;
8947
9166
  bindable.push(`${query.value}%`);
8948
9167
  } else if (query.method === StringMatchMethod.exact) {
8949
9168
  statement = `${keyWithTable} = ?`;
@@ -8959,24 +9178,24 @@ var convertStateFieldQuery = (query, tables, table, join, path, tableAlias = voi
8959
9178
  where = statement;
8960
9179
  } else if (query instanceof IntegerCompare) {
8961
9180
  if (tableField.type === "BLOB") {
8962
- where = `hex(${keyWithTable}) LIKE ?`;
9181
+ where = `hex(${keyWithTable}) LIKE ? `;
8963
9182
  bindable.push(`%${toHexString(new Uint8Array([Number(query.value.value)]))}%`);
8964
9183
  } else {
8965
9184
  if (query.compare === Compare.Equal) {
8966
9185
  where = `${keyWithTable} = ?`;
8967
9186
  } else if (query.compare === Compare.Greater) {
8968
- where = `${keyWithTable} > ?`;
9187
+ where = `${keyWithTable} > ? `;
8969
9188
  } else if (query.compare === Compare.Less) {
8970
- where = `${keyWithTable} < ?`;
9189
+ where = `${keyWithTable} <?`;
8971
9190
  } else if (query.compare === Compare.GreaterOrEqual) {
8972
- where = `${keyWithTable} >= ?`;
9191
+ where = `${keyWithTable} >= ? `;
8973
9192
  } else if (query.compare === Compare.LessOrEqual) {
8974
- where = `${keyWithTable} <= ?`;
9193
+ where = `${keyWithTable} <= ? `;
8975
9194
  } else {
8976
- throw new Error(`Unsupported compare type: ${query.compare}`);
9195
+ throw new Error(`Unsupported compare type: ${query.compare} `);
8977
9196
  }
8978
9197
  if (unwrapNestedType(tableField.from.type) === "u64") {
8979
- bindable.push(query.value.value);
9198
+ bindable.push(u64ToI64(query.value.value));
8980
9199
  } else {
8981
9200
  bindable.push(query.value.value);
8982
9201
  }
@@ -8991,6 +9210,253 @@ var convertStateFieldQuery = (query, tables, table, join, path, tableAlias = voi
8991
9210
  }
8992
9211
  return { where, bindable };
8993
9212
  };
9213
+ var removeDuplicatesOrdered = (arr) => {
9214
+ let seen = /* @__PURE__ */ new Set();
9215
+ return arr.filter((item) => {
9216
+ if (seen.has(item)) {
9217
+ return false;
9218
+ }
9219
+ seen.add(item);
9220
+ return true;
9221
+ });
9222
+ };
9223
+
9224
+ // dist/src/query-planner.js
9225
+ var __decorate4 = function(decorators, target, key, desc) {
9226
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
9227
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
9228
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
9229
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
9230
+ };
9231
+ var __metadata4 = function(k, v2) {
9232
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v2);
9233
+ };
9234
+ var getSortedNameKey = (tableName, names) => [tableName, ...names.sort()].join(",");
9235
+ var createIndexKey = (tableName, fields) => `${tableName}_index_${fields.map((x) => x).join("_")}`;
9236
+ var HALF_MAX_U32 = 2147483647;
9237
+ var HALF_MAX_U64 = 9223372036854775807n;
9238
+ var flattenQuery = function* (props) {
9239
+ if (!props) {
9240
+ return yield props;
9241
+ }
9242
+ let ors = [];
9243
+ let ands = [];
9244
+ let stack = [...props.query];
9245
+ let foundOr = false;
9246
+ for (const q of stack) {
9247
+ if (q instanceof Or) {
9248
+ if (foundOr) {
9249
+ yield props;
9250
+ return;
9251
+ }
9252
+ ors = q.or;
9253
+ foundOr = true;
9254
+ } else if (q instanceof And) {
9255
+ for (const a of q.and) {
9256
+ stack.push(a);
9257
+ }
9258
+ } else {
9259
+ ands.push(q);
9260
+ }
9261
+ }
9262
+ let maxFlatten = 4;
9263
+ if (ors.length === 0 || ors.length >= maxFlatten) {
9264
+ yield {
9265
+ query: ands,
9266
+ sort: props.sort
9267
+ };
9268
+ return;
9269
+ }
9270
+ for (const or2 of ors) {
9271
+ yield {
9272
+ query: [...ands, ...Array.isArray(or2) ? or2 : [or2]],
9273
+ sort: props.sort
9274
+ };
9275
+ }
9276
+ };
9277
+ var reduceResolution = (value) => {
9278
+ if (value instanceof UnsignedIntegerValue) {
9279
+ return value.number > HALF_MAX_U32 ? new UnsignedIntegerValue(HALF_MAX_U32) : new UnsignedIntegerValue(0);
9280
+ }
9281
+ if (value instanceof BigUnsignedIntegerValue) {
9282
+ return value.value > HALF_MAX_U64 ? new BigUnsignedIntegerValue(HALF_MAX_U64) : new BigUnsignedIntegerValue(0n);
9283
+ }
9284
+ throw new Error("Unknown integer value type: " + value?.constructor.name);
9285
+ };
9286
+ var nullifyQuery = (query) => {
9287
+ if (query instanceof IntegerCompare) {
9288
+ return new IntegerCompare({
9289
+ compare: Compare.Equal,
9290
+ value: reduceResolution(query.value),
9291
+ key: query.key
9292
+ });
9293
+ } else if (query instanceof StringMatch) {
9294
+ return new StringMatch({
9295
+ key: query.key,
9296
+ value: "",
9297
+ method: query.method
9298
+ });
9299
+ } else if (query instanceof ByteMatchQuery) {
9300
+ return new ByteMatchQuery({
9301
+ key: query.key,
9302
+ value: new Uint8Array()
9303
+ });
9304
+ } else if (query instanceof BoolQuery) {
9305
+ return new BoolQuery({
9306
+ key: query.key,
9307
+ value: false
9308
+ });
9309
+ } else if (query instanceof And) {
9310
+ let and = [];
9311
+ for (const condition of query.and) {
9312
+ and.push(nullifyQuery(condition));
9313
+ }
9314
+ return new And(and);
9315
+ } else if (query instanceof Or) {
9316
+ let or2 = [];
9317
+ for (const condition of query.or) {
9318
+ or2.push(nullifyQuery(condition));
9319
+ }
9320
+ return new Or(or2);
9321
+ } else if (query instanceof Not) {
9322
+ return new Not(nullifyQuery(query.not));
9323
+ } else if (query instanceof IsNull) {
9324
+ return query;
9325
+ } else if (query instanceof Nested) {
9326
+ throw new Error("Unsupported query type, deprecated");
9327
+ }
9328
+ throw new Error("Unknown query type: " + query?.constructor.name);
9329
+ };
9330
+ var PlannableQuery = class _PlannableQuery {
9331
+ query;
9332
+ sort;
9333
+ constructor(props) {
9334
+ this.query = props.query;
9335
+ this.sort = Array.isArray(props.sort) ? props.sort : props.sort ? [props.sort] : [];
9336
+ }
9337
+ get key() {
9338
+ let query = this.query.map((x) => nullifyQuery(x));
9339
+ let nullifiedPlannableQuery = new _PlannableQuery({
9340
+ query,
9341
+ sort: this.sort
9342
+ });
9343
+ return sha256Base64Sync(serialize(nullifiedPlannableQuery));
9344
+ }
9345
+ };
9346
+ __decorate4([
9347
+ field({ type: vec(Query) }),
9348
+ __metadata4("design:type", Array)
9349
+ ], PlannableQuery.prototype, "query", void 0);
9350
+ __decorate4([
9351
+ field({ type: vec(Sort) }),
9352
+ __metadata4("design:type", Array)
9353
+ ], PlannableQuery.prototype, "sort", void 0);
9354
+ var QueryPlanner = class {
9355
+ props;
9356
+ stats = /* @__PURE__ */ new Map();
9357
+ pendingIndexCreation = /* @__PURE__ */ new Map();
9358
+ constructor(props) {
9359
+ this.props = props;
9360
+ }
9361
+ async stop() {
9362
+ for (const promise of this.pendingIndexCreation.values()) {
9363
+ await promise.catch(() => {
9364
+ });
9365
+ }
9366
+ this.stats.clear();
9367
+ }
9368
+ scope(query) {
9369
+ let obj = this.stats.get(query.key);
9370
+ if (obj === void 0) {
9371
+ obj = {
9372
+ columnsToIndexes: /* @__PURE__ */ new Map()
9373
+ };
9374
+ this.stats.set(query.key, obj);
9375
+ }
9376
+ let indexCreateCommands = void 0;
9377
+ let pickedIndexKeys = /* @__PURE__ */ new Map();
9378
+ return {
9379
+ beforePrepare: async () => {
9380
+ if (indexCreateCommands != null) {
9381
+ for (const { key, cmd } of indexCreateCommands) {
9382
+ if (this.pendingIndexCreation.has(key)) {
9383
+ await this.pendingIndexCreation.get(key);
9384
+ }
9385
+ const promise = this.props.exec(cmd);
9386
+ this.pendingIndexCreation.set(key, promise);
9387
+ await promise;
9388
+ this.pendingIndexCreation.delete(key);
9389
+ }
9390
+ }
9391
+ if (this.pendingIndexCreation.size > 0) {
9392
+ for (const picked of pickedIndexKeys.keys()) {
9393
+ await this.pendingIndexCreation.get(picked);
9394
+ }
9395
+ }
9396
+ },
9397
+ resolveIndex: (tableName, columns) => {
9398
+ const sortedNameKey = getSortedNameKey(tableName, columns);
9399
+ let indexStats = obj.columnsToIndexes.get(sortedNameKey);
9400
+ if (indexStats === void 0) {
9401
+ indexStats = {
9402
+ results: []
9403
+ };
9404
+ obj.columnsToIndexes.set(sortedNameKey, indexStats);
9405
+ }
9406
+ if (indexStats.results.length === 0) {
9407
+ const permutations = generatePermutations(columns);
9408
+ for (const columns2 of permutations) {
9409
+ const indexKey = createIndexKey(tableName, columns2);
9410
+ const command = `create index if not exists ${indexKey} on ${tableName} (${columns2.map((n) => escapeColumnName(n)).join(", ")})`;
9411
+ (indexCreateCommands || (indexCreateCommands = [])).push({
9412
+ cmd: command,
9413
+ key: indexKey
9414
+ });
9415
+ indexStats.results.push({
9416
+ used: 0,
9417
+ times: [],
9418
+ avg: -1,
9419
+ // setting -1 will force the first time to be the fastest (i.e. new indices are always tested once)
9420
+ indexKey
9421
+ });
9422
+ }
9423
+ }
9424
+ let fastestIndex = indexStats.results[0];
9425
+ fastestIndex.used++;
9426
+ pickedIndexKeys.set(fastestIndex.indexKey, sortedNameKey);
9427
+ return fastestIndex.indexKey;
9428
+ },
9429
+ perform: async (fn) => {
9430
+ let t0 = hrtime.bigint();
9431
+ const out = await fn();
9432
+ let t1 = hrtime.bigint();
9433
+ const time = Number(t1 - t0);
9434
+ for (const [indexKey, columnsKey] of pickedIndexKeys) {
9435
+ const indexStats = obj.columnsToIndexes.get(columnsKey);
9436
+ if (indexStats === void 0) {
9437
+ throw new Error("index stats not found");
9438
+ }
9439
+ const index = indexStats.results.find((x) => x.indexKey === indexKey);
9440
+ if (index === void 0) {
9441
+ throw new Error("index not found");
9442
+ }
9443
+ index.times.push(time);
9444
+ if (index.times.length > 20) {
9445
+ index.times.shift();
9446
+ }
9447
+ index.avg = index.times.reduce((a, b) => a + b, 0) / index.times.length;
9448
+ indexStats.results.sort((a, b) => a.avg - b.avg);
9449
+ }
9450
+ return out;
9451
+ }
9452
+ };
9453
+ }
9454
+ };
9455
+ var generatePermutations = (list) => {
9456
+ if (list.length === 1)
9457
+ return [list];
9458
+ return [list, [...list].reverse()];
9459
+ };
8994
9460
 
8995
9461
  // dist/src/engine.js
8996
9462
  var escapePathToSQLName = (path) => {
@@ -9003,11 +9469,13 @@ var SQLLiteIndex = class {
9003
9469
  properties;
9004
9470
  primaryKeyArr;
9005
9471
  primaryKeyString;
9472
+ planner;
9006
9473
  scopeString;
9007
9474
  _rootTables;
9008
9475
  _tables;
9009
9476
  _cursor;
9010
9477
  // TODO choose limit better
9478
+ cursorPruner;
9011
9479
  iteratorTimeout;
9012
9480
  closed = true;
9013
9481
  id;
@@ -9017,22 +9485,25 @@ var SQLLiteIndex = class {
9017
9485
  this.id = v4_default();
9018
9486
  this.scopeString = properties.scope.length > 0 ? "_" + escapePathToSQLName(properties.scope).join("_") : void 0;
9019
9487
  this.iteratorTimeout = options?.iteratorTimeout || 6e4;
9488
+ this.planner = new QueryPlanner({
9489
+ exec: this.properties.db.exec.bind(this.properties.db)
9490
+ });
9020
9491
  }
9021
9492
  get tables() {
9022
9493
  if (this.closed) {
9023
- throw new Error("Not started");
9494
+ throw new NotStartedError();
9024
9495
  }
9025
9496
  return this._tables;
9026
9497
  }
9027
9498
  get rootTables() {
9028
9499
  if (this.closed) {
9029
- throw new Error("Not started");
9500
+ throw new NotStartedError();
9030
9501
  }
9031
9502
  return this._rootTables;
9032
9503
  }
9033
9504
  get cursor() {
9034
9505
  if (this.closed) {
9035
- throw new Error("Not started");
9506
+ throw new NotStartedError();
9036
9507
  }
9037
9508
  return this._cursor;
9038
9509
  }
@@ -9082,9 +9553,7 @@ var SQLLiteIndex = class {
9082
9553
  continue;
9083
9554
  }
9084
9555
  const sqlCreateTable = `create table if not exists ${table.name} (${[...table.fields, ...table.constraints].map((s) => s.definition).join(", ")}) strict`;
9085
- const sqlCreateIndex = `create index if not exists ${table.name}_index on ${table.name} (${table.fields.map((field2) => escapeColumnName(field2.name)).join(", ")})`;
9086
9556
  this.properties.db.exec(sqlCreateTable);
9087
- this.properties.db.exec(sqlCreateIndex);
9088
9557
  let sqlPut = `insert into ${table.name} (${table.fields.map((field2) => escapeColumnName(field2.name)).join(", ")}) VALUES (${table.fields.map((_x) => "?").join(", ")}) RETURNING ${table.primary};`;
9089
9558
  let sqlReplace = `insert or replace into ${table.name} (${table.fields.map((field2) => escapeColumnName(field2.name)).join(", ")}) VALUES (${table.fields.map((_x) => "?").join(", ")});`;
9090
9559
  await this.properties.db.prepare(sqlPut, putStatementKey(table));
@@ -9093,6 +9562,14 @@ var SQLLiteIndex = class {
9093
9562
  await this.properties.db.prepare(selectChildren(table), resolveChildrenStatement(table));
9094
9563
  }
9095
9564
  }
9565
+ this.cursorPruner = setInterval(() => {
9566
+ const now = Date.now();
9567
+ for (const [k, v2] of this._cursor) {
9568
+ if (v2.expire < now) {
9569
+ this.clearupIterator(k);
9570
+ }
9571
+ }
9572
+ }, this.iteratorTimeout);
9096
9573
  this.closed = false;
9097
9574
  }
9098
9575
  async clearStatements() {
@@ -9105,14 +9582,20 @@ var SQLLiteIndex = class {
9105
9582
  return;
9106
9583
  }
9107
9584
  this.closed = true;
9585
+ clearInterval(this.cursorPruner);
9108
9586
  await this.clearStatements();
9109
9587
  this._tables.clear();
9110
9588
  for (const [k, _v] of this._cursor) {
9111
9589
  await this.clearupIterator(k);
9112
9590
  }
9591
+ await this.planner.stop();
9113
9592
  }
9114
9593
  async drop() {
9594
+ if (this.closed) {
9595
+ throw new Error(`Already closed index ${this.id}, can not drop`);
9596
+ }
9115
9597
  this.closed = true;
9598
+ clearInterval(this.cursorPruner);
9116
9599
  await this.clearStatements();
9117
9600
  for (const table of this._rootTables) {
9118
9601
  await this.properties.db.exec(`drop table if exists ${table.name}`);
@@ -9121,6 +9604,7 @@ var SQLLiteIndex = class {
9121
9604
  for (const [k, _v] of this._cursor) {
9122
9605
  await this.clearupIterator(k);
9123
9606
  }
9607
+ await this.planner.stop();
9124
9608
  }
9125
9609
  async resolveDependencies(parentId, table) {
9126
9610
  const stmt = this.properties.db.statements.get(resolveChildrenStatement(table));
@@ -9131,33 +9615,40 @@ var SQLLiteIndex = class {
9131
9615
  async get(id, options) {
9132
9616
  for (const table of this._rootTables) {
9133
9617
  const { join: joinMap, selects } = selectAllFieldsFromTable(table, options?.shape);
9134
- const sql = `${generateSelectQuery(table, selects)} ${buildJoin(joinMap, true)} where ${this.primaryKeyString} = ? limit 1`;
9135
- const stmt = await this.properties.db.prepare(sql, sql);
9136
- const rows = await stmt.get([
9137
- table.primaryField?.from?.type ? convertToSQLType(id.key, table.primaryField.from.type) : id.key
9138
- ]);
9139
- if (!rows) {
9140
- continue;
9618
+ const sql = `${generateSelectQuery(table, selects)} ${buildJoin(joinMap).join} where ${this.primaryKeyString} = ? limit 1`;
9619
+ try {
9620
+ const stmt = await this.properties.db.prepare(sql, sql);
9621
+ const rows = await stmt.get([
9622
+ table.primaryField?.from?.type ? convertToSQLType(id.key, table.primaryField.from.type) : id.key
9623
+ ]);
9624
+ if (rows?.[getTablePrefixedField(table, table.primary)] == null) {
9625
+ continue;
9626
+ }
9627
+ return {
9628
+ value: await resolveInstanceFromValue(rows, this.tables, table, this.resolveDependencies.bind(this), true, options?.shape),
9629
+ id
9630
+ };
9631
+ } catch (error2) {
9632
+ if (this.closed) {
9633
+ throw new NotStartedError();
9634
+ }
9635
+ throw error2;
9141
9636
  }
9142
- return {
9143
- value: await resolveInstanceFromValue(rows, this.tables, table, this.resolveDependencies.bind(this), true, options?.shape),
9144
- id
9145
- };
9146
9637
  }
9147
9638
  return void 0;
9148
9639
  }
9149
9640
  async put(value, _id) {
9150
9641
  const classOfValue = value.constructor;
9151
9642
  return insert(async (values, table) => {
9152
- const preId = values[table.primaryIndex];
9643
+ let preId = values[table.primaryIndex];
9153
9644
  if (preId != null) {
9154
9645
  const statement = this.properties.db.statements.get(replaceStatementKey(table));
9155
- await statement.run(values.map((x) => typeof x === "boolean" ? x ? 1 : 0 : x));
9646
+ await statement.run(values);
9156
9647
  await statement.reset?.();
9157
9648
  return preId;
9158
9649
  } else {
9159
9650
  const statement = this.properties.db.statements.get(putStatementKey(table));
9160
- const out = await statement.get(values.map((x) => typeof x === "boolean" ? x ? 1 : 0 : x));
9651
+ const out = await statement.get(values);
9161
9652
  await statement.reset?.();
9162
9653
  if (out == null) {
9163
9654
  return void 0;
@@ -9177,26 +9668,35 @@ var SQLLiteIndex = class {
9177
9668
  let kept = void 0;
9178
9669
  let bindable = [];
9179
9670
  let sqlFetch = void 0;
9671
+ const normalizedQuery = new PlannableQuery({
9672
+ query: toQuery(request?.query),
9673
+ sort: request?.sort
9674
+ });
9675
+ let planningScope;
9180
9676
  const fetch2 = async (amount) => {
9181
9677
  kept = void 0;
9182
9678
  if (!once) {
9183
- let { sql, bindable: toBind } = convertSearchRequestToQuery(request, this.tables, this._rootTables, {
9679
+ planningScope = this.planner.scope(normalizedQuery);
9680
+ let { sql, bindable: toBind } = convertSearchRequestToQuery(normalizedQuery, this.tables, this._rootTables, {
9681
+ planner: planningScope,
9184
9682
  shape: options?.shape,
9185
- stable: typeof amount === "number"
9683
+ fetchAll: amount === "all"
9186
9684
  // if we are to fetch all, we dont need stable sorting
9187
9685
  });
9188
9686
  sqlFetch = sql;
9189
9687
  bindable = toBind;
9688
+ await planningScope.beforePrepare();
9190
9689
  stmt = await this.properties.db.prepare(sqlFetch, sqlFetch);
9191
- clearTimeout(iterator.timeout);
9192
- iterator.timeout = setTimeout(() => this.clearupIterator(requestId), this.iteratorTimeout);
9690
+ iterator.expire = Date.now() + this.iteratorTimeout;
9193
9691
  }
9194
9692
  once = true;
9195
- const allResults = await stmt.all([
9196
- ...bindable,
9197
- amount === "all" ? Number.MAX_SAFE_INTEGER : amount,
9198
- offset
9199
- ]);
9693
+ const allResults = await planningScope.perform(async () => {
9694
+ const allResults2 = await stmt.all([
9695
+ ...bindable,
9696
+ ...amount !== "all" ? [amount, offset] : []
9697
+ ]);
9698
+ return allResults2;
9699
+ });
9200
9700
  let results = await Promise.all(allResults.map(async (row) => {
9201
9701
  let selectedTable = this._rootTables.find((table) => row[getTablePrefixedField(table, this.primaryKeyString)] != null);
9202
9702
  const value = await resolveInstanceFromValue(row, this.tables, selectedTable, this.resolveDependencies.bind(this), true, options?.shape);
@@ -9209,14 +9709,13 @@ var SQLLiteIndex = class {
9209
9709
  if (amount === "all" || results.length < amount) {
9210
9710
  hasMore = false;
9211
9711
  await this.clearupIterator(requestId);
9212
- clearTimeout(iterator.timeout);
9213
9712
  }
9214
9713
  return results;
9215
9714
  };
9216
9715
  const iterator = {
9217
9716
  fetch: fetch2,
9218
9717
  /* countStatement: countStmt, */
9219
- timeout: setTimeout(() => this.clearupIterator(requestId), this.iteratorTimeout)
9718
+ expire: Date.now() + this.iteratorTimeout
9220
9719
  };
9221
9720
  this.cursor.set(requestId, iterator);
9222
9721
  let totalCount = void 0;
@@ -9224,9 +9723,9 @@ var SQLLiteIndex = class {
9224
9723
  all: async () => {
9225
9724
  const results = [];
9226
9725
  while (true) {
9227
- const res = await fetch2(100);
9726
+ const res = await fetch2("all");
9228
9727
  results.push(...res);
9229
- if (res.length === 0) {
9728
+ if (hasMore === false) {
9230
9729
  break;
9231
9730
  }
9232
9731
  }
@@ -9258,7 +9757,6 @@ var SQLLiteIndex = class {
9258
9757
  if (!cache) {
9259
9758
  return;
9260
9759
  }
9261
- clearTimeout(cache.timeout);
9262
9760
  this._cursor.delete(id);
9263
9761
  }
9264
9762
  async getSize() {
@@ -9428,8 +9926,15 @@ var SQLiteIndices = class _SQLiteIndices {
9428
9926
  for (const scope of this.scopes.values()) {
9429
9927
  await scope.drop();
9430
9928
  }
9431
- for (const index of this.indices) {
9432
- await index.index.drop();
9929
+ if (!this.properties.parent) {
9930
+ for (const index of this.indices) {
9931
+ await index.index.stop();
9932
+ }
9933
+ await this.properties.db.drop();
9934
+ } else {
9935
+ for (const index of this.indices) {
9936
+ await index.index.drop();
9937
+ }
9433
9938
  }
9434
9939
  this.scopes.clear();
9435
9940
  }
@@ -17396,10 +17901,10 @@ var sqlite3InitModule = (() => {
17396
17901
  });
17397
17902
  globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite32) {
17398
17903
  sqlite32.version = {
17399
- libVersion: "3.47.0",
17400
- libVersionNumber: 3047e3,
17401
- sourceId: "2024-10-21 16:30:22 03a9703e27c44437c39363d0baf82db4ebc94538a0f28411c85dda156f82636e",
17402
- downloadVersion: 347e4
17904
+ libVersion: "3.47.2",
17905
+ libVersionNumber: 3047002,
17906
+ sourceId: "2024-12-07 20:39:59 2aabe05e2e8cae4847a802ee2daddc1d7413d8fc560254d93ee3e72c14685b6c",
17907
+ downloadVersion: 3470200
17403
17908
  };
17404
17909
  });
17405
17910
  globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite32) {
@@ -20919,13 +21424,20 @@ var create = async (directory) => {
20919
21424
  await sqliteDb?.close();
20920
21425
  sqliteDb = void 0;
20921
21426
  };
21427
+ let dbFileName;
21428
+ let drop = async () => {
21429
+ if (poolUtil && dbFileName != null) {
21430
+ poolUtil.unlink(dbFileName);
21431
+ }
21432
+ return close();
21433
+ };
20922
21434
  let open = async () => {
20923
21435
  if (sqliteDb) {
20924
21436
  return sqliteDb;
20925
21437
  }
20926
21438
  if (directory) {
20927
21439
  directory = directory.replace(/^\./, "");
20928
- let dbFileName = `${directory}/db.sqlite`;
21440
+ dbFileName = `${directory}/db.sqlite`;
20929
21441
  poolUtil = poolUtil || await sqlite3.installOpfsSAHPoolVfs({
20930
21442
  directory: "peerbit/sqlite"
20931
21443
  // encodeName("peerbit")
@@ -20944,6 +21456,7 @@ var create = async (directory) => {
20944
21456
  return sqliteDb.exec(sql);
20945
21457
  },
20946
21458
  open,
21459
+ drop,
20947
21460
  prepare: async (sql, id) => {
20948
21461
  if (id == null) {
20949
21462
  id = v4_default();
@@ -21095,6 +21608,13 @@ var ProxyDatabase = class {
21095
21608
  databaseId: this.databaseId
21096
21609
  });
21097
21610
  }
21611
+ async drop() {
21612
+ return this.send({
21613
+ type: "drop",
21614
+ id: v4_default(),
21615
+ databaseId: this.databaseId
21616
+ });
21617
+ }
21098
21618
  async status() {
21099
21619
  return this.send({
21100
21620
  type: "status",