@omegup/msync 0.1.61 → 0.1.62

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 (39) hide show
  1. package/index.d.ts +13 -847
  2. package/index.esm.js +1986 -2233
  3. package/index.esm.js.map +1 -0
  4. package/index.js +1992 -2244
  5. package/index.js.map +1 -0
  6. package/lib/aggregate/$merge.d.ts +9 -9
  7. package/lib/aggregate/$upsert.d.ts +6 -6
  8. package/lib/aggregate/group/$group-merge.d.ts +9 -10
  9. package/lib/aggregate/group/utils/sub-group.d.ts +1 -1
  10. package/lib/aggregate/group/utils/sub-merge.d.ts +27 -4
  11. package/lib/aggregate/lookup/$lookup-delta.d.ts +2 -2
  12. package/lib/aggregate/lookup/$lookup-raw.d.ts +3 -3
  13. package/lib/aggregate/mongo-stages.d.ts +3 -2
  14. package/lib/aggregate/prefix.d.ts +5 -5
  15. package/lib/aggregate/raws.d.ts +1 -1
  16. package/lib/aggregate/set/$replace-with-each.d.ts +5 -5
  17. package/lib/aggregate/set/$set.d.ts +1 -1
  18. package/lib/aggregate/unwind/$unwind-delta.d.ts +1 -1
  19. package/lib/aggregate/unwind/index.d.ts +2 -2
  20. package/lib/boot/boot-simpl.d.ts +1 -1
  21. package/lib/boot/boot-utils.d.ts +1 -1
  22. package/lib/expression/concat.d.ts +4 -4
  23. package/lib/expression/date.d.ts +3 -3
  24. package/lib/expression/expr-base.d.ts +2 -2
  25. package/lib/expression/logic.d.ts +1 -1
  26. package/lib/expression/range.d.ts +2 -2
  27. package/lib/expression/val.d.ts +2 -2
  28. package/lib/field/field.d.ts +1 -1
  29. package/lib/predicate/$eq.d.ts +2 -2
  30. package/lib/types/accumulator.d.ts +2 -2
  31. package/lib/update/updater.d.ts +1 -1
  32. package/lib/utils/coll.d.ts +2 -2
  33. package/lib/utils/db-indexes.d.ts +1 -1
  34. package/lib/utils/guard.d.ts +2 -12
  35. package/lib/utils/json.d.ts +1 -0
  36. package/lib/utils/map-object.d.ts +1 -1
  37. package/package.json +22 -22
  38. package/types/global.d.ts +2 -0
  39. package/types/json.d.ts +1 -0
package/index.js CHANGED
@@ -1,592 +1,457 @@
1
- 'use strict';
2
-
3
- var mongodb = require('mongodb');
4
- var crypto$1 = require('crypto');
5
- var jsonCanonicalize = require('json-canonicalize');
6
- var promises = require('fs/promises');
7
-
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __exportAll = (all, no_symbols) => {
10
+ let target = {};
11
+ for (var name in all) __defProp(target, name, {
12
+ get: all[name],
13
+ enumerable: true
14
+ });
15
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
16
+ return target;
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
20
+ key = keys[i];
21
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
22
+ get: ((k) => from[k]).bind(null, key),
23
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
24
+ });
25
+ }
26
+ return to;
27
+ };
28
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
29
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
30
+ value: mod,
31
+ enumerable: true
32
+ }) : target, mod));
33
+ //#endregion
34
+ let mongodb = require("mongodb");
35
+ let crypto$1 = require("crypto");
36
+ crypto$1 = __toESM(crypto$1, 1);
37
+ let json_canonicalize = require("json-canonicalize");
38
+ let fs_promises = require("fs/promises");
39
+ //#region .build/lib/expression/expr-base.js
8
40
  const asExprRaw = (raw) => ({ get: () => raw });
9
41
  const asExpr = (r) => r;
10
42
  const asBoolExpr = (r) => r;
11
-
12
- const max = (...expr) => asExpr({
13
- raw: f => asExprRaw({ $max: expr.map(e => e.raw(f).get()) }),
14
- });
15
- const min = (...expr) => asExpr({
16
- raw: f => asExprRaw({ $min: expr.map(e => e.raw(f).get()) }),
17
- });
18
- const lt = (...expr) => asExpr({
19
- raw: f => asExprRaw({ $lt: expr.map(e => e.raw(f).get()) }),
20
- });
21
- const gt = (...expr) => asExpr({
22
- raw: f => asExprRaw({ $gt: expr.map(e => e.raw(f).get()) }),
23
- });
24
- const lte = (...expr) => asExpr({
25
- raw: f => asExprRaw({ $lte: expr.map(e => e.raw(f).get()) }),
26
- });
27
- const gte = (...expr) => asExpr({
28
- raw: f => asExprRaw({ $gte: expr.map(e => e.raw(f).get()) }),
29
- });
43
+ //#endregion
44
+ //#region .build/lib/expression/arith.js
45
+ const max = (...expr) => asExpr({ raw: (f) => asExprRaw({ $max: expr.map((e) => e.raw(f).get()) }) });
46
+ const min = (...expr) => asExpr({ raw: (f) => asExprRaw({ $min: expr.map((e) => e.raw(f).get()) }) });
47
+ const lt = (...expr) => asExpr({ raw: (f) => asExprRaw({ $lt: expr.map((e) => e.raw(f).get()) }) });
48
+ const gt = (...expr) => asExpr({ raw: (f) => asExprRaw({ $gt: expr.map((e) => e.raw(f).get()) }) });
49
+ const lte = (...expr) => asExpr({ raw: (f) => asExprRaw({ $lte: expr.map((e) => e.raw(f).get()) }) });
50
+ const gte = (...expr) => asExpr({ raw: (f) => asExprRaw({ $gte: expr.map((e) => e.raw(f).get()) }) });
30
51
  function subtract(...expr) {
31
- return asExpr({
32
- raw: f => asExprRaw({ $subtract: expr.map(e => e.raw(f).get()) }),
33
- });
52
+ return asExpr({ raw: (f) => asExprRaw({ $subtract: expr.map((e) => e.raw(f).get()) }) });
34
53
  }
35
54
  function add(...expr) {
36
- return asExpr({
37
- raw: f => asExprRaw({ $add: expr.map(e => e.raw(f).get()) }),
38
- });
55
+ return asExpr({ raw: (f) => asExprRaw({ $add: expr.map((e) => e.raw(f).get()) }) });
39
56
  }
40
57
  function divide(...expr) {
41
- return asExpr({
42
- raw: f => asExprRaw({ $divide: expr.map(e => e.raw(f).get()) }),
43
- });
58
+ return asExpr({ raw: (f) => asExprRaw({ $divide: expr.map((e) => e.raw(f).get()) }) });
44
59
  }
45
60
  function multiply(...expr) {
46
- return asExpr({
47
- raw: f => asExprRaw({ $multiply: expr.map(e => e.raw(f).get()) }),
48
- });
61
+ return asExpr({ raw: (f) => asExprRaw({ $multiply: expr.map((e) => e.raw(f).get()) }) });
49
62
  }
50
63
  function floor(expr) {
51
- return asExpr({
52
- raw: f => asExprRaw({ $floor: expr.raw(f).get() }),
53
- });
64
+ return asExpr({ raw: (f) => asExprRaw({ $floor: expr.raw(f).get() }) });
54
65
  }
55
66
  function ceil(expr) {
56
- return asExpr({
57
- raw: f => asExprRaw({ $ceil: expr.raw(f).get() }),
58
- });
67
+ return asExpr({ raw: (f) => asExprRaw({ $ceil: expr.raw(f).get() }) });
59
68
  }
60
-
69
+ //#endregion
70
+ //#region .build/lib/utils/json.js
71
+ const safeNarrow = () => {
72
+ return (x) => x;
73
+ };
61
74
  const id$1 = (x) => x;
62
75
  const defined = (x) => x != null;
63
- const noop = () => { };
76
+ const noop = () => {};
64
77
  const map1 = (k, to) => {
65
- const k2 = k;
66
- return { [k]: [k2, to] };
78
+ const k2 = k;
79
+ return { [k]: [k2, to] };
67
80
  };
68
-
81
+ //#endregion
82
+ //#region .build/lib/utils/map-object.js
69
83
  const map = (x, f) => Object.fromEntries(Object.entries(x).map(([k, v]) => [k, f(v, k)]));
70
84
  const mapExactToObject0 = (x, f) => {
71
- const filter = (x) => x.filter((x) => x[0] === x[1][0]);
72
- const matched = filter(Object.entries(x));
73
- return Object.fromEntries(matched.map(([k, v]) => [k, f(v[1], k)]));
85
+ const filter = (x) => x.filter((x) => x[0] === x[1][0]);
86
+ const matched = filter(Object.entries(x));
87
+ return Object.fromEntries(matched.map(([k, v]) => [k, f(v[1], k)]));
74
88
  };
75
89
  const mapExactToObject1 = (x, f) => mapExactToObject0(x, f);
76
90
  const mapExact0 = (x, f) => mapExactToObject0(x, (v, k) => [k, f(v, k)]);
77
91
  const mapExact1 = (x, f) => mapExactToObject1(x, (v, k) => [k, f(v, k)]);
78
92
  const mapExactToObject = (x, f) => mapExactToObject0(x, f);
79
93
  const mapExact = (x, f) => mapExactToObject(x, (v, k) => [k, f(v, k)]);
80
- const spread = (a, b) => ({ ...a, ...mapExact(b, id$1) });
81
- const spread0 = (a, b) => ({ ...a, ...mapExact0(b, id$1) });
82
-
83
- const val = (val) => asExpr({
84
- raw: () => asExprRaw((val && typeof val === 'object' && !(val instanceof Date)) ||
85
- (typeof val === 'string' && val[0] === '$')
86
- ? { $literal: val }
87
- : val),
88
- });
89
- const current = asExpr({
90
- raw: () => asExprRaw('$$CLUSTER_TIME'),
91
- });
92
- const $let = (vars, inExpr) => asExpr({
93
- raw: f => asExprRaw({
94
- $let: {
95
- vars: mapExactToObject(vars, v => v.raw(f).get()),
96
- in: inExpr.raw(f).get(),
97
- },
98
- }),
99
- });
94
+ const spread = (a, b) => ({
95
+ ...a,
96
+ ...mapExact(b, id$1)
97
+ });
98
+ const spread0 = (a, b) => ({
99
+ ...a,
100
+ ...mapExact0(b, id$1)
101
+ });
102
+ //#endregion
103
+ //#region .build/lib/expression/val.js
104
+ const val = (val) => asExpr({ raw: () => asExprRaw(val && typeof val === "object" && !(val instanceof Date) || typeof val === "string" && val[0] === "$" ? { $literal: val } : val) });
105
+ const current = asExpr({ raw: () => asExprRaw("$$CLUSTER_TIME") });
106
+ const $let = (vars, inExpr) => asExpr({ raw: (f) => asExprRaw({ $let: {
107
+ vars: mapExactToObject(vars, (v) => v.raw(f).get()),
108
+ in: inExpr.raw(f).get()
109
+ } }) });
100
110
  const nil = val(null);
