convex-ents
Advanced tools
Comparing version 0.8.1 to 0.9.0
import 'convex/values'; | ||
import 'convex/server'; | ||
import './schema.js'; | ||
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'; | ||
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'; | ||
import './deletion.js'; |
@@ -340,4 +340,9 @@ "use strict"; | ||
this.table, | ||
this.retrieve, | ||
paginationOpts | ||
async () => { | ||
const query = await this.retrieve(); | ||
if (query === null) { | ||
return null; | ||
} | ||
return await query.paginate(paginationOpts); | ||
} | ||
); | ||
@@ -458,39 +463,13 @@ } | ||
const query = await this.retrieve(); | ||
if (query === null) { | ||
return null; | ||
} | ||
const readPolicy = getReadRule(this.entDefinitions, this.table); | ||
if (readPolicy === void 0) { | ||
return await query.take(n); | ||
} | ||
let numItems = n; | ||
const docs = []; | ||
let hasMore = true; | ||
const iterator = query[Symbol.asyncIterator](); | ||
while (hasMore && docs.length < n) { | ||
const page = []; | ||
for (let i = 0; i < numItems; i++) { | ||
const { done, value } = await iterator.next(); | ||
if (done) { | ||
hasMore = false; | ||
break; | ||
} | ||
page.push(value); | ||
} | ||
docs.push( | ||
...(await filterByReadRule( | ||
this.ctx, | ||
this.entDefinitions, | ||
this.table, | ||
page, | ||
false | ||
)).slice(0, n - docs.length) | ||
); | ||
numItems = Math.min(64, numItems * 2); | ||
} | ||
return docs; | ||
return await takeFromQuery( | ||
query, | ||
n, | ||
this.ctx, | ||
this.entDefinitions, | ||
this.table | ||
); | ||
} | ||
}; | ||
var PromisePaginationResultOrNullImpl = class extends Promise { | ||
constructor(ctx, entDefinitions, table, retrieve, paginationOpts) { | ||
constructor(ctx, entDefinitions, table, retrieve) { | ||
super(() => { | ||
@@ -502,3 +481,2 @@ }); | ||
this.retrieve = retrieve; | ||
this.paginationOpts = paginationOpts; | ||
} | ||
@@ -516,7 +494,6 @@ async map(callbackFn) { | ||
async docs() { | ||
const query = await this.retrieve(); | ||
if (query === null) { | ||
const result = await this.retrieve(); | ||
if (result === null) { | ||
return null; | ||
} | ||
const result = await query.paginate(this.paginationOpts); | ||
return { | ||
@@ -797,12 +774,182 @@ ...result, | ||
}; | ||
var PromiseEdgeOrNullImpl = class extends PromiseEntsOrNullImpl { | ||
constructor(ctx, entDefinitions, table, field, retrieveRange) { | ||
super(ctx, entDefinitions, table, () => retrieveRange((q) => q), false); | ||
this.field = field; | ||
this.retrieveRange = retrieveRange; | ||
var PromiseEdgeOrNullImpl = class _PromiseEdgeOrNullImpl extends PromiseEntsOrNullImpl { | ||
constructor(ctx, entDefinitions, table, edgeDefinition, retrieveSourceId, retrieveQuery, retrieveDoc = async (edgeDoc) => { | ||
const sourceId = edgeDoc[edgeDefinition.field]; | ||
const targetId = edgeDoc[edgeDefinition.ref]; | ||
const doc = await this.ctx.db.get(targetId); | ||
if (doc === null) { | ||
throw new Error( | ||
`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}").` | ||
); | ||
} | ||
return doc; | ||
}) { | ||
super( | ||
ctx, | ||
entDefinitions, | ||
table, | ||
async () => { | ||
const query = await retrieveQuery(); | ||
if (query === null) { | ||
return null; | ||
} | ||
const edgeDocs = await query.collect(); | ||
return await Promise.all(edgeDocs.map(retrieveDoc)); | ||
}, | ||
false | ||
); | ||
this.edgeDefinition = edgeDefinition; | ||
this.retrieveSourceId = retrieveSourceId; | ||
this.retrieveQuery = retrieveQuery; | ||
this.retrieveDoc = retrieveDoc; | ||
} | ||
async has(id) { | ||
const docs = await this.retrieveRange((q) => q.eq(this.field, id)); | ||
return (docs?.length ?? 0) > 0; | ||
async has(targetId) { | ||
const sourceId = await this.retrieveSourceId(); | ||
if (sourceId === null) { | ||
return null; | ||
} | ||
const edgeDoc = this.ctx.db.query(this.edgeDefinition.table).withIndex( | ||
`${this.edgeDefinition.field}-${this.edgeDefinition.ref}`, | ||
(q) => q.eq(this.edgeDefinition.field, sourceId).eq( | ||
this.edgeDefinition.ref, | ||
targetId | ||
) | ||
).first(); | ||
return edgeDoc !== null; | ||
} | ||
order(order) { | ||
return new _PromiseEdgeOrNullImpl( | ||
this.ctx, | ||
this.entDefinitions, | ||
this.table, | ||
this.edgeDefinition, | ||
this.retrieveSourceId, | ||
async () => { | ||
const query = await this.retrieveQuery(); | ||
if (query === null) { | ||
return null; | ||
} | ||
return query.order(order); | ||
} | ||
); | ||
} | ||
paginate(paginationOpts) { | ||
return new PromisePaginationResultOrNullImpl( | ||
this.ctx, | ||
this.entDefinitions, | ||
this.table, | ||
async () => { | ||
const query = await this.retrieveQuery(); | ||
if (query === null) { | ||
return null; | ||
} | ||
const result = await query.paginate(paginationOpts); | ||
return { | ||
...result, | ||
page: await Promise.all(result.page.map(this.retrieveDoc)) | ||
}; | ||
} | ||
); | ||
} | ||
take(n) { | ||
return new PromiseEntsOrNullImpl( | ||
this.ctx, | ||
this.entDefinitions, | ||
this.table, | ||
async () => { | ||
return await this._take(n); | ||
}, | ||
false | ||
); | ||
} | ||
first() { | ||
return new PromiseEntOrNullImpl( | ||
this.ctx, | ||
this.entDefinitions, | ||
this.table, | ||
async () => { | ||
const docs = await this._take(1); | ||
if (docs === null) { | ||
return nullRetriever; | ||
} | ||
const [doc] = docs; | ||
return loadedRetriever(doc); | ||
}, | ||
false | ||
); | ||
} | ||
firstX() { | ||
return new PromiseEntWriterImpl( | ||
this.ctx, | ||
this.entDefinitions, | ||
this.table, | ||
async () => { | ||
const docs = await this._take(1); | ||
if (docs === null) { | ||
return nullRetriever; | ||
} | ||
const [doc] = docs; | ||
if (doc === void 0) { | ||
throw new Error("Query returned no documents"); | ||
} | ||
return loadedRetriever(doc); | ||
}, | ||
false | ||
); | ||
} | ||
unique() { | ||
return new PromiseEntOrNullImpl( | ||
this.ctx, | ||
this.entDefinitions, | ||
this.table, | ||
async () => { | ||
const docs = await this._take(2); | ||
if (docs === null) { | ||
return nullRetriever; | ||
} | ||
if (docs.length === 0) { | ||
return nullRetriever; | ||
} | ||
if (docs.length === 2) { | ||
throw new Error("unique() query returned more than one result"); | ||
} | ||
const [doc] = docs; | ||
return loadedRetriever(doc); | ||
}, | ||
false | ||
); | ||
} | ||
uniqueX() { | ||
return new PromiseEntWriterImpl( | ||
this.ctx, | ||
this.entDefinitions, | ||
this.table, | ||
async () => { | ||
const docs = await this._take(2); | ||
if (docs === null) { | ||
return nullRetriever; | ||
} | ||
if (docs.length === 0) { | ||
throw new Error("Query returned no documents"); | ||
} | ||
if (docs.length === 2) { | ||
throw new Error("unique() query returned more than one result"); | ||
} | ||
const [doc] = docs; | ||
return loadedRetriever(doc); | ||
}, | ||
true | ||
); | ||
} | ||
async _take(n) { | ||
const query = await this.retrieveQuery(); | ||
return await takeFromQuery( | ||
query, | ||
n, | ||
this.ctx, | ||
this.entDefinitions, | ||
this.table, | ||
this.retrieveDoc | ||
); | ||
} | ||
}; | ||
@@ -860,25 +1007,17 @@ var PromiseEntOrNullImpl = class extends Promise { | ||
this.entDefinitions, | ||
edgeDefinition.to, | ||
edgeDefinition.ref, | ||
async (indexRange) => { | ||
this.table, | ||
edgeDefinition, | ||
async () => { | ||
const { id } = await this.retrieve(); | ||
return id; | ||
}, | ||
async () => { | ||
const { id } = await this.retrieve(); | ||
if (id === null) { | ||
return null; | ||
} | ||
const edgeDocs = await this.ctx.db.query(edgeDefinition.table).withIndex( | ||
return this.ctx.db.query(edgeDefinition.table).withIndex( | ||
edgeDefinition.field, | ||
(q) => indexRange(q.eq(edgeDefinition.field, id)) | ||
).collect(); | ||
return (await Promise.all( | ||
edgeDocs.map( | ||
(edgeDoc) => this.ctx.db.get(edgeDoc[edgeDefinition.ref]) | ||
) | ||
)).filter((doc, i) => { | ||
if (doc === null) { | ||
throw new Error( | ||
`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}").` | ||
); | ||
} | ||
return true; | ||
}); | ||
(q) => q.eq(edgeDefinition.field, id) | ||
); | ||
} | ||
@@ -1275,2 +1414,41 @@ ); | ||
} | ||
async function takeFromQuery(query, n, ctx, entDefinitions, table, mapToResult) { | ||
if (query === null) { | ||
return null; | ||
} | ||
const readPolicy = getReadRule(entDefinitions, table); | ||
if (readPolicy === void 0) { | ||
const results = await query.take(n); | ||
if (mapToResult === void 0) { | ||
return results; | ||
} | ||
return Promise.all(results.map(mapToResult)); | ||
} | ||
let numItems = n; | ||
const docs = []; | ||
let hasMore = true; | ||
const iterator = query[Symbol.asyncIterator](); | ||
while (hasMore && docs.length < n) { | ||
const page = []; | ||
for (let i = 0; i < numItems; i++) { | ||
const { done, value } = await iterator.next(); | ||
if (done) { | ||
hasMore = false; | ||
break; | ||
} | ||
page.push(mapToResult === void 0 ? value : await mapToResult(value)); | ||
} | ||
docs.push( | ||
...(await filterByReadRule( | ||
ctx, | ||
entDefinitions, | ||
table, | ||
page, | ||
false | ||
)).slice(0, n - docs.length) | ||
); | ||
numItems = Math.min(64, numItems * 2); | ||
} | ||
return docs; | ||
} | ||
async function filterByReadRule(ctx, entDefinitions, table, docs, throwIfNull) { | ||
@@ -1277,0 +1455,0 @@ if (docs === null) { |
export { EntDefinition, defineEnt, defineEntFromTable, defineEntSchema, defineEntsFromTables, getEntDefinitions } from './schema.js'; | ||
export { G as GenericEnt, T as GenericEntWriter, t as PromiseEdgeEnts, r as PromiseEdgeEntsOrNull, u as PromiseEdgeEntsWriter, 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, k as PromiseQuery, e as PromiseQueryOrNull, M as PromiseQueryWriter, f as PromiseQueryWriterOrNull, h as PromiseTable, g as PromiseTableBase, Q as PromiseTableWriter, Z as addEntRules, A as entsTableFactory } from './index-uXk5iZ86.js'; | ||
export { J as GenericEnt, Z as GenericEntWriter, w as PromiseEdgeEnts, s as PromiseEdgeEntsOrNull, y as PromiseEdgeEntsWriter, 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, k as PromiseQuery, e as PromiseQueryOrNull, R as PromiseQueryWriter, f as PromiseQueryWriterOrNull, h as PromiseTable, g as PromiseTableBase, V as PromiseTableWriter, a2 as addEntRules, F as entsTableFactory } from './index-nOBiMg01.js'; | ||
export { scheduledDeleteFactory } from './deletion.js'; | ||
import 'convex/server'; | ||
import 'convex/values'; |
@@ -129,6 +129,14 @@ "use strict"; | ||
const inverseId = isSelfDirected && edge.type === "ref" && edge.inverseField !== void 0 ? edge.inverseField : inverseEdge === void 0 ? "bId" : inverseEdge.type === "ref" && inverseEdge.field !== void 0 ? inverseEdge.field : tableName === otherTableName ? edge.name + "Id" : otherTableName + "Id"; | ||
schema[edgeTableName] = defineEnt({ | ||
const edgeTable = defineEnt({ | ||
[forwardId]: import_values.v.id(tableName), | ||
[inverseId]: import_values.v.id(otherTableName) | ||
}).index(forwardId, [forwardId, inverseId]).index(inverseId, [inverseId, forwardId]); | ||
}).index(forwardId, [forwardId]).index(inverseId, [inverseId]).index(`${forwardId}-${inverseId}`, [forwardId, inverseId]); | ||
const isSymmetric = inverseEdge === void 0; | ||
if (!isSymmetric) { | ||
edgeTable.index(`${inverseId}-${forwardId}`, [ | ||
forwardId, | ||
inverseId | ||
]); | ||
} | ||
schema[edgeTableName] = edgeTable; | ||
edge.type = "ref"; | ||
@@ -135,0 +143,0 @@ edge.table = edgeTableName; |
import 'convex/server'; | ||
import 'convex/values'; | ||
export { E as EdgeChanges, a as WithEdgeInserts, c as WithEdgePatches, b as WithEdges, W as WriterImplBase } from './index-uXk5iZ86.js'; | ||
export { E as EdgeChanges, a as WithEdgeInserts, c as WithEdgePatches, b as WithEdges, W as WriterImplBase } from './index-nOBiMg01.js'; | ||
import './schema.js'; | ||
import './deletion.js'; |
@@ -83,4 +83,9 @@ "use strict"; | ||
this.table, | ||
this.retrieve, | ||
paginationOpts | ||
async () => { | ||
const query = await this.retrieve(); | ||
if (query === null) { | ||
return null; | ||
} | ||
return await query.paginate(paginationOpts); | ||
} | ||
); | ||
@@ -201,39 +206,13 @@ } | ||
const query = await this.retrieve(); | ||
if (query === null) { | ||
return null; | ||
} | ||
const readPolicy = getReadRule(this.entDefinitions, this.table); | ||
if (readPolicy === void 0) { | ||
return await query.take(n); | ||
} | ||
let numItems = n; | ||
const docs = []; | ||
let hasMore = true; | ||
const iterator = query[Symbol.asyncIterator](); | ||
while (hasMore && docs.length < n) { | ||
const page = []; | ||
for (let i = 0; i < numItems; i++) { | ||
const { done, value } = await iterator.next(); | ||
if (done) { | ||
hasMore = false; | ||
break; | ||
} | ||
page.push(value); | ||
} | ||
docs.push( | ||
...(await filterByReadRule( | ||
this.ctx, | ||
this.entDefinitions, | ||
this.table, | ||
page, | ||
false | ||
)).slice(0, n - docs.length) | ||
); | ||
numItems = Math.min(64, numItems * 2); | ||
} | ||
return docs; | ||
return await takeFromQuery( | ||
query, | ||
n, | ||
this.ctx, | ||
this.entDefinitions, | ||
this.table | ||
); | ||
} | ||
}; | ||
var PromisePaginationResultOrNullImpl = class extends Promise { | ||
constructor(ctx, entDefinitions, table, retrieve, paginationOpts) { | ||
constructor(ctx, entDefinitions, table, retrieve) { | ||
super(() => { | ||
@@ -245,3 +224,2 @@ }); | ||
this.retrieve = retrieve; | ||
this.paginationOpts = paginationOpts; | ||
} | ||
@@ -259,7 +237,6 @@ async map(callbackFn) { | ||
async docs() { | ||
const query = await this.retrieve(); | ||
if (query === null) { | ||
const result = await this.retrieve(); | ||
if (result === null) { | ||
return null; | ||
} | ||
const result = await query.paginate(this.paginationOpts); | ||
return { | ||
@@ -397,12 +374,182 @@ ...result, | ||
}; | ||
var PromiseEdgeOrNullImpl = class extends PromiseEntsOrNullImpl { | ||
constructor(ctx, entDefinitions, table, field, retrieveRange) { | ||
super(ctx, entDefinitions, table, () => retrieveRange((q) => q), false); | ||
this.field = field; | ||
this.retrieveRange = retrieveRange; | ||
var PromiseEdgeOrNullImpl = class _PromiseEdgeOrNullImpl extends PromiseEntsOrNullImpl { | ||
constructor(ctx, entDefinitions, table, edgeDefinition, retrieveSourceId, retrieveQuery, retrieveDoc = async (edgeDoc) => { | ||
const sourceId = edgeDoc[edgeDefinition.field]; | ||
const targetId = edgeDoc[edgeDefinition.ref]; | ||
const doc = await this.ctx.db.get(targetId); | ||
if (doc === null) { | ||
throw new Error( | ||
`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}").` | ||
); | ||
} | ||
return doc; | ||
}) { | ||
super( | ||
ctx, | ||
entDefinitions, | ||
table, | ||
async () => { | ||
const query = await retrieveQuery(); | ||
if (query === null) { | ||
return null; | ||
} | ||
const edgeDocs = await query.collect(); | ||
return await Promise.all(edgeDocs.map(retrieveDoc)); | ||
}, | ||
false | ||
); | ||
this.edgeDefinition = edgeDefinition; | ||
this.retrieveSourceId = retrieveSourceId; | ||
this.retrieveQuery = retrieveQuery; | ||
this.retrieveDoc = retrieveDoc; | ||
} | ||
async has(id) { | ||
const docs = await this.retrieveRange((q) => q.eq(this.field, id)); | ||
return (docs?.length ?? 0) > 0; | ||
async has(targetId) { | ||
const sourceId = await this.retrieveSourceId(); | ||
if (sourceId === null) { | ||
return null; | ||
} | ||
const edgeDoc = this.ctx.db.query(this.edgeDefinition.table).withIndex( | ||
`${this.edgeDefinition.field}-${this.edgeDefinition.ref}`, | ||
(q) => q.eq(this.edgeDefinition.field, sourceId).eq( | ||
this.edgeDefinition.ref, | ||
targetId | ||
) | ||
).first(); | ||
return edgeDoc !== null; | ||
} | ||
order(order) { | ||
return new _PromiseEdgeOrNullImpl( | ||
this.ctx, | ||
this.entDefinitions, | ||
this.table, | ||
this.edgeDefinition, | ||
this.retrieveSourceId, | ||
async () => { | ||
const query = await this.retrieveQuery(); | ||
if (query === null) { | ||
return null; | ||
} | ||
return query.order(order); | ||
} | ||
); | ||
} | ||
paginate(paginationOpts) { | ||
return new PromisePaginationResultOrNullImpl( | ||
this.ctx, | ||
this.entDefinitions, | ||
this.table, | ||
async () => { | ||
const query = await this.retrieveQuery(); | ||
if (query === null) { | ||
return null; | ||
} | ||
const result = await query.paginate(paginationOpts); | ||
return { | ||
...result, | ||
page: await Promise.all(result.page.map(this.retrieveDoc)) | ||
}; | ||
} | ||
); | ||
} | ||
take(n) { | ||
return new PromiseEntsOrNullImpl( | ||
this.ctx, | ||
this.entDefinitions, | ||
this.table, | ||
async () => { | ||
return await this._take(n); | ||
}, | ||
false | ||
); | ||
} | ||
first() { | ||
return new PromiseEntOrNullImpl( | ||
this.ctx, | ||
this.entDefinitions, | ||
this.table, | ||
async () => { | ||
const docs = await this._take(1); | ||
if (docs === null) { | ||
return nullRetriever; | ||
} | ||
const [doc] = docs; | ||
return loadedRetriever(doc); | ||
}, | ||
false | ||
); | ||
} | ||
firstX() { | ||
return new PromiseEntWriterImpl( | ||
this.ctx, | ||
this.entDefinitions, | ||
this.table, | ||
async () => { | ||
const docs = await this._take(1); | ||
if (docs === null) { | ||
return nullRetriever; | ||
} | ||
const [doc] = docs; | ||
if (doc === void 0) { | ||
throw new Error("Query returned no documents"); | ||
} | ||
return loadedRetriever(doc); | ||
}, | ||
false | ||
); | ||
} | ||
unique() { | ||
return new PromiseEntOrNullImpl( | ||
this.ctx, | ||
this.entDefinitions, | ||
this.table, | ||
async () => { | ||
const docs = await this._take(2); | ||
if (docs === null) { | ||
return nullRetriever; | ||
} | ||
if (docs.length === 0) { | ||
return nullRetriever; | ||
} | ||
if (docs.length === 2) { | ||
throw new Error("unique() query returned more than one result"); | ||
} | ||
const [doc] = docs; | ||
return loadedRetriever(doc); | ||
}, | ||
false | ||
); | ||
} | ||
uniqueX() { | ||
return new PromiseEntWriterImpl( | ||
this.ctx, | ||
this.entDefinitions, | ||
this.table, | ||
async () => { | ||
const docs = await this._take(2); | ||
if (docs === null) { | ||
return nullRetriever; | ||
} | ||
if (docs.length === 0) { | ||
throw new Error("Query returned no documents"); | ||
} | ||
if (docs.length === 2) { | ||
throw new Error("unique() query returned more than one result"); | ||
} | ||
const [doc] = docs; | ||
return loadedRetriever(doc); | ||
}, | ||
true | ||
); | ||
} | ||
async _take(n) { | ||
const query = await this.retrieveQuery(); | ||
return await takeFromQuery( | ||
query, | ||
n, | ||
this.ctx, | ||
this.entDefinitions, | ||
this.table, | ||
this.retrieveDoc | ||
); | ||
} | ||
}; | ||
@@ -460,25 +607,17 @@ var PromiseEntOrNullImpl = class extends Promise { | ||
this.entDefinitions, | ||
edgeDefinition.to, | ||
edgeDefinition.ref, | ||
async (indexRange) => { | ||
this.table, | ||
edgeDefinition, | ||
async () => { | ||
const { id } = await this.retrieve(); | ||
return id; | ||
}, | ||
async () => { | ||
const { id } = await this.retrieve(); | ||
if (id === null) { | ||
return null; | ||
} | ||
const edgeDocs = await this.ctx.db.query(edgeDefinition.table).withIndex( | ||
return this.ctx.db.query(edgeDefinition.table).withIndex( | ||
edgeDefinition.field, | ||
(q) => indexRange(q.eq(edgeDefinition.field, id)) | ||
).collect(); | ||
return (await Promise.all( | ||
edgeDocs.map( | ||
(edgeDoc) => this.ctx.db.get(edgeDoc[edgeDefinition.ref]) | ||
) | ||
)).filter((doc, i) => { | ||
if (doc === null) { | ||
throw new Error( | ||
`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}").` | ||
); | ||
} | ||
return true; | ||
}); | ||
(q) => q.eq(edgeDefinition.field, id) | ||
); | ||
} | ||
@@ -807,2 +946,41 @@ ); | ||
} | ||
async function takeFromQuery(query, n, ctx, entDefinitions, table, mapToResult) { | ||
if (query === null) { | ||
return null; | ||
} | ||
const readPolicy = getReadRule(entDefinitions, table); | ||
if (readPolicy === void 0) { | ||
const results = await query.take(n); | ||
if (mapToResult === void 0) { | ||
return results; | ||
} | ||
return Promise.all(results.map(mapToResult)); | ||
} | ||
let numItems = n; | ||
const docs = []; | ||
let hasMore = true; | ||
const iterator = query[Symbol.asyncIterator](); | ||
while (hasMore && docs.length < n) { | ||
const page = []; | ||
for (let i = 0; i < numItems; i++) { | ||
const { done, value } = await iterator.next(); | ||
if (done) { | ||
hasMore = false; | ||
break; | ||
} | ||
page.push(mapToResult === void 0 ? value : await mapToResult(value)); | ||
} | ||
docs.push( | ||
...(await filterByReadRule( | ||
ctx, | ||
entDefinitions, | ||
table, | ||
page, | ||
false | ||
)).slice(0, n - docs.length) | ||
); | ||
numItems = Math.min(64, numItems * 2); | ||
} | ||
return docs; | ||
} | ||
async function filterByReadRule(ctx, entDefinitions, table, docs, throwIfNull) { | ||
@@ -809,0 +987,0 @@ if (docs === null) { |
{ | ||
"name": "convex-ents", | ||
"version": "0.8.1", | ||
"version": "0.9.0", | ||
"description": "Relations, default values, unique fields, RLS for Convex", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
895069
6501