@omegup/msync 0.0.48 → 0.0.50
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 +2 -1
- package/index.esm.js +46 -29
- package/index.js +46 -28
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -645,6 +645,7 @@ type MongoTypes = {
|
|
|
645
645
|
};
|
|
646
646
|
type MongoTypeNames = keyof MongoTypes;
|
|
647
647
|
declare const $type: <T extends keyof MongoTypes>(operand: rawItem & readonly T[]) => Predicate<N | MongoTypes[T]>;
|
|
648
|
+
declare const $exists: <T extends keyof MongoTypes>(operand: rawItem & boolean) => Predicate<unknown>;
|
|
648
649
|
|
|
649
650
|
declare const $expr: <D extends O, C>(expr: Expr<boolean, D, C>) => Query<D, C>;
|
|
650
651
|
|
|
@@ -675,4 +676,4 @@ declare const enablePreAndPostImages: <T extends doc>(coll: Collection<T>) => Pr
|
|
|
675
676
|
declare const prepare: (testName?: string) => Promise<MongoClient$1>;
|
|
676
677
|
declare const makeCol: <T extends ID>(docs: readonly OptionalUnlessRequiredId<T>[], database: Db, name?: string) => Promise<Collection<T>>;
|
|
677
678
|
|
|
678
|
-
export { $accumulator, $and, $countDict, $entries, $eq, $expr, $getField, $group, $groupId, $groupMerge, $gt, $gtTs, $gte, $gteTs, $ifNull, $in, $insert, $insertX, $keys, $let, $lookup, $lt, $lte, $map, $map1, $match, $matchDelta, $merge, $merge_, $ne, $nin, $nor, $or, $outerLookup, $pushDict, $rand, $replaceWith, $set, $simpleInsert, $simpleMerge, $sum, $type, $unwind, $unwindDelta, type Accumulators, type Arr, type AsLiteral, type Delta, type DeltaAccumulator, type DeltaAccumulators, Expr, type ExprHKT, type Exprs, type ExprsExact, type ExprsExactHKT, type ExprsPart, Field, type ID, type Loose, Machine, type Merge, type MergeArgs, type MergeInto, type MergeMapOArgs, type Model, type MongoTypeNames, type N, type NoRaw, type NullToOBJ, type O, type OPick, type OPickD, type RONoRaw, type RORec, type RawStages, type Rec, type Replace, type SnapshotStreamExecutionResult, type StrKey, type Strict, type TS, Type, type WriteonlyCollection, add, and, array, ceil, comp, concat, concatArray, createIndex, ctx, current, dateAdd, dateDiff, dateLt, datePart, dayAndMonthPart, divide, type doc, enablePreAndPostImages, eq, eqTyped, except, exprMapVal, field, fieldF, fieldM, filter, filterDefined, first, firstSure, floor, from, func, gt, gte, inArray, isArray, ite, last, log, lt, lte, makeCol, map1, mapVal, max, maxDate, mergeExact, mergeExact0, mergeExpr, mergeObjects, minDate, monthPart, multiply, ne, nil, noop, type notArr, notNull, now, or, pair, prepare, rand, range, root, set, setField, size, slice, sortArray, staging, startOf, str, sub, subtract, to, toInt, val, weekPart, wrap, year };
|
|
679
|
+
export { $accumulator, $and, $countDict, $entries, $eq, $exists, $expr, $getField, $group, $groupId, $groupMerge, $gt, $gtTs, $gte, $gteTs, $ifNull, $in, $insert, $insertX, $keys, $let, $lookup, $lt, $lte, $map, $map1, $match, $matchDelta, $merge, $merge_, $ne, $nin, $nor, $or, $outerLookup, $pushDict, $rand, $replaceWith, $set, $simpleInsert, $simpleMerge, $sum, $type, $unwind, $unwindDelta, type Accumulators, type Arr, type AsLiteral, type Delta, type DeltaAccumulator, type DeltaAccumulators, Expr, type ExprHKT, type Exprs, type ExprsExact, type ExprsExactHKT, type ExprsPart, Field, type ID, type Loose, Machine, type Merge, type MergeArgs, type MergeInto, type MergeMapOArgs, type Model, type MongoTypeNames, type N, type NoRaw, type NullToOBJ, type O, type OPick, type OPickD, type RONoRaw, type RORec, type RawStages, type Rec, type Replace, type SnapshotStreamExecutionResult, type StrKey, type Strict, type TS, Type, type WriteonlyCollection, add, and, array, ceil, comp, concat, concatArray, createIndex, ctx, current, dateAdd, dateDiff, dateLt, datePart, dayAndMonthPart, divide, type doc, enablePreAndPostImages, eq, eqTyped, except, exprMapVal, field, fieldF, fieldM, filter, filterDefined, first, firstSure, floor, from, func, gt, gte, inArray, isArray, ite, last, log, lt, lte, makeCol, map1, mapVal, max, maxDate, mergeExact, mergeExact0, mergeExpr, mergeObjects, minDate, monthPart, multiply, ne, nil, noop, type notArr, notNull, now, or, pair, prepare, rand, range, root, set, setField, size, slice, sortArray, staging, startOf, str, sub, subtract, to, toInt, val, weekPart, wrap, year };
|
package/index.esm.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { UUID, MongoClient } from 'mongodb';
|
|
2
2
|
import { SynchronousPromise } from 'synchronous-promise';
|
|
3
3
|
import crypto$1 from 'crypto';
|
|
4
|
-
import { log as log$1 } from 'console';
|
|
5
4
|
import { writeFile } from 'fs/promises';
|
|
6
5
|
|
|
7
6
|
const asExprRaw = (raw) => ({ get: () => raw });
|
|
@@ -900,6 +899,7 @@ const dateLt = comp('$lt');
|
|
|
900
899
|
const $gte = comp('$gte');
|
|
901
900
|
const $lte = comp('$lte');
|
|
902
901
|
const $type = operator()('$type');
|
|
902
|
+
const $exists = operator()('$exists');
|
|
903
903
|
|
|
904
904
|
const $expr = (expr) => ({
|
|
905
905
|
raw: f => ({ $expr: expr.raw(f).get() }),
|
|
@@ -1382,16 +1382,16 @@ const replace = (s) => s.replace(/\{"\$timestamp":"(\d+)"\}/g, (_, d) => T(d));
|
|
|
1382
1382
|
const json = (a) => replace(JSON.stringify(a));
|
|
1383
1383
|
const log = (...args) => console.log(new Date(), ...args.map(a => (typeof a === 'function' ? a(replace) : a && typeof a === 'object' ? json(a) : a)));
|
|
1384
1384
|
|
|
1385
|
-
const aggregate = (input, snapshot = true, start = Date.now()) => input(({ coll, input }) => {
|
|
1385
|
+
const aggregate = (streamName, input, snapshot = true, start = Date.now()) => input(({ coll, input }) => {
|
|
1386
1386
|
const req = {
|
|
1387
1387
|
aggregate: coll.collectionName,
|
|
1388
1388
|
pipeline: input,
|
|
1389
1389
|
cursor: {},
|
|
1390
1390
|
...(snapshot && { readConcern: { level: 'snapshot' } }),
|
|
1391
1391
|
};
|
|
1392
|
-
log('exec', req);
|
|
1392
|
+
log('exec', streamName, req);
|
|
1393
1393
|
return coll.s.db.command(req).then(result => {
|
|
1394
|
-
log('execed', req, result, 'took', Date.now() - start);
|
|
1394
|
+
log('execed', streamName, req, result, 'took', Date.now() - start);
|
|
1395
1395
|
return result;
|
|
1396
1396
|
}, err => {
|
|
1397
1397
|
log('err', req, err);
|
|
@@ -1443,11 +1443,19 @@ const makeWatchStream = (db, { collection, projection: p, hardMatch: m }, startA
|
|
|
1443
1443
|
},
|
|
1444
1444
|
});
|
|
1445
1445
|
pipeline.push({
|
|
1446
|
-
$
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1446
|
+
$replaceWith: {
|
|
1447
|
+
ts: {
|
|
1448
|
+
$cond: {
|
|
1449
|
+
if: {
|
|
1450
|
+
$or: [
|
|
1451
|
+
{ $ne: ['$fullDocument', '$fullDocumentBeforeChange'] },
|
|
1452
|
+
{ $and: changeKeys.map(k => ({ $eq: [k, null] })) },
|
|
1453
|
+
],
|
|
1454
|
+
},
|
|
1455
|
+
then: '$clusterTime',
|
|
1456
|
+
else: null,
|
|
1457
|
+
},
|
|
1458
|
+
},
|
|
1451
1459
|
},
|
|
1452
1460
|
});
|
|
1453
1461
|
const stream = db.collection(collection.collectionName).watch(pipeline, {
|
|
@@ -1460,7 +1468,7 @@ const makeWatchStream = (db, { collection, projection: p, hardMatch: m }, startA
|
|
|
1460
1468
|
if (doc)
|
|
1461
1469
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
1462
1470
|
if (doc)
|
|
1463
|
-
log
|
|
1471
|
+
log('detected', streamName, collection.collectionName, doc);
|
|
1464
1472
|
return doc;
|
|
1465
1473
|
};
|
|
1466
1474
|
return { tryNext, close: () => stream.close() };
|
|
@@ -1483,12 +1491,7 @@ const executes$1 = (view, input, streamName) => {
|
|
|
1483
1491
|
else if (streamNames[streamName] != hash)
|
|
1484
1492
|
throw new Error(`streamName ${streamName} already used`);
|
|
1485
1493
|
const { collection, projection, hardMatch: pre, match } = view;
|
|
1486
|
-
const
|
|
1487
|
-
const removeNotYetSynchronizedFields = Object.values(mapExactToObject(projection, (_, k) => k.startsWith('_')
|
|
1488
|
-
? root()
|
|
1489
|
-
.of(k)
|
|
1490
|
-
.has($type(types.filter(x => x != 10)))
|
|
1491
|
-
: null));
|
|
1494
|
+
const removeNotYetSynchronizedFields = Object.values(mapExactToObject(projection, (_, k) => k.startsWith('_') ? root().of(k).has($exists(true)) : null));
|
|
1492
1495
|
const hardMatch = $and(pre, ...removeNotYetSynchronizedFields);
|
|
1493
1496
|
const job = {};
|
|
1494
1497
|
const db = collection.s.db, coll = collection.collectionName;
|
|
@@ -1588,10 +1591,14 @@ const executes$1 = (view, input, streamName) => {
|
|
|
1588
1591
|
.with($merge_({
|
|
1589
1592
|
into: snapshotCollection,
|
|
1590
1593
|
on: root().of('_id'),
|
|
1591
|
-
|
|
1594
|
+
stages: 'ctx',
|
|
1595
|
+
vars: {
|
|
1596
|
+
new: ['new', root().expr()],
|
|
1597
|
+
},
|
|
1598
|
+
whenMatched: link().with($replaceWith_(ite(eq(root().of('before').expr())(ctx()('new').of('after').expr()), root().expr(), mergeObjects(root().expr(), ctx()('new').expr())))).stages,
|
|
1592
1599
|
whenNotMatched: 'insert',
|
|
1593
1600
|
})).stages;
|
|
1594
|
-
const r = await aggregate(c => c({ coll: collection, input: cloneIntoNew }));
|
|
1601
|
+
const r = await aggregate(streamName, c => c({ coll: collection, input: cloneIntoNew }));
|
|
1595
1602
|
await snapshotCollection.deleteMany({ updated: true, after: null, before: null });
|
|
1596
1603
|
return next(step4({ result: r, ts: lastTS?.ts }), 'run the aggregation');
|
|
1597
1604
|
};
|
|
@@ -1599,7 +1606,7 @@ const executes$1 = (view, input, streamName) => {
|
|
|
1599
1606
|
const step4 = ({ result, ts }) => async () => {
|
|
1600
1607
|
const start = Date.now();
|
|
1601
1608
|
await snapshotCollection.updateMany({ before: null }, { $set: { before: null } });
|
|
1602
|
-
const aggResult = await aggregate(c => c({
|
|
1609
|
+
const aggResult = await aggregate(streamName, c => c({
|
|
1603
1610
|
coll: snapshotCollection,
|
|
1604
1611
|
input: link()
|
|
1605
1612
|
.with($match_(root().of('updated').has($eq(true))))
|
|
@@ -1608,7 +1615,7 @@ const executes$1 = (view, input, streamName) => {
|
|
|
1608
1615
|
.with(finalInput.raw(ts === undefined)).stages,
|
|
1609
1616
|
}), false, start);
|
|
1610
1617
|
const stream = makeStream(result.cursor.atClusterTime);
|
|
1611
|
-
return next(step5({ result, aggResult, stream }), 'remove handled deleted updated', () => stream.close());
|
|
1618
|
+
return next(step5({ ts: result.cursor.atClusterTime, aggResult, stream }), 'remove handled deleted updated', () => stream.close());
|
|
1612
1619
|
};
|
|
1613
1620
|
const step5 = (l) => async () => {
|
|
1614
1621
|
log(`remove handled deleted updated db['${snapshotCollection.collectionName}'].deleteMany({ updated: true, after: null })`);
|
|
@@ -1633,7 +1640,7 @@ const executes$1 = (view, input, streamName) => {
|
|
|
1633
1640
|
const step7 = (l) => async () => {
|
|
1634
1641
|
await last.updateOne({ _id: streamName }, {
|
|
1635
1642
|
$set: {
|
|
1636
|
-
ts: l.
|
|
1643
|
+
ts: l.ts,
|
|
1637
1644
|
data,
|
|
1638
1645
|
},
|
|
1639
1646
|
}, { upsert: true });
|
|
@@ -1642,11 +1649,15 @@ const executes$1 = (view, input, streamName) => {
|
|
|
1642
1649
|
const step8 = (l) => {
|
|
1643
1650
|
return nextData(l.aggResult.cursor.firstBatch)(() => l.stream
|
|
1644
1651
|
.tryNext()
|
|
1645
|
-
.catch(err => {
|
|
1652
|
+
.catch((err) => {
|
|
1646
1653
|
log('restarting', err);
|
|
1647
|
-
return
|
|
1654
|
+
return { ts: null };
|
|
1648
1655
|
})
|
|
1649
|
-
.then(doc =>
|
|
1656
|
+
.then(doc => doc
|
|
1657
|
+
? doc.ts
|
|
1658
|
+
? next(step7({ ...l, ts: doc.ts }), 'nothing changed')
|
|
1659
|
+
: next(step2, 'restart')
|
|
1660
|
+
: step8(l)), 'wait for change');
|
|
1650
1661
|
};
|
|
1651
1662
|
return stop;
|
|
1652
1663
|
};
|
|
@@ -1736,7 +1747,7 @@ const executes = (view, input, streamName) => {
|
|
|
1736
1747
|
const makeStream = (startAt) => makeWatchStream(db, view, startAt, streamName);
|
|
1737
1748
|
const step4 = (lastTS) => async () => {
|
|
1738
1749
|
const hardQuery = $and(lastTS && root().of('touchedAt').has($gteTs(lastTS.ts)), hardMatch, notDeleted, match && $expr(match));
|
|
1739
|
-
const aggResult = await aggregate(c => c({
|
|
1750
|
+
const aggResult = await aggregate(streamName, c => c({
|
|
1740
1751
|
coll: collection,
|
|
1741
1752
|
input: link()
|
|
1742
1753
|
.with($match_(hardQuery))
|
|
@@ -1745,17 +1756,23 @@ const executes = (view, input, streamName) => {
|
|
|
1745
1756
|
.with(finalInput.raw(lastTS === null)).stages,
|
|
1746
1757
|
}));
|
|
1747
1758
|
const stream = makeStream(aggResult.cursor.atClusterTime);
|
|
1748
|
-
return next(step7({ aggResult,
|
|
1759
|
+
return next(step7({ aggResult, ts: aggResult.cursor.atClusterTime, stream }), 'update __last', () => stream.close());
|
|
1749
1760
|
};
|
|
1750
1761
|
const step7 = (l) => async () => {
|
|
1751
|
-
await last.updateOne({ _id: streamName }, { $set: { ts: l.
|
|
1762
|
+
await last.updateOne({ _id: streamName }, { $set: { ts: l.ts, data } }, { upsert: true });
|
|
1752
1763
|
return step8(l);
|
|
1753
1764
|
};
|
|
1754
1765
|
const step8 = (l) => {
|
|
1755
1766
|
return {
|
|
1756
1767
|
data: l.aggResult.cursor.firstBatch,
|
|
1757
1768
|
info: { job: undefined, debug: 'wait for change' },
|
|
1758
|
-
cont: withStop(() => l.stream
|
|
1769
|
+
cont: withStop(() => l.stream
|
|
1770
|
+
.tryNext()
|
|
1771
|
+
.then(doc => doc
|
|
1772
|
+
? doc.ts
|
|
1773
|
+
? next(step7({ ...l, ts: doc.ts }), 'nothing changed')
|
|
1774
|
+
: next(step1, 'restart')
|
|
1775
|
+
: step8(l))),
|
|
1759
1776
|
};
|
|
1760
1777
|
};
|
|
1761
1778
|
return stop;
|
|
@@ -1810,4 +1827,4 @@ const makeCol = async (docs, database, name) => {
|
|
|
1810
1827
|
}
|
|
1811
1828
|
};
|
|
1812
1829
|
|
|
1813
|
-
export { $accumulator, $and, $countDict, $entries, $eq, $expr, $getField, $group, $groupId, $groupMerge, $gt, $gtTs, $gte, $gteTs, $ifNull, $in, $insert, $insertX, $keys, $let, $lookup, $lt, $lte, $map, $map1, $match, $matchDelta, $merge, $merge_, $ne, $nin, $nor, $or, $outerLookup, $pushDict, $rand, $replaceWith, $set, $simpleInsert, $simpleMerge, $sum, $type, $unwind, $unwindDelta, Field, Machine, add, and, array, ceil, comp, concat$1 as concat, concatArray, createIndex, ctx, current, dateAdd, dateDiff, dateLt, datePart, dayAndMonthPart, divide, enablePreAndPostImages, eq, eqTyped, except, exprMapVal, field, fieldF, fieldM, filter, filterDefined, first$1 as first, firstSure, floor, from, func, gt, gte, inArray, isArray, ite, last, log, lt, lte, makeCol, map1, mapVal, max, maxDate, mergeExact, mergeExact0, mergeExpr, mergeObjects, minDate, monthPart, multiply, ne, nil, noop, notNull, now, or, pair, prepare, rand, range, root, set, setField, size, slice, sortArray, staging, startOf, str, sub, subtract, to, toInt, val, weekPart, wrap, year };
|
|
1830
|
+
export { $accumulator, $and, $countDict, $entries, $eq, $exists, $expr, $getField, $group, $groupId, $groupMerge, $gt, $gtTs, $gte, $gteTs, $ifNull, $in, $insert, $insertX, $keys, $let, $lookup, $lt, $lte, $map, $map1, $match, $matchDelta, $merge, $merge_, $ne, $nin, $nor, $or, $outerLookup, $pushDict, $rand, $replaceWith, $set, $simpleInsert, $simpleMerge, $sum, $type, $unwind, $unwindDelta, Field, Machine, add, and, array, ceil, comp, concat$1 as concat, concatArray, createIndex, ctx, current, dateAdd, dateDiff, dateLt, datePart, dayAndMonthPart, divide, enablePreAndPostImages, eq, eqTyped, except, exprMapVal, field, fieldF, fieldM, filter, filterDefined, first$1 as first, firstSure, floor, from, func, gt, gte, inArray, isArray, ite, last, log, lt, lte, makeCol, map1, mapVal, max, maxDate, mergeExact, mergeExact0, mergeExpr, mergeObjects, minDate, monthPart, multiply, ne, nil, noop, notNull, now, or, pair, prepare, rand, range, root, set, setField, size, slice, sortArray, staging, startOf, str, sub, subtract, to, toInt, val, weekPart, wrap, year };
|
package/index.js
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
var mongodb = require('mongodb');
|
|
4
4
|
var synchronousPromise = require('synchronous-promise');
|
|
5
5
|
var crypto$1 = require('crypto');
|
|
6
|
-
var console$1 = require('console');
|
|
7
6
|
var promises = require('fs/promises');
|
|
8
7
|
|
|
9
8
|
const asExprRaw = (raw) => ({ get: () => raw });
|
|
@@ -902,6 +901,7 @@ const dateLt = comp('$lt');
|
|
|
902
901
|
const $gte = comp('$gte');
|
|
903
902
|
const $lte = comp('$lte');
|
|
904
903
|
const $type = operator()('$type');
|
|
904
|
+
const $exists = operator()('$exists');
|
|
905
905
|
|
|
906
906
|
const $expr = (expr) => ({
|
|
907
907
|
raw: f => ({ $expr: expr.raw(f).get() }),
|
|
@@ -1384,16 +1384,16 @@ const replace = (s) => s.replace(/\{"\$timestamp":"(\d+)"\}/g, (_, d) => T(d));
|
|
|
1384
1384
|
const json = (a) => replace(JSON.stringify(a));
|
|
1385
1385
|
const log = (...args) => console.log(new Date(), ...args.map(a => (typeof a === 'function' ? a(replace) : a && typeof a === 'object' ? json(a) : a)));
|
|
1386
1386
|
|
|
1387
|
-
const aggregate = (input, snapshot = true, start = Date.now()) => input(({ coll, input }) => {
|
|
1387
|
+
const aggregate = (streamName, input, snapshot = true, start = Date.now()) => input(({ coll, input }) => {
|
|
1388
1388
|
const req = {
|
|
1389
1389
|
aggregate: coll.collectionName,
|
|
1390
1390
|
pipeline: input,
|
|
1391
1391
|
cursor: {},
|
|
1392
1392
|
...(snapshot && { readConcern: { level: 'snapshot' } }),
|
|
1393
1393
|
};
|
|
1394
|
-
log('exec', req);
|
|
1394
|
+
log('exec', streamName, req);
|
|
1395
1395
|
return coll.s.db.command(req).then(result => {
|
|
1396
|
-
log('execed', req, result, 'took', Date.now() - start);
|
|
1396
|
+
log('execed', streamName, req, result, 'took', Date.now() - start);
|
|
1397
1397
|
return result;
|
|
1398
1398
|
}, err => {
|
|
1399
1399
|
log('err', req, err);
|
|
@@ -1445,11 +1445,19 @@ const makeWatchStream = (db, { collection, projection: p, hardMatch: m }, startA
|
|
|
1445
1445
|
},
|
|
1446
1446
|
});
|
|
1447
1447
|
pipeline.push({
|
|
1448
|
-
$
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1448
|
+
$replaceWith: {
|
|
1449
|
+
ts: {
|
|
1450
|
+
$cond: {
|
|
1451
|
+
if: {
|
|
1452
|
+
$or: [
|
|
1453
|
+
{ $ne: ['$fullDocument', '$fullDocumentBeforeChange'] },
|
|
1454
|
+
{ $and: changeKeys.map(k => ({ $eq: [k, null] })) },
|
|
1455
|
+
],
|
|
1456
|
+
},
|
|
1457
|
+
then: '$clusterTime',
|
|
1458
|
+
else: null,
|
|
1459
|
+
},
|
|
1460
|
+
},
|
|
1453
1461
|
},
|
|
1454
1462
|
});
|
|
1455
1463
|
const stream = db.collection(collection.collectionName).watch(pipeline, {
|
|
@@ -1462,7 +1470,7 @@ const makeWatchStream = (db, { collection, projection: p, hardMatch: m }, startA
|
|
|
1462
1470
|
if (doc)
|
|
1463
1471
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
1464
1472
|
if (doc)
|
|
1465
|
-
|
|
1473
|
+
log('detected', streamName, collection.collectionName, doc);
|
|
1466
1474
|
return doc;
|
|
1467
1475
|
};
|
|
1468
1476
|
return { tryNext, close: () => stream.close() };
|
|
@@ -1485,12 +1493,7 @@ const executes$1 = (view, input, streamName) => {
|
|
|
1485
1493
|
else if (streamNames[streamName] != hash)
|
|
1486
1494
|
throw new Error(`streamName ${streamName} already used`);
|
|
1487
1495
|
const { collection, projection, hardMatch: pre, match } = view;
|
|
1488
|
-
const
|
|
1489
|
-
const removeNotYetSynchronizedFields = Object.values(mapExactToObject(projection, (_, k) => k.startsWith('_')
|
|
1490
|
-
? root()
|
|
1491
|
-
.of(k)
|
|
1492
|
-
.has($type(types.filter(x => x != 10)))
|
|
1493
|
-
: null));
|
|
1496
|
+
const removeNotYetSynchronizedFields = Object.values(mapExactToObject(projection, (_, k) => k.startsWith('_') ? root().of(k).has($exists(true)) : null));
|
|
1494
1497
|
const hardMatch = $and(pre, ...removeNotYetSynchronizedFields);
|
|
1495
1498
|
const job = {};
|
|
1496
1499
|
const db = collection.s.db, coll = collection.collectionName;
|
|
@@ -1590,10 +1593,14 @@ const executes$1 = (view, input, streamName) => {
|
|
|
1590
1593
|
.with($merge_({
|
|
1591
1594
|
into: snapshotCollection,
|
|
1592
1595
|
on: root().of('_id'),
|
|
1593
|
-
|
|
1596
|
+
stages: 'ctx',
|
|
1597
|
+
vars: {
|
|
1598
|
+
new: ['new', root().expr()],
|
|
1599
|
+
},
|
|
1600
|
+
whenMatched: link().with($replaceWith_(ite(eq(root().of('before').expr())(ctx()('new').of('after').expr()), root().expr(), mergeObjects(root().expr(), ctx()('new').expr())))).stages,
|
|
1594
1601
|
whenNotMatched: 'insert',
|
|
1595
1602
|
})).stages;
|
|
1596
|
-
const r = await aggregate(c => c({ coll: collection, input: cloneIntoNew }));
|
|
1603
|
+
const r = await aggregate(streamName, c => c({ coll: collection, input: cloneIntoNew }));
|
|
1597
1604
|
await snapshotCollection.deleteMany({ updated: true, after: null, before: null });
|
|
1598
1605
|
return next(step4({ result: r, ts: lastTS?.ts }), 'run the aggregation');
|
|
1599
1606
|
};
|
|
@@ -1601,7 +1608,7 @@ const executes$1 = (view, input, streamName) => {
|
|
|
1601
1608
|
const step4 = ({ result, ts }) => async () => {
|
|
1602
1609
|
const start = Date.now();
|
|
1603
1610
|
await snapshotCollection.updateMany({ before: null }, { $set: { before: null } });
|
|
1604
|
-
const aggResult = await aggregate(c => c({
|
|
1611
|
+
const aggResult = await aggregate(streamName, c => c({
|
|
1605
1612
|
coll: snapshotCollection,
|
|
1606
1613
|
input: link()
|
|
1607
1614
|
.with($match_(root().of('updated').has($eq(true))))
|
|
@@ -1610,7 +1617,7 @@ const executes$1 = (view, input, streamName) => {
|
|
|
1610
1617
|
.with(finalInput.raw(ts === undefined)).stages,
|
|
1611
1618
|
}), false, start);
|
|
1612
1619
|
const stream = makeStream(result.cursor.atClusterTime);
|
|
1613
|
-
return next(step5({ result, aggResult, stream }), 'remove handled deleted updated', () => stream.close());
|
|
1620
|
+
return next(step5({ ts: result.cursor.atClusterTime, aggResult, stream }), 'remove handled deleted updated', () => stream.close());
|
|
1614
1621
|
};
|
|
1615
1622
|
const step5 = (l) => async () => {
|
|
1616
1623
|
log(`remove handled deleted updated db['${snapshotCollection.collectionName}'].deleteMany({ updated: true, after: null })`);
|
|
@@ -1635,7 +1642,7 @@ const executes$1 = (view, input, streamName) => {
|
|
|
1635
1642
|
const step7 = (l) => async () => {
|
|
1636
1643
|
await last.updateOne({ _id: streamName }, {
|
|
1637
1644
|
$set: {
|
|
1638
|
-
ts: l.
|
|
1645
|
+
ts: l.ts,
|
|
1639
1646
|
data,
|
|
1640
1647
|
},
|
|
1641
1648
|
}, { upsert: true });
|
|
@@ -1644,11 +1651,15 @@ const executes$1 = (view, input, streamName) => {
|
|
|
1644
1651
|
const step8 = (l) => {
|
|
1645
1652
|
return nextData(l.aggResult.cursor.firstBatch)(() => l.stream
|
|
1646
1653
|
.tryNext()
|
|
1647
|
-
.catch(err => {
|
|
1654
|
+
.catch((err) => {
|
|
1648
1655
|
log('restarting', err);
|
|
1649
|
-
return
|
|
1656
|
+
return { ts: null };
|
|
1650
1657
|
})
|
|
1651
|
-
.then(doc =>
|
|
1658
|
+
.then(doc => doc
|
|
1659
|
+
? doc.ts
|
|
1660
|
+
? next(step7({ ...l, ts: doc.ts }), 'nothing changed')
|
|
1661
|
+
: next(step2, 'restart')
|
|
1662
|
+
: step8(l)), 'wait for change');
|
|
1652
1663
|
};
|
|
1653
1664
|
return stop;
|
|
1654
1665
|
};
|
|
@@ -1738,7 +1749,7 @@ const executes = (view, input, streamName) => {
|
|
|
1738
1749
|
const makeStream = (startAt) => makeWatchStream(db, view, startAt, streamName);
|
|
1739
1750
|
const step4 = (lastTS) => async () => {
|
|
1740
1751
|
const hardQuery = $and(lastTS && root().of('touchedAt').has($gteTs(lastTS.ts)), hardMatch, notDeleted, match && $expr(match));
|
|
1741
|
-
const aggResult = await aggregate(c => c({
|
|
1752
|
+
const aggResult = await aggregate(streamName, c => c({
|
|
1742
1753
|
coll: collection,
|
|
1743
1754
|
input: link()
|
|
1744
1755
|
.with($match_(hardQuery))
|
|
@@ -1747,17 +1758,23 @@ const executes = (view, input, streamName) => {
|
|
|
1747
1758
|
.with(finalInput.raw(lastTS === null)).stages,
|
|
1748
1759
|
}));
|
|
1749
1760
|
const stream = makeStream(aggResult.cursor.atClusterTime);
|
|
1750
|
-
return next(step7({ aggResult,
|
|
1761
|
+
return next(step7({ aggResult, ts: aggResult.cursor.atClusterTime, stream }), 'update __last', () => stream.close());
|
|
1751
1762
|
};
|
|
1752
1763
|
const step7 = (l) => async () => {
|
|
1753
|
-
await last.updateOne({ _id: streamName }, { $set: { ts: l.
|
|
1764
|
+
await last.updateOne({ _id: streamName }, { $set: { ts: l.ts, data } }, { upsert: true });
|
|
1754
1765
|
return step8(l);
|
|
1755
1766
|
};
|
|
1756
1767
|
const step8 = (l) => {
|
|
1757
1768
|
return {
|
|
1758
1769
|
data: l.aggResult.cursor.firstBatch,
|
|
1759
1770
|
info: { job: undefined, debug: 'wait for change' },
|
|
1760
|
-
cont: withStop(() => l.stream
|
|
1771
|
+
cont: withStop(() => l.stream
|
|
1772
|
+
.tryNext()
|
|
1773
|
+
.then(doc => doc
|
|
1774
|
+
? doc.ts
|
|
1775
|
+
? next(step7({ ...l, ts: doc.ts }), 'nothing changed')
|
|
1776
|
+
: next(step1, 'restart')
|
|
1777
|
+
: step8(l))),
|
|
1761
1778
|
};
|
|
1762
1779
|
};
|
|
1763
1780
|
return stop;
|
|
@@ -1817,6 +1834,7 @@ exports.$and = $and;
|
|
|
1817
1834
|
exports.$countDict = $countDict;
|
|
1818
1835
|
exports.$entries = $entries;
|
|
1819
1836
|
exports.$eq = $eq;
|
|
1837
|
+
exports.$exists = $exists;
|
|
1820
1838
|
exports.$expr = $expr;
|
|
1821
1839
|
exports.$getField = $getField;
|
|
1822
1840
|
exports.$group = $group;
|