@omegup/msync 0.0.29 → 0.0.32-test1
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/index.d.ts +8 -2
- package/index.esm.js +153 -124
- package/index.js +153 -124
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -55,7 +55,7 @@ declare const root: <T extends O>() => Field<T, T, unknown>;
|
|
|
55
55
|
declare const ctx: <T>() => <K extends string>(k: K) => Field<unknown, T, RORec<K, T>>;
|
|
56
56
|
|
|
57
57
|
declare const QueryRaw: unique symbol;
|
|
58
|
-
type QueryRaw<T, C> = RawObj & {
|
|
58
|
+
type QueryRaw<T, C = unknown> = RawObj & {
|
|
59
59
|
[Type]?(x: typeof QueryRaw, y: T, c: C): void;
|
|
60
60
|
};
|
|
61
61
|
declare const Query: unique symbol;
|
|
@@ -316,6 +316,12 @@ declare global {
|
|
|
316
316
|
race<T extends readonly unknown[] | []>(values: T): Promise<Awaited<T[number]>>;
|
|
317
317
|
}
|
|
318
318
|
}
|
|
319
|
+
declare module 'synchronous-promise' {
|
|
320
|
+
interface SynchronousPromiseConstructor {
|
|
321
|
+
any<T extends readonly unknown[] | [], _ extends 0 = 0>(values: AppMap<PromiseHKT, T>): SynchronousPromise<T[number]>;
|
|
322
|
+
any<T extends readonly unknown[] | []>(values: T): SynchronousPromise<Awaited<T[number]>>;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
319
325
|
|
|
320
326
|
declare const RawStage: unique symbol;
|
|
321
327
|
declare module 'mongodb' {
|
|
@@ -472,7 +478,7 @@ declare const $set: <V extends O>() => <R extends O, C = unknown>(fields: MapO<V
|
|
|
472
478
|
declare const $replaceWith: <T extends O, V extends O>(expr: Expr<V, T>) => DeltaStages<O, T, V> & LinStages<O, T, V>;
|
|
473
479
|
|
|
474
480
|
type s$1 = string;
|
|
475
|
-
declare const $unwindDelta: <K1 extends s$1, T extends doc, K2 extends s$1, U extends doc>(k1: AsLiteral<K1>, k2: AsLiteral<K2>, k: K1 | K2 | false) => RawStages<Delta<Rec<K1, T>>, Delta<Rec<K1, T> & Rec<K2, Arr<U>>>, Delta<Rec<K1, T> & Rec<K2, U> & ID>>;
|
|
481
|
+
declare const $unwindDelta: <K1 extends s$1, T extends doc, K2 extends s$1, U extends doc, Null extends null = never>(k1: AsLiteral<K1>, k2: AsLiteral<K2>, k: K1 | K2 | false, includeNull?: Null) => RawStages<Delta<Rec<K1, T>>, Delta<Rec<K1, T> & Rec<K2, Arr<U>>>, Delta<Rec<K1, T> & Rec<K2, U | Null> & ID>>;
|
|
476
482
|
|
|
477
483
|
type s = string;
|
|
478
484
|
declare const $unwind: <T extends doc, K extends s, U extends doc>(k: AsLiteral<K>, dict: RORec<K, "key">) => DeltaStages<O, T & Rec<K, Arr<U>>, T & Rec<K, U>>;
|
package/index.esm.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SynchronousPromise } from 'synchronous-promise';
|
|
1
2
|
import { UUID, MongoClient } from 'mongodb';
|
|
2
3
|
import crypto$1 from 'crypto';
|
|
3
4
|
import { writeFile } from 'fs/promises';
|
|
@@ -464,7 +465,12 @@ const $replaceWith1 = (expr) => f => {
|
|
|
464
465
|
{ $replaceWith: parts.reduce((v, k) => ({ [k]: v }), expr.raw(f()).get()) },
|
|
465
466
|
]);
|
|
466
467
|
};
|
|
467
|
-
const $unwind1 = (k) => f =>
|
|
468
|
+
const $unwind1 = (k, includeNull) => f => {
|
|
469
|
+
const path = `$${f().of(k).str()}`;
|
|
470
|
+
return asStages([
|
|
471
|
+
{ $unwind: path },
|
|
472
|
+
]);
|
|
473
|
+
};
|
|
468
474
|
const $group1 = (id, args) => (f) => asStages([
|
|
469
475
|
{
|
|
470
476
|
$group: {
|
|
@@ -495,7 +501,7 @@ const $simpleLookup1 = (args) => f => {
|
|
|
495
501
|
const $match_ = (query) => $match1(query)(root);
|
|
496
502
|
const $set_ = (updater) => $set1(updater)(root);
|
|
497
503
|
const $replaceWith_ = (expr) => $replaceWith1(expr)(root);
|
|
498
|
-
const $unwind_ = (k) => $unwind1(k)(root);
|
|
504
|
+
const $unwind_ = (k, includeNull) => $unwind1(k)(root);
|
|
499
505
|
const $group_ = () => (id, args) => $group1(id, args)(root);
|
|
500
506
|
const $project_ = $project1;
|
|
501
507
|
const $simpleLookup_ = (args) => $simpleLookup1(args)(root);
|
|
@@ -611,29 +617,6 @@ const $groupMerge = (id, args, out, gid, extra, idPrefix = '') => ({
|
|
|
611
617
|
const $groupId = (id, args, out, extra) => $groupMerge(id, args, { into: out, whenNotMatched: 'fail' }, '_id', extra);
|
|
612
618
|
const $group = (id, args, out, extra, idPrefix = '') => $groupMerge(id, args, { into: out, whenNotMatched: 'insert' }, '_grp', extra, idPrefix);
|
|
613
619
|
|
|
614
|
-
const $expr = (expr) => ({
|
|
615
|
-
raw: f => ({ $expr: expr.raw(f).get() }),
|
|
616
|
-
});
|
|
617
|
-
|
|
618
|
-
const $lookupRaw = ({ field1, field2 }, { coll, exec, input }, k2, k) => (f) => {
|
|
619
|
-
root().of('_id').expr();
|
|
620
|
-
root().of(k2).of('_id').expr();
|
|
621
|
-
return link()
|
|
622
|
-
.with($simpleLookup1({
|
|
623
|
-
coll,
|
|
624
|
-
k: k2,
|
|
625
|
-
vars: map1('local', root().with(field1).expr()),
|
|
626
|
-
pipeline: link()
|
|
627
|
-
.with(input)
|
|
628
|
-
.with($match_($expr(eq(ctx()('local').expr())(root().of('before').with(field2).expr()))))
|
|
629
|
-
.with(exec)
|
|
630
|
-
.with($replaceWith_(root().of('before').expr())).stages,
|
|
631
|
-
})(f))
|
|
632
|
-
.with($unwind1(k2)(f))
|
|
633
|
-
.with(link().stages
|
|
634
|
-
).stages;
|
|
635
|
-
};
|
|
636
|
-
|
|
637
620
|
const deltaExpr = (expr) => (field) => {
|
|
638
621
|
return ite(eqTyped($ifNull(root().of(field).expr(), nil), nil), nil, expr(field));
|
|
639
622
|
};
|
|
@@ -663,7 +646,82 @@ const $setDelta = (updater) => {
|
|
|
663
646
|
.with($setEach(k => to(nil), dict)).stages;
|
|
664
647
|
};
|
|
665
648
|
|
|
666
|
-
const $unwindDelta = (k1, k2, k) => {
|
|
649
|
+
const $unwindDelta = (k1, k2, k, includeNull) => {
|
|
650
|
+
const outer = includeNull === null;
|
|
651
|
+
const newItems = {
|
|
652
|
+
$filter: {
|
|
653
|
+
input: { $ifNull: [`$after.${k2}`, []] },
|
|
654
|
+
as: 'a',
|
|
655
|
+
cond: {
|
|
656
|
+
$not: {
|
|
657
|
+
$in: [
|
|
658
|
+
'$$a._id',
|
|
659
|
+
{
|
|
660
|
+
$map: {
|
|
661
|
+
input: { $ifNull: [`$before.${k2}`, []] },
|
|
662
|
+
as: 'b',
|
|
663
|
+
in: '$$b._id',
|
|
664
|
+
},
|
|
665
|
+
},
|
|
666
|
+
],
|
|
667
|
+
},
|
|
668
|
+
},
|
|
669
|
+
},
|
|
670
|
+
};
|
|
671
|
+
const oldItems = {
|
|
672
|
+
$filter: {
|
|
673
|
+
input: {
|
|
674
|
+
$map: {
|
|
675
|
+
input: { $ifNull: [`$before.${k2}`, []] },
|
|
676
|
+
as: 'b',
|
|
677
|
+
in: {
|
|
678
|
+
before: '$$b',
|
|
679
|
+
after: {
|
|
680
|
+
$ifNull: [
|
|
681
|
+
{
|
|
682
|
+
$first: {
|
|
683
|
+
$filter: {
|
|
684
|
+
input: `$after.${k2}`,
|
|
685
|
+
as: 'a',
|
|
686
|
+
cond: { $eq: ['$$a._id', '$$b._id'] },
|
|
687
|
+
},
|
|
688
|
+
},
|
|
689
|
+
},
|
|
690
|
+
null,
|
|
691
|
+
],
|
|
692
|
+
},
|
|
693
|
+
},
|
|
694
|
+
},
|
|
695
|
+
},
|
|
696
|
+
as: 'a',
|
|
697
|
+
cond: { $ne: ['$$a.before', '$$a.after'] },
|
|
698
|
+
},
|
|
699
|
+
};
|
|
700
|
+
const ifNull = (k, part, str = `$${[k1, k2].sort()[0]}.${part}._id`) => outer && k == k2 ? { $ifNull: [str, 'null'] } : str;
|
|
701
|
+
const interDot = ([a, b]) => [a, '.', b];
|
|
702
|
+
const partReplace = (part) => ({
|
|
703
|
+
$cond: {
|
|
704
|
+
if: { $or: [{ $eq: [`$${k1}.${part}`, null] }, { $eq: [`$${k2}.${part}`, null] }] },
|
|
705
|
+
then: null,
|
|
706
|
+
else: {
|
|
707
|
+
_id: k
|
|
708
|
+
? `$${k}.${part}._id`
|
|
709
|
+
: {
|
|
710
|
+
$concat: interDot([k1, k2].sort().map(k => ifNull(k, part))),
|
|
711
|
+
},
|
|
712
|
+
[k1]: `$${k1}.${part}`,
|
|
713
|
+
[k2]: outer
|
|
714
|
+
? {
|
|
715
|
+
$cond: {
|
|
716
|
+
if: `$${k2}.${part}._id`,
|
|
717
|
+
then: `$${k2}.${part}`,
|
|
718
|
+
else: null,
|
|
719
|
+
},
|
|
720
|
+
}
|
|
721
|
+
: `$${k2}.${part}`,
|
|
722
|
+
},
|
|
723
|
+
},
|
|
724
|
+
});
|
|
667
725
|
const stages = link()
|
|
668
726
|
.with(asStages([
|
|
669
727
|
{
|
|
@@ -674,51 +732,34 @@ const $unwindDelta = (k1, k2, k) => {
|
|
|
674
732
|
},
|
|
675
733
|
[k2]: {
|
|
676
734
|
$concatArrays: [
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
{
|
|
686
|
-
|
|
687
|
-
$filter: {
|
|
688
|
-
input: `$after.${k2}`,
|
|
689
|
-
as: 'a',
|
|
690
|
-
cond: { $eq: ['$$a._id', '$$b._id'] },
|
|
691
|
-
},
|
|
692
|
-
},
|
|
693
|
-
},
|
|
694
|
-
null,
|
|
695
|
-
],
|
|
735
|
+
outer
|
|
736
|
+
? {
|
|
737
|
+
$cond: {
|
|
738
|
+
if: { $eq: [`$before.${k2}`, []] },
|
|
739
|
+
then: {
|
|
740
|
+
$cond: {
|
|
741
|
+
if: { $eq: [`$after.${k2}`, []] },
|
|
742
|
+
then: [],
|
|
743
|
+
else: [{ before: {}, after: null }],
|
|
744
|
+
},
|
|
696
745
|
},
|
|
746
|
+
else: oldItems,
|
|
697
747
|
},
|
|
698
|
-
}
|
|
699
|
-
|
|
748
|
+
}
|
|
749
|
+
: oldItems,
|
|
700
750
|
{
|
|
701
751
|
$map: {
|
|
702
|
-
input:
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
$not: {
|
|
708
|
-
$in: [
|
|
709
|
-
'$$a._id',
|
|
710
|
-
{
|
|
711
|
-
$map: {
|
|
712
|
-
input: { $ifNull: [`$before.${k2}`, []] },
|
|
713
|
-
as: 'b',
|
|
714
|
-
in: '$$b._id',
|
|
715
|
-
},
|
|
716
|
-
},
|
|
717
|
-
],
|
|
752
|
+
input: outer
|
|
753
|
+
? {
|
|
754
|
+
$cond: {
|
|
755
|
+
if: {
|
|
756
|
+
$and: [{ $ne: [`$before.${k2}`, []] }, { $eq: [`$after.${k2}`, []] }],
|
|
718
757
|
},
|
|
758
|
+
then: [{}],
|
|
759
|
+
else: newItems,
|
|
719
760
|
},
|
|
720
|
-
}
|
|
721
|
-
|
|
761
|
+
}
|
|
762
|
+
: newItems,
|
|
722
763
|
as: 'a',
|
|
723
764
|
in: { before: null, after: '$$a' },
|
|
724
765
|
},
|
|
@@ -732,45 +773,9 @@ const $unwindDelta = (k1, k2, k) => {
|
|
|
732
773
|
.with(asStages([
|
|
733
774
|
{
|
|
734
775
|
$replaceWith: {
|
|
735
|
-
_id:
|
|
736
|
-
before:
|
|
737
|
-
|
|
738
|
-
if: { $or: [{ $eq: [`$${k1}.before`, null] }, { $eq: [`$${k2}.before`, null] }] },
|
|
739
|
-
then: null,
|
|
740
|
-
else: {
|
|
741
|
-
_id: {
|
|
742
|
-
$concat: k
|
|
743
|
-
? `$${k}.before._id`
|
|
744
|
-
: [
|
|
745
|
-
`$${[k1, k2].sort()[0]}.before._id`,
|
|
746
|
-
'.',
|
|
747
|
-
`$${[k1, k2].sort()[1]}.before._id`,
|
|
748
|
-
],
|
|
749
|
-
},
|
|
750
|
-
[k1]: `$${k1}.before`,
|
|
751
|
-
[k2]: `$${k2}.before`,
|
|
752
|
-
},
|
|
753
|
-
},
|
|
754
|
-
},
|
|
755
|
-
after: {
|
|
756
|
-
$cond: {
|
|
757
|
-
if: { $or: [{ $eq: [`$${k1}.after`, null] }, { $eq: [`$${k2}.after`, null] }] },
|
|
758
|
-
then: null,
|
|
759
|
-
else: {
|
|
760
|
-
_id: {
|
|
761
|
-
$concat: k
|
|
762
|
-
? `$${k}.after._id`
|
|
763
|
-
: [
|
|
764
|
-
`$${[k1, k2].sort()[0]}.after._id`,
|
|
765
|
-
'.',
|
|
766
|
-
`$${[k1, k2].sort()[1]}.after._id`,
|
|
767
|
-
],
|
|
768
|
-
},
|
|
769
|
-
[k1]: `$${k1}.after`,
|
|
770
|
-
[k2]: `$${k2}.after`,
|
|
771
|
-
},
|
|
772
|
-
},
|
|
773
|
-
},
|
|
776
|
+
_id: '$_id',
|
|
777
|
+
before: partReplace('before'),
|
|
778
|
+
after: partReplace('after'),
|
|
774
779
|
},
|
|
775
780
|
},
|
|
776
781
|
])).stages;
|
|
@@ -790,7 +795,7 @@ const $unwind = (k, dict) => ({
|
|
|
790
795
|
raw: $unwind1(k),
|
|
791
796
|
});
|
|
792
797
|
|
|
793
|
-
const $lookupDelta = ({ field1, field2 }, { coll, exec, input }, k1, k2, k) => {
|
|
798
|
+
const $lookupDelta = ({ field1, field2 }, { coll, exec, input }, k1, k2, k, includeNull) => {
|
|
794
799
|
return link()
|
|
795
800
|
.with($replaceWithDelta(field(map1(k1, root().expr()))))
|
|
796
801
|
.with($simpleLookup_({
|
|
@@ -819,8 +824,30 @@ const $lookupDelta = ({ field1, field2 }, { coll, exec, input }, k1, k2, k) => {
|
|
|
819
824
|
const a = root().of(f1).of('before').expr();
|
|
820
825
|
const part = root().of(f);
|
|
821
826
|
return ite(eq(root().of(f).expr())(nil), nil, field(omit.backward(mergeExpr(omit.forward(map1(k2, a)), map1(k1, part.of(k1).expr())))));
|
|
822
|
-
}))
|
|
823
|
-
|
|
827
|
+
})).with($unwindDelta(k1, k2, k, includeNull)).stages;
|
|
828
|
+
};
|
|
829
|
+
|
|
830
|
+
const $expr = (expr) => ({
|
|
831
|
+
raw: f => ({ $expr: expr.raw(f).get() }),
|
|
832
|
+
});
|
|
833
|
+
|
|
834
|
+
const $lookupRaw = ({ field1, field2 }, { coll, exec, input }, k2, k) => (f) => {
|
|
835
|
+
root().of('_id').expr();
|
|
836
|
+
root().of(k2).of('_id').expr();
|
|
837
|
+
return link()
|
|
838
|
+
.with($simpleLookup1({
|
|
839
|
+
coll,
|
|
840
|
+
k: k2,
|
|
841
|
+
vars: map1('local', root().with(field1).expr()),
|
|
842
|
+
pipeline: link()
|
|
843
|
+
.with(input)
|
|
844
|
+
.with($match_($expr(eq(ctx()('local').expr())(root().of('before').with(field2).expr()))))
|
|
845
|
+
.with(exec)
|
|
846
|
+
.with($replaceWith_(root().of('before').expr())).stages,
|
|
847
|
+
})(f))
|
|
848
|
+
.with($unwind1(k2)(f))
|
|
849
|
+
.with(link().stages
|
|
850
|
+
).stages;
|
|
824
851
|
};
|
|
825
852
|
|
|
826
853
|
const asBefore = (f) => f(() => root().of('before'));
|
|
@@ -848,18 +875,20 @@ const patch = (x, k, v) => ({ ...x, [k]: v });
|
|
|
848
875
|
const restart = (sources) => {
|
|
849
876
|
return map(sources, x => x.stop());
|
|
850
877
|
};
|
|
851
|
-
const race =
|
|
878
|
+
const race = (sources) => {
|
|
852
879
|
const promises = Object.values(map(sources, ({ next }, key) => next.then(frame => ({ key, sources, frame }))));
|
|
853
|
-
return
|
|
880
|
+
return SynchronousPromise.any(promises);
|
|
854
881
|
};
|
|
855
882
|
|
|
856
|
-
const nextWinner =
|
|
883
|
+
const nextWinner = (previousWinner, previousWinnerNextFrame, sources, interrupt) => {
|
|
857
884
|
const { frame: previousFrame, key } = previousWinner;
|
|
858
885
|
if (!interrupt?.(key) && previousFrame.info.job) {
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
886
|
+
return previousWinnerNextFrame.then((previousFrameSuccessor) => {
|
|
887
|
+
if (previousFrameSuccessor.info.job) {
|
|
888
|
+
return { frame: previousFrameSuccessor, key };
|
|
889
|
+
}
|
|
890
|
+
return race(sources);
|
|
891
|
+
});
|
|
863
892
|
}
|
|
864
893
|
return race(sources);
|
|
865
894
|
};
|
|
@@ -921,7 +950,7 @@ class Machine {
|
|
|
921
950
|
return runCont(run(), cb);
|
|
922
951
|
}
|
|
923
952
|
}
|
|
924
|
-
const wrap = (root) =>
|
|
953
|
+
const wrap = (root) => root;
|
|
925
954
|
const runCont = async ({ next }, cb) => {
|
|
926
955
|
const { cont, info } = await next;
|
|
927
956
|
const stopped = cb?.(info);
|
|
@@ -934,9 +963,9 @@ const runCont = async ({ next }, cb) => {
|
|
|
934
963
|
};
|
|
935
964
|
|
|
936
965
|
const merge = ({ lsource: L, rsource: R, }) => mergeIterators({ sources: { L, R } });
|
|
937
|
-
const join = ({ lField, rField, left, right, as }, leftSnapshot, rightSnapshot, stagesUntilNextLookup) => {
|
|
938
|
-
createIndex(leftSnapshot.coll, { [lField.str()]: 1 }).catch(e => e.code == 86 || Promise.reject(e));
|
|
939
|
-
createIndex(rightSnapshot.coll, { [rField.str()]: 1 }).catch(e => e.code == 86 || Promise.reject(e));
|
|
966
|
+
const join = ({ lField, rField, left, right, as }, leftSnapshot, rightSnapshot, stagesUntilNextLookup, includeNull) => {
|
|
967
|
+
createIndex(leftSnapshot.coll, { [`before.${lField.str()}`]: 1 }).catch(e => e.code == 86 || Promise.reject(e));
|
|
968
|
+
createIndex(rightSnapshot.coll, { [`before.${rField.str()}`]: 1 }).catch(e => e.code == 86 || Promise.reject(e));
|
|
940
969
|
const rightJoinField = { field1: lField, field2: rField };
|
|
941
970
|
const joinId = 'left';
|
|
942
971
|
const joinR_Snapshot = asBefore($lookupRaw(rightJoinField, rightSnapshot, as));
|
|
@@ -949,7 +978,7 @@ const join = ({ lField, rField, left, right, as }, leftSnapshot, rightSnapshot,
|
|
|
949
978
|
out: (finalInput) => {
|
|
950
979
|
const leftJoinField = { field1: rField, field2: lField };
|
|
951
980
|
const joinL_Delta = $lookupDelta(leftJoinField, leftSnapshot, 'right', 'left', joinId);
|
|
952
|
-
const joinR_Delta = $lookupDelta(rightJoinField, rightSnapshot, 'left', 'right', joinId);
|
|
981
|
+
const joinR_Delta = $lookupDelta(rightJoinField, rightSnapshot, 'left', 'right', joinId, includeNull);
|
|
953
982
|
const mergeForeignIntoDoc = concatStages($replaceWithDelta(mergeObjects(root().of('left').expr(), fieldM({ a: root().of('right').expr(), b: root().of('_id').expr() }, dictId))), stagesUntilNextLookup.delta);
|
|
954
983
|
const lRunnerInput = concatStages(joinR_Delta, mergeForeignIntoDoc);
|
|
955
984
|
const rRunnerInput = concatStages(joinL_Delta, mergeForeignIntoDoc);
|
|
@@ -1183,7 +1212,7 @@ const makeWatchStream = (db, { collection, projection: p, hardMatch: m }, startA
|
|
|
1183
1212
|
};
|
|
1184
1213
|
|
|
1185
1214
|
const actions = {
|
|
1186
|
-
updateMany: (c, args) => [c.updateMany(...args), [`db['${c.collectionName}'].updateMany(
|
|
1215
|
+
updateMany: (c, args) => [c.updateMany(...args), [`db['${c.collectionName}'].updateMany(...`, args, ')']],
|
|
1187
1216
|
};
|
|
1188
1217
|
const streamNames = {};
|
|
1189
1218
|
const executes$1 = (view, input, streamName) => {
|
|
@@ -1242,7 +1271,7 @@ const executes$1 = (view, input, streamName) => {
|
|
|
1242
1271
|
params: x.params,
|
|
1243
1272
|
})),
|
|
1244
1273
|
};
|
|
1245
|
-
const step0 = () =>
|
|
1274
|
+
const step0 = () => SynchronousPromise.resolve(next(step1, 'empty new collection'));
|
|
1246
1275
|
const stop = withStop(step0);
|
|
1247
1276
|
const step1 = async () => {
|
|
1248
1277
|
await snapshotCollection.updateMany({ updated: true }, { $set: { updated: false, after: null } });
|
|
@@ -1263,9 +1292,9 @@ const executes$1 = (view, input, streamName) => {
|
|
|
1263
1292
|
params: p,
|
|
1264
1293
|
};
|
|
1265
1294
|
const [action, out] = actions[method](collection, params);
|
|
1266
|
-
log('teardown', `db
|
|
1295
|
+
log('teardown', `db['${snapshotCollection.collectionName}'].drop()`, ...out);
|
|
1267
1296
|
await Promise.all([snapshotCollection.drop(), action]);
|
|
1268
|
-
log('teardown done', `db
|
|
1297
|
+
log('teardown done', `db['${snapshotCollection.collectionName}'].drop()`, ...out);
|
|
1269
1298
|
};
|
|
1270
1299
|
if (exists && !same)
|
|
1271
1300
|
await handleTeardown(exists);
|
|
@@ -1405,7 +1434,7 @@ const executes = (view, input, streamName) => {
|
|
|
1405
1434
|
params: x.params,
|
|
1406
1435
|
})),
|
|
1407
1436
|
};
|
|
1408
|
-
const step0 = () =>
|
|
1437
|
+
const step0 = () => SynchronousPromise.resolve(next(step1, 'get last update'));
|
|
1409
1438
|
const stop = withStop(step0);
|
|
1410
1439
|
const step1 = () => Promise.all([
|
|
1411
1440
|
last.findOne({ _id: streamName, data }),
|
package/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var synchronousPromise = require('synchronous-promise');
|
|
3
4
|
var mongodb = require('mongodb');
|
|
4
5
|
var crypto$1 = require('crypto');
|
|
5
6
|
var promises = require('fs/promises');
|
|
@@ -466,7 +467,12 @@ const $replaceWith1 = (expr) => f => {
|
|
|
466
467
|
{ $replaceWith: parts.reduce((v, k) => ({ [k]: v }), expr.raw(f()).get()) },
|
|
467
468
|
]);
|
|
468
469
|
};
|
|
469
|
-
const $unwind1 = (k) => f =>
|
|
470
|
+
const $unwind1 = (k, includeNull) => f => {
|
|
471
|
+
const path = `$${f().of(k).str()}`;
|
|
472
|
+
return asStages([
|
|
473
|
+
{ $unwind: path },
|
|
474
|
+
]);
|
|
475
|
+
};
|
|
470
476
|
const $group1 = (id, args) => (f) => asStages([
|
|
471
477
|
{
|
|
472
478
|
$group: {
|
|
@@ -497,7 +503,7 @@ const $simpleLookup1 = (args) => f => {
|
|
|
497
503
|
const $match_ = (query) => $match1(query)(root);
|
|
498
504
|
const $set_ = (updater) => $set1(updater)(root);
|
|
499
505
|
const $replaceWith_ = (expr) => $replaceWith1(expr)(root);
|
|
500
|
-
const $unwind_ = (k) => $unwind1(k)(root);
|
|
506
|
+
const $unwind_ = (k, includeNull) => $unwind1(k)(root);
|
|
501
507
|
const $group_ = () => (id, args) => $group1(id, args)(root);
|
|
502
508
|
const $project_ = $project1;
|
|
503
509
|
const $simpleLookup_ = (args) => $simpleLookup1(args)(root);
|
|
@@ -613,29 +619,6 @@ const $groupMerge = (id, args, out, gid, extra, idPrefix = '') => ({
|
|
|
613
619
|
const $groupId = (id, args, out, extra) => $groupMerge(id, args, { into: out, whenNotMatched: 'fail' }, '_id', extra);
|
|
614
620
|
const $group = (id, args, out, extra, idPrefix = '') => $groupMerge(id, args, { into: out, whenNotMatched: 'insert' }, '_grp', extra, idPrefix);
|
|
615
621
|
|
|
616
|
-
const $expr = (expr) => ({
|
|
617
|
-
raw: f => ({ $expr: expr.raw(f).get() }),
|
|
618
|
-
});
|
|
619
|
-
|
|
620
|
-
const $lookupRaw = ({ field1, field2 }, { coll, exec, input }, k2, k) => (f) => {
|
|
621
|
-
root().of('_id').expr();
|
|
622
|
-
root().of(k2).of('_id').expr();
|
|
623
|
-
return link()
|
|
624
|
-
.with($simpleLookup1({
|
|
625
|
-
coll,
|
|
626
|
-
k: k2,
|
|
627
|
-
vars: map1('local', root().with(field1).expr()),
|
|
628
|
-
pipeline: link()
|
|
629
|
-
.with(input)
|
|
630
|
-
.with($match_($expr(eq(ctx()('local').expr())(root().of('before').with(field2).expr()))))
|
|
631
|
-
.with(exec)
|
|
632
|
-
.with($replaceWith_(root().of('before').expr())).stages,
|
|
633
|
-
})(f))
|
|
634
|
-
.with($unwind1(k2)(f))
|
|
635
|
-
.with(link().stages
|
|
636
|
-
).stages;
|
|
637
|
-
};
|
|
638
|
-
|
|
639
622
|
const deltaExpr = (expr) => (field) => {
|
|
640
623
|
return ite(eqTyped($ifNull(root().of(field).expr(), nil), nil), nil, expr(field));
|
|
641
624
|
};
|
|
@@ -665,7 +648,82 @@ const $setDelta = (updater) => {
|
|
|
665
648
|
.with($setEach(k => to(nil), dict)).stages;
|
|
666
649
|
};
|
|
667
650
|
|
|
668
|
-
const $unwindDelta = (k1, k2, k) => {
|
|
651
|
+
const $unwindDelta = (k1, k2, k, includeNull) => {
|
|
652
|
+
const outer = includeNull === null;
|
|
653
|
+
const newItems = {
|
|
654
|
+
$filter: {
|
|
655
|
+
input: { $ifNull: [`$after.${k2}`, []] },
|
|
656
|
+
as: 'a',
|
|
657
|
+
cond: {
|
|
658
|
+
$not: {
|
|
659
|
+
$in: [
|
|
660
|
+
'$$a._id',
|
|
661
|
+
{
|
|
662
|
+
$map: {
|
|
663
|
+
input: { $ifNull: [`$before.${k2}`, []] },
|
|
664
|
+
as: 'b',
|
|
665
|
+
in: '$$b._id',
|
|
666
|
+
},
|
|
667
|
+
},
|
|
668
|
+
],
|
|
669
|
+
},
|
|
670
|
+
},
|
|
671
|
+
},
|
|
672
|
+
};
|
|
673
|
+
const oldItems = {
|
|
674
|
+
$filter: {
|
|
675
|
+
input: {
|
|
676
|
+
$map: {
|
|
677
|
+
input: { $ifNull: [`$before.${k2}`, []] },
|
|
678
|
+
as: 'b',
|
|
679
|
+
in: {
|
|
680
|
+
before: '$$b',
|
|
681
|
+
after: {
|
|
682
|
+
$ifNull: [
|
|
683
|
+
{
|
|
684
|
+
$first: {
|
|
685
|
+
$filter: {
|
|
686
|
+
input: `$after.${k2}`,
|
|
687
|
+
as: 'a',
|
|
688
|
+
cond: { $eq: ['$$a._id', '$$b._id'] },
|
|
689
|
+
},
|
|
690
|
+
},
|
|
691
|
+
},
|
|
692
|
+
null,
|
|
693
|
+
],
|
|
694
|
+
},
|
|
695
|
+
},
|
|
696
|
+
},
|
|
697
|
+
},
|
|
698
|
+
as: 'a',
|
|
699
|
+
cond: { $ne: ['$$a.before', '$$a.after'] },
|
|
700
|
+
},
|
|
701
|
+
};
|
|
702
|
+
const ifNull = (k, part, str = `$${[k1, k2].sort()[0]}.${part}._id`) => outer && k == k2 ? { $ifNull: [str, 'null'] } : str;
|
|
703
|
+
const interDot = ([a, b]) => [a, '.', b];
|
|
704
|
+
const partReplace = (part) => ({
|
|
705
|
+
$cond: {
|
|
706
|
+
if: { $or: [{ $eq: [`$${k1}.${part}`, null] }, { $eq: [`$${k2}.${part}`, null] }] },
|
|
707
|
+
then: null,
|
|
708
|
+
else: {
|
|
709
|
+
_id: k
|
|
710
|
+
? `$${k}.${part}._id`
|
|
711
|
+
: {
|
|
712
|
+
$concat: interDot([k1, k2].sort().map(k => ifNull(k, part))),
|
|
713
|
+
},
|
|
714
|
+
[k1]: `$${k1}.${part}`,
|
|
715
|
+
[k2]: outer
|
|
716
|
+
? {
|
|
717
|
+
$cond: {
|
|
718
|
+
if: `$${k2}.${part}._id`,
|
|
719
|
+
then: `$${k2}.${part}`,
|
|
720
|
+
else: null,
|
|
721
|
+
},
|
|
722
|
+
}
|
|
723
|
+
: `$${k2}.${part}`,
|
|
724
|
+
},
|
|
725
|
+
},
|
|
726
|
+
});
|
|
669
727
|
const stages = link()
|
|
670
728
|
.with(asStages([
|
|
671
729
|
{
|
|
@@ -676,51 +734,34 @@ const $unwindDelta = (k1, k2, k) => {
|
|
|
676
734
|
},
|
|
677
735
|
[k2]: {
|
|
678
736
|
$concatArrays: [
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
{
|
|
688
|
-
|
|
689
|
-
$filter: {
|
|
690
|
-
input: `$after.${k2}`,
|
|
691
|
-
as: 'a',
|
|
692
|
-
cond: { $eq: ['$$a._id', '$$b._id'] },
|
|
693
|
-
},
|
|
694
|
-
},
|
|
695
|
-
},
|
|
696
|
-
null,
|
|
697
|
-
],
|
|
737
|
+
outer
|
|
738
|
+
? {
|
|
739
|
+
$cond: {
|
|
740
|
+
if: { $eq: [`$before.${k2}`, []] },
|
|
741
|
+
then: {
|
|
742
|
+
$cond: {
|
|
743
|
+
if: { $eq: [`$after.${k2}`, []] },
|
|
744
|
+
then: [],
|
|
745
|
+
else: [{ before: {}, after: null }],
|
|
746
|
+
},
|
|
698
747
|
},
|
|
748
|
+
else: oldItems,
|
|
699
749
|
},
|
|
700
|
-
}
|
|
701
|
-
|
|
750
|
+
}
|
|
751
|
+
: oldItems,
|
|
702
752
|
{
|
|
703
753
|
$map: {
|
|
704
|
-
input:
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
$not: {
|
|
710
|
-
$in: [
|
|
711
|
-
'$$a._id',
|
|
712
|
-
{
|
|
713
|
-
$map: {
|
|
714
|
-
input: { $ifNull: [`$before.${k2}`, []] },
|
|
715
|
-
as: 'b',
|
|
716
|
-
in: '$$b._id',
|
|
717
|
-
},
|
|
718
|
-
},
|
|
719
|
-
],
|
|
754
|
+
input: outer
|
|
755
|
+
? {
|
|
756
|
+
$cond: {
|
|
757
|
+
if: {
|
|
758
|
+
$and: [{ $ne: [`$before.${k2}`, []] }, { $eq: [`$after.${k2}`, []] }],
|
|
720
759
|
},
|
|
760
|
+
then: [{}],
|
|
761
|
+
else: newItems,
|
|
721
762
|
},
|
|
722
|
-
}
|
|
723
|
-
|
|
763
|
+
}
|
|
764
|
+
: newItems,
|
|
724
765
|
as: 'a',
|
|
725
766
|
in: { before: null, after: '$$a' },
|
|
726
767
|
},
|
|
@@ -734,45 +775,9 @@ const $unwindDelta = (k1, k2, k) => {
|
|
|
734
775
|
.with(asStages([
|
|
735
776
|
{
|
|
736
777
|
$replaceWith: {
|
|
737
|
-
_id:
|
|
738
|
-
before:
|
|
739
|
-
|
|
740
|
-
if: { $or: [{ $eq: [`$${k1}.before`, null] }, { $eq: [`$${k2}.before`, null] }] },
|
|
741
|
-
then: null,
|
|
742
|
-
else: {
|
|
743
|
-
_id: {
|
|
744
|
-
$concat: k
|
|
745
|
-
? `$${k}.before._id`
|
|
746
|
-
: [
|
|
747
|
-
`$${[k1, k2].sort()[0]}.before._id`,
|
|
748
|
-
'.',
|
|
749
|
-
`$${[k1, k2].sort()[1]}.before._id`,
|
|
750
|
-
],
|
|
751
|
-
},
|
|
752
|
-
[k1]: `$${k1}.before`,
|
|
753
|
-
[k2]: `$${k2}.before`,
|
|
754
|
-
},
|
|
755
|
-
},
|
|
756
|
-
},
|
|
757
|
-
after: {
|
|
758
|
-
$cond: {
|
|
759
|
-
if: { $or: [{ $eq: [`$${k1}.after`, null] }, { $eq: [`$${k2}.after`, null] }] },
|
|
760
|
-
then: null,
|
|
761
|
-
else: {
|
|
762
|
-
_id: {
|
|
763
|
-
$concat: k
|
|
764
|
-
? `$${k}.after._id`
|
|
765
|
-
: [
|
|
766
|
-
`$${[k1, k2].sort()[0]}.after._id`,
|
|
767
|
-
'.',
|
|
768
|
-
`$${[k1, k2].sort()[1]}.after._id`,
|
|
769
|
-
],
|
|
770
|
-
},
|
|
771
|
-
[k1]: `$${k1}.after`,
|
|
772
|
-
[k2]: `$${k2}.after`,
|
|
773
|
-
},
|
|
774
|
-
},
|
|
775
|
-
},
|
|
778
|
+
_id: '$_id',
|
|
779
|
+
before: partReplace('before'),
|
|
780
|
+
after: partReplace('after'),
|
|
776
781
|
},
|
|
777
782
|
},
|
|
778
783
|
])).stages;
|
|
@@ -792,7 +797,7 @@ const $unwind = (k, dict) => ({
|
|
|
792
797
|
raw: $unwind1(k),
|
|
793
798
|
});
|
|
794
799
|
|
|
795
|
-
const $lookupDelta = ({ field1, field2 }, { coll, exec, input }, k1, k2, k) => {
|
|
800
|
+
const $lookupDelta = ({ field1, field2 }, { coll, exec, input }, k1, k2, k, includeNull) => {
|
|
796
801
|
return link()
|
|
797
802
|
.with($replaceWithDelta(field(map1(k1, root().expr()))))
|
|
798
803
|
.with($simpleLookup_({
|
|
@@ -821,8 +826,30 @@ const $lookupDelta = ({ field1, field2 }, { coll, exec, input }, k1, k2, k) => {
|
|
|
821
826
|
const a = root().of(f1).of('before').expr();
|
|
822
827
|
const part = root().of(f);
|
|
823
828
|
return ite(eq(root().of(f).expr())(nil), nil, field(omit.backward(mergeExpr(omit.forward(map1(k2, a)), map1(k1, part.of(k1).expr())))));
|
|
824
|
-
}))
|
|
825
|
-
|
|
829
|
+
})).with($unwindDelta(k1, k2, k, includeNull)).stages;
|
|
830
|
+
};
|
|
831
|
+
|
|
832
|
+
const $expr = (expr) => ({
|
|
833
|
+
raw: f => ({ $expr: expr.raw(f).get() }),
|
|
834
|
+
});
|
|
835
|
+
|
|
836
|
+
const $lookupRaw = ({ field1, field2 }, { coll, exec, input }, k2, k) => (f) => {
|
|
837
|
+
root().of('_id').expr();
|
|
838
|
+
root().of(k2).of('_id').expr();
|
|
839
|
+
return link()
|
|
840
|
+
.with($simpleLookup1({
|
|
841
|
+
coll,
|
|
842
|
+
k: k2,
|
|
843
|
+
vars: map1('local', root().with(field1).expr()),
|
|
844
|
+
pipeline: link()
|
|
845
|
+
.with(input)
|
|
846
|
+
.with($match_($expr(eq(ctx()('local').expr())(root().of('before').with(field2).expr()))))
|
|
847
|
+
.with(exec)
|
|
848
|
+
.with($replaceWith_(root().of('before').expr())).stages,
|
|
849
|
+
})(f))
|
|
850
|
+
.with($unwind1(k2)(f))
|
|
851
|
+
.with(link().stages
|
|
852
|
+
).stages;
|
|
826
853
|
};
|
|
827
854
|
|
|
828
855
|
const asBefore = (f) => f(() => root().of('before'));
|
|
@@ -850,18 +877,20 @@ const patch = (x, k, v) => ({ ...x, [k]: v });
|
|
|
850
877
|
const restart = (sources) => {
|
|
851
878
|
return map(sources, x => x.stop());
|
|
852
879
|
};
|
|
853
|
-
const race =
|
|
880
|
+
const race = (sources) => {
|
|
854
881
|
const promises = Object.values(map(sources, ({ next }, key) => next.then(frame => ({ key, sources, frame }))));
|
|
855
|
-
return
|
|
882
|
+
return synchronousPromise.SynchronousPromise.any(promises);
|
|
856
883
|
};
|
|
857
884
|
|
|
858
|
-
const nextWinner =
|
|
885
|
+
const nextWinner = (previousWinner, previousWinnerNextFrame, sources, interrupt) => {
|
|
859
886
|
const { frame: previousFrame, key } = previousWinner;
|
|
860
887
|
if (!interrupt?.(key) && previousFrame.info.job) {
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
888
|
+
return previousWinnerNextFrame.then((previousFrameSuccessor) => {
|
|
889
|
+
if (previousFrameSuccessor.info.job) {
|
|
890
|
+
return { frame: previousFrameSuccessor, key };
|
|
891
|
+
}
|
|
892
|
+
return race(sources);
|
|
893
|
+
});
|
|
865
894
|
}
|
|
866
895
|
return race(sources);
|
|
867
896
|
};
|
|
@@ -923,7 +952,7 @@ class Machine {
|
|
|
923
952
|
return runCont(run(), cb);
|
|
924
953
|
}
|
|
925
954
|
}
|
|
926
|
-
const wrap = (root) =>
|
|
955
|
+
const wrap = (root) => root;
|
|
927
956
|
const runCont = async ({ next }, cb) => {
|
|
928
957
|
const { cont, info } = await next;
|
|
929
958
|
const stopped = cb?.(info);
|
|
@@ -936,9 +965,9 @@ const runCont = async ({ next }, cb) => {
|
|
|
936
965
|
};
|
|
937
966
|
|
|
938
967
|
const merge = ({ lsource: L, rsource: R, }) => mergeIterators({ sources: { L, R } });
|
|
939
|
-
const join = ({ lField, rField, left, right, as }, leftSnapshot, rightSnapshot, stagesUntilNextLookup) => {
|
|
940
|
-
createIndex(leftSnapshot.coll, { [lField.str()]: 1 }).catch(e => e.code == 86 || Promise.reject(e));
|
|
941
|
-
createIndex(rightSnapshot.coll, { [rField.str()]: 1 }).catch(e => e.code == 86 || Promise.reject(e));
|
|
968
|
+
const join = ({ lField, rField, left, right, as }, leftSnapshot, rightSnapshot, stagesUntilNextLookup, includeNull) => {
|
|
969
|
+
createIndex(leftSnapshot.coll, { [`before.${lField.str()}`]: 1 }).catch(e => e.code == 86 || Promise.reject(e));
|
|
970
|
+
createIndex(rightSnapshot.coll, { [`before.${rField.str()}`]: 1 }).catch(e => e.code == 86 || Promise.reject(e));
|
|
942
971
|
const rightJoinField = { field1: lField, field2: rField };
|
|
943
972
|
const joinId = 'left';
|
|
944
973
|
const joinR_Snapshot = asBefore($lookupRaw(rightJoinField, rightSnapshot, as));
|
|
@@ -951,7 +980,7 @@ const join = ({ lField, rField, left, right, as }, leftSnapshot, rightSnapshot,
|
|
|
951
980
|
out: (finalInput) => {
|
|
952
981
|
const leftJoinField = { field1: rField, field2: lField };
|
|
953
982
|
const joinL_Delta = $lookupDelta(leftJoinField, leftSnapshot, 'right', 'left', joinId);
|
|
954
|
-
const joinR_Delta = $lookupDelta(rightJoinField, rightSnapshot, 'left', 'right', joinId);
|
|
983
|
+
const joinR_Delta = $lookupDelta(rightJoinField, rightSnapshot, 'left', 'right', joinId, includeNull);
|
|
955
984
|
const mergeForeignIntoDoc = concatStages($replaceWithDelta(mergeObjects(root().of('left').expr(), fieldM({ a: root().of('right').expr(), b: root().of('_id').expr() }, dictId))), stagesUntilNextLookup.delta);
|
|
956
985
|
const lRunnerInput = concatStages(joinR_Delta, mergeForeignIntoDoc);
|
|
957
986
|
const rRunnerInput = concatStages(joinL_Delta, mergeForeignIntoDoc);
|
|
@@ -1185,7 +1214,7 @@ const makeWatchStream = (db, { collection, projection: p, hardMatch: m }, startA
|
|
|
1185
1214
|
};
|
|
1186
1215
|
|
|
1187
1216
|
const actions = {
|
|
1188
|
-
updateMany: (c, args) => [c.updateMany(...args), [`db['${c.collectionName}'].updateMany(
|
|
1217
|
+
updateMany: (c, args) => [c.updateMany(...args), [`db['${c.collectionName}'].updateMany(...`, args, ')']],
|
|
1189
1218
|
};
|
|
1190
1219
|
const streamNames = {};
|
|
1191
1220
|
const executes$1 = (view, input, streamName) => {
|
|
@@ -1244,7 +1273,7 @@ const executes$1 = (view, input, streamName) => {
|
|
|
1244
1273
|
params: x.params,
|
|
1245
1274
|
})),
|
|
1246
1275
|
};
|
|
1247
|
-
const step0 = () =>
|
|
1276
|
+
const step0 = () => synchronousPromise.SynchronousPromise.resolve(next(step1, 'empty new collection'));
|
|
1248
1277
|
const stop = withStop(step0);
|
|
1249
1278
|
const step1 = async () => {
|
|
1250
1279
|
await snapshotCollection.updateMany({ updated: true }, { $set: { updated: false, after: null } });
|
|
@@ -1265,9 +1294,9 @@ const executes$1 = (view, input, streamName) => {
|
|
|
1265
1294
|
params: p,
|
|
1266
1295
|
};
|
|
1267
1296
|
const [action, out] = actions[method](collection, params);
|
|
1268
|
-
log('teardown', `db
|
|
1297
|
+
log('teardown', `db['${snapshotCollection.collectionName}'].drop()`, ...out);
|
|
1269
1298
|
await Promise.all([snapshotCollection.drop(), action]);
|
|
1270
|
-
log('teardown done', `db
|
|
1299
|
+
log('teardown done', `db['${snapshotCollection.collectionName}'].drop()`, ...out);
|
|
1271
1300
|
};
|
|
1272
1301
|
if (exists && !same)
|
|
1273
1302
|
await handleTeardown(exists);
|
|
@@ -1407,7 +1436,7 @@ const executes = (view, input, streamName) => {
|
|
|
1407
1436
|
params: x.params,
|
|
1408
1437
|
})),
|
|
1409
1438
|
};
|
|
1410
|
-
const step0 = () =>
|
|
1439
|
+
const step0 = () => synchronousPromise.SynchronousPromise.resolve(next(step1, 'get last update'));
|
|
1411
1440
|
const stop = withStop(step0);
|
|
1412
1441
|
const step1 = () => Promise.all([
|
|
1413
1442
|
last.findOne({ _id: streamName, data }),
|