101
- const $getField = (expr, field) => asExpr({
102
- raw: f => asExprRaw({
103
- $getField: {
104
- field: field,
105
- input: expr.raw(f).get(),
106
- },
107
- }),
108
- });
109
- const func = (f, ...args) => asExpr({
110
- raw: field => asExprRaw({
111
- $function: {
112
- body: f.toString(),
113
- args: args.map(x => x.raw(field).get()),
114
- lang: 'js',
115
- },
116
- }),
117
- });
118
- const rand = function () {
119
- const s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
120
- return Array(17)
121
- .fill(0)
122
- .map(() => s[Math.floor(Math.random() * 62)])
123
- .join('');
111
+ const $getField = (expr, field) => asExpr({ raw: (f) => asExprRaw({ $getField: {
112
+ field,
113
+ input: expr.raw(f).get()
114
+ } }) });
115
+ const func = (f, ...args) => asExpr({ raw: (field) => asExprRaw({ $function: {
116
+ body: f.toString(),
117
+ args: args.map((x) => x.raw(field).get()),
118
+ lang: "js"
119
+ } }) });
120
+ const rand = function() {
121
+ const s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
122
+ return Array(17).fill(0).map(() => s[Math.floor(Math.random() * 62)]).join("");
124
123
  };
125
124
  const $rand = func(rand);
126
-
127
- const ite = ((cond, then, orelse) => asExpr({
128
- raw: (f) => asExprRaw({
129
- $cond: {
130
- if: cond.raw(f).get(),
131
- then: then.raw(f).get(),
132
- else: orelse.raw(f).get(),
133
- },
134
- }),
135
- }));
136
- const and = (...expr) => asExpr({
137
- raw: f => asExprRaw({ $and: expr.map(e => e.raw(f).get()) }),
138
- });
139
- const or = (...expr) => asExpr({
140
- raw: f => asExprRaw({ $or: expr.map(e => e.raw(f).get()) }),
141
- });
142
- const not = (expr) => asExpr({
143
- raw: f => asExprRaw({ $not: expr.raw(f).get() }),
144
- });
145
- const eq = (a) => (b) => asExpr({
146
- raw: f => asExprRaw({ $eq: [a.raw(f).get(), b.raw(f).get()] }),
147
- });
148
- const sub = (a, f) => asExpr({
149
- raw: (g) => asExprRaw(a.raw(g.with(f)).get()),
150
- });
151
- const eqTyped = (a, b) => asBoolExpr({
152
- raw: (f) => asExprRaw({ $eq: [a.raw(f).get(), b.raw(f).get()] }),
153
- });
154
- const ne = (a) => (b) => asExpr({
155
- raw: f => asExprRaw({ $ne: [a.raw(f).get(), b.raw(f).get()] }),
156
- });
125
+ //#endregion
126
+ //#region .build/lib/expression/logic.js
127
+ const ite = ((cond, then, orelse) => asExpr({ raw: (f) => asExprRaw({ $cond: {
128
+ if: cond.raw(f).get(),
129
+ then: then.raw(f).get(),
130
+ else: orelse.raw(f).get()
131
+ } }) }));
132
+ const and = (...expr) => asExpr({ raw: (f) => asExprRaw({ $and: expr.map((e) => e.raw(f).get()) }) });
133
+ const or = (...expr) => asExpr({ raw: (f) => asExprRaw({ $or: expr.map((e) => e.raw(f).get()) }) });
134
+ const not = (expr) => asExpr({ raw: (f) => asExprRaw({ $not: expr.raw(f).get() }) });
135
+ const eq = (a) => (b) => asExpr({ raw: (f) => asExprRaw({ $eq: [a.raw(f).get(), b.raw(f).get()] }) });
136
+ const sub = (a, f) => asExpr({ raw: (g) => asExprRaw(a.raw(g.with(f)).get()) });
137
+ const eqTyped = (a, b) => asBoolExpr({ raw: (f) => asExprRaw({ $eq: [a.raw(f).get(), b.raw(f).get()] }) });
138
+ const ne = (a) => (b) => asExpr({ raw: (f) => asExprRaw({ $ne: [a.raw(f).get(), b.raw(f).get()] }) });
157
139
  const notNull = (a) => ne($ifNull(a, nil))(nil);
158
- const $ifNull = (...expr) => asExpr({
159
- raw: f => asExprRaw({ $ifNull: expr.map(e => e.raw(f).get()) }),
160
- });
161
- const exprMapVal = (expr, map, or) => asExpr({
162
- raw: f => asExprRaw({
163
- $switch: {
164
- branches: Object.entries(map).map(([k, v]) => ({
165
- case: { $eq: [expr.raw(f).get(), { $literal: k }] },
166
- then: v.raw(f).get(),
167
- })),
168
- ...(or && { default: or.raw(f).get() }),
169
- },
170
- }),
171
- });
140
+ const $ifNull = (...expr) => asExpr({ raw: (f) => asExprRaw({ $ifNull: expr.map((e) => e.raw(f).get()) }) });
141
+ const exprMapVal = (expr, map, or) => asExpr({ raw: (f) => asExprRaw({ $switch: {
142
+ branches: Object.entries(map).map(([k, v]) => safeNarrow()({
143
+ case: { $eq: [expr.raw(f).get(), { $literal: k }] },
144
+ then: v.raw(f).get()
145
+ })),
146
+ ...or && { default: or.raw(f).get() }
147
+ } }) });
172
148
  const mapVal = (expr, map, or) => exprMapVal(expr, Object.fromEntries(Object.entries(map).map(([k, v]) => [k, val(v)])), val(or));
173
- const setField = ({ field, input, value, }) => asExpr({
174
- raw: f => asExprRaw({
175
- $setField: {
176
- field: field.raw(f).get(),
177
- input: input.raw(f).get(),
178
- value: value.raw(f).get(),
179
- },
180
- }),
181
- });
182
-
183
- class Field {
184
- field;
185
- raw;
186
- concat;
187
- has(p) {
188
- return { raw: f => ({ [f.with(this).str()]: p.raw }) };
189
- }
190
- constructor(field, raw, concat) {
191
- this.field = field;
192
- this.raw = raw;
193
- this.concat = concat;
194
- }
195
- static root = () => {
196
- const concat = (f1, f2) => new Field([f1.field, f2.field].filter(id$1).join('.'), f1.raw, f1.concat);
197
- return new Field('', s => (s ? `$${s}` : '$$ROOT'), concat);
198
- };
199
- static ctx = () => (k) => {
200
- const concat = (_, f2) => new Field(f2.field, f2.raw, f2.concat);
201
- return new Field(k, s => `$$${s}`, concat);
202
- };
203
- of(k) {
204
- return new Field([this.field, k].filter(id$1).join('.'), this.raw, this.concat);
205
- }
206
- with(k) {
207
- return k.concat(this, k);
208
- }
209
- str() {
210
- return this.field;
211
- }
212
- exprRaw() {
213
- return asExprRaw(this.raw(this.field));
214
- }
215
- expr() {
216
- return asExpr({
217
- raw: (f) => f.with(this).exprRaw(),
218
- });
219
- }
220
- }
149
+ const setField = ({ field, input, value }) => asExpr({ raw: (f) => asExprRaw({ $setField: {
150
+ field: field.raw(f).get(),
151
+ input: input.raw(f).get(),
152
+ value: value.raw(f).get()
153
+ } }) });
154
+ //#endregion
155
+ //#region .build/lib/field/field.js
156
+ var Field = class Field {
157
+ field;
158
+ raw;
159
+ concat;
160
+ has(p) {
161
+ return { raw: (f) => ({ [f.with(this).str()]: p.raw }) };
162
+ }
163
+ constructor(field, raw, concat) {
164
+ this.field = field;
165
+ this.raw = raw;
166
+ this.concat = concat;
167
+ }
168
+ static root = () => {
169
+ const concat = (f1, f2) => new Field([f1.field, f2.field].filter(id$1).join("."), f1.raw, f1.concat);
170
+ return new Field("", (s) => s ? `$${s}` : "$$ROOT", concat);
171
+ };
172
+ static ctx = () => (k) => {
173
+ const concat = (_, f2) => new Field(f2.field, f2.raw, f2.concat);
174
+ return new Field(k, (s) => `$$${s}`, concat);
175
+ };
176
+ of(k) {
177
+ return new Field([this.field, k].filter(id$1).join("."), this.raw, this.concat);
178
+ }
179
+ with(k) {
180
+ return k.concat(this, k);
181
+ }
182
+ str() {
183
+ return this.field;
184
+ }
185
+ exprRaw() {
186
+ return asExprRaw(this.raw(this.field));
187
+ }
188
+ expr() {
189
+ return asExpr({ raw: (f) => f.with(this).exprRaw() });
190
+ }
191
+ };
221
192
  const { root, ctx } = Field;
222
-
193
+ //#endregion
194
+ //#region .build/lib/accumulators/index.js
223
195
  const asAccumulator = (x) => x;
224
- const $sum_ = (expr) => ({ raw: f => asAccumulator({ $sum: expr.raw(f).get() }) });
196
+ const $sum_ = (expr) => ({ raw: (f) => asAccumulator({ $sum: expr.raw(f).get() }) });
225
197
  const $sum = (expr) => ({
226
- group: $sum_(ite(root().of('deleted').expr(), val(0), ite(root().of('old').expr(), subtract(val(0), $ifNull(sub(expr, root().of('v')), val(0))), sub(expr, root().of('v'))))),
227
- merge: (x, y) => add($ifNull(x, val(0)), y),
198
+ group: $sum_(ite(root().of("deleted").expr(), val(0), ite(root().of("old").expr(), subtract(val(0), $ifNull(sub(expr, root().of("v")), val(0))), sub(expr, root().of("v"))))),
199
+ merge: (x, y) => add($ifNull(x, val(0)), y)
228
200
  });
229
201
  const $accumulator_ = (init, accumulateArgs, accumulate, merge) => {
230
- return {
231
- raw: f => asAccumulator({
232
- $accumulator: {
233
- init: init.toString(),
234
- initArgs: [],
235
- accumulate: accumulate.toString(),
236
- accumulateArgs: accumulateArgs.map(e => e.raw(f).get()),
237
- merge: merge.toString(),
238
- lang: 'js',
239
- },
240
- }),
241
- };
202
+ return { raw: (f) => asAccumulator({ $accumulator: {
203
+ init: init.toString(),
204
+ initArgs: [],
205
+ accumulate: accumulate.toString(),
206
+ accumulateArgs: accumulateArgs.map((e) => e.raw(f).get()),
207
+ merge: merge.toString(),
208
+ lang: "js"
209
+ } }) };
242
210
  };
243
211
  const $accumulator = (init, accumulateArgs, accumulate, merge) => ({
244
- group: $accumulator_(init, accumulateArgs, accumulate, merge),
245
- merge: (a, b) => func(merge, a, b),
212
+ group: $accumulator_(init, accumulateArgs, accumulate, merge),
213
+ merge: (a, b) => func(merge, a, b)
246
214
  });
247
- const $countDict = (expr) => $accumulator(function () {
248
- return {};
215
+ const $countDict = (expr) => $accumulator(function() {
216
+ return {};
249
217
  }, [
250
- sub(expr, root().of('v')),
251
- root().of('old').expr(),
252
- root().of('deleted').expr(),
253
- ], function (a, k, old, deleted) {
254
- if (deleted)
255
- return a;
256
- let y = (a[k] || 0) + (old ? -1 : 1);
257
- return y ? (a[k] = y) : delete a[k], a;
258
- }, function (a, b) {
259
- return Object.keys(b).reduce((a, k) => {
260
- let y = (a[k] || 0) + b[k];
261
- return y ? (a[k] = y) : delete a[k], a;
262
- }, a || {});
263
- });
264
- const $countDictArray = (expr) => $accumulator(function () {
265
- return {};
218
+ sub(expr, root().of("v")),
219
+ root().of("old").expr(),
220
+ root().of("deleted").expr()
221
+ ], function(a, k, old, deleted) {
222
+ if (deleted) return a;
223
+ let y = (a[k] || 0) + (old ? -1 : 1);
224
+ return y ? a[k] = y : delete a[k], a;
225
+ }, function(a, b) {
226
+ return Object.keys(b).reduce((a, k) => {
227
+ let y = (a[k] || 0) + b[k];
228
+ return y ? a[k] = y : delete a[k], a;
229
+ }, a || {});
230
+ });
231
+ const $countDictArray = (expr) => $accumulator(function() {
232
+ return {};
266
233
  }, [
267
- sub(expr, root().of('v')),
268
- root().of('old').expr(),
269
- root().of('deleted').expr(),
270
- ], function (a, keys, old, deleted) {
271
- if (deleted)
272
- return a;
273
- keys.forEach(k => {
274
- const y = (a[k] || 0) + (old ? -1 : 1);
275
- if (y)
276
- a[k] = y;
277
- else
278
- delete a[k];
279
- });
280
- return a;
281
- }, function (a, b) {
282
- return Object.keys(b).reduce((a, k) => {
283
- let y = (a[k] || 0) + b[k];
284
- return y ? (a[k] = y) : delete a[k], a;
285
- }, a || {});
286
- });
287
- const $pushDict = (key, value) => $accumulator(function () {
288
- return {};
234
+ sub(expr, root().of("v")),
235
+ root().of("old").expr(),
236
+ root().of("deleted").expr()
237
+ ], function(a, keys, old, deleted) {
238
+ if (deleted) return a;
239
+ keys.forEach((k) => {
240
+ const y = (a[k] || 0) + (old ? -1 : 1);
241
+ if (y) a[k] = y;
242
+ else delete a[k];
243
+ });
244
+ return a;
245
+ }, function(a, b) {
246
+ return Object.keys(b).reduce((a, k) => {
247
+ let y = (a[k] || 0) + b[k];
248
+ return y ? a[k] = y : delete a[k], a;
249
+ }, a || {});
250
+ });
251
+ const $pushDict = (key, value) => $accumulator(function() {
252
+ return {};
289
253
  }, [
290
- sub(key, root().of('v')),
291
- sub(value, root().of('v')),
292
- root().of('old').expr(),
293
- root().of('deleted').expr(),
294
- ], function (ra, k, v, old, deleted) {
295
- if (deleted)
296
- return ra;
297
- let a = { ...ra };
298
- const equal = (a, b) => {
299
- if (!a || !b)
300
- return a === b;
301
- if (a instanceof Date)
302
- return b instanceof Date && a.getTime() === b.getTime();
303
- if ([a, b].some(a => Object.getPrototypeOf(a) != Object.prototype))
304
- return a.valueOf() === b.valueOf();
305
- const keys = Object.keys(a);
306
- return keys.length === Object.keys(b).length && keys.every(k => equal(a[k], b[k]));
307
- };
308
- const delta = (a[k] ||= { 0: [], 1: [] }), addR = delta[old ? 1 : 0], rmR = delta[old ? 0 : 1], idx = rmR.findIndex(x => equal(x, v));
309
- if (idx !== -1)
310
- rmR.splice(idx, 1);
311
- else
312
- addR.push(v);
313
- return a;
314
- }, function (acc, b) {
315
- return Object.keys(b).reduce((a, k) => {
316
- return Object.entries({ ...b[k] }).reduce((a, [p, v]) => v.reduce((a, v) => {
317
- const equal = (a, b) => {
318
- if ([a, b].some(a => !a || typeof a != 'object'))
319
- return a === b;
320
- const keys = Object.keys(a);
321
- return keys.length === Object.keys(b).length && keys.every(k => equal(a[k], b[k]));
322
- };
323
- const delta = (a[k] ||= { 0: [], 1: [] }), addR = delta[p], rmR = delta[+p ? 0 : 1], idx = rmR.findIndex(x => equal(x, v));
324
- if (idx !== -1)
325
- rmR.splice(idx, 1);
326
- else
327
- addR.push(v);
328
- return a;
329
- }, a), a);
330
- }, acc || {});
331
- });
332
- const $keys = (expr) => func(function (obj) {
333
- return Object.keys(obj);
254
+ sub(key, root().of("v")),
255
+ sub(value, root().of("v")),
256
+ root().of("old").expr(),
257
+ root().of("deleted").expr()
258
+ ], function(ra, k, v, old, deleted) {
259
+ if (deleted) return ra;
260
+ let a = { ...ra };
261
+ const equal = (a, b) => {
262
+ if (!a || !b) return a === b;
263
+ if (a instanceof Date) return b instanceof Date && a.getTime() === b.getTime();
264
+ if ([a, b].some((a) => Object.getPrototypeOf(a) != Object.prototype)) return a.valueOf() === b.valueOf();
265
+ const keys = Object.keys(a);
266
+ return keys.length === Object.keys(b).length && keys.every((k) => equal(a[k], b[k]));
267
+ };
268
+ const delta = a[k] ||= {
269
+ 0: [],
270
+ 1: []
271
+ }, addR = delta[old ? 1 : 0], rmR = delta[old ? 0 : 1], idx = rmR.findIndex((x) => equal(x, v));
272
+ if (idx !== -1) rmR.splice(idx, 1);
273
+ else addR.push(v);
274
+ return a;
275
+ }, function(acc, b) {
276
+ return Object.keys(b).reduce((a, k) => {
277
+ return Object.entries({ ...b[k] }).reduce((a, [p, v]) => v.reduce((a, v) => {
278
+ const equal = (a, b) => {
279
+ if ([a, b].some((a) => !a || typeof a != "object")) return a === b;
280
+ const keys = Object.keys(a);
281
+ return keys.length === Object.keys(b).length && keys.every((k) => equal(a[k], b[k]));
282
+ };
283
+ const delta = a[k] ||= {
284
+ 0: [],
285
+ 1: []
286
+ }, addR = delta[p], rmR = delta[+p ? 0 : 1], idx = rmR.findIndex((x) => equal(x, v));
287
+ if (idx !== -1) rmR.splice(idx, 1);
288
+ else addR.push(v);
289
+ return a;
290
+ }, a), a);
291
+ }, acc || {});
292
+ });
293
+ const $keys = (expr) => func(function(obj) {
294
+ return Object.keys(obj);
334
295
  }, expr);
335
- const $entries = (expr) => func(function (obj) {
336
- return Object.entries({ ...obj }).flatMap(([k, v]) => v[0].map(v => ({ k, v })));
296
+ const $entries = (expr) => func(function(obj) {
297
+ return Object.entries({ ...obj }).flatMap(([k, v]) => v[0].map((v) => ({
298
+ k,
299
+ v
300
+ })));
337
301
  }, expr);
338
-
302
+ //#endregion
303
+ //#region .build/lib/aggregate/prefix.js
339
304
  const asStages = (x) => x;
340
305
  const concatStages = (part1, part2) => asStages([...part1, ...part2]);
341
306
  const concatDelta = (part1, part2) => ({
342
- delta: concatStages(part1.delta, part2.delta),
343
- raw: f => concatStages(part1.raw(f), part2.raw(f)),
307
+ delta: concatStages(part1.delta, part2.delta),
308
+ raw: (f) => concatStages(part1.raw(f), part2.raw(f))
344
309
  });
345
310
  const pipe = (stream, s, concat, empty) => {
346
- const acc = {
347
- with: (map) => pipe(map(i => stream(concat(s, i))), empty(), concat, empty),
348
- then: (next) => pipe(stream, concat(s, next), concat, empty),
349
- get: () => stream(s),
350
- };
351
- return acc;
311
+ return {
312
+ with: (map) => pipe(map((i) => stream(concat(s, i))), empty(), concat, empty),
313
+ then: (next) => pipe(stream, concat(s, next), concat, empty),
314
+ get: () => stream(s)
315
+ };
352
316
  };
353
317
  const concat$1 = (stages) => ({
354
- with: extra => concat$1(concatStages(stages, extra)),
355
- stages,
318
+ with: (extra) => concat$1(concatStages(stages, extra)),
319
+ stages
356
320
  });
357
321
  const link = () => ({
358
- with: extra => concat$1(extra),
359
- stages: asStages([]),
322
+ with: (extra) => concat$1(extra),
323
+ stages: asStages([])
360
324
  });
361
325
  const emptyDelta = () => ({
362
- delta: link().stages,
363
- raw: () => link().stages,
364
- });
365
- const concatTStages = ({ coll, exec, input }, stages) => ({ coll, input, exec: concatStages(exec, stages) });
366
-
367
- const concat = (...expr) => asExpr({
368
- raw: f => asExprRaw({ $concat: expr.map(e => e.raw(f).get()) }),
369
- });
370
- const $substr = (expr, start, length) => asExpr({
371
- raw: f => asExprRaw({
372
- $substrCP: [expr.raw(f).get(), start.raw(f).get(), length.raw(f).get()],
373
- }),
374
- });
375
- const padLeft = (expr, pad) => asExpr({
376
- raw: f => asExprRaw({
377
- $let: {
378
- vars: {
379
- x: {
380
- $concat: [{ $literal: pad }, expr.raw(f).get()],
381
- },
382
- },
383
- in: { $substrCP: ['$$x', { $subtract: [{ $strLenCP: '$$x' }, pad.length] }, pad.length] },
384
- },
385
- }),
386
- });
387
- const regex = (expr, regex, options) => asExpr({
388
- raw: f => asExprRaw({
389
- $regexMatch: {
390
- input: expr.raw(f).get(),
391
- regex: regex.raw(f).get(),
392
- options: options?.raw(f).get(),
393
- },
394
- }),
395
- });
396
- const str = (expr) => asExpr({
397
- raw: f => asExprRaw({ $toString: expr.raw(f).get() }),
398
- });
399
- const toInt = (expr) => asExpr({
400
- raw: f => asExprRaw({ $toInt: expr.raw(f).get() }),
401
- });
402
- const fieldM = (expr, m) => asExpr({
403
- raw: (f) => asExprRaw(Object.fromEntries(Object.entries(m).flatMap(([dom, ref]) => expr[ref] ? [[dom, expr[ref].raw(f).get()]] : []))),
404
- });
326
+ delta: link().stages,
327
+ raw: () => link().stages
328
+ });
329
+ const concatTStages = ({ coll, exec, input }, stages) => ({
330
+ coll,
331
+ input,
332
+ exec: concatStages(exec, stages)
333
+ });
334
+ //#endregion
335
+ //#region .build/lib/expression/concat.js
336
+ const concat = (...expr) => asExpr({ raw: (f) => asExprRaw({ $concat: expr.map((e) => e.raw(f).get()) }) });
337
+ const $substr = (expr, start, length) => asExpr({ raw: (f) => asExprRaw({ $substrCP: [
338
+ expr.raw(f).get(),
339
+ start.raw(f).get(),
340
+ length.raw(f).get()
341
+ ] }) });
342
+ const padLeft = (expr, pad) => asExpr({ raw: (f) => asExprRaw({ $let: {
343
+ vars: { x: { $concat: [{ $literal: pad }, expr.raw(f).get()] } },
344
+ in: { $substrCP: [
345
+ "$$x",
346
+ { $subtract: [{ $strLenCP: "$$x" }, pad.length] },
347
+ pad.length
348
+ ] }
349
+ } }) });
350
+ const regex = (expr, regex, options) => asExpr({ raw: (f) => asExprRaw({ $regexMatch: {
351
+ input: expr.raw(f).get(),
352
+ regex: regex.raw(f).get(),
353
+ options: options?.raw(f).get()
354
+ } }) });
355
+ const str = (expr) => asExpr({ raw: (f) => asExprRaw({ $toString: expr.raw(f).get() }) });
356
+ const toInt = (expr) => asExpr({ raw: (f) => asExprRaw({ $toInt: expr.raw(f).get() }) });
357
+ const fieldM = (expr, m) => asExpr({ raw: (f) => asExprRaw(Object.fromEntries(Object.entries(m).flatMap(([dom, ref]) => expr[ref] ? [[dom, expr[ref].raw(f).get()]] : []))) });
405
358
  const mergeExact = (...[exprsExact1, exprsExact2]) => spread(exprsExact1, exprsExact2);
406
359
  const mergeExact0 = (...[exprsExact1, exprsExact2]) => spread0(exprsExact1, exprsExact2);
407
360
  const mergeExpr = (...exprs) => mergeExact(...exprs);
408
- const fieldF = () => (exprs) => Object.keys(exprs).length
409
- ? asExpr({
410
- raw: f => asExprRaw(mapExactToObject(exprs, e => e.raw(f).get())),
411
- })
412
- : val({});
361
+ const fieldF = () => (exprs) => Object.keys(exprs).length ? asExpr({ raw: (f) => asExprRaw(mapExactToObject(exprs, (e) => e.raw(f).get())) }) : asExpr(val(safeNarrow()({})));
413
362
  const field = fieldF();
414
-
415
- const sym = (eq) => ({
416
- backward: eq.forward,
417
- forward: eq.backward,
418
- backward1: eq.forward1,
419
- forward1: eq.backward1,
420
- });
421
- const reflex = () => ({
422
- backward: id,
423
- forward: id,
424
- backward1: id,
425
- forward1: id,
426
- });
427
- const id = (x) => x;
428
- const assertEqual = () => reflex();
429
- const eqExtends = (_1, _2) => assertEqual();
430
- const fromEq = (eq) => ({
431
- ...eq,
432
- backward1: (eq.backward),
433
- forward1: (eq.forward),
434
- });
435
- const literalsEqaul = (_) => assertEqual();
436
- const omitRORec = () => assertEqual();
437
- const omitPick = () => assertEqual();
438
- const omitExclude = () => assertEqual();
439
- const renamedFields = () => assertEqual();
440
- const translateOmit = () => assertEqual();
441
- const excludeIdem = () => assertEqual();
442
- const eqPar = () => assertEqual();
443
-
444
- const size = (expr) => asExpr({
445
- raw: f => asExprRaw({ $size: expr.raw(f).get() }),
446
- });
363
+ //#endregion
364
+ //#region .build/lib/expression/array.js
365
+ const size = (expr) => asExpr({ raw: (f) => asExprRaw({ $size: expr.raw(f).get() }) });
447
366
  const filterDefined = (expr) => filter({
448
- expr,
449
- as: 'x',
450
- cond: ctx()('x').expr(),
451
- });
452
- const filter = ({ as, cond, expr, limit, }) => asExpr({
453
- raw: f => asExprRaw({
454
- $filter: {
455
- input: expr.raw(f).get(),
456
- as,
457
- cond: cond.raw(f).get(),
458
- ...(limit ? { limit: limit.raw(f).get() } : {}),
459
- },
460
- }),
461
- });
462
- const sortArray = ({ sortBy, expr, order, }) => asExpr({
463
- raw: f => asExprRaw({ $sortArray: { input: expr.raw(f).get(), sortBy: { [sortBy]: order ?? -1 } } }),
464
- });
465
- const isArray = (expr) => asBoolExpr({
466
- raw: f => asExprRaw({ $isArray: expr.raw(f).get() }),
467
- });
468
- const inArray = (item, expr) => asExpr({
469
- raw: f => asExprRaw({ $in: [item.raw(f).get(), expr.raw(f).get()] }),
470
- });
471
- const array = (...exprs) => asExpr({
472
- raw: f => asExprRaw(exprs.map(x => x.raw(f).get())),
473
- });
474
- const concatArray = (...exprs) => asExpr({
475
- raw: f => asExprRaw({ $concatArrays: exprs.map(x => x.raw(f).get()) }),
476
- });
477
- const first$1 = (expr) => asExpr({
478
- raw: f => asExprRaw({ $first: expr.raw(f).get() }),
479
- });
480
- const firstSure = first$1;
481
- const last = (expr) => asExpr({
482
- raw: f => asExprRaw({ $last: expr.raw(f).get() }),
483
- });
484
- const mergeObjects = (...exprs) => asExpr({
485
- raw: f => asExprRaw({ $mergeObjects: exprs.map(x => x.raw(f).get()) }),
486
- });
487
- const anyElementTrue = (expr) => asExpr({
488
- raw: f => asExprRaw({ $anyElementTrue: expr.raw(f).get() }),
489
- });
490
- const $reduce = (input, initialValue, inExpr) => asExpr({
491
- raw: f => asExprRaw({
492
- $reduce: {
493
- input: input.raw(f).get(),
494
- initialValue: initialValue.raw(f).get(),
495
- in: inExpr.raw(f).get(),
496
- },
497
- }),
498
- });
499
- const indexOfArray = (array, item) => asExpr({
500
- raw: f => asExprRaw({
501
- $indexOfArray: [array.raw(f).get(), item.raw(f).get()],
502
- }),
503
- });
504
- const slice = (array, start, end) => asExpr({
505
- raw: f => asExprRaw({
506
- $slice: [array.raw(f).get(), start.raw(f).get(), end.raw(f).get()],
507
- }),
508
- });
367
+ expr,
368
+ as: "x",
369
+ cond: ctx()("x").expr()
370
+ });
371
+ const filter = ({ as, cond, expr, limit }) => asExpr({ raw: (f) => asExprRaw({ $filter: {
372
+ input: expr.raw(f).get(),
373
+ as,
374
+ cond: cond.raw(f).get(),
375
+ ...limit ? { limit: limit.raw(f).get() } : {}
376
+ } }) });
377
+ const sortArray = ({ sortBy, expr, order }) => asExpr({ raw: (f) => asExprRaw({ $sortArray: {
378
+ input: expr.raw(f).get(),
379
+ sortBy: { [sortBy]: order ?? -1 }
380
+ } }) });
381
+ const isArray = (expr) => asBoolExpr({ raw: (f) => asExprRaw({ $isArray: expr.raw(f).get() }) });
382
+ const inArray = (item, expr) => asExpr({ raw: (f) => asExprRaw({ $in: [item.raw(f).get(), expr.raw(f).get()] }) });
383
+ const array = (...exprs) => asExpr({ raw: (f) => asExprRaw(exprs.map((x) => x.raw(f).get())) });
384
+ const concatArray = (...exprs) => asExpr({ raw: (f) => asExprRaw({ $concatArrays: exprs.map((x) => x.raw(f).get()) }) });
385
+ const first = (expr) => asExpr({ raw: (f) => asExprRaw({ $first: expr.raw(f).get() }) });
386
+ const firstSure = first;
387
+ const last = (expr) => asExpr({ raw: (f) => asExprRaw({ $last: expr.raw(f).get() }) });
388
+ const mergeObjects = (...exprs) => asExpr({ raw: (f) => asExprRaw({ $mergeObjects: exprs.map((x) => x.raw(f).get()) }) });
389
+ const anyElementTrue = (expr) => asExpr({ raw: (f) => asExprRaw({ $anyElementTrue: expr.raw(f).get() }) });
390
+ const $reduce = (input, initialValue, inExpr) => asExpr({ raw: (f) => asExprRaw({ $reduce: {
391
+ input: input.raw(f).get(),
392
+ initialValue: initialValue.raw(f).get(),
393
+ in: inExpr.raw(f).get()
394
+ } }) });
395
+ const indexOfArray = (array, item) => asExpr({ raw: (f) => asExprRaw({ $indexOfArray: [array.raw(f).get(), item.raw(f).get()] }) });
396
+ const slice = (array, start, end) => asExpr({ raw: (f) => asExprRaw({ $slice: [
397
+ array.raw(f).get(),
398
+ start.raw(f).get(),
399
+ end.raw(f).get()
400
+ ] }) });
509
401
  const except = (a, b) => {
510
- const value = ctx()('value');
511
- const out = value.of('out').expr();
512
- const except = value.of('except').expr();
513
- const curr = ctx()('this').expr();
514
- const indexInExcept = ctx()('indexInExcept').expr();
515
- return $let({
516
- res: [
517
- 'res',
518
- $reduce(a, field({ out: ['out', array()], except: ['except', b] }), $let({
519
- indexInExcept: ['indexInExcept', indexOfArray(except, curr)],
520
- }, ite(gte(indexInExcept, val(0)), field({
521
- out: ['out', out],
522
- except: [
523
- 'except',
524
- concatArray(ite(eq(indexInExcept)(val(0)), array(), slice(except, val(0), indexInExcept)), slice(except, add(indexInExcept, val(1)), size(except))),
525
- ],
526
- }), field({
527
- out: ['out', concatArray(out, array(curr))],
528
- except: ['except', except],
529
- })))),
530
- ],
531
- }, ctx()('res').of('out').expr());
402
+ const value = ctx()("value");
403
+ const out = value.of("out").expr();
404
+ const except = value.of("except").expr();
405
+ const curr = ctx()("this").expr();
406
+ const indexInExcept = ctx()("indexInExcept").expr();
407
+ return $let({ res: ["res", $reduce(a, field({
408
+ out: ["out", array()],
409
+ except: ["except", b]
410
+ }), $let({ indexInExcept: ["indexInExcept", indexOfArray(except, curr)] }, ite(gte(indexInExcept, val(0)), field({
411
+ out: ["out", out],
412
+ except: ["except", concatArray(ite(eq(indexInExcept)(val(0)), array(), slice(except, val(0), indexInExcept)), slice(except, add(indexInExcept, val(1)), size(except)))]
413
+ }), field({
414
+ out: ["out", concatArray(out, array(curr))],
415
+ except: ["except", except]
416
+ }))))] }, ctx()("res").of("out").expr());
532
417
  };
533
-
534
- const $match1 = (query) => f => asStages(query ? [{ $match: query.raw(f()) }] : []);
535
- const $set1 = (updater) => f => asStages([
536
- {
537
- $set: Object.fromEntries(updater.raw(f()).map(([k, v]) => [
538
- f()
539
- .of(k.slice(1))
540
- .str(),
541
- v,
542
- ])),
543
- },
544
- ]);
545
- const $project1 = (projection) => asStages([
546
- {
547
- $project: mapExactToObject(projection, () => 1),
548
- },
549
- ]);
550
- const $replaceWith1 = (expr) => f => {
551
- const parts = f().str().split('.').filter(id$1);
552
- return asStages([
553
- { $replaceWith: parts.reduce((v, k) => ({ [k]: v }), expr.raw(f()).get()) },
554
- ]);
555
- };
556
- const $unwind1 = (k, includeNull) => f => {
557
- const path = `$${f().of(k).str()}`;
558
- return asStages([
559
- { $unwind: includeNull === null ? { path, preserveNullAndEmptyArrays: true } : path },
560
- ]);
561
- };
562
- const $group1 = (id, args) => (f) => asStages([
563
- {
564
- $group: {
565
- _id: id.raw(f()).get(),
566
- ...mapExactToObject(args, v => v.raw(f())),
567
- },
568
- },
569
- ]);
570
- const rawVars = (vars, f) => mapExactToObject(vars, v => v.raw(f).get());
571
- const $simpleLookup1 = (args) => f => {
572
- const { coll, k, vars, fields, ...etc } = args;
573
- const letVars = rawVars(vars, f());
574
- return asStages([
575
- {
576
- $lookup: {
577
- ...(coll && { from: coll.collectionName }),
578
- ...(fields && {
579
- localField: f().with(fields.local).str(),
580
- foreignField: root().with(fields.foreign).str(),
581
- }),
582
- as: f().of(k).str(),
583
- ...(Object.keys(letVars).length > 0 && { let: letVars }),
584
- ...etc,
585
- },
586
- },
587
- ]);
418
+ //#endregion
419
+ //#region .build/lib/aggregate/raws.js
420
+ const $match1 = (query) => (f) => asStages(query ? [{ $match: query.raw(f()) }] : []);
421
+ const $set1 = (updater) => (f) => asStages([{ $set: Object.fromEntries(updater.raw(f()).map(([k, v]) => [f().of(k.slice(1)).str(), v])) }]);
422
+ const $project1 = (projection) => asStages([{ $project: mapExactToObject(projection, () => 1) }]);
423
+ const $replaceWith1 = (expr) => (f) => {
424
+ const parts = f().str().split(".").filter(id$1);
425
+ return asStages([{ $replaceWith: parts.reduce((v, k) => ({ [k]: v }), expr.raw(f()).get()) }]);
588
426
  };
589
-
427
+ const $unwind1 = (k, includeNull) => (f) => {
428
+ const path = `$${f().of(k).str()}`;
429
+ return asStages([{ $unwind: includeNull === null ? {
430
+ path,
431
+ preserveNullAndEmptyArrays: true
432
+ } : path }]);
433
+ };
434
+ const $group1 = (id, args) => (f) => asStages([{ $group: {
435
+ _id: id.raw(f()).get(),
436
+ ...mapExactToObject(args, (v) => v.raw(f()))
437
+ } }]);
438
+ const rawVars = (vars, f) => mapExactToObject(vars, (v) => v.raw(f).get());
439
+ const $simpleLookup1 = (args) => (f) => {
440
+ const { coll, k, vars, fields, ...etc } = args;
441
+ const letVars = rawVars(vars, f());
442
+ return asStages([{ $lookup: {
443
+ ...coll && { from: coll.collectionName },
444
+ ...fields && {
445
+ localField: f().with(fields.local).str(),
446
+ foreignField: root().with(fields.foreign).str()
447
+ },
448
+ as: f().of(k).str(),
449
+ ...Object.keys(letVars).length > 0 && { let: letVars },
450
+ ...etc
451
+ } }]);
452
+ };
453
+ //#endregion
454
+ //#region .build/lib/aggregate/mongo-stages.js
590
455
  const $match_ = (query) => $match1(query)(root);
591
456
  const $set_ = (updater) => $set1(updater)(root);
592
457
  const $replaceWith_ = (expr) => $replaceWith1(expr)(root);
@@ -594,1856 +459,1745 @@ const $unwind_ = (k, includeNull) => $unwind1(k, includeNull)(root);
594
459
  const $group_ = () => (id, args) => $group1(id, args)(root);
595
460
  const $project_ = $project1;
596
461
  const $simpleLookup_ = (args) => $simpleLookup1(args)(root);
597
-
462
+ //#endregion
463
+ //#region .build/lib/aggregate/group/utils/sub-group.js
598
464
  const subGroup = (id, args, addGrp) => {
599
- const part = filterDefined(array(ite(eqTyped(root().of('after').expr(), nil), nil, field({
600
- v: ['v', root().of('after').expr()],
601
- old: ['old', val(false)],
602
- deleted: [
603
- 'deleted',
604
- root()
605
- .of('deleted')
606
- .of('after')
607
- .expr(),
608
- ],
609
- })), ite(eqTyped(root().of('before').expr(), nil), nil, field({
610
- v: ['v', root().of('before').expr()],
611
- old: ['old', val(true)],
612
- deleted: [
613
- 'deleted',
614
- root()
615
- .of('deleted')
616
- .of('before')
617
- .expr(),
618
- ],
619
- }))));
620
- const replaceWith = (expr) => $replaceWith_(expr);
621
- return link()
622
- .with($replaceWith_(field({
623
- part: ['part', part],
624
- })))
625
- .with($unwind_('part'))
626
- .with($replaceWith_(root().of('part').expr()))
627
- .with($group_()(sub(id, root().of('v')), mapExact(args, v => v.group)))
628
- .with(replaceWith(field(addGrp(mapExact(args, (_, k) => $getField(root().expr(), k)))))).stages;
465
+ const part = filterDefined(array(ite(eqTyped(root().of("after").expr(), nil), nil, field({
466
+ v: ["v", root().of("after").expr()],
467
+ old: ["old", val(false)],
468
+ deleted: ["deleted", root().of("deleted").of("after").expr()]
469
+ })), ite(eqTyped(root().of("before").expr(), nil), nil, field({
470
+ v: ["v", root().of("before").expr()],
471
+ old: ["old", val(true)],
472
+ deleted: ["deleted", root().of("deleted").of("before").expr()]
473
+ }))));
474
+ const replaceWith = (expr) => $replaceWith_(expr);
475
+ return link().with($replaceWith_(field({ part: ["part", part] }))).with($unwind_("part")).with($replaceWith_(root().of("part").expr())).with($group_()(sub(id, root().of("v")), mapExact(args, (v) => v.group))).with(replaceWith(field(addGrp(mapExact(args, (_, k) => $getField(root().expr(), k)))))).stages;
629
476
  };
630
-
631
- const dayAndMonthPart = (date) => asExpr({
632
- raw: f => asExprRaw({ $dateToString: { date: date.raw(f).get(), format: '%m-%d' } }),
633
- });
634
- const now = () => asExpr({
635
- raw: f => asExprRaw('$$NOW'),
636
- });
637
- const monthPart = (date) => asExpr({
638
- raw: f => asExprRaw({ $dateToString: { date: date.raw(f).get(), format: '%Y-%m' } }),
639
- });
640
- const weekPart = (date) => asExpr({
641
- raw: f => asExprRaw({ $dateToString: { date: date.raw(f).get(), format: '%Y-%U' } }),
642
- });
643
- const year = (date) => asExpr({
644
- raw: f => asExprRaw({ $year: date.raw(f).get() }),
645
- });
646
- const dateAdd = (date, amount, unit) => asExpr({
647
- raw: f => asExprRaw({
648
- $dateAdd: {
649
- startDate: date.raw(f).get(),
650
- unit: unit.raw(f).get(),
651
- amount: amount.raw(f).get(),
652
- },
653
- }),
654
- });
655
- const maxDate = (expr) => asExpr({
656
- raw: f => asExprRaw({ $max: expr.raw(f).get() }),
657
- });
658
- const minDate = (expr) => asExpr({
659
- raw: f => asExprRaw({ $min: expr.raw(f).get() }),
660
- });
661
- const datePart = (date) => asExpr({
662
- raw: f => asExprRaw({ $dateToString: { date: date.raw(f).get(), format: '%Y-%m-%d' } }),
663
- });
664
- const startOf = (startDate, freq, offset) => asExpr({
665
- raw: f => asExprRaw({
666
- $let: {
667
- vars: { d: startDate.raw(f).get(), f: freq.raw(f).get(), i: offset.raw(f).get() },
668
- in: {
669
- $switch: {
670
- branches: [
671
- {
672
- case: { $eq: ['$$f', 'week'] },
673
- then: {
674
- $dateFromParts: {
675
- isoWeekYear: { $isoWeekYear: '$$d' },
676
- isoWeek: {
677
- $add: [
678
- { $isoWeek: '$$d' },
679
- {
680
- $cond: {
681
- if: {
682
- $lt: ['$$i', { $isoDayOfWeek: '$$d' }],
683
- },
684
- then: 1,
685
- else: 0,
686
- },
687
- },
688
- ],
689
- },
690
- isoDayOfWeek: '$$i',
691
- },
692
- },
693
- },
694
- {
695
- case: { $eq: ['$$f', 'month'] },
696
- then: {
697
- $dateFromParts: {
698
- year: { $year: '$$d' },
699
- month: {
700
- $add: [
701
- { $month: '$$d' },
702
- {
703
- $cond: {
704
- if: {
705
- $lt: ['$$i', { $dayOfMonth: '$$d' }],
706
- },
707
- then: 1,
708
- else: 0,
709
- },
710
- },
711
- ],
712
- },
713
- day: '$$i',
714
- },
715
- },
716
- },
717
- {
718
- case: { $eq: ['$$f', 'year'] },
719
- then: {
720
- $dateFromParts: {
721
- year: {
722
- $add: [
723
- { $year: '$$d' },
724
- {
725
- $cond: {
726
- if: {
727
- $or: [
728
- {
729
- $lt: [{ $floor: { $divide: ['$$i', 100] } }, { $month: '$$d' }],
730
- },
731
- {
732
- $and: [
733
- {
734
- $eq: [
735
- { $floor: { $divide: ['$$i', 100] } },
736
- { $month: '$$d' },
737
- ],
738
- },
739
- {
740
- $lt: [{ $mod: ['$$i', 100] }, { $dayOfMonth: '$$d' }],
741
- },
742
- ],
743
- },
744
- ],
745
- },
746
- then: 1,
747
- else: 0,
748
- },
749
- },
750
- ],
751
- },
752
- month: { $floor: { $divide: ['$$i', 100] } },
753
- day: { $mod: ['$$i', 100] },
754
- },
755
- },
756
- },
757
- ],
758
- default: {
759
- $dateFromParts: {
760
- year: { $year: '$$d' },
761
- month: { $month: '$$d' },
762
- day: { $add: [{ $dayOfMonth: '$$d' }, '$$i'] },
763
- },
764
- },
765
- },
766
- },
767
- },
768
- }),
769
- });
770
- const dateDiff = ({ end, unit, start, }) => asExpr({
771
- raw: f => asExprRaw({
772
- $let: {
773
- vars: {
774
- f: unit.raw(f).get(),
775
- end: end.raw(f).get(),
776
- start: start.raw(f).get(),
777
- },
778
- in: {
779
- $let: {
780
- vars: {
781
- diff: {
782
- $dateDiff: {
783
- startDate: '$$start',
784
- endDate: '$$end',
785
- unit: '$$f',
786
- },
787
- },
788
- },
789
- in: {
790
- $switch: {
791
- branches: [
792
- {
793
- case: { $eq: ['$$f', 'month'] },
794
- then: {
795
- $cond: {
796
- if: {
797
- $lte: [{ $dayOfMonth: '$$start' }, { $dayOfMonth: '$$end' }],
798
- },
799
- then: '$$diff',
800
- else: { $subtract: ['$$diff', 1] },
801
- },
802
- },
803
- },
804
- {
805
- case: { $eq: ['$$f', 'week'] },
806
- then: {
807
- $cond: {
808
- if: {
809
- $lte: [{ $isoDayOfWeek: '$$start' }, { $isoDayOfWeek: '$$end' }],
810
- },
811
- then: '$$diff',
812
- else: { $subtract: ['$$diff', 1] },
813
- },
814
- },
815
- },
816
- {
817
- case: { $eq: ['$$f', 'year'] },
818
- then: {
819
- $cond: {
820
- if: {
821
- $or: [
822
- {
823
- $lt: [{ $month: '$$start' }, { $month: '$$end' }],
824
- },
825
- {
826
- $and: [
827
- {
828
- $eq: [{ $month: '$$start' }, { $month: '$$end' }],
829
- },
830
- {
831
- $lte: [{ $dayOfMonth: '$$start' }, { $dayOfMonth: '$$end' }],
832
- },
833
- ],
834
- },
835
- ],
836
- },
837
- then: '$$diff',
838
- else: { $subtract: ['$$diff', 1] },
839
- },
840
- },
841
- },
842
- ],
843
- default: '$$diff',
844
- },
845
- },
846
- },
847
- },
848
- },
849
- }),
850
- });
851
- const mapFromPlainDateTime = ({ plainDate, timezone, }) => asExpr({
852
- raw: f => asExprRaw({
853
- $dateFromString: {
854
- dateString: {
855
- $dateToString: { date: plainDate.raw(f).get(), timezone: 'GMT' },
856
- },
857
- timezone: timezone.raw(f).get(),
858
- },
859
- }),
860
- });
861
- const mapToPlainDateTime = (date, timezone) => asExpr({
862
- raw: f => asExprRaw({
863
- $dateFromString: {
864
- $dateToString: {
865
- date: date.raw(f).get(),
866
- timezone: timezone.raw(f).get(),
867
- },
868
- },
869
- }),
870
- });
871
-
872
- const range = (start, end, step) => asExpr({
873
- raw: f => asExprRaw({ $range: [start.raw(f).get(), end.raw(f).get(), step?.raw(f).get() ?? 1] }),
874
- });
875
- const $map0 = ({ as, expr, input, }) => asExpr({
876
- raw: f => asExprRaw({
877
- $map: {
878
- input: input.raw(f).get(),
879
- as,
880
- in: expr.raw(f).get(),
881
- },
882
- }),
883
- });
884
- const $map1 = (ex, map) => $map0({ input: ex, as: 'item', expr: map(ctx()('item')) });
885
- const $map = (ex, map) => $map1(ex, i => map(i.expr()));
886
-
477
+ //#endregion
478
+ //#region .build/lib/expression/date.js
479
+ const dayAndMonthPart = (date) => asExpr({ raw: (f) => asExprRaw({ $dateToString: {
480
+ date: date.raw(f).get(),
481
+ format: "%m-%d"
482
+ } }) });
483
+ const now = () => asExpr({ raw: (f) => asExprRaw("$$NOW") });
484
+ const monthPart = (date) => asExpr({ raw: (f) => asExprRaw({ $dateToString: {
485
+ date: date.raw(f).get(),
486
+ format: "%Y-%m"
487
+ } }) });
488
+ const weekPart = (date) => asExpr({ raw: (f) => asExprRaw({ $dateToString: {
489
+ date: date.raw(f).get(),
490
+ format: "%Y-%U"
491
+ } }) });
492
+ const year = (date) => asExpr({ raw: (f) => asExprRaw({ $year: date.raw(f).get() }) });
493
+ const dateAdd = (date, amount, unit) => asExpr({ raw: (f) => asExprRaw({ $dateAdd: {
494
+ startDate: date.raw(f).get(),
495
+ unit: unit.raw(f).get(),
496
+ amount: amount.raw(f).get()
497
+ } }) });
498
+ const maxDate = (expr) => asExpr({ raw: (f) => asExprRaw({ $max: expr.raw(f).get() }) });
499
+ const minDate = (expr) => asExpr({ raw: (f) => asExprRaw({ $min: expr.raw(f).get() }) });
500
+ const datePart = (date) => asExpr({ raw: (f) => asExprRaw({ $dateToString: {
501
+ date: date.raw(f).get(),
502
+ format: "%Y-%m-%d"
503
+ } }) });
504
+ const startOf = (startDate, freq, offset) => asExpr({ raw: (f) => asExprRaw({ $let: {
505
+ vars: {
506
+ d: startDate.raw(f).get(),
507
+ f: freq.raw(f).get(),
508
+ i: offset.raw(f).get()
509
+ },
510
+ in: { $switch: {
511
+ branches: [
512
+ {
513
+ case: { $eq: ["$$f", "week"] },
514
+ then: { $dateFromParts: {
515
+ isoWeekYear: { $isoWeekYear: "$$d" },
516
+ isoWeek: { $add: [{ $isoWeek: "$$d" }, { $cond: {
517
+ if: { $lt: ["$$i", { $isoDayOfWeek: "$$d" }] },
518
+ then: 1,
519
+ else: 0
520
+ } }] },
521
+ isoDayOfWeek: "$$i"
522
+ } }
523
+ },
524
+ {
525
+ case: { $eq: ["$$f", "month"] },
526
+ then: { $dateFromParts: {
527
+ year: { $year: "$$d" },
528
+ month: { $add: [{ $month: "$$d" }, { $cond: {
529
+ if: { $lt: ["$$i", { $dayOfMonth: "$$d" }] },
530
+ then: 1,
531
+ else: 0
532
+ } }] },
533
+ day: "$$i"
534
+ } }
535
+ },
536
+ {
537
+ case: { $eq: ["$$f", "year"] },
538
+ then: { $dateFromParts: {
539
+ year: { $add: [{ $year: "$$d" }, { $cond: {
540
+ if: { $or: [{ $lt: [{ $floor: { $divide: ["$$i", 100] } }, { $month: "$$d" }] }, { $and: [{ $eq: [{ $floor: { $divide: ["$$i", 100] } }, { $month: "$$d" }] }, { $lt: [{ $mod: ["$$i", 100] }, { $dayOfMonth: "$$d" }] }] }] },
541
+ then: 1,
542
+ else: 0
543
+ } }] },
544
+ month: { $floor: { $divide: ["$$i", 100] } },
545
+ day: { $mod: ["$$i", 100] }
546
+ } }
547
+ }
548
+ ],
549
+ default: { $dateFromParts: {
550
+ year: { $year: "$$d" },
551
+ month: { $month: "$$d" },
552
+ day: { $add: [{ $dayOfMonth: "$$d" }, "$$i"] }
553
+ } }
554
+ } }
555
+ } }) });
556
+ const dateDiff = ({ end, unit, start }) => asExpr({ raw: (f) => asExprRaw({ $let: {
557
+ vars: {
558
+ f: unit.raw(f).get(),
559
+ end: end.raw(f).get(),
560
+ start: start.raw(f).get()
561
+ },
562
+ in: { $let: {
563
+ vars: { diff: { $dateDiff: {
564
+ startDate: "$$start",
565
+ endDate: "$$end",
566
+ unit: "$$f"
567
+ } } },
568
+ in: { $switch: {
569
+ branches: [
570
+ {
571
+ case: { $eq: ["$$f", "month"] },
572
+ then: { $cond: {
573
+ if: { $lte: [{ $dayOfMonth: "$$start" }, { $dayOfMonth: "$$end" }] },
574
+ then: "$$diff",
575
+ else: { $subtract: ["$$diff", 1] }
576
+ } }
577
+ },
578
+ {
579
+ case: { $eq: ["$$f", "week"] },
580
+ then: { $cond: {
581
+ if: { $lte: [{ $isoDayOfWeek: "$$start" }, { $isoDayOfWeek: "$$end" }] },
582
+ then: "$$diff",
583
+ else: { $subtract: ["$$diff", 1] }
584
+ } }
585
+ },
586
+ {
587
+ case: { $eq: ["$$f", "year"] },
588
+ then: { $cond: {
589
+ if: { $or: [{ $lt: [{ $month: "$$start" }, { $month: "$$end" }] }, { $and: [{ $eq: [{ $month: "$$start" }, { $month: "$$end" }] }, { $lte: [{ $dayOfMonth: "$$start" }, { $dayOfMonth: "$$end" }] }] }] },
590
+ then: "$$diff",
591
+ else: { $subtract: ["$$diff", 1] }
592
+ } }
593
+ }
594
+ ],
595
+ default: "$$diff"
596
+ } }
597
+ } }
598
+ } }) });
599
+ const mapFromPlainDateTime = ({ plainDate, timezone }) => asExpr({ raw: (f) => asExprRaw({ $dateFromString: {
600
+ dateString: { $dateToString: {
601
+ date: plainDate.raw(f).get(),
602
+ timezone: "GMT"
603
+ } },
604
+ timezone: timezone.raw(f).get()
605
+ } }) });
606
+ const mapToPlainDateTime = (date, timezone) => asExpr({ raw: (f) => asExprRaw({ $dateFromString: { $dateToString: {
607
+ date: date.raw(f).get(),
608
+ timezone: timezone.raw(f).get()
609
+ } } }) });
610
+ //#endregion
611
+ //#region .build/lib/expression/range.js
612
+ const range = (start, end, step) => asExpr({ raw: (f) => asExprRaw({ $range: [
613
+ start.raw(f).get(),
614
+ end.raw(f).get(),
615
+ step?.raw(f).get() ?? 1
616
+ ] }) });
617
+ const $map0 = ({ as, expr, input }) => asExpr({ raw: (f) => asExprRaw({ $map: {
618
+ input: input.raw(f).get(),
619
+ as,
620
+ in: expr.raw(f).get()
621
+ } }) });
622
+ const $map1 = (ex, map) => $map0({
623
+ input: ex,
624
+ as: "item",
625
+ expr: map(ctx()("item"))
626
+ });
627
+ const $map = (ex, map) => $map1(ex, (i) => map(i.expr()));
628
+ //#endregion
629
+ //#region .build/lib/update/updater.js
887
630
  const subUpdater = (a, f) => ({ raw: (g) => a.raw(g.with(f)) });
888
631
  const rawSet = (fields) => (f) => {
889
- return Object.entries(mapExactToObject0(fields, v => v)).flatMap(([k, v]) => v.raw(f).map(([l, v]) => [`.${k}${l}`, v]));
632
+ return Object.entries(mapExactToObject0(fields, (v) => v)).flatMap(([k, v]) => v.raw(f).map(([l, v]) => [`.${k}${l}`, v]));
890
633
  };
891
- const set = () => (fields) => ({
892
- raw: rawSet(fields),
893
- });
634
+ const set = () => (fields) => ({ raw: rawSet(fields) });
894
635
  const setQ = () => {
895
- return (fields) => ({
896
- raw: rawSet(fields),
897
- });
636
+ return (fields) => ({ raw: rawSet(fields) });
898
637
  };
899
- const weaken = (updater) => ({ raw: f => updater.raw(f) });
900
- const to = (expr) => ({
901
- raw: f => [['', expr.raw(f).get()]],
902
- });
903
-
904
- const dbcoll = (x) => ({
905
- db: x.dbName,
906
- coll: x.collectionName,
907
- });
908
-
909
- const $merge_ = ({ into, on, whenNotMatched, ...notMatched }) => asStages([
910
- {
911
- $merge: {
912
- into: dbcoll(into),
913
- on: on.str(),
914
- ...(whenNotMatched && { whenNotMatched }),
915
- ...(notMatched.stages && {
916
- whenMatched: notMatched.whenMatched,
917
- ...(notMatched.stages === 'ctx' && { let: rawVars(notMatched.vars, root()) }),
918
- }),
919
- },
920
- },
921
- ]);
638
+ const weaken = (updater) => ({ raw: (f) => updater.raw(f) });
639
+ const to = (expr) => ({ raw: (f) => [["", expr.raw(f).get()]] });
640
+ //#endregion
641
+ //#region .build/lib/utils/coll.js
642
+ const dbcoll = (x) => safeNarrow()({
643
+ db: x.dbName,
644
+ coll: x.collectionName
645
+ });
646
+ //#endregion
647
+ //#region .build/lib/aggregate/out.js
648
+ const $merge_ = ({ into, on, whenNotMatched, ...notMatched }) => asStages([{ $merge: {
649
+ into: dbcoll(into),
650
+ on: on.str(),
651
+ ...whenNotMatched && { whenNotMatched },
652
+ ...notMatched.stages && {
653
+ whenMatched: notMatched.whenMatched,
654
+ ...notMatched.stages === "ctx" && { let: rawVars(notMatched.vars, root()) }
655
+ }
656
+ } }]);
922
657
  const $merge2 = (args) => $merge_(args);
923
-
658
+ //#endregion
659
+ //#region .build/lib/aggregate/$merge.js
924
660
  const getSubsetMatchForExt = (ext) => {
925
- const extObj = mapExactToObject(ext, (v, k) => {
926
- return eq(root()
927
- .of('old')
928
- .of(k)
929
- .expr())(val(v));
930
- });
931
- const checks = Object.values(extObj);
932
- return checks.length ? (checks.length === 1 ? checks[0] : and(...checks)) : null;
661
+ const extObj = mapExactToObject(ext, (v, k) => {
662
+ return eq(root().of("old").of(k).expr())(val(v));
663
+ });
664
+ const checks = Object.values(extObj);
665
+ return checks.length ? checks.length === 1 ? checks[0] : and(...checks) : null;
933
666
  };
934
667
  const getWhenMatchedForMerge = (whenNotMatched, update, canWrite) => {
935
- const orNull = (e) => whenNotMatched === 'discard' ? $ifNull(e, nil) : e;
936
- const newOrOld = whenNotMatched ===
937
- 'insert'
938
- ? ctx()('new')
939
- : root();
940
- const merged = mergeObjects(root().expr(), update(ctx()('new').expr(), root().expr()), field({
941
- deletedAt: ['deletedAt', orNull(newOrOld.of('deletedAt').expr())],
942
- }));
943
- return link()
944
- .with($replaceWith_(field({
945
- old: ['old', root().expr()],
946
- merged: ['merged', merged],
947
- })))
948
- .with(getWhenMatched(whenNotMatched, canWrite)).stages;
668
+ const orNull = (e) => whenNotMatched === "discard" ? $ifNull(e, nil) : e;
669
+ const newOrOld = whenNotMatched === "insert" ? ctx()("new") : root();
670
+ const merged = mergeObjects(root().expr(), update(ctx()("new").expr(), root().expr()), field({ deletedAt: ["deletedAt", orNull(newOrOld.of("deletedAt").expr())] }));
671
+ return link().with($replaceWith_(field({
672
+ old: ["old", root().expr()],
673
+ merged: ["merged", merged]
674
+ }))).with(getWhenMatched(whenNotMatched, canWrite)).stages;
949
675
  };
950
676
  const getWhenMatched = (whenNotMatched, canWrite) => {
951
- const orNull = (e) => whenNotMatched === 'discard' ? $ifNull(e, nil) : e;
952
- const preMergeOld = mergeObjects(root().of('old').expr(), field({
953
- deletedAt: ['deletedAt', orNull(root().of('old').of('deletedAt').expr())],
954
- touchedAt: ['touchedAt', root().of('merged').of('touchedAt').expr()],
955
- }));
956
- const diff = ne(preMergeOld)(root().of('merged').expr());
957
- const useNew = canWrite ? and(diff, canWrite) : diff;
958
- return link().with($replaceWith_(ite(useNew, root().of('merged').expr(), root().of('old').expr()))).stages;
677
+ const orNull = (e) => whenNotMatched === "discard" ? $ifNull(e, nil) : e;
678
+ const preMergeOld = mergeObjects(root().of("old").expr(), field({
679
+ deletedAt: ["deletedAt", orNull(root().of("old").of("deletedAt").expr())],
680
+ touchedAt: ["touchedAt", root().of("merged").of("touchedAt").expr()]
681
+ }));
682
+ const diff = ne(preMergeOld)(root().of("merged").expr());
683
+ const useNew = canWrite ? and(diff, canWrite) : diff;
684
+ return link().with($replaceWith_(ite(useNew, root().of("merged").expr(), root().of("old").expr()))).stages;
959
685
  };
960
686
  const $mergeX = (out, keys, f, map, ext, update) => {
961
- const patch = mapExact(keys, (v) => {
962
- return $ifNull(sub(v, f), nil);
963
- });
964
- const filter = mapExactToObject(ext, v => ({ $eq: v }));
965
- const sameSubset = getSubsetMatchForExt(ext);
966
- const setDeleted = out.whenNotMatched === 'discard';
967
- const replacer = map(field(omitPick().backward(spread(patch, {
968
- _id: ['_id', f.of('_id').expr()],
969
- touchedAt: ['touchedAt', current],
970
- }))));
971
- const sss = setDeleted
972
- ? link()
973
- .with($set_(set()({
974
- deletedAt: ['deletedAt', to(current)],
975
- })))
976
- .with($merge_({
977
- into: out.coll,
978
- on: root().of('_id'),
979
- whenNotMatched: 'insert',
980
- stages: true,
981
- whenMatched: getWhenMatchedForMerge(out.whenNotMatched, update, sameSubset),
982
- })).stages
983
- : link().with($merge_({
984
- into: out.coll,
985
- on: root().of('_id'),
986
- whenNotMatched: 'fail',
987
- stages: true,
988
- whenMatched: getWhenMatchedForMerge(out.whenNotMatched, update, sameSubset),
989
- })).stages;
990
- const teardown = (coll) => ({
991
- collection: coll,
992
- method: 'updateMany',
993
- params: [
994
- filter,
995
- [
996
- {
997
- $unset: Object.keys(mapExactToObject(keys, () => 1)),
998
- },
999
- ],
1000
- ],
1001
- });
1002
- return {
1003
- raw: (first) => link().with($replaceWith_(replacer)).with(sss)
1004
- .stages,
1005
- teardown: c => c(teardown(out.coll)),
1006
- };
1007
- };
1008
- const $mergeId = () => (out, keys, id, ext, update = x => x) => {
1009
- const omRORec = omitRORec();
1010
- return $mergeX(out, keys, root().of('after'), or => {
1011
- return ite(eqTyped(root().of('after').expr(), nil), field(omRORec.backward(spread(mapExact(keys, () => nil), {
1012
- _id: ['_id', id],
1013
- touchedAt: ['touchedAt', current],
1014
- }))), or);
1015
- }, ext, update);
1016
- };
1017
- const $simpleMergePart = () => (out, keys, ext, update = x => x) => $mergeX(out, keys, root(), id$1, ext, update);
1018
- const $simpleMerge = () => (out, keys, whenNotMatched = 'fail', update = x => x) => $mergeX({ coll: out, whenNotMatched }, keys, root(), id$1, {}, update);
1019
- const $mergePart = () => (out, keys, ext, update = x => x) => $mergeId()({ coll: out, whenNotMatched: 'fail' }, keys, assertNotNull$1(root().of('before').of('_id').expr()), ext, update);
1020
- const $merge = () => (out, keys, update = x => x) => $mergePart()(out, keys, {}, update);
687
+ const patch = mapExact(keys, (v) => {
688
+ return $ifNull(sub(v, f), nil);
689
+ });
690
+ const filter = mapExactToObject(ext, (v) => ({ $eq: v }));
691
+ const sameSubset = getSubsetMatchForExt(ext);
692
+ const setDeleted = out.whenNotMatched === "discard";
693
+ const replacer = map(field(spread(patch, {
694
+ _id: ["_id", f.of("_id").expr()],
695
+ touchedAt: ["touchedAt", current]
696
+ })));
697
+ const sss = setDeleted ? link().with($set_(set()({ deletedAt: ["deletedAt", to(current)] }))).with($merge_({
698
+ into: out.coll,
699
+ on: root().of("_id"),
700
+ whenNotMatched: "insert",
701
+ stages: true,
702
+ whenMatched: getWhenMatchedForMerge(out.whenNotMatched, update, sameSubset)
703
+ })).stages : link().with($merge_({
704
+ into: out.coll,
705
+ on: root().of("_id"),
706
+ whenNotMatched: "fail",
707
+ stages: true,
708
+ whenMatched: getWhenMatchedForMerge(out.whenNotMatched, update, sameSubset)
709
+ })).stages;
710
+ const teardown = (coll) => ({
711
+ collection: coll,
712
+ method: "updateMany",
713
+ params: [filter, [{ $unset: Object.keys(mapExactToObject(keys, () => 1)) }]]
714
+ });
715
+ return {
716
+ raw: (first) => link().with($replaceWith_(replacer)).with(sss).stages,
717
+ teardown: (c) => c(teardown(out.coll))
718
+ };
719
+ };
720
+ const $mergeId = () => (out, keys, id, ext, update = (x) => x) => {
721
+ return $mergeX(out, keys, root().of("after"), (or) => {
722
+ return ite(eqTyped(root().of("after").expr(), nil), field(spread(mapExact(keys, () => nil), {
723
+ _id: ["_id", id],
724
+ touchedAt: ["touchedAt", current]
725
+ })), or);
726
+ }, ext, update);
727
+ };
728
+ const $simpleMergePart = () => (out, keys, ext, update = (x) => x) => $mergeX(out, keys, root(), id$1, ext, update);
729
+ const $simpleMerge = () => (out, keys, whenNotMatched = "fail", update = (x) => x) => $mergeX({
730
+ coll: out,
731
+ whenNotMatched
732
+ }, keys, root(), id$1, {}, update);
733
+ const $mergePart = () => (out, keys, ext, update = (x) => x) => {
734
+ return $mergeId()({
735
+ coll: out,
736
+ whenNotMatched: "fail"
737
+ }, keys, assertNotNull$1(root().of("before").of("_id").expr()), ext, update);
738
+ };
739
+ const $merge = () => (out, keys, update = (x) => x) => $mergePart()(out, keys, {}, update);
1021
740
  const assertNotNull$1 = (expr) => expr;
1022
-
741
+ //#endregion
742
+ //#region .build/lib/aggregate/group/utils/sub-merge.js
1023
743
  const subMerge = (args, out, gid, extra, idPrefix, first) => {
1024
- const e = extra;
1025
- const mergeOldWithNew = mapExact0(args, (v, k) => to(first
1026
- ? ctx()('new').of(k).expr()
1027
- : v.merge(root().of('old').of(k).expr(), ctx()('new').of(k).expr())));
1028
- const mergeAggregates = $set_(set()({
1029
- merged: ['merged', set()(mergeOldWithNew)],
1030
- }));
1031
- const gidPath = root().of(gid).expr();
1032
- const mapId = (k, v) => map1(k, v);
1033
- const F1 = {
1034
- _id: ['_id', to(idPrefix ? concat(val(idPrefix), $rand) : $rand)],
1035
- touchedAt: ['touchedAt', to(current)],
1036
- };
1037
- const F2 = mapId(gid, to(gidPath));
1038
- const addExtraAndMerge = {
1039
- ...mapExact0(extra, to),
1040
- ...F1,
1041
- ...F2,
1042
- };
1043
- const addTSAndExtra = {
1044
- ...mapExact0(e, to),
1045
- ...(out.whenNotMatched === 'insert' ? { deletedAt: ['deletedAt', to(nil)] } : {}),
1046
- touchedAt: ['touchedAt', to(current)],
1047
- };
1048
- const updater = set()(addTSAndExtra);
1049
- const whenMatched = getWhenMatched(out.whenNotMatched, null);
1050
- return link()
1051
- .with($set_(set()(addExtraAndMerge)))
1052
- .with($merge_({
1053
- ...out,
1054
- on: root().of(gid),
1055
- vars: { new: ['new', root().expr()] },
1056
- stages: 'ctx',
1057
- whenMatched: link()
1058
- .with($replaceWith_(field({ old: ['old', root().expr()], merged: ['merged', root().expr()] })))
1059
- .with(mergeAggregates)
1060
- .with($set_(set()({
1061
- merged: [
1062
- 'merged',
1063
- subUpdater(updater, root().of('merged')),
1064
- ],
1065
- })))
1066
- .with(whenMatched).stages,
1067
- })).stages;
744
+ const e = extra;
745
+ const mergeOldWithNew = mapExact0(args, (v, k) => to(first ? ctx()("new").of(k).expr() : v.merge(root().of("old").of(k).expr(), ctx()("new").of(k).expr())));
746
+ const mergeAggregates = $set_(set()({ merged: ["merged", set()(mergeOldWithNew)] }));
747
+ const gidPath = root().of(gid).expr();
748
+ const mapId = (k, v) => map1(k, v);
749
+ const F1 = {
750
+ _id: ["_id", to(idPrefix ? concat(val(idPrefix), $rand) : $rand)],
751
+ touchedAt: ["touchedAt", to(current)]
752
+ };
753
+ const F2 = mapId(gid, to(gidPath));
754
+ const extraAndId = spread0(mapExact0(extra, to), F1);
755
+ const addExtraAndMerge = spread0(extraAndId, F2);
756
+ const addTSAndExtra = {
757
+ ...mapExact0(e, to),
758
+ ...out.whenNotMatched === "insert" ? { deletedAt: ["deletedAt", to(nil)] } : {},
759
+ touchedAt: ["touchedAt", to(current)]
760
+ };
761
+ const updater = set()(addTSAndExtra);
762
+ const whenMatched = getWhenMatched(out.whenNotMatched, null);
763
+ const whenMatchedStages = link().with($replaceWith_(field({
764
+ old: ["old", root().expr()],
765
+ merged: ["merged", root().expr()]
766
+ }))).with(mergeAggregates).with($set_(set()({ merged: ["merged", subUpdater(updater, root().of("merged"))] }))).with(whenMatched).stages;
767
+ const ready = $set_(set()(addExtraAndMerge));
768
+ const stages = link().with(ready);
769
+ if (out.whenNotMatched === "insert") {
770
+ const insertMarker = $set_(set()({ deletedAt: ["deletedAt", to(nil)] }));
771
+ return stages.with(insertMarker).with($merge_({
772
+ into: out.into,
773
+ whenNotMatched: "insert",
774
+ on: root().of(gid),
775
+ vars: { new: ["new", root().expr()] },
776
+ stages: "ctx",
777
+ whenMatched: whenMatchedStages
778
+ })).stages;
779
+ }
780
+ if (out.whenNotMatched === "discard") {
781
+ const discardMarker = $set_(set()({ deletedAt: ["deletedAt", to(current)] }));
782
+ return stages.with(discardMarker).with($merge_({
783
+ into: out.into,
784
+ whenNotMatched: "insert",
785
+ on: root().of(gid),
786
+ vars: { new: ["new", root().expr()] },
787
+ stages: "ctx",
788
+ whenMatched: whenMatchedStages
789
+ })).stages;
790
+ }
791
+ return stages.with($merge_({
792
+ into: out.into,
793
+ whenNotMatched: "fail",
794
+ on: root().of(gid),
795
+ vars: { new: ["new", root().expr()] },
796
+ stages: "ctx",
797
+ whenMatched: whenMatchedStages
798
+ })).stages;
1068
799
  };
1069
-
800
+ //#endregion
801
+ //#region .build/lib/aggregate/group/$group-merge.js
1070
802
  const addGrp = (gid) => (expr) => {
1071
- const omit = omitPick();
1072
- return omit.backward(mergeExpr(omit.forward(expr), map1(gid, root().of('_id').expr())));
1073
- };
1074
- const $groupMerge = (id, args, out, gid, extra, idPrefix = '') => ({
1075
- raw: (first) => link()
1076
- .with(subGroup(id, args, addGrp(gid)))
1077
- .with(subMerge(args, out, gid, extra, idPrefix, first)).stages,
1078
- teardown: c => c(out.whenNotMatched === 'insert'
1079
- ? {
1080
- collection: out.into,
1081
- method: 'deleteMany',
1082
- params: [{}],
1083
- }
1084
- : {
1085
- collection: out.into,
1086
- method: 'updateMany',
1087
- params: [
1088
- {},
1089
- [
1090
- {
1091
- $unset: Object.keys({
1092
- ...mapExactToObject(extra, () => 1),
1093
- ...mapExactToObject(args, () => 1),
1094
- }),
1095
- },
1096
- ],
1097
- ],
1098
- }),
1099
- });
1100
- const $groupId = (id, args, out, extra) => $groupMerge(id, args, { into: out, whenNotMatched: 'fail' }, '_id', extra);
1101
- const $group = (id, args, out, extra, idPrefix = '') => $groupMerge(id, args, { into: out, whenNotMatched: 'insert' }, '_grp', extra, idPrefix);
1102
-
803
+ return mergeExpr(expr, map1(gid, root().of("_id").expr()));
804
+ };
805
+ const $groupMerge = (id, args, out, gid, extra, idPrefix = "") => ({
806
+ raw: (first) => link().with(subGroup(id, args, addGrp(gid))).with(subMerge(args, out, gid, extra, idPrefix, first)).stages,
807
+ teardown: (c) => c({
808
+ collection: out.into,
809
+ method: "updateMany",
810
+ params: [{}, [{ $unset: Object.keys({
811
+ ...mapExactToObject(extra, () => 1),
812
+ ...mapExactToObject(args, () => 1)
813
+ }) }, ...out.whenNotMatched === "insert" ? [{ $set: {
814
+ deletedAt: "$$NOW",
815
+ touchedAt: "$$CLUSTER_TIME"
816
+ } }] : []]]
817
+ })
818
+ });
819
+ const $groupId = (id, args, out, extra) => $groupMerge(id, args, {
820
+ into: out,
821
+ whenNotMatched: "fail"
822
+ }, "_id", extra);
823
+ const $group = (id, args, out, extra, idPrefix = "") => $groupMerge(id, args, {
824
+ into: out,
825
+ whenNotMatched: "insert"
826
+ }, "_grp", extra, idPrefix);
827
+ //#endregion
828
+ //#region .build/types/mongo.js
829
+ var mongo_exports = /* @__PURE__ */ __exportAll({});
830
+ __reExport(mongo_exports, require("mongodb"));
831
+ //#endregion
832
+ //#region .build/types/index.js
833
+ var types_exports = /* @__PURE__ */ __exportAll({});
834
+ __reExport(types_exports, mongo_exports);
835
+ //#endregion
836
+ //#region .build/lib/aggregate/set/$replace-with-each.js
1103
837
  const deltaExpr = (expr) => (field) => {
1104
- return ite(eqTyped($ifNull(root().of(field).expr(), nil), nil), nil, expr(field));
838
+ return ite(eqTyped($ifNull(root().of(field).expr(), nil), nil), nil, expr(field));
1105
839
  };
