@omegup/msync 0.1.20 → 0.1.22

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.
Files changed (92) hide show
  1. package/index.d.ts +4 -8
  2. package/index.esm.js +146 -71
  3. package/index.js +145 -71
  4. package/lib/accumulators/index.d.ts +10 -0
  5. package/lib/aggregate/$merge.d.ts +28 -0
  6. package/lib/aggregate/$upsert.d.ts +15 -0
  7. package/lib/aggregate/group/$group-merge.d.ts +12 -0
  8. package/lib/aggregate/group/index.d.ts +2 -0
  9. package/lib/aggregate/group/utils/sub-group.d.ts +6 -0
  10. package/lib/aggregate/group/utils/sub-merge.d.ts +20 -0
  11. package/lib/aggregate/index.d.ts +9 -0
  12. package/lib/aggregate/lookup/$lookup-delta.d.ts +10 -0
  13. package/lib/aggregate/lookup/$lookup-raw.d.ts +9 -0
  14. package/lib/aggregate/lookup/index.d.ts +12 -0
  15. package/lib/aggregate/match/$match-delta.d.ts +3 -0
  16. package/lib/aggregate/match/$match.d.ts +3 -0
  17. package/lib/aggregate/match/index.d.ts +2 -0
  18. package/lib/aggregate/mongo-stages.d.ts +13 -0
  19. package/lib/aggregate/out.d.ts +37 -0
  20. package/lib/aggregate/prefix.d.ts +33 -0
  21. package/lib/aggregate/raws.d.ts +17 -0
  22. package/lib/aggregate/set/$replace-with-each.d.ts +13 -0
  23. package/lib/aggregate/set/$set-delta.d.ts +5 -0
  24. package/lib/aggregate/set/$set.d.ts +6 -0
  25. package/lib/aggregate/set/index.d.ts +1 -0
  26. package/lib/aggregate/unwind/$unwind-delta.d.ts +5 -0
  27. package/lib/aggregate/unwind/index.d.ts +6 -0
  28. package/lib/boot/boot-simpl.d.ts +14 -0
  29. package/lib/boot/boot-utils.d.ts +27 -0
  30. package/lib/boot/boot.d.ts +16 -0
  31. package/lib/boot/first-stages.d.ts +12 -0
  32. package/lib/boot/index.d.ts +3 -0
  33. package/lib/boot/single.d.ts +11 -0
  34. package/lib/expression/arith.d.ts +32 -0
  35. package/lib/expression/array.d.ts +30 -0
  36. package/lib/expression/concat.d.ts +34 -0
  37. package/lib/expression/date.d.ts +17 -0
  38. package/lib/expression/expr-base.d.ts +5 -0
  39. package/lib/expression/index.d.ts +7 -0
  40. package/lib/expression/logic.d.ts +23 -0
  41. package/lib/expression/range.d.ts +11 -0
  42. package/lib/expression/val.d.ts +25 -0
  43. package/lib/field/field.d.ts +25 -0
  44. package/lib/field/index.d.ts +1 -0
  45. package/lib/machine.d.ts +9 -0
  46. package/lib/predicate/$eq.d.ts +24 -0
  47. package/lib/predicate/$expr.d.ts +3 -0
  48. package/lib/predicate/$in.d.ts +2 -0
  49. package/lib/predicate/index.d.ts +3 -0
  50. package/lib/predicate/utils.d.ts +5 -0
  51. package/lib/query/index.d.ts +1 -0
  52. package/lib/query/logic.d.ts +11 -0
  53. package/lib/stream/aggregate.d.ts +7 -0
  54. package/lib/types/accumulator.d.ts +30 -0
  55. package/lib/types/aggregate.d.ts +9 -0
  56. package/lib/types/expr.d.ts +27 -0
  57. package/lib/types/extern.d.ts +3 -0
  58. package/lib/types/index.d.ts +8 -0
  59. package/lib/types/lookup.d.ts +19 -0
  60. package/lib/types/machine.d.ts +17 -0
  61. package/lib/types/predicate.d.ts +11 -0
  62. package/lib/types/query.d.ts +12 -0
  63. package/lib/types/stream.d.ts +71 -0
  64. package/lib/update/index.d.ts +1 -0
  65. package/lib/update/updater.d.ts +19 -0
  66. package/lib/utils/before.d.ts +3 -0
  67. package/lib/utils/coll.d.ts +5 -0
  68. package/lib/utils/db-indexes.d.ts +4 -0
  69. package/lib/utils/guard.d.ts +19 -0
  70. package/lib/utils/index.d.ts +4 -0
  71. package/lib/utils/json.d.ts +9 -0
  72. package/lib/utils/log.d.ts +1 -0
  73. package/lib/utils/map-object.d.ts +41 -0
  74. package/lib/utils/merge/combiners.d.ts +6 -0
  75. package/lib/utils/merge/index.d.ts +2 -0
  76. package/lib/utils/merge/merge.d.ts +10 -0
  77. package/lib/utils/merge/next-winner.d.ts +3 -0
  78. package/lib/utils/merge/types.d.ts +19 -0
  79. package/lib/utils/merge/utils.d.ts +4 -0
  80. package/lib/utils/tear-down.d.ts +2 -0
  81. package/lib/watch.d.ts +34 -0
  82. package/package.json +1 -1
  83. package/test/mongodb.d.ts +9 -0
  84. package/test/uri.d.ts +1 -0
  85. package/types/class.d.ts +1 -0
  86. package/types/extern.d.ts +3 -0
  87. package/types/global.d.ts +50 -0
  88. package/types/hkt.d.ts +56 -0
  89. package/types/index.d.ts +6 -0
  90. package/types/json.d.ts +54 -0
  91. package/types/mongo.d.ts +24 -0
  92. package/types/view.d.ts +35 -0
package/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
+ var mongodb = require('mongodb');
3
4
  var crypto$1 = require('crypto');
4
5
  var jsonCanonicalize = require('json-canonicalize');
5
6
  var synchronousPromise = require('synchronous-promise');
6
- var mongodb = require('mongodb');
7
7
  var promises = require('fs/promises');
8
8
 
9
9
  const asExprRaw = (raw) => ({ get: () => raw });
@@ -84,7 +84,7 @@ const val = (val) => asExpr({
84
84
  : val),
85
85
  });
86
86
  const current = asExpr({
87
- raw: () => asExprRaw('$$CLUSTER_TIME'),
87
+ raw: () => asExprRaw(new mongodb.MaxKey()),
88
88
  });
