@omegup/msync 0.1.61 → 0.1.63

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