1106
840
  const $setEach1 = (updater, dict) => {
1107
- return $set1(set()(mapExact1(dict, updater)));
841
+ return $set1(set()(mapExact1(dict, updater)));
1108
842
  };
1109
843
  const $setEach = (updater, dict) => $setEach1(updater, dict)(root);
1110
844
  const $replaceWithEach1 = (t) => {
1111
- return $setEach(k => to(t(k)), {
1112
- after: ['after', 'after'],
1113
- before: ['before', 'before'],
1114
- });
845
+ return $setEach((k) => to(t(k)), {
846
+ after: ["after", "after"],
847
+ before: ["before", "before"]
848
+ });
1115
849
  };
1116
850
  const $replaceWithEach = (expr) => $replaceWithEach1(deltaExpr(expr));
1117
-
851
+ //#endregion
852
+ //#region .build/lib/aggregate/set/$set-delta.js
1118
853
  const $replaceWithDelta = (expr) => $replaceWithEach((field) => sub(expr, root().of(field)));
1119
854
  const $setDelta = (updater) => {
1120
- const dict = {
1121
- after1: ['after1', 'after'],
1122
- before1: ['before1', 'before'],
1123
- };
1124
- const side = (k) => root().of(k);
1125
- const update = (k) => subUpdater(weaken(updater), side(k));
1126
- return link()
1127
- .with($setEach(k => to(side(k).expr()), dict))
1128
- .with($setEach(update, dict))
1129
- .with($replaceWithEach(field => root().of(`${field}1`).expr()))
1130
- .with($setEach(k => to(nil), dict)).stages;
855
+ const dict = {
856
+ after1: ["after1", "after"],
857
+ before1: ["before1", "before"]
858
+ };
859
+ const side = (k) => root().of(k);
860
+ const update = (k) => subUpdater(weaken(updater), side(k));
861
+ return link().with($setEach((k) => to(side(k).expr()), dict)).with($setEach(update, dict)).with($replaceWithEach((field) => root().of(`${field}1`).expr())).with($setEach((k) => to(nil), dict)).stages;
1131
862
  };
