@ahrowe/mongo 0.1.2 → 0.2.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/CHANGELOG.md +19 -0
- package/README.md +50 -20
- package/dist/db.d.ts +31 -13
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +177 -156
- package/dist/db.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/outboxRelay.d.ts +34 -5
- package/dist/outboxRelay.d.ts.map +1 -1
- package/dist/outboxRelay.js +75 -52
- package/dist/outboxRelay.js.map +1 -1
- package/dist/types/outbox.d.ts +14 -2
- package/dist/types/outbox.d.ts.map +1 -1
- package/dist/types/outbox.js +4 -1
- package/dist/types/outbox.js.map +1 -1
- package/docs/CLAUDE.md +116 -86
- package/package.json +5 -2
- package/dist/batchify.d.ts +0 -36
- package/dist/batchify.d.ts.map +0 -1
- package/dist/batchify.js +0 -57
- package/dist/batchify.js.map +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# @ahrowe/mongo
|
|
2
|
+
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 53e6119: `bulkWrite` throws on a service that emits outbox events (the default), whose listeners would miss its writes; use the write methods, or a service with `emitOutboxEvents: false`
|
|
8
|
+
- 53e6119: `keepFailedMs` defaults to 90 days instead of forever; pass `Infinity` to keep dead-lettered rows
|
|
9
|
+
- 53e6119: On a service with `emitOutboxEvents: false` and a validator, `updateMany` validates every updated document instead of one, so it can now fail on documents that were invalid before
|
|
10
|
+
- 53e6119: `.on(...)` and `.onPropertiesUpdated(...)` return a function that removes the listener instead of an `EventEmitter`, and `.on` only takes `'created' | 'updated' | 'removed'`
|
|
11
|
+
- 53e6119: `OutboxStatus.Processing` and `OutboxRow.leasedUntil` are gone: a claimed row stays `pending`, with `leasedBy` set and `nextAttemptAt` at the end of its lease; run the one-time database commands under "Upgrading from 0.1" in docs/CLAUDE.md once no 0.1 relay runs any more
|
|
12
|
+
- 53e6119: `upsertOne`, `updateOne`, `removeOne` and `removeMany` throw on `projection` and `includeResultMetadata`, since writes validate and record the full document; read the fields you need with `find`/`findOne` afterwards
|
|
13
|
+
- 53e6119: `getServiceBus` and `service.eventBus` are gone: register listeners with `.on(...)`, and deliver events that reach a process another way with the new `dispatchEvent(collectionName, event)`
|
|
14
|
+
- 53e6119: New `toOutboxDoc` service option decides what outbox rows hold of a document, e.g. to keep a secret out of what listeners store; `ServiceOptions` and `OutboxEvent` are exported
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- 53e6119: `updateMany`/`removeMany` on a service with outbox events work through 500 documents per round trip instead of one at a time, still in one transaction
|
|
19
|
+
- 53e6119: The relay dead-letters a row whose lease ran out on every attempt (a listener that crashes the process or outlasts `leaseMs`) instead of claiming it again forever
|
package/README.md
CHANGED
|
@@ -26,15 +26,15 @@ await users.updateOne({ _id: user._id }, { $set: { email: 'c@d.com' } });
|
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
Call `createService` once per collection and reuse that instance everywhere.
|
|
29
|
-
Calling it again for the same collection name is supported (it
|
|
30
|
-
first call's
|
|
29
|
+
Calling it again for the same collection name is supported (it shares the
|
|
30
|
+
first call's listeners and logs a warning, so listeners on either instance
|
|
31
31
|
still fire) but other per-instance options are **not** shared: a mismatched
|
|
32
32
|
`emitOutboxEvents` means writes through one instance never fire events at all
|
|
33
33
|
(not a bus issue — no outbox row is written), a mismatched `validate` means
|
|
34
34
|
the two instances enforce different schemas on the same collection, and a
|
|
35
35
|
mismatched `addCreatedOnField`/`addUpdatedOnField` means only some documents
|
|
36
|
-
get timestamped
|
|
37
|
-
|
|
36
|
+
get timestamped, and a mismatched `toOutboxDoc` means a field one instance keeps
|
|
37
|
+
out of the outbox reaches listeners through the other. Prefer sharing one instance unless one
|
|
38
38
|
of these divergences is what you actually want (e.g. a backfill instance with
|
|
39
39
|
`emitOutboxEvents: false`).
|
|
40
40
|
|
|
@@ -83,11 +83,11 @@ across multiple pods racing the same row (claims are leased atomically).
|
|
|
83
83
|
`updateOne`/`updateMany` only enqueue `'updated'` for documents that actually
|
|
84
84
|
changed.
|
|
85
85
|
|
|
86
|
-
`updateMany`/`removeMany`
|
|
87
|
-
one
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
86
|
+
`updateMany`/`removeMany` work through the matched documents in chunks of 500,
|
|
87
|
+
all inside one transaction: a failure in any chunk rolls back every chunk. Each
|
|
88
|
+
outbox row's `{ prevDoc, doc }` pair is exact, because nothing else can change a
|
|
89
|
+
document between the transaction reading it and writing it. Run the relay to
|
|
90
|
+
drain the outbox:
|
|
91
91
|
|
|
92
92
|
```ts
|
|
93
93
|
import { startOutboxRelay } from '@ahrowe/mongo';
|
|
@@ -96,7 +96,11 @@ const relay = startOutboxRelay({ instanceId: process.env.HOSTNAME ?? 'local' });
|
|
|
96
96
|
// relay.stop() on shutdown
|
|
97
97
|
```
|
|
98
98
|
|
|
99
|
-
|
|
99
|
+
Processed rows are kept for 7 days (`keepDoneMs`), dead-lettered rows for 90
|
|
100
|
+
days (`keepFailedMs`), then removed by a TTL index. Both are relay options, and
|
|
101
|
+
`Infinity` keeps rows forever. A row no relay processes stays until one does.
|
|
102
|
+
|
|
103
|
+
`updateMany`/`removeMany` have **no size cap by default**, but a single
|
|
100
104
|
transaction processing a very large matched set risks hitting MongoDB's
|
|
101
105
|
transaction lifetime limit. Pass `{ maxBatchSize }` (per-call, or as a
|
|
102
106
|
`createService` option for a service-wide default) to enforce one and fail fast
|
|
@@ -106,8 +110,28 @@ instead:
|
|
|
106
110
|
await users.updateMany({}, { $set: { plan: 'pro' } }, { maxBatchSize: 500 });
|
|
107
111
|
```
|
|
108
112
|
|
|
109
|
-
Past that limit it throws
|
|
110
|
-
transaction
|
|
113
|
+
Past that limit it throws before writing anything; it never processes a partial
|
|
114
|
+
batch. For more than fits one transaction, split the work into several calls,
|
|
115
|
+
each committing on its own. For a rerunnable migration, select by a condition the
|
|
116
|
+
update itself clears:
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
for (;;) {
|
|
120
|
+
const batch = await beans.find({ roastLevel: { $exists: false } }, { projection: { _id: 1 }, limit: 1000 });
|
|
121
|
+
if (!batch.length) break;
|
|
122
|
+
await beans.updateMany({ _id: { $in: batch.map((b) => b._id) } }, { $set: { roastLevel: 'medium' } });
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Rows reach every listener, and whatever those store. Decide what they hold of a
|
|
127
|
+
document with `toOutboxDoc`, e.g. to keep a secret out:
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
const hooks = createService<Hook>('webhooks', null, { toOutboxDoc: ({ secret, ...hook }) => hook });
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
`bulkWrite` has no transaction, validation or events, so it refuses a service
|
|
134
|
+
that emits outbox events.
|
|
111
135
|
|
|
112
136
|
Pass `{ meta: {...} }` on a call to thread arbitrary data through to listeners,
|
|
113
137
|
so a specific handler can decide to skip its own side effect without anyone else
|
|
@@ -150,8 +174,9 @@ await session.withTransaction(async () => {
|
|
|
150
174
|
});
|
|
151
175
|
```
|
|
152
176
|
|
|
153
|
-
|
|
154
|
-
|
|
177
|
+
Write methods run in a transaction: the passed `session`'s if it has one active,
|
|
178
|
+
otherwise their own. Exceptions: `bulkWrite`, and `removeOne`/`removeMany` on a
|
|
179
|
+
service with `emitOutboxEvents: false`.
|
|
155
180
|
|
|
156
181
|
### Connection health
|
|
157
182
|
|
|
@@ -183,15 +208,20 @@ first so it releases any leases it's holding.
|
|
|
183
208
|
## API
|
|
184
209
|
|
|
185
210
|
- `connect(connectionString, databaseName?) → { createService, on }`
|
|
186
|
-
- `createService<T>(collectionName, validate?, { addCreatedOnField?, addUpdatedOnField?, maxLimit?, maxBatchSize?, emitOutboxEvents? }) → DbService<T>`
|
|
211
|
+
- `createService<T>(collectionName, validate?, { addCreatedOnField?, addUpdatedOnField?, maxLimit?, maxBatchSize?, emitOutboxEvents?, toOutboxDoc? }) → DbService<T>` (options type: `ServiceOptions<T>`)
|
|
187
212
|
- `withSession(cb)`, `startSession(options?)`, `disconnect()`
|
|
188
213
|
- `setOutboxContextProvider(fn)` — capture request/actor context at write time for outbox rows
|
|
189
|
-
- `startOutboxRelay({ instanceId, pollIntervalMs?, batchSize?, leaseMs?, maxAttempts?, autoStart? }) → { stop, tick, drain }`
|
|
190
|
-
- `
|
|
191
|
-
- `
|
|
214
|
+
- `startOutboxRelay({ instanceId, pollIntervalMs?, batchSize?, leaseMs?, maxAttempts?, backoffMs?, keepDoneMs?, keepFailedMs?, autoStart? }) → { stop, tick, drain }`
|
|
215
|
+
- `dispatchEvent(collectionName, event)`: deliver an event to this process's listeners, when events arrive from somewhere other than the relay (e.g. a broker)
|
|
216
|
+
- `getRegisteredCollections()`, `getOutboxCollection()`: relay/advanced internals
|
|
217
|
+
- `OutboxEvent`, `OutboxOp`, `OutboxStatus`, `OutboxRow`, `OUTBOX_COLLECTION`: event and outbox row shapes, for tooling/inspection
|
|
192
218
|
- `DbService<T>` methods: `find`, `findOne`, `findCursor`, `insert`, `updateOne`,
|
|
193
|
-
`updateMany`, `removeOne`, `removeMany`, `count`, `exists`, `aggregate`, `distinct`,
|
|
194
|
-
`createIndex`, `dropIndex`, `bulkWrite`, `on`, `onPropertiesUpdated`, `
|
|
219
|
+
`upsertOne`, `updateMany`, `removeOne`, `removeMany`, `count`, `exists`, `aggregate`, `distinct`,
|
|
220
|
+
`createIndex`, `dropIndex`, `bulkWrite`, `on`, `onPropertiesUpdated`, `generateId`, `name`
|
|
221
|
+
|
|
222
|
+
What changed in each version is in [CHANGELOG.md](CHANGELOG.md). Upgrading from
|
|
223
|
+
0.1 also takes one-time database commands, in
|
|
224
|
+
[docs/CLAUDE.md](docs/CLAUDE.md#upgrading-from-01).
|
|
195
225
|
|
|
196
226
|
See [docs/CLAUDE.md](docs/CLAUDE.md) for gotchas (upserts are rejected, `findOne`
|
|
197
227
|
strictness, the opt-in `maxLimit`/`maxBatchSize` caps, `bulkWrite` safety gate).
|
package/dist/db.d.ts
CHANGED
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
import { ObjectId, ClientSession, UpdateFilter, FindOptions, Filter, UpdateOptions, FindOneAndUpdateOptions, FindOneAndDeleteOptions, BulkWriteOptions, BulkWriteResult, AggregateOptions, ClientSessionOptions, type Document, type WithId, type InferIdType, type FindCursor, Collection as MongoCollection } from 'mongodb';
|
|
2
2
|
import { EventEmitter } from 'node:events';
|
|
3
|
-
import { type OutboxRow } from './types/outbox.js';
|
|
3
|
+
import { OutboxOp, type OutboxEvent, type OutboxRow } from './types/outbox.js';
|
|
4
4
|
type ContextProvider = () => unknown;
|
|
5
5
|
export declare const setOutboxContextProvider: (fn: ContextProvider) => void;
|
|
6
|
-
|
|
6
|
+
/** Collections with a service in this process. The relay only claims rows for these. */
|
|
7
7
|
export declare const getRegisteredCollections: () => string[];
|
|
8
|
+
/**
|
|
9
|
+
* Delivers one event to every listener registered for its collection and op in this process,
|
|
10
|
+
* waits for all of them, then rejects with the first failure, if any. The relay calls this per
|
|
11
|
+
* outbox row. Call it yourself only when events reach this process another way, e.g. from a broker.
|
|
12
|
+
*/
|
|
13
|
+
export declare const dispatchEvent: (collectionName: string, event: OutboxEvent) => Promise<void>;
|
|
14
|
+
/** Test-only: drops every listener on a collection. Not part of the public barrel. */
|
|
15
|
+
export declare const removeAllListeners: (collectionName: string) => void;
|
|
8
16
|
/** Raw outbox collection — used by the relay to claim/mark rows WITHOUT emitting. */
|
|
9
17
|
export declare const getOutboxCollection: () => MongoCollection<OutboxRow>;
|
|
10
|
-
|
|
18
|
+
/** Write options that would return a partial or wrapped document instead of the full one. */
|
|
19
|
+
type PartialResultOptions = 'projection' | 'includeResultMetadata';
|
|
20
|
+
export interface ServiceOptions<T> {
|
|
11
21
|
addCreatedOnField?: boolean;
|
|
12
22
|
addUpdatedOnField?: boolean;
|
|
13
23
|
/** Ceiling for findCursor's `limit` option. No cap by default. Overridable per-call. */
|
|
@@ -20,6 +30,14 @@ interface ServiceOptions {
|
|
|
20
30
|
* listeners and would only churn the outbox.
|
|
21
31
|
*/
|
|
22
32
|
emitOutboxEvents?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* What this collection's outbox rows hold of a document, `doc` and `prevDoc` alike, e.g.
|
|
35
|
+
* `({ secret, ...hook }) => hook`. Rows are copied to every listener, so a secret in them leaks
|
|
36
|
+
* into whatever those store. An update records a row only if this result changed. Must be pure
|
|
37
|
+
* and must not modify the document it gets. It also gets stored documents that were never
|
|
38
|
+
* validated against `T` (older ones, skipValidation writes), and a throw fails the write.
|
|
39
|
+
*/
|
|
40
|
+
toOutboxDoc?: (doc: T) => object;
|
|
23
41
|
}
|
|
24
42
|
interface FindOptionsWithReadPref extends FindOptions {
|
|
25
43
|
preferReadFromSecondary?: boolean;
|
|
@@ -74,12 +92,12 @@ export interface DbService<T extends WithEntityFields> {
|
|
|
74
92
|
find: (query: Filter<T>, options?: FindOptions) => Promise<WithId<T>[]>;
|
|
75
93
|
findCursor: (query: Filter<T>, options?: FindOptionsWithReadPref) => FindCursor<WithId<T>>;
|
|
76
94
|
findOne: (query: Filter<T>, options?: FindOptions) => Promise<WithId<T>>;
|
|
77
|
-
updateOne: (query: Filter<T>, updateBody: UpdateFilter<T>, options?: Omit<FindOneAndUpdateOptions, 'upsert'> & {
|
|
95
|
+
updateOne: (query: Filter<T>, updateBody: UpdateFilter<T>, options?: Omit<FindOneAndUpdateOptions, 'upsert' | PartialResultOptions> & {
|
|
78
96
|
returnOriginal?: boolean;
|
|
79
97
|
skipValidation?: boolean;
|
|
80
98
|
meta?: Record<string, unknown>;
|
|
81
99
|
}) => Promise<T | null>;
|
|
82
|
-
upsertOne: (query: Filter<T>, updateBody: UpdateFilter<T>, options?: Omit<FindOneAndUpdateOptions, 'upsert' | 'returnDocument'> & {
|
|
100
|
+
upsertOne: (query: Filter<T>, updateBody: UpdateFilter<T>, options?: Omit<FindOneAndUpdateOptions, 'upsert' | 'returnDocument' | PartialResultOptions> & {
|
|
83
101
|
skipValidation?: boolean;
|
|
84
102
|
meta?: Record<string, unknown>;
|
|
85
103
|
}) => Promise<T>;
|
|
@@ -95,7 +113,7 @@ export interface DbService<T extends WithEntityFields> {
|
|
|
95
113
|
upsertedCount: number;
|
|
96
114
|
upsertedId: InferIdType<T> | null;
|
|
97
115
|
}>;
|
|
98
|
-
removeOne: (query: Filter<T>, options?: FindOneAndDeleteOptions & {
|
|
116
|
+
removeOne: (query: Filter<T>, options?: Omit<FindOneAndDeleteOptions, PartialResultOptions> & {
|
|
99
117
|
meta?: Record<string, unknown>;
|
|
100
118
|
}) => Promise<WithId<T> | null>;
|
|
101
119
|
removeMany: (query: Filter<T>, options?: any) => Promise<{
|
|
@@ -127,20 +145,20 @@ export interface DbService<T extends WithEntityFields> {
|
|
|
127
145
|
name: string;
|
|
128
146
|
createIndex: (fields: IndexSpec<T>, options?: any) => Promise<string>;
|
|
129
147
|
dropIndex: (indexName: string, options?: any) => Promise<Document>;
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
148
|
+
/** Registers a listener the relay (or `dispatchEvent`) delivers to. Returns a function that removes it. */
|
|
149
|
+
on: (event: `${OutboxOp}`, callback: (...args: any[]) => unknown) => () => void;
|
|
150
|
+
onPropertiesUpdated: (properties: Array<string | ReadonlyArray<string>>, callback: (...args: any[]) => unknown) => () => void;
|
|
133
151
|
bulkWrite: (operations: any[], options?: BulkWriteOptions & {
|
|
134
152
|
allowBulkwrite?: boolean;
|
|
135
153
|
}) => Promise<BulkWriteResult>;
|
|
136
154
|
}
|
|
137
155
|
declare const createService: <T extends WithEntityFields>(collectionName: string, validate?: ((entity: T) => {
|
|
138
156
|
error?: unknown;
|
|
139
|
-
}) | null, options?: ServiceOptions) => DbService<T>;
|
|
157
|
+
}) | null, options?: ServiceOptions<T>) => DbService<T>;
|
|
140
158
|
declare const connect: (connectionString: string, databaseName?: string) => {
|
|
141
159
|
createService: <T extends WithEntityFields>(collectionName: string, validate?: ((entity: T) => {
|
|
142
160
|
error?: unknown;
|
|
143
|
-
}) | null, options?: ServiceOptions) => DbService<T>;
|
|
161
|
+
}) | null, options?: ServiceOptions<T>) => DbService<T>;
|
|
144
162
|
on: (eventName: string, callback: (...args: any[]) => void) => EventEmitter<[never]>;
|
|
145
163
|
};
|
|
146
164
|
export declare const disconnect: () => Promise<void>;
|
|
@@ -151,12 +169,12 @@ declare const _default: {
|
|
|
151
169
|
connect: (connectionString: string, databaseName?: string) => {
|
|
152
170
|
createService: <T extends WithEntityFields>(collectionName: string, validate?: ((entity: T) => {
|
|
153
171
|
error?: unknown;
|
|
154
|
-
}) | null, options?: ServiceOptions) => DbService<T>;
|
|
172
|
+
}) | null, options?: ServiceOptions<T>) => DbService<T>;
|
|
155
173
|
on: (eventName: string, callback: (...args: any[]) => void) => EventEmitter<[never]>;
|
|
156
174
|
};
|
|
157
175
|
createService: <T extends WithEntityFields>(collectionName: string, validate?: ((entity: T) => {
|
|
158
176
|
error?: unknown;
|
|
159
|
-
}) | null, options?: ServiceOptions) => DbService<T>;
|
|
177
|
+
}) | null, options?: ServiceOptions<T>) => DbService<T>;
|
|
160
178
|
withSession: <R>(callback: (session: ClientSession) => Promise<R>) => Promise<R>;
|
|
161
179
|
startSession: (options?: ClientSessionOptions) => Promise<ClientSession>;
|
|
162
180
|
disconnect: () => Promise<void>;
|
package/dist/db.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,WAAW,EACX,MAAM,EACN,aAAa,EACb,uBAAuB,EACvB,uBAAuB,EAEvB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,KAAK,QAAQ,EACb,KAAK,MAAM,EACX,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,UAAU,IAAI,eAAe,EAC9B,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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"}
|