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.
- package/dist/livedata_server.d.ts +4 -4
- package/dist/livedata_server.js +11 -11
- package/dist/meteor/binary-heap/max_heap.d.ts +31 -31
- package/dist/meteor/binary-heap/max_heap.js +186 -186
- package/dist/meteor/binary-heap/min_heap.d.ts +6 -6
- package/dist/meteor/binary-heap/min_heap.js +17 -17
- package/dist/meteor/binary-heap/min_max_heap.d.ts +11 -11
- package/dist/meteor/binary-heap/min_max_heap.js +48 -48
- package/dist/meteor/callback-hook/hook.d.ts +11 -11
- package/dist/meteor/callback-hook/hook.js +78 -78
- package/dist/meteor/ddp/crossbar.d.ts +15 -15
- package/dist/meteor/ddp/crossbar.js +136 -136
- package/dist/meteor/ddp/heartbeat.d.ts +19 -19
- package/dist/meteor/ddp/heartbeat.js +77 -77
- package/dist/meteor/ddp/livedata_server.d.ts +141 -142
- package/dist/meteor/ddp/livedata_server.js +403 -403
- package/dist/meteor/ddp/method-invocation.d.ts +35 -35
- package/dist/meteor/ddp/method-invocation.js +72 -72
- package/dist/meteor/ddp/random-stream.d.ts +8 -8
- package/dist/meteor/ddp/random-stream.js +100 -100
- package/dist/meteor/ddp/session-collection-view.d.ts +20 -20
- package/dist/meteor/ddp/session-collection-view.js +106 -106
- package/dist/meteor/ddp/session-document-view.d.ts +8 -8
- package/dist/meteor/ddp/session-document-view.js +82 -82
- package/dist/meteor/ddp/session.d.ts +75 -75
- package/dist/meteor/ddp/session.js +590 -590
- package/dist/meteor/ddp/stream_server.d.ts +20 -21
- package/dist/meteor/ddp/stream_server.js +181 -181
- package/dist/meteor/ddp/subscription.d.ts +94 -94
- package/dist/meteor/ddp/subscription.js +370 -370
- package/dist/meteor/ddp/utils.d.ts +8 -8
- package/dist/meteor/ddp/utils.js +104 -104
- package/dist/meteor/ddp/writefence.d.ts +20 -20
- package/dist/meteor/ddp/writefence.js +111 -111
- package/dist/meteor/diff-sequence/diff.d.ts +17 -17
- package/dist/meteor/diff-sequence/diff.js +257 -257
- package/dist/meteor/ejson/ejson.d.ts +82 -82
- package/dist/meteor/ejson/ejson.js +568 -569
- package/dist/meteor/ejson/stringify.d.ts +2 -2
- package/dist/meteor/ejson/stringify.js +119 -119
- package/dist/meteor/ejson/utils.d.ts +12 -12
- package/dist/meteor/ejson/utils.js +42 -42
- package/dist/meteor/mongo/caching_change_observer.d.ts +16 -16
- package/dist/meteor/mongo/caching_change_observer.js +63 -63
- package/dist/meteor/mongo/doc_fetcher.d.ts +7 -7
- package/dist/meteor/mongo/doc_fetcher.js +53 -53
- package/dist/meteor/mongo/geojson_utils.d.ts +3 -3
- package/dist/meteor/mongo/geojson_utils.js +40 -41
- package/dist/meteor/mongo/live_connection.d.ts +28 -28
- package/dist/meteor/mongo/live_connection.js +264 -264
- package/dist/meteor/mongo/live_cursor.d.ts +25 -25
- package/dist/meteor/mongo/live_cursor.js +60 -60
- package/dist/meteor/mongo/minimongo_common.d.ts +84 -84
- package/dist/meteor/mongo/minimongo_common.js +1998 -1998
- package/dist/meteor/mongo/minimongo_matcher.d.ts +23 -23
- package/dist/meteor/mongo/minimongo_matcher.js +283 -283
- package/dist/meteor/mongo/minimongo_sorter.d.ts +16 -16
- package/dist/meteor/mongo/minimongo_sorter.js +268 -268
- package/dist/meteor/mongo/observe_driver_utils.d.ts +9 -9
- package/dist/meteor/mongo/observe_driver_utils.js +72 -73
- package/dist/meteor/mongo/observe_multiplexer.d.ts +46 -46
- package/dist/meteor/mongo/observe_multiplexer.js +203 -203
- package/dist/meteor/mongo/oplog-observe-driver.d.ts +68 -68
- package/dist/meteor/mongo/oplog-observe-driver.js +918 -918
- package/dist/meteor/mongo/oplog_tailing.d.ts +35 -35
- package/dist/meteor/mongo/oplog_tailing.js +352 -352
- package/dist/meteor/mongo/oplog_v2_converter.d.ts +1 -1
- package/dist/meteor/mongo/oplog_v2_converter.js +125 -126
- package/dist/meteor/mongo/polling_observe_driver.d.ts +30 -30
- package/dist/meteor/mongo/polling_observe_driver.js +216 -221
- package/dist/meteor/mongo/synchronous-cursor.d.ts +17 -17
- package/dist/meteor/mongo/synchronous-cursor.js +261 -261
- package/dist/meteor/mongo/synchronous-queue.d.ts +13 -13
- package/dist/meteor/mongo/synchronous-queue.js +110 -110
- package/dist/meteor/ordered-dict/ordered_dict.d.ts +31 -31
- package/dist/meteor/ordered-dict/ordered_dict.js +198 -198
- package/dist/meteor/random/AbstractRandomGenerator.d.ts +42 -42
- package/dist/meteor/random/AbstractRandomGenerator.js +92 -92
- package/dist/meteor/random/AleaRandomGenerator.d.ts +13 -13
- package/dist/meteor/random/AleaRandomGenerator.js +90 -90
- package/dist/meteor/random/NodeRandomGenerator.d.ts +16 -16
- package/dist/meteor/random/NodeRandomGenerator.js +42 -42
- package/dist/meteor/random/createAleaGenerator.d.ts +2 -2
- package/dist/meteor/random/createAleaGenerator.js +32 -32
- package/dist/meteor/random/createRandom.d.ts +1 -1
- package/dist/meteor/random/createRandom.js +22 -22
- package/dist/meteor/random/main.d.ts +1 -1
- package/dist/meteor/random/main.js +12 -12
- package/dist/meteor/types.d.ts +1 -1
- package/dist/meteor/types.js +2 -2
- 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.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
* @
|
|
24
|
-
* @
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
*
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
* @
|
|
31
|
-
* @
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
*
|
|
35
|
-
* @
|
|
36
|
-
* @
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
* @
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
* @
|
|
43
|
-
* @
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
* @
|
|
47
|
-
* @
|
|
48
|
-
* @
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
return
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
return
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
},
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
return
|
|
173
|
-
},
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
//
|
|
244
|
-
if (
|
|
245
|
-
return
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
(
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
;
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
;
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
* @
|
|
359
|
-
*
|
|
360
|
-
*
|
|
361
|
-
*
|
|
362
|
-
*
|
|
363
|
-
*
|
|
364
|
-
* @param {Boolean} options.
|
|
365
|
-
*
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
* @
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
;
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
* @
|
|
399
|
-
*
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
*
|
|
410
|
-
*
|
|
411
|
-
*
|
|
412
|
-
* @
|
|
413
|
-
* @param {EJSON}
|
|
414
|
-
* @param {
|
|
415
|
-
* @param {
|
|
416
|
-
*
|
|
417
|
-
*
|
|
418
|
-
*
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
//
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
if
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
const
|
|
461
|
-
|
|
462
|
-
if
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
case
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
const
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
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
|
-
|
|
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
|
+
;
|