1132
-
863
+ //#endregion
864
+ //#region .build/lib/utils/guard.js
865
+ const sym = (eq) => ({
866
+ backward: eq.forward,
867
+ forward: eq.backward,
868
+ backward1: eq.forward1,
869
+ forward1: eq.backward1
870
+ });
871
+ const reflex = () => ({
872
+ backward: id,
873
+ forward: id,
874
+ backward1: id,
875
+ forward1: id
876
+ });
877
+ const id = (x) => x;
878
+ const assertEqual = () => reflex();
879
+ const fromEq = (eq) => ({
880
+ ...eq,
881
+ backward1: eq.backward,
882
+ forward1: eq.forward
883
+ });
884
+ const literalsEqaul = (_) => assertEqual();
885
+ //#endregion
886
+ //#region .build/lib/predicate/utils.js
1133
887
  const operator = () => (op) => (operand) => {
1134
- return {
1135
- raw: { [op]: operand },
1136
- };
888
+ return { raw: { [op]: operand } };
1137
889
  };
1138
-
890
+ //#endregion
891
+ //#region .build/lib/predicate/$eq.js
1139
892
  const dualEq = operator();
1140
- const $eq = dualEq('$eq');
1141
- const $ne = dualEq('$ne');
893
+ const $eq = dualEq("$eq");
894
+ const $ne = dualEq("$ne");
1142
895
  const comp = operator();
1143
- const $gt = comp('$gt');
1144
- const $gtTs = comp('$gt');
1145
- const $gteTs = comp('$gte');
1146
- const $lt = comp('$lt');
1147
- const dateLt = comp('$lt');
1148
- const $gte = comp('$gte');
1149
- const $lte = comp('$lte');
1150
- const $type = operator()('$type');
1151
- const $exists = operator()('$exists');
1152
-
1153
- const $expr = (expr) => ({
1154
- raw: f => ({ $expr: expr.raw(f).get() }),
1155
- });
1156
-
896
+ const $gt = comp("$gt");
897
+ const $gtTs = comp("$gt");
898
+ const $gteTs = comp("$gte");
899
+ const $lt = comp("$lt");
900
+ const dateLt = comp("$lt");
901
+ const $gte = comp("$gte");
902
+ const $lte = comp("$lte");
903
+ const $type = operator()("$type");
904
+ const $exists = operator()("$exists");
905
+ //#endregion
906
+ //#region .build/lib/predicate/$expr.js
907
+ const $expr = (expr) => ({ raw: (f) => safeNarrow()({ $expr: expr.raw(f).get() }) });
908
+ //#endregion
909
+ //#region .build/lib/predicate/$in.js
1157
910
  const dualIn = operator();
1158
- const $in = dualIn('$in');
1159
- const $nin = dualIn('$nin');
1160
-
911
+ const $in = dualIn("$in");
912
+ const $nin = dualIn("$nin");
913
+ //#endregion
914
+ //#region .build/lib/aggregate/match/$match-delta.js
1161
915
  const $matchDelta = (query) => concatStages($replaceWithDelta(ite(query, root().expr(), nil)), matchDelta());
1162
916
  const matchDelta = () => {
1163
- const part = (side) => root().of(side).expr();
1164
- return $match_($expr(ne(part('before'))(part('after'))));
917
+ const part = (side) => root().of(side).expr();
918
+ return $match_($expr(ne(part("before"))(part("after"))));
1165
919
  };
1166
-
920
+ //#endregion
921
+ //#region .build/lib/aggregate/match/$match.js
1167
922
  const $match = (query) => ({
1168
- raw: $match1($expr(query)),
1169
- delta: $matchDelta(query),
923
+ raw: $match1($expr(query)),
924
+ delta: $matchDelta(query)
1170
925
  });
1171
-
926
+ //#endregion
927
+ //#region .build/lib/aggregate/unwind/$unwind-delta.js
1172
928
  const joinIdOf = (k, k1, k1Id, k2Id) => {
1173
- if (k === k1)
1174
- return k1Id;
1175
- if (typeof k === 'string')
1176
- return k2Id;
1177
- const idOf = (key) => (key === k1 ? k1Id : k2Id);
1178
- return concat(idOf(k[0]), val(k[1]), idOf(k[2]));
929
+ if (k === k1) return k1Id;
930
+ if (typeof k === "string") return k2Id;
931
+ const idOf = (key) => key === k1 ? k1Id : k2Id;
932
+ return concat(idOf(k[0]), val(k[1]), idOf(k[2]));
1179
933
  };
1180
934
  const andAlso = (probe, keep) => ite(eqTyped(probe, nil), nil, keep);
1181
935
  const slotsMany = (k1, k2, k, emptyOf) => {
1182
- const emptyArr = array();
1183
- const src = root();
1184
- const k2Arr = (side) => src.of(side).of(k2).expr();
1185
- const k2OrEmpty = (side) => $ifNull(k2Arr(side), emptyArr);
1186
- const k1Id = root().of('_id').expr();
1187
- const k1Delta = field({
1188
- before: [
1189
- 'before',
1190
- $ifNull(src.of('before').of(k1).expr(), nil),
1191
- ],
1192
- after: [
1193
- 'after',
1194
- $ifNull(src.of('after').of(k1).expr(), nil),
1195
- ],
1196
- deleted: ['deleted', src.of('deleted').expr()],
1197
- });
1198
- const itemId = (k2Id) => {
1199
- const at = (key) => (key === k1 ? k1Id : k2Id);
1200
- if (typeof k === 'string')
1201
- return at(k);
1202
- return concat(at(k[0]), val(k[1]), at(k[2]));
1203
- };
1204
- const keyed = (side) => {
1205
- const items = ctx()('items').expr();
1206
- return $let({ items: ['items', k2OrEmpty(side)] }, ite(eq(items)(emptyArr), emptyOf(k1Id), $map0({
1207
- input: items,
1208
- as: 'b',
1209
- expr: field({
1210
- _id: ['_id', itemId(ctx()('b').of('_id').expr())],
1211
- value: ['value', ctx()('b').expr()],
1212
- }),
1213
- })));
1214
- };
1215
- const beforeKeyed = keyed('before');
1216
- const afterKeyed = keyed('after');
1217
- const bound = (name) => ctx()(name).expr();
1218
- const idOf = (name) => ctx()(name).of('_id').expr();
1219
- const valueOf = (name) => ctx()(name).of('value').expr();
1220
- const kept = $map0({
1221
- input: bound('beforeK'),
1222
- as: 'b',
1223
- expr: field({
1224
- _id: ['_id', idOf('b')],
1225
- before: ['before', valueOf('b')],
1226
- after: [
1227
- 'after',
1228
- first$1($map0({
1229
- input: filter({
1230
- expr: bound('afterK'),
1231
- as: 'a',
1232
- limit: val(1),
1233
- cond: eq(idOf('a'))(idOf('b')),
1234
- }),
1235
- as: 'a',
1236
- expr: valueOf('a'),
1237
- })),
1238
- ],
1239
- }),
1240
- });
1241
- const beforeIds = $map0({
1242
- input: bound('beforeK'),
1243
- as: 'id',
1244
- expr: ctx()('id').of('_id').expr(),
1245
- });
1246
- const added = $map0({
1247
- input: filter({
1248
- expr: bound('afterK'),
1249
- as: 'a',
1250
- cond: not(inArray(idOf('a'), beforeIds)),
1251
- }),
1252
- as: 'a',
1253
- expr: field({
1254
- _id: ['_id', idOf('a')],
1255
- before: ['before', nil],
1256
- after: ['after', valueOf('a')],
1257
- }),
1258
- });
1259
- const slots = $let({
1260
- beforeK: ['beforeK', beforeKeyed],
1261
- afterK: ['afterK', afterKeyed],
1262
- }, concatArray(kept, added));
1263
- const exclude = excludeIdem();
1264
- return $replaceWith_(field(exclude.backward(mergeExpr(exclude.forward(map1(k2, slots)), map1(k1, k1Delta)))));
936
+ const emptyArr = array();
937
+ const src = root();
938
+ const k2Arr = (side) => src.of(side).of(k2).expr();
939
+ const k2OrEmpty = (side) => $ifNull(k2Arr(side), emptyArr);
940
+ const k1Id = root().of("_id").expr();
941
+ const k1Delta = field({
942
+ before: ["before", $ifNull(src.of("before").of(k1).expr(), nil)],
943
+ after: ["after", $ifNull(src.of("after").of(k1).expr(), nil)],
944
+ deleted: ["deleted", src.of("deleted").expr()]
945
+ });
946
+ const itemId = (k2Id) => {
947
+ const at = (key) => key === k1 ? k1Id : k2Id;
948
+ if (typeof k === "string") return at(k);
949
+ return concat(at(k[0]), val(k[1]), at(k[2]));
950
+ };
951
+ const keyed = (side) => {
952
+ const items = ctx()("items").expr();
953
+ return $let({ items: ["items", k2OrEmpty(side)] }, ite(eq(items)(emptyArr), emptyOf(k1Id), $map0({
954
+ input: items,
955
+ as: "b",
956
+ expr: field({
957
+ _id: ["_id", itemId(ctx()("b").of("_id").expr())],
958
+ value: ["value", ctx()("b").expr()]
959
+ })
960
+ })));
961
+ };
962
+ const beforeKeyed = keyed("before");
963
+ const afterKeyed = keyed("after");
964
+ const bound = (name) => ctx()(name).expr();
965
+ const idOf = (name) => ctx()(name).of("_id").expr();
966
+ const valueOf = (name) => ctx()(name).of("value").expr();
967
+ const kept = $map0({
968
+ input: bound("beforeK"),
969
+ as: "b",
970
+ expr: field({
971
+ _id: ["_id", idOf("b")],
972
+ before: ["before", valueOf("b")],
973
+ after: ["after", first($map0({
974
+ input: filter({
975
+ expr: bound("afterK"),
976
+ as: "a",
977
+ limit: val(1),
978
+ cond: eq(idOf("a"))(idOf("b"))
979
+ }),
980
+ as: "a",
981
+ expr: valueOf("a")
982
+ }))]
983
+ })
984
+ });
985
+ const beforeIds = $map0({
986
+ input: bound("beforeK"),
987
+ as: "id",
988
+ expr: ctx()("id").of("_id").expr()
989
+ });
990
+ const added = $map0({
991
+ input: filter({
992
+ expr: bound("afterK"),
993
+ as: "a",
994
+ cond: not(inArray(idOf("a"), beforeIds))
995
+ }),
996
+ as: "a",
997
+ expr: field({
998
+ _id: ["_id", idOf("a")],
999
+ before: ["before", nil],
1000
+ after: ["after", valueOf("a")]
1001
+ })
1002
+ });
1003
+ const slots = $let({
1004
+ beforeK: ["beforeK", beforeKeyed],
1005
+ afterK: ["afterK", afterKeyed]
1006
+ }, concatArray(kept, added));
1007
+ return $replaceWith_(field(mergeExpr(map1(k2, slots), map1(k1, k1Delta))));
1265
1008
  };
1266
1009
  const noEmpty = (_id) => array();
1267
1010
  const padEmpty = (id) => array(field({
1268
- _id: ['_id', id],
1269
- value: ['value', field({})],
1011
+ _id: ["_id", id],
1012
+ value: ["value", field({})]
1270
1013
  }));
1271
1014
  const joinMany = (k1, k2, eq1, eq2) => {
1272
- const doc = root();
1273
- const id = () => root().of(k2).of('_id').expr();
1274
- const k1At = (side) => doc.of(k1).of(side).expr();
1275
- const rowOf = (a, b) => mergeObjects(mergeObjects(field({ _id: ['_id', id()] }), field(map1(k1, a))), field(map1(k2, b)));
1276
- const rowPad = (k1v, n2) => {
1277
- return rowOf(k1v, n2.forward(nil));
1278
- };
1279
- const rowReal = (k1v, k2v) => rowOf(k1v, k2v);
1280
- const k2join = (raw, orNull, pad, real) => ite(eqTyped(raw, field({})), pad, andAlso(orNull, real));
1281
- const joinAt = (side) => {
1282
- const k2t = () => root().of(k2).of(side).expr();
1283
- const k2w = () => root().of(k2).of(side).expr();
1284
- if (!eq1) {
1285
- const k1t = () => root().of(k1).of(side).expr();
1286
- return andAlso(k1At(side), k2join(k2t(), k2t(), eq2 ? rowPad(k1t(), eq2) : nil, rowReal(k1t(), k2t())));
1287
- }
1288
- const k1v = () => {
1289
- return $ifNull(root().of(k1).of(side).expr(), eq1.forward(nil));
1290
- };
1291
- return k2join(k2w(), k2w(), eq2 ? rowPad(k1v(), eq2) : nil, rowReal(k1v(), k2w()));
1292
- };
1293
- const isPad = (side) => ite(eq(doc.of(k2).of(side).expr())(field({})), val(true), doc.of(k1).of('deleted').of(side).expr());
1294
- const joinDelta = field({
1295
- _id: ['_id', id()],
1296
- before: ['before', joinAt('before')],
1297
- after: ['after', joinAt('after')],
1298
- deleted: [
1299
- 'deleted',
1300
- field({
1301
- before: ['before', isPad('before')],
1302
- after: ['after', isPad('after')],
1303
- }),
1304
- ],
1305
- });
1306
- return $replaceWith_(joinDelta);
1015
+ const doc = root();
1016
+ const id = () => root().of(k2).of("_id").expr();
1017
+ const k1At = (side) => doc.of(k1).of(side).expr();
1018
+ const rowOf = (a, b) => mergeObjects(mergeObjects(field({ _id: ["_id", id()] }), field(map1(k1, a))), field(map1(k2, b)));
1019
+ const rowPad = (k1v, n2) => {
1020
+ return rowOf(k1v, n2.forward(nil));
1021
+ };
1022
+ const rowReal = (k1v, k2v) => rowOf(k1v, k2v);
1023
+ const k2join = (raw, orNull, pad, real) => ite(eqTyped(raw, field({})), pad, andAlso(orNull, real));
1024
+ const joinAt = (side) => {
1025
+ const k2t = () => root().of(k2).of(side).expr();
1026
+ const k2w = () => root().of(k2).of(side).expr();
1027
+ if (!eq1) {
1028
+ const k1t = () => root().of(k1).of(side).expr();
1029
+ return andAlso(k1At(side), k2join(k2t(), k2t(), eq2 ? rowPad(k1t(), eq2) : nil, rowReal(k1t(), k2t())));
1030
+ }
1031
+ const k1v = () => {
1032
+ return $ifNull(root().of(k1).of(side).expr(), eq1.forward(nil));
1033
+ };
1034
+ return k2join(k2w(), k2w(), eq2 ? rowPad(k1v(), eq2) : nil, rowReal(k1v(), k2w()));
1035
+ };
1036
+ const isPad = (side) => ite(eq(doc.of(k2).of(side).expr())(field({})), val(true), doc.of(k1).of("deleted").of(side).expr());
1037
+ const joinDelta = field({
1038
+ _id: ["_id", id()],
1039
+ before: ["before", joinAt("before")],
1040
+ after: ["after", joinAt("after")],
1041
+ deleted: ["deleted", field({
1042
+ before: ["before", isPad("before")],
1043
+ after: ["after", isPad("after")]
1044
+ })]
1045
+ });
1046
+ return $replaceWith_(joinDelta);
1307
1047
  };
