convex-ents 0.8.1 → 0.9.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.
@@ -1,5 +1,5 @@
1
1
  import 'convex/values';
2
2
  import 'convex/server';
3
3
  import './schema.js';
4
- export { Y as DocRetriever, D as Ent, X as EntMutationCtx, V as EntQueryCtx, B as EntsTable, C as EntsTableWriter, G as GenericEnt, T as GenericEntWriter, y as PromiseArray, x as PromiseArrayOrNull, F as PromiseEdge, t as PromiseEdgeEnts, r as PromiseEdgeEntsOrNull, u as PromiseEdgeEntsWriter, s as PromiseEdgeEntsWriterOrNull, H as PromiseEdgeOrThrow, I as PromiseEdgeWriter, K as PromiseEdgeWriterOrNull, J as PromiseEdgeWriterOrThrow, w as PromiseEnt, U as PromiseEntId, v as PromiseEntOrNull, S as PromiseEntWriter, R as PromiseEntWriterOrNull, p as PromiseEnts, n as PromiseEntsOrNull, q as PromiseEntsOrNulls, N as PromiseEntsWriter, o as PromiseEntsWriterOrNull, j as PromiseOrderedQuery, i as PromiseOrderedQueryBase, P as PromiseOrderedQueryOrNull, L as PromiseOrderedQueryWriter, d as PromiseOrderedQueryWriterOrNull, m as PromisePaginationResult, l as PromisePaginationResultOrNull, O as PromisePaginationResultWriter, k as PromiseQuery, e as PromiseQueryOrNull, M as PromiseQueryWriter, f as PromiseQueryWriterOrNull, h as PromiseTable, g as PromiseTableBase, Q as PromiseTableWriter, Z as addEntRules, z as entWrapper, A as entsTableFactory, a1 as getDeletionConfig, a0 as getEdgeDefinitions, _ as getReadRule, $ as getWriteRule } from './index-uXk5iZ86.js';
4
+ export { a1 as DocRetriever, I as Ent, a0 as EntMutationCtx, $ as EntQueryCtx, G as EntsTable, H as EntsTableWriter, J as GenericEnt, Z as GenericEntWriter, C as PromiseArray, B as PromiseArrayOrNull, K as PromiseEdge, w as PromiseEdgeEnts, s as PromiseEdgeEntsOrNull, y as PromiseEdgeEntsWriter, u as PromiseEdgeEntsWriterOrNull, L as PromiseEdgeOrThrow, v as PromiseEdgeOrderedEnts, r as PromiseEdgeOrderedEntsOrNull, x as PromiseEdgeOrderedEntsWriter, t as PromiseEdgeOrderedEntsWriterOrNull, M as PromiseEdgeWriter, O as PromiseEdgeWriterOrNull, N as PromiseEdgeWriterOrThrow, A as PromiseEnt, _ as PromiseEntId, z as PromiseEntOrNull, Y as PromiseEntWriter, X as PromiseEntWriterOrNull, p as PromiseEnts, n as PromiseEntsOrNull, q as PromiseEntsOrNulls, S as PromiseEntsWriter, o as PromiseEntsWriterOrNull, j as PromiseOrderedQuery, i as PromiseOrderedQueryBase, P as PromiseOrderedQueryOrNull, Q as PromiseOrderedQueryWriter, d as PromiseOrderedQueryWriterOrNull, m as PromisePaginationResult, l as PromisePaginationResultOrNull, U as PromisePaginationResultWriter, T as PromisePaginationResultWriterOrNull, k as PromiseQuery, e as PromiseQueryOrNull, R as PromiseQueryWriter, f as PromiseQueryWriterOrNull, h as PromiseTable, g as PromiseTableBase, V as PromiseTableWriter, a2 as addEntRules, D as entWrapper, F as entsTableFactory, a6 as getDeletionConfig, a5 as getEdgeDefinitions, a3 as getReadRule, a4 as getWriteRule } from './index-nOBiMg01.js';
5
5
  import './deletion.js';
package/dist/functions.js CHANGED
@@ -337,8 +337,13 @@ var PromiseQueryOrNullImpl = class _PromiseQueryOrNullImpl extends Promise {
337
337
  this.ctx,
338
338
  this.entDefinitions,
339
339
  this.table,
340
- this.retrieve,
341
- paginationOpts
340
+ async () => {
341
+ const query = await this.retrieve();
342
+ if (query === null) {
343
+ return null;
344
+ }
345
+ return await query.paginate(paginationOpts);
346
+ }
342
347
  );
