@omegup/msync 0.1.60 → 0.1.62

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