tersejson 0.3.0 → 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.
- package/README.md +39 -0
- package/dist/mongodb.d.mts +107 -0
- package/dist/mongodb.d.ts +107 -0
- package/dist/mongodb.js +472 -0
- package/dist/mongodb.js.map +1 -0
- package/dist/mongodb.mjs +465 -0
- package/dist/mongodb.mjs.map +1 -0
- package/package.json +15 -2
package/dist/mongodb.mjs
ADDED
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
// src/core.ts
|
|
9
|
+
function alphaGenerator(index) {
|
|
10
|
+
let key = "";
|
|
11
|
+
let remaining = index;
|
|
12
|
+
do {
|
|
13
|
+
key = String.fromCharCode(97 + remaining % 26) + key;
|
|
14
|
+
remaining = Math.floor(remaining / 26) - 1;
|
|
15
|
+
} while (remaining >= 0);
|
|
16
|
+
return key;
|
|
17
|
+
}
|
|
18
|
+
function numericGenerator(index) {
|
|
19
|
+
return String(index);
|
|
20
|
+
}
|
|
21
|
+
function alphanumericGenerator(index) {
|
|
22
|
+
const letterIndex = Math.floor(index / 9);
|
|
23
|
+
const numIndex = index % 9 + 1;
|
|
24
|
+
return alphaGenerator(letterIndex) + numIndex;
|
|
25
|
+
}
|
|
26
|
+
function shortGenerator(index) {
|
|
27
|
+
if (index === 0) return "_";
|
|
28
|
+
return alphaGenerator(index - 1);
|
|
29
|
+
}
|
|
30
|
+
function prefixedGenerator(prefix, style = "numeric") {
|
|
31
|
+
return (index) => {
|
|
32
|
+
if (style === "alpha") {
|
|
33
|
+
return prefix + alphaGenerator(index);
|
|
34
|
+
}
|
|
35
|
+
return prefix + index;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function createKeyGenerator(pattern) {
|
|
39
|
+
if (typeof pattern === "function") {
|
|
40
|
+
return { generator: pattern, name: "custom" };
|
|
41
|
+
}
|
|
42
|
+
if (typeof pattern === "string") {
|
|
43
|
+
switch (pattern) {
|
|
44
|
+
case "alpha":
|
|
45
|
+
return { generator: alphaGenerator, name: "alpha" };
|
|
46
|
+
case "numeric":
|
|
47
|
+
return { generator: numericGenerator, name: "numeric" };
|
|
48
|
+
case "alphanumeric":
|
|
49
|
+
return { generator: alphanumericGenerator, name: "alphanumeric" };
|
|
50
|
+
case "short":
|
|
51
|
+
return { generator: shortGenerator, name: "short" };
|
|
52
|
+
case "prefixed":
|
|
53
|
+
return { generator: prefixedGenerator("k"), name: "prefixed:k" };
|
|
54
|
+
default:
|
|
55
|
+
return { generator: alphaGenerator, name: "alpha" };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (typeof pattern === "object" && "prefix" in pattern) {
|
|
59
|
+
return {
|
|
60
|
+
generator: prefixedGenerator(pattern.prefix, pattern.style || "numeric"),
|
|
61
|
+
name: `prefixed:${pattern.prefix}`
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
return { generator: alphaGenerator, name: "alpha" };
|
|
65
|
+
}
|
|
66
|
+
function resolveNestedDepth(handling, maxDepth) {
|
|
67
|
+
if (handling === void 0 || handling === "deep") {
|
|
68
|
+
return maxDepth;
|
|
69
|
+
}
|
|
70
|
+
if (handling === "shallow") {
|
|
71
|
+
return 1;
|
|
72
|
+
}
|
|
73
|
+
if (handling === "arrays") {
|
|
74
|
+
return maxDepth;
|
|
75
|
+
}
|
|
76
|
+
if (typeof handling === "number") {
|
|
77
|
+
return handling;
|
|
78
|
+
}
|
|
79
|
+
return maxDepth;
|
|
80
|
+
}
|
|
81
|
+
function collectKeys(data, options, currentDepth = 0) {
|
|
82
|
+
const keys = /* @__PURE__ */ new Set();
|
|
83
|
+
const { minKeyLength, maxDepth, nestedHandling, excludeKeys, includeKeys } = options;
|
|
84
|
+
if (currentDepth >= maxDepth) return keys;
|
|
85
|
+
const keyCounts = /* @__PURE__ */ new Map();
|
|
86
|
+
for (const item of data) {
|
|
87
|
+
if (typeof item !== "object" || item === null) continue;
|
|
88
|
+
for (const key of Object.keys(item)) {
|
|
89
|
+
if (excludeKeys?.includes(key)) continue;
|
|
90
|
+
const shouldInclude = includeKeys?.includes(key) || key.length >= minKeyLength;
|
|
91
|
+
if (shouldInclude) {
|
|
92
|
+
keys.add(key);
|
|
93
|
+
keyCounts.set(key, (keyCounts.get(key) || 0) + 1);
|
|
94
|
+
}
|
|
95
|
+
const value = item[key];
|
|
96
|
+
if (nestedHandling === "shallow") {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (Array.isArray(value) && value.length > 0 && isCompressibleArray(value)) {
|
|
100
|
+
const nestedKeys = collectKeys(
|
|
101
|
+
value,
|
|
102
|
+
options,
|
|
103
|
+
currentDepth + 1
|
|
104
|
+
);
|
|
105
|
+
nestedKeys.forEach((k) => keys.add(k));
|
|
106
|
+
} else if (nestedHandling !== "arrays" && typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
107
|
+
const nestedKeys = collectKeys(
|
|
108
|
+
[value],
|
|
109
|
+
options,
|
|
110
|
+
currentDepth + 1
|
|
111
|
+
);
|
|
112
|
+
nestedKeys.forEach((k) => keys.add(k));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (options.homogeneousOnly && data.length > 0) {
|
|
117
|
+
for (const [key, count] of keyCounts) {
|
|
118
|
+
if (count < data.length) {
|
|
119
|
+
keys.delete(key);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return keys;
|
|
124
|
+
}
|
|
125
|
+
function isCompressibleArray(data) {
|
|
126
|
+
if (!Array.isArray(data) || data.length === 0) return false;
|
|
127
|
+
return data.every(
|
|
128
|
+
(item) => typeof item === "object" && item !== null && !Array.isArray(item)
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
function compressObject(obj, keyToShort, maxDepth, currentDepth = 0) {
|
|
132
|
+
if (currentDepth >= maxDepth) return obj;
|
|
133
|
+
const compressed = {};
|
|
134
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
135
|
+
const shortKey = keyToShort.get(key) ?? key;
|
|
136
|
+
if (Array.isArray(value) && isCompressibleArray(value)) {
|
|
137
|
+
compressed[shortKey] = value.map(
|
|
138
|
+
(item) => compressObject(
|
|
139
|
+
item,
|
|
140
|
+
keyToShort,
|
|
141
|
+
maxDepth,
|
|
142
|
+
currentDepth + 1
|
|
143
|
+
)
|
|
144
|
+
);
|
|
145
|
+
} else if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
146
|
+
compressed[shortKey] = compressObject(
|
|
147
|
+
value,
|
|
148
|
+
keyToShort,
|
|
149
|
+
maxDepth,
|
|
150
|
+
currentDepth + 1
|
|
151
|
+
);
|
|
152
|
+
} else {
|
|
153
|
+
compressed[shortKey] = value;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return compressed;
|
|
157
|
+
}
|
|
158
|
+
function compress(data, options = {}) {
|
|
159
|
+
const {
|
|
160
|
+
minKeyLength = 3,
|
|
161
|
+
maxDepth = 10,
|
|
162
|
+
keyPattern = "alpha",
|
|
163
|
+
nestedHandling = "deep",
|
|
164
|
+
homogeneousOnly = false,
|
|
165
|
+
excludeKeys,
|
|
166
|
+
includeKeys
|
|
167
|
+
} = options;
|
|
168
|
+
const { generator, name: patternName } = createKeyGenerator(keyPattern);
|
|
169
|
+
const effectiveDepth = resolveNestedDepth(nestedHandling, maxDepth);
|
|
170
|
+
const allKeys = collectKeys(data, {
|
|
171
|
+
minKeyLength,
|
|
172
|
+
maxDepth: effectiveDepth,
|
|
173
|
+
nestedHandling,
|
|
174
|
+
excludeKeys,
|
|
175
|
+
includeKeys,
|
|
176
|
+
homogeneousOnly
|
|
177
|
+
});
|
|
178
|
+
const sortedKeys = Array.from(allKeys).sort();
|
|
179
|
+
const keyToShort = /* @__PURE__ */ new Map();
|
|
180
|
+
const keyMap = {};
|
|
181
|
+
sortedKeys.forEach((key, index) => {
|
|
182
|
+
const shortKey = generator(index);
|
|
183
|
+
if (shortKey.length < key.length) {
|
|
184
|
+
keyToShort.set(key, shortKey);
|
|
185
|
+
keyMap[shortKey] = key;
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
const compressed = data.map(
|
|
189
|
+
(item) => compressObject(item, keyToShort, effectiveDepth)
|
|
190
|
+
);
|
|
191
|
+
return {
|
|
192
|
+
__terse__: true,
|
|
193
|
+
v: 1,
|
|
194
|
+
k: keyMap,
|
|
195
|
+
d: compressed,
|
|
196
|
+
p: patternName
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
function createTerseProxy(compressed, keyMap) {
|
|
200
|
+
const originalToShort = new Map(
|
|
201
|
+
Object.entries(keyMap).map(([short, original]) => [original, short])
|
|
202
|
+
);
|
|
203
|
+
const handler = {
|
|
204
|
+
get(target, prop) {
|
|
205
|
+
if (typeof prop === "symbol") {
|
|
206
|
+
return Reflect.get(target, prop);
|
|
207
|
+
}
|
|
208
|
+
const shortKey = originalToShort.get(prop);
|
|
209
|
+
const actualKey = shortKey ?? prop;
|
|
210
|
+
const value = target[actualKey];
|
|
211
|
+
if (Array.isArray(value)) {
|
|
212
|
+
return value.map((item) => {
|
|
213
|
+
if (typeof item === "object" && item !== null && !Array.isArray(item)) {
|
|
214
|
+
return createTerseProxy(item, keyMap);
|
|
215
|
+
}
|
|
216
|
+
return item;
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
if (typeof value === "object" && value !== null) {
|
|
220
|
+
return createTerseProxy(value, keyMap);
|
|
221
|
+
}
|
|
222
|
+
return value;
|
|
223
|
+
},
|
|
224
|
+
has(target, prop) {
|
|
225
|
+
if (typeof prop === "symbol") {
|
|
226
|
+
return Reflect.has(target, prop);
|
|
227
|
+
}
|
|
228
|
+
const shortKey = originalToShort.get(prop);
|
|
229
|
+
return (shortKey ?? prop) in target;
|
|
230
|
+
},
|
|
231
|
+
ownKeys(target) {
|
|
232
|
+
return Object.keys(target).map((shortKey) => keyMap[shortKey] ?? shortKey);
|
|
233
|
+
},
|
|
234
|
+
getOwnPropertyDescriptor(target, prop) {
|
|
235
|
+
if (typeof prop === "symbol") {
|
|
236
|
+
return Reflect.getOwnPropertyDescriptor(target, prop);
|
|
237
|
+
}
|
|
238
|
+
const shortKey = originalToShort.get(prop);
|
|
239
|
+
const actualKey = shortKey ?? prop;
|
|
240
|
+
const descriptor = Object.getOwnPropertyDescriptor(target, actualKey);
|
|
241
|
+
if (descriptor) {
|
|
242
|
+
return { ...descriptor, enumerable: true, configurable: true };
|
|
243
|
+
}
|
|
244
|
+
return void 0;
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
return new Proxy(compressed, handler);
|
|
248
|
+
}
|
|
249
|
+
function wrapWithProxy(payload) {
|
|
250
|
+
if (Array.isArray(payload.d)) {
|
|
251
|
+
return payload.d.map((item) => {
|
|
252
|
+
if (typeof item === "object" && item !== null && !Array.isArray(item)) {
|
|
253
|
+
return createTerseProxy(item, payload.k);
|
|
254
|
+
}
|
|
255
|
+
return item;
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
if (typeof payload.d === "object" && payload.d !== null) {
|
|
259
|
+
return createTerseProxy(payload.d, payload.k);
|
|
260
|
+
}
|
|
261
|
+
return payload.d;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// src/mongodb.ts
|
|
265
|
+
var isPatched = false;
|
|
266
|
+
var globalOptions = {};
|
|
267
|
+
var originalMethods = {};
|
|
268
|
+
function wrapResults(results) {
|
|
269
|
+
if (globalOptions.enabled === false) {
|
|
270
|
+
return results;
|
|
271
|
+
}
|
|
272
|
+
if (results.length < (globalOptions.minArrayLength ?? 1)) {
|
|
273
|
+
return results;
|
|
274
|
+
}
|
|
275
|
+
if (!isCompressibleArray(results)) {
|
|
276
|
+
return results;
|
|
277
|
+
}
|
|
278
|
+
const payload = compress(results, globalOptions);
|
|
279
|
+
return wrapWithProxy(payload);
|
|
280
|
+
}
|
|
281
|
+
function wrapSingleDoc(doc) {
|
|
282
|
+
if (globalOptions.enabled === false || globalOptions.skipSingleDocs) {
|
|
283
|
+
return doc;
|
|
284
|
+
}
|
|
285
|
+
if (doc === null || doc === void 0) {
|
|
286
|
+
return doc;
|
|
287
|
+
}
|
|
288
|
+
if (typeof doc !== "object") {
|
|
289
|
+
return doc;
|
|
290
|
+
}
|
|
291
|
+
const payload = compress([doc], globalOptions);
|
|
292
|
+
const wrapped = wrapWithProxy(payload);
|
|
293
|
+
return wrapped[0];
|
|
294
|
+
}
|
|
295
|
+
async function patchMongoDB() {
|
|
296
|
+
let mongodb;
|
|
297
|
+
try {
|
|
298
|
+
mongodb = await import('mongodb');
|
|
299
|
+
} catch {
|
|
300
|
+
throw new Error(
|
|
301
|
+
"terseMongo requires mongodb to be installed. Run: npm install mongodb"
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
const { FindCursor, AggregationCursor, Collection } = mongodb;
|
|
305
|
+
if (FindCursor?.prototype) {
|
|
306
|
+
originalMethods.findCursorToArray = FindCursor.prototype.toArray;
|
|
307
|
+
FindCursor.prototype.toArray = async function() {
|
|
308
|
+
const results = await originalMethods.findCursorToArray.call(this);
|
|
309
|
+
return wrapResults(results);
|
|
310
|
+
};
|
|
311
|
+
originalMethods.findCursorNext = FindCursor.prototype.next;
|
|
312
|
+
FindCursor.prototype.next = async function() {
|
|
313
|
+
const doc = await originalMethods.findCursorNext.call(this);
|
|
314
|
+
return doc ? wrapSingleDoc(doc) : null;
|
|
315
|
+
};
|
|
316
|
+
originalMethods.findCursorIterator = FindCursor.prototype[Symbol.asyncIterator];
|
|
317
|
+
FindCursor.prototype[Symbol.asyncIterator] = async function* () {
|
|
318
|
+
const iterator = originalMethods.findCursorIterator.call(this);
|
|
319
|
+
for await (const doc of iterator) {
|
|
320
|
+
yield wrapSingleDoc(doc);
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
if (AggregationCursor?.prototype) {
|
|
325
|
+
originalMethods.aggregationCursorToArray = AggregationCursor.prototype.toArray;
|
|
326
|
+
AggregationCursor.prototype.toArray = async function() {
|
|
327
|
+
const results = await originalMethods.aggregationCursorToArray.call(this);
|
|
328
|
+
return wrapResults(results);
|
|
329
|
+
};
|
|
330
|
+
originalMethods.aggregationCursorNext = AggregationCursor.prototype.next;
|
|
331
|
+
AggregationCursor.prototype.next = async function() {
|
|
332
|
+
const doc = await originalMethods.aggregationCursorNext.call(this);
|
|
333
|
+
return doc ? wrapSingleDoc(doc) : null;
|
|
334
|
+
};
|
|
335
|
+
originalMethods.aggregationCursorIterator = AggregationCursor.prototype[Symbol.asyncIterator];
|
|
336
|
+
AggregationCursor.prototype[Symbol.asyncIterator] = async function* () {
|
|
337
|
+
const iterator = originalMethods.aggregationCursorIterator.call(this);
|
|
338
|
+
for await (const doc of iterator) {
|
|
339
|
+
yield wrapSingleDoc(doc);
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
if (Collection?.prototype) {
|
|
344
|
+
originalMethods.collectionFindOne = Collection.prototype.findOne;
|
|
345
|
+
Collection.prototype.findOne = async function(...args) {
|
|
346
|
+
const doc = await originalMethods.collectionFindOne.apply(this, args);
|
|
347
|
+
return doc ? wrapSingleDoc(doc) : null;
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
async function unpatchMongoDB() {
|
|
352
|
+
let mongodb;
|
|
353
|
+
try {
|
|
354
|
+
mongodb = await import('mongodb');
|
|
355
|
+
} catch {
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
const { FindCursor, AggregationCursor, Collection } = mongodb;
|
|
359
|
+
if (FindCursor?.prototype && originalMethods.findCursorToArray) {
|
|
360
|
+
FindCursor.prototype.toArray = originalMethods.findCursorToArray;
|
|
361
|
+
FindCursor.prototype.next = originalMethods.findCursorNext;
|
|
362
|
+
FindCursor.prototype[Symbol.asyncIterator] = originalMethods.findCursorIterator;
|
|
363
|
+
}
|
|
364
|
+
if (AggregationCursor?.prototype && originalMethods.aggregationCursorToArray) {
|
|
365
|
+
AggregationCursor.prototype.toArray = originalMethods.aggregationCursorToArray;
|
|
366
|
+
AggregationCursor.prototype.next = originalMethods.aggregationCursorNext;
|
|
367
|
+
AggregationCursor.prototype[Symbol.asyncIterator] = originalMethods.aggregationCursorIterator;
|
|
368
|
+
}
|
|
369
|
+
if (Collection?.prototype && originalMethods.collectionFindOne) {
|
|
370
|
+
Collection.prototype.findOne = originalMethods.collectionFindOne;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
async function terseMongo(options = {}) {
|
|
374
|
+
if (isPatched) {
|
|
375
|
+
globalOptions = { minArrayLength: 1, ...options };
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
globalOptions = { minArrayLength: 1, ...options };
|
|
379
|
+
await patchMongoDB();
|
|
380
|
+
isPatched = true;
|
|
381
|
+
}
|
|
382
|
+
function terseMongoSync(options = {}) {
|
|
383
|
+
if (isPatched) {
|
|
384
|
+
globalOptions = { minArrayLength: 1, ...options };
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
globalOptions = { minArrayLength: 1, ...options };
|
|
388
|
+
let mongodb;
|
|
389
|
+
try {
|
|
390
|
+
mongodb = __require("mongodb");
|
|
391
|
+
} catch {
|
|
392
|
+
throw new Error(
|
|
393
|
+
"terseMongo requires mongodb to be installed. Run: npm install mongodb"
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
const { FindCursor, AggregationCursor, Collection } = mongodb;
|
|
397
|
+
if (FindCursor?.prototype) {
|
|
398
|
+
originalMethods.findCursorToArray = FindCursor.prototype.toArray;
|
|
399
|
+
FindCursor.prototype.toArray = async function() {
|
|
400
|
+
const results = await originalMethods.findCursorToArray.call(this);
|
|
401
|
+
return wrapResults(results);
|
|
402
|
+
};
|
|
403
|
+
originalMethods.findCursorNext = FindCursor.prototype.next;
|
|
404
|
+
FindCursor.prototype.next = async function() {
|
|
405
|
+
const doc = await originalMethods.findCursorNext.call(this);
|
|
406
|
+
return doc ? wrapSingleDoc(doc) : null;
|
|
407
|
+
};
|
|
408
|
+
originalMethods.findCursorIterator = FindCursor.prototype[Symbol.asyncIterator];
|
|
409
|
+
FindCursor.prototype[Symbol.asyncIterator] = async function* () {
|
|
410
|
+
const iterator = originalMethods.findCursorIterator.call(this);
|
|
411
|
+
for await (const doc of iterator) {
|
|
412
|
+
yield wrapSingleDoc(doc);
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
if (AggregationCursor?.prototype) {
|
|
417
|
+
originalMethods.aggregationCursorToArray = AggregationCursor.prototype.toArray;
|
|
418
|
+
AggregationCursor.prototype.toArray = async function() {
|
|
419
|
+
const results = await originalMethods.aggregationCursorToArray.call(this);
|
|
420
|
+
return wrapResults(results);
|
|
421
|
+
};
|
|
422
|
+
originalMethods.aggregationCursorNext = AggregationCursor.prototype.next;
|
|
423
|
+
AggregationCursor.prototype.next = async function() {
|
|
424
|
+
const doc = await originalMethods.aggregationCursorNext.call(this);
|
|
425
|
+
return doc ? wrapSingleDoc(doc) : null;
|
|
426
|
+
};
|
|
427
|
+
originalMethods.aggregationCursorIterator = AggregationCursor.prototype[Symbol.asyncIterator];
|
|
428
|
+
AggregationCursor.prototype[Symbol.asyncIterator] = async function* () {
|
|
429
|
+
const iterator = originalMethods.aggregationCursorIterator.call(this);
|
|
430
|
+
for await (const doc of iterator) {
|
|
431
|
+
yield wrapSingleDoc(doc);
|
|
432
|
+
}
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
if (Collection?.prototype) {
|
|
436
|
+
originalMethods.collectionFindOne = Collection.prototype.findOne;
|
|
437
|
+
Collection.prototype.findOne = async function(...args) {
|
|
438
|
+
const doc = await originalMethods.collectionFindOne.apply(this, args);
|
|
439
|
+
return doc ? wrapSingleDoc(doc) : null;
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
isPatched = true;
|
|
443
|
+
}
|
|
444
|
+
async function unterse() {
|
|
445
|
+
if (!isPatched) return;
|
|
446
|
+
await unpatchMongoDB();
|
|
447
|
+
Object.keys(originalMethods).forEach((key) => {
|
|
448
|
+
delete originalMethods[key];
|
|
449
|
+
});
|
|
450
|
+
isPatched = false;
|
|
451
|
+
globalOptions = {};
|
|
452
|
+
}
|
|
453
|
+
function isTerseMongoActive() {
|
|
454
|
+
return isPatched;
|
|
455
|
+
}
|
|
456
|
+
function getTerseMongoOptions() {
|
|
457
|
+
return { ...globalOptions };
|
|
458
|
+
}
|
|
459
|
+
function setTerseMongoOptions(options) {
|
|
460
|
+
globalOptions = { ...globalOptions, ...options };
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
export { getTerseMongoOptions, isTerseMongoActive, setTerseMongoOptions, terseMongo, terseMongoSync, unterse };
|
|
464
|
+
//# sourceMappingURL=mongodb.mjs.map
|
|
465
|
+
//# sourceMappingURL=mongodb.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core.ts","../src/mongodb.ts"],"names":[],"mappings":"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","file":"mongodb.mjs","sourcesContent":["/**\n * TerseJSON Core\n *\n * The core compression and expansion algorithms.\n */\n\nimport {\n TersePayload,\n isTersePayload,\n KeyPattern,\n KeyGenerator,\n NestedHandling,\n CompressOptions,\n} from './types';\n\n// ============================================================================\n// KEY PATTERN GENERATORS\n// ============================================================================\n\n/**\n * Alpha pattern: a, b, c, ... z, aa, ab, ...\n */\nfunction alphaGenerator(index: number): string {\n let key = '';\n let remaining = index;\n\n do {\n key = String.fromCharCode(97 + (remaining % 26)) + key;\n remaining = Math.floor(remaining / 26) - 1;\n } while (remaining >= 0);\n\n return key;\n}\n\n/**\n * Numeric pattern: 0, 1, 2, ... 9, 10, 11, ...\n */\nfunction numericGenerator(index: number): string {\n return String(index);\n}\n\n/**\n * Alphanumeric pattern: a1, a2, ... a9, b1, b2, ...\n */\nfunction alphanumericGenerator(index: number): string {\n const letterIndex = Math.floor(index / 9);\n const numIndex = (index % 9) + 1;\n return alphaGenerator(letterIndex) + numIndex;\n}\n\n/**\n * Short pattern: uses shortest possible keys\n * _, a, b, ..., z, aa, ab, ...\n */\nfunction shortGenerator(index: number): string {\n if (index === 0) return '_';\n return alphaGenerator(index - 1);\n}\n\n/**\n * Prefixed pattern: k0, k1, k2, ...\n */\nfunction prefixedGenerator(prefix: string, style: 'numeric' | 'alpha' = 'numeric'): KeyGenerator {\n return (index: number) => {\n if (style === 'alpha') {\n return prefix + alphaGenerator(index);\n }\n return prefix + index;\n };\n}\n\n/**\n * Creates a key generator from a pattern configuration\n */\nexport function createKeyGenerator(pattern: KeyPattern): { generator: KeyGenerator; name: string } {\n // If it's already a function, use it directly\n if (typeof pattern === 'function') {\n return { generator: pattern, name: 'custom' };\n }\n\n // If it's a preset string\n if (typeof pattern === 'string') {\n switch (pattern) {\n case 'alpha':\n return { generator: alphaGenerator, name: 'alpha' };\n case 'numeric':\n return { generator: numericGenerator, name: 'numeric' };\n case 'alphanumeric':\n return { generator: alphanumericGenerator, name: 'alphanumeric' };\n case 'short':\n return { generator: shortGenerator, name: 'short' };\n case 'prefixed':\n return { generator: prefixedGenerator('k'), name: 'prefixed:k' };\n default:\n return { generator: alphaGenerator, name: 'alpha' };\n }\n }\n\n // If it's a prefix config object\n if (typeof pattern === 'object' && 'prefix' in pattern) {\n return {\n generator: prefixedGenerator(pattern.prefix, pattern.style || 'numeric'),\n name: `prefixed:${pattern.prefix}`,\n };\n }\n\n return { generator: alphaGenerator, name: 'alpha' };\n}\n\n/**\n * Resolves nested handling to a numeric depth\n */\nfunction resolveNestedDepth(handling: NestedHandling | undefined, maxDepth: number): number {\n if (handling === undefined || handling === 'deep') {\n return maxDepth;\n }\n if (handling === 'shallow') {\n return 1;\n }\n if (handling === 'arrays') {\n return maxDepth; // Special handling in collect/compress functions\n }\n if (typeof handling === 'number') {\n return handling;\n }\n return maxDepth;\n}\n\n// Legacy generateShortKey removed - use createKeyGenerator instead\n\ninterface CollectKeysOptions {\n minKeyLength: number;\n maxDepth: number;\n nestedHandling: NestedHandling;\n excludeKeys?: string[];\n includeKeys?: string[];\n homogeneousOnly?: boolean;\n}\n\n/**\n * Collects all unique keys from an array of objects\n */\nfunction collectKeys(\n data: Record<string, unknown>[],\n options: CollectKeysOptions,\n currentDepth: number = 0\n): Set<string> {\n const keys = new Set<string>();\n const { minKeyLength, maxDepth, nestedHandling, excludeKeys, includeKeys } = options;\n\n if (currentDepth >= maxDepth) return keys;\n\n // For homogeneous mode, track key counts\n const keyCounts = new Map<string, number>();\n\n for (const item of data) {\n if (typeof item !== 'object' || item === null) continue;\n\n for (const key of Object.keys(item)) {\n // Skip excluded keys\n if (excludeKeys?.includes(key)) continue;\n\n // Include if in includeKeys, or if meets minKeyLength\n const shouldInclude = includeKeys?.includes(key) || key.length >= minKeyLength;\n\n if (shouldInclude) {\n keys.add(key);\n keyCounts.set(key, (keyCounts.get(key) || 0) + 1);\n }\n\n // Handle nested structures based on nestedHandling option\n const value = item[key];\n\n if (nestedHandling === 'shallow') {\n // Don't process nested structures\n continue;\n }\n\n if (Array.isArray(value) && value.length > 0 && isCompressibleArray(value)) {\n // Nested array of objects - always process\n const nestedKeys = collectKeys(\n value as Record<string, unknown>[],\n options,\n currentDepth + 1\n );\n nestedKeys.forEach(k => keys.add(k));\n } else if (\n nestedHandling !== 'arrays' &&\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value)\n ) {\n // Single nested object - skip if nestedHandling is 'arrays'\n const nestedKeys = collectKeys(\n [value as Record<string, unknown>],\n options,\n currentDepth + 1\n );\n nestedKeys.forEach(k => keys.add(k));\n }\n }\n }\n\n // If homogeneous mode, only keep keys that appear in ALL objects\n if (options.homogeneousOnly && data.length > 0) {\n for (const [key, count] of keyCounts) {\n if (count < data.length) {\n keys.delete(key);\n }\n }\n }\n\n return keys;\n}\n\n/**\n * Checks if an array is compressible (array of objects with consistent structure)\n */\nexport function isCompressibleArray(data: unknown): data is Record<string, unknown>[] {\n if (!Array.isArray(data) || data.length === 0) return false;\n\n // Check if all items are objects\n return data.every(\n item => typeof item === 'object' && item !== null && !Array.isArray(item)\n );\n}\n\n/**\n * Compresses an object using the key mapping\n */\nfunction compressObject(\n obj: Record<string, unknown>,\n keyToShort: Map<string, string>,\n maxDepth: number,\n currentDepth: number = 0\n): Record<string, unknown> {\n if (currentDepth >= maxDepth) return obj;\n\n const compressed: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const shortKey = keyToShort.get(key) ?? key;\n\n if (Array.isArray(value) && isCompressibleArray(value)) {\n // Recursively compress nested arrays\n compressed[shortKey] = value.map(item =>\n compressObject(\n item as Record<string, unknown>,\n keyToShort,\n maxDepth,\n currentDepth + 1\n )\n );\n } else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n // Compress single nested objects too\n compressed[shortKey] = compressObject(\n value as Record<string, unknown>,\n keyToShort,\n maxDepth,\n currentDepth + 1\n );\n } else {\n compressed[shortKey] = value;\n }\n }\n\n return compressed;\n}\n\n/**\n * Expands an object using the key mapping\n */\nfunction expandObject(\n obj: Record<string, unknown>,\n shortToKey: Map<string, string>,\n maxDepth: number,\n currentDepth: number = 0\n): Record<string, unknown> {\n if (currentDepth >= maxDepth) return obj;\n\n const expanded: Record<string, unknown> = {};\n\n for (const [shortKey, value] of Object.entries(obj)) {\n const originalKey = shortToKey.get(shortKey) ?? shortKey;\n\n if (Array.isArray(value)) {\n expanded[originalKey] = value.map(item => {\n if (typeof item === 'object' && item !== null && !Array.isArray(item)) {\n return expandObject(\n item as Record<string, unknown>,\n shortToKey,\n maxDepth,\n currentDepth + 1\n );\n }\n return item;\n });\n } else if (typeof value === 'object' && value !== null) {\n expanded[originalKey] = expandObject(\n value as Record<string, unknown>,\n shortToKey,\n maxDepth,\n currentDepth + 1\n );\n } else {\n expanded[originalKey] = value;\n }\n }\n\n return expanded;\n}\n\n// Re-export CompressOptions from types for backwards compatibility\nexport type { CompressOptions } from './types';\n\n/**\n * Compresses an array of objects by replacing keys with short aliases\n */\nexport function compress<T extends Record<string, unknown>[]>(\n data: T,\n options: CompressOptions = {}\n): TersePayload<unknown[]> {\n const {\n minKeyLength = 3,\n maxDepth = 10,\n keyPattern = 'alpha',\n nestedHandling = 'deep',\n homogeneousOnly = false,\n excludeKeys,\n includeKeys,\n } = options;\n\n // Create key generator\n const { generator, name: patternName } = createKeyGenerator(keyPattern);\n\n // Resolve nested depth\n const effectiveDepth = resolveNestedDepth(nestedHandling, maxDepth);\n\n // Collect all unique keys\n const allKeys = collectKeys(data, {\n minKeyLength,\n maxDepth: effectiveDepth,\n nestedHandling,\n excludeKeys,\n includeKeys,\n homogeneousOnly,\n });\n\n // Sort keys by frequency of use (most used first) for optimal compression\n // For now, just sort alphabetically for deterministic output\n const sortedKeys = Array.from(allKeys).sort();\n\n // Create bidirectional mapping\n const keyToShort = new Map<string, string>();\n const keyMap: Record<string, string> = {};\n\n sortedKeys.forEach((key, index) => {\n const shortKey = generator(index);\n // Only use short key if it's actually shorter\n if (shortKey.length < key.length) {\n keyToShort.set(key, shortKey);\n keyMap[shortKey] = key;\n }\n });\n\n // Compress the data\n const compressed = data.map(item =>\n compressObject(item, keyToShort, effectiveDepth)\n );\n\n return {\n __terse__: true,\n v: 1,\n k: keyMap,\n d: compressed,\n p: patternName,\n };\n}\n\n/**\n * Expands a TersePayload back to its original form\n */\nexport function expand<T = unknown>(payload: TersePayload): T {\n const shortToKey = new Map(\n Object.entries(payload.k).map(([short, original]) => [short, original])\n );\n\n if (Array.isArray(payload.d)) {\n return payload.d.map(item => {\n if (typeof item === 'object' && item !== null && !Array.isArray(item)) {\n return expandObject(item as Record<string, unknown>, shortToKey, 10);\n }\n return item;\n }) as T;\n }\n\n if (typeof payload.d === 'object' && payload.d !== null) {\n return expandObject(payload.d as Record<string, unknown>, shortToKey, 10) as T;\n }\n\n return payload.d as T;\n}\n\n/**\n * Creates a Proxy that transparently maps original keys to short keys\n * This is the magic that makes client-side access seamless\n */\nexport function createTerseProxy<T extends Record<string, unknown>>(\n compressed: Record<string, unknown>,\n keyMap: Record<string, string> // short -> original\n): T {\n // Create reverse map: original -> short\n const originalToShort = new Map(\n Object.entries(keyMap).map(([short, original]) => [original, short])\n );\n\n const handler: ProxyHandler<Record<string, unknown>> = {\n get(target, prop: string | symbol) {\n if (typeof prop === 'symbol') {\n return Reflect.get(target, prop);\n }\n\n // Check if accessing by original key name\n const shortKey = originalToShort.get(prop);\n const actualKey = shortKey ?? prop;\n const value = target[actualKey];\n\n // Recursively proxy nested objects/arrays\n if (Array.isArray(value)) {\n return value.map(item => {\n if (typeof item === 'object' && item !== null && !Array.isArray(item)) {\n return createTerseProxy(item as Record<string, unknown>, keyMap);\n }\n return item;\n });\n }\n\n if (typeof value === 'object' && value !== null) {\n return createTerseProxy(value as Record<string, unknown>, keyMap);\n }\n\n return value;\n },\n\n has(target, prop: string | symbol) {\n if (typeof prop === 'symbol') {\n return Reflect.has(target, prop);\n }\n const shortKey = originalToShort.get(prop);\n return (shortKey ?? prop) in target;\n },\n\n ownKeys(target) {\n // Return original key names\n return Object.keys(target).map(shortKey => keyMap[shortKey] ?? shortKey);\n },\n\n getOwnPropertyDescriptor(target, prop: string | symbol) {\n if (typeof prop === 'symbol') {\n return Reflect.getOwnPropertyDescriptor(target, prop);\n }\n const shortKey = originalToShort.get(prop);\n const actualKey = shortKey ?? prop;\n const descriptor = Object.getOwnPropertyDescriptor(target, actualKey);\n if (descriptor) {\n return { ...descriptor, enumerable: true, configurable: true };\n }\n return undefined;\n },\n };\n\n return new Proxy(compressed, handler) as T;\n}\n\n/**\n * Wraps TersePayload data with Proxies for transparent access\n */\nexport function wrapWithProxy<T>(payload: TersePayload): T {\n if (Array.isArray(payload.d)) {\n return payload.d.map(item => {\n if (typeof item === 'object' && item !== null && !Array.isArray(item)) {\n return createTerseProxy(item as Record<string, unknown>, payload.k);\n }\n return item;\n }) as T;\n }\n\n if (typeof payload.d === 'object' && payload.d !== null) {\n return createTerseProxy(payload.d as Record<string, unknown>, payload.k) as T;\n }\n\n return payload.d as T;\n}\n\n// Re-export for convenience\nexport { isTersePayload };\n","/**\n * TerseJSON MongoDB Integration\n *\n * Zero-config integration with MongoDB native driver.\n * Call terseMongo() once at startup and all queries automatically\n * return memory-efficient Proxy-wrapped results.\n *\n * @example\n * ```typescript\n * import { terseMongo } from 'tersejson/mongodb';\n * import { MongoClient } from 'mongodb';\n *\n * terseMongo(); // Patch once at startup\n *\n * const client = new MongoClient(uri);\n * const users = await client.db('mydb').collection('users').find().toArray();\n * // users is automatically Proxy-wrapped - 70% less memory\n * ```\n *\n * @packageDocumentation\n */\n\nimport { compress, wrapWithProxy, isCompressibleArray } from './core';\nimport { CompressOptions } from './types';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\n/**\n * Options for terseMongo initialization\n */\nexport interface TerseMongoOptions extends Partial<CompressOptions> {\n /**\n * Enable/disable compression (default: true)\n */\n enabled?: boolean;\n\n /**\n * Minimum array length to compress (default: 1)\n * Single documents are always wrapped for consistency\n */\n minArrayLength?: number;\n\n /**\n * Skip compression for single document queries like findOne (default: false)\n * Set to true if you don't want overhead on single doc fetches\n */\n skipSingleDocs?: boolean;\n}\n\n// ============================================================================\n// STATE\n// ============================================================================\n\nlet isPatched = false;\nlet globalOptions: TerseMongoOptions = {};\n\n// Store original methods for restoration\nconst originalMethods: {\n findCursorToArray?: Function;\n findCursorNext?: Function;\n findCursorIterator?: Function;\n aggregationCursorToArray?: Function;\n aggregationCursorNext?: Function;\n aggregationCursorIterator?: Function;\n collectionFindOne?: Function;\n} = {};\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\n/**\n * Wrap an array of documents with TerseJSON Proxy\n */\nfunction wrapResults<T extends Record<string, unknown>>(results: T[]): T[] {\n if (globalOptions.enabled === false) {\n return results;\n }\n\n if (results.length < (globalOptions.minArrayLength ?? 1)) {\n return results;\n }\n\n if (!isCompressibleArray(results)) {\n return results;\n }\n\n const payload = compress(results as Record<string, unknown>[], globalOptions);\n return wrapWithProxy(payload) as T[];\n}\n\n/**\n * Wrap a single document with TerseJSON Proxy\n */\nfunction wrapSingleDoc<T extends Record<string, unknown>>(doc: T): T {\n if (globalOptions.enabled === false || globalOptions.skipSingleDocs) {\n return doc;\n }\n\n if (doc === null || doc === undefined) {\n return doc;\n }\n\n if (typeof doc !== 'object') {\n return doc;\n }\n\n // Compress as single-item array, return first item\n const payload = compress([doc] as Record<string, unknown>[], globalOptions);\n const wrapped = wrapWithProxy(payload) as T[];\n return wrapped[0];\n}\n\n// ============================================================================\n// PATCHING FUNCTIONS\n// ============================================================================\n\n/**\n * Dynamically import mongodb and patch its prototypes\n */\nasync function patchMongoDB(): Promise<void> {\n // Dynamic import to avoid bundling mongodb\n let mongodb: typeof import('mongodb');\n try {\n mongodb = await import('mongodb');\n } catch {\n throw new Error(\n 'terseMongo requires mongodb to be installed. Run: npm install mongodb'\n );\n }\n\n const { FindCursor, AggregationCursor, Collection } = mongodb;\n\n // Patch FindCursor\n if (FindCursor?.prototype) {\n // toArray\n originalMethods.findCursorToArray = FindCursor.prototype.toArray;\n (FindCursor.prototype as any).toArray = async function (): Promise<any[]> {\n const results = await originalMethods.findCursorToArray!.call(this);\n return wrapResults(results);\n };\n\n // next\n originalMethods.findCursorNext = FindCursor.prototype.next;\n (FindCursor.prototype as any).next = async function (): Promise<any | null> {\n const doc = await originalMethods.findCursorNext!.call(this);\n return doc ? wrapSingleDoc(doc) : null;\n };\n\n // async iterator\n originalMethods.findCursorIterator =\n FindCursor.prototype[Symbol.asyncIterator];\n (FindCursor.prototype as any)[Symbol.asyncIterator] = async function* () {\n const iterator = originalMethods.findCursorIterator!.call(this);\n for await (const doc of iterator) {\n yield wrapSingleDoc(doc);\n }\n };\n }\n\n // Patch AggregationCursor\n if (AggregationCursor?.prototype) {\n // toArray\n originalMethods.aggregationCursorToArray =\n AggregationCursor.prototype.toArray;\n (AggregationCursor.prototype as any).toArray = async function (): Promise<any[]> {\n const results =\n await originalMethods.aggregationCursorToArray!.call(this);\n return wrapResults(results);\n };\n\n // next\n originalMethods.aggregationCursorNext = AggregationCursor.prototype.next;\n (AggregationCursor.prototype as any).next = async function (): Promise<any | null> {\n const doc = await originalMethods.aggregationCursorNext!.call(this);\n return doc ? wrapSingleDoc(doc) : null;\n };\n\n // async iterator\n originalMethods.aggregationCursorIterator =\n AggregationCursor.prototype[Symbol.asyncIterator];\n (AggregationCursor.prototype as any)[Symbol.asyncIterator] = async function* () {\n const iterator = originalMethods.aggregationCursorIterator!.call(this);\n for await (const doc of iterator) {\n yield wrapSingleDoc(doc);\n }\n };\n }\n\n // Patch Collection.findOne\n if (Collection?.prototype) {\n originalMethods.collectionFindOne = Collection.prototype.findOne;\n (Collection.prototype as any).findOne = async function (\n ...args: any[]\n ): Promise<any | null> {\n const doc = await originalMethods.collectionFindOne!.apply(this, args);\n return doc ? wrapSingleDoc(doc) : null;\n };\n }\n}\n\n/**\n * Restore original MongoDB methods\n */\nasync function unpatchMongoDB(): Promise<void> {\n let mongodb: typeof import('mongodb');\n try {\n mongodb = await import('mongodb');\n } catch {\n return;\n }\n\n const { FindCursor, AggregationCursor, Collection } = mongodb;\n\n if (FindCursor?.prototype && originalMethods.findCursorToArray) {\n FindCursor.prototype.toArray = originalMethods.findCursorToArray as any;\n FindCursor.prototype.next = originalMethods.findCursorNext as any;\n FindCursor.prototype[Symbol.asyncIterator] =\n originalMethods.findCursorIterator as any;\n }\n\n if (AggregationCursor?.prototype && originalMethods.aggregationCursorToArray) {\n AggregationCursor.prototype.toArray =\n originalMethods.aggregationCursorToArray as any;\n AggregationCursor.prototype.next =\n originalMethods.aggregationCursorNext as any;\n AggregationCursor.prototype[Symbol.asyncIterator] =\n originalMethods.aggregationCursorIterator as any;\n }\n\n if (Collection?.prototype && originalMethods.collectionFindOne) {\n Collection.prototype.findOne = originalMethods.collectionFindOne as any;\n }\n}\n\n// ============================================================================\n// PUBLIC API\n// ============================================================================\n\n/**\n * Initialize TerseJSON integration with MongoDB native driver.\n *\n * Call this once at application startup, before any MongoDB queries.\n * All subsequent queries will automatically return Proxy-wrapped results.\n *\n * @example\n * ```typescript\n * import { terseMongo } from 'tersejson/mongodb';\n *\n * // Basic usage\n * await terseMongo();\n *\n * // With options\n * await terseMongo({\n * minKeyLength: 4, // Only compress keys with 4+ characters\n * minArrayLength: 5, // Only compress arrays with 5+ items\n * skipSingleDocs: true, // Don't wrap findOne results\n * });\n * ```\n *\n * @param options - Configuration options\n */\nexport async function terseMongo(\n options: TerseMongoOptions = {}\n): Promise<void> {\n if (isPatched) {\n // Update options if already patched\n globalOptions = { minArrayLength: 1, ...options };\n return;\n }\n\n globalOptions = { minArrayLength: 1, ...options };\n await patchMongoDB();\n isPatched = true;\n}\n\n/**\n * Synchronous version of terseMongo for CommonJS compatibility.\n *\n * Note: This requires mongodb to already be loaded in the module cache.\n * For best results, use the async terseMongo() instead.\n *\n * @param options - Configuration options\n */\nexport function terseMongoSync(options: TerseMongoOptions = {}): void {\n if (isPatched) {\n globalOptions = { minArrayLength: 1, ...options };\n return;\n }\n\n globalOptions = { minArrayLength: 1, ...options };\n\n // Try synchronous require\n let mongodb: typeof import('mongodb');\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n mongodb = require('mongodb');\n } catch {\n throw new Error(\n 'terseMongo requires mongodb to be installed. Run: npm install mongodb'\n );\n }\n\n const { FindCursor, AggregationCursor, Collection } = mongodb;\n\n // Same patching logic as async version\n if (FindCursor?.prototype) {\n originalMethods.findCursorToArray = FindCursor.prototype.toArray;\n (FindCursor.prototype as any).toArray = async function (): Promise<any[]> {\n const results = await originalMethods.findCursorToArray!.call(this);\n return wrapResults(results);\n };\n\n originalMethods.findCursorNext = FindCursor.prototype.next;\n (FindCursor.prototype as any).next = async function (): Promise<any | null> {\n const doc = await originalMethods.findCursorNext!.call(this);\n return doc ? wrapSingleDoc(doc) : null;\n };\n\n originalMethods.findCursorIterator =\n FindCursor.prototype[Symbol.asyncIterator];\n (FindCursor.prototype as any)[Symbol.asyncIterator] = async function* () {\n const iterator = originalMethods.findCursorIterator!.call(this);\n for await (const doc of iterator) {\n yield wrapSingleDoc(doc);\n }\n };\n }\n\n if (AggregationCursor?.prototype) {\n originalMethods.aggregationCursorToArray =\n AggregationCursor.prototype.toArray;\n (AggregationCursor.prototype as any).toArray = async function (): Promise<any[]> {\n const results =\n await originalMethods.aggregationCursorToArray!.call(this);\n return wrapResults(results);\n };\n\n originalMethods.aggregationCursorNext = AggregationCursor.prototype.next;\n (AggregationCursor.prototype as any).next = async function (): Promise<any | null> {\n const doc = await originalMethods.aggregationCursorNext!.call(this);\n return doc ? wrapSingleDoc(doc) : null;\n };\n\n originalMethods.aggregationCursorIterator =\n AggregationCursor.prototype[Symbol.asyncIterator];\n (AggregationCursor.prototype as any)[Symbol.asyncIterator] = async function* () {\n const iterator = originalMethods.aggregationCursorIterator!.call(this);\n for await (const doc of iterator) {\n yield wrapSingleDoc(doc);\n }\n };\n }\n\n if (Collection?.prototype) {\n originalMethods.collectionFindOne = Collection.prototype.findOne;\n (Collection.prototype as any).findOne = async function (\n ...args: any[]\n ): Promise<any | null> {\n const doc = await originalMethods.collectionFindOne!.apply(this, args);\n return doc ? wrapSingleDoc(doc) : null;\n };\n }\n\n isPatched = true;\n}\n\n/**\n * Remove TerseJSON patches from MongoDB driver.\n *\n * Useful for testing or when you need to temporarily disable compression.\n *\n * @example\n * ```typescript\n * import { terseMongo, unterse } from 'tersejson/mongodb';\n *\n * await terseMongo();\n * // ... queries are Proxy-wrapped\n *\n * await unterse();\n * // ... queries return normal documents\n * ```\n */\nexport async function unterse(): Promise<void> {\n if (!isPatched) return;\n\n await unpatchMongoDB();\n\n // Clear stored references\n Object.keys(originalMethods).forEach((key) => {\n delete originalMethods[key as keyof typeof originalMethods];\n });\n\n isPatched = false;\n globalOptions = {};\n}\n\n/**\n * Check if TerseJSON MongoDB patching is active\n */\nexport function isTerseMongoActive(): boolean {\n return isPatched;\n}\n\n/**\n * Get current TerseJSON MongoDB options\n */\nexport function getTerseMongoOptions(): TerseMongoOptions {\n return { ...globalOptions };\n}\n\n/**\n * Update TerseJSON MongoDB options without re-patching\n */\nexport function setTerseMongoOptions(options: Partial<TerseMongoOptions>): void {\n globalOptions = { ...globalOptions, ...options };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tersejson",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Memory-efficient JSON processing. Lazy Proxy expansion uses 70% less RAM than JSON.parse - plus 30-80% smaller payloads.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"json",
|
|
@@ -32,6 +32,9 @@
|
|
|
32
32
|
"react-query",
|
|
33
33
|
"swr",
|
|
34
34
|
"angular",
|
|
35
|
+
"mongodb",
|
|
36
|
+
"mongoose",
|
|
37
|
+
"database",
|
|
35
38
|
"key-compression",
|
|
36
39
|
"api-optimization",
|
|
37
40
|
"lightweight",
|
|
@@ -90,6 +93,11 @@
|
|
|
90
93
|
"types": "./dist/server-memory.d.ts",
|
|
91
94
|
"import": "./dist/server-memory.mjs",
|
|
92
95
|
"require": "./dist/server-memory.js"
|
|
96
|
+
},
|
|
97
|
+
"./mongodb": {
|
|
98
|
+
"types": "./dist/mongodb.d.ts",
|
|
99
|
+
"import": "./dist/mongodb.mjs",
|
|
100
|
+
"require": "./dist/mongodb.js"
|
|
93
101
|
}
|
|
94
102
|
},
|
|
95
103
|
"files": [
|
|
@@ -109,14 +117,16 @@
|
|
|
109
117
|
"@types/node": "^20.11.0",
|
|
110
118
|
"eslint": "^8.56.0",
|
|
111
119
|
"express": "^4.18.2",
|
|
120
|
+
"mongodb": "^7.0.0",
|
|
112
121
|
"sharp": "^0.34.5",
|
|
113
122
|
"tsup": "^8.0.1",
|
|
114
123
|
"typescript": "^5.3.3",
|
|
115
124
|
"vitest": "^1.2.0"
|
|
116
125
|
},
|
|
117
126
|
"peerDependencies": {
|
|
127
|
+
"@apollo/client": ">=3.0.0",
|
|
118
128
|
"express": ">=4.0.0",
|
|
119
|
-
"
|
|
129
|
+
"mongodb": ">=5.0.0"
|
|
120
130
|
},
|
|
121
131
|
"peerDependenciesMeta": {
|
|
122
132
|
"express": {
|
|
@@ -124,6 +134,9 @@
|
|
|
124
134
|
},
|
|
125
135
|
"@apollo/client": {
|
|
126
136
|
"optional": true
|
|
137
|
+
},
|
|
138
|
+
"mongodb": {
|
|
139
|
+
"optional": true
|
|
127
140
|
}
|
|
128
141
|
},
|
|
129
142
|
"engines": {
|