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