1308
1048
  const $unwindDelta = (k1, k2, k, includeNull1, includeNull2) => {
1309
- const stages = (emptyOf, eq1, eq2) => {
1310
- return link()
1311
- .with(slotsMany(k1, k2, k, emptyOf))
1312
- .with($unwind_(k2))
1313
- .with(joinMany(k1, k2, eq1, eq2))
1314
- .with(matchDelta()).stages;
1315
- };
1316
- const run = (emptyOf) => stages(emptyOf, includeNull1 === null && literalsEqaul(), includeNull2 === null && literalsEqaul());
1317
- if (k === k2)
1318
- return run(noEmpty);
1319
- if (includeNull2 === null)
1320
- return run(padEmpty);
1321
- return run(noEmpty);
1049
+ const stages = (emptyOf, eq1, eq2) => {
1050
+ return link().with(slotsMany(k1, k2, k, emptyOf)).with($unwind_(k2)).with(joinMany(k1, k2, eq1, eq2)).with(matchDelta()).stages;
1051
+ };
1052
+ const run = (emptyOf) => stages(emptyOf, includeNull1 === null && literalsEqaul(includeNull1), includeNull2 === null && literalsEqaul(includeNull2));
1053
+ if (k === k2) return run(noEmpty);
1054
+ if (includeNull2 === null) return run(padEmpty);
1055
+ return run(noEmpty);
1322
1056
  };
1323
-
1324
- const $unwind = (k, dict, middle = '.') => {
1325
- const joinK = ['left', middle, 'right'];
1326
- return {
1327
- delta: link()
1328
- .with($replaceWithDelta(field({
1329
- _id: ['_id', root().of('_id').expr()],
1330
- left: ['left', root().expr()],
1331
- right: ['right', root().of(k).expr()],
1332
- })))
1333
- .with($unwindDelta('left', 'right', joinK))
1334
- .with($replaceWithDelta(mergeObjects(root().of('left').expr(), fieldM({
1335
- key: root().of('right').expr(),
1336
- id: root().of('_id').expr(),
1337
- }, dict)))).stages,
1338
- raw: (f) => link()
1339
- .with($unwind1(k)(f))
1340
- .with($set1(set()({
1341
- _id: [
1342
- '_id',
1343
- to(joinIdOf(joinK, 'left', root().of('_id').expr(), root().of(k).of('_id').expr())),
1344
- ],
1345
- }))(f)).stages,
1346
- };
1057
+ //#endregion
1058
+ //#region .build/lib/aggregate/unwind/index.js
1059
+ const $unwind = (k, dict, middle = ".") => {
1060
+ const joinK = [
1061
+ "left",
1062
+ middle,
1063
+ "right"
1064
+ ];
1065
+ return {
1066
+ delta: link().with($replaceWithDelta(field({
1067
+ _id: ["_id", root().of("_id").expr()],
1068
+ left: ["left", root().expr()],
1069
+ right: ["right", root().of(k).expr()]
1070
+ }))).with($unwindDelta("left", "right", joinK)).with($replaceWithDelta(mergeObjects(root().of("left").expr(), fieldM({
1071
+ key: root().of("right").expr(),
1072
+ id: root().of("_id").expr()
1073
+ }, dict)))).stages,
1074
+ raw: (f) => link().with($unwind1(k)(f)).with($set1(set()({ _id: ["_id", to(joinIdOf(joinK, "left", root().of("_id").expr(), root().of(k).of("_id").expr()))] }))(f)).stages
1075
+ };
1347
1076
  };
1348
-
1077
+ //#endregion
1078
+ //#region .build/lib/aggregate/lookup/$lookup-delta.js
1349
1079
  const $lookupDelta = ({ field1, field2 }, { coll, exec, input }, k1, k2, k, includeNull1, includeNull2) => {
1350
- const omit = omitRORec();
1351
- const hash = crypto$1
1352
- .createHash('md5')
1353
- .update(coll.collectionName + jsonCanonicalize.canonicalize(input) + jsonCanonicalize.canonicalize(exec))
1354
- .digest('base64url');
1355
- const normForeignKey = (f) => to($ifNull(root().of(f).of(k1).with(field1).expr(), val(hash)));
1356
- return link()
1357
- .with($replaceWithDelta(field(map1(k1, root().expr()))))
1358
- .with($set_(set()({
1359
- bId: ['bId', normForeignKey('before')],
1360
- aId: ['aId', normForeignKey('after')],
1361
- })))
1362
- .with($simpleLookup_({
1363
- coll,
1364
- k: 'a',
1365
- fields: {
1366
- foreign: root().of('before').with(field2),
1367
- local: root().of('aId'),
1368
- },
1369
- vars: {},
1370
- pipeline: link().with(input).with(exec).stages,
1371
- }))
1372
- .with($simpleLookup_({
1373
- coll,
1374
- k: 'b',
1375
- fields: {
1376
- foreign: root().of('before').with(field2),
1377
- local: root().of('bId'),
1378
- },
1379
- vars: {},
1380
- pipeline: link().with(input).with(exec).stages,
1381
- }))
1382
- .with($replaceWithEach((f) => {
1383
- const joined = (side, arr) => {
1384
- const here = root();
1385
- return ite(eqTyped(root().of(side).expr(), nil), nil, field(omit.backward(mergeExpr(omit.forward(map1(k2, here.of(arr).of('before').expr())), map1(k1, here
1386
- .of(side)
1387
- .of(k1)
1388
- .expr())))));
1389
- };
1390
- return f === 'after' ? joined('after', 'a') : joined('before', 'b');
1391
- }))
1392
- .with(includeNull1 === null
1393
- ? $replaceWithEach1((part) => {
1394
- const otherPart = root().of(part === 'after' ? 'before' : 'after');
1395
- const n1 = literalsEqaul().forward(nil);
1396
- const expr = $ifNull(root().of(part).expr(), field(omit.backward(mergeExpr(omit.forward(map1(k2, otherPart.of(k2).expr())), map1(k1, n1)))));
1397
- return expr;
1398
- })
1399
- : link().stages)
1400
- .with($unwindDelta(k1, k2, k, includeNull1, includeNull2)).stages;
1080
+ const hash = crypto$1.default.createHash("md5").update(coll.collectionName + (0, json_canonicalize.canonicalize)(input) + (0, json_canonicalize.canonicalize)(exec)).digest("base64url");
1081
+ const normForeignKey = (f) => to($ifNull(root().of(f).of(k1).with(field1).expr(), asExpr(val(hash))));
1082
+ return link().with($replaceWithDelta(field(map1(k1, root().expr())))).with($set_(set()({
1083
+ bId: ["bId", normForeignKey("before")],
1084
+ aId: ["aId", normForeignKey("after")]
1085
+ }))).with($simpleLookup_({
1086
+ coll,
1087
+ k: "a",
1088
+ fields: {
1089
+ foreign: root().of("before").with(field2),
1090
+ local: root().of("aId")
1091
+ },
1092
+ vars: {},
1093
+ pipeline: link().with(input).with(exec).stages
1094
+ })).with($simpleLookup_({
1095
+ coll,
1096
+ k: "b",
1097
+ fields: {
1098
+ foreign: root().of("before").with(field2),
1099
+ local: root().of("bId")
1100
+ },
1101
+ vars: {},
1102
+ pipeline: link().with(input).with(exec).stages
1103
+ })).with($replaceWithEach((f) => {
1104
+ const joined = (side, arr) => {
1105
+ const here = root();
1106
+ return ite(eqTyped(root().of(side).expr(), nil), nil, field(mergeExpr(map1(k2, here.of(arr).of("before").expr()), map1(k1, here.of(side).of(k1).expr()))));
1107
+ };
1108
+ return f === "after" ? joined("after", "a") : joined("before", "b");
1109
+ })).with(includeNull1 === null ? $replaceWithEach1((part) => {
1110
+ const otherPart = root().of(part === "after" ? "before" : "after");
1111
+ const n1 = literalsEqaul(includeNull1).forward(nil);
1112
+ return $ifNull(root().of(part).expr(), field(mergeExpr(map1(k2, otherPart.of(k2).expr()), map1(k1, n1))));
1113
+ }) : link().stages).with($unwindDelta(k1, k2, k, includeNull1, includeNull2)).stages;
1401
1114
  };
1402
-
1115
+ //#endregion
1116
+ //#region .build/lib/aggregate/lookup/$lookup-raw.js
1403
1117
  const $lookupRaw = ({ field1, field2 }, { coll, exec, input }, k2, k, includeNull) => (f) => {
1404
- const left = root().of('_id').expr();
1405
- const right = root().of(k2).of('_id').expr();
1406
- const keepLeft = k === 'left';
1407
- const composedId = typeof k === 'string' ? right : concat(left, val(k[1]), right);
1408
- return link()
1409
- .with($simpleLookup1({
1410
- coll,
1411
- k: k2,
1412
- fields: {
1413
- local: field1,
1414
- foreign: root().of('before').with(field2),
1415
- },
1416
- vars: {},
1417
- pipeline: link()
1418
- .with(input)
1419
- .with(exec)
1420
- .with($replaceWith_(root().of('before').expr())).stages,
1421
- })(f))
1422
- .with($unwind1(k2, includeNull)(f))
1423
- .with(keepLeft
1424
- ? link().stages
1425
- : $set1(set()({
1426
- _id: ['_id', to($ifNull(composedId, left))],
1427
- }))(f)).stages;
1118
+ const left = root().of("_id").expr();
1119
+ const right = root().of(k2).of("_id").expr();
1120
+ const keepLeft = k === "left";
1121
+ const composedId = typeof k === "string" ? right : concat(left, val(k[1]), right);
1122
+ return link().with($simpleLookup1({
1123
+ coll,
1124
+ k: k2,
1125
+ fields: {
1126
+ local: field1,
1127
+ foreign: root().of("before").with(field2)
1128
+ },
1129
+ vars: {},
1130
+ pipeline: link().with(input).with(exec).with($replaceWith_(root().of("before").expr())).stages
1131
+ })(f)).with($unwind1(k2, includeNull)(f)).with(keepLeft ? link().stages : $set1(set()({ _id: ["_id", to($ifNull(composedId, left))] }))(f)).stages;
1428
1132
  };
1429
-
1430
- const asBefore = (f) => f(() => root().of('before'));
1431
-
1133
+ //#endregion
1134
+ //#region .build/lib/utils/before.js
1135
+ const asBefore = (f) => f(() => root().of("before"));
1136
+ //#endregion
1137
+ //#region .build/lib/utils/log.js
1432
1138
  const T = (s) => `Timestamp(${parseInt(`${BigInt(s) / 2n ** 32n}`)}, ${parseInt(`${BigInt(s) % 2n ** 32n}`)})`;
1433
1139
  const replace = (s) => s.replace(/\{"\$timestamp":"(\d+)"\}/g, (_, d) => T(d));
1434
1140
  const json = (a) => replace(JSON.stringify(a));
1435
- const log = (...args) => console.log(new Date(), ...args.map(a => (typeof a === 'function' ? a(replace) : a && typeof a === 'object' ? json(a) : a)));
1436
-
1437
- const indexMap = new Map();
1141
+ const log = (...args) => console.log(/* @__PURE__ */ new Date(), ...args.map((a) => typeof a === "function" ? a(replace) : a && typeof a === "object" ? json(a) : a));
1142
+ //#endregion
1143
+ //#region .build/lib/utils/db-indexes.js
1144
+ const indexMap = /* @__PURE__ */ new Map();
1438
1145
  const createIndex = async (collection, indexSpec, op) => {
1439
- const { name, ...options } = op ?? {};
1440
- const map = indexMap.get(collection.collectionName) ?? new Map();
1441
- indexMap.set(collection.collectionName, map);
1442
- const indexKey = `${JSON.stringify(indexSpec)}-${JSON.stringify(options)}`;
1443
- if (map.has(indexKey)) {
1444
- await map.get(indexKey);
1445
- return;
1446
- }
1447
- const promise = createIndexWithRetry(collection, indexSpec, op);
1448
- map.set(indexKey, promise);
1449
- await promise;
1146
+ const { name, ...options } = op ?? {};
1147
+ const map = indexMap.get(collection.collectionName) ?? /* @__PURE__ */ new Map();
1148
+ indexMap.set(collection.collectionName, map);
1149
+ const indexKey = `${JSON.stringify(indexSpec)}-${JSON.stringify(options)}`;
1150
+ if (map.has(indexKey)) {
1151
+ await map.get(indexKey);
1152
+ return;
1153
+ }
1154
+ const promise = createIndexWithRetry(collection, indexSpec, op);
1155
+ map.set(indexKey, promise);
1156
+ await promise;
1450
1157
  };
1451
1158
  const createIndexWithRetry = async (collection, indexSpec, options) => {
1452
- const log = () => { };
1453
- log('Creating index', { collection: collection.collectionName});
1454
- while (true) {
1455
- try {
1456
- await collection.createIndex(indexSpec, options);
1457
- log('Index created', { collection: collection.collectionName, indexSpec, options });
1458
- }
1459
- catch (e) {
1460
- if ([85, 276].includes(e.code)) {
1461
- log('Index created with different name', e.code, {
1462
- collection: collection.collectionName});
1463
- break;
1464
- }
1465
- if (e.code == 12587) {
1466
- await new Promise(res => setTimeout(res, 300));
1467
- continue;
1468
- }
1469
- log('Error creating index', {
1470
- collection: collection.collectionName});
1471
- console.error('Error creating index', e);
1472
- throw e;
1473
- }
1474
- break;
1475
- }
1159
+ collection.collectionName;
1160
+ while (true) {
1161
+ try {
1162
+ await collection.createIndex(indexSpec, options);
1163
+ collection.collectionName;
1164
+ } catch (e) {
1165
+ if ([85, 276].includes(e.code)) {
1166
+ e.code, collection.collectionName;
1167
+ break;
1168
+ }
1169
+ if (e.code == 12587) {
1170
+ await new Promise((res) => setTimeout(res, 300));
1171
+ continue;
1172
+ }
1173
+ collection.collectionName;
1174
+ console.error("Error creating index", e);
1175
+ throw e;
1176
+ }
1177
+ break;
1178
+ }
1476
1179
  };
1477
1180
  const ensureCollection = async (db, collectionName) => {
1478
- if (!(await db.listCollections({ name: collectionName }, { nameOnly: true }).next())) {
1479
- await db.createCollection(collectionName);
1480
- }
1181
+ if (!await db.listCollections({ name: collectionName }, { nameOnly: true }).next()) await db.createCollection(collectionName);
1481
1182
  };
1482
-
1183
+ //#endregion
1184
+ //#region .build/lib/utils/merge/utils.js
1483
1185
  const patch = ({ ...x }, k, v) => {
1484
- delete x[k];
1485
- return { ...x, [k]: v };
1186
+ delete x[k];
1187
+ return {
1188
+ ...x,
1189
+ [k]: v
1190
+ };
1486
1191
  };
1487
1192
  const restart = (sources) => {
1488
- return map(sources, x => x.stop());
1193
+ return map(sources, (x) => x.stop());
1489
1194
  };
1490
1195
  const race = (sources) => {
1491
- const promises = Object.values(map(sources, ({ next }, key) => next.then(frame => ({ key, frame }), error => new Error(error))));
1492
- return Promise.any(promises).then((result) => {
1493
- if (result instanceof Error) {
1494
- throw result;
1495
- }
1496
- else {
1497
- return result;
1498
- }
1499
- });
1196
+ const promises = Object.values(map(sources, ({ next }, key) => next.then((frame) => ({
1197
+ key,
1198
+ frame
1199
+ }), (error) => new Error(error))));
1200
+ return Promise.any(promises).then((result) => {
1201
+ if (result instanceof Error) throw result;
1202
+ else return result;
1203
+ });
1500
1204
  };
1501
-
1205
+ //#endregion
1206
+ //#region .build/lib/utils/merge/next-winner.js
1502
1207
  const nextWinner = (previousWinner, previousWinnerNextFrame, sources, interrupt) => {
1503
- const { frame: previousFrame, key } = previousWinner;
1504
- if (!interrupt?.(key) && previousFrame.info.job) {
1505
- return previousWinnerNextFrame.then((previousFrameSuccessor) => {
1506
- if (previousFrameSuccessor.info.job) {
1507
- return { frame: previousFrameSuccessor, key };
1508
- }
1509
- return race(sources);
1510
- });
1511
- }
1512
- return race(sources);
1208
+ const { frame: previousFrame, key } = previousWinner;
1209
+ if (!interrupt?.(key) && previousFrame.info.job) return previousWinnerNextFrame.then((previousFrameSuccessor) => {
1210
+ if (previousFrameSuccessor.info.job) return {
1211
+ frame: previousFrameSuccessor,
1212
+ key
1213
+ };
1214
+ return race(sources);
1215
+ });
1216
+ return race(sources);
1513
1217
  };
1514
-
1515
- const makeSelect = (winner, nextFrame, interrupt) => sources => nextWinner(winner, nextFrame, sources, interrupt);
1218
+ //#endregion
1219
+ //#region .build/lib/utils/merge/merge.js
1220
+ const makeSelect = (winner, nextFrame, interrupt) => (sources) => nextWinner(winner, nextFrame, sources, interrupt);
1516
1221
  const makeContinuation = (sources, winner, interrupt, hooks) => () => {
1517
- const { frame, key } = winner;
1518
- const result = frame.cont();
1519
- hooks?.start?.(frame, result);
1520
- return mergeIterators({
1521
- sources: patch(sources, key, result),
1522
- interrupt,
1523
- select: makeSelect(winner, result.next, interrupt),
1524
- hooks,
1525
- });
1222
+ const { frame, key } = winner;
1223
+ const result = frame.cont();
1224
+ hooks?.start?.(frame, result);
1225
+ return mergeIterators({
1226
+ sources: patch(sources, key, result),
1227
+ interrupt,
1228
+ select: makeSelect(winner, result.next, interrupt),
1229
+ hooks
1230
+ });
1526
1231
  };
1527
1232
  const makeReiterate = (sources, interrupt, hooks) => (winner) => {
1528
- const { frame, key } = winner;
1529
- return {
1530
- cont: makeContinuation(sources, winner, interrupt, hooks),
1531
- data: frame.data,
1532
- info: { key, value: frame.info, job: frame.info.job },
1533
- };
1233
+ const { frame, key } = winner;
1234
+ return {
1235
+ cont: makeContinuation(sources, winner, interrupt, hooks),
1236
+ data: frame.data,
1237
+ info: {
1238
+ key,
1239
+ value: frame.info,
1240
+ job: frame.info.job
1241
+ }
1242
+ };
1534
1243
  };
1535
1244
  const mergeIterators = (params) => {
1536
- const { sources, interrupt, select = race, hooks } = params;
1537
- return {
1538
- stop: () => mergeIterators({ sources: restart(sources), interrupt, select, hooks }),
1539
- next: select(sources).then(makeReiterate(sources, interrupt, hooks)),
1540
- clear: async () => {
1541
- for (const key in sources) {
1542
- await sources[key].clear();
1543
- }
1544
- },
1545
- };
1245
+ const { sources, interrupt, select = race, hooks } = params;
1246
+ return {
1247
+ stop: () => mergeIterators({
1248
+ sources: restart(sources),
1249
+ interrupt,
1250
+ select,
1251
+ hooks
1252
+ }),
1253
+ next: select(sources).then(makeReiterate(sources, interrupt, hooks)),
1254
+ clear: async () => {
1255
+ for (const key in sources) await sources[key].clear();
1256
+ }
1257
+ };
1546
1258
  };
1547
-
1259
+ //#endregion
1260
+ //#region .build/lib/utils/merge/combiners.js
1548
1261
  const state = { steady: false };
1549
1262
  let timeout = null;
1550
1263
  const firstWorksMerge = (iters) => {
1551
- const iterator = () => {
1552
- const results = iters.map(iter => iter());
1553
- const sources = { ...results };
1554
- return mergeIterators({
1555
- sources,
1556
- interrupt: key => false,
1557
- hooks: {
1558
- start: (frame, result) => {
1559
- if (!frame.info.job)
1560
- return;
1561
- if (timeout !== null) {
1562
- clearTimeout(timeout);
1563
- timeout = null;
1564
- }
1565
- result.next.then(() => {
1566
- if (!frame.info.job)
1567
- return;
1568
- if (!state.steady) {
1569
- if (timeout !== null)
1570
- clearTimeout(timeout);
1571
- timeout = setTimeout(() => {
1572
- state.steady = true;
1573
- console.log('steady');
1574
- }, 2000);
1575
- }
1576
- });
1577
- },
1578
- },
1579
- });
1580
- };
1581
- return iterator;
1264
+ const iterator = () => {
1265
+ const results = iters.map((iter) => iter());
1266
+ const sources = Object.fromEntries(results.map((result, index) => [String(index), result]));
1267
+ return mergeIterators({
1268
+ sources,
1269
+ interrupt: (key) => false,
1270
+ hooks: { start: (frame, result) => {
1271
+ if (!frame.info.job) return;
1272
+ if (timeout !== null) {
1273
+ clearTimeout(timeout);
1274
+ timeout = null;
1275
+ }
1276
+ result.next.then(() => {
1277
+ if (!frame.info.job) return;
1278
+ if (!state.steady) {
1279
+ if (timeout !== null) clearTimeout(timeout);
1280
+ timeout = setTimeout(() => {
1281
+ state.steady = true;
1282
+ console.log("steady");
1283
+ }, 2e3);
1284
+ }
1285
+ });
1286
+ } }
1287
+ });
1288
+ };
1289
+ return iterator;
1290
+ };
1291
+ //#endregion
1292
+ //#region .build/lib/machine.js
1293
+ var Machine = class {
1294
+ sources;
1295
+ constructor(root) {
1296
+ this.sources = root ? [root] : [];
1297
+ }
1298
+ add(x) {
1299
+ this.sources.push(x);
1300
+ }
1301
+ runner() {
1302
+ const items = this.sources.filter((x) => x);
1303
+ if (items.length === 1) return items[0];
1304
+ return firstWorksMerge(items);
1305
+ }
1306
+ start(cb) {
1307
+ const run = this.runner();
1308
+ return runCont(run, cb);
1309
+ }
1582
1310
  };
1583
-
1584
- class Machine {
1585
- sources;
1586
- constructor(root) {
1587
- this.sources = root ? [root] : [];
1588
- }
1589
- add(x) {
1590
- this.sources.push(x);
1591
- }
1592
- runner() {
1593
- const items = this.sources.filter(x => x);
1594
- if (items.length === 1) {
1595
- return items[0];
1596
- }
1597
- return firstWorksMerge(items);
1598
- }
1599
- start(cb) {
1600
- const run = this.runner();
1601
- return runCont(run, cb);
1602
- }
1603
- }
1604
1311
  const wrap = (root) => root;
1605
1312
  const runCont = async (it, cb) => {
1606
- while (true) {
1607
- const { next, stop: _, clear } = it();
1608
- const res = await next.then(next => ({ ok: true, next }), err => ({ ok: false, err }));
1609
- if (!res.ok) {
1610
- console.error(res.err);
1611
- process.exit(1);
1612
- }
1613
- const { cont, info } = res.next;
1614
- if (cb?.(info)) {
1615
- await clear();
1616
- throw new Error('Machine stopped');
1617
- }
1618
- it = cont;
1619
- }
1313
+ while (true) {
1314
+ const { next, stop: _, clear } = it();
1315
+ const res = await next.then((next) => ({
1316
+ ok: true,
1317
+ next
1318
+ }), (err) => ({
1319
+ ok: false,
1320
+ err
1321
+ }));
1322
+ if (!res.ok) {
1323
+ console.error(res.err);
1324
+ process.exit(1);
1325
+ }
1326
+ const { cont, info } = res.next;
1327
+ if (cb?.(info)) {
1328
+ await clear();
1329
+ throw new Error("Machine stopped");
1330
+ }
1331
+ it = cont;
1332
+ }
1620
1333
  };
1621
-
1622
- const merge = ({ lsource: L, rsource: R, }) => mergeIterators({ sources: { L, R } });
1334
+ //#endregion
1335
+ //#region .build/lib/aggregate/lookup/index.js
1336
+ const merge = ({ lsource: L, rsource: R }) => mergeIterators({ sources: {
1337
+ L,
1338
+ R
1339
+ } });
1623
1340
  const join = (params, leftSnapshot, rightSnapshot, stagesUntilNextLookup, outerLeft) => {
1624
- const { lField, rField, left, right, as } = params;
1625
- const rightJoinField = { field1: lField, field2: rField };
1626
- const joinId = params.to === 'one' ? 'left' : ['left', params.middle, 'right'];
1627
- const joinR_Snapshot = asBefore($lookupRaw(rightJoinField, rightSnapshot, as, joinId, outerLeft));
1628
- const resultingSnapshot = concatTStages(leftSnapshot, joinR_Snapshot);
1629
- const dict = { [as]: 'a' };
1630
- const idB = { _id: 'b' };
1631
- const dictId = { ...dict, ...idB };
1632
- return {
1633
- stages: consume => consume(concatTStages(resultingSnapshot, asBefore(stagesUntilNextLookup.raw))),
1634
- out: (finalInput) => {
1635
- const leftJoinField = { field1: rField, field2: lField };
1636
- const joinL_Delta = $lookupDelta(leftJoinField, leftSnapshot, 'right', 'left', joinId, outerLeft);
1637
- const joinR_Delta = $lookupDelta(rightJoinField, rightSnapshot, 'left', 'right', joinId, undefined, outerLeft);
1638
- const mergeForeignIntoDoc = concatStages($replaceWithDelta(mergeObjects(root().of('left').expr(), fieldM({
1639
- a: root().of('right').expr(),
1640
- b: root().of('_id').expr(),
1641
- }, dictId))), stagesUntilNextLookup.delta);
1642
- const lRunnerInput = concatStages(joinR_Delta, mergeForeignIntoDoc);
1643
- const rRunnerInput = concatStages(joinL_Delta, mergeForeignIntoDoc);
1644
- const getRunner = (f, stages, final) => f.out({
1645
- raw: first => concatStages(stages, final.raw(first)),
1646
- teardown: final.teardown,
1647
- }, async () => {
1648
- log('Creating indexes for lookup left', leftSnapshot.coll.collectionName, {
1649
- [`before.${lField.str()}`]: 1,
1650
- });
1651
- await createIndex(leftSnapshot.coll, { [`before.${lField.str()}`]: 1 }, { name: 'left_' + new mongodb.UUID().toString('base64') });
1652
- log('Creating indexes for lookup right', rightSnapshot.coll.collectionName, {
1653
- [`before.${rField.str()}`]: 1,
1654
- });
1655
- await createIndex(rightSnapshot.coll, { [`before.${rField.str()}`]: 1 }, { name: 'right_' + new mongodb.UUID().toString('base64') });
1656
- });
1657
- const lRunner = getRunner(left, lRunnerInput, finalInput);
1658
- const rRunner = getRunner(right, rRunnerInput, finalInput);
1659
- return () => merge({ lsource: lRunner(), rsource: rRunner() });
1660
- },
1661
- };
1341
+ const { lField, rField, left, right, as } = params;
1342
+ const rightJoinField = {
1343
+ field1: lField,
1344
+ field2: rField
1345
+ };
1346
+ const joinId = params.to === "one" ? "left" : [
1347
+ "left",
1348
+ params.middle,
1349
+ "right"
1350
+ ];
1351
+ const joinR_Snapshot = asBefore($lookupRaw(rightJoinField, rightSnapshot, as, joinId, outerLeft));
1352
+ const resultingSnapshot = concatTStages(leftSnapshot, joinR_Snapshot);
1353
+ const dict = { [as]: "a" };
1354
+ const idB = { _id: "b" };
1355
+ const dictId = {
1356
+ ...dict,
1357
+ ...idB
1358
+ };
1359
+ return {
1360
+ stages: (consume) => consume(concatTStages(resultingSnapshot, asBefore(stagesUntilNextLookup.raw))),
1361
+ out: (finalInput) => {
1362
+ const joinL_Delta = $lookupDelta({
1363
+ field1: rField,
1364
+ field2: lField
1365
+ }, leftSnapshot, "right", "left", joinId, outerLeft);
1366
+ const joinR_Delta = $lookupDelta(rightJoinField, rightSnapshot, "left", "right", joinId, void 0, outerLeft);
1367
+ const mergeForeignIntoDoc = concatStages($replaceWithDelta(mergeObjects(root().of("left").expr(), fieldM({
1368
+ a: root().of("right").expr(),
1369
+ b: root().of("_id").expr()
1370
+ }, dictId))), stagesUntilNextLookup.delta);
1371
+ const lRunnerInput = concatStages(joinR_Delta, mergeForeignIntoDoc);
1372
+ const rRunnerInput = concatStages(joinL_Delta, mergeForeignIntoDoc);
1373
+ const getRunner = (f, stages, final) => f.out({
1374
+ raw: (first) => concatStages(stages, final.raw(first)),
1375
+ teardown: final.teardown
1376
+ }, async () => {
1377
+ log("Creating indexes for lookup left", leftSnapshot.coll.collectionName, { [`before.${lField.str()}`]: 1 });
1378
+ await createIndex(leftSnapshot.coll, { [`before.${lField.str()}`]: 1 }, { name: "left_" + new types_exports.UUID().toString("base64") });
1379
+ log("Creating indexes for lookup right", rightSnapshot.coll.collectionName, { [`before.${rField.str()}`]: 1 });
1380
+ await createIndex(rightSnapshot.coll, { [`before.${rField.str()}`]: 1 }, { name: "right_" + new types_exports.UUID().toString("base64") });
1381
+ });
1382
+ const lRunner = getRunner(left, lRunnerInput, finalInput);
1383
+ const rRunner = getRunner(right, rRunnerInput, finalInput);
1384
+ return () => merge({
1385
+ lsource: lRunner(),
1386
+ rsource: rRunner()
1387
+ });
1388
+ }
1389
+ };
1662
1390
  };
1663
1391
  const $lookup1 = (p, outerLeft) => (input) => p.left.stages((lStages) => p.right.stages((rStages) => join(p, lStages, rStages, input, outerLeft)));
1664
- const $lookup = (p) => (l) => p.to === 'one'
1665
- ? $lookup1({
1666
- right: p.from,
1667
- as: p.as,
1668
- lField: p.localField,
1669
- rField: root().of('_id'),
1670
- left: l(emptyDelta()),
1671
- to: 'one',
1672
- })
1673
- : $lookup1({
1674
- to: 'many',
1675
- right: p.from,
1676
- as: p.as,
1677
- lField: p.localField,
1678
- rField: p.foreignField,
1679
- left: l(emptyDelta()),
1680
- middle: p.middle,
1681
- });
1682
- const $outerLookup = (p) => (l) => p.to === 'one'
1683
- ? $lookup1({
1684
- right: p.from,
1685
- as: p.as,
1686
- lField: p.localField,
1687
- rField: root().of('_id'),
1688
- left: l(emptyDelta()),
1689
- to: 'one',
1690
- }, null)
1691
- : $lookup1({
1692
- to: 'many',
1693
- right: p.from,
1694
- as: p.as,
1695
- lField: p.localField,
1696
- rField: p.foreignField,
1697
- left: l(emptyDelta()),
1698
- middle: p.middle,
1699
- }, null);
1700
-
1392
+ const $lookup = (p) => (l) => p.to === "one" ? $lookup1({
1393
+ right: p.from,
1394
+ as: p.as,
1395
+ lField: p.localField,
1396
+ rField: root().of("_id"),
1397
+ left: l(emptyDelta()),
1398
+ to: "one"
1399
+ }) : $lookup1({
1400
+ to: "many",
1401
+ right: p.from,
1402
+ as: p.as,
1403
+ lField: p.localField,
1404
+ rField: p.foreignField,
1405
+ left: l(emptyDelta()),
1406
+ middle: p.middle
1407
+ });
1408
+ const $outerLookup = (p) => (l) => p.to === "one" ? $lookup1({
1409
+ right: p.from,
1410
+ as: p.as,
1411
+ lField: p.localField,
1412
+ rField: root().of("_id"),
1413
+ left: l(emptyDelta()),
1414
+ to: "one"
1415
+ }, null) : $lookup1({
1416
+ to: "many",
1417
+ right: p.from,
1418
+ as: p.as,
1419
+ lField: p.localField,
1420
+ rField: p.foreignField,
1421
+ left: l(emptyDelta()),
1422
+ middle: p.middle
1423
+ }, null);
1424
+ //#endregion
1425
+ //#region .build/lib/aggregate/set/$set.js
1701
1426
  const $setCore = (updater) => ({
1702
- delta: $setDelta(updater),
1703
- raw: $set1(updater),
1704
- lin: $set_(updater),
1427
+ delta: $setDelta(updater),
1428
+ raw: $set1(updater),
1429
+ lin: $set_(updater)
1705
1430
  });
1706
1431
  const $set = () => (fields) => $setCore(setQ()(fields));
1707
1432
  const $replaceWith = (expr) => ({
1708
- delta: $replaceWithDelta(expr),
1709
- raw: $replaceWith1(expr),
1710
- lin: $replaceWith_(expr),
1711
- });
1712
-
1713
- const $insertX = (out, expr, map, ext, extExpr, update = x => x) => {
1714
- const filter = mapExactToObject(ext, v => ({ $eq: v }));
1715
- const sameSubset = getSubsetMatchForExt(ext);
1716
- return {
1717
- teardown: c => c({
1718
- collection: out,
1719
- method: 'updateMany',
1720
- params: [
1721
- filter,
1722
- [{ $set: { deletedAt: '$$NOW', touchedAt: '$$CLUSTER_TIME' } }],
1723
- ],
1724
- }),
1725
- raw: () => {
1726
- const replacer = map(mergeObjects(expr, field(mergeExpr(extExpr, {
1727
- deletedAt: ['deletedAt', nil],
1728
- touchedAt: ['touchedAt', current],
1729
- }))));
1730
- return link()
1731
- .with($replaceWith_(replacer))
1732
- .with($merge_({
1733
- into: out,
1734
- on: root().of('_id'),
1735
- stages: true,
1736
- whenMatched: getWhenMatchedForMerge('insert', update, sameSubset),
1737
- whenNotMatched: 'insert',
1738
- })).stages;
1739
- },
1740
- };
1433
+ delta: $replaceWithDelta(expr),
1434
+ raw: $replaceWith1(expr),
1435
+ lin: $replaceWith_(expr)
1436
+ });
1437
+ //#endregion
1438
+ //#region .build/lib/aggregate/$upsert.js
1439
+ const $insertX = (out, expr, map, ext, extExpr, update = (x) => x) => {
1440
+ const filter = mapExactToObject(ext, (v) => ({ $eq: v }));
1441
+ const sameSubset = getSubsetMatchForExt(ext);
1442
+ return {
1443
+ teardown: (c) => c({
1444
+ collection: out,
1445
+ method: "updateMany",
1446
+ params: [filter, [{ $set: {
1447
+ deletedAt: "$$NOW",
1448
+ touchedAt: "$$CLUSTER_TIME"
1449
+ } }]]
1450
+ }),
1451
+ raw: () => {
1452
+ const replacer = map(mergeObjects(expr, field(mergeExpr(extExpr, {
1453
+ deletedAt: ["deletedAt", nil],
1454
+ touchedAt: ["touchedAt", current]
1455
+ }))));
1456
+ return link().with($replaceWith_(replacer)).with($merge_({
1457
+ into: out,
1458
+ on: root().of("_id"),
1459
+ stages: true,
1460
+ whenMatched: getWhenMatchedForMerge("insert", update, sameSubset),
1461
+ whenNotMatched: "insert"
1462
+ })).stages;
1463
+ }
1464
+ };
1741
1465
  };
