mongodb-livedata-server 0.0.4 → 0.0.6

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