@monlite/core 0.8.0 → 0.10.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 +26 -0
- package/dist/index.cjs +24 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +133 -99
- package/dist/index.d.ts +133 -99
- package/dist/index.js +24 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,9 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A collection. In **document** mode (default) every document is stored as JSON
|
|
3
|
+
* in a `data` column — schema-free. In **structured** mode (when a `schema` is
|
|
4
|
+
* given) the listed fields become real, typed SQL columns (fast, indexable,
|
|
5
|
+
* joinable) while any other fields overflow into a JSON `data` column. The CRUD
|
|
6
|
+
* and query API is identical in both modes.
|
|
7
|
+
*/
|
|
8
|
+
declare class Collection<T = Doc> {
|
|
9
|
+
private readonly mon;
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly mode: CollectionMode;
|
|
12
|
+
private initialized;
|
|
13
|
+
private readonly columnDefs;
|
|
14
|
+
private readonly columnOrder;
|
|
15
|
+
/** Declared native columns (empty in document mode). */
|
|
16
|
+
private readonly columns;
|
|
17
|
+
private readonly jsonColumns;
|
|
18
|
+
private insertSqlCache?;
|
|
19
|
+
private readonly trackPath;
|
|
20
|
+
constructor(mon: Monlite, name: string, options?: CollectionOptions);
|
|
21
|
+
private get db();
|
|
22
|
+
/** Run a DB operation, normalizing driver errors into typed MonliteErrors. */
|
|
23
|
+
private guard;
|
|
24
|
+
/** Native column names declared for this collection (structured mode). */
|
|
25
|
+
get columnNames(): string[];
|
|
26
|
+
private ensureTable;
|
|
27
|
+
private columnDdl;
|
|
28
|
+
/** Auto-additive migration: add declared columns missing from an existing table. */
|
|
29
|
+
private migrateColumns;
|
|
30
|
+
private rowToDoc;
|
|
31
|
+
private encodeColumn;
|
|
32
|
+
private insertColumns;
|
|
33
|
+
private insertSql;
|
|
34
|
+
/** Split an input document into a row aligned with `insertColumns()`. */
|
|
35
|
+
private buildInsert;
|
|
36
|
+
/** Build the `SET` clause + values to persist an updated document. */
|
|
37
|
+
private buildUpdateSet;
|
|
38
|
+
/** Sync store for recording local changes (both document and structured). */
|
|
39
|
+
private get recorder();
|
|
40
|
+
/** @internal Read a full document by id (mode-aware), synchronously. */
|
|
41
|
+
getRaw(id: string): WithId<T> | null;
|
|
42
|
+
/**
|
|
43
|
+
* @internal Apply a remote change to storage WITHOUT recording it to the
|
|
44
|
+
* change feed (the sync store records the `remote` feed row itself). Used by
|
|
45
|
+
* `@monlite/sync` so structured collections sync correctly through the same
|
|
46
|
+
* column/overflow split as local writes.
|
|
47
|
+
*/
|
|
48
|
+
applyRemoteWrite(op: "upsert" | "delete", id: string, doc: Record<string, any> | undefined, ts: number): void;
|
|
49
|
+
/** @internal Notify reactivity watchers and plugins that documents changed. */
|
|
50
|
+
private afterWrite;
|
|
51
|
+
create(args: CreateArgs<T>): Promise<WithId<T>>;
|
|
52
|
+
createMany(args: CreateManyArgs<T>): Promise<{
|
|
53
|
+
count: number;
|
|
54
|
+
}>;
|
|
55
|
+
private buildFindSql;
|
|
56
|
+
/** @internal Synchronous core of findMany (used by reactivity). */
|
|
57
|
+
findManyCore(args?: FindManyArgs<T>): WithId<T>[];
|
|
58
|
+
/** @internal Synchronous core of exists (used by reactivity). */
|
|
59
|
+
existsCore(where: WhereInput<T> | undefined): boolean;
|
|
60
|
+
findMany(args?: FindManyArgs<T>): Promise<WithId<T>[]>;
|
|
61
|
+
findFirst(args?: FindFirstArgs<T>): Promise<WithId<T> | null>;
|
|
62
|
+
/** Alias of {@link findFirst} for Prisma familiarity. */
|
|
63
|
+
findUnique(args?: FindFirstArgs<T>): Promise<WithId<T> | null>;
|
|
64
|
+
/** Like {@link findFirst} but throws if no document matches. */
|
|
65
|
+
findFirstOrThrow(args?: FindFirstArgs<T>): Promise<WithId<T>>;
|
|
66
|
+
/** True if at least one document matches. */
|
|
67
|
+
exists(where?: WhereInput<T>): Promise<boolean>;
|
|
68
|
+
/**
|
|
69
|
+
* Subscribe to a live query. The callback fires immediately with the current
|
|
70
|
+
* results (`type: "init"`) and again whenever a change affects the result set
|
|
71
|
+
* (row-level: only relevant changes trigger a recompute). Includes changes
|
|
72
|
+
* applied by `@monlite/sync`.
|
|
73
|
+
*/
|
|
74
|
+
watch(args: FindManyArgs<T> | undefined, cb: (event: LiveEvent<T>) => void): WatchHandle<T>;
|
|
75
|
+
/** Show SQLite's query plan for a `findMany`, and whether it uses an index. */
|
|
76
|
+
explain(args?: FindManyArgs<T>): Promise<ExplainResult>;
|
|
77
|
+
findById(id: string): Promise<WithId<T> | null>;
|
|
78
|
+
count(args?: CountArgs<T>): Promise<number>;
|
|
79
|
+
/**
|
|
80
|
+
* Return the distinct values of a field. Array fields stored in JSON are
|
|
81
|
+
* unwound (each element counts as a value), matching MongoDB's `distinct`.
|
|
82
|
+
*/
|
|
83
|
+
distinct(field: string, where?: WhereInput<T>): Promise<any[]>;
|
|
84
|
+
private runUpdate;
|
|
85
|
+
update(args: UpdateArgs<T>): Promise<WithId<T> | null>;
|
|
86
|
+
updateMany(args: UpdateArgs<T>): Promise<{
|
|
87
|
+
count: number;
|
|
88
|
+
}>;
|
|
89
|
+
upsert(args: UpsertArgs<T>): Promise<WithId<T>>;
|
|
90
|
+
private runDelete;
|
|
91
|
+
delete(args: DeleteArgs<T>): Promise<WithId<T> | null>;
|
|
92
|
+
deleteMany(args?: DeleteArgs<T>): Promise<{
|
|
93
|
+
count: number;
|
|
94
|
+
}>;
|
|
95
|
+
aggregate(args?: AggregateArgs<T>): Promise<AggregateResult>;
|
|
96
|
+
groupBy(args: GroupByArgs<T>): Promise<GroupByResult[]>;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Documents that changed in a single write, delivered to `afterWrite`. */
|
|
100
|
+
interface PluginChange {
|
|
101
|
+
collection: string;
|
|
102
|
+
ids: string[];
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* A monlite plugin. Plugins keep `@monlite/core` lean — heavier or optional
|
|
106
|
+
* capabilities (full-text search, vector, encryption) live in their own
|
|
107
|
+
* packages and hook in here.
|
|
108
|
+
*/
|
|
109
|
+
interface MonlitePlugin {
|
|
110
|
+
name: string;
|
|
111
|
+
/** Called once when the database opens (e.g. to create auxiliary tables). */
|
|
112
|
+
init?(db: Monlite): void;
|
|
113
|
+
/**
|
|
114
|
+
* Called synchronously after every committed write (including changes applied
|
|
115
|
+
* by `@monlite/sync`), so derived state like a search index stays in sync.
|
|
116
|
+
*/
|
|
117
|
+
afterWrite?(db: Monlite, change: PluginChange): void;
|
|
118
|
+
/**
|
|
119
|
+
* Methods to attach to every collection handle (e.g. `search`). The impl
|
|
120
|
+
* receives the collection as its first argument, then the caller's arguments.
|
|
121
|
+
*/
|
|
122
|
+
collectionMethods?: Record<string, (collection: Collection<any>, ...args: any[]) => any>;
|
|
123
|
+
}
|
|
124
|
+
|
|
1
125
|
/**
|
|
2
126
|
* Public type surface for monlite.
|
|
3
127
|
*
|
|
4
128
|
* Documents are plain objects. monlite adds three system fields to every
|
|
5
129
|
* stored document: `_id`, `created_at`, and `updated_at`.
|
|
6
130
|
*/
|
|
131
|
+
|
|
7
132
|
/** A free-form document. */
|
|
8
133
|
type Doc = Record<string, any>;
|
|
9
134
|
/** System fields monlite manages on every document. */
|
|
@@ -238,6 +363,8 @@ interface MonliteOptions {
|
|
|
238
363
|
* when installed, otherwise the built-in `node:sqlite` (Node >= 22.5).
|
|
239
364
|
*/
|
|
240
365
|
driver?: DriverName;
|
|
366
|
+
/** Opt-in plugins (e.g. `@monlite/fts`). */
|
|
367
|
+
plugins?: MonlitePlugin[];
|
|
241
368
|
/**
|
|
242
369
|
* Enable sync metadata (change feed, tombstones, version tracking) so the
|
|
243
370
|
* database can replicate via `@monlite/sync`. Off by default — adds zero
|
|
@@ -259,108 +386,12 @@ interface MonliteOptions {
|
|
|
259
386
|
wal?: boolean;
|
|
260
387
|
/** Milliseconds to wait on a locked database before erroring. Default `5000`. */
|
|
261
388
|
busyTimeout?: number;
|
|
389
|
+
/** Allow loading SQLite extensions (required by `@monlite/vector`). Default `false`. */
|
|
390
|
+
allowExtensions?: boolean;
|
|
262
391
|
/** Verbose logger for executed SQL (debugging). */
|
|
263
392
|
verbose?: (sql: string) => void;
|
|
264
393
|
}
|
|
265
394
|
|
|
266
|
-
/**
|
|
267
|
-
* A collection. In **document** mode (default) every document is stored as JSON
|
|
268
|
-
* in a `data` column — schema-free. In **structured** mode (when a `schema` is
|
|
269
|
-
* given) the listed fields become real, typed SQL columns (fast, indexable,
|
|
270
|
-
* joinable) while any other fields overflow into a JSON `data` column. The CRUD
|
|
271
|
-
* and query API is identical in both modes.
|
|
272
|
-
*/
|
|
273
|
-
declare class Collection<T = Doc> {
|
|
274
|
-
private readonly mon;
|
|
275
|
-
readonly name: string;
|
|
276
|
-
readonly mode: CollectionMode;
|
|
277
|
-
private initialized;
|
|
278
|
-
private readonly columnDefs;
|
|
279
|
-
private readonly columnOrder;
|
|
280
|
-
/** Declared native columns (empty in document mode). */
|
|
281
|
-
private readonly columns;
|
|
282
|
-
private readonly jsonColumns;
|
|
283
|
-
private insertSqlCache?;
|
|
284
|
-
private readonly trackPath;
|
|
285
|
-
constructor(mon: Monlite, name: string, options?: CollectionOptions);
|
|
286
|
-
private get db();
|
|
287
|
-
/** Run a DB operation, normalizing driver errors into typed MonliteErrors. */
|
|
288
|
-
private guard;
|
|
289
|
-
/** Native column names declared for this collection (structured mode). */
|
|
290
|
-
get columnNames(): string[];
|
|
291
|
-
private ensureTable;
|
|
292
|
-
private columnDdl;
|
|
293
|
-
/** Auto-additive migration: add declared columns missing from an existing table. */
|
|
294
|
-
private migrateColumns;
|
|
295
|
-
private rowToDoc;
|
|
296
|
-
private encodeColumn;
|
|
297
|
-
private insertColumns;
|
|
298
|
-
private insertSql;
|
|
299
|
-
/** Split an input document into a row aligned with `insertColumns()`. */
|
|
300
|
-
private buildInsert;
|
|
301
|
-
/** Build the `SET` clause + values to persist an updated document. */
|
|
302
|
-
private buildUpdateSet;
|
|
303
|
-
/** Sync store for recording local changes (both document and structured). */
|
|
304
|
-
private get recorder();
|
|
305
|
-
/** @internal Read a full document by id (mode-aware), synchronously. */
|
|
306
|
-
getRaw(id: string): WithId<T> | null;
|
|
307
|
-
/**
|
|
308
|
-
* @internal Apply a remote change to storage WITHOUT recording it to the
|
|
309
|
-
* change feed (the sync store records the `remote` feed row itself). Used by
|
|
310
|
-
* `@monlite/sync` so structured collections sync correctly through the same
|
|
311
|
-
* column/overflow split as local writes.
|
|
312
|
-
*/
|
|
313
|
-
applyRemoteWrite(op: "upsert" | "delete", id: string, doc: Record<string, any> | undefined, ts: number): void;
|
|
314
|
-
/** @internal Notify reactivity watchers that documents changed. */
|
|
315
|
-
private afterWrite;
|
|
316
|
-
create(args: CreateArgs<T>): Promise<WithId<T>>;
|
|
317
|
-
createMany(args: CreateManyArgs<T>): Promise<{
|
|
318
|
-
count: number;
|
|
319
|
-
}>;
|
|
320
|
-
private buildFindSql;
|
|
321
|
-
/** @internal Synchronous core of findMany (used by reactivity). */
|
|
322
|
-
findManyCore(args?: FindManyArgs<T>): WithId<T>[];
|
|
323
|
-
/** @internal Synchronous core of exists (used by reactivity). */
|
|
324
|
-
existsCore(where: WhereInput<T> | undefined): boolean;
|
|
325
|
-
findMany(args?: FindManyArgs<T>): Promise<WithId<T>[]>;
|
|
326
|
-
findFirst(args?: FindFirstArgs<T>): Promise<WithId<T> | null>;
|
|
327
|
-
/** Alias of {@link findFirst} for Prisma familiarity. */
|
|
328
|
-
findUnique(args?: FindFirstArgs<T>): Promise<WithId<T> | null>;
|
|
329
|
-
/** Like {@link findFirst} but throws if no document matches. */
|
|
330
|
-
findFirstOrThrow(args?: FindFirstArgs<T>): Promise<WithId<T>>;
|
|
331
|
-
/** True if at least one document matches. */
|
|
332
|
-
exists(where?: WhereInput<T>): Promise<boolean>;
|
|
333
|
-
/**
|
|
334
|
-
* Subscribe to a live query. The callback fires immediately with the current
|
|
335
|
-
* results (`type: "init"`) and again whenever a change affects the result set
|
|
336
|
-
* (row-level: only relevant changes trigger a recompute). Includes changes
|
|
337
|
-
* applied by `@monlite/sync`.
|
|
338
|
-
*/
|
|
339
|
-
watch(args: FindManyArgs<T> | undefined, cb: (event: LiveEvent<T>) => void): WatchHandle<T>;
|
|
340
|
-
/** Show SQLite's query plan for a `findMany`, and whether it uses an index. */
|
|
341
|
-
explain(args?: FindManyArgs<T>): Promise<ExplainResult>;
|
|
342
|
-
findById(id: string): Promise<WithId<T> | null>;
|
|
343
|
-
count(args?: CountArgs<T>): Promise<number>;
|
|
344
|
-
/**
|
|
345
|
-
* Return the distinct values of a field. Array fields stored in JSON are
|
|
346
|
-
* unwound (each element counts as a value), matching MongoDB's `distinct`.
|
|
347
|
-
*/
|
|
348
|
-
distinct(field: string, where?: WhereInput<T>): Promise<any[]>;
|
|
349
|
-
private runUpdate;
|
|
350
|
-
update(args: UpdateArgs<T>): Promise<WithId<T> | null>;
|
|
351
|
-
updateMany(args: UpdateArgs<T>): Promise<{
|
|
352
|
-
count: number;
|
|
353
|
-
}>;
|
|
354
|
-
upsert(args: UpsertArgs<T>): Promise<WithId<T>>;
|
|
355
|
-
private runDelete;
|
|
356
|
-
delete(args: DeleteArgs<T>): Promise<WithId<T> | null>;
|
|
357
|
-
deleteMany(args?: DeleteArgs<T>): Promise<{
|
|
358
|
-
count: number;
|
|
359
|
-
}>;
|
|
360
|
-
aggregate(args?: AggregateArgs<T>): Promise<AggregateResult>;
|
|
361
|
-
groupBy(args: GroupByArgs<T>): Promise<GroupByResult[]>;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
395
|
/**
|
|
365
396
|
* The minimal SQLite driver surface monlite needs. Implemented by both the
|
|
366
397
|
* better-sqlite3 and the built-in node:sqlite backends so the rest of the
|
|
@@ -581,8 +612,11 @@ declare class Monlite {
|
|
|
581
612
|
/** @internal Sync metadata store; present only when `{ sync: true }`. */
|
|
582
613
|
readonly $sync?: SyncStore;
|
|
583
614
|
private readonly collections;
|
|
615
|
+
private readonly plugins;
|
|
584
616
|
private closed;
|
|
585
617
|
constructor(filename: string, options?: MonliteOptions);
|
|
618
|
+
/** @internal Notify plugins that documents changed (post-commit). */
|
|
619
|
+
firePluginAfterWrite(collection: string, ids: string[]): void;
|
|
586
620
|
/** Stable node id for LWW tie-breaking (only when sync is enabled). */
|
|
587
621
|
get nodeId(): string | undefined;
|
|
588
622
|
/** The underlying native database handle (escape hatch). */
|
|
@@ -683,4 +717,4 @@ declare function objectId(): string;
|
|
|
683
717
|
/** True when a value looks like a monlite/ObjectId id (24 hex chars). */
|
|
684
718
|
declare function isObjectId(value: unknown): value is string;
|
|
685
719
|
|
|
686
|
-
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 ExplainResult, type FieldFilter, type FieldSelection, type FilterInput, type FindFirstArgs, type FindManyArgs, type GroupByArgs, type GroupByResult, type HavingComparison, type HavingInput, type LiveEvent, type LocalChange, Monlite, MonliteConstraintError, MonliteError, MonliteForeignKeyError, MonliteNotNullError, type MonliteOptions, MonliteQueryError, MonliteUniqueConstraintError, type OrderBy, type PreparedStatement, type RemoteChange, 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 };
|
|
720
|
+
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 ExplainResult, type FieldFilter, type FieldSelection, type FilterInput, type FindFirstArgs, type FindManyArgs, type GroupByArgs, type GroupByResult, type HavingComparison, type HavingInput, type LiveEvent, type LocalChange, Monlite, MonliteConstraintError, MonliteError, MonliteForeignKeyError, MonliteNotNullError, type MonliteOptions, type MonlitePlugin, MonliteQueryError, MonliteUniqueConstraintError, type OrderBy, type PluginChange, type PreparedStatement, type RemoteChange, 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
|
@@ -1,9 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A collection. In **document** mode (default) every document is stored as JSON
|
|
3
|
+
* in a `data` column — schema-free. In **structured** mode (when a `schema` is
|
|
4
|
+
* given) the listed fields become real, typed SQL columns (fast, indexable,
|
|
5
|
+
* joinable) while any other fields overflow into a JSON `data` column. The CRUD
|
|
6
|
+
* and query API is identical in both modes.
|
|
7
|
+
*/
|
|
8
|
+
declare class Collection<T = Doc> {
|
|
9
|
+
private readonly mon;
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly mode: CollectionMode;
|
|
12
|
+
private initialized;
|
|
13
|
+
private readonly columnDefs;
|
|
14
|
+
private readonly columnOrder;
|
|
15
|
+
/** Declared native columns (empty in document mode). */
|
|
16
|
+
private readonly columns;
|
|
17
|
+
private readonly jsonColumns;
|
|
18
|
+
private insertSqlCache?;
|
|
19
|
+
private readonly trackPath;
|
|
20
|
+
constructor(mon: Monlite, name: string, options?: CollectionOptions);
|
|
21
|
+
private get db();
|
|
22
|
+
/** Run a DB operation, normalizing driver errors into typed MonliteErrors. */
|
|
23
|
+
private guard;
|
|
24
|
+
/** Native column names declared for this collection (structured mode). */
|
|
25
|
+
get columnNames(): string[];
|
|
26
|
+
private ensureTable;
|
|
27
|
+
private columnDdl;
|
|
28
|
+
/** Auto-additive migration: add declared columns missing from an existing table. */
|
|
29
|
+
private migrateColumns;
|
|
30
|
+
private rowToDoc;
|
|
31
|
+
private encodeColumn;
|
|
32
|
+
private insertColumns;
|
|
33
|
+
private insertSql;
|
|
34
|
+
/** Split an input document into a row aligned with `insertColumns()`. */
|
|
35
|
+
private buildInsert;
|
|
36
|
+
/** Build the `SET` clause + values to persist an updated document. */
|
|
37
|
+
private buildUpdateSet;
|
|
38
|
+
/** Sync store for recording local changes (both document and structured). */
|
|
39
|
+
private get recorder();
|
|
40
|
+
/** @internal Read a full document by id (mode-aware), synchronously. */
|
|
41
|
+
getRaw(id: string): WithId<T> | null;
|
|
42
|
+
/**
|
|
43
|
+
* @internal Apply a remote change to storage WITHOUT recording it to the
|
|
44
|
+
* change feed (the sync store records the `remote` feed row itself). Used by
|
|
45
|
+
* `@monlite/sync` so structured collections sync correctly through the same
|
|
46
|
+
* column/overflow split as local writes.
|
|
47
|
+
*/
|
|
48
|
+
applyRemoteWrite(op: "upsert" | "delete", id: string, doc: Record<string, any> | undefined, ts: number): void;
|
|
49
|
+
/** @internal Notify reactivity watchers and plugins that documents changed. */
|
|
50
|
+
private afterWrite;
|
|
51
|
+
create(args: CreateArgs<T>): Promise<WithId<T>>;
|
|
52
|
+
createMany(args: CreateManyArgs<T>): Promise<{
|
|
53
|
+
count: number;
|
|
54
|
+
}>;
|
|
55
|
+
private buildFindSql;
|
|
56
|
+
/** @internal Synchronous core of findMany (used by reactivity). */
|
|
57
|
+
findManyCore(args?: FindManyArgs<T>): WithId<T>[];
|
|
58
|
+
/** @internal Synchronous core of exists (used by reactivity). */
|
|
59
|
+
existsCore(where: WhereInput<T> | undefined): boolean;
|
|
60
|
+
findMany(args?: FindManyArgs<T>): Promise<WithId<T>[]>;
|
|
61
|
+
findFirst(args?: FindFirstArgs<T>): Promise<WithId<T> | null>;
|
|
62
|
+
/** Alias of {@link findFirst} for Prisma familiarity. */
|
|
63
|
+
findUnique(args?: FindFirstArgs<T>): Promise<WithId<T> | null>;
|
|
64
|
+
/** Like {@link findFirst} but throws if no document matches. */
|
|
65
|
+
findFirstOrThrow(args?: FindFirstArgs<T>): Promise<WithId<T>>;
|
|
66
|
+
/** True if at least one document matches. */
|
|
67
|
+
exists(where?: WhereInput<T>): Promise<boolean>;
|
|
68
|
+
/**
|
|
69
|
+
* Subscribe to a live query. The callback fires immediately with the current
|
|
70
|
+
* results (`type: "init"`) and again whenever a change affects the result set
|
|
71
|
+
* (row-level: only relevant changes trigger a recompute). Includes changes
|
|
72
|
+
* applied by `@monlite/sync`.
|
|
73
|
+
*/
|
|
74
|
+
watch(args: FindManyArgs<T> | undefined, cb: (event: LiveEvent<T>) => void): WatchHandle<T>;
|
|
75
|
+
/** Show SQLite's query plan for a `findMany`, and whether it uses an index. */
|
|
76
|
+
explain(args?: FindManyArgs<T>): Promise<ExplainResult>;
|
|
77
|
+
findById(id: string): Promise<WithId<T> | null>;
|
|
78
|
+
count(args?: CountArgs<T>): Promise<number>;
|
|
79
|
+
/**
|
|
80
|
+
* Return the distinct values of a field. Array fields stored in JSON are
|
|
81
|
+
* unwound (each element counts as a value), matching MongoDB's `distinct`.
|
|
82
|
+
*/
|
|
83
|
+
distinct(field: string, where?: WhereInput<T>): Promise<any[]>;
|
|
84
|
+
private runUpdate;
|
|
85
|
+
update(args: UpdateArgs<T>): Promise<WithId<T> | null>;
|
|
86
|
+
updateMany(args: UpdateArgs<T>): Promise<{
|
|
87
|
+
count: number;
|
|
88
|
+
}>;
|
|
89
|
+
upsert(args: UpsertArgs<T>): Promise<WithId<T>>;
|
|
90
|
+
private runDelete;
|
|
91
|
+
delete(args: DeleteArgs<T>): Promise<WithId<T> | null>;
|
|
92
|
+
deleteMany(args?: DeleteArgs<T>): Promise<{
|
|
93
|
+
count: number;
|
|
94
|
+
}>;
|
|
95
|
+
aggregate(args?: AggregateArgs<T>): Promise<AggregateResult>;
|
|
96
|
+
groupBy(args: GroupByArgs<T>): Promise<GroupByResult[]>;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Documents that changed in a single write, delivered to `afterWrite`. */
|
|
100
|
+
interface PluginChange {
|
|
101
|
+
collection: string;
|
|
102
|
+
ids: string[];
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* A monlite plugin. Plugins keep `@monlite/core` lean — heavier or optional
|
|
106
|
+
* capabilities (full-text search, vector, encryption) live in their own
|
|
107
|
+
* packages and hook in here.
|
|
108
|
+
*/
|
|
109
|
+
interface MonlitePlugin {
|
|
110
|
+
name: string;
|
|
111
|
+
/** Called once when the database opens (e.g. to create auxiliary tables). */
|
|
112
|
+
init?(db: Monlite): void;
|
|
113
|
+
/**
|
|
114
|
+
* Called synchronously after every committed write (including changes applied
|
|
115
|
+
* by `@monlite/sync`), so derived state like a search index stays in sync.
|
|
116
|
+
*/
|
|
117
|
+
afterWrite?(db: Monlite, change: PluginChange): void;
|
|
118
|
+
/**
|
|
119
|
+
* Methods to attach to every collection handle (e.g. `search`). The impl
|
|
120
|
+
* receives the collection as its first argument, then the caller's arguments.
|
|
121
|
+
*/
|
|
122
|
+
collectionMethods?: Record<string, (collection: Collection<any>, ...args: any[]) => any>;
|
|
123
|
+
}
|
|
124
|
+
|
|
1
125
|
/**
|
|
2
126
|
* Public type surface for monlite.
|
|
3
127
|
*
|
|
4
128
|
* Documents are plain objects. monlite adds three system fields to every
|
|
5
129
|
* stored document: `_id`, `created_at`, and `updated_at`.
|
|
6
130
|
*/
|
|
131
|
+
|
|
7
132
|
/** A free-form document. */
|
|
8
133
|
type Doc = Record<string, any>;
|
|
9
134
|
/** System fields monlite manages on every document. */
|
|
@@ -238,6 +363,8 @@ interface MonliteOptions {
|
|
|
238
363
|
* when installed, otherwise the built-in `node:sqlite` (Node >= 22.5).
|
|
239
364
|
*/
|
|
240
365
|
driver?: DriverName;
|
|
366
|
+
/** Opt-in plugins (e.g. `@monlite/fts`). */
|
|
367
|
+
plugins?: MonlitePlugin[];
|
|
241
368
|
/**
|
|
242
369
|
* Enable sync metadata (change feed, tombstones, version tracking) so the
|
|
243
370
|
* database can replicate via `@monlite/sync`. Off by default — adds zero
|
|
@@ -259,108 +386,12 @@ interface MonliteOptions {
|
|
|
259
386
|
wal?: boolean;
|
|
260
387
|
/** Milliseconds to wait on a locked database before erroring. Default `5000`. */
|
|
261
388
|
busyTimeout?: number;
|
|
389
|
+
/** Allow loading SQLite extensions (required by `@monlite/vector`). Default `false`. */
|
|
390
|
+
allowExtensions?: boolean;
|
|
262
391
|
/** Verbose logger for executed SQL (debugging). */
|
|
263
392
|
verbose?: (sql: string) => void;
|
|
264
393
|
}
|
|
265
394
|
|
|
266
|
-
/**
|
|
267
|
-
* A collection. In **document** mode (default) every document is stored as JSON
|
|
268
|
-
* in a `data` column — schema-free. In **structured** mode (when a `schema` is
|
|
269
|
-
* given) the listed fields become real, typed SQL columns (fast, indexable,
|
|
270
|
-
* joinable) while any other fields overflow into a JSON `data` column. The CRUD
|
|
271
|
-
* and query API is identical in both modes.
|
|
272
|
-
*/
|
|
273
|
-
declare class Collection<T = Doc> {
|
|
274
|
-
private readonly mon;
|
|
275
|
-
readonly name: string;
|
|
276
|
-
readonly mode: CollectionMode;
|
|
277
|
-
private initialized;
|
|
278
|
-
private readonly columnDefs;
|
|
279
|
-
private readonly columnOrder;
|
|
280
|
-
/** Declared native columns (empty in document mode). */
|
|
281
|
-
private readonly columns;
|
|
282
|
-
private readonly jsonColumns;
|
|
283
|
-
private insertSqlCache?;
|
|
284
|
-
private readonly trackPath;
|
|
285
|
-
constructor(mon: Monlite, name: string, options?: CollectionOptions);
|
|
286
|
-
private get db();
|
|
287
|
-
/** Run a DB operation, normalizing driver errors into typed MonliteErrors. */
|
|
288
|
-
private guard;
|
|
289
|
-
/** Native column names declared for this collection (structured mode). */
|
|
290
|
-
get columnNames(): string[];
|
|
291
|
-
private ensureTable;
|
|
292
|
-
private columnDdl;
|
|
293
|
-
/** Auto-additive migration: add declared columns missing from an existing table. */
|
|
294
|
-
private migrateColumns;
|
|
295
|
-
private rowToDoc;
|
|
296
|
-
private encodeColumn;
|
|
297
|
-
private insertColumns;
|
|
298
|
-
private insertSql;
|
|
299
|
-
/** Split an input document into a row aligned with `insertColumns()`. */
|
|
300
|
-
private buildInsert;
|
|
301
|
-
/** Build the `SET` clause + values to persist an updated document. */
|
|
302
|
-
private buildUpdateSet;
|
|
303
|
-
/** Sync store for recording local changes (both document and structured). */
|
|
304
|
-
private get recorder();
|
|
305
|
-
/** @internal Read a full document by id (mode-aware), synchronously. */
|
|
306
|
-
getRaw(id: string): WithId<T> | null;
|
|
307
|
-
/**
|
|
308
|
-
* @internal Apply a remote change to storage WITHOUT recording it to the
|
|
309
|
-
* change feed (the sync store records the `remote` feed row itself). Used by
|
|
310
|
-
* `@monlite/sync` so structured collections sync correctly through the same
|
|
311
|
-
* column/overflow split as local writes.
|
|
312
|
-
*/
|
|
313
|
-
applyRemoteWrite(op: "upsert" | "delete", id: string, doc: Record<string, any> | undefined, ts: number): void;
|
|
314
|
-
/** @internal Notify reactivity watchers that documents changed. */
|
|
315
|
-
private afterWrite;
|
|
316
|
-
create(args: CreateArgs<T>): Promise<WithId<T>>;
|
|
317
|
-
createMany(args: CreateManyArgs<T>): Promise<{
|
|
318
|
-
count: number;
|
|
319
|
-
}>;
|
|
320
|
-
private buildFindSql;
|
|
321
|
-
/** @internal Synchronous core of findMany (used by reactivity). */
|
|
322
|
-
findManyCore(args?: FindManyArgs<T>): WithId<T>[];
|
|
323
|
-
/** @internal Synchronous core of exists (used by reactivity). */
|
|
324
|
-
existsCore(where: WhereInput<T> | undefined): boolean;
|
|
325
|
-
findMany(args?: FindManyArgs<T>): Promise<WithId<T>[]>;
|
|
326
|
-
findFirst(args?: FindFirstArgs<T>): Promise<WithId<T> | null>;
|
|
327
|
-
/** Alias of {@link findFirst} for Prisma familiarity. */
|
|
328
|
-
findUnique(args?: FindFirstArgs<T>): Promise<WithId<T> | null>;
|
|
329
|
-
/** Like {@link findFirst} but throws if no document matches. */
|
|
330
|
-
findFirstOrThrow(args?: FindFirstArgs<T>): Promise<WithId<T>>;
|
|
331
|
-
/** True if at least one document matches. */
|
|
332
|
-
exists(where?: WhereInput<T>): Promise<boolean>;
|
|
333
|
-
/**
|
|
334
|
-
* Subscribe to a live query. The callback fires immediately with the current
|
|
335
|
-
* results (`type: "init"`) and again whenever a change affects the result set
|
|
336
|
-
* (row-level: only relevant changes trigger a recompute). Includes changes
|
|
337
|
-
* applied by `@monlite/sync`.
|
|
338
|
-
*/
|
|
339
|
-
watch(args: FindManyArgs<T> | undefined, cb: (event: LiveEvent<T>) => void): WatchHandle<T>;
|
|
340
|
-
/** Show SQLite's query plan for a `findMany`, and whether it uses an index. */
|
|
341
|
-
explain(args?: FindManyArgs<T>): Promise<ExplainResult>;
|
|
342
|
-
findById(id: string): Promise<WithId<T> | null>;
|
|
343
|
-
count(args?: CountArgs<T>): Promise<number>;
|
|
344
|
-
/**
|
|
345
|
-
* Return the distinct values of a field. Array fields stored in JSON are
|
|
346
|
-
* unwound (each element counts as a value), matching MongoDB's `distinct`.
|
|
347
|
-
*/
|
|
348
|
-
distinct(field: string, where?: WhereInput<T>): Promise<any[]>;
|
|
349
|
-
private runUpdate;
|
|
350
|
-
update(args: UpdateArgs<T>): Promise<WithId<T> | null>;
|
|
351
|
-
updateMany(args: UpdateArgs<T>): Promise<{
|
|
352
|
-
count: number;
|
|
353
|
-
}>;
|
|
354
|
-
upsert(args: UpsertArgs<T>): Promise<WithId<T>>;
|
|
355
|
-
private runDelete;
|
|
356
|
-
delete(args: DeleteArgs<T>): Promise<WithId<T> | null>;
|
|
357
|
-
deleteMany(args?: DeleteArgs<T>): Promise<{
|
|
358
|
-
count: number;
|
|
359
|
-
}>;
|
|
360
|
-
aggregate(args?: AggregateArgs<T>): Promise<AggregateResult>;
|
|
361
|
-
groupBy(args: GroupByArgs<T>): Promise<GroupByResult[]>;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
395
|
/**
|
|
365
396
|
* The minimal SQLite driver surface monlite needs. Implemented by both the
|
|
366
397
|
* better-sqlite3 and the built-in node:sqlite backends so the rest of the
|
|
@@ -581,8 +612,11 @@ declare class Monlite {
|
|
|
581
612
|
/** @internal Sync metadata store; present only when `{ sync: true }`. */
|
|
582
613
|
readonly $sync?: SyncStore;
|
|
583
614
|
private readonly collections;
|
|
615
|
+
private readonly plugins;
|
|
584
616
|
private closed;
|
|
585
617
|
constructor(filename: string, options?: MonliteOptions);
|
|
618
|
+
/** @internal Notify plugins that documents changed (post-commit). */
|
|
619
|
+
firePluginAfterWrite(collection: string, ids: string[]): void;
|
|
586
620
|
/** Stable node id for LWW tie-breaking (only when sync is enabled). */
|
|
587
621
|
get nodeId(): string | undefined;
|
|
588
622
|
/** The underlying native database handle (escape hatch). */
|
|
@@ -683,4 +717,4 @@ declare function objectId(): string;
|
|
|
683
717
|
/** True when a value looks like a monlite/ObjectId id (24 hex chars). */
|
|
684
718
|
declare function isObjectId(value: unknown): value is string;
|
|
685
719
|
|
|
686
|
-
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 ExplainResult, type FieldFilter, type FieldSelection, type FilterInput, type FindFirstArgs, type FindManyArgs, type GroupByArgs, type GroupByResult, type HavingComparison, type HavingInput, type LiveEvent, type LocalChange, Monlite, MonliteConstraintError, MonliteError, MonliteForeignKeyError, MonliteNotNullError, type MonliteOptions, MonliteQueryError, MonliteUniqueConstraintError, type OrderBy, type PreparedStatement, type RemoteChange, 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 };
|
|
720
|
+
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 ExplainResult, type FieldFilter, type FieldSelection, type FilterInput, type FindFirstArgs, type FindManyArgs, type GroupByArgs, type GroupByResult, type HavingComparison, type HavingInput, type LiveEvent, type LocalChange, Monlite, MonliteConstraintError, MonliteError, MonliteForeignKeyError, MonliteNotNullError, type MonliteOptions, type MonlitePlugin, MonliteQueryError, MonliteUniqueConstraintError, type OrderBy, type PluginChange, type PreparedStatement, type RemoteChange, 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
|
@@ -949,9 +949,11 @@ var Collection = class {
|
|
|
949
949
|
).run(...values);
|
|
950
950
|
this.afterWrite([id]);
|
|
951
951
|
}
|
|
952
|
-
/** @internal Notify reactivity watchers that documents changed. */
|
|
952
|
+
/** @internal Notify reactivity watchers and plugins that documents changed. */
|
|
953
953
|
afterWrite(ids) {
|
|
954
|
+
if (ids.length === 0) return;
|
|
954
955
|
this.mon.reactor.emit(this.name, ids);
|
|
956
|
+
this.mon.firePluginAfterWrite(this.name, ids);
|
|
955
957
|
}
|
|
956
958
|
/* ----------------------------- create ----------------------------- */
|
|
957
959
|
async create(args) {
|
|
@@ -1368,8 +1370,10 @@ var NodeSqliteDriver = class {
|
|
|
1368
1370
|
this.verbose = options.verbose;
|
|
1369
1371
|
const { DatabaseSync } = nodeSqlite;
|
|
1370
1372
|
this.raw = new DatabaseSync(filename, {
|
|
1371
|
-
readOnly: options.readonly ?? false
|
|
1373
|
+
readOnly: options.readonly ?? false,
|
|
1374
|
+
...options.allowExtensions ? { allowExtension: true } : {}
|
|
1372
1375
|
});
|
|
1376
|
+
if (options.allowExtensions) this.raw.enableLoadExtension(true);
|
|
1373
1377
|
this.raw.exec(`PRAGMA busy_timeout = ${options.busyTimeout ?? 5e3}`);
|
|
1374
1378
|
if (!options.readonly && (options.wal ?? true)) {
|
|
1375
1379
|
this.raw.exec("PRAGMA journal_mode = WAL");
|
|
@@ -1885,6 +1889,7 @@ var Monlite = class {
|
|
|
1885
1889
|
/** @internal Sync metadata store; present only when `{ sync: true }`. */
|
|
1886
1890
|
$sync;
|
|
1887
1891
|
collections = /* @__PURE__ */ new Map();
|
|
1892
|
+
plugins;
|
|
1888
1893
|
closed = false;
|
|
1889
1894
|
constructor(filename, options = {}) {
|
|
1890
1895
|
this.driver = createDriver(filename, {
|
|
@@ -1892,6 +1897,7 @@ var Monlite = class {
|
|
|
1892
1897
|
readonly: options.readonly,
|
|
1893
1898
|
wal: options.wal,
|
|
1894
1899
|
busyTimeout: options.busyTimeout,
|
|
1900
|
+
allowExtensions: options.allowExtensions,
|
|
1895
1901
|
verbose: options.verbose
|
|
1896
1902
|
});
|
|
1897
1903
|
this.autoIndexer = new AutoIndexer(
|
|
@@ -1902,6 +1908,15 @@ var Monlite = class {
|
|
|
1902
1908
|
if (options.sync) {
|
|
1903
1909
|
this.$sync = new SyncStore(this.driver, options.nodeId, this);
|
|
1904
1910
|
}
|
|
1911
|
+
this.plugins = options.plugins ?? [];
|
|
1912
|
+
for (const plugin of this.plugins) plugin.init?.(this);
|
|
1913
|
+
}
|
|
1914
|
+
/** @internal Notify plugins that documents changed (post-commit). */
|
|
1915
|
+
firePluginAfterWrite(collection, ids) {
|
|
1916
|
+
if (this.plugins.length === 0 || ids.length === 0) return;
|
|
1917
|
+
for (const plugin of this.plugins) {
|
|
1918
|
+
plugin.afterWrite?.(this, { collection, ids });
|
|
1919
|
+
}
|
|
1905
1920
|
}
|
|
1906
1921
|
/** Stable node id for LWW tie-breaking (only when sync is enabled). */
|
|
1907
1922
|
get nodeId() {
|
|
@@ -1927,6 +1942,13 @@ var Monlite = class {
|
|
|
1927
1942
|
if (!col) {
|
|
1928
1943
|
col = new Collection(this, name, options);
|
|
1929
1944
|
this.collections.set(name, col);
|
|
1945
|
+
for (const plugin of this.plugins) {
|
|
1946
|
+
for (const [method, impl] of Object.entries(
|
|
1947
|
+
plugin.collectionMethods ?? {}
|
|
1948
|
+
)) {
|
|
1949
|
+
col[method] = (...args) => impl(col, ...args);
|
|
1950
|
+
}
|
|
1951
|
+
}
|
|
1930
1952
|
} else if (options?.schema) {
|
|
1931
1953
|
const requested = Object.keys(options.schema);
|
|
1932
1954
|
const existing = new Set(col.columnNames);
|