tersejson 0.2.1 → 0.3.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.
@@ -0,0 +1,107 @@
1
+ import { C as CompressOptions } from './types-BTonKlz8.mjs';
2
+
3
+ /**
4
+ * TerseJSON MongoDB Integration
5
+ *
6
+ * Zero-config integration with MongoDB native driver.
7
+ * Call terseMongo() once at startup and all queries automatically
8
+ * return memory-efficient Proxy-wrapped results.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { terseMongo } from 'tersejson/mongodb';
13
+ * import { MongoClient } from 'mongodb';
14
+ *
15
+ * terseMongo(); // Patch once at startup
16
+ *
17
+ * const client = new MongoClient(uri);
18
+ * const users = await client.db('mydb').collection('users').find().toArray();
19
+ * // users is automatically Proxy-wrapped - 70% less memory
20
+ * ```
21
+ *
22
+ * @packageDocumentation
23
+ */
24
+
25
+ /**
26
+ * Options for terseMongo initialization
27
+ */
28
+ interface TerseMongoOptions extends Partial<CompressOptions> {
29
+ /**
30
+ * Enable/disable compression (default: true)
31
+ */
32
+ enabled?: boolean;
33
+ /**
34
+ * Minimum array length to compress (default: 1)
35
+ * Single documents are always wrapped for consistency
36
+ */
37
+ minArrayLength?: number;
38
+ /**
39
+ * Skip compression for single document queries like findOne (default: false)
40
+ * Set to true if you don't want overhead on single doc fetches
41
+ */
42
+ skipSingleDocs?: boolean;
43
+ }
44
+ /**
45
+ * Initialize TerseJSON integration with MongoDB native driver.
46
+ *
47
+ * Call this once at application startup, before any MongoDB queries.
48
+ * All subsequent queries will automatically return Proxy-wrapped results.
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * import { terseMongo } from 'tersejson/mongodb';
53
+ *
54
+ * // Basic usage
55
+ * await terseMongo();
56
+ *
57
+ * // With options
58
+ * await terseMongo({
59
+ * minKeyLength: 4, // Only compress keys with 4+ characters
60
+ * minArrayLength: 5, // Only compress arrays with 5+ items
61
+ * skipSingleDocs: true, // Don't wrap findOne results
62
+ * });
63
+ * ```
64
+ *
65
+ * @param options - Configuration options
66
+ */
67
+ declare function terseMongo(options?: TerseMongoOptions): Promise<void>;
68
+ /**
69
+ * Synchronous version of terseMongo for CommonJS compatibility.
70
+ *
71
+ * Note: This requires mongodb to already be loaded in the module cache.
72
+ * For best results, use the async terseMongo() instead.
73
+ *
74
+ * @param options - Configuration options
75
+ */
76
+ declare function terseMongoSync(options?: TerseMongoOptions): void;
77
+ /**
78
+ * Remove TerseJSON patches from MongoDB driver.
79
+ *
80
+ * Useful for testing or when you need to temporarily disable compression.
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * import { terseMongo, unterse } from 'tersejson/mongodb';
85
+ *
86
+ * await terseMongo();
87
+ * // ... queries are Proxy-wrapped
88
+ *
89
+ * await unterse();
90
+ * // ... queries return normal documents
91
+ * ```
92
+ */
93
+ declare function unterse(): Promise<void>;
94
+ /**
95
+ * Check if TerseJSON MongoDB patching is active
96
+ */
97
+ declare function isTerseMongoActive(): boolean;
98
+ /**
99
+ * Get current TerseJSON MongoDB options
100
+ */
101
+ declare function getTerseMongoOptions(): TerseMongoOptions;
102
+ /**
103
+ * Update TerseJSON MongoDB options without re-patching
104
+ */
105
+ declare function setTerseMongoOptions(options: Partial<TerseMongoOptions>): void;
106
+
107
+ export { type TerseMongoOptions, getTerseMongoOptions, isTerseMongoActive, setTerseMongoOptions, terseMongo, terseMongoSync, unterse };
@@ -0,0 +1,107 @@
1
+ import { C as CompressOptions } from './types-BTonKlz8.js';
2
+
3
+ /**
4
+ * TerseJSON MongoDB Integration
5
+ *
6
+ * Zero-config integration with MongoDB native driver.
7
+ * Call terseMongo() once at startup and all queries automatically
8
+ * return memory-efficient Proxy-wrapped results.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { terseMongo } from 'tersejson/mongodb';
13
+ * import { MongoClient } from 'mongodb';
14
+ *
15
+ * terseMongo(); // Patch once at startup
16
+ *
17
+ * const client = new MongoClient(uri);
18
+ * const users = await client.db('mydb').collection('users').find().toArray();
19
+ * // users is automatically Proxy-wrapped - 70% less memory
20
+ * ```
21
+ *
22
+ * @packageDocumentation
23
+ */
24
+
25
+ /**
26
+ * Options for terseMongo initialization
27
+ */
28
+ interface TerseMongoOptions extends Partial<CompressOptions> {
29
+ /**
30
+ * Enable/disable compression (default: true)
31
+ */
32
+ enabled?: boolean;
33
+ /**
34
+ * Minimum array length to compress (default: 1)
35
+ * Single documents are always wrapped for consistency
36
+ */
37
+ minArrayLength?: number;
38
+ /**
39
+ * Skip compression for single document queries like findOne (default: false)
40
+ * Set to true if you don't want overhead on single doc fetches
41
+ */
42
+ skipSingleDocs?: boolean;
43
+ }
44
+ /**
45
+ * Initialize TerseJSON integration with MongoDB native driver.
46
+ *
47
+ * Call this once at application startup, before any MongoDB queries.
48
+ * All subsequent queries will automatically return Proxy-wrapped results.
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * import { terseMongo } from 'tersejson/mongodb';
53
+ *
54
+ * // Basic usage
55
+ * await terseMongo();
56
+ *
57
+ * // With options
58
+ * await terseMongo({
59
+ * minKeyLength: 4, // Only compress keys with 4+ characters
60
+ * minArrayLength: 5, // Only compress arrays with 5+ items
61
+ * skipSingleDocs: true, // Don't wrap findOne results
62
+ * });
63
+ * ```
64
+ *
65
+ * @param options - Configuration options
66
+ */
67
+ declare function terseMongo(options?: TerseMongoOptions): Promise<void>;
68
+ /**
69
+ * Synchronous version of terseMongo for CommonJS compatibility.
70
+ *
71
+ * Note: This requires mongodb to already be loaded in the module cache.
72
+ * For best results, use the async terseMongo() instead.
73
+ *
74
+ * @param options - Configuration options
75
+ */
76
+ declare function terseMongoSync(options?: TerseMongoOptions): void;
77
+ /**
78
+ * Remove TerseJSON patches from MongoDB driver.
79
+ *
80
+ * Useful for testing or when you need to temporarily disable compression.
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * import { terseMongo, unterse } from 'tersejson/mongodb';
85
+ *
86
+ * await terseMongo();
87
+ * // ... queries are Proxy-wrapped
88
+ *
89
+ * await unterse();
90
+ * // ... queries return normal documents
91
+ * ```
92
+ */
93
+ declare function unterse(): Promise<void>;
94
+ /**
95
+ * Check if TerseJSON MongoDB patching is active
96
+ */
97
+ declare function isTerseMongoActive(): boolean;
98
+ /**
99
+ * Get current TerseJSON MongoDB options
100
+ */
101
+ declare function getTerseMongoOptions(): TerseMongoOptions;
102
+ /**
103
+ * Update TerseJSON MongoDB options without re-patching
104
+ */
105
+ declare function setTerseMongoOptions(options: Partial<TerseMongoOptions>): void;
106
+
107
+ export { type TerseMongoOptions, getTerseMongoOptions, isTerseMongoActive, setTerseMongoOptions, terseMongo, terseMongoSync, unterse };
@@ -0,0 +1,472 @@
1
+ 'use strict';
2
+
3
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
4
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
5
+ }) : x)(function(x) {
6
+ if (typeof require !== "undefined") return require.apply(this, arguments);
7
+ throw Error('Dynamic require of "' + x + '" is not supported');
8
+ });
9
+
10
+ // src/core.ts
11
+ function alphaGenerator(index) {
12
+ let key = "";
13
+ let remaining = index;
14
+ do {
15
+ key = String.fromCharCode(97 + remaining % 26) + key;
16
+ remaining = Math.floor(remaining / 26) - 1;
17
+ } while (remaining >= 0);
18
+ return key;
19
+ }
20
+ function numericGenerator(index) {
21
+ return String(index);
22
+ }
23
+ function alphanumericGenerator(index) {
24
+ const letterIndex = Math.floor(index / 9);
25
+ const numIndex = index % 9 + 1;
26
+ return alphaGenerator(letterIndex) + numIndex;
27
+ }
28
+ function shortGenerator(index) {
29
+ if (index === 0) return "_";
30
+ return alphaGenerator(index - 1);
31
+ }
32
+ function prefixedGenerator(prefix, style = "numeric") {
33
+ return (index) => {
34
+ if (style === "alpha") {
35
+ return prefix + alphaGenerator(index);
36
+ }
37
+ return prefix + index;
38
+ };
39
+ }
40
+ function createKeyGenerator(pattern) {
41
+ if (typeof pattern === "function") {
42
+ return { generator: pattern, name: "custom" };
43
+ }
44
+ if (typeof pattern === "string") {
45
+ switch (pattern) {
46
+ case "alpha":
47
+ return { generator: alphaGenerator, name: "alpha" };
48
+ case "numeric":
49
+ return { generator: numericGenerator, name: "numeric" };
50
+ case "alphanumeric":
51
+ return { generator: alphanumericGenerator, name: "alphanumeric" };
52
+ case "short":
53
+ return { generator: shortGenerator, name: "short" };
54
+ case "prefixed":
55
+ return { generator: prefixedGenerator("k"), name: "prefixed:k" };
56
+ default:
57
+ return { generator: alphaGenerator, name: "alpha" };
58
+ }
59
+ }
60
+ if (typeof pattern === "object" && "prefix" in pattern) {
61
+ return {
62
+ generator: prefixedGenerator(pattern.prefix, pattern.style || "numeric"),
63
+ name: `prefixed:${pattern.prefix}`
64
+ };
65
+ }
66
+ return { generator: alphaGenerator, name: "alpha" };
67
+ }
68
+ function resolveNestedDepth(handling, maxDepth) {
69
+ if (handling === void 0 || handling === "deep") {
70
+ return maxDepth;
71
+ }
72
+ if (handling === "shallow") {
73
+ return 1;
74
+ }
75
+ if (handling === "arrays") {
76
+ return maxDepth;
77
+ }
78
+ if (typeof handling === "number") {
79
+ return handling;
80
+ }
81
+ return maxDepth;
82
+ }
83
+ function collectKeys(data, options, currentDepth = 0) {
84
+ const keys = /* @__PURE__ */ new Set();
85
+ const { minKeyLength, maxDepth, nestedHandling, excludeKeys, includeKeys } = options;
86
+ if (currentDepth >= maxDepth) return keys;
87
+ const keyCounts = /* @__PURE__ */ new Map();
88
+ for (const item of data) {
89
+ if (typeof item !== "object" || item === null) continue;
90
+ for (const key of Object.keys(item)) {
91
+ if (excludeKeys?.includes(key)) continue;
92
+ const shouldInclude = includeKeys?.includes(key) || key.length >= minKeyLength;
93
+ if (shouldInclude) {
94
+ keys.add(key);
95
+ keyCounts.set(key, (keyCounts.get(key) || 0) + 1);
96
+ }
97
+ const value = item[key];
98
+ if (nestedHandling === "shallow") {
99
+ continue;
100
+ }
101
+ if (Array.isArray(value) && value.length > 0 && isCompressibleArray(value)) {
102
+ const nestedKeys = collectKeys(
103
+ value,
104
+ options,
105
+ currentDepth + 1
106
+ );
107
+ nestedKeys.forEach((k) => keys.add(k));
108
+ } else if (nestedHandling !== "arrays" && typeof value === "object" && value !== null && !Array.isArray(value)) {
109
+ const nestedKeys = collectKeys(
110
+ [value],
111
+ options,
112
+ currentDepth + 1
113
+ );
114
+ nestedKeys.forEach((k) => keys.add(k));
115
+ }
116
+ }
117
+ }
118
+ if (options.homogeneousOnly && data.length > 0) {
119
+ for (const [key, count] of keyCounts) {
120
+ if (count < data.length) {
121
+ keys.delete(key);
122
+ }
123
+ }
124
+ }
125
+ return keys;
126
+ }
127
+ function isCompressibleArray(data) {
128
+ if (!Array.isArray(data) || data.length === 0) return false;
129
+ return data.every(
130
+ (item) => typeof item === "object" && item !== null && !Array.isArray(item)
131
+ );
132
+ }
133
+ function compressObject(obj, keyToShort, maxDepth, currentDepth = 0) {
134
+ if (currentDepth >= maxDepth) return obj;
135
+ const compressed = {};
136
+ for (const [key, value] of Object.entries(obj)) {
137
+ const shortKey = keyToShort.get(key) ?? key;
138
+ if (Array.isArray(value) && isCompressibleArray(value)) {
139
+ compressed[shortKey] = value.map(
140
+ (item) => compressObject(
141
+ item,
142
+ keyToShort,
143
+ maxDepth,
144
+ currentDepth + 1
145
+ )
146
+ );
147
+ } else if (typeof value === "object" && value !== null && !Array.isArray(value)) {
148
+ compressed[shortKey] = compressObject(
149
+ value,
150
+ keyToShort,
151
+ maxDepth,
152
+ currentDepth + 1
153
+ );
154
+ } else {
155
+ compressed[shortKey] = value;
156
+ }
157
+ }
158
+ return compressed;
159
+ }
160
+ function compress(data, options = {}) {
161
+ const {
162
+ minKeyLength = 3,
163
+ maxDepth = 10,
164
+ keyPattern = "alpha",
165
+ nestedHandling = "deep",
166
+ homogeneousOnly = false,
167
+ excludeKeys,
168
+ includeKeys
169
+ } = options;
170
+ const { generator, name: patternName } = createKeyGenerator(keyPattern);
171
+ const effectiveDepth = resolveNestedDepth(nestedHandling, maxDepth);
172
+ const allKeys = collectKeys(data, {
173
+ minKeyLength,
174
+ maxDepth: effectiveDepth,
175
+ nestedHandling,
176
+ excludeKeys,
177
+ includeKeys,
178
+ homogeneousOnly
179
+ });
180
+ const sortedKeys = Array.from(allKeys).sort();
181
+ const keyToShort = /* @__PURE__ */ new Map();
182
+ const keyMap = {};
183
+ sortedKeys.forEach((key, index) => {
184
+ const shortKey = generator(index);
185
+ if (shortKey.length < key.length) {
186
+ keyToShort.set(key, shortKey);
187
+ keyMap[shortKey] = key;
188
+ }
189
+ });
190
+ const compressed = data.map(
191
+ (item) => compressObject(item, keyToShort, effectiveDepth)
192
+ );
193
+ return {
194
+ __terse__: true,
195
+ v: 1,
196
+ k: keyMap,
197
+ d: compressed,
198
+ p: patternName
199
+ };
200
+ }
201
+ function createTerseProxy(compressed, keyMap) {
202
+ const originalToShort = new Map(
203
+ Object.entries(keyMap).map(([short, original]) => [original, short])
204
+ );
205
+ const handler = {
206
+ get(target, prop) {
207
+ if (typeof prop === "symbol") {
208
+ return Reflect.get(target, prop);
209
+ }
210
+ const shortKey = originalToShort.get(prop);
211
+ const actualKey = shortKey ?? prop;
212
+ const value = target[actualKey];
213
+ if (Array.isArray(value)) {
214
+ return value.map((item) => {
215
+ if (typeof item === "object" && item !== null && !Array.isArray(item)) {
216
+ return createTerseProxy(item, keyMap);
217
+ }
218
+ return item;
219
+ });
220
+ }
221
+ if (typeof value === "object" && value !== null) {
222
+ return createTerseProxy(value, keyMap);
223
+ }
224
+ return value;
225
+ },
226
+ has(target, prop) {
227
+ if (typeof prop === "symbol") {
228
+ return Reflect.has(target, prop);
229
+ }
230
+ const shortKey = originalToShort.get(prop);
231
+ return (shortKey ?? prop) in target;
232
+ },
233
+ ownKeys(target) {
234
+ return Object.keys(target).map((shortKey) => keyMap[shortKey] ?? shortKey);
235
+ },
236
+ getOwnPropertyDescriptor(target, prop) {
237
+ if (typeof prop === "symbol") {
238
+ return Reflect.getOwnPropertyDescriptor(target, prop);
239
+ }
240
+ const shortKey = originalToShort.get(prop);
241
+ const actualKey = shortKey ?? prop;
242
+ const descriptor = Object.getOwnPropertyDescriptor(target, actualKey);
243
+ if (descriptor) {
244
+ return { ...descriptor, enumerable: true, configurable: true };
245
+ }
246
+ return void 0;
247
+ }
248
+ };
249
+ return new Proxy(compressed, handler);
250
+ }
251
+ function wrapWithProxy(payload) {
252
+ if (Array.isArray(payload.d)) {
253
+ return payload.d.map((item) => {
254
+ if (typeof item === "object" && item !== null && !Array.isArray(item)) {
255
+ return createTerseProxy(item, payload.k);
256
+ }
257
+ return item;
258
+ });
259
+ }
260
+ if (typeof payload.d === "object" && payload.d !== null) {
261
+ return createTerseProxy(payload.d, payload.k);
262
+ }
263
+ return payload.d;
264
+ }
265
+
266
+ // src/mongodb.ts
267
+ var isPatched = false;
268
+ var globalOptions = {};
269
+ var originalMethods = {};
270
+ function wrapResults(results) {
271
+ if (globalOptions.enabled === false) {
272
+ return results;
273
+ }
274
+ if (results.length < (globalOptions.minArrayLength ?? 1)) {
275
+ return results;
276
+ }
277
+ if (!isCompressibleArray(results)) {
278
+ return results;
279
+ }
280
+ const payload = compress(results, globalOptions);
281
+ return wrapWithProxy(payload);
282
+ }
283
+ function wrapSingleDoc(doc) {
284
+ if (globalOptions.enabled === false || globalOptions.skipSingleDocs) {
285
+ return doc;
286
+ }
287
+ if (doc === null || doc === void 0) {
288
+ return doc;
289
+ }
290
+ if (typeof doc !== "object") {
291
+ return doc;
292
+ }
293
+ const payload = compress([doc], globalOptions);
294
+ const wrapped = wrapWithProxy(payload);
295
+ return wrapped[0];
296
+ }
297
+ async function patchMongoDB() {
298
+ let mongodb;
299
+ try {
300
+ mongodb = await import('mongodb');
301
+ } catch {
302
+ throw new Error(
303
+ "terseMongo requires mongodb to be installed. Run: npm install mongodb"
304
+ );
305
+ }
306
+ const { FindCursor, AggregationCursor, Collection } = mongodb;
307
+ if (FindCursor?.prototype) {
308
+ originalMethods.findCursorToArray = FindCursor.prototype.toArray;
309
+ FindCursor.prototype.toArray = async function() {
310
+ const results = await originalMethods.findCursorToArray.call(this);
311
+ return wrapResults(results);
312
+ };
313
+ originalMethods.findCursorNext = FindCursor.prototype.next;
314
+ FindCursor.prototype.next = async function() {
315
+ const doc = await originalMethods.findCursorNext.call(this);
316
+ return doc ? wrapSingleDoc(doc) : null;
317
+ };
318
+ originalMethods.findCursorIterator = FindCursor.prototype[Symbol.asyncIterator];
319
+ FindCursor.prototype[Symbol.asyncIterator] = async function* () {
320
+ const iterator = originalMethods.findCursorIterator.call(this);
321
+ for await (const doc of iterator) {
322
+ yield wrapSingleDoc(doc);
323
+ }
324
+ };
325
+ }
326
+ if (AggregationCursor?.prototype) {
327
+ originalMethods.aggregationCursorToArray = AggregationCursor.prototype.toArray;
328
+ AggregationCursor.prototype.toArray = async function() {
329
+ const results = await originalMethods.aggregationCursorToArray.call(this);
330
+ return wrapResults(results);
331
+ };
332
+ originalMethods.aggregationCursorNext = AggregationCursor.prototype.next;
333
+ AggregationCursor.prototype.next = async function() {
334
+ const doc = await originalMethods.aggregationCursorNext.call(this);
335
+ return doc ? wrapSingleDoc(doc) : null;
336
+ };
337
+ originalMethods.aggregationCursorIterator = AggregationCursor.prototype[Symbol.asyncIterator];
338
+ AggregationCursor.prototype[Symbol.asyncIterator] = async function* () {
339
+ const iterator = originalMethods.aggregationCursorIterator.call(this);
340
+ for await (const doc of iterator) {
341
+ yield wrapSingleDoc(doc);
342
+ }
343
+ };
344
+ }
345
+ if (Collection?.prototype) {
346
+ originalMethods.collectionFindOne = Collection.prototype.findOne;
347
+ Collection.prototype.findOne = async function(...args) {
348
+ const doc = await originalMethods.collectionFindOne.apply(this, args);
349
+ return doc ? wrapSingleDoc(doc) : null;
350
+ };
351
+ }
352
+ }
353
+ async function unpatchMongoDB() {
354
+ let mongodb;
355
+ try {
356
+ mongodb = await import('mongodb');
357
+ } catch {
358
+ return;
359
+ }
360
+ const { FindCursor, AggregationCursor, Collection } = mongodb;
361
+ if (FindCursor?.prototype && originalMethods.findCursorToArray) {
362
+ FindCursor.prototype.toArray = originalMethods.findCursorToArray;
363
+ FindCursor.prototype.next = originalMethods.findCursorNext;
364
+ FindCursor.prototype[Symbol.asyncIterator] = originalMethods.findCursorIterator;
365
+ }
366
+ if (AggregationCursor?.prototype && originalMethods.aggregationCursorToArray) {
367
+ AggregationCursor.prototype.toArray = originalMethods.aggregationCursorToArray;
368
+ AggregationCursor.prototype.next = originalMethods.aggregationCursorNext;
369
+ AggregationCursor.prototype[Symbol.asyncIterator] = originalMethods.aggregationCursorIterator;
370
+ }
371
+ if (Collection?.prototype && originalMethods.collectionFindOne) {
372
+ Collection.prototype.findOne = originalMethods.collectionFindOne;
373
+ }
374
+ }
375
+ async function terseMongo(options = {}) {
376
+ if (isPatched) {
377
+ globalOptions = { minArrayLength: 1, ...options };
378
+ return;
379
+ }
380
+ globalOptions = { minArrayLength: 1, ...options };
381
+ await patchMongoDB();
382
+ isPatched = true;
383
+ }
384
+ function terseMongoSync(options = {}) {
385
+ if (isPatched) {
386
+ globalOptions = { minArrayLength: 1, ...options };
387
+ return;
388
+ }
389
+ globalOptions = { minArrayLength: 1, ...options };
390
+ let mongodb;
391
+ try {
392
+ mongodb = __require("mongodb");
393
+ } catch {
394
+ throw new Error(
395
+ "terseMongo requires mongodb to be installed. Run: npm install mongodb"
396
+ );
397
+ }
398
+ const { FindCursor, AggregationCursor, Collection } = mongodb;
399
+ if (FindCursor?.prototype) {
400
+ originalMethods.findCursorToArray = FindCursor.prototype.toArray;
401
+ FindCursor.prototype.toArray = async function() {
402
+ const results = await originalMethods.findCursorToArray.call(this);
403
+ return wrapResults(results);
404
+ };
405
+ originalMethods.findCursorNext = FindCursor.prototype.next;
406
+ FindCursor.prototype.next = async function() {
407
+ const doc = await originalMethods.findCursorNext.call(this);
408
+ return doc ? wrapSingleDoc(doc) : null;
409
+ };
410
+ originalMethods.findCursorIterator = FindCursor.prototype[Symbol.asyncIterator];
411
+ FindCursor.prototype[Symbol.asyncIterator] = async function* () {
412
+ const iterator = originalMethods.findCursorIterator.call(this);
413
+ for await (const doc of iterator) {
414
+ yield wrapSingleDoc(doc);
415
+ }
416
+ };
417
+ }
418
+ if (AggregationCursor?.prototype) {
419
+ originalMethods.aggregationCursorToArray = AggregationCursor.prototype.toArray;
420
+ AggregationCursor.prototype.toArray = async function() {
421
+ const results = await originalMethods.aggregationCursorToArray.call(this);
422
+ return wrapResults(results);
423
+ };
424
+ originalMethods.aggregationCursorNext = AggregationCursor.prototype.next;
425
+ AggregationCursor.prototype.next = async function() {
426
+ const doc = await originalMethods.aggregationCursorNext.call(this);
427
+ return doc ? wrapSingleDoc(doc) : null;
428
+ };
429
+ originalMethods.aggregationCursorIterator = AggregationCursor.prototype[Symbol.asyncIterator];
430
+ AggregationCursor.prototype[Symbol.asyncIterator] = async function* () {
431
+ const iterator = originalMethods.aggregationCursorIterator.call(this);
432
+ for await (const doc of iterator) {
433
+ yield wrapSingleDoc(doc);
434
+ }
435
+ };
436
+ }
437
+ if (Collection?.prototype) {
438
+ originalMethods.collectionFindOne = Collection.prototype.findOne;
439
+ Collection.prototype.findOne = async function(...args) {
440
+ const doc = await originalMethods.collectionFindOne.apply(this, args);
441
+ return doc ? wrapSingleDoc(doc) : null;
442
+ };
443
+ }
444
+ isPatched = true;
445
+ }
446
+ async function unterse() {
447
+ if (!isPatched) return;
448
+ await unpatchMongoDB();
449
+ Object.keys(originalMethods).forEach((key) => {
450
+ delete originalMethods[key];
451
+ });
452
+ isPatched = false;
453
+ globalOptions = {};
454
+ }
455
+ function isTerseMongoActive() {
456
+ return isPatched;
457
+ }
458
+ function getTerseMongoOptions() {
459
+ return { ...globalOptions };
460
+ }
461
+ function setTerseMongoOptions(options) {
462
+ globalOptions = { ...globalOptions, ...options };
463
+ }
464
+
465
+ exports.getTerseMongoOptions = getTerseMongoOptions;
466
+ exports.isTerseMongoActive = isTerseMongoActive;
467
+ exports.setTerseMongoOptions = setTerseMongoOptions;
468
+ exports.terseMongo = terseMongo;
469
+ exports.terseMongoSync = terseMongoSync;
470
+ exports.unterse = unterse;
471
+ //# sourceMappingURL=mongodb.js.map
472
+ //# sourceMappingURL=mongodb.js.map