343
348
  }
344
349
  take(n) {
@@ -454,50 +459,23 @@ var PromiseQueryOrNullImpl = class _PromiseQueryOrNullImpl extends Promise {
454
459
  }
455
460
  async _take(n) {
456
461
  const query = await this.retrieve();
457
- if (query === null) {
458
- return null;
459
- }
460
- const readPolicy = getReadRule(this.entDefinitions, this.table);
461
- if (readPolicy === void 0) {
462
- return await query.take(n);
463
- }
464
- let numItems = n;
465
- const docs = [];
466
- let hasMore = true;
467
- const iterator = query[Symbol.asyncIterator]();
468
- while (hasMore && docs.length < n) {
469
- const page = [];
470
- for (let i = 0; i < numItems; i++) {
471
- const { done, value } = await iterator.next();
472
- if (done) {
473
- hasMore = false;
474
- break;
475
- }
476
- page.push(value);
477
- }
478
- docs.push(
479
- ...(await filterByReadRule(
480
- this.ctx,
481
- this.entDefinitions,
482
- this.table,
483
- page,
484
- false
485
- )).slice(0, n - docs.length)
486
- );
487
- numItems = Math.min(64, numItems * 2);
488
- }
489
- return docs;
462
+ return await takeFromQuery(
463
+ query,
464
+ n,
465
+ this.ctx,
466
+ this.entDefinitions,
467
+ this.table
468
+ );
490
469
  }
491
470
  };