89
89
  const $let = (vars, inExpr) => asExpr({
90
90
  raw: f => asExprRaw({
@@ -1306,16 +1306,18 @@ const nextWinner = (previousWinner, previousWinnerNextFrame, sources, interrupt)
1306
1306
  };
1307
1307
 
1308
1308
  const mergeIterators = (params) => {
1309
- const { sources, interrupt, select = race } = params;
1309
+ const { sources, interrupt, select = race, hooks } = params;
1310
1310
  const reiterate = (winner) => {
1311
1311
  const { frame, key } = winner;
1312
1312
  return {
1313
1313
  cont: () => {
1314
1314
  const result = frame.cont();
1315
+ hooks?.start?.(frame, result);
1315
1316
  return mergeIterators({
1316
1317
  sources: patch(sources, key, result),
1317
1318
  interrupt,
1318
1319
  select: sources => nextWinner(winner, result.next, sources, interrupt),
1320
+ hooks,
1319
1321
  });
1320
1322
  },
1321
1323
  data: frame.data,
@@ -1323,7 +1325,7 @@ const mergeIterators = (params) => {
1323
1325
  };
1324
1326
  };
1325
1327
  return {
1326
- stop: () => mergeIterators({ sources: restart(sources), interrupt }),
1328
+ stop: () => mergeIterators({ sources: restart(sources), interrupt, select, hooks }),
1327
1329
  next: select(sources).then(reiterate),
1328
1330
  clear: async () => {
1329
1331
  for (const key in sources) {
@@ -1333,56 +1335,37 @@ const mergeIterators = (params) => {
1333
1335
  };
1334
1336
  };
1335
1337
 
1336
- const T = (s) => `Timestamp(${parseInt(`${BigInt(s) / 2n ** 32n}`)}, ${parseInt(`${BigInt(s) % 2n ** 32n}`)})`;
1337
- const replace = (s) => s.replace(/\{"\$timestamp":"(\d+)"\}/g, (_, d) => T(d));
1338
- const json = (a) => replace(JSON.stringify(a));
1339
- const log = (...args) => console.log(new Date(), ...args.map(a => (typeof a === 'function' ? a(replace) : a && typeof a === 'object' ? json(a) : a)));
1340
-
1341
1338
  const state = { steady: false, f: (_) => Promise.resolve() };
1342
1339
  let timeout = null;
1343
- const setF = (f) => {
1344
- state.f = f;
1345
- };
1346
- const aggregate = (db, streamName, input, snapshot = true, start = Date.now()) => input(({ coll, input }) => {
1347
- const req = {
1348
- aggregate: coll.collectionName,
1349
- pipeline: input,
1350
- cursor: {},
1351
- ...(snapshot && { readConcern: { level: 'snapshot' } }),
1352
- };
1353
- if (timeout !== null) {
1354
- clearTimeout(timeout);
1355
- timeout = null;
1356
- }
1357
- log('exec', streamName, req);
1358
- const start2 = Date.now();
1359
- return db.then(d => d.command(req)).then(result => {
1360
- log('prepare', streamName, Date.now() - start);
1361
- log('prepare2', streamName, start2 - start);
1362
- const r = result;
1363
- log('execed', streamName, (replace) => replace(JSON.stringify(req).replaceAll('"$$CLUSTER_TIME"', JSON.stringify(r.cursor.atClusterTime))), result, 'took', Date.now() - start);
1364
- if (!state.steady) {
1365
- if (timeout !== null)
1366
- throw new Error('timeout should be null');
1367
- timeout = setTimeout(() => {
1368
- state.steady = true;
1369
- console.log('steady');
1370
- }, 10000);
1371
- }
1372
- return r;
1373
- }, err => {
1374
- log('err', req, err);
1375
- throw new Error(err);
1376
- });
1377
- });
1378
-
1379
1340
  const firstWorksMerge = (iters) => {
1380
1341
  const iterator = () => {
1381
1342
  const results = iters.map(iter => iter());
1382
1343
  const sources = { ...results };
1383
1344
  return mergeIterators({
1384
1345
  sources,
1385
- interrupt: key => state.steady
1346
+ interrupt: key => false,
1347
+ hooks: {
1348
+ start: (frame, result) => {
1349
+ if (!frame.info.job)
1350
+ return;
1351
+ if (timeout !== null) {
1352
+ clearTimeout(timeout);
1353
+ timeout = null;
1354
+ }
1355
+ result.next.then(() => {
1356
+ if (!frame.info.job)
1357
+ return;
1358
+ if (!state.steady) {
1359
+ if (timeout !== null)
1360
+ clearTimeout(timeout);
1361
+ timeout = setTimeout(() => {
1362
+ state.steady = true;
1363
+ console.log('steady');
1364
+ }, 2000);
1365
+ }
1366
+ });
1367
+ },
1368
+ },
1386
1369
  });
1387
1370
  };
1388
1371
  return iterator;
@@ -1512,10 +1495,7 @@ const $insertX = (out, expr, map, ext, extExpr) => {
1512
1495
  teardown: c => c({
1513
1496
  collection: out,
1514
1497
  method: 'updateMany',
1515
- params: [
1516
- filter,
1517
- [{ $set: { deletedAt: '$$NOW', touchedAt: '$$CLUSTER_TIME' } }],
1518
- ],
1498
+ params: [filter, [{ $set: { deletedAt: '$$NOW', touchedAt: '$$CLUSTER_TIME' } }]],
1519
1499
  }),
1520
1500
  raw: () => {
1521
1501
  const replacer = map(mergeObjects(expr, field(mergeExpr(extExpr, {
@@ -1546,6 +1526,32 @@ const $insertPart = (out, ext) => {
1546
1526
  const $insert = (out) => $insertPart(out, {});
1547
1527
  const assertNotNull = (expr) => expr;
1548
1528
 
1529
+ const T = (s) => `Timestamp(${parseInt(`${BigInt(s) / 2n ** 32n}`)}, ${parseInt(`${BigInt(s) % 2n ** 32n}`)})`;
1530
+ const replace = (s) => s.replace(/\{"\$timestamp":"(\d+)"\}/g, (_, d) => T(d));
1531
+ const json = (a) => replace(JSON.stringify(a));
1532
+ const log = (...args) => console.log(new Date(), ...args.map(a => (typeof a === 'function' ? a(replace) : a && typeof a === 'object' ? json(a) : a)));
1533
+
1534
+ const aggregate = (db, streamName, input, snapshot = true, start = Date.now()) => input(({ coll, input }) => {
1535
+ const req = {
1536
+ aggregate: coll.collectionName,
1537
+ pipeline: input,
1538
+ cursor: {},
1539
+ ...(snapshot && { readConcern: { level: 'snapshot' } }),
1540
+ };
1541
+ log('exec', streamName, req);
1542
+ const start2 = Date.now();
1543
+ return db.then(d => d.command(req)).then(result => {
1544
+ log('prepare', streamName, Date.now() - start);
1545
+ log('prepare2', streamName, start2 - start);
1546
+ const r = result;
1547
+ log('execed', streamName, (replace) => replace(JSON.stringify(req).replaceAll('"$$CLUSTER_TIME"', JSON.stringify(r.cursor.atClusterTime))), result, 'took', Date.now() - start);
1548
+ return r;
1549
+ }, err => {
1550
+ log('err', req, err);
1551
+ throw new Error(err);
1552
+ });
1553
+ });
1554
+
1549
1555
  const addTeardown = (it, tr) => {
1550
1556
  if (!tr)
1551
1557
  return it;
@@ -1573,7 +1579,7 @@ async function getLastCommittedTs(adminDb) {
1573
1579
  const st = await adminDb.command({ replSetGetStatus: 1 });
1574
1580
  return st?.optimes?.lastCommittedOpTime?.ts ?? null;
1575
1581
  }
1576
- async function waitUntilStablePast(db, oplogTs, { pollMs = 0, timeoutMs = 10_000, } = {}) {
1582
+ async function waitUntilStablePast(db, oplogTs, { pollMs = 0, timeoutMs = 10_000 } = {}) {
1577
1583
  const adminDb = db.client.db('admin');
1578
1584
  const deadline = Date.now() + timeoutMs;
1579
1585
  while (true) {
@@ -1581,7 +1587,7 @@ async function waitUntilStablePast(db, oplogTs, { pollMs = 0, timeoutMs = 10_000
1581
1587
  if (stable && stable.comp(oplogTs) >= 0)
1582
1588
  return;
1583
1589
  if (Date.now() > deadline) {
1584
- throw new Error("Timed out waiting for stable timestamp to reach oplog event time");
1590
+ throw new Error('Timed out waiting for stable timestamp to reach oplog event time');
1585
1591
  }
1586
1592
  await sleep(pollMs);
1587
1593
  }
@@ -1603,29 +1609,37 @@ async function* tailOplog(db, opts) {
1603
1609
  try {
1604
1610
  for await (const doc of cursor) {
1605
1611
  lastTs = doc.ts;
1606
- if (doc.op === 'i') {
1607
- yield { ns: doc.ns, fields: new Set(Object.keys(doc.o)), doc };
1612
+ if (doc.op === 'i' || '_id' in doc.o) {
1613
+ const fields = new Set(Object.keys(doc.o));
1614
+ fields.delete('_id');
1615
+ yield { fields, doc, changeTouched: doc.o['touchedAt'] instanceof mongodb.MaxKey };
1608
1616
  }
1609
1617
  else {
1618
+ let changeTouched = false;
1610
1619
  if (doc.o['$v'] !== 2) {
1611
- throw new Error(`Expected update with $v: 2, got ${JSON.stringify(doc.o)}`);
1620
+ throw new Error(`Expected update with $v: 2, got ${JSON.stringify(doc)}`);
1612
1621
  }
1613
1622
  const updatedFields = [];
1614
1623
  const diff = doc.o['diff'];
1615
1624
  for (const updateOp in diff) {
1616
1625
  if (['u', 'i', 'd'].includes(updateOp)) {
1617
1626
  updatedFields.push(...Object.keys(diff[updateOp]));
1627
+ if (diff[updateOp]['touchedAt'] instanceof mongodb.MaxKey) {
1628
+ changeTouched = true;
1629
+ }
1618
1630
  }
1619
1631
  else if (updateOp.startsWith('s')) {
1620
1632
  updatedFields.push(updateOp.slice(1));
1621
1633
  }
1622
1634
  }
1623
- yield { ns: doc.ns, fields: new Set(updatedFields), doc };
1635
+ yield { fields: new Set(updatedFields), doc, changeTouched };
1624
1636
  }
1625
1637
  }
1626
1638
  }
1627
1639
  catch (e) {
1628
- log('oplog loop error', e);
1640
+ log('oplog loop error, notifying watchers and reopening');
1641
+ console.error(e);
1642
+ yield null;
1629
1643
  }
1630
1644
  finally {
1631
1645
  log('oplog loop ended');
@@ -1636,16 +1650,76 @@ async function* tailOplog(db, opts) {
1636
1650
  }
1637
1651
  const watchers = new Map();
1638
1652
  let running = false;
1653
+ const makePromise = () => {
1654
+ let resolve = () => { };
1655
+ let promise = new Promise(r => (resolve = r));
1656
+ return { promise, resolve };
1657
+ };
1639
1658
  const loop = async (db) => {
1640
1659
  log('starting oplog loop');
1641
- for await (const { ns, fields, doc } of tailOplog(db, {})) {
1642
- log('oplog event', ns, doc.op, [...fields]);
1643
- const m = watchers.get(ns);
1644
- if (!m)
1660
+ let notify = makePromise();
1661
+ let batch = [];
1662
+ const last = db.collection('__last');
1663
+ const run = async () => {
1664
+ for await (const event of tailOplog(db, {
1665
+ since: (await last.findOne({ _id: 'oplog' }))?.ts,
1666
+ })) {
1667
+ if (event?.fields.size === 0)
1668
+ continue;
1669
+ batch = event && batch ? [...batch, event] : null;
1670
+ notify.resolve();
1671
+ }
1672
+ };
1673
+ run();
1674
+ const iter = async function* () {
1675
+ while (true) {
1676
+ await notify.promise;
1677
+ const b = batch;
1678
+ if (b?.length) {
1679
+ last
1680
+ .updateOne({ _id: 'oplog' }, { $set: { ts: b[b.length - 1].doc.ts } }, { upsert: true })
1681
+ .catch(() => { });
1682
+ }
1683
+ batch = [];
1684
+ notify = makePromise();
1685
+ yield b;
1686
+ }
1687
+ };
1688
+ for await (const events of iter()) {
1689
+ if (!events) {
1690
+ log('notifying watchers of oplog loop restart');
1691
+ for (const m of watchers.values()) {
1692
+ for (const { cb } of m.values()) {
1693
+ cb(null);
1694
+ }
1695
+ }
1645
1696
  continue;
1646
- for (const { cb, keys } of m.values()) {
1647
- if (!keys || keys.some(k => fields.has(k))) {
1648
- cb(doc);
1697
+ }
1698
+ const groups = Object.groupBy(events.filter(e => e.changeTouched), ev => ev.doc.ns);
1699
+ for (const [ns, evs] of Object.entries(groups)) {
1700
+ if (!evs)
1701
+ continue;
1702
+ const [dbName, collName] = ns.split('.');
1703
+ if (dbName !== db.databaseName)
1704
+ continue;
1705
+ const coll = db.collection(collName);
1706
+ coll
1707
+ .bulkWrite(evs.map((e) => ({
1708
+ updateOne: {
1709
+ filter: { _id: e.doc.o['_id'] ?? e.doc.o2?._id },
1710
+ update: { $set: { touchedAt: e.doc.ts } },
1711
+ },
1712
+ })))
1713
+ .catch(() => { });
1714
+ }
1715
+ for (const { fields, doc } of events) {
1716
+ const m = watchers.get(doc.ns);
1717
+ if (!m)
1718
+ continue;
1719
+ for (const { cb, keys } of m.values()) {
1720
+ if (!keys || keys.some(k => fields.has(k))) {
1721
+ cb(doc);
1722
+ }
1649
1723
  }
1650
1724
  }
1651
1725
  }
@@ -1671,7 +1745,7 @@ const makeWatchStream = ({ collection, projection: p, hardMatch: m }, streamName
1671
1745
  const projection = { ...(p ? mapExactToObject(p, v => v) : {}), deletedAt: 1 };
1672
1746
  let resolve = (_) => { };
1673
1747
  const promise = new Promise(r => (resolve = r));
1674
- const close = register(collection, p ? Object.keys(projection) : null, (doc) => {
1748
+ const close = register(collection, p ? Object.keys(projection) : null, doc => {
1675
1749
  log(streamName, 'change detected', doc);
1676
1750
  resolve(doc);
1677
1751
  close();
@@ -1680,9 +1754,10 @@ const makeWatchStream = ({ collection, projection: p, hardMatch: m }, streamName
1680
1754
  tryNext: async () => {
1681
1755
  const doc = await promise;
1682
1756
  const start = Date.now();
1683
- await waitUntilStablePast(collection.s.db, doc.ts);
1757
+ if (doc)
1758
+ await waitUntilStablePast(collection.s.db, doc.ts);
1684
1759
  log(streamName, 'stable past took', Date.now() - start);
1685
- return doc;
1760
+ return doc ?? {};
1686
1761
  },
1687
1762
  close: async () => close(),
1688
1763
  };
@@ -1865,7 +1940,7 @@ const executes$2 = (view, input, streamName, skip = false, after, needs = {}) =>
1865
1940
  log('teardown done', `db['${snapshotCollection.collectionName}'].drop()`, ...out);
1866
1941
  };
1867
1942
  if (!same) {
1868
- log('not same, new data', data);
1943
+ log('not same, new data', streamName, data);
1869
1944
  await handleTeardown(exists ?? { data });
1870
1945
  }
1871
1946
  await after?.();
@@ -1954,8 +2029,8 @@ const executes$2 = (view, input, streamName, skip = false, after, needs = {}) =>
1954
2029
  job: null,
1955
2030
  },
1956
2031
  };
1957
- if (l.ts)
1958
- patch.$set = data;
2032
+ if (l.first)
2033
+ patch.$set = { ...patch.$set, data };
1959
2034
  await last.updateOne({ _id: streamName }, patch, { upsert: true });
1960
2035
  log('updated __last', Date.now() - start, `db['${last.collectionName}'].updateOne({ _id: '${streamName}' }, `, patch, `, { upsert: true })`);
1961
2036
  return step8(l);
@@ -2246,7 +2321,6 @@ exports.range = range;
2246
2321
  exports.regex = regex;
2247
2322
  exports.root = root;
2248
2323
  exports.set = set;
2249
- exports.setF = setF;
2250
2324
  exports.setField = setField;
2251
2325
  exports.single = single;
2252
2326
  exports.size = size;
@@ -0,0 +1,10 @@
1
+ import type { AppMap, Arr, N, O, Rec } from '../../types';
2
+ import type { ExprHKT } from '../expression/concat';
3
+ import { type NoRaw } from '../expression/val';
4
+ import type { DeltaAccumulator, Expr, Part } from '../types';
5
+ export declare const $sum: <D extends O, C = unknown>(expr: Expr<number | N, D, C>) => DeltaAccumulator<D, number, C>;
6
+ export declare const $accumulator: <D, T, Ctx, A extends readonly unknown[]>(init: () => NoRaw<T>, accumulateArgs: AppMap<ExprHKT<Part<D>, Ctx>, A>, accumulate: (a: NoRaw<T>, ...args: NoRaw<A>) => NoRaw<T>, merge: (...args: NoRaw<[T | N, T]>) => NoRaw<T>) => DeltaAccumulator<D, T, Ctx>;
7
+ export declare const $countDict: <D extends O, C = unknown>(expr: Expr<string, D, C>) => DeltaAccumulator<D, Rec<string, number>, C>;
8
+ export declare const $pushDict: <D extends O, V, C = unknown>(key: Expr<string, D, C>, value: Expr<V, D, C>) => DeltaAccumulator<D, Rec<string, Rec<"0" | "1", Arr<V>>>, C>;
9
+ export declare const $keys: <D extends O, C = unknown>(expr: Expr<Rec<string, number>, D, C>) => Expr<Arr<string>, D, C>;
10
+ export declare const $entries: <D extends O, V, C = unknown>(expr: Expr<Rec<string, Rec<"1" | "0", Arr<V>>>, D, C>) => Expr<Arr<Rec<"k", string> & Rec<"v", V>>, D, C>;
@@ -0,0 +1,28 @@
1
+ import type { IdHKT, OPick, RWCollection, Timestamp } from '../../types';
2
+ import type { doc, ID, N, O, rawItem, Rec, Replace, RORec, StrKey } from '../../types/json';
3
+ import { type ExprsExact } from '../expression/concat';
4
+ import type { Delta, Expr, IsDeleted, Model, RawStages, StreamRunnerParam, TS } from '../types';
5
+ import { type Exact } from '../utils/map-object';
6
+ type OutInputE<T, E, A = T | null> = ID & Rec<'after', A> & E;
7
+ type Allowed<K extends string> = Exclude<K, keyof (TS & ID)>;
8
+ export type Patch<V, KK extends StrKey<V> = StrKey<V>> = ((OPick<V, Allowed<KK>> & ID) | (Rec<Allowed<KK>, N> & ID)) & TS;
9
+ type TakeDoc<V, E = ID, KK extends StrKey<V> = StrKey<V>> = OPick<V, Allowed<KK>> & E;
10
+ type ND = {
11
+ readonly deletedAt?: null;
12
+ };
13
+ type SafeE<E> = Omit<E, `$${string}` | keyof ID>;
14
+ export declare const getWhenMatchedForMerge: <Out extends Model, P extends Model, K extends keyof IsDeleted>(whenNotMatched: "discard" | "fail" | "insert") => RawStages<O, Out, Out | Replace<Out, P>, RORec<"new", Replace<P, RORec<K, Timestamp>>>>;
15
+ export declare const getWhenMatched: <Out extends Model, P extends Model, K extends keyof IsDeleted>(whenNotMatched: "discard" | "fail" | "insert") => RawStages<O, Rec<"old" | "merged", Out | Replace<Out, P>>, Out | Replace<Out, P>>;
16
+ type MergeCollection<V extends O, Out extends Model> = {
17
+ coll: RWCollection<Out | Replace<Out, Patch<V>> | Replace<Patch<V>, IsDeleted>, Out>;
18
+ whenNotMatched: 'discard';
19
+ } | {
20
+ coll: RWCollection<Out | Replace<Out, Patch<V>>, Out>;
21
+ whenNotMatched: 'fail';
22
+ };
23
+ export declare const $mergeId: <V extends O>() => <SourcePart extends doc, Out extends Model, E = unknown, EEE extends RORec<string, rawItem> = {}>(out: MergeCollection<V, Out>, keys: ExprsExact<TakeDoc<V, unknown>, SourcePart>, id: Expr<string, OutInputE<TakeDoc<V>, E, null>>, ext: Exact<Omit<SafeE<EEE>, keyof (ND & TS)>, IdHKT>) => StreamRunnerParam<OutInputE<SourcePart, E>, "out">;
24
+ export declare const $simpleMergePart: <V extends O>() => <Source extends doc, Out extends Model, EEE extends RORec<string, rawItem>>(out: MergeCollection<V, Out>, keys: ExprsExact<TakeDoc<V, unknown>, Source>, ext: Exact<Omit<SafeE<EEE>, keyof (ND & TS)>, IdHKT>) => StreamRunnerParam<Source, "out">;
25
+ export declare const $simpleMerge: <V extends O>() => <Source extends doc, Out extends Model>(out: RWCollection<Out | Replace<Out, Patch<V>> | Replace<Patch<V>, IsDeleted>, Out>, keys: ExprsExact<TakeDoc<V, unknown>, Source>, whenNotMatched?: "fail" | "discard") => StreamRunnerParam<Source, "out">;
26
+ export declare const $mergePart: <V extends O>() => <Out extends Model, SourcePart extends doc, EEE extends RORec<string, rawItem>>(out: RWCollection<Out | Replace<Out, Patch<V>>, Out>, keys: ExprsExact<TakeDoc<V, unknown>, SourcePart>, ext: Exact<Omit<SafeE<EEE>, keyof (ND & TS)>, IdHKT>) => StreamRunnerParam<Delta<SourcePart>, "out">;
27
+ export declare const $merge: <V extends O>() => <Out extends Model, SourcePart extends doc>(out: RWCollection<Out | Replace<Out, Patch<V>>, Out>, keys: ExprsExact<TakeDoc<V, unknown>, SourcePart>) => StreamRunnerParam<Delta<SourcePart>, "out">;
28
+ export {};
@@ -0,0 +1,15 @@
1
+ import type { IdHKT, RWCollection } from '../../types';
2
+ import type { ID, O, RORec, doc, rawItem } from '../../types/json';
3
+ import { type ExprsExact } from '../expression/concat';
4
+ import type { Del, Delta, Expr, StreamRunnerParam, TS } from '../types';
5
+ import { type Exact } from '../utils/map-object';
6
+ type ND = {
7
+ readonly deletedAt?: null;
8
+ };
9
+ type SafeE<E> = Omit<E, `$${string}` | keyof ID>;
10
+ export type Merge<T extends doc, E> = Omit<SafeE<E>, keyof (ND & TS)> & ((T & ND & TS) | Del);
11
+ export declare const $insertX: <T extends doc, D extends O, EEE extends RORec<string, rawItem>>(out: RWCollection<Merge<T, EEE>>, expr: Expr<T, D>, map: (x: Expr<T & ND & TS & Omit<SafeE<EEE>, keyof (ND & TS)>, D>) => Expr<Merge<T, EEE>, D>, ext: Exact<Omit<SafeE<EEE>, keyof (ND & TS)>, IdHKT>, extExpr: ExprsExact<Omit<SafeE<EEE>, keyof (ND & TS)>, unknown>) => StreamRunnerParam<D, "out">;
12
+ export declare const $simpleInsert: <T extends doc>(out: RWCollection<Merge<T, {}>>) => StreamRunnerParam<T, "out">;
13
+ export declare const $insertPart: <T extends doc, EEE extends RORec<string, rawItem>>(out: RWCollection<Merge<T, EEE>>, ext: Exact<Omit<SafeE<EEE>, keyof (ND & TS)>, IdHKT>) => StreamRunnerParam<Delta<T>, "out">;
14
+ export declare const $insert: <T extends doc>(out: RWCollection<Merge<T, {}>>) => StreamRunnerParam<Delta<T>, "out">;
15
+ export {};
@@ -0,0 +1,12 @@
1
+ import type { RWCollection, WriteonlyCollection } from '../../../types';
2
+ import type { AsLiteral, ID, O, Rec, doc, notArr } from '../../../types/json';
3
+ import { type ExprsExact } from '../../expression/concat';
4
+ import type { Delta, DeltaAccumulators, Expr, StreamRunnerParam, TS } from '../../types';
5
+ import type { MergeInto } from '../out';
6
+ import { type Extra, type IdAndTsKeys, type Loose, type MergedInput, type Strict, type V_Grp } from './utils/sub-merge';
7
+ type Denied<GID = never> = keyof (TS & ID) | GID;
8
+ type GI<GG> = Exclude<GG, keyof TS>;
9
+ export declare const $groupMerge: <T extends O, Grp extends notArr, V extends O, GG extends string, EE = {}, Out extends Loose<Grp, V, GG> = Loose<Grp, V, GG>>(id: Expr<Grp, T>, args: DeltaAccumulators<T, O & Omit<V, Denied<GI<GG>>>>, out: MergeInto<Strict<Grp, V, GG, EE>, Out, WriteonlyCollection<MergedInput<Out, V, Grp, GG, EE>>>, gid: AsLiteral<GI<GG>>, extra: ExprsExact<Extra<EE, V, GG>, V_Grp<V, GG, Grp>>, idPrefix?: string) => StreamRunnerParam<Delta<T>, "out">;
10
+ export declare const $groupId: <T extends O, V extends O, EE = {}, Out extends Loose<string, V, "_id"> = Loose<string, V, "_id">>(id: Expr<string, T>, args: DeltaAccumulators<T, O & Omit<V, Denied>>, out: RWCollection<MergedInput<Out, V, string, "_id", EE>, Out>, extra: ExprsExact<Omit<EE, IdAndTsKeys | keyof Omit<V, IdAndTsKeys>>, doc & Omit<V, IdAndTsKeys>>) => StreamRunnerParam<Delta<T>, "out">;
11
+ export declare const $group: <T extends O, Grp extends notArr, V extends O, EE = {}, Out extends Loose<Grp, V, "_grp"> = Loose<Grp, V, "_grp">>(id: Expr<Grp, T>, args: DeltaAccumulators<T, O & Omit<V, Denied<"_grp">>>, out: RWCollection<MergedInput<Out, V, Grp, "_grp", EE> | Strict<Grp, V, "_grp", EE>, Out>, extra: ExprsExact<Omit<EE, IdAndTsKeys | "_grp" | Exclude<keyof V, IdAndTsKeys | "_grp">>, Rec<"_grp", Grp> & Omit<V, IdAndTsKeys | "_grp">>, idPrefix?: string) => StreamRunnerParam<Delta<T>, "out">;
12
+ export {};
@@ -0,0 +1,2 @@
1
+ export { $groupMerge, $groupId, $group } from './$group-merge';
2
+ export type { Loose, Strict } from './utils/sub-merge';
@@ -0,0 +1,6 @@
1
+ import type { O, RORec, Rec } from '../../../../types';
2
+ import { type ExprsExact } from '../../../expression/concat';
3
+ import type { Delta, Expr, RawStages } from '../../../types';
4
+ import type { DeltaAccumulators } from '../../../types/accumulator';
5
+ export type WithItem<V, Grp> = Rec<'_id', Grp> & Rec<'item', O<V>>;
6
+ export declare const subGroup: <T extends O, Grp, V extends O, GID extends string>(id: Expr<Grp, T>, args: DeltaAccumulators<T, V>, addGrp: <D extends Rec<"_id", Grp>>(src: ExprsExact<V, D>) => ExprsExact<RORec<GID, Grp> & V, D>) => RawStages<unknown, Delta<T>, Rec<GID, Grp> & V>;
@@ -0,0 +1,20 @@
1
+ import type { AsLiteral, ID, O, Rec, Replace, WriteonlyCollection, notArr } from '../../../../types';
2
+ import { type ExprsExact } from '../../../expression/concat';
3
+ import type { Model, RawStages, TS } from '../../../types';
4
+ import type { DeltaAccumulators } from '../../../types/accumulator';
5
+ import { type MergeInto } from '../../out';
6
+ type GI<GG> = Exclude<GG, keyof TS>;
7
+ export type IdAndTsKeys = keyof (TS & ID);
8
+ type V<VV, GG extends string> = Omit<VV, IdAndTsKeys | GI<GG>>;
9
+ export type Prepare<Grp, GG extends string> = TS & ID & Rec<GI<GG>, Grp>;
10
+ type Par<T> = {
11
+ [P in keyof T]?: T[P] | null;
12
+ };
13
+ export type Loose<Grp, VV, GG extends string> = Prepare<Grp, GG> & Par<V<VV, GG>>;
14
+ export type Strict<Grp, VV, GG extends string, EE> = Prepare<Grp, GG> & V<VV, GG> & Omit<EE, IdAndTsKeys | GI<GG> | keyof V<VV, GG>>;
15
+ export type V_Grp<VV, GG extends string, Grp> = Rec<GI<GG>, Grp> & V<VV, GG>;
16
+ export type Extra<EE, VV, GG extends string> = Omit<EE, IdAndTsKeys | GI<GG> | keyof V<VV, GG>>;
17
+ type OrReplace<T, V> = T | Replace<T, V>;
18
+ export type MergedInput<Out, VV, Grp, GG extends string, EE> = OrReplace<Replace<Replace<Out, V<VV, GG>>, Extra<EE, VV, GG>> & Model, TS & ID & V_Grp<VV, GG, Grp> & Extra<EE, VV, GG>>;
19
+ export declare const subMerge: <T extends O, Grp extends notArr, VV extends O, GG extends string, EE = {}, Out extends Loose<Grp, VV, GG> = Loose<Grp, VV, GG>>(args: DeltaAccumulators<T, V<VV, GG>>, out: MergeInto<Strict<Grp, VV, GG, EE>, Out, WriteonlyCollection<MergedInput<Out, VV, Grp, GG, EE>>>, gid: AsLiteral<GI<GG>>, extra: ExprsExact<Extra<EE, VV, GG>, V_Grp<VV, GG, Grp>>, idPrefix: string, first: boolean) => RawStages<unknown, V_Grp<VV, GG, Grp>, "out">;
20
+ export {};
@@ -0,0 +1,9 @@
1
+ export * from './group';
2
+ export * from './lookup';
3
+ export * from './match';
4
+ export * from './set';
5
+ export * from './unwind';
6
+ export * from './$merge';
7
+ export * from './$upsert';
8
+ export * from './out';
9
+ export { $group_ } from './mongo-stages';
@@ -0,0 +1,10 @@
1
+ import type { AsLiteral, ID, N, O, Rec, doc, rawItem } from '../../../types';
2
+ import { Field } from '../../field';
3
+ import type { BA, Before, Delta, RawStages, TStages, UBefore } from '../../types';
4
+ type s = string;
5
+ type Both<K1 extends s, LE, KK2 extends s, RE, N1 extends null = never, N2 extends null = never> = Delta<Rec<K1, LE | N1> & Rec<Exclude<KK2, BA | K1>, RE | N2> & ID>;
6
+ export declare const $lookupDelta: <LQ extends O, LE extends LQ & doc, RQ extends O, RE extends RQ & doc, BRB extends UBefore<RQ>, RS extends UBefore<RQ>, S extends rawItem, K1 extends s, KK2 extends s, N1 extends null = never, N2 extends null = never>({ field1, field2 }: {
7
+ field1: Field<LQ, S | N>;
8
+ field2: Field<RQ, S | N>;
9
+ }, { coll, exec, input }: TStages<RS, UBefore<RQ>, BRB, Before<RE>>, k1: AsLiteral<K1>, k2: AsLiteral<Exclude<KK2, BA | K1>>, k: ([N1] extends [never] ? K1 : never) | ([N2] extends [never] ? Exclude<KK2, BA | K1> : never) | false, includeNull1?: N1, includeNull2?: N2) => RawStages<unknown, Delta<LE>, Both<K1, LE, KK2, RE, N1, N2>>;
10
+ export {};
@@ -0,0 +1,9 @@
1
+ import type { App, AsLiteral, HKT, ID, O, Rec } from '../../../types';
2
+ import { type Field } from '../../field';
3
+ import type { Before, RawStages, TStages } from '../../types';
4
+ type s = string;
5
+ export declare const $lookupRaw: <LQ extends O, LE extends LQ & ID, RQ extends O, RE extends RQ & ID, BRB extends Before<RQ>, RS, S, As extends s, Null extends null = never>({ field1, field2 }: {
6
+ field1: Field<LQ, S>;
7
+ field2: Field<RQ, S>;
8
+ }, { coll, exec, input }: TStages<RS, Before<RQ>, BRB, Before<RE>>, k2: AsLiteral<As>, k: "left", includeNull?: Null) => <F extends HKT<O, O>>(f: <T extends O>() => Field<App<F, T>, T>) => RawStages<App<F, LQ>, App<F, LE>, App<F, LE & Rec<As, RE> & ID>>;
9
+ export {};
@@ -0,0 +1,12 @@
1
+ import type { AsLiteral, O, RORec, doc, notArr } from '../../../types';
2
+ import { type Field } from '../../field';
3
+ import type { SnapshotStream, SnapshotStreamExecutionResult } from '../../types/stream';
4
+ type Params<As extends string, LQ extends O, RQ extends O, RE extends RQ, S extends notArr> = {
5
+ localField: Field<LQ, S>;
6
+ foreignField: Field<RQ, S>;
7
+ from: SnapshotStreamExecutionResult<RQ, RE>;
8
+ as: AsLiteral<As>;
9
+ };
10
+ export declare const $lookup: <As extends string, LQ extends doc, RQ extends O, RE extends RQ & doc, S extends notArr>(p: Params<As, LQ, RQ, RE, S>) => <LE extends LQ>(l: SnapshotStream<LQ, LE>) => SnapshotStream<LQ, LE & RORec<As, RE>>;
11
+ export declare const $outerLookup: <As extends string, LQ extends doc, RQ extends O, RE extends RQ & doc, S extends notArr>(p: Params<As, LQ, RQ, RE, S>) => <LE extends LQ>(l: SnapshotStream<LQ, LE>) => SnapshotStream<LQ, LE & RORec<As, RE | null>>;
12
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { doc } from '../../../types';
2
+ import type { Delta, Expr } from '../../types';
3
+ export declare const $matchDelta: <T extends doc>(query: Expr<boolean, T>) => import("../../types").RawStages<unknown, Delta<T>, Delta<T>, unknown, number>;
@@ -0,0 +1,3 @@
1
+ import type { doc } from '../../../types';
2
+ import type { DeltaStages, Expr } from '../../types';
3
+ export declare const $match: <T extends doc>(query: Expr<boolean, T>) => DeltaStages<T, T, T>;
@@ -0,0 +1,2 @@
1
+ export { $matchDelta } from './$match-delta';
2
+ export { $match } from './$match';
@@ -0,0 +1,13 @@
1
+ import type { Arr, O, Rec } from '../../types';
2
+ import type { Accumulators, Expr, LookupArgs, Query, RawStages } from '../types';
3
+ import type { Updater } from '../update/updater';
4
+ export * from './raws';
5
+ type s = string;
6
+ export declare const $match_: <Q, T extends Q & O, C = unknown>(query?: Query<T, C>) => RawStages<O<T>, T, T, C>;
7
+ export declare const $set_: <Q, T extends Q & O, V extends Q & O, C = unknown>(updater: Updater<T, T, V, C>) => RawStages<O<Q>, T, V, C, 1>;
8
+ export declare const $replaceWith_: <T extends O, V extends O, C = unknown>(expr: Expr<V, T, C>) => RawStages<O, T, V, C, 1>;
9
+ export declare const $unwind_: <T extends O, K extends s, U, Null extends null = never>(k: K, includeNull?: Null) => RawStages<O<T>, T & Rec<K, Arr<U>>, T & Rec<K, Null | U>>;
10
+ export declare const $group_: <V extends O>() => <ID, T extends O, C = unknown>(id: Expr<ID, T, C>, args: Accumulators<T, V, C>) => RawStages<O, T, Rec<"_id", ID> & V, C, 1>;
11
+ export declare const $documents_: <T extends O, C>(docs: Expr<Arr<T>, unknown, C>) => RawStages<unknown, null, T, C, 1>;
12
+ export declare const $project_: <T extends O, K extends import("../..").StrKey<T>>(projection: import("../utils").ExactKeys<K>) => RawStages<T, T, T, unknown, 1>;
13
+ export declare const $simpleLookup_: <T extends O, U extends O, R, K extends s, Ctx, C = unknown, S = string>(args: LookupArgs<T, U, R, K, Ctx, C, S>) => RawStages<O<T>, T, T & Rec<K, Arr<U>>, C, 1>;
@@ -0,0 +1,37 @@
1
+ import type { O, RWCollection, ReadonlyCollection, Replace, jsonItem } from '../../types';
2
+ import type { ExprsExact } from '../expression/concat';
3
+ import { type Field } from '../field';
4
+ import type { RawStages } from '../types';
5
+ export type MergeInto<T extends O, Out extends O, E = unknown> = {
6
+ whenNotMatched: 'insert';
7
+ into: RWCollection<T, Out> & E;
8
+ } | {
9
+ whenNotMatched: 'discard' | 'fail';
10
+ into: ReadonlyCollection<Out> & E;
11
+ };
12
+ export type MergeArgs<T extends O, Out extends O, Ctx, In extends O> = {
13
+ on: Field<T, jsonItem> & Field<Out, jsonItem>;
14
+ } & MergeInto<T, Out> & (({
15
+ stages?: never;
16
+ } & ({
17
+ whenMatched: 'keepExisting' | 'fail';
18
+ } | {
19
+ whenMatched: 'replace';
20
+ into: RWCollection<T, Out>;
21
+ } | {
22
+ whenMatched: 'merge';
23
+ into: RWCollection<Replace<Out, T>, Out>;
24
+ })) | {
25
+ stages: true;
26
+ into: RWCollection<In, Out>;
27
+ whenMatched: RawStages<unknown, Out, In, {
28
+ new: T;
29
+ }>;
30
+ } | {
31
+ stages: 'ctx';
32
+ vars: ExprsExact<Ctx, T>;
33
+ into: RWCollection<In, Out>;
34
+ whenMatched: RawStages<unknown, Out, In, Ctx>;
35
+ });
36
+ export declare const $merge_: <T extends O, Out extends O = T, Ctx = unknown, In extends O = Out>({ into, on, whenNotMatched, ...notMatched }: MergeArgs<T, Out, Ctx, In>) => RawStages<unknown, T, "out", unknown, number>;
37
+ export declare const $merge2: <T extends O, Out extends O = T, Ctx = unknown, In extends O = Out>(args: MergeArgs<T, Out, Ctx, In>) => RawStages<unknown, T, "out", unknown, number>;
@@ -0,0 +1,33 @@
1
+ import type { App, HKT, O2, O3, O, RawObj } from '../../types';
2
+ import type { Delta, DeltaStages, FRawStages, RawStages, Stream, TStages } from '../types';
3
+ import type { Equal } from '../utils/guard';
4
+ type n = number;
5
+ export declare const asStages: <Q, T extends Q, V extends Q, C = unknown, M extends n = number>(x: readonly RawObj[]) => RawStages<Q, T, V, C, M>;
6
+ export declare const same: <T extends Dom, V extends Dom, F extends HKT<Dom, Q>, Dom = unknown, Q = unknown, C = unknown, M extends n = number>(_: Equal<Dom, T, V>) => RawStages<Q, App<F, T>, App<F, V>, C, M>;
7
+ export declare const concatStages: <Q, T extends Q, V extends Q, W extends Q, C, M extends n = number>(part1: RawStages<Q, T, V, C, M>, part2: RawStages<Q, V, W, C, M>) => RawStages<Q, T, W, C, M>;
8
+ export declare const concatFStages: <Q, T extends Q & O, V extends Q & O, W extends Q & O, C, M extends n = number>(part1: FRawStages<Q, T, V, C, M>, part2: FRawStages<Q, V, W, C, M>) => FRawStages<Q, T, W, C, M>;
9
+ export declare const concatDelta: <Q extends O, T extends Q, V extends Q, W extends Q>(part1: DeltaStages<Q, T, V>, part2: DeltaStages<Q, V, W>) => DeltaStages<Q, T, W>;
10
+ export type Concat<out Q, in T extends Q, out V extends Q, in out C, in out M extends n = n> = {
11
+ with: <Q2, W extends Q2>(extra: RawStages<Q | Q2, V, W, C, M>) => Concat<Q | Q2, T, W, C, M>;
12
+ stages: RawStages<Q, T, V, C, M>;
13
+ };
14
+ type FConcat<out Q, in T extends Q & O, out V extends Q & O, in out C, in out M extends n = n> = {
15
+ with: <Q2, W extends Q2 & O>(extra: FRawStages<Q | Q2, V, W, C, M>) => FConcat<Q | Q2, T, W, C, M>;
16
+ stages: FRawStages<Q, T, V, C, M>;
17
+ };
18
+ export type DeltaPipe<Q extends O, T extends Q, F extends HKT<O2>, G extends HKT<O3>> = {
19
+ with: <Q2 extends O, V extends Q2>(map: (a: Stream<Q, T, F, G>) => Stream<Q | Q2, V, F, G>) => DeltaPipe<Q | Q2, V, F, G>;
20
+ then: <Q2 extends O, V extends Q2>(next: App<G, [Q2 | T, T, V]>) => DeltaPipe<Q | Q2, V, F, G>;
21
+ get: () => App<F, [Q, T]>;
22
+ };
23
+ export declare const pipe: <Q extends O, S extends Q, T extends Q, F extends HKT<O2>, G extends HKT<O3>>(stream: Stream<Q, S, F, G>, s: App<G, [Q, S, T]>, concat: <Q_1 extends O, T_1 extends Q_1, V extends Q_1, W extends Q_1>(part1: App<G, [Q_1, T_1, V]>, part2: App<G, [Q_1, V, W]>) => App<G, [Q_1, T_1, W]>, empty: <T_2 extends Q>() => App<G, [Q, T_2, T_2]>) => DeltaPipe<Q, T, F, G>;
24
+ type Link = <T, C = unknown, M extends n = n>() => Concat<T, T, T, C, M>;
25
+ type FLink = <T extends O, C = unknown, M extends n = n>() => FConcat<T, T, T, C, M>;
26
+ export declare const link: Link;
27
+ export declare const flink: FLink;
28
+ export declare const emptyDelta: <T extends O>() => {
29
+ delta: RawStages<Delta<T>, Delta<T>, Delta<T>, unknown, number>;
30
+ raw: <F extends HKT<O>>() => RawStages<App<F, T>, App<F, T>, App<F, T>, unknown, number>;
31
+ };
32
+ export declare const concatTStages: <S, Q, B extends Q, T extends Q, V extends Q>({ coll, exec, input }: TStages<S, Q, B, T>, stages: RawStages<Q, T, V>) => TStages<S, Q, B, V>;
33
+ export {};