1742
1466
  const $simpleInsert = (out, ext) => {
1743
- const extExpr = mapExact(ext, (v) => val(v));
1744
- return $insertX(out, root().expr(), id$1, ext, extExpr);
1467
+ const extExpr = mapExact(ext, (v) => val(v));
1468
+ return $insertX(out, root().expr(), id$1, ext, extExpr);
1745
1469
  };
1746
1470
  const $insertPart = (out, ext) => {
1747
- const extExpr = mapExact(ext, (v) => val(v));
1748
- return $insertX(out, assertNotNull(root().of('after').expr()), x => ite(eq(root().of('after').expr())(nil), field(mergeExpr(translateOmit().forward(extExpr), {
1749
- deletedAt: ['deletedAt', current],
1750
- _id: [
1751
- '_id',
1752
- assertNotNull(root().of('before').of('_id').expr()),
1753
- ],
1754
- touchedAt: ['touchedAt', current],
1755
- })), x), ext, extExpr);
1471
+ const extExpr = mapExact(ext, (v) => val(v));
1472
+ return $insertX(out, assertNotNull(root().of("after").expr()), (x) => ite(eq(root().of("after").expr())(nil), field(mergeExpr(extExpr, {
1473
+ deletedAt: ["deletedAt", current],
1474
+ _id: ["_id", assertNotNull(root().of("before").of("_id").expr())],
1475
+ touchedAt: ["touchedAt", current]
1476
+ })), x), ext, extExpr);
1756
1477
  };
1757
1478
  const $insert = (out) => $insertPart(out, {});
1758
1479
  const assertNotNull = (expr) => expr;
1759
-
1480
+ //#endregion
1481
+ //#region .build/lib/stream/aggregate.js
1760
1482
  const aggregate = (db, streamName, input, snapshot = true, start = Date.now()) => input(({ coll, input }) => {
1761
- const req = {
1762
- aggregate: coll.collectionName,
1763
- pipeline: input,
1764
- cursor: {},
1765
- ...(snapshot && { readConcern: { level: 'snapshot' } }),
1766
- };
1767
- log('exec', streamName, req);
1768
- const start2 = Date.now();
1769
- return db.command(req)
1770
- .then(result => {
1771
- log('prepare', streamName, Date.now() - start);
1772
- log('prepare2', streamName, start2 - start);
1773
- const r = result;
1774
- log('execed', streamName, (replace) => replace(JSON.stringify(req).replaceAll('"$$CLUSTER_TIME"', JSON.stringify(r.cursor.atClusterTime))), result, 'took', Date.now() - start);
1775
- return r;
1776
- }, async (err) => {
1777
- log('err', req, err);
1778
- console.error(err);
1779
- await new Promise(() => { });
1780
- throw new Error(err);
1781
- });
1782
- });
1783
-
1483
+ const req = {
1484
+ aggregate: coll.collectionName,
1485
+ pipeline: input,
1486
+ cursor: {},
1487
+ ...snapshot && { readConcern: { level: "snapshot" } }
1488
+ };
1489
+ log("exec", streamName, req);
1490
+ const start2 = Date.now();
1491
+ return db.command(req).then((result) => {
1492
+ log("prepare", streamName, Date.now() - start);
1493
+ log("prepare2", streamName, start2 - start);
1494
+ const r = result;
1495
+ log("execed", streamName, (replace) => replace(JSON.stringify(req).replaceAll("\"$$CLUSTER_TIME\"", JSON.stringify(r.cursor.atClusterTime))), result, "took", Date.now() - start);
1496
+ return r;
1497
+ }, async (err) => {
1498
+ log("err", req, err);
1499
+ console.error(err);
1500
+ await new Promise(() => {});
1501
+ throw new Error(err);
1502
+ });
1503
+ });
1504
+ //#endregion
1505
+ //#region .build/lib/utils/tear-down.js
1784
1506
  const addTeardown = (it, tr) => {
1785
- if (!tr)
1786
- return it;
1787
- return () => {
1788
- const { next, stop, clear } = it();
1789
- const n = next;
1790
- return {
1791
- next: n.then(({ cont, ...res }) => ({ cont: addTeardown(cont, tr), ...res })),
1792
- stop: () => (tr(), stop()),
1793
- clear: async () => {
1794
- await tr();
1795
- await clear();
1796
- },
1797
- };
1798
- };
1507
+ if (!tr) return it;
1508
+ return () => {
1509
+ const { next, stop, clear } = it();
1510
+ return {
1511
+ next: next.then(({ cont, ...res }) => ({
1512
+ cont: addTeardown(cont, tr),
1513
+ ...res
1514
+ })),
1515
+ stop: () => (tr(), stop()),
1516
+ clear: async () => {
1517
+ await tr();
1518
+ await clear();
1519
+ }
1520
+ };
1521
+ };
1799
1522
  };
1800
-
1801
- const sleep = (ms) => new Promise(r => setTimeout(r, ms));
1802
- const maxTimestamp = new mongodb.Timestamp(0xffffffffffffffffn);
1523
+ //#endregion
1524
+ //#region .build/lib/watch.js
1525
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
1526
+ const maxTimestamp = new mongodb.Timestamp(18446744073709551615n);
1803
1527
  const getCurrentTimestamp = async (db) => {
1804
- const adminDb = db.admin();
1805
- const serverStatus = await adminDb.command({ serverStatus: 1 });
1806
- return serverStatus['operationTime'];
1528
+ return (await db.admin().command({ serverStatus: 1 }))["operationTime"];
1807
1529
  };
1808
1530
  async function getLastCommittedTs(adminDb) {
1809
- const st = await adminDb.command({ replSetGetStatus: 1 });
1810
- return st?.optimes?.lastCommittedOpTime?.ts ?? null;
1531
+ return (await adminDb.command({ replSetGetStatus: 1 }))?.optimes?.lastCommittedOpTime?.ts ?? null;
1811
1532
  }
