mongodb-livedata-server 0.1.3 → 0.1.4

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.
Files changed (91) hide show
  1. package/dist/livedata_server.d.ts +4 -4
  2. package/dist/livedata_server.js +11 -11
  3. package/dist/meteor/binary-heap/max_heap.d.ts +31 -31
  4. package/dist/meteor/binary-heap/max_heap.js +186 -186
  5. package/dist/meteor/binary-heap/min_heap.d.ts +6 -6
  6. package/dist/meteor/binary-heap/min_heap.js +17 -17
  7. package/dist/meteor/binary-heap/min_max_heap.d.ts +11 -11
  8. package/dist/meteor/binary-heap/min_max_heap.js +48 -48
  9. package/dist/meteor/callback-hook/hook.d.ts +11 -11
  10. package/dist/meteor/callback-hook/hook.js +78 -78
  11. package/dist/meteor/ddp/crossbar.d.ts +15 -15
  12. package/dist/meteor/ddp/crossbar.js +136 -136
  13. package/dist/meteor/ddp/heartbeat.d.ts +19 -19
  14. package/dist/meteor/ddp/heartbeat.js +77 -77
  15. package/dist/meteor/ddp/livedata_server.d.ts +141 -142
  16. package/dist/meteor/ddp/livedata_server.js +403 -403
  17. package/dist/meteor/ddp/method-invocation.d.ts +35 -35
  18. package/dist/meteor/ddp/method-invocation.js +72 -72
  19. package/dist/meteor/ddp/random-stream.d.ts +8 -8
  20. package/dist/meteor/ddp/random-stream.js +100 -100
  21. package/dist/meteor/ddp/session-collection-view.d.ts +20 -20
  22. package/dist/meteor/ddp/session-collection-view.js +106 -106
  23. package/dist/meteor/ddp/session-document-view.d.ts +8 -8
  24. package/dist/meteor/ddp/session-document-view.js +82 -82
  25. package/dist/meteor/ddp/session.d.ts +75 -75
  26. package/dist/meteor/ddp/session.js +590 -590
  27. package/dist/meteor/ddp/stream_server.d.ts +20 -21
  28. package/dist/meteor/ddp/stream_server.js +181 -181
  29. package/dist/meteor/ddp/subscription.d.ts +94 -94
  30. package/dist/meteor/ddp/subscription.js +370 -370
  31. package/dist/meteor/ddp/utils.d.ts +8 -8
  32. package/dist/meteor/ddp/utils.js +104 -104
  33. package/dist/meteor/ddp/writefence.d.ts +20 -20
  34. package/dist/meteor/ddp/writefence.js +111 -111
  35. package/dist/meteor/diff-sequence/diff.d.ts +17 -17
  36. package/dist/meteor/diff-sequence/diff.js +257 -257
  37. package/dist/meteor/ejson/ejson.d.ts +82 -82
  38. package/dist/meteor/ejson/ejson.js +568 -569
  39. package/dist/meteor/ejson/stringify.d.ts +2 -2
  40. package/dist/meteor/ejson/stringify.js +119 -119
  41. package/dist/meteor/ejson/utils.d.ts +12 -12
  42. package/dist/meteor/ejson/utils.js +42 -42
  43. package/dist/meteor/mongo/caching_change_observer.d.ts +16 -16
  44. package/dist/meteor/mongo/caching_change_observer.js +63 -63
  45. package/dist/meteor/mongo/doc_fetcher.d.ts +7 -7
  46. package/dist/meteor/mongo/doc_fetcher.js +53 -53
  47. package/dist/meteor/mongo/geojson_utils.d.ts +3 -3
  48. package/dist/meteor/mongo/geojson_utils.js +40 -41
  49. package/dist/meteor/mongo/live_connection.d.ts +28 -28
  50. package/dist/meteor/mongo/live_connection.js +264 -264
  51. package/dist/meteor/mongo/live_cursor.d.ts +25 -25
  52. package/dist/meteor/mongo/live_cursor.js +60 -60
  53. package/dist/meteor/mongo/minimongo_common.d.ts +84 -84
  54. package/dist/meteor/mongo/minimongo_common.js +1998 -1998
  55. package/dist/meteor/mongo/minimongo_matcher.d.ts +23 -23
  56. package/dist/meteor/mongo/minimongo_matcher.js +283 -283
  57. package/dist/meteor/mongo/minimongo_sorter.d.ts +16 -16
  58. package/dist/meteor/mongo/minimongo_sorter.js +268 -268
  59. package/dist/meteor/mongo/observe_driver_utils.d.ts +9 -9
  60. package/dist/meteor/mongo/observe_driver_utils.js +72 -73
  61. package/dist/meteor/mongo/observe_multiplexer.d.ts +46 -46
  62. package/dist/meteor/mongo/observe_multiplexer.js +203 -203
  63. package/dist/meteor/mongo/oplog-observe-driver.d.ts +68 -68
  64. package/dist/meteor/mongo/oplog-observe-driver.js +918 -918
  65. package/dist/meteor/mongo/oplog_tailing.d.ts +35 -35
  66. package/dist/meteor/mongo/oplog_tailing.js +352 -352
  67. package/dist/meteor/mongo/oplog_v2_converter.d.ts +1 -1
  68. package/dist/meteor/mongo/oplog_v2_converter.js +125 -126
  69. package/dist/meteor/mongo/polling_observe_driver.d.ts +30 -30
  70. package/dist/meteor/mongo/polling_observe_driver.js +216 -221
  71. package/dist/meteor/mongo/synchronous-cursor.d.ts +17 -17
  72. package/dist/meteor/mongo/synchronous-cursor.js +261 -261
  73. package/dist/meteor/mongo/synchronous-queue.d.ts +13 -13
  74. package/dist/meteor/mongo/synchronous-queue.js +110 -110
  75. package/dist/meteor/ordered-dict/ordered_dict.d.ts +31 -31
  76. package/dist/meteor/ordered-dict/ordered_dict.js +198 -198
  77. package/dist/meteor/random/AbstractRandomGenerator.d.ts +42 -42
  78. package/dist/meteor/random/AbstractRandomGenerator.js +92 -92
  79. package/dist/meteor/random/AleaRandomGenerator.d.ts +13 -13
  80. package/dist/meteor/random/AleaRandomGenerator.js +90 -90
  81. package/dist/meteor/random/NodeRandomGenerator.d.ts +16 -16
  82. package/dist/meteor/random/NodeRandomGenerator.js +42 -42
  83. package/dist/meteor/random/createAleaGenerator.d.ts +2 -2
  84. package/dist/meteor/random/createAleaGenerator.js +32 -32
  85. package/dist/meteor/random/createRandom.d.ts +1 -1
  86. package/dist/meteor/random/createRandom.js +22 -22
  87. package/dist/meteor/random/main.d.ts +1 -1
  88. package/dist/meteor/random/main.js +12 -12
  89. package/dist/meteor/types.d.ts +1 -1
  90. package/dist/meteor/types.js +2 -2
  91. package/package.json +5 -5
