@monlite/core 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -0
- package/dist/index.cjs +50 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -1
- package/dist/index.d.ts +23 -1
- package/dist/index.js +50 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -76,6 +76,8 @@ declare class Collection<T = Doc> {
|
|
|
76
76
|
/** @internal Synchronous core of exists (used by reactivity). */
|
|
77
77
|
existsCore(where: WhereInput<T> | undefined): boolean;
|
|
78
78
|
findMany(args?: FindManyArgs<T>): Promise<WithId<T>[]>;
|
|
79
|
+
/** Resolve one `$lookup` spec against already-fetched rows (2 queries, no N+1). */
|
|
80
|
+
private applyLookup;
|
|
79
81
|
findFirst(args?: FindFirstArgs<T>): Promise<WithId<T> | null>;
|
|
80
82
|
/** Alias of {@link findFirst} for Prisma familiarity. */
|
|
81
83
|
findUnique(args?: FindFirstArgs<T>): Promise<WithId<T> | null>;
|
|
@@ -341,18 +343,38 @@ type Select<T = Doc> = {
|
|
|
341
343
|
} & {
|
|
342
344
|
[path: string]: boolean;
|
|
343
345
|
};
|
|
346
|
+
/**
|
|
347
|
+
* A `$lookup`-style left join: for each result, fetch matching documents from
|
|
348
|
+
* another collection and attach them. With `unwind`, emit one row per match
|
|
349
|
+
* (`$unwind`); `unwind: "preserve"` also keeps rows that have no match.
|
|
350
|
+
*/
|
|
351
|
+
interface LookupSpec {
|
|
352
|
+
/** The collection to join. */
|
|
353
|
+
from: string;
|
|
354
|
+
/** Field on this collection to match on. */
|
|
355
|
+
localField: string;
|
|
356
|
+
/** Field on the `from` collection to match against. */
|
|
357
|
+
foreignField: string;
|
|
358
|
+
/** Output field that receives the matched document(s). */
|
|
359
|
+
as: string;
|
|
360
|
+
/** Flatten the `as` array to a single object (one output row per match). */
|
|
361
|
+
unwind?: boolean | "preserve";
|
|
362
|
+
}
|
|
344
363
|
interface FindManyArgs<T = Doc> {
|
|
345
364
|
where?: WhereInput<T>;
|
|
346
365
|
orderBy?: OrderBy<T>;
|
|
347
366
|
select?: Select<T>;
|
|
348
367
|
skip?: number;
|
|
349
368
|
take?: number;
|
|
369
|
+
/** Join related documents from other collections ($lookup / $unwind). */
|
|
370
|
+
lookup?: LookupSpec | LookupSpec[];
|
|
350
371
|
}
|
|
351
372
|
interface FindFirstArgs<T = Doc> {
|
|
352
373
|
where?: WhereInput<T>;
|
|
353
374
|
orderBy?: OrderBy<T>;
|
|
354
375
|
select?: Select<T>;
|
|
355
376
|
skip?: number;
|
|
377
|
+
lookup?: LookupSpec | LookupSpec[];
|
|
356
378
|
}
|
|
357
379
|
interface CreateArgs<T = Doc> {
|
|
358
380
|
data: Partial<T> & Record<string, any>;
|
|
@@ -788,4 +810,4 @@ declare function objectId(): string;
|
|
|
788
810
|
/** True when a value looks like a monlite/ObjectId id (24 hex chars). */
|
|
789
811
|
declare function isObjectId(value: unknown): value is string;
|
|
790
812
|
|
|
791
|
-
export { type AggregateArgs, type AggregateResult, type ApplyResult, Collection, type CollectionMode, type CollectionOptions, type CollectionSchema, type ColumnDef, type ColumnInfo, type ColumnType, type ConflictResolver, type ConflictRow, type CountArgs, type CreateArgs, type CreateManyArgs, Monlite as Db, type DeleteArgs, type Doc, type Driver, type DriverName, type DriverOpenOptions, type EncryptionOptions, type ExplainResult, type FieldFilter, type FieldSelection, type FilterInput, type FindFirstArgs, type FindManyArgs, type GroupByArgs, type GroupByResult, type HavingComparison, type HavingInput, type LiveEvent, type LocalChange, type MigrateOptions, Monlite, MonliteConstraintError, MonliteEncryptionError, MonliteError, MonliteForeignKeyError, MonliteNotNullError, type MonliteOptions, type MonlitePlugin, MonliteQueryError, MonliteUniqueConstraintError, type OrderBy, type PluginChange, type PreparedStatement, type RemoteChange, type RunResult, type Select, type SortOrder, type SyncOp, type SyncStateRow, SyncStore, type SystemFields, type UpdateArgs, type UpdateData, type UpdateOperators, type UpsertArgs, type Version, type WatchHandle, type WhereInput as WhereClause, type WhereInput, type WithId, compareVersions, createDb, isObjectId, makeVersion, normalizeDriverError, objectId, versionTs };
|
|
813
|
+
export { type AggregateArgs, type AggregateResult, type ApplyResult, Collection, type CollectionMode, type CollectionOptions, type CollectionSchema, type ColumnDef, type ColumnInfo, type ColumnType, type ConflictResolver, type ConflictRow, type CountArgs, type CreateArgs, type CreateManyArgs, Monlite as Db, type DeleteArgs, type Doc, type Driver, type DriverName, type DriverOpenOptions, type EncryptionOptions, type ExplainResult, type FieldFilter, type FieldSelection, type FilterInput, type FindFirstArgs, type FindManyArgs, type GroupByArgs, type GroupByResult, type HavingComparison, type HavingInput, type LiveEvent, type LocalChange, type LookupSpec, type MigrateOptions, Monlite, MonliteConstraintError, MonliteEncryptionError, MonliteError, MonliteForeignKeyError, MonliteNotNullError, type MonliteOptions, type MonlitePlugin, MonliteQueryError, MonliteUniqueConstraintError, type OrderBy, type PluginChange, type PreparedStatement, type RemoteChange, type RunResult, type Select, type SortOrder, type SyncOp, type SyncStateRow, SyncStore, type SystemFields, type UpdateArgs, type UpdateData, type UpdateOperators, type UpsertArgs, type Version, type WatchHandle, type WhereInput as WhereClause, type WhereInput, type WithId, compareVersions, createDb, isObjectId, makeVersion, normalizeDriverError, objectId, versionTs };
|
package/dist/index.d.ts
CHANGED
|
@@ -76,6 +76,8 @@ declare class Collection<T = Doc> {
|
|
|
76
76
|
/** @internal Synchronous core of exists (used by reactivity). */
|
|
77
77
|
existsCore(where: WhereInput<T> | undefined): boolean;
|
|
78
78
|
findMany(args?: FindManyArgs<T>): Promise<WithId<T>[]>;
|
|
79
|
+
/** Resolve one `$lookup` spec against already-fetched rows (2 queries, no N+1). */
|
|
80
|
+
private applyLookup;
|
|
79
81
|
findFirst(args?: FindFirstArgs<T>): Promise<WithId<T> | null>;
|
|
80
82
|
/** Alias of {@link findFirst} for Prisma familiarity. */
|
|
81
83
|
findUnique(args?: FindFirstArgs<T>): Promise<WithId<T> | null>;
|
|
@@ -341,18 +343,38 @@ type Select<T = Doc> = {
|
|
|
341
343
|
} & {
|
|
342
344
|
[path: string]: boolean;
|
|
343
345
|
};
|
|
346
|
+
/**
|
|
347
|
+
* A `$lookup`-style left join: for each result, fetch matching documents from
|
|
348
|
+
* another collection and attach them. With `unwind`, emit one row per match
|
|
349
|
+
* (`$unwind`); `unwind: "preserve"` also keeps rows that have no match.
|
|
350
|
+
*/
|
|
351
|
+
interface LookupSpec {
|
|
352
|
+
/** The collection to join. */
|
|
353
|
+
from: string;
|
|
354
|
+
/** Field on this collection to match on. */
|
|
355
|
+
localField: string;
|
|
356
|
+
/** Field on the `from` collection to match against. */
|
|
357
|
+
foreignField: string;
|
|
358
|
+
/** Output field that receives the matched document(s). */
|
|
359
|
+
as: string;
|
|
360
|
+
/** Flatten the `as` array to a single object (one output row per match). */
|
|
361
|
+
unwind?: boolean | "preserve";
|
|
362
|
+
}
|
|
344
363
|
interface FindManyArgs<T = Doc> {
|
|
345
364
|
where?: WhereInput<T>;
|
|
346
365
|
orderBy?: OrderBy<T>;
|
|
347
366
|
select?: Select<T>;
|
|
348
367
|
skip?: number;
|
|
349
368
|
take?: number;
|
|
369
|
+
/** Join related documents from other collections ($lookup / $unwind). */
|
|
370
|
+
lookup?: LookupSpec | LookupSpec[];
|
|
350
371
|
}
|
|
351
372
|
interface FindFirstArgs<T = Doc> {
|
|
352
373
|
where?: WhereInput<T>;
|
|
353
374
|
orderBy?: OrderBy<T>;
|
|
354
375
|
select?: Select<T>;
|
|
355
376
|
skip?: number;
|
|
377
|
+
lookup?: LookupSpec | LookupSpec[];
|
|
356
378
|
}
|
|
357
379
|
interface CreateArgs<T = Doc> {
|
|
358
380
|
data: Partial<T> & Record<string, any>;
|
|
@@ -788,4 +810,4 @@ declare function objectId(): string;
|
|
|
788
810
|
/** True when a value looks like a monlite/ObjectId id (24 hex chars). */
|
|
789
811
|
declare function isObjectId(value: unknown): value is string;
|
|
790
812
|
|
|
791
|
-
export { type AggregateArgs, type AggregateResult, type ApplyResult, Collection, type CollectionMode, type CollectionOptions, type CollectionSchema, type ColumnDef, type ColumnInfo, type ColumnType, type ConflictResolver, type ConflictRow, type CountArgs, type CreateArgs, type CreateManyArgs, Monlite as Db, type DeleteArgs, type Doc, type Driver, type DriverName, type DriverOpenOptions, type EncryptionOptions, type ExplainResult, type FieldFilter, type FieldSelection, type FilterInput, type FindFirstArgs, type FindManyArgs, type GroupByArgs, type GroupByResult, type HavingComparison, type HavingInput, type LiveEvent, type LocalChange, type MigrateOptions, Monlite, MonliteConstraintError, MonliteEncryptionError, MonliteError, MonliteForeignKeyError, MonliteNotNullError, type MonliteOptions, type MonlitePlugin, MonliteQueryError, MonliteUniqueConstraintError, type OrderBy, type PluginChange, type PreparedStatement, type RemoteChange, type RunResult, type Select, type SortOrder, type SyncOp, type SyncStateRow, SyncStore, type SystemFields, type UpdateArgs, type UpdateData, type UpdateOperators, type UpsertArgs, type Version, type WatchHandle, type WhereInput as WhereClause, type WhereInput, type WithId, compareVersions, createDb, isObjectId, makeVersion, normalizeDriverError, objectId, versionTs };
|
|
813
|
+
export { type AggregateArgs, type AggregateResult, type ApplyResult, Collection, type CollectionMode, type CollectionOptions, type CollectionSchema, type ColumnDef, type ColumnInfo, type ColumnType, type ConflictResolver, type ConflictRow, type CountArgs, type CreateArgs, type CreateManyArgs, Monlite as Db, type DeleteArgs, type Doc, type Driver, type DriverName, type DriverOpenOptions, type EncryptionOptions, type ExplainResult, type FieldFilter, type FieldSelection, type FilterInput, type FindFirstArgs, type FindManyArgs, type GroupByArgs, type GroupByResult, type HavingComparison, type HavingInput, type LiveEvent, type LocalChange, type LookupSpec, type MigrateOptions, Monlite, MonliteConstraintError, MonliteEncryptionError, MonliteError, MonliteForeignKeyError, MonliteNotNullError, type MonliteOptions, type MonlitePlugin, MonliteQueryError, MonliteUniqueConstraintError, type OrderBy, type PluginChange, type PreparedStatement, type RemoteChange, type RunResult, type Select, type SortOrder, type SyncOp, type SyncStateRow, SyncStore, type SystemFields, type UpdateArgs, type UpdateData, type UpdateOperators, type UpsertArgs, type Version, type WatchHandle, type WhereInput as WhereClause, type WhereInput, type WithId, compareVersions, createDb, isObjectId, makeVersion, normalizeDriverError, objectId, versionTs };
|
package/dist/index.js
CHANGED
|
@@ -1150,7 +1150,56 @@ var Collection = class {
|
|
|
1150
1150
|
return this.db.prepare(`SELECT 1 FROM "${this.name}" WHERE ${clause} LIMIT 1`).get(...params) != null;
|
|
1151
1151
|
}
|
|
1152
1152
|
async findMany(args = {}) {
|
|
1153
|
-
return this.findManyCore(args);
|
|
1153
|
+
if (!args.lookup) return this.findManyCore(args);
|
|
1154
|
+
const specs = Array.isArray(args.lookup) ? args.lookup : [args.lookup];
|
|
1155
|
+
let rows = this.findManyCore({
|
|
1156
|
+
...args,
|
|
1157
|
+
select: void 0,
|
|
1158
|
+
lookup: void 0
|
|
1159
|
+
});
|
|
1160
|
+
for (const spec of specs) rows = await this.applyLookup(rows, spec);
|
|
1161
|
+
if (args.select) {
|
|
1162
|
+
rows = rows.map((r) => {
|
|
1163
|
+
const projected = project(r, args.select);
|
|
1164
|
+
for (const spec of specs) projected[spec.as] = r[spec.as];
|
|
1165
|
+
return projected;
|
|
1166
|
+
});
|
|
1167
|
+
}
|
|
1168
|
+
return rows;
|
|
1169
|
+
}
|
|
1170
|
+
/** Resolve one `$lookup` spec against already-fetched rows (2 queries, no N+1). */
|
|
1171
|
+
async applyLookup(rows, spec) {
|
|
1172
|
+
const localValues = [
|
|
1173
|
+
...new Set(
|
|
1174
|
+
rows.map((r) => r[spec.localField]).filter((v) => v !== void 0 && v !== null)
|
|
1175
|
+
)
|
|
1176
|
+
];
|
|
1177
|
+
const foreign = localValues.length ? await this.mon.collection(spec.from).findMany({
|
|
1178
|
+
where: { [spec.foreignField]: { in: localValues } }
|
|
1179
|
+
}) : [];
|
|
1180
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
1181
|
+
for (const f of foreign) {
|
|
1182
|
+
const key = f[spec.foreignField];
|
|
1183
|
+
const list = byKey.get(key);
|
|
1184
|
+
if (list) list.push(f);
|
|
1185
|
+
else byKey.set(key, [f]);
|
|
1186
|
+
}
|
|
1187
|
+
if (spec.unwind) {
|
|
1188
|
+
const out = [];
|
|
1189
|
+
for (const r of rows) {
|
|
1190
|
+
const matches = byKey.get(r[spec.localField]) ?? [];
|
|
1191
|
+
if (matches.length === 0) {
|
|
1192
|
+
if (spec.unwind === "preserve") out.push({ ...r, [spec.as]: null });
|
|
1193
|
+
} else {
|
|
1194
|
+
for (const m of matches) out.push({ ...r, [spec.as]: m });
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
return out;
|
|
1198
|
+
}
|
|
1199
|
+
return rows.map((r) => ({
|
|
1200
|
+
...r,
|
|
1201
|
+
[spec.as]: byKey.get(r[spec.localField]) ?? []
|
|
1202
|
+
}));
|
|
1154
1203
|
}
|
|
1155
1204
|
async findFirst(args = {}) {
|
|
1156
1205
|
const rows = await this.findMany({ ...args, take: 1 });
|