@semics-tech/mongolite 1.3.0 → 1.4.1
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 +80 -21
- package/dist/cjs/collection.js +9 -6
- package/dist/cjs/cursors/findCursor.js +6 -4
- package/dist/cjs/index.js +108 -1
- package/dist/cjs/mongo-client.js +18 -1
- package/dist/cjs/server.js +164 -0
- package/dist/cjs/sync/commands.js +126 -0
- package/dist/cjs/sync/diff.js +174 -0
- package/dist/cjs/sync/httpSink.js +159 -0
- package/dist/cjs/sync/index.js +40 -0
- package/dist/cjs/sync/mongoExecutor.js +306 -0
- package/dist/cjs/sync/mongoSink.js +161 -0
- package/dist/cjs/sync/outbox.js +358 -0
- package/dist/cjs/sync/protocol.js +177 -0
- package/dist/cjs/sync/replicator.js +747 -0
- package/dist/cjs/sync/shadow.js +178 -0
- package/dist/cjs/sync/types.js +2 -0
- package/dist/cloudflare.d.ts +1 -1
- package/dist/cloudflare.js.map +1 -1
- package/dist/collection.js +9 -6
- package/dist/collection.js.map +1 -1
- package/dist/cursors/findCursor.d.ts +2 -1
- package/dist/cursors/findCursor.js +6 -4
- package/dist/cursors/findCursor.js.map +1 -1
- package/dist/index.d.ts +68 -2
- package/dist/index.js +96 -1
- package/dist/index.js.map +1 -1
- package/dist/mongo-client.d.ts +13 -0
- package/dist/mongo-client.js +18 -1
- package/dist/mongo-client.js.map +1 -1
- package/dist/server.d.ts +97 -0
- package/dist/server.js +158 -0
- package/dist/server.js.map +1 -0
- package/dist/sync/commands.d.ts +49 -0
- package/dist/sync/commands.js +118 -0
- package/dist/sync/commands.js.map +1 -0
- package/dist/sync/diff.d.ts +55 -0
- package/dist/sync/diff.js +169 -0
- package/dist/sync/diff.js.map +1 -0
- package/dist/sync/httpSink.d.ts +93 -0
- package/dist/sync/httpSink.js +155 -0
- package/dist/sync/httpSink.js.map +1 -0
- package/dist/sync/index.d.ts +17 -0
- package/dist/sync/index.js +10 -0
- package/dist/sync/index.js.map +1 -0
- package/dist/sync/mongoExecutor.d.ts +37 -0
- package/dist/sync/mongoExecutor.js +302 -0
- package/dist/sync/mongoExecutor.js.map +1 -0
- package/dist/sync/mongoSink.d.ts +109 -0
- package/dist/sync/mongoSink.js +123 -0
- package/dist/sync/mongoSink.js.map +1 -0
- package/dist/sync/outbox.d.ts +120 -0
- package/dist/sync/outbox.js +355 -0
- package/dist/sync/outbox.js.map +1 -0
- package/dist/sync/protocol.d.ts +93 -0
- package/dist/sync/protocol.js +168 -0
- package/dist/sync/protocol.js.map +1 -0
- package/dist/sync/replicator.d.ts +177 -0
- package/dist/sync/replicator.js +744 -0
- package/dist/sync/replicator.js.map +1 -0
- package/dist/sync/shadow.d.ts +54 -0
- package/dist/sync/shadow.js +173 -0
- package/dist/sync/shadow.js.map +1 -0
- package/dist/sync/types.d.ts +388 -0
- package/dist/sync/types.js +2 -0
- package/dist/sync/types.js.map +1 -0
- package/package.json +16 -2
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public types for one-way replication from a local MongoLite database to an
|
|
3
|
+
* upstream MongoDB deployment.
|
|
4
|
+
*
|
|
5
|
+
* The design is a **transactional outbox**: SQLite triggers record every row
|
|
6
|
+
* change into a durable log inside the same database (and the same transaction)
|
|
7
|
+
* as the write itself, and a background replicator drains that log into the
|
|
8
|
+
* upstream. Nothing is lost if the process dies or the network is down — the log
|
|
9
|
+
* simply grows until it can be drained.
|
|
10
|
+
*/
|
|
11
|
+
import type { DocumentDiff } from './diff.js';
|
|
12
|
+
export type { DocumentDiff };
|
|
13
|
+
/** The kind of change captured for a document. */
|
|
14
|
+
export type SyncOperationType = 'insert' | 'update' | 'delete';
|
|
15
|
+
/**
|
|
16
|
+
* A single change waiting to be replicated, as stored in the outbox.
|
|
17
|
+
*/
|
|
18
|
+
export interface SyncOutboxRecord {
|
|
19
|
+
/** Monotonic outbox sequence number. Doubles as the replication checkpoint. */
|
|
20
|
+
id: number;
|
|
21
|
+
/** Local collection the change happened in. */
|
|
22
|
+
collection: string;
|
|
23
|
+
/** `_id` of the affected document. */
|
|
24
|
+
documentId: string;
|
|
25
|
+
operation: SyncOperationType;
|
|
26
|
+
/**
|
|
27
|
+
* Document state after the change, including `_id`. `null` for deletes.
|
|
28
|
+
* Undefined only if the stored JSON was unparseable (such rows are dead-lettered).
|
|
29
|
+
*/
|
|
30
|
+
document: Record<string, unknown> | null;
|
|
31
|
+
/** Millisecond epoch when the change was captured locally. */
|
|
32
|
+
capturedAt: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A change coalesced into the single upstream operation that realises it.
|
|
36
|
+
*
|
|
37
|
+
* Replication is full-document last-write-wins, so a run of changes to one
|
|
38
|
+
* document collapses to whatever its final state was: an upsert of the latest
|
|
39
|
+
* document, or a delete.
|
|
40
|
+
*/
|
|
41
|
+
export interface SyncOperation {
|
|
42
|
+
/** Upstream collection name (after any `collectionMap` renaming). */
|
|
43
|
+
collection: string;
|
|
44
|
+
/** Local collection the change originated in. */
|
|
45
|
+
sourceCollection: string;
|
|
46
|
+
documentId: string;
|
|
47
|
+
type: 'upsert' | 'delete';
|
|
48
|
+
/** Full document to write upstream. Always present for `upsert`. */
|
|
49
|
+
document?: Record<string, unknown>;
|
|
50
|
+
/** Outbox id this operation was derived from — the newest row for the document. */
|
|
51
|
+
outboxId: number;
|
|
52
|
+
/**
|
|
53
|
+
* The upstream `_v` this operation asserts against — the version last seen for this
|
|
54
|
+
* document. `null` means the document has never been upstream, so the write must
|
|
55
|
+
* create it rather than replace a known revision.
|
|
56
|
+
*
|
|
57
|
+
* A sink turns this into a conditional write; that is what makes a lost race
|
|
58
|
+
* detectable instead of silently overwriting a concurrent edit.
|
|
59
|
+
*/
|
|
60
|
+
baseVersion?: number | null;
|
|
61
|
+
/**
|
|
62
|
+
* The minimal change to apply upstream, relative to the last-known server state.
|
|
63
|
+
*
|
|
64
|
+
* Present for `upsert` whenever a shadow exists. Applying this rather than
|
|
65
|
+
* {@link SyncOperation.document} leaves untouched fields — including BSON values the
|
|
66
|
+
* local store cannot represent — exactly as they are upstream.
|
|
67
|
+
*/
|
|
68
|
+
diff?: DocumentDiff;
|
|
69
|
+
}
|
|
70
|
+
/** Outcome of applying one batch of operations to the upstream. */
|
|
71
|
+
export interface SyncApplyResult {
|
|
72
|
+
/** Number of operations the upstream accepted. */
|
|
73
|
+
applied: number;
|
|
74
|
+
/**
|
|
75
|
+
* Operations the upstream rejected permanently (schema validation, document
|
|
76
|
+
* too large, …). These are dead-lettered rather than retried forever.
|
|
77
|
+
* Indexes refer to positions in the `operations` array passed to `apply`.
|
|
78
|
+
*/
|
|
79
|
+
failures?: SyncApplyFailure[];
|
|
80
|
+
/**
|
|
81
|
+
* Operations whose conditional write did not match — someone else changed the
|
|
82
|
+
* document upstream since it was last seen.
|
|
83
|
+
*
|
|
84
|
+
* This is a distinct outcome from {@link SyncApplyResult.failures}: a conflict is a
|
|
85
|
+
* normal thing to reconcile, not a poison document, so it is never dead-lettered.
|
|
86
|
+
*/
|
|
87
|
+
conflicts?: SyncApplyConflict[];
|
|
88
|
+
}
|
|
89
|
+
/** Why a conditional write did not land. */
|
|
90
|
+
export type SyncConflictReason =
|
|
91
|
+
/** The upstream `_v` had moved on — a concurrent writer got there first. */
|
|
92
|
+
'version-mismatch'
|
|
93
|
+
/** A document believed to be new already existed upstream. */
|
|
94
|
+
| 'already-exists'
|
|
95
|
+
/** A document expected upstream was not there. */
|
|
96
|
+
| 'missing';
|
|
97
|
+
/** An operation that lost a race against another writer. */
|
|
98
|
+
export interface SyncApplyConflict {
|
|
99
|
+
/** Index into the `operations` array passed to `apply`. */
|
|
100
|
+
index: number;
|
|
101
|
+
reason: SyncConflictReason;
|
|
102
|
+
/** The current upstream document, when the sink was able to read it back. */
|
|
103
|
+
serverDocument?: Record<string, unknown>;
|
|
104
|
+
/** The current upstream `_v`, when known. */
|
|
105
|
+
serverVersion?: number | null;
|
|
106
|
+
}
|
|
107
|
+
/** What to do about a document that changed upstream and locally at the same time. */
|
|
108
|
+
export type SyncConflictResolution =
|
|
109
|
+
/** Keep the upstream version and discard the local change. The default. */
|
|
110
|
+
'server'
|
|
111
|
+
/** Force the local version upstream, overwriting the other writer's change. */
|
|
112
|
+
| 'local'
|
|
113
|
+
/** Leave both sides alone; the local change is dropped without being retried. */
|
|
114
|
+
| 'skip';
|
|
115
|
+
/** Everything known about a conflict, passed to {@link SyncOptions.onConflict}. */
|
|
116
|
+
export interface SyncConflictContext {
|
|
117
|
+
/** Upstream collection name. */
|
|
118
|
+
collection: string;
|
|
119
|
+
/** Local collection the change originated in. */
|
|
120
|
+
sourceCollection: string;
|
|
121
|
+
documentId: string;
|
|
122
|
+
operation: 'upsert' | 'delete';
|
|
123
|
+
reason: SyncConflictReason;
|
|
124
|
+
/** The local document that failed to push. `null` for a delete. */
|
|
125
|
+
localDocument: Record<string, unknown> | null;
|
|
126
|
+
/** The current upstream document, if it could be read. */
|
|
127
|
+
serverDocument: Record<string, unknown> | null;
|
|
128
|
+
/** The version the push asserted against. */
|
|
129
|
+
baseVersion: number | null;
|
|
130
|
+
/** The version actually found upstream. */
|
|
131
|
+
serverVersion: number | null;
|
|
132
|
+
}
|
|
133
|
+
export interface SyncApplyFailure {
|
|
134
|
+
/** Index into the `operations` array passed to `apply`. */
|
|
135
|
+
index: number;
|
|
136
|
+
message: string;
|
|
137
|
+
/** Upstream error code, when the sink can determine one. */
|
|
138
|
+
code?: number | string;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* The destination a {@link SyncReplicator} writes to.
|
|
142
|
+
*
|
|
143
|
+
* Implement this to replicate somewhere other than a MongoDB deployment
|
|
144
|
+
* reachable by the official driver — an HTTP data API, a queue, or a test
|
|
145
|
+
* double. The replicator owns retries and checkpointing; a sink only has to
|
|
146
|
+
* apply a batch or throw.
|
|
147
|
+
*/
|
|
148
|
+
export interface SyncSink {
|
|
149
|
+
/** Human-readable name, used in log and event output. */
|
|
150
|
+
readonly name: string;
|
|
151
|
+
/** Establish the upstream connection. Called before the first `apply`, and again after a reconnect. */
|
|
152
|
+
connect?(): Promise<void>;
|
|
153
|
+
/**
|
|
154
|
+
* Apply a batch of coalesced operations.
|
|
155
|
+
*
|
|
156
|
+
* Throw to signal a **transient** failure — the replicator backs off and
|
|
157
|
+
* retries the same batch, so this must be safe to re-run. Return
|
|
158
|
+
* {@link SyncApplyResult.failures} to signal **permanent** per-operation
|
|
159
|
+
* failures, which are dead-lettered so one poison document cannot stall the
|
|
160
|
+
* whole stream.
|
|
161
|
+
*/
|
|
162
|
+
apply(operations: SyncOperation[]): Promise<SyncApplyResult>;
|
|
163
|
+
/**
|
|
164
|
+
* Reads documents back from the upstream by `_id`.
|
|
165
|
+
*
|
|
166
|
+
* Used to refresh the local shadow after a conflict, so the next push diffs against
|
|
167
|
+
* current upstream state instead of losing the race again. A sink that cannot read
|
|
168
|
+
* may omit this — conflict resolution then falls back to dropping the local change.
|
|
169
|
+
*
|
|
170
|
+
* Ids that do not exist upstream are simply absent from the result.
|
|
171
|
+
*/
|
|
172
|
+
fetch?(collection: string, documentIds: string[]): Promise<Record<string, unknown>[]>;
|
|
173
|
+
/** Release the upstream connection. */
|
|
174
|
+
close?(): Promise<void>;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* How to translate MongoLite's string `_id` values into upstream `_id` values.
|
|
178
|
+
*
|
|
179
|
+
* - `auto` (default) — a 24-character hex string becomes an `ObjectId`, anything
|
|
180
|
+
* else stays a string. MongoLite generates ObjectId-shaped ids, so this makes
|
|
181
|
+
* replicated documents look native upstream.
|
|
182
|
+
* - `string` — always write `_id` as a string. Use this when the upstream is
|
|
183
|
+
* already populated with string ids, or when ids that merely *look* like
|
|
184
|
+
* ObjectIds should stay strings.
|
|
185
|
+
*/
|
|
186
|
+
export type SyncIdMapping = 'auto' | 'string';
|
|
187
|
+
/** What to do when the outbox exceeds {@link SyncOptions.maxOutboxSize}. */
|
|
188
|
+
export type SyncOverflowStrategy =
|
|
189
|
+
/** Drop superseded revisions, keeping the newest row per document. Lossless — replication is last-write-wins. */
|
|
190
|
+
'compact'
|
|
191
|
+
/** Leave the outbox alone and only emit an `overflow` event. */
|
|
192
|
+
| 'warn';
|
|
193
|
+
/** Seeding behaviour for documents that already existed before sync was set up. */
|
|
194
|
+
export type SyncInitialMode =
|
|
195
|
+
/** Replicate the existing contents of each collection on first start. Default. */
|
|
196
|
+
'backfill'
|
|
197
|
+
/** Replicate only changes made from now on. */
|
|
198
|
+
| 'changes-only';
|
|
199
|
+
export interface SyncCollectionOptions {
|
|
200
|
+
/**
|
|
201
|
+
* Collections to replicate. Omit to replicate every collection in the
|
|
202
|
+
* database, including ones created later.
|
|
203
|
+
*/
|
|
204
|
+
collections?: string[];
|
|
205
|
+
/** Collections to exclude. Applied after `collections`. */
|
|
206
|
+
exclude?: string[];
|
|
207
|
+
/** Rename collections upstream: `{ localName: 'upstreamName' }`. */
|
|
208
|
+
collectionMap?: Record<string, string>;
|
|
209
|
+
}
|
|
210
|
+
export interface SyncOptions extends SyncCollectionOptions {
|
|
211
|
+
/**
|
|
212
|
+
* Replicator name. Persisted with the checkpoint, so restarting resumes where
|
|
213
|
+
* it left off. Use distinct names when replicating one database to several
|
|
214
|
+
* upstreams. Defaults to `'default'`.
|
|
215
|
+
*/
|
|
216
|
+
name?: string;
|
|
217
|
+
/** Maximum operations per upstream round trip. Defaults to `500`. */
|
|
218
|
+
batchSize?: number;
|
|
219
|
+
/**
|
|
220
|
+
* How long to wait before re-checking an empty outbox, in ms. Defaults to
|
|
221
|
+
* `250`. Writes made through this process wake the replicator immediately, so
|
|
222
|
+
* this only bounds the latency of changes made by *other* processes sharing
|
|
223
|
+
* the database file.
|
|
224
|
+
*/
|
|
225
|
+
pollIntervalMs?: number;
|
|
226
|
+
/** Initial delay before retrying a failed batch, in ms. Defaults to `500`. */
|
|
227
|
+
retryDelayMs?: number;
|
|
228
|
+
/** Ceiling for the exponential retry backoff, in ms. Defaults to `30_000`. */
|
|
229
|
+
maxRetryDelayMs?: number;
|
|
230
|
+
/**
|
|
231
|
+
* Give up on a batch after this many consecutive failures, stopping the
|
|
232
|
+
* replicator and emitting `error`. Defaults to `Infinity` — keep retrying, so
|
|
233
|
+
* a long outage is survived rather than dropped.
|
|
234
|
+
*/
|
|
235
|
+
maxRetries?: number;
|
|
236
|
+
/** See {@link SyncIdMapping}. Defaults to `'auto'`. */
|
|
237
|
+
idMapping?: SyncIdMapping;
|
|
238
|
+
/** See {@link SyncInitialMode}. Defaults to `'backfill'`. */
|
|
239
|
+
initial?: SyncInitialMode;
|
|
240
|
+
/**
|
|
241
|
+
* Soft cap on pending outbox rows. Exceeding it emits `overflow` and applies
|
|
242
|
+
* {@link SyncOptions.overflowStrategy}. Defaults to `100_000`.
|
|
243
|
+
*/
|
|
244
|
+
maxOutboxSize?: number;
|
|
245
|
+
/** See {@link SyncOverflowStrategy}. Defaults to `'compact'`. */
|
|
246
|
+
overflowStrategy?: SyncOverflowStrategy;
|
|
247
|
+
/**
|
|
248
|
+
* Rewrite or drop documents on their way upstream. Return `null` to skip the
|
|
249
|
+
* document entirely (the change is still acknowledged, not retried).
|
|
250
|
+
* Deletes are passed through with `document === null` and cannot be rewritten.
|
|
251
|
+
*/
|
|
252
|
+
transform?: (document: Record<string, unknown>, context: {
|
|
253
|
+
collection: string;
|
|
254
|
+
sourceCollection: string;
|
|
255
|
+
operation: SyncOperationType;
|
|
256
|
+
}) => Record<string, unknown> | null;
|
|
257
|
+
/** How often to re-scan for newly created collections, in ms. Defaults to `5_000`. */
|
|
258
|
+
collectionScanIntervalMs?: number;
|
|
259
|
+
/**
|
|
260
|
+
* Let the Node.js process exit while replication is still running. Defaults to
|
|
261
|
+
* `false`: a running replicator keeps the process alive, so a script cannot
|
|
262
|
+
* exit with changes still queued. Set to `true` for short-lived processes that
|
|
263
|
+
* manage their own lifetime.
|
|
264
|
+
*/
|
|
265
|
+
unref?: boolean;
|
|
266
|
+
/**
|
|
267
|
+
* Guard every push with a conditional write against the document's last-known
|
|
268
|
+
* upstream `_v`, so a concurrent edit by another writer is detected instead of
|
|
269
|
+
* silently overwritten. Defaults to `true`.
|
|
270
|
+
*
|
|
271
|
+
* Turning this off restores unconditional whole-document replacement: faster and
|
|
272
|
+
* free of the `_v`/`_updatedAt` fields, but the local database becomes the effective
|
|
273
|
+
* source of truth. Only appropriate when nothing else writes to the upstream.
|
|
274
|
+
*/
|
|
275
|
+
versioning?: boolean;
|
|
276
|
+
/**
|
|
277
|
+
* Called when a push loses a race against another writer.
|
|
278
|
+
*
|
|
279
|
+
* Return `'server'` (the default) to keep the upstream version and discard the local
|
|
280
|
+
* change, `'local'` to force the local version through anyway, or `'skip'` to leave
|
|
281
|
+
* both sides alone. Either way the local shadow is refreshed from the upstream first,
|
|
282
|
+
* so the decision is made against current state.
|
|
283
|
+
*/
|
|
284
|
+
onConflict?: (context: SyncConflictContext) => SyncConflictResolution;
|
|
285
|
+
/** Log replicator activity to the console. Defaults to `false`. */
|
|
286
|
+
verbose?: boolean;
|
|
287
|
+
}
|
|
288
|
+
/** Point-in-time view of replication progress. */
|
|
289
|
+
export interface SyncStatus {
|
|
290
|
+
name: string;
|
|
291
|
+
running: boolean;
|
|
292
|
+
/** True once the sink is connected and batches are flowing. */
|
|
293
|
+
connected: boolean;
|
|
294
|
+
/** Highest outbox id known to be applied upstream. */
|
|
295
|
+
checkpoint: number;
|
|
296
|
+
/** Outbox rows not yet applied. */
|
|
297
|
+
pending: number;
|
|
298
|
+
/** Operations successfully applied since `start()`. */
|
|
299
|
+
applied: number;
|
|
300
|
+
/** Batches that failed and were retried since `start()`. */
|
|
301
|
+
retries: number;
|
|
302
|
+
/** Operations permanently rejected upstream and moved to the dead-letter table. */
|
|
303
|
+
deadLettered: number;
|
|
304
|
+
/** Pushes that lost a race against another writer since `start()`. */
|
|
305
|
+
conflicts: number;
|
|
306
|
+
/** Collections currently being watched. */
|
|
307
|
+
collections: string[];
|
|
308
|
+
/** Last error seen, if replication is currently degraded. */
|
|
309
|
+
lastError?: string;
|
|
310
|
+
}
|
|
311
|
+
/** A permanently-rejected operation, retained for inspection and replay. */
|
|
312
|
+
export interface SyncDeadLetter {
|
|
313
|
+
id: number;
|
|
314
|
+
collection: string;
|
|
315
|
+
documentId: string;
|
|
316
|
+
operation: string;
|
|
317
|
+
document: Record<string, unknown> | null;
|
|
318
|
+
error: string;
|
|
319
|
+
failedAt: number;
|
|
320
|
+
}
|
|
321
|
+
/** Events emitted by {@link SyncReplicator}. */
|
|
322
|
+
export interface SyncEvents {
|
|
323
|
+
/** The sink connected (on start, and after recovering from an outage). */
|
|
324
|
+
connected: [];
|
|
325
|
+
/** A batch was applied upstream. */
|
|
326
|
+
batch: [{
|
|
327
|
+
applied: number;
|
|
328
|
+
deadLettered: number;
|
|
329
|
+
checkpoint: number;
|
|
330
|
+
}];
|
|
331
|
+
/** The outbox drained — everything local is upstream. */
|
|
332
|
+
drained: [{
|
|
333
|
+
checkpoint: number;
|
|
334
|
+
}];
|
|
335
|
+
/** A batch failed and will be retried after `retryInMs`. */
|
|
336
|
+
retry: [{
|
|
337
|
+
attempt: number;
|
|
338
|
+
retryInMs: number;
|
|
339
|
+
error: Error;
|
|
340
|
+
}];
|
|
341
|
+
/** An operation was permanently rejected and moved to the dead-letter table. */
|
|
342
|
+
deadLetter: [SyncDeadLetter];
|
|
343
|
+
/** A push lost a race against another writer; `resolution` is what was done about it. */
|
|
344
|
+
conflict: [SyncConflictContext & {
|
|
345
|
+
resolution: SyncConflictResolution;
|
|
346
|
+
}];
|
|
347
|
+
/** The outbox exceeded `maxOutboxSize`. */
|
|
348
|
+
overflow: [{
|
|
349
|
+
pending: number;
|
|
350
|
+
limit: number;
|
|
351
|
+
compacted: number;
|
|
352
|
+
}];
|
|
353
|
+
/** Replication stopped because of an unrecoverable error. */
|
|
354
|
+
error: [Error];
|
|
355
|
+
/** The replicator stopped. */
|
|
356
|
+
stopped: [];
|
|
357
|
+
}
|
|
358
|
+
/** Counts returned by a bulk write, used to detect conditional writes that did not match. */
|
|
359
|
+
export interface MongoBulkWriteResultLike {
|
|
360
|
+
matchedCount?: number;
|
|
361
|
+
modifiedCount?: number;
|
|
362
|
+
upsertedCount?: number;
|
|
363
|
+
deletedCount?: number;
|
|
364
|
+
/** Present on `MongoBulkWriteError`, mapping input index → generated `_id`. */
|
|
365
|
+
upsertedIds?: Record<number, unknown>;
|
|
366
|
+
}
|
|
367
|
+
/** Minimal shape of the pieces of the `mongodb` driver the sink uses. */
|
|
368
|
+
export interface MongoDriverLike {
|
|
369
|
+
MongoClient: new (uri: string, options?: Record<string, unknown>) => MongoClientLike;
|
|
370
|
+
ObjectId: {
|
|
371
|
+
new (id: string): unknown;
|
|
372
|
+
isValid(id: string): boolean;
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
export interface MongoClientLike {
|
|
376
|
+
connect(): Promise<unknown>;
|
|
377
|
+
close(force?: boolean): Promise<void>;
|
|
378
|
+
db(name?: string): MongoDbLike;
|
|
379
|
+
}
|
|
380
|
+
export interface MongoDbLike {
|
|
381
|
+
collection(name: string): MongoCollectionLike;
|
|
382
|
+
}
|
|
383
|
+
export interface MongoCollectionLike {
|
|
384
|
+
bulkWrite(operations: unknown[], options?: Record<string, unknown>): Promise<MongoBulkWriteResultLike>;
|
|
385
|
+
find(filter: Record<string, unknown>, options?: Record<string, unknown>): {
|
|
386
|
+
toArray(): Promise<Record<string, unknown>[]>;
|
|
387
|
+
};
|
|
388
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/sync/types.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@semics-tech/mongolite",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "A MongoDB-like client using SQLite as a persistent store, written in TypeScript.",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -21,6 +21,11 @@
|
|
|
21
21
|
"types": "./dist/better-sqlite3.d.ts",
|
|
22
22
|
"import": "./dist/better-sqlite3.js",
|
|
23
23
|
"require": "./dist/cjs/better-sqlite3.js"
|
|
24
|
+
},
|
|
25
|
+
"./server": {
|
|
26
|
+
"types": "./dist/server.d.ts",
|
|
27
|
+
"import": "./dist/server.js",
|
|
28
|
+
"require": "./dist/cjs/server.js"
|
|
24
29
|
}
|
|
25
30
|
},
|
|
26
31
|
"bin": {
|
|
@@ -71,7 +76,7 @@
|
|
|
71
76
|
},
|
|
72
77
|
"homepage": "https://github.com/semics-tech/mongolite#readme",
|
|
73
78
|
"devDependencies": {
|
|
74
|
-
"@types/better-sqlite3": "^
|
|
79
|
+
"@types/better-sqlite3": "^9.6.0",
|
|
75
80
|
"@types/node": "^26.1.2",
|
|
76
81
|
"@typescript-eslint/eslint-plugin": "^8.58.1",
|
|
77
82
|
"@typescript-eslint/parser": "^8.58.1",
|
|
@@ -80,6 +85,7 @@
|
|
|
80
85
|
"eslint-config-prettier": "^10.1.8",
|
|
81
86
|
"eslint-plugin-prettier": "^5.1.3",
|
|
82
87
|
"expect": "^30.0.0",
|
|
88
|
+
"mongodb": "^7.5.0",
|
|
83
89
|
"mongodb-memory-server": "^11.2.0",
|
|
84
90
|
"prettier": "^3.2.5",
|
|
85
91
|
"tsx": "^4.19.4",
|
|
@@ -93,6 +99,14 @@
|
|
|
93
99
|
"optionalDependencies": {
|
|
94
100
|
"better-sqlite3": "^13.0.2"
|
|
95
101
|
},
|
|
102
|
+
"peerDependencies": {
|
|
103
|
+
"mongodb": ">=6"
|
|
104
|
+
},
|
|
105
|
+
"peerDependenciesMeta": {
|
|
106
|
+
"mongodb": {
|
|
107
|
+
"optional": true
|
|
108
|
+
}
|
|
109
|
+
},
|
|
96
110
|
"files": [
|
|
97
111
|
"dist/**/*",
|
|
98
112
|
"README.md"
|