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