492
471
  var PromisePaginationResultOrNullImpl = class extends Promise {
493
- constructor(ctx, entDefinitions, table, retrieve, paginationOpts) {
472
+ constructor(ctx, entDefinitions, table, retrieve) {
494
473
  super(() => {
495
474
  });
496
475
  this.ctx = ctx;
497
476
  this.entDefinitions = entDefinitions;
498
477
  this.table = table;
499
478
  this.retrieve = retrieve;
500
- this.paginationOpts = paginationOpts;
501
479
  }
502
480
  async map(callbackFn) {
503
481
  const result = await this;
@@ -510,11 +488,10 @@ var PromisePaginationResultOrNullImpl = class extends Promise {
510
488
  };
511
489
  }
512
490
  async docs() {
513
- const query = await this.retrieve();
514
- if (query === null) {
491
+ const result = await this.retrieve();
492
+ if (result === null) {
515
493
  return null;
516
494
  }
517
- const result = await query.paginate(this.paginationOpts);
518
495
  return {
519
496
  ...result,
520
497
  page: await filterByReadRule(
@@ -790,15 +767,185 @@ var PromiseEntsOrNullImpl = class extends Promise {
790
767
  ).then(onfulfilled, onrejected);
791
768
  }
792
769
  };
793
- var PromiseEdgeOrNullImpl = class extends PromiseEntsOrNullImpl {
794
- constructor(ctx, entDefinitions, table, field, retrieveRange) {
795
- super(ctx, entDefinitions, table, () => retrieveRange((q) => q), false);
796
- this.field = field;
797
- this.retrieveRange = retrieveRange;
770
+ var PromiseEdgeOrNullImpl = class _PromiseEdgeOrNullImpl extends PromiseEntsOrNullImpl {
771
+ constructor(ctx, entDefinitions, table, edgeDefinition, retrieveSourceId, retrieveQuery, retrieveDoc = async (edgeDoc) => {
772
+ const sourceId = edgeDoc[edgeDefinition.field];
773
+ const targetId = edgeDoc[edgeDefinition.ref];
774
+ const doc = await this.ctx.db.get(targetId);
775
+ if (doc === null) {
776
+ throw new Error(
777
+ `Dangling reference for edge "${edgeDefinition.name}" in table "${this.table}" for document with ID "${sourceId}": Could not find a document with ID "${targetId}" in table "${edgeDefinition.to}" (edge document ID is "${edgeDoc._id}").`
778
+ );
779
+ }
780
+ return doc;
781
+ }) {
782
+ super(
783
+ ctx,
784
+ entDefinitions,
785
+ table,
786
+ async () => {
787
+ const query = await retrieveQuery();
788
+ if (query === null) {
789
+ return null;
790
+ }
791
+ const edgeDocs = await query.collect();
792
+ return await Promise.all(edgeDocs.map(retrieveDoc));
793
+ },
794
+ false
795
+ );
796
+ this.edgeDefinition = edgeDefinition;
797
+ this.retrieveSourceId = retrieveSourceId;
798
+ this.retrieveQuery = retrieveQuery;
799
+ this.retrieveDoc = retrieveDoc;
800
+ }
801
+ async has(targetId) {
802
+ const sourceId = await this.retrieveSourceId();
803
+ if (sourceId === null) {
804
+ return null;
805
+ }
806
+ const edgeDoc = this.ctx.db.query(this.edgeDefinition.table).withIndex(
807
+ `${this.edgeDefinition.field}-${this.edgeDefinition.ref}`,
808
+ (q) => q.eq(this.edgeDefinition.field, sourceId).eq(
809
+ this.edgeDefinition.ref,
810
+ targetId
811
+ )
812
+ ).first();
813
+ return edgeDoc !== null;
814
+ }
815
+ order(order) {
816
+ return new _PromiseEdgeOrNullImpl(
817
+ this.ctx,
818
+ this.entDefinitions,
819
+ this.table,
820
+ this.edgeDefinition,
821
+ this.retrieveSourceId,
822
+ async () => {
823
+ const query = await this.retrieveQuery();
824
+ if (query === null) {
825
+ return null;
826
+ }
827
+ return query.order(order);
828
+ }
829
+ );
830
+ }
831
+ paginate(paginationOpts) {
832
+ return new PromisePaginationResultOrNullImpl(
833
+ this.ctx,
834
+ this.entDefinitions,
835
+ this.table,
836
+ async () => {
837
+ const query = await this.retrieveQuery();
838
+ if (query === null) {
839
+ return null;
840
+ }
841
+ const result = await query.paginate(paginationOpts);
842
+ return {
843
+ ...result,
844
+ page: await Promise.all(result.page.map(this.retrieveDoc))
845
+ };
846
+ }
847
+ );
848
+ }
849
+ take(n) {
850
+ return new PromiseEntsOrNullImpl(
851
+ this.ctx,
852
+ this.entDefinitions,
853
+ this.table,
854
+ async () => {
855
+ return await this._take(n);
856
+ },
857
+ false
858
+ );
859
+ }
860
+ first() {
861
+ return new PromiseEntOrNullImpl(
862
+ this.ctx,
863
+ this.entDefinitions,
864
+ this.table,
865
+ async () => {
866
+ const docs = await this._take(1);
867
+ if (docs === null) {
868
+ return nullRetriever;
869
+ }
870
+ const [doc] = docs;
871
+ return loadedRetriever(doc);
872
+ },
873
+ false
874
+ );
875
+ }
876
+ firstX() {
877
+ return new PromiseEntWriterImpl(
878
+ this.ctx,
879
+ this.entDefinitions,
880
+ this.table,
881
+ async () => {
882
+ const docs = await this._take(1);
883
+ if (docs === null) {
884
+ return nullRetriever;
885
+ }
886
+ const [doc] = docs;
887
+ if (doc === void 0) {
888
+ throw new Error("Query returned no documents");
889
+ }
890
+ return loadedRetriever(doc);
891
+ },
892
+ false
893
+ );
894
+ }
895
+ unique() {
896
+ return new PromiseEntOrNullImpl(
897
+ this.ctx,
898
+ this.entDefinitions,
899
+ this.table,
900
+ async () => {
901
+ const docs = await this._take(2);
902
+ if (docs === null) {
903
+ return nullRetriever;
904
+ }
905
+ if (docs.length === 0) {
906
+ return nullRetriever;
907
+ }
908
+ if (docs.length === 2) {
909
+ throw new Error("unique() query returned more than one result");
910
+ }
911
+ const [doc] = docs;
912
+ return loadedRetriever(doc);
913
+ },
914
+ false
915
+ );
916
+ }
917
+ uniqueX() {
918
+ return new PromiseEntWriterImpl(
919
+ this.ctx,
920
+ this.entDefinitions,
921
+ this.table,
922
+ async () => {
923
+ const docs = await this._take(2);
924
+ if (docs === null) {
925
+ return nullRetriever;
926
+ }
927
+ if (docs.length === 0) {
928
+ throw new Error("Query returned no documents");
929
+ }
930
+ if (docs.length === 2) {
931
+ throw new Error("unique() query returned more than one result");
932
+ }
933
+ const [doc] = docs;
934
+ return loadedRetriever(doc);
935
+ },
936
+ true
937
+ );
798
938
  }
799
- async has(id) {
800
- const docs = await this.retrieveRange((q) => q.eq(this.field, id));
801
- return (docs?.length ?? 0) > 0;
939
+ async _take(n) {
940
+ const query = await this.retrieveQuery();
941
+ return await takeFromQuery(
942
+ query,
943
+ n,
944
+ this.ctx,
945
+ this.entDefinitions,
946
+ this.table,
947
+ this.retrieveDoc
948
+ );
802
949
  }
803
950
  };
804
951
  var PromiseEntOrNullImpl = class extends Promise {
@@ -852,29 +999,21 @@ var PromiseEntOrNullImpl = class extends Promise {
852
999
  return new PromiseEdgeOrNullImpl(
853
1000
  this.ctx,
854
1001
  this.entDefinitions,
855
- edgeDefinition.to,
856
- edgeDefinition.ref,
857
- async (indexRange) => {
1002
+ this.table,
1003
+ edgeDefinition,
1004
+ async () => {
1005
+ const { id } = await this.retrieve();
1006
+ return id;
1007
+ },
1008
+ async () => {
858
1009
  const { id } = await this.retrieve();
859
1010
  if (id === null) {
860
1011
  return null;
861
1012
  }
862
- const edgeDocs = await this.ctx.db.query(edgeDefinition.table).withIndex(
1013
+ return this.ctx.db.query(edgeDefinition.table).withIndex(
863
1014
  edgeDefinition.field,
864
- (q) => indexRange(q.eq(edgeDefinition.field, id))
865
- ).collect();
866
- return (await Promise.all(
867
- edgeDocs.map(
868
- (edgeDoc) => this.ctx.db.get(edgeDoc[edgeDefinition.ref])
869
- )
870
- )).filter((doc, i) => {
871
- if (doc === null) {
872
- throw new Error(
873
- `Dangling reference for edge "${edgeDefinition.name}" in table "${this.table}" for document with ID "${id}": Could not find a document with ID "${edgeDocs[i][edgeDefinition.field]}" in table "${edgeDefinition.to}" (edge document ID is "${edgeDocs[i]._id}").`
874
- );
875
- }
876
- return true;
877
- });
1015
+ (q) => q.eq(edgeDefinition.field, id)
1016
+ );
878
1017
  }
879
1018
  );
880
1019
  }
@@ -1266,6 +1405,45 @@ function loadedRetriever(doc) {
1266
1405
  function addEntRules(entDefinitions, rules) {
1267
1406
  return { ...entDefinitions, rules };
1268
1407
  }
1408
+ async function takeFromQuery(query, n, ctx, entDefinitions, table, mapToResult) {
1409
+ if (query === null) {
1410
+ return null;
1411
+ }
1412
+ const readPolicy = getReadRule(entDefinitions, table);
1413
+ if (readPolicy === void 0) {
1414
+ const results = await query.take(n);
1415
+ if (mapToResult === void 0) {
1416
+ return results;
1417
+ }
1418
+ return Promise.all(results.map(mapToResult));
1419
+ }
1420
+ let numItems = n;
1421
+ const docs = [];
1422
+ let hasMore = true;
1423
+ const iterator = query[Symbol.asyncIterator]();
1424
+ while (hasMore && docs.length < n) {
1425
+ const page = [];
1426
+ for (let i = 0; i < numItems; i++) {
1427
+ const { done, value } = await iterator.next();
1428
+ if (done) {
1429
+ hasMore = false;
1430
+ break;
1431
+ }
1432
+ page.push(mapToResult === void 0 ? value : await mapToResult(value));
1433
+ }
1434
+ docs.push(
1435
+ ...(await filterByReadRule(
1436
+ ctx,
1437
+ entDefinitions,
1438
+ table,
1439
+ page,
1440
+ false
1441
+ )).slice(0, n - docs.length)
1442
+ );
1443
+ numItems = Math.min(64, numItems * 2);
1444
+ }
1445
+ return docs;
1446
+ }
1269
1447
  async function filterByReadRule(ctx, entDefinitions, table, docs, throwIfNull) {
1270
1448
  if (docs === null) {
1271
1449
  return null;