@@ -1,569 +1,568 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.clone = exports.equals = exports.isBinary = exports.parse = exports.stringify = exports.fromJSONValue = exports._adjustTypesFromJSONValue = exports.toJSONValue = exports._adjustTypesToJSONValue = exports._getConverters = exports._getTypes = exports._isCustomType = exports.addType = void 0;
7
- const utils_1 = require("./utils");
8
- const stringify_1 = __importDefault(require("./stringify"));
9
- // Custom type interface definition
10
- /**
11
- * @class CustomType
12
- * @instanceName customType
13
- * @memberOf EJSON
14
- * @summary The interface that a class must satisfy to be able to become an
15
- * EJSON custom type via EJSON.addType.
16
- */
17
- /**
18
- * @function typeName
19
- * @memberOf EJSON.CustomType
20
- * @summary Return the tag used to identify this type. This must match the
21
- * tag used to register this type with
22
- * [`EJSON.addType`](#ejson_add_type).
23
- * @locus Anywhere
24
- * @instance
25
- */
26
- /**
27
- * @function toJSONValue
28
- * @memberOf EJSON.CustomType
29
- * @summary Serialize this instance into a JSON-compatible value.
30
- * @locus Anywhere
31
- * @instance
32
- */
33
- /**
34
- * @function clone
35
- * @memberOf EJSON.CustomType
36
- * @summary Return a value `r` such that `this.equals(r)` is true, and
37
- * modifications to `r` do not affect `this` and vice versa.
38
- * @locus Anywhere
39
- * @instance
40
- */
41
- /**
42
- * @function equals
43
- * @memberOf EJSON.CustomType
44
- * @summary Return `true` if `other` has a value equal to `this`; `false`
45
- * otherwise.
46
- * @locus Anywhere
47
- * @param {Object} other Another object to compare this to.
48
- * @instance
49
- */
50
- const customTypes = new Map();
51
- // Add a custom type, using a method of your choice to get to and
52
- // from a basic JSON-able representation. The factory argument
53
- // is a function of JSON-able --> your object
54
- // The type you add must have:
55
- // - A toJSONValue() method, so that Meteor can serialize it
56
- // - a typeName() method, to show how to look it up in our type table.
57
- // It is okay if these methods are monkey-patched on.
58
- // EJSON.clone will use toJSONValue and the given factory to produce
59
- // a clone, but you may specify a method clone() that will be
60
- // used instead.
61
- // Similarly, EJSON.equals will use toJSONValue to make comparisons,
62
- // but you may provide a method equals() instead.
63
- /**
64
- * @summary Add a custom datatype to EJSON.
65
- * @locus Anywhere
66
- * @param {String} name A tag for your custom type; must be unique among
67
- * custom data types defined in your project, and must
68
- * match the result of your type's `typeName` method.
69
- * @param {Function} factory A function that deserializes a JSON-compatible
70
- * value into an instance of your type. This should
71
- * match the serialization performed by your
72
- * type's `toJSONValue` method.
73
- */
74
- function addType(name, factory) {
75
- if (customTypes.has(name)) {
76
- throw new Error(`Type ${name} already present`);
77
- }
78
- customTypes.set(name, factory);
79
- }
80
- exports.addType = addType;
81
- ;
82
- const builtinConverters = [
83
- {
84
- matchJSONValue(obj) {
85
- return (0, utils_1.hasOwn)(obj, '$date') && (0, utils_1.lengthOf)(obj) === 1;
86
- },
87
- matchObject(obj) {
88
- return obj instanceof Date;
89
- },
90
- toJSONValue(obj) {
91
- return { $date: obj.getTime() };
92
- },
93
- fromJSONValue(obj) {
94
- return new Date(obj.$date);
95
- },
96
- },
97
- {
98
- matchJSONValue(obj) {
99
- return (0, utils_1.hasOwn)(obj, '$regexp')
100
- && (0, utils_1.hasOwn)(obj, '$flags')
101
- && (0, utils_1.lengthOf)(obj) === 2;
102
- },
103
- matchObject(obj) {
104
- return obj instanceof RegExp;
105
- },
106
- toJSONValue(regexp) {
107
- return {
108
- $regexp: regexp.source,
109
- $flags: regexp.flags
110
- };
111
- },
112
- fromJSONValue(obj) {
113
- // Replaces duplicate / invalid flags.
114
- return new RegExp(obj.$regexp, obj.$flags
115
- // Cut off flags at 50 chars to avoid abusing RegExp for DOS.
116
- .slice(0, 50)
117
- .replace(/[^gimuy]/g, '')
118
- .replace(/(.)(?=.*\1)/g, ''));
119
- },
120
- },
121
- {
122
- // which we match.)
123
- matchJSONValue(obj) {
124
- return (0, utils_1.hasOwn)(obj, '$InfNaN') && (0, utils_1.lengthOf)(obj) === 1;
125
- },
126
- matchObject: utils_1.isInfOrNaN,
127
- toJSONValue(obj) {
128
- let sign;
129
- if (Number.isNaN(obj)) {
130
- sign = 0;
131
- }
132
- else if (obj === Infinity) {
133
- sign = 1;
134
- }
135
- else {
136
- sign = -1;
137
- }
138
- return { $InfNaN: sign };
139
- },
140
- fromJSONValue(obj) {
141
- return obj.$InfNaN / 0;
142
- },
143
- },
144
- {
145
- matchJSONValue(obj) {
146
- return (0, utils_1.hasOwn)(obj, '$binary') && (0, utils_1.lengthOf)(obj) === 1;
147
- },
148
- matchObject(obj) {
149
- return typeof Uint8Array !== 'undefined' && obj instanceof Uint8Array
150
- || (obj && (0, utils_1.hasOwn)(obj, '$Uint8ArrayPolyfill'));
151
- },
152
- toJSONValue(obj) {
153
- return { $binary: Buffer.from(obj).toString("base64") };
154
- },
155
- fromJSONValue(obj) {
156
- return Buffer.from(obj.$binary, "base64").toString();
157
- },
158
- },
159
- {
160
- matchJSONValue(obj) {
161
- return (0, utils_1.hasOwn)(obj, '$escape') && (0, utils_1.lengthOf)(obj) === 1;
162
- },
163
- matchObject(obj) {
164
- let match = false;
165
- if (obj) {
166
- const keyCount = (0, utils_1.lengthOf)(obj);
167
- if (keyCount === 1 || keyCount === 2) {
168
- match =
169
- builtinConverters.some(converter => converter.matchJSONValue(obj));
170
- }
171
- }
172
- return match;
173
- },
174
- toJSONValue(obj) {
175
- const newObj = {};
176
- (0, utils_1.keysOf)(obj).forEach(key => {
177
- newObj[key] = toJSONValue(obj[key]);
178
- });
179
- return { $escape: newObj };
180
- },
181
- fromJSONValue(obj) {
182
- const newObj = {};
183
- (0, utils_1.keysOf)(obj.$escape).forEach(key => {
184
- newObj[key] = fromJSONValue(obj.$escape[key]);
185
- });
186
- return newObj;
187
- },
188
- },
189
- {
190
- matchJSONValue(obj) {
191
- return (0, utils_1.hasOwn)(obj, '$type')
192
- && (0, utils_1.hasOwn)(obj, '$value') && (0, utils_1.lengthOf)(obj) === 2;
193
- },
194
- matchObject(obj) {
195
- return _isCustomType(obj);
196
- },
197
- toJSONValue(obj) {
198
- const jsonValue = obj.toJSONValue();
199
- return { $type: obj.typeName(), $value: jsonValue };
200
- },
201
- fromJSONValue(obj) {
202
- const typeName = obj.$type;
203
- if (!customTypes.has(typeName)) {
204
- throw new Error(`Custom EJSON type ${typeName} is not defined`);
205
- }
206
- const converter = customTypes.get(typeName);
207
- return converter(obj.$value);
208
- },
209
- },
210
- ];
211
- function _isCustomType(obj) {
212
- return obj &&
213
- (0, utils_1.isFunction)(obj.toJSONValue) &&
214
- (0, utils_1.isFunction)(obj.typeName) &&
215
- customTypes.has(obj.typeName());
216
- }
217
- exports._isCustomType = _isCustomType;
218
- function _getTypes(isOriginal = false) { return (isOriginal ? customTypes : (0, utils_1.convertMapToObject)(customTypes)); }
219
- exports._getTypes = _getTypes;
220
- function _getConverters() { return builtinConverters; }
221
- exports._getConverters = _getConverters;
222
- // Either return the JSON-compatible version of the argument, or undefined (if
223
- // the item isn't itself replaceable, but maybe some fields in it are)
224
- const toJSONValueHelper = item => {
225
- for (let i = 0; i < builtinConverters.length; i++) {
226
- const converter = builtinConverters[i];
227
- if (converter.matchObject(item)) {
228
- return converter.toJSONValue(item);
229
- }
230
- }
231
- return undefined;
232
- };
233
- // for both arrays and objects, in-place modification.
234
- function _adjustTypesToJSONValue(obj) {
235
- // Is it an atom that we need to adjust?
236
- if (obj === null) {
237
- return null;
238
- }
239
- const maybeChanged = toJSONValueHelper(obj);
240
- if (maybeChanged !== undefined) {
241
- return maybeChanged;
242
- }
243
- // Other atoms are unchanged.
244
- if (!(0, utils_1.isObject)(obj)) {
245
- return obj;
246
- }
247
- // Iterate over array or object structure.
248
- (0, utils_1.keysOf)(obj).forEach(key => {
249
- const value = obj[key];
250
- if (!(0, utils_1.isObject)(value) && value !== undefined &&
251
- !(0, utils_1.isInfOrNaN)(value)) {
252
- return; // continue
253
- }
254
- const changed = toJSONValueHelper(value);
255
- if (changed) {
256
- obj[key] = changed;
257
- return; // on to the next key
258
- }
259
- // if we get here, value is an object but not adjustable
260
- // at this level. recurse.
261
- _adjustTypesToJSONValue(value);
262
- });
263
- return obj;
264
- }
265
- exports._adjustTypesToJSONValue = _adjustTypesToJSONValue;
266
- ;
267
- /**
268
- * @summary Serialize an EJSON-compatible value into its plain JSON
269
- * representation.
270
- * @locus Anywhere
271
- * @param {EJSON} val A value to serialize to plain JSON.
272
- */
273
- function toJSONValue(item) {
274
- const changed = toJSONValueHelper(item);
275
- if (changed !== undefined) {
276
- return changed;
277
- }
278
- let newItem = item;
279
- if ((0, utils_1.isObject)(item)) {
280
- newItem = clone(item);
281
- _adjustTypesToJSONValue(newItem);
282
- }
283
- return newItem;
284
- }
285
- exports.toJSONValue = toJSONValue;
286
- ;
287
- // Either return the argument changed to have the non-json
288
- // rep of itself (the Object version) or the argument itself.
289
- // DOES NOT RECURSE. For actually getting the fully-changed value, use
290
- // EJSON.fromJSONValue
291
- const fromJSONValueHelper = value => {
292
- if ((0, utils_1.isObject)(value) && value !== null) {
293
- const keys = (0, utils_1.keysOf)(value);
294
- if (keys.length <= 2
295
- && keys.every(k => typeof k === 'string' && k.substr(0, 1) === '$')) {
296
- for (let i = 0; i < builtinConverters.length; i++) {
297
- const converter = builtinConverters[i];
298
- if (converter.matchJSONValue(value)) {
299
- return converter.fromJSONValue(value);
300
- }
301
- }
302
- }
303
- }
304
- return value;
305
- };
306
- // for both arrays and objects. Tries its best to just
307
- // use the object you hand it, but may return something
308
- // different if the object you hand it itself needs changing.
309
- function _adjustTypesFromJSONValue(obj) {
310
- if (obj === null) {
311
- return null;
312
- }
313
- const maybeChanged = fromJSONValueHelper(obj);
314
- if (maybeChanged !== obj) {
315
- return maybeChanged;
316
- }
317
- // Other atoms are unchanged.
318
- if (!(0, utils_1.isObject)(obj)) {
319
- return obj;
320
- }
321
- (0, utils_1.keysOf)(obj).forEach(key => {
322
- const value = obj[key];
323
- if ((0, utils_1.isObject)(value)) {
324
- const changed = fromJSONValueHelper(value);
325
- if (value !== changed) {
326
- obj[key] = changed;
327
- return;
328
- }
329
- // if we get here, value is an object but not adjustable
330
- // at this level. recurse.
331
- _adjustTypesFromJSONValue(value);
332
- }
333
- });
334
- return obj;
335
- }
336
- exports._adjustTypesFromJSONValue = _adjustTypesFromJSONValue;
337
- ;
338
- /**
339
- * @summary Deserialize an EJSON value from its plain JSON representation.
340
- * @locus Anywhere
341
- * @param {JSONCompatible} val A value to deserialize into EJSON.
342
- */
343
- function fromJSONValue(item) {
344
- let changed = fromJSONValueHelper(item);
345
- if (changed === item && (0, utils_1.isObject)(item)) {
346
- changed = clone(item);
347
- _adjustTypesFromJSONValue(changed);
348
- }
349
- return changed;
350
- }
351
- exports.fromJSONValue = fromJSONValue;
352
- ;
353
- /**
354
- * @summary Serialize a value to a string. For EJSON values, the serialization
355
- * fully represents the value. For non-EJSON values, serializes the
356
- * same way as `JSON.stringify`.
357
- * @locus Anywhere
358
- * @param {EJSON} val A value to stringify.
359
- * @param {Object} [options]
360
- * @param {Boolean | Integer | String} options.indent Indents objects and
361
- * arrays for easy readability. When `true`, indents by 2 spaces; when an
362
- * integer, indents by that number of spaces; and when a string, uses the
363
- * string as the indentation pattern.
364
- * @param {Boolean} options.canonical When `true`, stringifies keys in an
365
- * object in sorted order.
366
- */
367
- function stringify(val, opts) {
368
- return (0, utils_1.handleError)((item, options) => {
369
- let serialized;
370
- const json = toJSONValue(item);
371
- if (options && (options.canonical || options.indent)) {
372
- serialized = (0, stringify_1.default)(json, options);
373
- }
374
- else {
375
- serialized = JSON.stringify(json);
376
- }
377
- return serialized;
378
- }, val, opts);
379
- }
380
- exports.stringify = stringify;
381
- /**
382
- * @summary Parse a string into an EJSON value. Throws an error if the string
383
- * is not valid EJSON.
384
- * @locus Anywhere
385
- * @param {String} str A string to parse into an EJSON value.
386
- */
387
- function parse(item) {
388
- if (typeof item !== 'string') {
389
- throw new Error('EJSON.parse argument should be a string');
390
- }
391
- return fromJSONValue(JSON.parse(item));
392
- }
393
- exports.parse = parse;
394
- ;
395
- /**
396
- * @summary Returns true if `x` is a buffer of binary data, as returned from
397
- * [`EJSON.newBinary`](#ejson_new_binary).
398
- * @param {Object} x The variable to check.
399
- * @locus Anywhere
400
- */
401
- function isBinary(obj) {
402
- return !!((typeof Uint8Array !== 'undefined' && obj instanceof Uint8Array) ||
403
- (obj && obj.$Uint8ArrayPolyfill));
404
- }
405
- exports.isBinary = isBinary;
406
- ;
407
- /**
408
- * @summary Return true if `a` and `b` are equal to each other. Return false
409
- * otherwise. Uses the `equals` method on `a` if present, otherwise
410
- * performs a deep comparison.
411
- * @locus Anywhere
412
- * @param {EJSON} a
413
- * @param {EJSON} b
414
- * @param {Object} [options]
415
- * @param {Boolean} options.keyOrderSensitive Compare in key sensitive order,
416
- * if supported by the JavaScript implementation. For example, `{a: 1, b: 2}`
417
- * is equal to `{b: 2, a: 1}` only when `keyOrderSensitive` is `false`. The
418
- * default is `false`.
419
- */
420
- function equals(a, b, options) {
421
- let i;
422
- const keyOrderSensitive = !!(options && options.keyOrderSensitive);
423
- if (a === b) {
424
- return true;
425
- }
426
- // This differs from the IEEE spec for NaN equality, b/c we don't want
427
- // anything ever with a NaN to be poisoned from becoming equal to anything.
428
- if (Number.isNaN(a) && Number.isNaN(b)) {
429
- return true;
430
- }
431
- // if either one is falsy, they'd have to be === to be equal
432
- if (!a || !b) {
433
- return false;
434
- }
435
- if (!((0, utils_1.isObject)(a) && (0, utils_1.isObject)(b))) {
436
- return false;
437
- }
438
- if (a instanceof Date && b instanceof Date) {
439
- return a.valueOf() === b.valueOf();
440
- }
441
- if (isBinary(a) && isBinary(b)) {
442
- if (a.length !== b.length) {
443
- return false;
444
- }
445
- for (i = 0; i < a.length; i++) {
446
- if (a[i] !== b[i]) {
447
- return false;
448
- }
449
- }
450
- return true;
451
- }
452
- if ((0, utils_1.isFunction)(a.equals)) {
453
- return a.equals(b, options);
454
- }
455
- if ((0, utils_1.isFunction)(b.equals)) {
456
- return b.equals(a, options);
457
- }
458
- // Array.isArray works across iframes while instanceof won't
459
- const aIsArray = Array.isArray(a);
460
- const bIsArray = Array.isArray(b);
461
- // if not both or none are array they are not equal
462
- if (aIsArray !== bIsArray) {
463
- return false;
464
- }
465
- if (aIsArray && bIsArray) {
466
- if (a.length !== b.length) {
467
- return false;
468
- }
469
- for (i = 0; i < a.length; i++) {
470
- if (!equals(a[i], b[i], options)) {
471
- return false;
472
- }
473
- }
474
- return true;
475
- }
476
- // fallback for custom types that don't implement their own equals
477
- switch (+_isCustomType(a) + +_isCustomType(b)) {
478
- case 1: return false;
479
- case 2: return equals(toJSONValue(a), toJSONValue(b));
480
- default: // Do nothing
481
- }
482
- // fall back to structural equality of objects
483
- let ret;
484
- const aKeys = (0, utils_1.keysOf)(a);
485
- const bKeys = (0, utils_1.keysOf)(b);
486
- if (keyOrderSensitive) {
487
- i = 0;
488
- ret = aKeys.every(key => {
489
- if (i >= bKeys.length) {
490
- return false;
491
- }
492
- if (key !== bKeys[i]) {
493
- return false;
494
- }
495
- if (!equals(a[key], b[bKeys[i]], options)) {
496
- return false;
497
- }
498
- i++;
499
- return true;
500
- });
501
- }
502
- else {
503
- i = 0;
504
- ret = aKeys.every(key => {
505
- if (!(0, utils_1.hasOwn)(b, key)) {
506
- return false;
507
- }
508
- if (!equals(a[key], b[key], options)) {
509
- return false;
510
- }
511
- i++;
512
- return true;
513
- });
514
- }
515
- return ret && i === bKeys.length;
516
- }
517
- exports.equals = equals;
518
- ;
519
- /**
520
- * @summary Return a deep copy of `val`.
521
- * @locus Anywhere
522
- * @param {EJSON} val A value to copy.
523
- */
524
- function clone(v) {
525
- let ret;
526
- if (!(0, utils_1.isObject)(v)) {
527
- return v;
528
- }
529
- if (v === null) {
530
- return null; // null has typeof "object"
531
- }
532
- if (v instanceof Date) {
533
- return new Date(v.getTime());
534
- }
535
- // RegExps are not really EJSON elements (eg we don't define a serialization
536
- // for them), but they're immutable anyway, so we can support them in clone.
537
- if (v instanceof RegExp) {
538
- return v;
539
- }
540
- if (isBinary(v)) {
541
- ret = new Uint8Array(v.length);
542
- for (let i = 0; i < v.length; i++) {
543
- ret[i] = v[i];
544
- }
545
- return ret;
546
- }
547
- if (Array.isArray(v)) {
548
- return v.map(clone);
549
- }
550
- if ((0, utils_1.isArguments)(v)) {
551
- return Array.from(v).map(clone);
552
- }
553
- // handle general user-defined typed Objects if they have a clone method
554
- if ("clone" in v && (0, utils_1.isFunction)(v.clone)) {
555
- return v.clone();
556
- }
557
- // handle other custom types
558
- if (_isCustomType(v)) {
559
- return fromJSONValue(clone(toJSONValue(v)));
560
- }
561
- // handle other objects
562
- ret = {};
563
- (0, utils_1.keysOf)(v).forEach((key) => {
564
- ret[key] = clone(v[key]);
565
- });
566
- return ret;
567
- }
568
- exports.clone = clone;
569
- ;
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.addType = addType;
7
+ exports._isCustomType = _isCustomType;
8
+ exports._getTypes = _getTypes;
9
+ exports._getConverters = _getConverters;
10
+ exports._adjustTypesToJSONValue = _adjustTypesToJSONValue;
11
+ exports.toJSONValue = toJSONValue;
12
+ exports._adjustTypesFromJSONValue = _adjustTypesFromJSONValue;
13
+ exports.fromJSONValue = fromJSONValue;
14
+ exports.stringify = stringify;
15
+ exports.parse = parse;
16
+ exports.isBinary = isBinary;
17
+ exports.equals = equals;
18
+ exports.clone = clone;
19
+ const utils_1 = require("./utils");
20
+ const stringify_1 = __importDefault(require("./stringify"));
21
+ // Custom type interface definition
22
+ /**
23
+ * @class CustomType
24
+ * @instanceName customType
25
+ * @memberOf EJSON
26
+ * @summary The interface that a class must satisfy to be able to become an
27
+ * EJSON custom type via EJSON.addType.
28
+ */
29
+ /**
30
+ * @function typeName
31
+ * @memberOf EJSON.CustomType
32
+ * @summary Return the tag used to identify this type. This must match the
33
+ * tag used to register this type with
34
+ * [`EJSON.addType`](#ejson_add_type).
35
+ * @locus Anywhere
36
+ * @instance
37
+ */
38
+ /**
39
+ * @function toJSONValue
40
+ * @memberOf EJSON.CustomType
41
+ * @summary Serialize this instance into a JSON-compatible value.
42
+ * @locus Anywhere
43
+ * @instance
44
+ */
45
+ /**
46
+ * @function clone
47
+ * @memberOf EJSON.CustomType
48
+ * @summary Return a value `r` such that `this.equals(r)` is true, and
49
+ * modifications to `r` do not affect `this` and vice versa.
50
+ * @locus Anywhere
51
+ * @instance
52
+ */
53
+ /**
54
+ * @function equals
55
+ * @memberOf EJSON.CustomType
56
+ * @summary Return `true` if `other` has a value equal to `this`; `false`
57
+ * otherwise.
58
+ * @locus Anywhere
59
+ * @param {Object} other Another object to compare this to.
60
+ * @instance
61
+ */
62
+ const customTypes = new Map();
63
+ // Add a custom type, using a method of your choice to get to and
64
+ // from a basic JSON-able representation. The factory argument
65
+ // is a function of JSON-able --> your object
66
+ // The type you add must have:
67
+ // - A toJSONValue() method, so that Meteor can serialize it
68
+ // - a typeName() method, to show how to look it up in our type table.
69
+ // It is okay if these methods are monkey-patched on.
70
+ // EJSON.clone will use toJSONValue and the given factory to produce
71
+ // a clone, but you may specify a method clone() that will be
72
+ // used instead.
73
+ // Similarly, EJSON.equals will use toJSONValue to make comparisons,
74
+ // but you may provide a method equals() instead.
75
+ /**
76
+ * @summary Add a custom datatype to EJSON.
77
+ * @locus Anywhere
78
+ * @param {String} name A tag for your custom type; must be unique among
79
+ * custom data types defined in your project, and must
80
+ * match the result of your type's `typeName` method.
81
+ * @param {Function} factory A function that deserializes a JSON-compatible
82
+ * value into an instance of your type. This should
83
+ * match the serialization performed by your
84
+ * type's `toJSONValue` method.
85
+ */
86
+ function addType(name, factory) {
87
+ if (customTypes.has(name)) {
88
+ throw new Error(`Type ${name} already present`);
89
+ }
90
+ customTypes.set(name, factory);
91
+ }
92
+ ;
93
+ const builtinConverters = [
94
+ {
95
+ matchJSONValue(obj) {
96
+ return (0, utils_1.hasOwn)(obj, '$date') && (0, utils_1.lengthOf)(obj) === 1;
97
+ },
98
+ matchObject(obj) {
99
+ return obj instanceof Date;
100
+ },
101
+ toJSONValue(obj) {
102
+ return { $date: obj.getTime() };
103
+ },
104
+ fromJSONValue(obj) {
105
+ return new Date(obj.$date);
106
+ },
107
+ },
108
+ {
109
+ matchJSONValue(obj) {
110
+ return (0, utils_1.hasOwn)(obj, '$regexp')
111
+ && (0, utils_1.hasOwn)(obj, '$flags')
112
+ && (0, utils_1.lengthOf)(obj) === 2;
113
+ },
114
+ matchObject(obj) {
115
+ return obj instanceof RegExp;
116
+ },
117
+ toJSONValue(regexp) {
118
+ return {
119
+ $regexp: regexp.source,
120
+ $flags: regexp.flags
121
+ };
122
+ },
123
+ fromJSONValue(obj) {
124
+ // Replaces duplicate / invalid flags.
125
+ return new RegExp(obj.$regexp, obj.$flags
126
+ // Cut off flags at 50 chars to avoid abusing RegExp for DOS.
127
+ .slice(0, 50)
128
+ .replace(/[^gimuy]/g, '')
129
+ .replace(/(.)(?=.*\1)/g, ''));
130
+ },
131
+ },
132
+ {
133
+ // which we match.)
134
+ matchJSONValue(obj) {
135
+ return (0, utils_1.hasOwn)(obj, '$InfNaN') && (0, utils_1.lengthOf)(obj) === 1;
136
+ },
137
+ matchObject: utils_1.isInfOrNaN,
138
+ toJSONValue(obj) {
139
+ let sign;
140
+ if (Number.isNaN(obj)) {
141
+ sign = 0;
142
+ }
143
+ else if (obj === Infinity) {
144
+ sign = 1;
145
+ }
146
+ else {
147
+ sign = -1;
148
+ }
149
+ return { $InfNaN: sign };
150
+ },
151
+ fromJSONValue(obj) {
152
+ return obj.$InfNaN / 0;
153
+ },
154
+ },
155
+ {
156
+ matchJSONValue(obj) {
157
+ return (0, utils_1.hasOwn)(obj, '$binary') && (0, utils_1.lengthOf)(obj) === 1;
158
+ },
159
+ matchObject(obj) {
160
+ return typeof Uint8Array !== 'undefined' && obj instanceof Uint8Array
161
+ || (obj && (0, utils_1.hasOwn)(obj, '$Uint8ArrayPolyfill'));
162
+ },
163
+ toJSONValue(obj) {
164
+ return { $binary: Buffer.from(obj).toString("base64") };
165
+ },
166
+ fromJSONValue(obj) {
167
+ return Buffer.from(obj.$binary, "base64").toString();
168
+ },
169
+ },
170
+ {
171
+ matchJSONValue(obj) {
172
+ return (0, utils_1.hasOwn)(obj, '$escape') && (0, utils_1.lengthOf)(obj) === 1;
173
+ },
174
+ matchObject(obj) {
175
+ let match = false;
176
+ if (obj) {
177
+ const keyCount = (0, utils_1.lengthOf)(obj);
178
+ if (keyCount === 1 || keyCount === 2) {
179
+ match =
180
+ builtinConverters.some(converter => converter.matchJSONValue(obj));
181
+ }
182
+ }
183
+ return match;
184
+ },
185
+ toJSONValue(obj) {
186
+ const newObj = {};
187
+ (0, utils_1.keysOf)(obj).forEach(key => {
188
+ newObj[key] = toJSONValue(obj[key]);
189
+ });
190
+ return { $escape: newObj };
191
+ },
192
+ fromJSONValue(obj) {
193
+ const newObj = {};
194
+ (0, utils_1.keysOf)(obj.$escape).forEach(key => {
195
+ newObj[key] = fromJSONValue(obj.$escape[key]);
196
+ });
197
+ return newObj;
198
+ },
199
+ },
200
+ {
201
+ matchJSONValue(obj) {
202
+ return (0, utils_1.hasOwn)(obj, '$type')
203
+ && (0, utils_1.hasOwn)(obj, '$value') && (0, utils_1.lengthOf)(obj) === 2;
204
+ },
205
+ matchObject(obj) {
206
+ return _isCustomType(obj);
207
+ },
208
+ toJSONValue(obj) {
209
+ const jsonValue = obj.toJSONValue();
210
+ return { $type: obj.typeName(), $value: jsonValue };
211
+ },
212
+ fromJSONValue(obj) {
213
+ const typeName = obj.$type;
214
+ if (!customTypes.has(typeName)) {
215
+ throw new Error(`Custom EJSON type ${typeName} is not defined`);
216
+ }
217
+ const converter = customTypes.get(typeName);
218
+ return converter(obj.$value);
219
+ },
220
+ },
221
+ ];
222
+ function _isCustomType(obj) {
223
+ return obj &&
224
+ (0, utils_1.isFunction)(obj.toJSONValue) &&
225
+ (0, utils_1.isFunction)(obj.typeName) &&
226
+ customTypes.has(obj.typeName());
227
+ }
228
+ function _getTypes(isOriginal = false) { return (isOriginal ? customTypes : (0, utils_1.convertMapToObject)(customTypes)); }
229
+ function _getConverters() { return builtinConverters; }
230
+ // Either return the JSON-compatible version of the argument, or undefined (if
231
+ // the item isn't itself replaceable, but maybe some fields in it are)
232
+ const toJSONValueHelper = item => {
233
+ for (let i = 0; i < builtinConverters.length; i++) {
234
+ const converter = builtinConverters[i];
235
+ if (converter.matchObject(item)) {
236
+ return converter.toJSONValue(item);
237
+ }
238
+ }
239
+ return undefined;
240
+ };
241
+ // for both arrays and objects, in-place modification.
242
+ function _adjustTypesToJSONValue(obj) {
243
+ // Is it an atom that we need to adjust?
244
+ if (obj === null) {
245
+ return null;
246
+ }
247
+ const maybeChanged = toJSONValueHelper(obj);
248
+ if (maybeChanged !== undefined) {
249
+ return maybeChanged;
250
+ }
251
+ // Other atoms are unchanged.
252
+ if (!(0, utils_1.isObject)(obj)) {
253
+ return obj;
254
+ }
255
+ // Iterate over array or object structure.
256
+ (0, utils_1.keysOf)(obj).forEach(key => {
257
+ const value = obj[key];
258
+ if (!(0, utils_1.isObject)(value) && value !== undefined &&
259
+ !(0, utils_1.isInfOrNaN)(value)) {
260
+ return; // continue
261
+ }
262
+ const changed = toJSONValueHelper(value);
263
+ if (changed) {
264
+ obj[key] = changed;
265
+ return; // on to the next key
266
+ }
267
+ // if we get here, value is an object but not adjustable
268
+ // at this level. recurse.
269
+ _adjustTypesToJSONValue(value);
270
+ });
271
+ return obj;
272
+ }
273
+ ;
274
+ /**
275
+ * @summary Serialize an EJSON-compatible value into its plain JSON
276
+ * representation.
277
+ * @locus Anywhere
278
+ * @param {EJSON} val A value to serialize to plain JSON.
279
+ */
280
+ function toJSONValue(item) {
281
+ const changed = toJSONValueHelper(item);
282
+ if (changed !== undefined) {
283
+ return changed;
284
+ }
285
+ let newItem = item;
286
+ if ((0, utils_1.isObject)(item)) {
287
+ newItem = clone(item);
288
+ _adjustTypesToJSONValue(newItem);
289
+ }
290
+ return newItem;
291
+ }
292
+ ;
293
+ // Either return the argument changed to have the non-json
294
+ // rep of itself (the Object version) or the argument itself.
295
+ // DOES NOT RECURSE. For actually getting the fully-changed value, use
296
+ // EJSON.fromJSONValue
297
+ const fromJSONValueHelper = value => {
298
+ if ((0, utils_1.isObject)(value) && value !== null) {
299
+ const keys = (0, utils_1.keysOf)(value);
300
+ if (keys.length <= 2
301
+ && keys.every(k => typeof k === 'string' && k.substr(0, 1) === '$')) {
302
+ for (let i = 0; i < builtinConverters.length; i++) {
303
+ const converter = builtinConverters[i];
304
+ if (converter.matchJSONValue(value)) {
305
+ return converter.fromJSONValue(value);
306
+ }
307
+ }
308
+ }
309
+ }
310
+ return value;
311
+ };
312
+ // for both arrays and objects. Tries its best to just
313
+ // use the object you hand it, but may return something
314
+ // different if the object you hand it itself needs changing.
315
+ function _adjustTypesFromJSONValue(obj) {
316
+ if (obj === null) {
317
+ return null;
318
+ }
319
+ const maybeChanged = fromJSONValueHelper(obj);
320
+ if (maybeChanged !== obj) {
321
+ return maybeChanged;
322
+ }
323
+ // Other atoms are unchanged.
324
+ if (!(0, utils_1.isObject)(obj)) {
325
+ return obj;
326
+ }
327
+ (0, utils_1.keysOf)(obj).forEach(key => {
328
+ const value = obj[key];
329
+ if ((0, utils_1.isObject)(value)) {
330
+ const changed = fromJSONValueHelper(value);
331
+ if (value !== changed) {
332
+ obj[key] = changed;
333
+ return;
334
+ }
335
+ // if we get here, value is an object but not adjustable
336
+ // at this level. recurse.
337
+ _adjustTypesFromJSONValue(value);
338
+ }
339
+ });
340
+ return obj;
341
+ }
342
+ ;
343
+ /**
344
+ * @summary Deserialize an EJSON value from its plain JSON representation.
345
+ * @locus Anywhere
346
+ * @param {JSONCompatible} val A value to deserialize into EJSON.
347
+ */
348
+ function fromJSONValue(item) {
349
+ let changed = fromJSONValueHelper(item);
350
+ if (changed === item && (0, utils_1.isObject)(item)) {
351
+ changed = clone(item);
352
+ _adjustTypesFromJSONValue(changed);
353
+ }
354
+ return changed;
355
+ }
356
+ ;
357
+ /**
358
+ * @summary Serialize a value to a string. For EJSON values, the serialization
359
+ * fully represents the value. For non-EJSON values, serializes the
360
+ * same way as `JSON.stringify`.
361
+ * @locus Anywhere
362
+ * @param {EJSON} val A value to stringify.
363
+ * @param {Object} [options]
364
+ * @param {Boolean | Integer | String} options.indent Indents objects and
365
+ * arrays for easy readability. When `true`, indents by 2 spaces; when an
366
+ * integer, indents by that number of spaces; and when a string, uses the
367
+ * string as the indentation pattern.
368
+ * @param {Boolean} options.canonical When `true`, stringifies keys in an
369
+ * object in sorted order.
370
+ */
371
+ function stringify(val, opts) {
372
+ return (0, utils_1.handleError)((item, options) => {
373
+ let serialized;
374
+ const json = toJSONValue(item);
375
+ if (options && (options.canonical || options.indent)) {
376
+ serialized = (0, stringify_1.default)(json, options);
377
+ }
378
+ else {
379
+ serialized = JSON.stringify(json);
380
+ }
381
+ return serialized;
382
+ }, val, opts);
383
+ }
384
+ /**
385
+ * @summary Parse a string into an EJSON value. Throws an error if the string
386
+ * is not valid EJSON.
387
+ * @locus Anywhere
388
+ * @param {String} str A string to parse into an EJSON value.
389
+ */
390
+ function parse(item) {
391
+ if (typeof item !== 'string') {
392
+ throw new Error('EJSON.parse argument should be a string');
393
+ }
394
+ return fromJSONValue(JSON.parse(item));
395
+ }
396
+ ;
397
+ /**
398
+ * @summary Returns true if `x` is a buffer of binary data, as returned from
399
+ * [`EJSON.newBinary`](#ejson_new_binary).
400
+ * @param {Object} x The variable to check.
401
+ * @locus Anywhere
402
+ */
403
+ function isBinary(obj) {
404
+ return !!((typeof Uint8Array !== 'undefined' && obj instanceof Uint8Array) ||
405
+ (obj && obj.$Uint8ArrayPolyfill));
406
+ }
407
+ ;
408
+ /**
409
+ * @summary Return true if `a` and `b` are equal to each other. Return false
410
+ * otherwise. Uses the `equals` method on `a` if present, otherwise
411
+ * performs a deep comparison.
412
+ * @locus Anywhere
413
+ * @param {EJSON} a
414
+ * @param {EJSON} b
415
+ * @param {Object} [options]
416
+ * @param {Boolean} options.keyOrderSensitive Compare in key sensitive order,
417
+ * if supported by the JavaScript implementation. For example, `{a: 1, b: 2}`
418
+ * is equal to `{b: 2, a: 1}` only when `keyOrderSensitive` is `false`. The
419
+ * default is `false`.
420
+ */
421
+ function equals(a, b, options) {
422
+ let i;
423
+ const keyOrderSensitive = !!(options && options.keyOrderSensitive);
424
+ if (a === b) {
425
+ return true;
426
+ }
427
+ // This differs from the IEEE spec for NaN equality, b/c we don't want
428
+ // anything ever with a NaN to be poisoned from becoming equal to anything.
429
+ if (Number.isNaN(a) && Number.isNaN(b)) {
430
+ return true;
431
+ }
432
+ // if either one is falsy, they'd have to be === to be equal
433
+ if (!a || !b) {
434
+ return false;
435
+ }
436
+ if (!((0, utils_1.isObject)(a) && (0, utils_1.isObject)(b))) {
437
+ return false;
438
+ }
439
+ if (a instanceof Date && b instanceof Date) {
440
+ return a.valueOf() === b.valueOf();
441
+ }
442
+ if (isBinary(a) && isBinary(b)) {
443
+ if (a.length !== b.length) {
444
+ return false;
445
+ }
446
+ for (i = 0; i < a.length; i++) {
447
+ if (a[i] !== b[i]) {
448
+ return false;
449
+ }
450
+ }
451
+ return true;
452
+ }
453
+ if ((0, utils_1.isFunction)(a.equals)) {
454
+ return a.equals(b, options);
455
+ }
456
+ if ((0, utils_1.isFunction)(b.equals)) {
457
+ return b.equals(a, options);
458
+ }
459
+ // Array.isArray works across iframes while instanceof won't
460
+ const aIsArray = Array.isArray(a);
461
+ const bIsArray = Array.isArray(b);
462
+ // if not both or none are array they are not equal
463
+ if (aIsArray !== bIsArray) {
464
+ return false;
465
+ }
466
+ if (aIsArray && bIsArray) {
467
+ if (a.length !== b.length) {
468
+ return false;
469
+ }
470
+ for (i = 0; i < a.length; i++) {
471
+ if (!equals(a[i], b[i], options)) {
472
+ return false;
473
+ }
474
+ }
475
+ return true;
476
+ }
477
+ // fallback for custom types that don't implement their own equals
478
+ switch (+_isCustomType(a) + +_isCustomType(b)) {
479
+ case 1: return false;
480
+ case 2: return equals(toJSONValue(a), toJSONValue(b));
481
+ default: // Do nothing
482
+ }
483
+ // fall back to structural equality of objects
484
+ let ret;
485
+ const aKeys = (0, utils_1.keysOf)(a);
486
+ const bKeys = (0, utils_1.keysOf)(b);
487
+ if (keyOrderSensitive) {
488
+ i = 0;
489
+ ret = aKeys.every(key => {
490
+ if (i >= bKeys.length) {
491
+ return false;
492
+ }
493
+ if (key !== bKeys[i]) {
494
+ return false;
495
+ }
496
+ if (!equals(a[key], b[bKeys[i]], options)) {
497
+ return false;
498
+ }
499
+ i++;
500
+ return true;
501
+ });
502
+ }
503
+ else {
504
+ i = 0;
505
+ ret = aKeys.every(key => {
506
+ if (!(0, utils_1.hasOwn)(b, key)) {
507
+ return false;
508
+ }
509
+ if (!equals(a[key], b[key], options)) {
510
+ return false;
511
+ }
512
+ i++;
513
+ return true;
514
+ });
515
+ }
516
+ return ret && i === bKeys.length;
517
+ }
518
+ ;
519
+ /**
520
+ * @summary Return a deep copy of `val`.
521
+ * @locus Anywhere
522
+ * @param {EJSON} val A value to copy.
523
+ */
524
+ function clone(v) {
525
+ let ret;
526
+ if (!(0, utils_1.isObject)(v)) {
527
+ return v;
528
+ }
529
+ if (v === null) {
530
+ return null; // null has typeof "object"
531
+ }
532
+ if (v instanceof Date) {
533
+ return new Date(v.getTime());
534
+ }
535
+ // RegExps are not really EJSON elements (eg we don't define a serialization
536
+ // for them), but they're immutable anyway, so we can support them in clone.
537
+ if (v instanceof RegExp) {
538
+ return v;
539
+ }
540
+ if (isBinary(v)) {
541
+ ret = new Uint8Array(v.length);
542
+ for (let i = 0; i < v.length; i++) {
543
+ ret[i] = v[i];
544
+ }
545
+ return ret;
546
+ }
547
+ if (Array.isArray(v)) {
548
+ return v.map(clone);
549
+ }
550
+ if ((0, utils_1.isArguments)(v)) {
551
+ return Array.from(v).map(clone);
552
+ }
553
+ // handle general user-defined typed Objects if they have a clone method
554
+ if ("clone" in v && (0, utils_1.isFunction)(v.clone)) {
555
+ return v.clone();
556
+ }
557
+ // handle other custom types
558
+ if (_isCustomType(v)) {
559
+ return fromJSONValue(clone(toJSONValue(v)));
560
+ }
561
+ // handle other objects
562
+ ret = {};
563
+ (0, utils_1.keysOf)(v).forEach((key) => {
564
+ ret[key] = clone(v[key]);
565
+ });
566
+ return ret;
567
+ }
568
+ ;