@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 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
- $match: {
1447
- $or: [
1448
- { $expr: { $ne: ['$fullDocument', '$fullDocumentBeforeChange'] } },
1449
- Object.fromEntries(changeKeys.map(k => [k, null])),
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$1('detected', streamName, collection.collectionName, doc);
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 types = Array.from({ length: 19 }).map((_, i) => i + 1);
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
- whenMatched: 'merge',
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.result.cursor.atClusterTime,
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 1;
1654
+ return { ts: null };
1648
1655
  })
1649
- .then(doc => (doc ? next(step2, 'restart') : step8(l))), 'wait for change');
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, result: aggResult, stream }), 'update __last', () => stream.close());
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.result.cursor.atClusterTime, data } }, { upsert: true });
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.tryNext().then(doc => (doc ? next(step1, 'restart') : step8(l)))),
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
- $match: {
1449
- $or: [
1450
- { $expr: { $ne: ['$fullDocument', '$fullDocumentBeforeChange'] } },
1451
- Object.fromEntries(changeKeys.map(k => [k, null])),
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
- console$1.log('detected', streamName, collection.collectionName, doc);
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 types = Array.from({ length: 19 }).map((_, i) => i + 1);
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
- whenMatched: 'merge',
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.result.cursor.atClusterTime,
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 1;
1656
+ return { ts: null };
1650
1657
  })
1651
- .then(doc => (doc ? next(step2, 'restart') : step8(l))), 'wait for change');
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, result: aggResult, stream }), 'update __last', () => stream.close());
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.result.cursor.atClusterTime, data } }, { upsert: true });
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.tryNext().then(doc => (doc ? next(step1, 'restart') : step8(l)))),
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;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "module": "index.esm.js",
4
4
  "typings": "index.d.ts",
5
5
  "name": "@omegup/msync",
6
- "version": "0.0.48",
6
+ "version": "0.0.50",
7
7
  "dependencies": {
8
8
  "dayjs": "^1.11.9",
9
9
  "dotenv": "^16.3.1",