1812
- async function waitUntilStablePast(db, oplogTs, { pollMs = 0, timeoutMs = 10_000 } = {}) {
1813
- const adminDb = db.client.db('admin');
1814
- const deadline = Date.now() + timeoutMs;
1815
- while (true) {
1816
- const stable = await getLastCommittedTs(adminDb);
1817
- if (stable && stable.comp(oplogTs) >= 0)
1818
- return;
1819
- if (Date.now() > deadline) {
1820
- throw new Error('Timed out waiting for stable timestamp to reach oplog event time');
1821
- }
1822
- await sleep(pollMs);
1823
- }
1533
+ async function waitUntilStablePast(db, oplogTs, { pollMs = 0, timeoutMs = 1e4 } = {}) {
1534
+ const adminDb = db.client.db("admin");
1535
+ const deadline = Date.now() + timeoutMs;
1536
+ while (true) {
1537
+ const stable = await getLastCommittedTs(adminDb);
1538
+ if (stable && stable.comp(oplogTs) >= 0) return;
1539
+ if (Date.now() > deadline) throw new Error("Timed out waiting for stable timestamp to reach oplog event time");
1540
+ await sleep(pollMs);
1541
+ }
1824
1542
  }
1825
1543
  async function* tailOplog(db) {
1826
- let lastTs = await getCurrentTimestamp(db);
1827
- const reopenDelayMs = 250;
1828
- const coll = db.client.db('local').collection('oplog.rs');
1829
- while (true) {
1830
- const cursor = coll.find({
1831
- ts: { $gt: lastTs },
1832
- $or: [
1833
- {
1834
- ns: RegExp(`^${db.namespace}\\.(?!tmp_)(?!__).*(?<!_snapshot)$`),
1835
- op: { $in: ['i', 'u'] },
1836
- },
1837
- {
1838
- ns: 'admin.$cmd',
1839
- op: 'c',
1840
- 'o.applyOps': {
1841
- $elemMatch: {
1842
- ns: RegExp(`^${db.namespace}\\.(?!tmp_)(?!__).*(?<!_snapshot)$`),
1843
- op: { $in: ['i', 'u'] },
1844
- },
1845
- },
1846
- },
1847
- ],
1848
- }, {
1849
- tailable: true,
1850
- awaitData: true,
1851
- noCursorTimeout: true,
1852
- });
1853
- try {
1854
- for await (const docs of cursor) {
1855
- for (const doc of docs.op === 'c' ? docs.o['applyOps'] : [docs]) {
1856
- doc.ts = docs.ts;
1857
- if (doc.op === 'i' || '_id' in doc.o) {
1858
- const fields = new Set(Object.keys(doc.o));
1859
- fields.delete('_id');
1860
- yield { fields, doc };
1861
- }
1862
- else {
1863
- if (doc.o['$v'] !== 2) {
1864
- throw new Error(`Expected update with $v: 2, got ${JSON.stringify(doc)}`);
1865
- }
1866
- const updatedFields = [];
1867
- const diff = doc.o['diff'];
1868
- for (const updateOp in diff) {
1869
- if (['u', 'i', 'd'].includes(updateOp)) {
1870
- updatedFields.push(...Object.keys(diff[updateOp]));
1871
- }
1872
- else if (updateOp.startsWith('s')) {
1873
- updatedFields.push(updateOp.slice(1));
1874
- }
1875
- }
1876
- yield { fields: new Set(updatedFields), doc };
1877
- }
1878
- }
1879
- }
1880
- }
1881
- catch (e) {
1882
- log('oplog loop error, notifying watchers and reopening');
1883
- console.error(e);
1884
- lastTs = await getCurrentTimestamp(db);
1885
- yield null;
1886
- }
1887
- finally {
1888
- log('oplog loop ended');
1889
- await cursor.close().catch(() => { });
1890
- }
1891
- await sleep(reopenDelayMs);
1892
- }
1544
+ let lastTs = await getCurrentTimestamp(db);
1545
+ const reopenDelayMs = 250;
1546
+ const coll = db.client.db("local").collection("oplog.rs");
1547
+ while (true) {
1548
+ const cursor = coll.find({
1549
+ ts: { $gt: lastTs },
1550
+ $or: [{
1551
+ ns: RegExp(`^${db.namespace}\\.(?!tmp_)(?!__).*(?<!_snapshot)$`),
1552
+ op: { $in: ["i", "u"] }
1553
+ }, {
1554
+ ns: "admin.$cmd",
1555
+ op: "c",
1556
+ "o.applyOps": { $elemMatch: {
1557
+ ns: RegExp(`^${db.namespace}\\.(?!tmp_)(?!__).*(?<!_snapshot)$`),
1558
+ op: { $in: ["i", "u"] }
1559
+ } }
1560
+ }]
1561
+ }, {
1562
+ tailable: true,
1563
+ awaitData: true,
1564
+ noCursorTimeout: true
1565
+ });
1566
+ try {
1567
+ for await (const docs of cursor) for (const doc of docs.op === "c" ? docs.o["applyOps"] : [docs]) {
1568
+ doc.ts = docs.ts;
1569
+ if (doc.op === "i" || "_id" in doc.o) {
1570
+ const fields = new Set(Object.keys(doc.o));
1571
+ fields.delete("_id");
1572
+ yield {
1573
+ fields,
1574
+ doc
1575
+ };
1576
+ } else {
1577
+ if (doc.o["$v"] !== 2) throw new Error(`Expected update with $v: 2, got ${JSON.stringify(doc)}`);
1578
+ const updatedFields = [];
1579
+ const diff = doc.o["diff"];
1580
+ for (const updateOp in diff) if ([
1581
+ "u",
1582
+ "i",
1583
+ "d"
1584
+ ].includes(updateOp)) updatedFields.push(...Object.keys(diff[updateOp]));
1585
+ else if (updateOp.startsWith("s")) updatedFields.push(updateOp.slice(1));
1586
+ yield {
1587
+ fields: new Set(updatedFields),
1588
+ doc
1589
+ };
1590
+ }
1591
+ }
1592
+ } catch (e) {
1593
+ log("oplog loop error, notifying watchers and reopening");
1594
+ console.error(e);
1595
+ lastTs = await getCurrentTimestamp(db);
1596
+ yield null;
1597
+ } finally {
1598
+ log("oplog loop ended");
1599
+ await cursor.close().catch(() => {});
1600
+ }
1601
+ await sleep(reopenDelayMs);
1602
+ }
1893
1603
  }
1894
- const watchers = new Map();
1604
+ const watchers = /* @__PURE__ */ new Map();
1895
1605
  let running = false;
1896
1606
  const makePromise = () => {
1897
- let resolve = () => { };
1898
- let promise = new Promise(r => (resolve = r));
1899
- return { promise, resolve };
1607
+ let resolve = () => {};
1608
+ return {
1609
+ promise: new Promise((r) => resolve = r),
1610
+ resolve
1611
+ };
1900
1612
  };
1901
1613
  const loop = async (db) => {
1902
- log('starting oplog loop');
1903
- let notify = makePromise();
1904
- let batch = [];
1905
- const run = async () => {
1906
- for await (const event of tailOplog(db)) {
1907
- if (event?.fields.size === 0)
1908
- continue;
1909
- batch = event && batch ? [...batch, event] : null;
1910
- notify.resolve();
1911
- }
1912
- };
1913
- run();
1914
- const iter = async function* () {
1915
- while (true) {
1916
- await notify.promise;
1917
- const b = batch;
1918
- batch = [];
1919
- notify = makePromise();
1920
- yield b;
1921
- }
1922
- };
1923
- for await (const events of iter()) {
1924
- if (!events) {
1925
- log('notifying watchers of oplog loop restart');
1926
- for (const m of watchers.values()) {
1927
- for (const { cb } of [...m.values()]) {
1928
- cb(null);
1929
- }
1930
- }
1931
- continue;
1932
- }
1933
- for (const { fields, doc } of events) {
1934
- const m = watchers.get(doc.ns);
1935
- if (!m)
1936
- continue;
1937
- for (const { cb, keys, rem, match } of [...m.values()]) {
1938
- if (!keys || (doc.op === 'i' ? (match ? true : true) : keys.some(k => fields.has(k)))) {
1939
- cb(doc);
1940
- rem();
1941
- }
1942
- }
1943
- }
1944
- }
1614
+ log("starting oplog loop");
1615
+ let notify = makePromise();
1616
+ let batch = [];
1617
+ const run = async () => {
1618
+ for await (const event of tailOplog(db)) {
1619
+ if (event?.fields.size === 0) continue;
1620
+ batch = event && batch ? [...batch, event] : null;
1621
+ notify.resolve();
1622
+ }
1623
+ };
1624
+ run();
1625
+ const iter = async function* () {
1626
+ while (true) {
1627
+ await notify.promise;
1628
+ const b = batch;
1629
+ batch = [];
1630
+ notify = makePromise();
1631
+ yield b;
1632
+ }
1633
+ };
1634
+ for await (const events of iter()) {
1635
+ if (!events) {
1636
+ log("notifying watchers of oplog loop restart");
1637
+ for (const m of watchers.values()) for (const { cb } of [...m.values()]) cb(null);
1638
+ continue;
1639
+ }
1640
+ for (const { fields, doc } of events) {
1641
+ const m = watchers.get(doc.ns);
1642
+ if (!m) continue;
1643
+ for (const { cb, keys, rem, match } of [...m.values()]) if (!keys || (doc.op === "i" ? match ? true : true : keys.some((k) => fields.has(k)))) {
1644
+ cb(doc);
1645
+ rem();
1646
+ }
1647
+ }
1648
+ }
1945
1649
  };
1946
1650
  const register = (coll, keys, match, cb) => {
1947
- const ns = coll.namespace;
1948
- let m = watchers.get(ns);
1949
- if (!m)
1950
- watchers.set(ns, (m = new Map()));
1951
- const id = crypto.randomUUID();
1952
- const rem = () => {
1953
- m.delete(id);
1954
- if (m.size === 0)
1955
- watchers.delete(ns);
1956
- };
1957
- m.set(id, { cb, keys, match, rem });
1958
- if (!running) {
1959
- running = true;
1960
- loop(coll.s.db);
1961
- }
1962
- return rem;
1651
+ const ns = coll.namespace;
1652
+ let m = watchers.get(ns);
1653
+ if (!m) watchers.set(ns, m = /* @__PURE__ */ new Map());
1654
+ const id = crypto.randomUUID();
1655
+ const rem = () => {
1656
+ m.delete(id);
1657
+ if (m.size === 0) watchers.delete(ns);
1658
+ };
1659
+ m.set(id, {
1660
+ cb,
1661
+ keys,
1662
+ match,
1663
+ rem
1664
+ });
1665
+ if (!running) {
1666
+ running = true;
1667
+ loop(coll.s.db);
1668
+ }
1669
+ return rem;
1963
1670
  };
1964
1671
  let maxKeysRemoved = null;
1965
1672
  const makeWatchStream = async ({ collection, projection: p, hardMatch: m }, streamName) => {
1966
- const { db } = collection.s;
1967
- await (maxKeysRemoved ??= Promise.all((await db.listCollections({}, { nameOnly: true }).toArray()).map(x => void db
1968
- .collection(x.name)
1969
- .updateMany({ touchedAt: maxTimestamp }, [{ $set: { touchedAt: '$$CLUSTER_TIME' } }]))).then(() => { }));
1970
- const projection = { ...(p ? mapExactToObject(p, v => v) : {}), deletedAt: 1 };
1971
- let notify = makePromise();
1972
- register(collection, p ? Object.keys(projection) : null, m, doc => {
1973
- log(streamName, 'change detected', doc);
1974
- notify.resolve(doc);
1975
- });
1976
- return {
1977
- tryNext: async () => {
1978
- const doc = await notify.promise;
1979
- const start = Date.now();
1980
- if (doc)
1981
- await waitUntilStablePast(collection.s.db, doc.ts);
1982
- log(streamName, 'stable past took', Date.now() - start);
1983
- return doc ?? {};
1984
- },
1985
- close: async () => { },
1986
- };
1673
+ const { db } = collection.s;
1674
+ await (maxKeysRemoved ??= Promise.all((await db.listCollections({}, { nameOnly: true }).toArray()).map((x) => void db.collection(x.name).updateMany({ touchedAt: maxTimestamp }, [{ $set: { touchedAt: "$$CLUSTER_TIME" } }]))).then(() => {}));
1675
+ const projection = {
1676
+ ...p ? mapExactToObject(p, (v) => v) : {},
1677
+ deletedAt: 1
1678
+ };
1679
+ let notify = makePromise();
1680
+ register(collection, p ? Object.keys(projection) : null, m, (doc) => {
1681
+ log(streamName, "change detected", doc);
1682
+ notify.resolve(doc);
1683
+ });
1684
+ return {
1685
+ tryNext: async () => {
1686
+ const doc = await notify.promise;
1687
+ const start = Date.now();
1688
+ if (doc) await waitUntilStablePast(collection.s.db, doc.ts);
1689
+ log(streamName, "stable past took", Date.now() - start);
1690
+ return doc ?? {};
1691
+ },
1692
+ close: async () => {}
1693
+ };
1987
1694
  };
1988
-
1695
+ //#endregion
1696
+ //#region .build/lib/boot/boot-utils.js
1989
1697
  const actions = {
1990
- updateMany: (c, args) => [
1991
- c.updateMany(...args),
1992
- [`db['${c.collectionName}'].updateMany(...`, args, ')'],
1993
- ],
1994
- deleteMany: (c, args) => [
1995
- c.deleteMany(...args),
1996
- [`db['${c.collectionName}'].deleteMany(...`, args, ')'],
1997
- ],
1698
+ updateMany: (c, args) => [c.updateMany(...args), [
1699
+ `db['${c.collectionName}'].updateMany(...`,
1700
+ args,
1701
+ ")"
1702
+ ]],
1703
+ deleteMany: (c, args) => [c.deleteMany(...args), [
1704
+ `db['${c.collectionName}'].deleteMany(...`,
1705
+ args,
1706
+ ")"
1707
+ ]]
1998
1708
  };
1999
-
1709
+ //#endregion
1710
+ //#region .build/lib/query/logic.js
2000
1711
  const filterUndefined = (applyOperator) => {
2001
- return (op, args) => applyOperator(op, args.filter(defined));
1712
+ return (op, args) => applyOperator(op, args.filter(defined));
2002
1713
  };
2003
1714
  const combine = (op, applyOperatorToPreItems) => (...args) => {
2004
- const mapToItems = applyOperatorToPreItems(op, args);
2005
- return mapToItems && { raw: field => mapToItems(x => x.raw(field)) };
2006
- };
2007
- const all = (op, x) => x.length === 0 ? undefined : f => ({ [op]: x.map(f) });
2008
- const first = (op, x) => (x.length === 1 ? f => f(x[0]) : all(op, x));
2009
- const $and = combine('$and', filterUndefined(first));
2010
- const $nor = combine('$nor', filterUndefined(all));
2011
- const $or = combine('$or', filterUndefined(first));
2012
-
2013
- const previous = (ts) => new mongodb.Timestamp({ t: ts.high - 60, i: 0 });
1715
+ const mapToItems = applyOperatorToPreItems(op, args);
1716
+ return mapToItems && { raw: (field) => mapToItems((x) => x.raw(field)) };
1717
+ };
1718
+ const all = (op, x) => x.length === 0 ? void 0 : (f) => safeNarrow()({ [op]: x.map(f) });
1719
+ const first$1 = (op, x) => x.length === 1 ? (f) => f(x[0]) : all(op, x);
1720
+ const $and = combine("$and", filterUndefined(first$1));
1721
+ const $nor = combine("$nor", filterUndefined(all));
1722
+ const $or = combine("$or", filterUndefined(first$1));
1723
+ //#endregion
1724
+ //#region .build/lib/boot/first-stages.js
1725
+ const previous = (ts) => new mongodb.Timestamp({
1726
+ t: ts.high - 60,
1727
+ i: 0
1728
+ });
2014
1729
  const getFirstStages = (view, needs) => {
2015
- const { projection, hardMatch: pre, match } = view;
2016
- const projectInput = projection && $project_(spread(projection, {
2017
- deletedAt: ['deletedAt', 1],
2018
- _id: ['_id', 1],
2019
- }));
2020
- const removeNotYetSynchronizedFields = projection && Object.values(mapExactToObject(projection, (_, k) => (needs[k] ?? k.startsWith('_')) ? root().of(k).has($exists(true)) : null));
2021
- const hardMatch = removeNotYetSynchronizedFields ? $and(pre, ...removeNotYetSynchronizedFields) : pre;
2022
- const firstStages = (lastTS, keepNulls = false) => {
2023
- const hardQuery = $and(lastTS
2024
- ? root().of('touchedAt').has($gtTs(previous(lastTS.ts)))
2025
- : root().of('deletedAt').has($eq(null)), lastTS ? null : match && $expr(match), keepNulls ? pre : hardMatch);
2026
- const ln = link()
2027
- .with($match_(hardQuery));
2028
- return (projectInput ? ln.with(projectInput) : ln);
2029
- };
2030
- return { firstStages, hardMatch };
1730
+ const { projection, hardMatch: pre, match } = view;
1731
+ const projectInput = projection && $project_(spread(projection, {
1732
+ deletedAt: ["deletedAt", 1],
1733
+ _id: ["_id", 1]
1734
+ }));
1735
+ const removeNotYetSynchronizedFields = projection && Object.values(mapExactToObject(projection, (_, k) => needs[k] ?? k.startsWith("_") ? root().of(k).has($exists(true)) : null));
1736
+ const hardMatch = removeNotYetSynchronizedFields ? $and(pre, ...removeNotYetSynchronizedFields) : pre;
1737
+ const firstStages = (lastTS, keepNulls = false) => {
1738
+ const hardQuery = $and(lastTS ? root().of("touchedAt").has($gtTs(previous(lastTS.ts))) : root().of("deletedAt").has($eq(null)), lastTS ? null : match && $expr(match), keepNulls ? pre : hardMatch);
1739
+ const ln = link().with($match_(hardQuery));
1740
+ return projectInput ? ln.with(projectInput) : ln;
1741
+ };
1742
+ return {
1743
+ firstStages,
1744
+ hardMatch
1745
+ };
2031
1746
  };
2032
-
1747
+ //#endregion
1748
+ //#region .build/lib/boot/boot.js
2033
1749
  const streamNames = {};
