squint-cljs 0.14.200 → 0.14.202
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/lib/cli.js +108 -108
- package/lib/cljs.pprint.js +260 -260
- package/lib/compiler.js +1333 -1290
- package/lib/compiler.node.js +45 -45
- package/lib/compiler.sci.js +1277 -1276
- package/lib/node.nrepl_server.js +29 -29
- package/lib/squint.core.umd.js +3 -3
- package/package.json +1 -1
- package/src/squint/core.js +415 -97
- package/src/squint/multi.js +65 -8
- package/src/squint/string.js +22 -5
package/src/squint/core.js
CHANGED
|
@@ -65,6 +65,16 @@ function dequal(foo, bar) {
|
|
|
65
65
|
return true;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
// A plain object and a js/Map are both map reps; compare by entries.
|
|
69
|
+
// Same-type pairs skip this and keep their fast paths below.
|
|
70
|
+
if (isMapLike(foo) && isMapLike(bar) && foo.constructor !== bar.constructor) {
|
|
71
|
+
if (mapCount(foo) !== mapCount(bar)) return false;
|
|
72
|
+
for (const k of foo instanceof Map ? foo.keys() : Object.keys(foo)) {
|
|
73
|
+
if (!mapHas(bar, k) || !dequal(mapGet(foo, k), mapGet(bar, k))) return false;
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
|
|
68
78
|
// Sets (hash or sorted) compare by elements, across concrete types.
|
|
69
79
|
if (isSetLike(foo) || isSetLike(bar)) {
|
|
70
80
|
if (!isSetLike(foo) || !isSetLike(bar) || foo.size !== bar.size) return false;
|
|
@@ -80,6 +90,8 @@ function dequal(foo, bar) {
|
|
|
80
90
|
|
|
81
91
|
if (foo && bar && (ctor = foo.constructor) === bar.constructor) {
|
|
82
92
|
if (ctor === Date) return foo.getTime() === bar.getTime();
|
|
93
|
+
// regexes only compare by identity, like CLJS
|
|
94
|
+
if (ctor === RegExp) return false;
|
|
83
95
|
|
|
84
96
|
if (ctor === Array) {
|
|
85
97
|
if ((len = foo.length) === bar.length) {
|
|
@@ -211,8 +223,23 @@ function getAssocMut(m) {
|
|
|
211
223
|
}
|
|
212
224
|
}
|
|
213
225
|
|
|
226
|
+
function validateArrayKeys(o, k, kvs) {
|
|
227
|
+
// like CLJS: a vector key is an index in [0, count], count appends
|
|
228
|
+
let len = o.length;
|
|
229
|
+
for (let i = 0; i < kvs.length + 2; i += 2) {
|
|
230
|
+
const key = i === 0 ? k : kvs[i - 2];
|
|
231
|
+
if (!Number.isInteger(key)) {
|
|
232
|
+
throw new Error("Vector's key for assoc must be a number.");
|
|
233
|
+
}
|
|
234
|
+
if (key < 0 || key > len) {
|
|
235
|
+
throw new Error(`Index ${key} out of bounds [0,${len}]`);
|
|
236
|
+
}
|
|
237
|
+
if (key === len) len++;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
214
241
|
export function assoc_BANG_(m, k, v, ...kvs) {
|
|
215
|
-
if (kvs.length % 2 !== 0) {
|
|
242
|
+
if (arguments.length < 3 || kvs.length % 2 !== 0) {
|
|
216
243
|
throw new Error('Illegal argument: assoc expects an odd number of arguments.');
|
|
217
244
|
}
|
|
218
245
|
switch (typeConst(m)) {
|
|
@@ -224,6 +251,13 @@ export function assoc_BANG_(m, k, v, ...kvs) {
|
|
|
224
251
|
}
|
|
225
252
|
break;
|
|
226
253
|
case ARRAY_TYPE:
|
|
254
|
+
validateArrayKeys(m, k, kvs);
|
|
255
|
+
m[k] = v;
|
|
256
|
+
|
|
257
|
+
for (let i = 0; i < kvs.length; i += 2) {
|
|
258
|
+
m[kvs[i]] = kvs[i + 1];
|
|
259
|
+
}
|
|
260
|
+
break;
|
|
227
261
|
case OBJECT_TYPE:
|
|
228
262
|
m[k] = v;
|
|
229
263
|
|
|
@@ -272,7 +306,11 @@ function copy(o) {
|
|
|
272
306
|
}
|
|
273
307
|
|
|
274
308
|
export function assoc(o, k, v, ...kvs) {
|
|
275
|
-
if (
|
|
309
|
+
if (arguments.length < 3 || kvs.length % 2 !== 0) {
|
|
310
|
+
throw new Error('Illegal argument: assoc expects an odd number of arguments.');
|
|
311
|
+
}
|
|
312
|
+
// only nil puns to an empty map; assoc on false throws, like CLJS
|
|
313
|
+
if (o == null) {
|
|
276
314
|
o = {};
|
|
277
315
|
}
|
|
278
316
|
const ret = copy(o);
|
|
@@ -283,6 +321,9 @@ export function assoc(o, k, v, ...kvs) {
|
|
|
283
321
|
// squint has no distinct hash-map or array-map type; both build a plain object.
|
|
284
322
|
export function hash_map(...kvs) {
|
|
285
323
|
if (kvs.length === 0) return {};
|
|
324
|
+
if (kvs.length % 2 !== 0) {
|
|
325
|
+
throw new Error('No value supplied for key: ' + kvs[kvs.length - 1]);
|
|
326
|
+
}
|
|
286
327
|
return assoc({}, ...kvs);
|
|
287
328
|
}
|
|
288
329
|
|
|
@@ -444,6 +485,10 @@ export function conj_BANG_(...xs) {
|
|
|
444
485
|
if (n === 0) {
|
|
445
486
|
return vector();
|
|
446
487
|
}
|
|
488
|
+
// single arg: return the coll unchanged, including nil, like CLJS
|
|
489
|
+
if (n === 1) {
|
|
490
|
+
return xs[0];
|
|
491
|
+
}
|
|
447
492
|
|
|
448
493
|
let o = xs[0];
|
|
449
494
|
if (o === null || o === undefined) {
|
|
@@ -477,17 +522,14 @@ export function conj_BANG_(...xs) {
|
|
|
477
522
|
break;
|
|
478
523
|
case MAP_TYPE:
|
|
479
524
|
for (const x of rest) {
|
|
480
|
-
if (
|
|
481
|
-
|
|
482
|
-
o.set(kv[0], kv[1]);
|
|
483
|
-
});
|
|
484
|
-
else o.set(x[0], x[1]);
|
|
525
|
+
if (isVectorArray(x)) { asMapEntry(x); o.set(x[0], x[1]); }
|
|
526
|
+
else for (const kv of mapEntriesOf(x)) o.set(kv[0], kv[1]);
|
|
485
527
|
}
|
|
486
528
|
break;
|
|
487
529
|
case OBJECT_TYPE:
|
|
488
530
|
for (const x of rest) {
|
|
489
|
-
if (
|
|
490
|
-
else o[
|
|
531
|
+
if (isVectorArray(x)) { asMapEntry(x); o[x[0]] = x[1]; }
|
|
532
|
+
else for (const kv of mapEntriesOf(x)) o[kv[0]] = kv[1];
|
|
491
533
|
}
|
|
492
534
|
break;
|
|
493
535
|
default:
|
|
@@ -499,6 +541,28 @@ export function conj_BANG_(...xs) {
|
|
|
499
541
|
return o;
|
|
500
542
|
}
|
|
501
543
|
|
|
544
|
+
// entries carried by a non-entry conj arg onto a map: a map merges, a
|
|
545
|
+
// seqable must contain entry vectors, like CLJS
|
|
546
|
+
function* mapEntriesOf(x) {
|
|
547
|
+
if (isMapLike(x)) {
|
|
548
|
+
yield* iterable(x);
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
for (const kv of iterable(x)) {
|
|
552
|
+
if (!isVectorArray(kv)) {
|
|
553
|
+
throw new Error('conj on a map takes map entries or seqables of map entries');
|
|
554
|
+
}
|
|
555
|
+
yield kv;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
function asMapEntry(x) {
|
|
560
|
+
if (x.length < 2) {
|
|
561
|
+
throw new Error('Vector arg to map conj must be a pair');
|
|
562
|
+
}
|
|
563
|
+
return x;
|
|
564
|
+
}
|
|
565
|
+
|
|
502
566
|
export function conj(...xs) {
|
|
503
567
|
if (xs.length === 0) {
|
|
504
568
|
return vector();
|
|
@@ -530,11 +594,8 @@ export function conj(...xs) {
|
|
|
530
594
|
case MAP_TYPE:
|
|
531
595
|
m = new Map(o);
|
|
532
596
|
for (const x of rest) {
|
|
533
|
-
if (
|
|
534
|
-
|
|
535
|
-
m.set(kv[0], kv[1]);
|
|
536
|
-
});
|
|
537
|
-
else m.set(x[0], x[1]);
|
|
597
|
+
if (isVectorArray(x)) { asMapEntry(x); m.set(x[0], x[1]); }
|
|
598
|
+
else for (const kv of mapEntriesOf(x)) m.set(kv[0], kv[1]);
|
|
538
599
|
}
|
|
539
600
|
|
|
540
601
|
return copyMeta(o, m);
|
|
@@ -547,8 +608,8 @@ export function conj(...xs) {
|
|
|
547
608
|
o2 = { ...o };
|
|
548
609
|
|
|
549
610
|
for (const x of rest) {
|
|
550
|
-
if (
|
|
551
|
-
else o2[
|
|
611
|
+
if (isVectorArray(x)) { asMapEntry(x); o2[x[0]] = x[1]; }
|
|
612
|
+
else for (const kv of mapEntriesOf(x)) o2[kv[0]] = kv[1];
|
|
552
613
|
}
|
|
553
614
|
|
|
554
615
|
return copyMeta(o, o2);
|
|
@@ -570,7 +631,7 @@ export function disj(s, ...xs) {
|
|
|
570
631
|
if (s == null) return s;
|
|
571
632
|
// pass s itself (not a spread) so a SortedSet keeps its comparator
|
|
572
633
|
const s1 = new s.constructor(s);
|
|
573
|
-
return disj_BANG_(s1, ...xs);
|
|
634
|
+
return copyMeta(s, disj_BANG_(s1, ...xs));
|
|
574
635
|
}
|
|
575
636
|
|
|
576
637
|
export function contains_QMARK_(coll, v) {
|
|
@@ -599,7 +660,11 @@ export function dissoc_BANG_(m, ...ks) {
|
|
|
599
660
|
export function dissoc(m, ...ks) {
|
|
600
661
|
if (!m) return;
|
|
601
662
|
if (ks.length === 0) return m;
|
|
602
|
-
|
|
663
|
+
const tc = typeConst(m);
|
|
664
|
+
if (tc !== MAP_TYPE && tc !== OBJECT_TYPE) {
|
|
665
|
+
throw new Error('dissoc expects a map, got: ' + typeof m);
|
|
666
|
+
}
|
|
667
|
+
if (tc === MAP_TYPE) {
|
|
603
668
|
let present = false;
|
|
604
669
|
for (const k of ks) if (m.has(k)) { present = true; break; }
|
|
605
670
|
if (!present) return m;
|
|
@@ -641,6 +706,9 @@ export function pr(...xs) {
|
|
|
641
706
|
}
|
|
642
707
|
|
|
643
708
|
export function nth(coll, idx, orElse) {
|
|
709
|
+
if (typeof idx !== 'number') {
|
|
710
|
+
throw new Error('Index argument to nth must be a number');
|
|
711
|
+
}
|
|
644
712
|
const hasDefault = arguments.length > 2;
|
|
645
713
|
// nil coll puns to nil, like Clojure
|
|
646
714
|
if (coll == null) return hasDefault ? orElse : null;
|
|
@@ -727,7 +795,8 @@ export function seqable_QMARK_(x) {
|
|
|
727
795
|
object_QMARK_(x) ||
|
|
728
796
|
// we used to check instanceof Object but this returns false for TC39 Records
|
|
729
797
|
// also we used to write `Symbol.iterator in` but this does not work for strings and some other types
|
|
730
|
-
!!x[Symbol.iterator]
|
|
798
|
+
!!x[Symbol.iterator] ||
|
|
799
|
+
!!x[ISEQABLE_SYM]
|
|
731
800
|
);
|
|
732
801
|
}
|
|
733
802
|
|
|
@@ -757,6 +826,8 @@ export function iterable(x) {
|
|
|
757
826
|
if (x[Symbol.iterator]) {
|
|
758
827
|
return x;
|
|
759
828
|
}
|
|
829
|
+
// a type extended to ISeqable seqs through its -seq method
|
|
830
|
+
if (x[ISeqable__seq] !== undefined) return iterable(x[ISeqable__seq](x));
|
|
760
831
|
if (x instanceof Object) return Object.entries(x).map(tagMapEntry);
|
|
761
832
|
throw new TypeError(`${x} is not iterable`);
|
|
762
833
|
}
|
|
@@ -773,6 +844,7 @@ export const es6_iterator = _iterator;
|
|
|
773
844
|
|
|
774
845
|
export function seq(x) {
|
|
775
846
|
if (x == null) return x;
|
|
847
|
+
if (!seqable_QMARK_(x)) throw new TypeError(x + ' is not ISeqable');
|
|
776
848
|
// a string seqs into its characters, like CLJS.
|
|
777
849
|
if (typeof x === 'string') return x.length ? [...x] : null;
|
|
778
850
|
const iter = iterable(x);
|
|
@@ -833,13 +905,13 @@ export function rest(coll) {
|
|
|
833
905
|
return cell._rest; // first chunk had one element; the next cell is the rest
|
|
834
906
|
}
|
|
835
907
|
|
|
908
|
+
const REDUCED_DEREF = (self) => self.value;
|
|
909
|
+
|
|
836
910
|
class Reduced {
|
|
837
911
|
value;
|
|
838
912
|
constructor(x) {
|
|
839
913
|
this.value = x;
|
|
840
|
-
|
|
841
|
-
_deref() {
|
|
842
|
-
return this.value;
|
|
914
|
+
this[IDeref__deref] = REDUCED_DEREF;
|
|
843
915
|
}
|
|
844
916
|
}
|
|
845
917
|
|
|
@@ -1128,6 +1200,8 @@ class Cons {
|
|
|
1128
1200
|
);
|
|
1129
1201
|
|
|
1130
1202
|
export function cons(x, coll) {
|
|
1203
|
+
// like CLJS cons, which seqs a non-ISeq tail
|
|
1204
|
+
if (!seqable_QMARK_(coll)) throw new TypeError(coll + ' is not ISeqable');
|
|
1131
1205
|
return new Cons(x, coll);
|
|
1132
1206
|
}
|
|
1133
1207
|
|
|
@@ -1291,48 +1365,179 @@ export function nil_QMARK_(v) {
|
|
|
1291
1365
|
|
|
1292
1366
|
export const PROTOCOL_SENTINEL = {};
|
|
1293
1367
|
|
|
1368
|
+
// marker protocols so (satisfies? IAtom x) works, like CLJS. Marked in the
|
|
1369
|
+
// constructor, not on the prototype, so no top-level mutation pins Atom
|
|
1370
|
+
// into bundles that do not use it.
|
|
1371
|
+
const IATOM_SYM = Symbol('squint.core.IAtom');
|
|
1372
|
+
const IDEREF_SYM = Symbol('squint.core.IDeref');
|
|
1373
|
+
const ISEQABLE_SYM = Symbol('squint.core.ISeqable');
|
|
1374
|
+
export const IAtom = { __sym: IATOM_SYM };
|
|
1375
|
+
export const IDeref = { __sym: IDEREF_SYM };
|
|
1376
|
+
// method slot for (-deref x), named like the defprotocol emission so
|
|
1377
|
+
// (extend-type T IDeref (-deref [x] ...)) fills it
|
|
1378
|
+
export const IDeref__deref = Symbol('IDeref_-deref');
|
|
1379
|
+
export function _deref(o) {
|
|
1380
|
+
if (o != null && o[IDeref__deref] !== undefined) return o[IDeref__deref](o);
|
|
1381
|
+
return nilImpl(_deref, 'IDeref.-deref', o)(o);
|
|
1382
|
+
}
|
|
1383
|
+
export const ISeqable = { __sym: ISEQABLE_SYM };
|
|
1384
|
+
export const ISeqable__seq = Symbol('ISeqable_-seq');
|
|
1385
|
+
export function _seq(o) {
|
|
1386
|
+
if (o != null && o[ISeqable__seq] !== undefined) return o[ISeqable__seq](o);
|
|
1387
|
+
return nilImpl(_seq, 'ISeqable.-seq', o)(o);
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
// an extend-type on nil stores the impl on the dispatch fn under null,
|
|
1391
|
+
// the same convention the generated protocol dispatch fns use
|
|
1392
|
+
function nilImpl(dispatchFn, protoMethod, o) {
|
|
1393
|
+
const f = dispatchFn[null];
|
|
1394
|
+
if (f === undefined) throw missing_protocol(protoMethod, o);
|
|
1395
|
+
return f;
|
|
1396
|
+
}
|
|
1397
|
+
export const IReset = { __sym: Symbol('squint.core.IReset') };
|
|
1398
|
+
export const IReset__reset_BANG_ = Symbol('IReset_-reset!');
|
|
1399
|
+
export function _reset_BANG_(o, v) {
|
|
1400
|
+
if (o != null && o[IReset__reset_BANG_] !== undefined) return o[IReset__reset_BANG_](o, v);
|
|
1401
|
+
return nilImpl(_reset_BANG_, 'IReset.-reset!', o)(o, v);
|
|
1402
|
+
}
|
|
1403
|
+
export const ISwap = { __sym: Symbol('squint.core.ISwap') };
|
|
1404
|
+
export const ISwap__swap_BANG_ = Symbol('ISwap_-swap!');
|
|
1405
|
+
export function _swap_BANG_(o, f, ...args) {
|
|
1406
|
+
if (o != null && o[ISwap__swap_BANG_] !== undefined) return o[ISwap__swap_BANG_](o, f, ...args);
|
|
1407
|
+
return nilImpl(_swap_BANG_, 'ISwap.-swap!', o)(o, f, ...args);
|
|
1408
|
+
}
|
|
1409
|
+
export const IWatchable = { __sym: Symbol('squint.core.IWatchable') };
|
|
1410
|
+
export const IWatchable__add_watch = Symbol('IWatchable_-add-watch');
|
|
1411
|
+
export const IWatchable__remove_watch = Symbol('IWatchable_-remove-watch');
|
|
1412
|
+
export const IWatchable__notify_watches = Symbol('IWatchable_-notify-watches');
|
|
1413
|
+
export function _add_watch(o, k, f) {
|
|
1414
|
+
if (o != null && o[IWatchable__add_watch] !== undefined) return o[IWatchable__add_watch](o, k, f);
|
|
1415
|
+
return nilImpl(_add_watch, 'IWatchable.-add-watch', o)(o, k, f);
|
|
1416
|
+
}
|
|
1417
|
+
export function _remove_watch(o, k) {
|
|
1418
|
+
if (o != null && o[IWatchable__remove_watch] !== undefined) return o[IWatchable__remove_watch](o, k);
|
|
1419
|
+
return nilImpl(_remove_watch, 'IWatchable.-remove-watch', o)(o, k);
|
|
1420
|
+
}
|
|
1421
|
+
export function _notify_watches(o, oldv, newv) {
|
|
1422
|
+
if (o != null && o[IWatchable__notify_watches] !== undefined) return o[IWatchable__notify_watches](o, oldv, newv);
|
|
1423
|
+
return nilImpl(_notify_watches, 'IWatchable.-notify-watches', o)(o, oldv, newv);
|
|
1424
|
+
}
|
|
1425
|
+
|
|
1426
|
+
// shared protocol impls: one fn per operation, a pointer per instance
|
|
1427
|
+
const ATOM_DEREF = (self) => self.val;
|
|
1428
|
+
const ATOM_RESET = (self, x) => {
|
|
1429
|
+
if (self._validator && !truth_(self._validator(x))) {
|
|
1430
|
+
throw new Error('Validator rejected reference state');
|
|
1431
|
+
}
|
|
1432
|
+
const old_val = self.val;
|
|
1433
|
+
self.val = x;
|
|
1434
|
+
if (self._hasWatches) {
|
|
1435
|
+
for (const [k, f] of Object.entries(self._watches)) f(k, self, old_val, x);
|
|
1436
|
+
}
|
|
1437
|
+
return x;
|
|
1438
|
+
};
|
|
1439
|
+
const ATOM_SWAP = function (self, f, a, b, xs) {
|
|
1440
|
+
switch (arguments.length) {
|
|
1441
|
+
case 2:
|
|
1442
|
+
return ATOM_RESET(self, f(self.val));
|
|
1443
|
+
case 3:
|
|
1444
|
+
return ATOM_RESET(self, f(self.val, a));
|
|
1445
|
+
case 4:
|
|
1446
|
+
return ATOM_RESET(self, f(self.val, a, b));
|
|
1447
|
+
default:
|
|
1448
|
+
return ATOM_RESET(self, f(self.val, a, b, ...xs));
|
|
1449
|
+
}
|
|
1450
|
+
};
|
|
1451
|
+
const ATOM_ADD_WATCH = (self, k, f) => {
|
|
1452
|
+
self._watches[k] = f;
|
|
1453
|
+
self._hasWatches = true;
|
|
1454
|
+
};
|
|
1455
|
+
const ATOM_REMOVE_WATCH = (self, k) => {
|
|
1456
|
+
delete self._watches[k];
|
|
1457
|
+
};
|
|
1458
|
+
const ATOM_NOTIFY = (self, oldv, newv) => {
|
|
1459
|
+
for (const [k, f] of Object.entries(self._watches)) f(k, self, oldv, newv);
|
|
1460
|
+
};
|
|
1461
|
+
|
|
1294
1462
|
export class Atom {
|
|
1295
1463
|
constructor(init) {
|
|
1296
1464
|
this.val = init;
|
|
1297
1465
|
this._watches = {};
|
|
1298
|
-
this._deref = () => this.val;
|
|
1299
1466
|
this._hasWatches = false;
|
|
1300
|
-
this
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1467
|
+
this[IATOM_SYM] = true;
|
|
1468
|
+
this[IDEREF_SYM] = true;
|
|
1469
|
+
this[IDeref__deref] = ATOM_DEREF;
|
|
1470
|
+
this[IReset.__sym] = true;
|
|
1471
|
+
this[IReset__reset_BANG_] = ATOM_RESET;
|
|
1472
|
+
this[ISwap.__sym] = true;
|
|
1473
|
+
this[ISwap__swap_BANG_] = ATOM_SWAP;
|
|
1474
|
+
this[IWatchable.__sym] = true;
|
|
1475
|
+
this[IWatchable__add_watch] = ATOM_ADD_WATCH;
|
|
1476
|
+
this[IWatchable__remove_watch] = ATOM_REMOVE_WATCH;
|
|
1477
|
+
this[IWatchable__notify_watches] = ATOM_NOTIFY;
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
export function atom(init, ...opts) {
|
|
1482
|
+
const a = new Atom(init);
|
|
1483
|
+
for (let i = 0; i < opts.length; i += 2) {
|
|
1484
|
+
if (opts[i] === 'meta') a[_metaSym] = opts[i + 1];
|
|
1485
|
+
else if (opts[i] === 'validator') a._validator = opts[i + 1];
|
|
1486
|
+
}
|
|
1487
|
+
return a;
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
export function get_validator(ref) {
|
|
1491
|
+
return ref._validator ?? null;
|
|
1492
|
+
}
|
|
1493
|
+
|
|
1494
|
+
export function set_validator_BANG_(ref, f) {
|
|
1495
|
+
if (f != null && !truth_(f(deref(ref)))) {
|
|
1496
|
+
throw new Error('Validator rejected reference state');
|
|
1319
1497
|
}
|
|
1498
|
+
ref._validator = f;
|
|
1499
|
+
return null;
|
|
1320
1500
|
}
|
|
1321
1501
|
|
|
1322
|
-
|
|
1323
|
-
|
|
1502
|
+
// the CLJS missing-protocol error, used by every protocol dispatch miss
|
|
1503
|
+
export function missing_protocol(proto, obj) {
|
|
1504
|
+
let ty;
|
|
1505
|
+
if (obj === null) ty = 'null';
|
|
1506
|
+
else if (obj === undefined) ty = 'undefined';
|
|
1507
|
+
else if (Array.isArray(obj)) ty = 'array';
|
|
1508
|
+
else if (typeof obj === 'object' && obj.constructor && obj.constructor !== Object) {
|
|
1509
|
+
ty = obj.constructor.name;
|
|
1510
|
+
} else ty = typeof obj;
|
|
1511
|
+
return new Error(
|
|
1512
|
+
`No protocol method ${proto} defined for type ${ty}: ${obj ?? ''}`
|
|
1513
|
+
);
|
|
1324
1514
|
}
|
|
1325
1515
|
|
|
1326
1516
|
export function deref(ref) {
|
|
1327
|
-
return ref
|
|
1517
|
+
if (ref?.[IDeref__deref] !== undefined) return ref[IDeref__deref](ref);
|
|
1518
|
+
return nilImpl(_deref, 'IDeref.-deref', ref)(ref);
|
|
1328
1519
|
}
|
|
1329
1520
|
|
|
1330
1521
|
export function reset_BANG_(atm, v) {
|
|
1331
|
-
atm
|
|
1522
|
+
if (atm?.[IReset__reset_BANG_] !== undefined) return atm[IReset__reset_BANG_](atm, v);
|
|
1523
|
+
return nilImpl(_reset_BANG_, 'IReset.-reset!', atm)(atm, v);
|
|
1332
1524
|
}
|
|
1333
1525
|
|
|
1334
1526
|
export function swap_BANG_(atm, f, ...args) {
|
|
1335
1527
|
f = __toFn(f);
|
|
1528
|
+
if (atm?.[ISwap__swap_BANG_] !== undefined) {
|
|
1529
|
+
// the CLJS -swap! contract: up to two positional args, the rest packed
|
|
1530
|
+
switch (args.length) {
|
|
1531
|
+
case 0:
|
|
1532
|
+
return atm[ISwap__swap_BANG_](atm, f);
|
|
1533
|
+
case 1:
|
|
1534
|
+
return atm[ISwap__swap_BANG_](atm, f, args[0]);
|
|
1535
|
+
case 2:
|
|
1536
|
+
return atm[ISwap__swap_BANG_](atm, f, args[0], args[1]);
|
|
1537
|
+
default:
|
|
1538
|
+
return atm[ISwap__swap_BANG_](atm, f, args[0], args[1], args.slice(2));
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1336
1541
|
const v = f(deref(atm), ...args);
|
|
1337
1542
|
reset_BANG_(atm, v);
|
|
1338
1543
|
return v;
|
|
@@ -1342,19 +1547,19 @@ export function swap_vals_BANG_(atm, f, ...args) {
|
|
|
1342
1547
|
const oldv = deref(atm);
|
|
1343
1548
|
f = __toFn(f);
|
|
1344
1549
|
const newv = f(oldv, ...args);
|
|
1345
|
-
atm
|
|
1550
|
+
reset_BANG_(atm, newv);
|
|
1346
1551
|
return [oldv, newv];
|
|
1347
1552
|
}
|
|
1348
1553
|
|
|
1349
1554
|
export function reset_vals_BANG_(atm, newv) {
|
|
1350
1555
|
const oldv = deref(atm);
|
|
1351
|
-
atm
|
|
1556
|
+
reset_BANG_(atm, newv);
|
|
1352
1557
|
return [oldv, newv];
|
|
1353
1558
|
}
|
|
1354
1559
|
|
|
1355
1560
|
export function compare_and_set_BANG_(atm, oldv, newv) {
|
|
1356
1561
|
if (deref(atm) === oldv) {
|
|
1357
|
-
atm
|
|
1562
|
+
reset_BANG_(atm, newv);
|
|
1358
1563
|
return true;
|
|
1359
1564
|
} else {
|
|
1360
1565
|
return false;
|
|
@@ -1519,6 +1724,18 @@ export function set_QMARK_(x) {
|
|
|
1519
1724
|
return typeConst(x) === SET_TYPE;
|
|
1520
1725
|
}
|
|
1521
1726
|
|
|
1727
|
+
export function hash_set(...xs) {
|
|
1728
|
+
return new Set(xs);
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1731
|
+
export function sorted_QMARK_(x) {
|
|
1732
|
+
return x != null && x[SORTED_TAG] === true;
|
|
1733
|
+
}
|
|
1734
|
+
|
|
1735
|
+
export function char_QMARK_(x) {
|
|
1736
|
+
return typeof x === 'string' && x.length === 1;
|
|
1737
|
+
}
|
|
1738
|
+
|
|
1522
1739
|
export function apply(f, ...args) {
|
|
1523
1740
|
f = __toFn(f);
|
|
1524
1741
|
const xs = args.slice(0, args.length - 1);
|
|
@@ -1697,9 +1914,10 @@ export function interpose(sep, coll) {
|
|
|
1697
1914
|
|
|
1698
1915
|
export function select_keys(o, ks) {
|
|
1699
1916
|
const type = typeConst(o);
|
|
1700
|
-
//
|
|
1701
|
-
const ret =
|
|
1702
|
-
|
|
1917
|
+
// always a map, like CLJS; a js/Map source keeps its rep
|
|
1918
|
+
const ret = type === MAP_TYPE ? new Map() : {};
|
|
1919
|
+
// iterable puns nil to no keys and a map to its entries, like CLJS seq
|
|
1920
|
+
for (const k of iterable(ks)) {
|
|
1703
1921
|
const v = get(o, k);
|
|
1704
1922
|
if (v !== undefined) {
|
|
1705
1923
|
assoc_BANG_(ret, k, v);
|
|
@@ -1892,10 +2110,13 @@ export function partition_by(f, coll) {
|
|
|
1892
2110
|
export function empty(coll) {
|
|
1893
2111
|
const type = typeConst(coll);
|
|
1894
2112
|
if (type != null) {
|
|
2113
|
+
// a class instance is not an emptyable collection, like CLJS;
|
|
2114
|
+
// a plain or null-prototype object still empties to {}
|
|
2115
|
+
if (type === OBJECT_TYPE && coll.constructor !== undefined && coll.constructor !== Object) return null;
|
|
1895
2116
|
return copyMeta(coll, emptyOfType(type));
|
|
1896
|
-
} else {
|
|
1897
|
-
throw new Error(`Can't create empty of ${typeof coll}`);
|
|
1898
2117
|
}
|
|
2118
|
+
// non-collections give nil, like CLJS
|
|
2119
|
+
return null;
|
|
1899
2120
|
}
|
|
1900
2121
|
|
|
1901
2122
|
export function merge(...args) {
|
|
@@ -1906,6 +2127,9 @@ export function merge(...args) {
|
|
|
1906
2127
|
let obj;
|
|
1907
2128
|
if (firstArg === null || firstArg === undefined) {
|
|
1908
2129
|
obj = {};
|
|
2130
|
+
} else if (typeConst(firstArg) === undefined) {
|
|
2131
|
+
// a non-collection passes through; conj! throws when maps follow, like CLJS
|
|
2132
|
+
obj = firstArg;
|
|
1909
2133
|
} else {
|
|
1910
2134
|
obj = into(empty(firstArg), firstArg);
|
|
1911
2135
|
}
|
|
@@ -2023,7 +2247,15 @@ function take1(n) {
|
|
|
2023
2247
|
});
|
|
2024
2248
|
}
|
|
2025
2249
|
|
|
2250
|
+
function assertNumber(n) {
|
|
2251
|
+
if (typeof n !== 'number') {
|
|
2252
|
+
throw new Error('Assert failed: (number? n)');
|
|
2253
|
+
}
|
|
2254
|
+
return n;
|
|
2255
|
+
}
|
|
2256
|
+
|
|
2026
2257
|
export function take(n, coll) {
|
|
2258
|
+
assertNumber(n);
|
|
2027
2259
|
if (arguments.length === 1) {
|
|
2028
2260
|
return take1(n);
|
|
2029
2261
|
}
|
|
@@ -2041,6 +2273,7 @@ export function take(n, coll) {
|
|
|
2041
2273
|
}
|
|
2042
2274
|
|
|
2043
2275
|
export function take_last(n, coll) {
|
|
2276
|
+
assertNumber(n);
|
|
2044
2277
|
if (n <= 0) {
|
|
2045
2278
|
return null;
|
|
2046
2279
|
}
|
|
@@ -2089,6 +2322,7 @@ function take_nth1(n) {
|
|
|
2089
2322
|
}
|
|
2090
2323
|
|
|
2091
2324
|
export function take_nth(n, coll) {
|
|
2325
|
+
assertNumber(n);
|
|
2092
2326
|
if (arguments.length === 1) return take_nth1(n);
|
|
2093
2327
|
if (n <= 0) {
|
|
2094
2328
|
return repeat(first(coll));
|
|
@@ -2113,8 +2347,18 @@ export function partial(f, ...xs) {
|
|
|
2113
2347
|
}
|
|
2114
2348
|
|
|
2115
2349
|
export function cycle(coll) {
|
|
2350
|
+
// seq the coll eagerly: nil or empty cycles to an empty seq and a
|
|
2351
|
+
// non-iterable throws, like the seq call in CLJS cycle. The first lap
|
|
2352
|
+
// is cached and replayed, like the retained seq in CLJS Cycle, so a
|
|
2353
|
+
// one-shot iterator source cycles instead of ending after one lap.
|
|
2354
|
+
const it = iterable(coll);
|
|
2116
2355
|
return lazy(function* () {
|
|
2117
|
-
|
|
2356
|
+
const cache = [];
|
|
2357
|
+
for (const x of it) {
|
|
2358
|
+
cache.push(x);
|
|
2359
|
+
yield x;
|
|
2360
|
+
}
|
|
2361
|
+
while (cache.length) yield* cache;
|
|
2118
2362
|
});
|
|
2119
2363
|
}
|
|
2120
2364
|
|
|
@@ -2126,6 +2370,7 @@ function drop1(n) {
|
|
|
2126
2370
|
}
|
|
2127
2371
|
|
|
2128
2372
|
export function drop(n, xs) {
|
|
2373
|
+
assertNumber(n);
|
|
2129
2374
|
if (arguments.length === 1) return drop1(n);
|
|
2130
2375
|
return lazyIter(xs, function* (iter) {
|
|
2131
2376
|
for (let x = 0; x < n; x++) {
|
|
@@ -2220,7 +2465,8 @@ export function update(coll, k, f, ...args) {
|
|
|
2220
2465
|
|
|
2221
2466
|
export function get_in(coll, path, orElse) {
|
|
2222
2467
|
let entry = coll;
|
|
2223
|
-
|
|
2468
|
+
// iterable puns a nil path to an empty path, like CLJS
|
|
2469
|
+
for (const item of iterable(path)) {
|
|
2224
2470
|
entry = get(entry, item);
|
|
2225
2471
|
}
|
|
2226
2472
|
if (entry === undefined) return orElse;
|
|
@@ -2285,6 +2531,18 @@ export function reverse(coll) {
|
|
|
2285
2531
|
return toArray(coll).reverse();
|
|
2286
2532
|
}
|
|
2287
2533
|
|
|
2534
|
+
export function rseq(x) {
|
|
2535
|
+
// vectors and sorted maps/sets are reversible, like CLJS
|
|
2536
|
+
if (isVectorArray(x)) {
|
|
2537
|
+
return x.length === 0 ? null : [...x].reverse();
|
|
2538
|
+
}
|
|
2539
|
+
if (x != null && x[SORTED_TAG] === true) {
|
|
2540
|
+
const xs = [...x].reverse();
|
|
2541
|
+
return xs.length === 0 ? null : xs;
|
|
2542
|
+
}
|
|
2543
|
+
throw new Error('rseq not supported on: ' + typeof x);
|
|
2544
|
+
}
|
|
2545
|
+
|
|
2288
2546
|
export function sort(f, coll) {
|
|
2289
2547
|
if (arguments.length === 1) {
|
|
2290
2548
|
coll = f;
|
|
@@ -2571,8 +2829,10 @@ export function dorun(x) {
|
|
|
2571
2829
|
}
|
|
2572
2830
|
|
|
2573
2831
|
export function doall(x) {
|
|
2574
|
-
// realize
|
|
2575
|
-
|
|
2832
|
+
// realize a lazy seq and return it, like CLJS; anything else is
|
|
2833
|
+
// already concrete
|
|
2834
|
+
if (x != null && x[TYPE_TAG] === LAZY_ITERABLE_TYPE) for (const _ of x);
|
|
2835
|
+
return x;
|
|
2576
2836
|
}
|
|
2577
2837
|
|
|
2578
2838
|
export function aclone(arr) {
|
|
@@ -2580,13 +2840,53 @@ export function aclone(arr) {
|
|
|
2580
2840
|
return cloned;
|
|
2581
2841
|
}
|
|
2582
2842
|
|
|
2843
|
+
function typed_array(sizeOrSeq, initValOrSeq) {
|
|
2844
|
+
if (initValOrSeq !== undefined) {
|
|
2845
|
+
const a = new Array(sizeOrSeq);
|
|
2846
|
+
if (typeof initValOrSeq === 'number') return a.fill(initValOrSeq);
|
|
2847
|
+
let i = 0;
|
|
2848
|
+
for (const x of iterable(initValOrSeq)) {
|
|
2849
|
+
if (i >= sizeOrSeq) break;
|
|
2850
|
+
a[i++] = x;
|
|
2851
|
+
}
|
|
2852
|
+
return a;
|
|
2853
|
+
}
|
|
2854
|
+
if (typeof sizeOrSeq === 'number') return new Array(sizeOrSeq).fill(null);
|
|
2855
|
+
return [...iterable(sizeOrSeq)];
|
|
2856
|
+
}
|
|
2857
|
+
|
|
2858
|
+
// like CLJS: provided for compatibility, all make a plain array
|
|
2859
|
+
export function int_array(sizeOrSeq, initValOrSeq) {
|
|
2860
|
+
return typed_array(sizeOrSeq, initValOrSeq);
|
|
2861
|
+
}
|
|
2862
|
+
export function long_array(sizeOrSeq, initValOrSeq) {
|
|
2863
|
+
return typed_array(sizeOrSeq, initValOrSeq);
|
|
2864
|
+
}
|
|
2865
|
+
export function float_array(sizeOrSeq, initValOrSeq) {
|
|
2866
|
+
return typed_array(sizeOrSeq, initValOrSeq);
|
|
2867
|
+
}
|
|
2868
|
+
export function double_array(sizeOrSeq, initValOrSeq) {
|
|
2869
|
+
return typed_array(sizeOrSeq, initValOrSeq);
|
|
2870
|
+
}
|
|
2871
|
+
export function object_array(sizeOrSeq, initValOrSeq) {
|
|
2872
|
+
return typed_array(sizeOrSeq, initValOrSeq);
|
|
2873
|
+
}
|
|
2874
|
+
|
|
2583
2875
|
export function add_watch(ref, key, fn) {
|
|
2584
|
-
ref
|
|
2876
|
+
if (ref?.[IWatchable__add_watch] !== undefined) {
|
|
2877
|
+
ref[IWatchable__add_watch](ref, key, fn);
|
|
2878
|
+
return ref;
|
|
2879
|
+
}
|
|
2880
|
+
nilImpl(_add_watch, 'IWatchable.-add-watch', ref)(ref, key, fn);
|
|
2585
2881
|
return ref;
|
|
2586
2882
|
}
|
|
2587
2883
|
|
|
2588
2884
|
export function remove_watch(ref, key) {
|
|
2589
|
-
ref
|
|
2885
|
+
if (ref?.[IWatchable__remove_watch] !== undefined) {
|
|
2886
|
+
ref[IWatchable__remove_watch](ref, key);
|
|
2887
|
+
return ref;
|
|
2888
|
+
}
|
|
2889
|
+
nilImpl(_remove_watch, 'IWatchable.-remove-watch', ref)(ref, key);
|
|
2590
2890
|
return ref;
|
|
2591
2891
|
}
|
|
2592
2892
|
|
|
@@ -2639,15 +2939,15 @@ export function every_pred(...preds) {
|
|
|
2639
2939
|
|
|
2640
2940
|
export function some_fn(...fns) {
|
|
2641
2941
|
return (...args) => {
|
|
2942
|
+
let res;
|
|
2642
2943
|
for (const f of fns) {
|
|
2643
2944
|
for (const a of args) {
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
}
|
|
2945
|
+
res = f(a);
|
|
2946
|
+
// truth_, not JS truthiness: 0 and "" are truthy in CLJS
|
|
2947
|
+
if (truth_(res)) return res;
|
|
2648
2948
|
}
|
|
2649
2949
|
}
|
|
2650
|
-
return
|
|
2950
|
+
return res;
|
|
2651
2951
|
};
|
|
2652
2952
|
}
|
|
2653
2953
|
|
|
@@ -2791,7 +3091,8 @@ export function re_seq(re, s) {
|
|
|
2791
3091
|
}
|
|
2792
3092
|
|
|
2793
3093
|
export function NaN_QMARK_(x) {
|
|
2794
|
-
|
|
3094
|
+
// coercing, like CLJS js/isNaN: (NaN? "foo") is true
|
|
3095
|
+
return isNaN(x);
|
|
2795
3096
|
}
|
|
2796
3097
|
|
|
2797
3098
|
export function number_QMARK_(x) {
|
|
@@ -2799,7 +3100,7 @@ export function number_QMARK_(x) {
|
|
|
2799
3100
|
}
|
|
2800
3101
|
|
|
2801
3102
|
export function keys(obj) {
|
|
2802
|
-
if (obj == null) return;
|
|
3103
|
+
if (obj == null) return null;
|
|
2803
3104
|
const t = typeConst(obj);
|
|
2804
3105
|
switch (t) {
|
|
2805
3106
|
case OBJECT_TYPE: {
|
|
@@ -2811,6 +3112,11 @@ export function keys(obj) {
|
|
|
2811
3112
|
if (obj.size) return Array.from(obj.keys());
|
|
2812
3113
|
return;
|
|
2813
3114
|
}
|
|
3115
|
+
// not a map: nil when empty, like seq in CLJS, else throw
|
|
3116
|
+
for (const _ of iterable(obj)) {
|
|
3117
|
+
throw new TypeError(obj + ' is not a map');
|
|
3118
|
+
}
|
|
3119
|
+
return null;
|
|
2814
3120
|
}
|
|
2815
3121
|
|
|
2816
3122
|
export function js_keys(obj) {
|
|
@@ -2818,7 +3124,7 @@ export function js_keys(obj) {
|
|
|
2818
3124
|
}
|
|
2819
3125
|
|
|
2820
3126
|
export function vals(obj) {
|
|
2821
|
-
if (obj == null) return;
|
|
3127
|
+
if (obj == null) return null;
|
|
2822
3128
|
const t = typeConst(obj);
|
|
2823
3129
|
switch (t) {
|
|
2824
3130
|
case OBJECT_TYPE: {
|
|
@@ -2830,6 +3136,11 @@ export function vals(obj) {
|
|
|
2830
3136
|
if (obj.size) return Array.from(obj.values());
|
|
2831
3137
|
return;
|
|
2832
3138
|
}
|
|
3139
|
+
// not a map: nil when empty, like seq in CLJS, else throw
|
|
3140
|
+
for (const _ of iterable(obj)) {
|
|
3141
|
+
throw new TypeError(obj + ' is not a map');
|
|
3142
|
+
}
|
|
3143
|
+
return null;
|
|
2833
3144
|
}
|
|
2834
3145
|
|
|
2835
3146
|
export function string_QMARK_(s) {
|
|
@@ -3024,34 +3335,22 @@ export function mod(x, y) {
|
|
|
3024
3335
|
}
|
|
3025
3336
|
|
|
3026
3337
|
export function min_key(k, x, ...more) {
|
|
3027
|
-
|
|
3028
|
-
|
|
3338
|
+
k = __toFn(k);
|
|
3339
|
+
// pairwise (if (< (k x) (k y)) x y), like CLJS, so NaN propagates right
|
|
3340
|
+
let min = x;
|
|
3341
|
+
for (const y of more) {
|
|
3342
|
+
if (!(k(min) < k(y))) min = y;
|
|
3029
3343
|
}
|
|
3030
|
-
var kx = k(x);
|
|
3031
|
-
var min = x;
|
|
3032
|
-
more.forEach((y) => {
|
|
3033
|
-
var ky = k(y);
|
|
3034
|
-
if (ky <= kx) {
|
|
3035
|
-
kx = ky;
|
|
3036
|
-
min = y;
|
|
3037
|
-
}
|
|
3038
|
-
});
|
|
3039
3344
|
return min;
|
|
3040
3345
|
}
|
|
3041
3346
|
|
|
3042
3347
|
export function max_key(k, x, ...more) {
|
|
3043
|
-
|
|
3044
|
-
|
|
3348
|
+
k = __toFn(k);
|
|
3349
|
+
// pairwise (if (> (k x) (k y)) x y), like CLJS, so NaN propagates right
|
|
3350
|
+
let max = x;
|
|
3351
|
+
for (const y of more) {
|
|
3352
|
+
if (!(k(max) > k(y))) max = y;
|
|
3045
3353
|
}
|
|
3046
|
-
var kx = k(x);
|
|
3047
|
-
var max = x;
|
|
3048
|
-
more.forEach((y) => {
|
|
3049
|
-
var ky = k(y);
|
|
3050
|
-
if (ky >= kx) {
|
|
3051
|
-
kx = ky;
|
|
3052
|
-
max = y;
|
|
3053
|
-
}
|
|
3054
|
-
});
|
|
3055
3354
|
return max;
|
|
3056
3355
|
}
|
|
3057
3356
|
|
|
@@ -3465,6 +3764,7 @@ export function memoize(f) {
|
|
|
3465
3764
|
}
|
|
3466
3765
|
|
|
3467
3766
|
export function peek(vec) {
|
|
3767
|
+
if (vec == null) return null;
|
|
3468
3768
|
// A list peeks at its front; squint lists are array-backed, so check list
|
|
3469
3769
|
// before array to avoid returning the last element.
|
|
3470
3770
|
if (list_QMARK_(vec)) {
|
|
@@ -3472,7 +3772,7 @@ export function peek(vec) {
|
|
|
3472
3772
|
} else if (array_QMARK_(vec)) {
|
|
3473
3773
|
return vec[vec.length - 1];
|
|
3474
3774
|
} else {
|
|
3475
|
-
|
|
3775
|
+
throw missing_protocol('IStack.-peek', vec);
|
|
3476
3776
|
}
|
|
3477
3777
|
}
|
|
3478
3778
|
|
|
@@ -3487,7 +3787,7 @@ export function pop(vec) {
|
|
|
3487
3787
|
ret.pop();
|
|
3488
3788
|
return ret;
|
|
3489
3789
|
} else {
|
|
3490
|
-
|
|
3790
|
+
throw missing_protocol('IStack.-pop', vec);
|
|
3491
3791
|
}
|
|
3492
3792
|
}
|
|
3493
3793
|
|
|
@@ -3518,7 +3818,7 @@ export function update_vals(m, f) {
|
|
|
3518
3818
|
}
|
|
3519
3819
|
|
|
3520
3820
|
export function random_uuid() {
|
|
3521
|
-
return crypto.randomUUID();
|
|
3821
|
+
return new UUID(crypto.randomUUID());
|
|
3522
3822
|
}
|
|
3523
3823
|
|
|
3524
3824
|
export class UUID {
|
|
@@ -3531,20 +3831,34 @@ export class UUID {
|
|
|
3531
3831
|
}
|
|
3532
3832
|
|
|
3533
3833
|
export function uuid(s) {
|
|
3534
|
-
|
|
3834
|
+
// lowercased, like CLJS
|
|
3835
|
+
return new UUID(s.toLowerCase());
|
|
3535
3836
|
}
|
|
3536
3837
|
|
|
3537
3838
|
export function uuid_QMARK_(x) {
|
|
3538
3839
|
return x instanceof UUID;
|
|
3539
3840
|
}
|
|
3540
3841
|
|
|
3842
|
+
const UUID_REGEX = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
|
|
3843
|
+
|
|
3844
|
+
export function parse_uuid(s) {
|
|
3845
|
+
if (typeof s !== 'string') {
|
|
3846
|
+
throw new Error('Expected string, got: ' + (s === null ? 'nil' : typeof s));
|
|
3847
|
+
}
|
|
3848
|
+
return UUID_REGEX.test(s) ? uuid(s) : null;
|
|
3849
|
+
}
|
|
3850
|
+
|
|
3541
3851
|
export function inst_QMARK_(x) {
|
|
3542
3852
|
return x instanceof Date;
|
|
3543
3853
|
}
|
|
3544
3854
|
|
|
3855
|
+
const DELAY_DEREF = (self) => self._deref();
|
|
3856
|
+
|
|
3545
3857
|
export class Delay {
|
|
3546
3858
|
constructor(f) {
|
|
3547
3859
|
this.f = f;
|
|
3860
|
+
this[IDEREF_SYM] = true;
|
|
3861
|
+
this[IDeref__deref] = DELAY_DEREF;
|
|
3548
3862
|
}
|
|
3549
3863
|
_deref() {
|
|
3550
3864
|
if (this.realized) {
|
|
@@ -3564,6 +3878,10 @@ export function realized_QMARK_(x) {
|
|
|
3564
3878
|
throw new Error('realized? not supported on: ' + str(x));
|
|
3565
3879
|
}
|
|
3566
3880
|
|
|
3881
|
+
export function force(x) {
|
|
3882
|
+
return x instanceof Delay ? x._deref() : x;
|
|
3883
|
+
}
|
|
3884
|
+
|
|
3567
3885
|
function clj__GT_js_(x, seen) {
|
|
3568
3886
|
// we need to protect against circular objects
|
|
3569
3887
|
if (seen.has(x)) return x;
|
|
@@ -3591,12 +3909,12 @@ export function not_EQ_(...more) {
|
|
|
3591
3909
|
return not(_EQ_(...more));
|
|
3592
3910
|
}
|
|
3593
3911
|
|
|
3912
|
+
const VOLATILE_DEREF = (self) => self.v;
|
|
3913
|
+
|
|
3594
3914
|
class Volatile {
|
|
3595
3915
|
constructor(v) {
|
|
3596
3916
|
this.v = v;
|
|
3597
|
-
|
|
3598
|
-
_deref() {
|
|
3599
|
-
return this.v;
|
|
3917
|
+
this[IDeref__deref] = VOLATILE_DEREF;
|
|
3600
3918
|
}
|
|
3601
3919
|
}
|
|
3602
3920
|
|