Skip to content

Commit 981465c

Browse files
feat(NODE-3938): Add support for pre/post images in change streams (#3250)
1 parent 55a2e45 commit 981465c

11 files changed

+1559
-13
lines changed

src/change_stream.ts

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ const CHANGE_STREAM_OPTIONS = [
5050
'resumeAfter',
5151
'startAfter',
5252
'startAtOperationTime',
53-
'fullDocument'
53+
'fullDocument',
54+
'fullDocumentBeforeChange'
5455
] as const;
5556

5657
const CURSOR_OPTIONS = [
@@ -131,11 +132,35 @@ export type ChangeStreamAggregateRawResult<TChange> = {
131132
*/
132133
export interface ChangeStreamOptions extends AggregateOptions {
133134
/**
134-
* Allowed values: 'updateLookup'. When set to 'updateLookup',
135-
* the change stream will include both a delta describing the changes to the document,
136-
* as well as a copy of the entire document that was changed from some time after the change occurred.
135+
* Allowed values: 'updateLookup', 'whenAvailable', 'required'.
136+
*
137+
* When set to 'updateLookup', the change notification for partial updates
138+
* will include both a delta describing the changes to the document as well
139+
* as a copy of the entire document that was changed from some time after
140+
* the change occurred.
141+
*
142+
* When set to 'whenAvailable', configures the change stream to return the
143+
* post-image of the modified document for replace and update change events
144+
* if the post-image for this event is available.
145+
*
146+
* When set to 'required', the same behavior as 'whenAvailable' except that
147+
* an error is raised if the post-image is not available.
137148
*/
138149
fullDocument?: string;
150+
151+
/**
152+
* Allowed values: 'whenAvailable', 'required', 'off'.
153+
*
154+
* The default is to not send a value, which is equivalent to 'off'.
155+
*
156+
* When set to 'whenAvailable', configures the change stream to return the
157+
* pre-image of the modified document for replace, update, and delete change
158+
* events if it is available.
159+
*
160+
* When set to 'required', the same behavior as 'whenAvailable' except that
161+
* an error is raised if the pre-image is not available.
162+
*/
163+
fullDocumentBeforeChange?: string;
139164
/** The maximum amount of time for the server to wait on new documents to satisfy a change stream query. */
140165
maxAwaitTimeMS?: number;
141166
/**
@@ -230,15 +255,23 @@ export interface ChangeStreamUpdateDocument<TSchema extends Document = Document>
230255
operationType: 'update';
231256
/**
232257
* This is only set if `fullDocument` is set to `'updateLookup'`
233-
* The fullDocument document represents the most current majority-committed version of the updated document.
234-
* The fullDocument document may vary from the document at the time of the update operation depending on the
235-
* number of interleaving majority-committed operations that occur between the update operation and the document lookup.
258+
* Contains the point-in-time post-image of the modified document if the
259+
* post-image is available and either 'required' or 'whenAvailable' was
260+
* specified for the 'fullDocument' option when creating the change stream.
236261
*/
237262
fullDocument?: TSchema;
238263
/** Contains a description of updated and removed fields in this operation */
239264
updateDescription: UpdateDescription<TSchema>;
240265
/** Namespace the update event occured on */
241266
ns: ChangeStreamNameSpace;
267+
/**
268+
* Contains the pre-image of the modified or deleted document if the
269+
* pre-image is available for the change event and either 'required' or
270+
* 'whenAvailable' was specified for the 'fullDocumentBeforeChange' option
271+
* when creating the change stream. If 'whenAvailable' was specified but the
272+
* pre-image is unavailable, this will be explicitly set to null.
273+
*/
274+
fullDocumentBeforeChange?: TSchema;
242275
}
243276

244277
/**
@@ -254,6 +287,14 @@ export interface ChangeStreamReplaceDocument<TSchema extends Document = Document
254287
fullDocument: TSchema;
255288
/** Namespace the replace event occured on */
256289
ns: ChangeStreamNameSpace;
290+
/**
291+
* Contains the pre-image of the modified or deleted document if the
292+
* pre-image is available for the change event and either 'required' or
293+
* 'whenAvailable' was specified for the 'fullDocumentBeforeChange' option
294+
* when creating the change stream. If 'whenAvailable' was specified but the
295+
* pre-image is unavailable, this will be explicitly set to null.
296+
*/
297+
fullDocumentBeforeChange?: TSchema;
257298
}
258299

259300
/**
@@ -267,6 +308,14 @@ export interface ChangeStreamDeleteDocument<TSchema extends Document = Document>
267308
operationType: 'delete';
268309
/** Namespace the delete event occured on */
269310
ns: ChangeStreamNameSpace;
311+
/**
312+
* Contains the pre-image of the modified or deleted document if the
313+
* pre-image is available for the change event and either 'required' or
314+
* 'whenAvailable' was specified for the 'fullDocumentBeforeChange' option
315+
* when creating the change stream. If 'whenAvailable' was specified but the
316+
* pre-image is unavailable, this will be explicitly set to null.
317+
*/
318+
fullDocumentBeforeChange?: TSchema;
270319
}
271320

272321
/**

src/operations/create_collection.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ export interface CreateCollectionOptions extends CommandOperationOptions {
9191
expireAfterSeconds?: number;
9292
/** @experimental */
9393
encryptedFields?: Document;
94+
/**
95+
* If set, enables pre-update and post-update document events to be included for any
96+
* change streams that listen on this collection.
97+
*/
98+
changeStreamPreAndPostImages?: { enabled: boolean };
9499
}
95100

96101
/** @internal */

test/integration/collection-management/collection_management.spec.test.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
const { loadSpecTests } = require('../../spec/index');
44
const { runUnifiedSuite } = require('../../tools/unified-spec-runner/runner');
55

6+
// The Node driver does not have a Collection.modifyCollection helper.
7+
const SKIPPED_TESTS = ['modifyCollection to changeStreamPreAndPostImages enabled'];
8+
69
describe('Collection management unified spec tests', function () {
7-
runUnifiedSuite(loadSpecTests('collection-management'));
10+
runUnifiedSuite(loadSpecTests('collection-management'), SKIPPED_TESTS);
811
});

0 commit comments

Comments
 (0)