2034
1750
  const executes$2 = (view, input, streamName, skip = false, after, needs = {}) => {
2035
- const { collection, projection, match } = view;
2036
- const { firstStages, hardMatch } = getFirstStages(view, needs);
2037
- const db = collection.s.db, coll = collection.collectionName;
2038
- const hash = crypto$1
2039
- .createHash('md5')
2040
- .update(new Error().stack + '')
2041
- .digest('base64url');
2042
- if (!streamNames[streamName])
2043
- streamNames[streamName] = hash;
2044
- else if (streamNames[streamName] != hash)
2045
- throw new Error(`streamName ${streamName} already used`);
2046
- const last = db.collection('__last');
2047
- const snapshotCollection = db.collection(coll + '_' + streamName + '_snapshot');
2048
- const job = {};
2049
- const run = (finalInput, setup) => {
2050
- const dropSnapshot = async () => {
2051
- await snapshotCollection.drop().catch(noop);
2052
- log('snapshot collection dropped', streamName, `db['${snapshotCollection.collectionName}'].drop()`);
2053
- log('with', [...(indexMap.get(snapshotCollection.collectionName)?.keys() ?? [])], 'indexes in map before deletion');
2054
- indexMap.delete(snapshotCollection.collectionName);
2055
- };
2056
- const clear = async () => Promise.all([dropSnapshot(), last.deleteOne({ _id: streamName })]);
2057
- const withStop = (next, tr) => {
2058
- return addTeardown(() => ({ stop, next: next(), clear }), tr);
2059
- };
2060
- const nextData = (data, job) => (next, debug, tr) => ({
2061
- cont: withStop(next, tr),
2062
- data,
2063
- info: { job, debug: `${streamName} on ${collection.collectionName}: ${debug}` },
2064
- });
2065
- const next = nextData([], job);
2066
- const data = {
2067
- input: input.delta,
2068
- finalInputFirst: finalInput.raw(true),
2069
- finalInput: finalInput.raw(false),
2070
- match: view.match?.raw(root()).get(),
2071
- project: projection,
2072
- teardown: finalInput.teardown((x) => ({
2073
- collection: x.collection.collectionName,
2074
- method: x.method,
2075
- params: x.params,
2076
- })),
2077
- };
2078
- const step0 = () => Promise.resolve(next(step1, 'empty new collection'));
2079
- const stop = withStop(step0);
2080
- const step1 = async () => {
2081
- log('reset collection', streamName, `db['${snapshotCollection.collectionName}'].updateMany( updated: true }, { $set: { updated: false, after: null } })`);
2082
- await snapshotCollection.updateMany({ updated: true }, { $set: { updated: false, after: null } });
2083
- log('reset collection done', streamName);
2084
- return next(step2, 'get last update');
2085
- };
2086
- const step2 = () => Promise.all([
2087
- last.findOne({ _id: streamName, data, job: null }),
2088
- last.findOne({ _id: streamName }),
2089
- ]).then(ts => next(step2_5(ts), ts[0]
2090
- ? `no teardown to handle, starting at ${ts[0].ts}`
2091
- : ts[1]
2092
- ? 'handle teardown'
2093
- : 'start fresh'));
2094
- const step2_5 = ([same, exists]) => async () => {
2095
- const handleTeardown = async (last) => {
2096
- if (!last.data)
2097
- return;
2098
- const { collection: c, method: m, params: p } = last.data.teardown;
2099
- const { collection, method, params } = {
2100
- collection: db.collection(c),
2101
- method: m,
2102
- params: p,
2103
- };
2104
- const [action, out] = actions[method](collection, params);
2105
- log('teardown', `db['${snapshotCollection.collectionName}'].drop()`, ...out);
2106
- await Promise.all([dropSnapshot(), action]);
2107
- log('teardown done', `db['${snapshotCollection.collectionName}'].drop()`, ...out);
2108
- };
2109
- if (!same) {
2110
- log('not same, new data', streamName, data);
2111
- await handleTeardown(exists ?? { data });
2112
- }
2113
- log('creating indexes');
2114
- await createIndex(snapshotCollection, { before: 1 }, {
2115
- partialFilterExpression: { before: null },
2116
- name: 'before_' + new mongodb.UUID().toString('base64'),
2117
- });
2118
- await createIndex(snapshotCollection, { updated: 1 }, {
2119
- partialFilterExpression: { updated: true },
2120
- name: 'updated_' + new mongodb.UUID().toString('base64'),
2121
- });
2122
- await createIndex(snapshotCollection, { updated: 1, after: 1, before: 1 }, {
2123
- partialFilterExpression: { updated: true, after: null, before: null },
2124
- name: 'updated_nulls_' + new mongodb.UUID().toString('base64'),
2125
- });
2126
- await createIndex(snapshotCollection, { updated: 1, after: 1 }, {
2127
- partialFilterExpression: { updated: true, after: null },
2128
- name: 'updated_no_after_' + new mongodb.UUID().toString('base64'),
2129
- });
2130
- await createIndex(snapshotCollection, { updated: 1 }, {
2131
- partialFilterExpression: { updated: true, after: null, before: null },
2132
- name: 'updated_nulls_' + new mongodb.UUID().toString('base64'),
2133
- });
2134
- await ensureCollection(db, coll);
2135
- await db.command({
2136
- collMod: coll,
2137
- changeStreamPreAndPostImages: { enabled: true },
2138
- });
2139
- await createIndex(collection, { touchedAt: 1 }, hardMatch
2140
- ? {
2141
- partialFilterExpression: hardMatch.raw(root()),
2142
- name: 'touchedAt_hard_' + new mongodb.UUID().toString('base64'),
2143
- }
2144
- : {});
2145
- await setup?.();
2146
- await after?.();
2147
- return nextData([])(async () => {
2148
- await new Promise(resolve => setTimeout(resolve, 1000));
2149
- return next(step3(same), 'clone into new collection');
2150
- }, 'wait for clone into new collection');
2151
- };
2152
- const step3 = (lastTS) => async () => {
2153
- const notDeleted = eq($ifNull(root().of('deletedAt').expr(), nil))(nil);
2154
- const query = match ? and(notDeleted, match) : notDeleted;
2155
- const replaceRaw = $replaceWith_(field({
2156
- after: ['after', lastTS ? ite(query, root().expr(), nil) : root().expr()],
2157
- updated: ['updated', val(true)],
2158
- _id: ['_id', root().of('_id').expr()],
2159
- }));
2160
- const cloneIntoNew = firstStages(lastTS)
2161
- .with(replaceRaw)
2162
- .with($merge_({
2163
- into: snapshotCollection,
2164
- on: root().of('_id'),
2165
- stages: 'ctx',
2166
- vars: {
2167
- new: ['new', root().expr()],
2168
- },
2169
- whenMatched: link().with($replaceWith_(ite(eq(root().of('before').expr())(ctx()('new').of('after').expr()), root().expr(), mergeObjects(root().expr(), ctx()('new').expr())))).stages,
2170
- whenNotMatched: 'insert',
2171
- })).stages;
2172
- const stream = await makeStream();
2173
- const r = await aggregate(db, streamName, c => c({ coll: collection, input: cloneIntoNew }));
2174
- const start = Date.now();
2175
- const res = await snapshotCollection.deleteMany({ updated: true, after: null, before: null });
2176
- log('deleting from cloned into new collection', Date.now() - start, res, `db['${snapshotCollection.collectionName}'].deleteMany({ updated: true, after: null, before: null })`);
2177
- return next(step4({ result: r, ts: lastTS?.ts, stream }), 'run the aggregation', () => stream.close());
2178
- };
2179
- const makeStream = () => makeWatchStream(view, streamName);
2180
- const step4 = ({ result, ts, stream }) => async () => {
2181
- const start = Date.now();
2182
- log('snapshot', streamName, 'ensure before null', Date.now() - start);
2183
- const first = ts === undefined;
2184
- const stages = finalInput.raw(first);
2185
- await last.updateOne({ _id: streamName }, { $set: { job: 1 } }, { upsert: true });
2186
- const nextRes = stream.tryNext();
2187
- const aggResult = await aggregate(db, streamName, c => c({
2188
- coll: snapshotCollection,
2189
- input: link()
2190
- .with($match_(root().of('updated').has($eq(true))))
2191
- .with($set_(set()({
2192
- before: [
2193
- 'before',
2194
- to($ifNull(root().of('before').expr(), nil)),
2195
- ],
2196
- })))
2197
- .with(input.delta)
2198
- .with(stages).stages,
2199
- }), false, start);
2200
- return next(step5({ ts: result.cursor.atClusterTime, aggResult, stream, nextRes, first }), 'remove handled deleted updated');
2201
- };
2202
- const step5 = (l) => async () => {
2203
- log(streamName, `remove handled deleted updated db['${snapshotCollection.collectionName}'].deleteMany({ updated: true, after: null })`);
2204
- await snapshotCollection.deleteMany({ updated: true, after: null });
2205
- log('removed handled deleted updated');
2206
- return next(step6(l), 'update snapshot aggregation');
2207
- };
2208
- const step6 = (l) => async () => {
2209
- log('update snapshot aggregation', `db['${snapshotCollection.collectionName}'].updateMany({ updated: true }, [ { $set: { updated: false, after: null, before: '$after' } } ])`);
2210
- const start = Date.now();
2211
- await snapshotCollection.updateMany({ updated: true }, [
2212
- {
2213
- $set: {
2214
- updated: false,
2215
- after: null,
2216
- before: '$after',
2217
- },
2218
- },
2219
- ]);
2220
- log('updated snapshot aggregation', Date.now() - start);
2221
- return next(step7(l), 'update __last');
2222
- };
2223
- const step7 = (l) => async () => {
2224
- const start = Date.now();
2225
- const patch = {
2226
- $set: {
2227
- ts: l.ts,
2228
- job: null,
2229
- },
2230
- };
2231
- if (l.first)
2232
- patch.$set = { ...patch.$set, data };
2233
- await last.updateOne({ _id: streamName }, patch, { upsert: true });
2234
- log('updated __last', Date.now() - start, `db['${last.collectionName}'].updateOne({ _id: '${streamName}' }, `, patch, `, { upsert: true })`);
2235
- return step8(l);
2236
- };
2237
- const step8 = (l) => {
2238
- return nextData(l.aggResult.cursor.firstBatch)(() => l.nextRes.then(doc => doc
2239
- ? next(step3({ _id: streamName, ts: l.ts }), 'restart')
2240
- : step8({ ...l, nextRes: l.stream.tryNext() })), 'wait for change');
2241
- };
2242
- return skip
2243
- ? withStop(() => Promise.resolve(next(step3(null), 'clone into new collection')))
2244
- : stop;
2245
- };
2246
- const hasBefore = root().of('before').has($ne(null));
2247
- return {
2248
- stages: c => c({
2249
- coll: snapshotCollection,
2250
- input: $match_(hasBefore),
2251
- exec: asBefore(input.raw),
2252
- }),
2253
- out: run,
2254
- };
2255
- };
2256
- const staging = (view, streamName, skip = false, after) => pipe(input => executes$2(view, input, streamName, skip, after, view.needs), emptyDelta(), concatDelta, emptyDelta);
2257
-
1751
+ const { collection, projection, match } = view;
1752
+ const { firstStages, hardMatch } = getFirstStages(view, needs);
1753
+ const db = collection.s.db, coll = collection.collectionName;
1754
+ const hash = crypto$1.default.createHash("md5").update((/* @__PURE__ */ new Error()).stack + "").digest("base64url");
1755
+ if (!streamNames[streamName]) streamNames[streamName] = hash;
1756
+ else if (streamNames[streamName] != hash) throw new Error(`streamName ${streamName} already used`);
1757
+ const last = db.collection("__last");
1758
+ const snapshotCollection = db.collection(coll + "_" + streamName + "_snapshot");
1759
+ const job = {};
1760
+ const run = (finalInput, setup) => {
1761
+ const dropSnapshot = async () => {
1762
+ await snapshotCollection.drop().catch(noop);
1763
+ log("snapshot collection dropped", streamName, `db['${snapshotCollection.collectionName}'].drop()`);
1764
+ log("with", [...indexMap.get(snapshotCollection.collectionName)?.keys() ?? []], "indexes in map before deletion");
1765
+ indexMap.delete(snapshotCollection.collectionName);
1766
+ };
1767
+ const clear = async () => Promise.all([dropSnapshot(), last.deleteOne({ _id: streamName })]);
1768
+ const withStop = (next, tr) => {
1769
+ return addTeardown(() => ({
1770
+ stop,
1771
+ next: next(),
1772
+ clear
1773
+ }), tr);
1774
+ };
1775
+ const nextData = (data, job) => (next, debug, tr) => ({
1776
+ cont: withStop(next, tr),
1777
+ data,
1778
+ info: {
1779
+ job,
1780
+ debug: `${streamName} on ${collection.collectionName}: ${debug}`
1781
+ }
1782
+ });
1783
+ const next = nextData([], job);
1784
+ const data = {
1785
+ input: input.delta,
1786
+ finalInputFirst: finalInput.raw(true),
1787
+ finalInput: finalInput.raw(false),
1788
+ match: view.match?.raw(root()).get(),
1789
+ project: projection,
1790
+ teardown: finalInput.teardown((x) => ({
1791
+ collection: x.collection.collectionName,
1792
+ method: x.method,
1793
+ params: x.params
1794
+ }))
1795
+ };
1796
+ const step0 = () => Promise.resolve(next(step1, "empty new collection"));
1797
+ const stop = withStop(step0);
1798
+ const step1 = async () => {
1799
+ log("reset collection", streamName, `db['${snapshotCollection.collectionName}'].updateMany( updated: true }, { $set: { updated: false, after: null } })`);
1800
+ await snapshotCollection.updateMany({ updated: true }, { $set: {
1801
+ updated: false,
1802
+ after: null
1803
+ } });
1804
+ log("reset collection done", streamName);
1805
+ return next(step2, "get last update");
1806
+ };
1807
+ const step2 = () => Promise.all([last.findOne({
1808
+ _id: streamName,
1809
+ data,
1810
+ job: null
1811
+ }), last.findOne({ _id: streamName })]).then((ts) => next(step2_5(ts), ts[0] ? `no teardown to handle, starting at ${ts[0].ts}` : ts[1] ? "handle teardown" : "start fresh"));
1812
+ const step2_5 = ([same, exists]) => async () => {
1813
+ const handleTeardown = async (last) => {
1814
+ if (!last.data) return;
1815
+ const { collection: c, method: m, params: p } = last.data.teardown;
1816
+ const { collection, method, params } = {
1817
+ collection: db.collection(c),
1818
+ method: m,
1819
+ params: p
1820
+ };
1821
+ const [action, out] = actions[method](collection, params);
1822
+ log("teardown", `db['${snapshotCollection.collectionName}'].drop()`, ...out);
1823
+ await Promise.all([dropSnapshot(), action]);
1824
+ log("teardown done", `db['${snapshotCollection.collectionName}'].drop()`, ...out);
1825
+ };
1826
+ if (!same) {
1827
+ log("not same, new data", streamName, data);
1828
+ await handleTeardown(exists ?? { data });
1829
+ }
1830
+ log("creating indexes");
1831
+ await createIndex(snapshotCollection, { before: 1 }, {
1832
+ partialFilterExpression: { before: null },
1833
+ name: "before_" + new mongodb.UUID().toString("base64")
1834
+ });
1835
+ await createIndex(snapshotCollection, { updated: 1 }, {
1836
+ partialFilterExpression: { updated: true },
1837
+ name: "updated_" + new mongodb.UUID().toString("base64")
1838
+ });
1839
+ await createIndex(snapshotCollection, {
1840
+ updated: 1,
1841
+ after: 1,
1842
+ before: 1
1843
+ }, {
1844
+ partialFilterExpression: {
1845
+ updated: true,
1846
+ after: null,
1847
+ before: null
1848
+ },
1849
+ name: "updated_nulls_" + new mongodb.UUID().toString("base64")
1850
+ });
1851
+ await createIndex(snapshotCollection, {
1852
+ updated: 1,
1853
+ after: 1
1854
+ }, {
1855
+ partialFilterExpression: {
1856
+ updated: true,
1857
+ after: null
1858
+ },
1859
+ name: "updated_no_after_" + new mongodb.UUID().toString("base64")
1860
+ });
1861
+ await createIndex(snapshotCollection, { updated: 1 }, {
1862
+ partialFilterExpression: {
1863
+ updated: true,
1864
+ after: null,
1865
+ before: null
1866
+ },
1867
+ name: "updated_nulls_" + new mongodb.UUID().toString("base64")
1868
+ });
1869
+ await ensureCollection(db, coll);
1870
+ await db.command({
1871
+ collMod: coll,
1872
+ changeStreamPreAndPostImages: { enabled: true }
1873
+ });
1874
+ await createIndex(collection, { touchedAt: 1 }, hardMatch ? {
1875
+ partialFilterExpression: hardMatch.raw(root()),
1876
+ name: "touchedAt_hard_" + new mongodb.UUID().toString("base64")
1877
+ } : {});
1878
+ await setup?.();
1879
+ await after?.();
1880
+ return nextData([])(async () => {
1881
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
1882
+ return next(step3(same), "clone into new collection");
1883
+ }, "wait for clone into new collection");
1884
+ };
1885
+ const step3 = (lastTS) => async () => {
1886
+ const notDeleted = eq($ifNull(root().of("deletedAt").expr(), nil))(nil);
1887
+ const query = match ? and(notDeleted, match) : notDeleted;
1888
+ const replaceRaw = $replaceWith_(field({
1889
+ after: ["after", lastTS ? ite(query, root().expr(), nil) : root().expr()],
1890
+ updated: ["updated", val(true)],
1891
+ _id: ["_id", root().of("_id").expr()]
1892
+ }));
1893
+ const cloneIntoNew = firstStages(lastTS).with(replaceRaw).with($merge_({
1894
+ into: snapshotCollection,
1895
+ on: root().of("_id"),
1896
+ stages: "ctx",
1897
+ vars: { new: ["new", root().expr()] },
1898
+ whenMatched: link().with($replaceWith_(ite(eq(root().of("before").expr())(ctx()("new").of("after").expr()), root().expr(), mergeObjects(root().expr(), ctx()("new").expr())))).stages,
1899
+ whenNotMatched: "insert"
1900
+ })).stages;
1901
+ const stream = await makeStream();
1902
+ const r = await aggregate(db, streamName, (c) => c({
1903
+ coll: collection,
1904
+ input: cloneIntoNew
1905
+ }));
1906
+ const start = Date.now();
1907
+ const res = await snapshotCollection.deleteMany({
1908
+ updated: true,
1909
+ after: null,
1910
+ before: null
1911
+ });
1912
+ log("deleting from cloned into new collection", Date.now() - start, res, `db['${snapshotCollection.collectionName}'].deleteMany({ updated: true, after: null, before: null })`);
1913
+ return next(step4({
1914
+ result: r,
1915
+ ts: lastTS?.ts,
1916
+ stream
1917
+ }), "run the aggregation", () => stream.close());
1918
+ };
1919
+ const makeStream = () => makeWatchStream(view, streamName);
1920
+ const step4 = ({ result, ts, stream }) => async () => {
1921
+ const start = Date.now();
1922
+ log("snapshot", streamName, "ensure before null", Date.now() - start);
1923
+ const first = ts === void 0;
1924
+ const stages = finalInput.raw(first);
1925
+ await last.updateOne({ _id: streamName }, { $set: { job: 1 } }, { upsert: true });
1926
+ const nextRes = stream.tryNext();
1927
+ const aggResult = await aggregate(db, streamName, (c) => c({
1928
+ coll: snapshotCollection,
1929
+ input: link().with($match_(root().of("updated").has($eq(true)))).with($set_(set()({ before: ["before", to($ifNull(root().of("before").expr(), nil))] }))).with(input.delta).with(stages).stages
1930
+ }), false, start);
1931
+ return next(step5({
1932
+ ts: result.cursor.atClusterTime,
1933
+ aggResult,
1934
+ stream,
1935
+ nextRes,
1936
+ first
1937
+ }), "remove handled deleted updated");
1938
+ };
1939
+ const step5 = (l) => async () => {
1940
+ log(streamName, `remove handled deleted updated db['${snapshotCollection.collectionName}'].deleteMany({ updated: true, after: null })`);
1941
+ await snapshotCollection.deleteMany({
1942
+ updated: true,
1943
+ after: null
1944
+ });
1945
+ log("removed handled deleted updated");
1946
+ return next(step6(l), "update snapshot aggregation");
1947
+ };
1948
+ const step6 = (l) => async () => {
1949
+ log("update snapshot aggregation", `db['${snapshotCollection.collectionName}'].updateMany({ updated: true }, [ { $set: { updated: false, after: null, before: '$after' } } ])`);
1950
+ const start = Date.now();
1951
+ await snapshotCollection.updateMany({ updated: true }, [{ $set: {
1952
+ updated: false,
1953
+ after: null,
1954
+ before: "$after"
1955
+ } }]);
1956
+ log("updated snapshot aggregation", Date.now() - start);
1957
+ return next(step7(l), "update __last");
1958
+ };
1959
+ const step7 = (l) => async () => {
1960
+ const start = Date.now();
1961
+ const patch = { $set: {
1962
+ ts: l.ts,
1963
+ job: null
1964
+ } };
1965
+ if (l.first) patch.$set = {
1966
+ ...patch.$set,
1967
+ data
1968
+ };
1969
+ await last.updateOne({ _id: streamName }, patch, { upsert: true });
1970
+ log("updated __last", Date.now() - start, `db['${last.collectionName}'].updateOne({ _id: '${streamName}' }, `, patch, `, { upsert: true })`);
1971
+ return step8(l);
1972
+ };
1973
+ const step8 = (l) => {
1974
+ return nextData(l.aggResult.cursor.firstBatch)(() => l.nextRes.then((doc) => doc ? next(step3({
1975
+ _id: streamName,
1976
+ ts: l.ts
1977
+ }), "restart") : step8({
1978
+ ...l,
1979
+ nextRes: l.stream.tryNext()
1980
+ })), "wait for change");
1981
+ };
1982
+ return skip ? withStop(() => Promise.resolve(next(step3(null), "clone into new collection"))) : stop;
1983
+ };
1984
+ const hasBefore = root().of("before").has($ne(null));
1985
+ return {
1986
+ stages: (c) => c({
1987
+ coll: snapshotCollection,
1988
+ input: $match_(hasBefore),
1989
+ exec: asBefore(input.raw)
1990
+ }),
1991
+ out: run
1992
+ };
1993
+ };
1994
+ const staging = (view, streamName, skip = false, after) => pipe((input) => executes$2(view, input, streamName, skip, after, view.needs), emptyDelta(), concatDelta, emptyDelta);
1995
+ //#endregion
1996
+ //#region .build/lib/boot/boot-simpl.js
2258
1997
  const executes$1 = (view, input, streamName, needs) => {
2259
- const hash = crypto$1
2260
- .createHash('md5')
2261
- .update(new Error().stack + '')
2262
- .digest('base64url');
2263
- if (!streamNames[streamName])
2264
- streamNames[streamName] = hash;
2265
- else if (streamNames[streamName] != hash)
2266
- throw new Error('streamName already used');
2267
- const { collection, projection, hardMatch: pre, match } = view;
2268
- const removeNotYetSynchronizedFields = projection &&
2269
- Object.values(mapExactToObject(projection, (_, k) => (needs[k] ?? k.startsWith('_')) ? root().of(k).has($exists(true)) : null));
2270
- const hardMatch = removeNotYetSynchronizedFields
2271
- ? $and(pre, ...removeNotYetSynchronizedFields)
2272
- : pre;
2273
- const job = {};
2274
- const db = collection.s.db, coll = collection.collectionName;
2275
- const last = db.collection('__last');
2276
- const projectInput = projection &&
2277
- $project_(spread(projection, {
2278
- deletedAt: ['deletedAt', 1],
2279
- _id: ['_id', 1],
2280
- }));
2281
- const notDeleted = root().of('deletedAt').has($eq(null));
2282
- const stages = (lastTS) => {
2283
- const hardQuery = $and(lastTS && root().of('touchedAt').has($gteTs(previous(lastTS.ts))), hardMatch, notDeleted, match && $expr(match));
2284
- const ln = link().with($match_(hardQuery));
2285
- return (projectInput ? ln.with(projectInput) : ln).with(input);
2286
- };
2287
- const run = (finalInput) => {
2288
- const clear = async () => { };
2289
- const withStop = (next, tr) => {
2290
- return addTeardown(() => ({ stop, next: next(), clear }), tr);
2291
- };
2292
- const next = (next, debug, tr) => ({
2293
- cont: withStop(next, tr),
2294
- data: [],
2295
- info: { job, debug },
2296
- });
2297
- const data = {
2298
- input: input,
2299
- finalInputFirst: finalInput.raw(true),
2300
- finalInput: finalInput.raw(false),
2301
- match: view.match?.raw(root()).get(),
2302
- project: projection,
2303
- teardown: finalInput.teardown((x) => ({
2304
- collection: x.collection.collectionName,
2305
- method: x.method,
2306
- params: x.params,
2307
- })),
2308
- };
2309
- const step0 = () => Promise.resolve(next(step1, 'get last update'));
2310
- const stop = withStop(step0);
2311
- const step1 = async () => {
2312
- log('creating indexes');
2313
- await ensureCollection(db, coll);
2314
- await db.command({
2315
- collMod: coll,
2316
- changeStreamPreAndPostImages: { enabled: true },
2317
- });
2318
- await createIndex(collection, { touchedAt: 1 }, {
2319
- partialFilterExpression: { deletedAt: { $eq: null } },
2320
- name: 'touchedAt_' + new mongodb.UUID().toString('base64'),
2321
- });
2322
- log('stream started', { streamName, data });
2323
- const ts = await Promise.all([
2324
- last.findOne({ _id: streamName, data }),
2325
- last.findOne({ _id: streamName }),
2326
- ]);
2327
- log('got last update', { streamName, ts });
2328
- return next(step2_5(ts), 'handle teardown');
2329
- };
2330
- const step2_5 = ([same, exists]) => async () => {
2331
- const handleTeardown = async (last) => {
2332
- if (!last.data)
2333
- return;
2334
- const { collection: c, method: m, params: p } = last.data.teardown;
2335
- const { collection, method, params } = {
2336
- collection: db.collection(c),
2337
- method: m,
2338
- params: p,
2339
- };
2340
- const [action, out] = actions[method](collection, params);
2341
- log('teardown', ...out);
2342
- await action;
2343
- log('teardown done', ...out);
2344
- };
2345
- if (exists && !same)
2346
- await handleTeardown(exists);
2347
- return {
2348
- cont: withStop(async () => {
2349
- await new Promise(resolve => setTimeout(resolve, 1000));
2350
- return next(step4(same), 'clone into new collection');
2351
- }),
2352
- data: [],
2353
- info: { debug: 'wait for clone into new collection', job: undefined },
2354
- };
2355
- };
2356
- const makeStream = () => makeWatchStream(view, streamName);
2357
- const step4 = (lastTS) => async () => {
2358
- const raw = stages(lastTS).with(finalInput.raw(lastTS === null)).stages;
2359
- const stream = await makeStream();
2360
- const nextRes = stream.tryNext();
2361
- const aggResult = await aggregate(db, streamName, c => c({
2362
- coll: collection,
2363
- input: raw,
2364
- }));
2365
- return next(step7({ aggResult, ts: aggResult.cursor.atClusterTime, stream, nextRes }), 'update __last', () => stream.close());
2366
- };
2367
- const step7 = (l) => async () => {
2368
- await last.updateOne({ _id: streamName }, { $set: { ts: l.ts, data } }, { upsert: true });
2369
- return step8(l);
2370
- };
2371
- const step8 = (l) => {
2372
- return {
2373
- data: l.aggResult.cursor.firstBatch,
2374
- info: { job: undefined, debug: 'wait for change' },
2375
- cont: withStop(() => l.nextRes.then(doc => doc
2376
- ? next(step4({ _id: streamName, ts: l.ts }), 'restart')
2377
- : step8({ ...l, nextRes: l.stream.tryNext() }))),
2378
- };
2379
- };
2380
- return stop;
2381
- };
2382
- return {
2383
- out: run,
2384
- };
1998
+ const hash = crypto$1.default.createHash("md5").update((/* @__PURE__ */ new Error()).stack + "").digest("base64url");
1999
+ if (!streamNames[streamName]) streamNames[streamName] = hash;
2000
+ else if (streamNames[streamName] != hash) throw new Error("streamName already used");
2001
+ const { collection, projection, hardMatch: pre, match } = view;
2002
+ const removeNotYetSynchronizedFields = projection && Object.values(mapExactToObject(projection, (_, k) => needs[k] ?? k.startsWith("_") ? root().of(k).has($exists(true)) : null));
2003
+ const hardMatch = removeNotYetSynchronizedFields ? $and(pre, ...removeNotYetSynchronizedFields) : pre;
2004
+ const job = {};
2005
+ const db = collection.s.db, coll = collection.collectionName;
2006
+ const last = db.collection("__last");
2007
+ const projectInput = projection && $project_(spread(projection, {
2008
+ deletedAt: ["deletedAt", 1],
2009
+ _id: ["_id", 1]
2010
+ }));
2011
+ const notDeleted = root().of("deletedAt").has($eq(null));
2012
+ const stages = (lastTS) => {
2013
+ const hardQuery = $and(lastTS && root().of("touchedAt").has($gteTs(previous(lastTS.ts))), hardMatch, notDeleted, match && $expr(match));
2014
+ const ln = link().with($match_(hardQuery));
2015
+ return (projectInput ? ln.with(projectInput) : ln).with(input);
2016
+ };
2017
+ const run = (finalInput) => {
2018
+ const clear = async () => {};
2019
+ const withStop = (next, tr) => {
2020
+ return addTeardown(() => ({
2021
+ stop,
2022
+ next: next(),
2023
+ clear
2024
+ }), tr);
2025
+ };
2026
+ const next = (next, debug, tr) => ({
2027
+ cont: withStop(next, tr),
2028
+ data: [],
2029
+ info: {
2030
+ job,
2031
+ debug
2032
+ }
2033
+ });
2034
+ const data = {
2035
+ input,
2036
+ finalInputFirst: finalInput.raw(true),
2037
+ finalInput: finalInput.raw(false),
2038
+ match: view.match?.raw(root()).get(),
2039
+ project: projection,
2040
+ teardown: finalInput.teardown((x) => ({
2041
+ collection: x.collection.collectionName,
2042
+ method: x.method,
2043
+ params: x.params
2044
+ }))
2045
+ };
2046
+ const step0 = () => Promise.resolve(next(step1, "get last update"));
2047
+ const stop = withStop(step0);
2048
+ const step1 = async () => {
2049
+ log("creating indexes");
2050
+ await ensureCollection(db, coll);
2051
+ await db.command({
2052
+ collMod: coll,
2053
+ changeStreamPreAndPostImages: { enabled: true }
2054
+ });
2055
+ await createIndex(collection, { touchedAt: 1 }, {
2056
+ partialFilterExpression: { deletedAt: { $eq: null } },
2057
+ name: "touchedAt_" + new mongodb.UUID().toString("base64")
2058
+ });
2059
+ log("stream started", {
2060
+ streamName,
2061
+ data
2062
+ });
2063
+ const ts = await Promise.all([last.findOne({
2064
+ _id: streamName,
2065
+ data
2066
+ }), last.findOne({ _id: streamName })]);
2067
+ log("got last update", {
2068
+ streamName,
2069
+ ts
2070
+ });
2071
+ return next(step2_5(ts), "handle teardown");
2072
+ };
2073
+ const step2_5 = ([same, exists]) => async () => {
2074
+ const handleTeardown = async (last) => {
2075
+ if (!last.data) return;
2076
+ const { collection: c, method: m, params: p } = last.data.teardown;
2077
+ const { collection, method, params } = {
2078
+ collection: db.collection(c),
2079
+ method: m,
2080
+ params: p
2081
+ };
2082
+ const [action, out] = actions[method](collection, params);
2083
+ log("teardown", ...out);
2084
+ await action;
2085
+ log("teardown done", ...out);
2086
+ };
2087
+ if (exists && !same) await handleTeardown(exists);
2088
+ return {
2089
+ cont: withStop(async () => {
2090
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
2091
+ return next(step4(same), "clone into new collection");
2092
+ }),
2093
+ data: [],
2094
+ info: {
2095
+ debug: "wait for clone into new collection",
2096
+ job: void 0
2097
+ }
2098
+ };
2099
+ };
2100
+ const makeStream = () => makeWatchStream(view, streamName);
2101
+ const step4 = (lastTS) => async () => {
2102
+ const raw = stages(lastTS).with(finalInput.raw(lastTS === null)).stages;
2103
+ const stream = await makeStream();
2104
+ const nextRes = stream.tryNext();
2105
+ const aggResult = await aggregate(db, streamName, (c) => c({
2106
+ coll: collection,
2107
+ input: raw
2108
+ }));
2109
+ return next(step7({
2110
+ aggResult,
2111
+ ts: aggResult.cursor.atClusterTime,
2112
+ stream,
2113
+ nextRes
2114
+ }), "update __last", () => stream.close());
2115
+ };
2116
+ const step7 = (l) => async () => {
2117
+ await last.updateOne({ _id: streamName }, { $set: {
2118
+ ts: l.ts,
2119
+ data
2120
+ } }, { upsert: true });
2121
+ return step8(l);
2122
+ };
2123
+ const step8 = (l) => {
2124
+ return {
2125
+ data: l.aggResult.cursor.firstBatch,
2126
+ info: {
2127
+ job: void 0,
2128
+ debug: "wait for change"
2129
+ },
2130
+ cont: withStop(() => l.nextRes.then((doc) => doc ? next(step4({
2131
+ _id: streamName,
2132
+ ts: l.ts
2133
+ }), "restart") : step8({
2134
+ ...l,
2135
+ nextRes: l.stream.tryNext()
2136
+ })))
2137
+ };
2138
+ };
2139
+ return stop;
2140
+ };
2141
+ return { out: run };
2385
2142
  };
2386
2143
  const emptyLin = () => ({ lin: link().stages });
2387
- const from = (view, streamName, needs = {}) => pipe(input => executes$1(view, input.lin, streamName, needs), { lin: link().stages }, ({ lin: a }, { lin: b }) => ({ lin: concatStages(a, b) }), emptyLin);
2388
-
2144
+ const from = (view, streamName, needs = {}) => pipe((input) => executes$1(view, input.lin, streamName, needs), { lin: link().stages }, ({ lin: a }, { lin: b }) => ({ lin: concatStages(a, b) }), emptyLin);
2145
+ //#endregion
2146
+ //#region .build/lib/boot/single.js
2389
2147
  const executes = (view, input, needs) => {
2390
- const { firstStages } = getFirstStages(view, needs);
2391
- const { collection } = view;
2392
- return (finalInput) => {
2393
- const start = input.raw(root);
2394
- const stages = firstStages(null, true).with(start).with(finalInput).stages;
2395
- return c => c({
2396
- coll: collection,
2397
- input: link().stages,
2398
- exec: stages,
2399
- });
2400
- };
2401
- };
2402
- const single = (view, needs = {}) => pipe(input => executes(view, input, needs), emptyDelta(), concatDelta, emptyDelta);
2403
-
2404
- require('dotenv').config();
2405
- const uri = process.env['MONGO_URL'];
2406
-
2148
+ const { firstStages } = getFirstStages(view, needs);
2149
+ const { collection } = view;
2150
+ return (finalInput) => {
2151
+ const start = input.raw(root);
2152
+ const stages = firstStages(null, true).with(start).with(finalInput).stages;
2153
+ return (c) => c({
2154
+ coll: collection,
2155
+ input: link().stages,
2156
+ exec: stages
2157
+ });
2158
+ };
2159
+ };
2160
+ const single = (view, needs = {}) => pipe((input) => executes(view, input, needs), emptyDelta(), concatDelta, emptyDelta);
2161
+ //#endregion
2162
+ //#region .build/test/uri.js
2163
+ require("dotenv").config();
2164
+ const uri = process.env["MONGO_URL"];
2165
+ //#endregion
2166
+ //#region .build/test/mongodb.js
2407
2167
  const enablePreAndPostImages = (coll) => coll.s.db.command({
2408
- collMod: coll.collectionName,
2409
- changeStreamPreAndPostImages: { enabled: true },
2168
+ collMod: coll.collectionName,
2169
+ changeStreamPreAndPostImages: { enabled: true }
2410
2170
  });
2411
2171
  const prepare = async (testName) => {
2412
- const client = new mongodb.MongoClient(uri, testName ? { monitorCommands: true } : {});
2413
- if (testName) {
2414
- const handler = (c) => {
2415
- promises.writeFile(`./out/${testName}.log`, JSON.stringify(c.command) + ',\n', { flag: 'w' });
2416
- };
2417
- client.on('commandStarted', handler);
2418
- client.on('commandSucceeded', handler);
2419
- }
2420
- await client.connect();
2421
- await client.db('admin').command({
2422
- setClusterParameter: {
2423
- changeStreamOptions: {
2424
- preAndPostImages: { expireAfterSeconds: 60 },
2425
- },
2426
- },
2427
- });
2428
- return client;
2172
+ const client = new mongodb.MongoClient(uri, testName ? { monitorCommands: true } : {});
2173
+ if (testName) {
2174
+ const handler = (c) => {
2175
+ (0, fs_promises.writeFile)(`./out/${testName}.log`, JSON.stringify(c.command) + ",\n", { flag: "w" });
2176
+ };
2177
+ client.on("commandStarted", handler);
2178
+ client.on("commandSucceeded", handler);
2179
+ }
2180
+ await client.connect();
2181
+ await client.db("admin").command({ setClusterParameter: { changeStreamOptions: { preAndPostImages: { expireAfterSeconds: 60 } } } });
2182
+ return client;
2429
2183
  };
2184
+ const clears = [];
2430
2185
  const makeCol = async (docs, database, name) => {
2431
- if (!name) {
2432
- (name = crypto.randomUUID());
2433
- }
2434
- try {
2435
- const col = await database.createCollection(name, {
2436
- changeStreamPreAndPostImages: { enabled: true },
2437
- });
2438
- if (docs.length)
2439
- await col.insertMany([...docs]);
2440
- return col;
2441
- }
2442
- catch {
2443
- return database.collection(name);
2444
- }
2186
+ if (!name) {
2187
+ const n = name = crypto.randomUUID();
2188
+ clears.push(async () => {
2189
+ await database.collection(n).drop({ ignoreUndefined: true });
2190
+ });
2191
+ }
2192
+ try {
2193
+ const col = await database.createCollection(name, { changeStreamPreAndPostImages: { enabled: true } });
2194
+ if (docs.length) await col.insertMany([...docs]);
2195
+ return col;
2196
+ } catch {
2197
+ return database.collection(name);
2198
+ }
2445
2199
  };
2446
-
2200
+ //#endregion
2447
2201
  exports.$accumulator = $accumulator;
2448
2202
  exports.$and = $and;
2449
2203
  exports.$countDict = $countDict;
@@ -2521,18 +2275,15 @@ exports.divide = divide;
2521
2275
  exports.emptyDelta = emptyDelta;
2522
2276
  exports.enablePreAndPostImages = enablePreAndPostImages;
2523
2277
  exports.eq = eq;
2524
- exports.eqExtends = eqExtends;
2525
- exports.eqPar = eqPar;
2526
2278
  exports.eqTyped = eqTyped;
2527
2279
  exports.except = except;
2528
- exports.excludeIdem = excludeIdem;
2529
2280
  exports.exprMapVal = exprMapVal;
2530
2281
  exports.field = field;
2531
2282
  exports.fieldF = fieldF;
2532
2283
  exports.fieldM = fieldM;
2533
2284
  exports.filter = filter;
2534
2285
  exports.filterDefined = filterDefined;
2535
- exports.first = first$1;
2286
+ exports.first = first;
2536
2287
  exports.firstSure = firstSure;
2537
2288
  exports.floor = floor;
2538
2289
  exports.from = from;
@@ -2581,9 +2332,6 @@ exports.noop = noop;
2581
2332
  exports.not = not;
2582
2333
  exports.notNull = notNull;
2583
2334
  exports.now = now;
2584
- exports.omitExclude = omitExclude;
2585
- exports.omitPick = omitPick;
2586
- exports.omitRORec = omitRORec;
2587
2335
  exports.or = or;
2588
2336
  exports.padLeft = padLeft;
2589
2337
  exports.prepare = prepare;
@@ -2591,7 +2339,6 @@ exports.rand = rand;
2591
2339
  exports.range = range;
2592
2340
  exports.reflex = reflex;
2593
2341
  exports.regex = regex;
2594
- exports.renamedFields = renamedFields;
2595
2342
  exports.root = root;
2596
2343
  exports.set = set;
2597
2344
  exports.setField = setField;
@@ -2609,8 +2356,9 @@ exports.subtract = subtract;
2609
2356
  exports.sym = sym;
2610
2357
  exports.to = to;
2611
2358
  exports.toInt = toInt;
2612
- exports.translateOmit = translateOmit;
2613
2359
  exports.val = val;
2614
2360
  exports.weekPart = weekPart;
2615
2361
  exports.wrap = wrap;
2616
2362
  exports.year = year;
2363
+
2364
+ //# sourceMappingURL=index.js.map