@monlite/core 0.8.0 → 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.
- package/README.md +25 -0
- package/dist/index.cjs +20 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +131 -99
- package/dist/index.d.ts +131 -99
- package/dist/index.js +20 -1
- 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
|
|
@@ -263,104 +390,6 @@ interface MonliteOptions {
|
|
|
263
390
|
verbose?: (sql: string) => void;
|
|
264
391
|
}
|
|
265
392
|
|
|
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
393
|
/**
|
|
365
394
|
* The minimal SQLite driver surface monlite needs. Implemented by both the
|
|
366
395
|
* better-sqlite3 and the built-in node:sqlite backends so the rest of the
|
|
@@ -581,8 +610,11 @@ declare class Monlite {
|
|
|
581
610
|
/** @internal Sync metadata store; present only when `{ sync: true }`. */
|
|
582
611
|
readonly $sync?: SyncStore;
|
|
583
612
|
private readonly collections;
|
|
613
|
+
private readonly plugins;
|
|
584
614
|
private closed;
|
|
585
615
|
constructor(filename: string, options?: MonliteOptions);
|
|
616
|
+
/** @internal Notify plugins that documents changed (post-commit). */
|
|
617
|
+
firePluginAfterWrite(collection: string, ids: string[]): void;
|
|
586
618
|
/** Stable node id for LWW tie-breaking (only when sync is enabled). */
|
|
587
619
|
get nodeId(): string | undefined;
|
|
588
620
|
/** The underlying native database handle (escape hatch). */
|
|
@@ -683,4 +715,4 @@ declare function objectId(): string;
|
|
|
683
715
|
/** True when a value looks like a monlite/ObjectId id (24 hex chars). */
|
|
684
716
|
declare function isObjectId(value: unknown): value is string;
|
|
685
717
|
|
|
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 };
|
|
718
|
+
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
|
|
@@ -263,104 +390,6 @@ interface MonliteOptions {
|
|
|
263
390
|
verbose?: (sql: string) => void;
|
|
264
391
|
}
|
|
265
392
|
|
|
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
393
|
/**
|
|
365
394
|
* The minimal SQLite driver surface monlite needs. Implemented by both the
|
|
366
395
|
* better-sqlite3 and the built-in node:sqlite backends so the rest of the
|
|
@@ -581,8 +610,11 @@ declare class Monlite {
|
|
|
581
610
|
/** @internal Sync metadata store; present only when `{ sync: true }`. */
|
|
582
611
|
readonly $sync?: SyncStore;
|
|
583
612
|
private readonly collections;
|
|
613
|
+
private readonly plugins;
|
|
584
614
|
private closed;
|
|
585
615
|
constructor(filename: string, options?: MonliteOptions);
|
|
616
|
+
/** @internal Notify plugins that documents changed (post-commit). */
|
|
617
|
+
firePluginAfterWrite(collection: string, ids: string[]): void;
|
|
586
618
|
/** Stable node id for LWW tie-breaking (only when sync is enabled). */
|
|
587
619
|
get nodeId(): string | undefined;
|
|
588
620
|
/** The underlying native database handle (escape hatch). */
|
|
@@ -683,4 +715,4 @@ declare function objectId(): string;
|
|
|
683
715
|
/** True when a value looks like a monlite/ObjectId id (24 hex chars). */
|
|
684
716
|
declare function isObjectId(value: unknown): value is string;
|
|
685
717
|
|
|
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 };
|
|
718
|
+
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) {
|
|
@@ -1885,6 +1887,7 @@ var Monlite = class {
|
|
|
1885
1887
|
/** @internal Sync metadata store; present only when `{ sync: true }`. */
|
|
1886
1888
|
$sync;
|
|
1887
1889
|
collections = /* @__PURE__ */ new Map();
|
|
1890
|
+
plugins;
|
|
1888
1891
|
closed = false;
|
|
1889
1892
|
constructor(filename, options = {}) {
|
|
1890
1893
|
this.driver = createDriver(filename, {
|
|
@@ -1902,6 +1905,15 @@ var Monlite = class {
|
|
|
1902
1905
|
if (options.sync) {
|
|
1903
1906
|
this.$sync = new SyncStore(this.driver, options.nodeId, this);
|
|
1904
1907
|
}
|
|
1908
|
+
this.plugins = options.plugins ?? [];
|
|
1909
|
+
for (const plugin of this.plugins) plugin.init?.(this);
|
|
1910
|
+
}
|
|
1911
|
+
/** @internal Notify plugins that documents changed (post-commit). */
|
|
1912
|
+
firePluginAfterWrite(collection, ids) {
|
|
1913
|
+
if (this.plugins.length === 0 || ids.length === 0) return;
|
|
1914
|
+
for (const plugin of this.plugins) {
|
|
1915
|
+
plugin.afterWrite?.(this, { collection, ids });
|
|
1916
|
+
}
|
|
1905
1917
|
}
|
|
1906
1918
|
/** Stable node id for LWW tie-breaking (only when sync is enabled). */
|
|
1907
1919
|
get nodeId() {
|
|
@@ -1927,6 +1939,13 @@ var Monlite = class {
|
|
|
1927
1939
|
if (!col) {
|
|
1928
1940
|
col = new Collection(this, name, options);
|
|
1929
1941
|
this.collections.set(name, col);
|
|
1942
|
+
for (const plugin of this.plugins) {
|
|
1943
|
+
for (const [method, impl] of Object.entries(
|
|
1944
|
+
plugin.collectionMethods ?? {}
|
|
1945
|
+
)) {
|
|
1946
|
+
col[method] = (...args) => impl(col, ...args);
|
|
1947
|
+
}
|
|
1948
|
+
}
|
|
1930
1949
|
} else if (options?.schema) {
|
|
1931
1950
|
const requested = Object.keys(options.schema);
|
|
1932
1951
|
const existing = new Set(col.columnNames);
|