@omegup/msync 0.1.53 → 0.1.54

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 (4) hide show
  1. package/index.d.ts +11 -15
  2. package/index.esm.js +139 -191
  3. package/index.js +138 -192
  4. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -168,10 +168,8 @@ type D = O<DeletedAt & ID>;
168
168
  type Model = D & TS;
169
169
  type BA = 'before' | 'after';
170
170
  type PreDelta<T, K extends BA = BA, E = unknown> = Rec<K, T> & E;
171
- type DeletedFlags = O<{
172
- readonly before?: true;
173
- readonly after?: true;
174
- }>;
171
+ type NTrue = true | N;
172
+ type DeletedFlags = Rec<BA, NTrue>;
175
173
  type Deleted = {
176
174
  readonly deleted?: DeletedFlags;
177
175
  };
@@ -245,7 +243,7 @@ declare const mapExact1: <K extends s$3, F extends HKT<K>, G extends HKT<K>>(x:
245
243
  declare const mapExactToObject: <T, F extends HKT<T[StrKey<T>]>, G extends HKT<StrKey<T>>>(x: Exact<T, F>, f: <P extends StrKey<T>>(v: App<F, T[P]>, k: P) => App<G, P>) => ExactPart1<T, G>;
246
244
  declare const mapExact: <T, F extends HKT<T[StrKey<T>]>, G extends HKT<T[StrKey<T>]>>(x: Exact<T, F>, f: <P extends StrKey<T>>(v: App<F, T[P]>, k: P) => App<G, T[P]>) => Exact<T, G>;
247
245
  type Dom$1<T, V> = HKT<T[StrKey<T>] | V[StrKey<V>]>;
248
- declare const spread: <T, V, F extends Dom$1<T, V>, E = unknown, No extends keyof V = never>(a: Exact<Omit<T, No>, F>, b: Exact<V, F>) => Exact<V & Omit<T, keyof V> & Pick<E, symbol & keyof E>, F>;
246
+ declare const spread: <T, V, F extends Dom$1<T, V>, EK extends symbol = never, EE = unknown, No extends keyof V = never>(a: Exact<Omit<T, No>, F>, b: Exact<V, F>) => Exact<V & Omit<T, keyof V> & Record<EK, EE>, F>;
249
247
  interface MergeHKT<T, V, F1 extends HKT<StrKey<Omit<T, No>>>, F2 extends HKT<StrKey<V>>, No extends keyof V = never> extends HKT<StrKey<V & Omit<T, No>>> {
250
248
  readonly out: I<StrKey<V & Omit<T, No>>, this> extends StrKey<V> ? App<F2, I<StrKey<V>, this>> : App<F1, I<StrKey<Omit<T, No>>, this>>;
251
249
  }
@@ -291,10 +289,10 @@ declare const fieldM: <M extends RORec<Dom, Ref>, T extends RORec<Ref, unknown>,
291
289
  type Exprs<out T, in D, in C = unknown> = {
292
290
  readonly [K in StrKey<T>]: Expr<T[K], D, C>;
293
291
  };
294
- declare const mergeExact: <T1, T2, F extends HKT<T1[StrKey<T1>] | T2[StrKey<T2>]>, E = unknown>(exprsExact1: Exact<Omit<T1, keyof T2>, F>, exprsExact2: Exact<T2, F>) => Exact<T2 & Omit<T1, keyof T2> & Pick<E, symbol & keyof E>, F>;
292
+ declare const mergeExact: <T1, T2, F extends HKT<T1[StrKey<T1>] | T2[StrKey<T2>]>, EK extends symbol = never, EE = unknown>(exprsExact1: Exact<Omit<T1, keyof T2>, F>, exprsExact2: Exact<T2, F>) => Exact<T2 & Omit<T1, keyof T2> & Record<EK, EE>, F>;
295
293
  type MergeMapOArgs<T1, T2, F1 extends HKT<StrKey<Omit<T1, StrKey<T2>>>>, F2 extends HKT<StrKey<T2>>> = readonly [MapO<Omit<T1, StrKey<T2>>, F1>, MapO<T2, F2>];
296
294
  declare const mergeExact0: <T1, T2, F1 extends HKT<StrKey<Omit<T1, StrKey<T2>>>>, F2 extends HKT<StrKey<T2>>, E = unknown>(exprsExact1: MapO<Omit<T1, StrKey<T2>>, F1>, exprsExact2: MapO<T2, F2>) => MapO<T2 & Omit<T1, StrKey<T2>> & Pick<E, symbol & keyof E>, MergeHKT<T1, T2, F1, F2, StrKey<T2>>>;
297
- declare const mergeExpr: <T1, T2, D, C = unknown, E = unknown>(exprs_0: Exact<Omit<T1, keyof T2>, ExprHKT<D, C, IdHKT<unknown>>>, exprs_1: Exact<T2, ExprHKT<D, C, IdHKT<unknown>>>) => ExprsExact<T2 & Omit<T1, keyof T2> & Pick<E, symbol & keyof E>, D, C>;
295
+ declare const mergeExpr: <T1, T2, D, C = unknown, EK extends symbol = never, EE = unknown>(exprs_0: Exact<Omit<T1, keyof T2>, ExprHKT<D, C, IdHKT<unknown>>>, exprs_1: Exact<T2, ExprHKT<D, C, IdHKT<unknown>>>) => ExprsExact<T2 & Omit<T1, keyof T2> & Record<EK, EE>, D, C>;
298
296
  type ExprsPart<T, D, C> = ExactPart<T, ExprHKT<D, C>>;
299
297
  interface ExprHKT<D, C = unknown, F extends HKT = IdHKT> extends HKT<unknown> {
300
298
  readonly out: Expr<App<F, I<unknown, this>>, D, C>;
@@ -303,7 +301,6 @@ type ExprsExact<T, D, C = unknown, F extends HKT = IdHKT> = Exact<T, ExprHKT<D,
303
301
  interface ExprsExactHKT<E, D, C = unknown, F extends HKT = IdHKT> extends HKT {
304
302
  readonly out: ExprsExact<E & I<unknown, this>, D, C, F>;
305
303
  }
306
- declare const pair: <T, D, C, P extends StrKey<T>>(k: P, v: Expr<T[P], D, C>) => ExprsExact<T, D, C>[P];
307
304
  declare const fieldF: <F extends HKT>() => <T extends object, D, C = unknown>(exprs: ExprsExact<T, D, C, F>) => Expr<O<{ [K in keyof T]: App<F, T[K]>; }>, D, C>;
308
305
  declare const field: <T extends object, D, C = unknown>(exprs: ExprsExact<T, D, C>) => Expr<O<T>, D, C>;
309
306
 
@@ -471,7 +468,6 @@ declare const renamedFields: <K extends s$2, F extends HKT<K, s$2>, G extends HK
471
468
  declare const translateOmit: <T, K extends string, Q extends string, P extends string>() => Equal<unknown, Omit<Omit<T, K | Q>, P>, Omit<Omit<T, K | Q>, Q | P>>;
472
469
  declare const excludeIdem: <K extends s$2, E extends s$2, S extends E = E>() => Equal<Exclude<K, E>, Exclude<K, E>, Exclude<Exclude<K, E>, S>>;
473
470
  declare const eqPar: <K extends string, T extends Rec<K, jsonItem>, K2 extends K>() => Equal<unknown, Par$1<K2, T>, Par$1<K, T>>;
474
- declare const notExtendExcluded: <Key extends keyof any, Others extends keyof any, Source extends keyof any, Denied extends keyof any, F extends HKT<Others | Exclude<Source, Denied | Key>, Dom>, Else extends Dom, Dom = unknown>() => Equal<Dom, Key extends Others | Exclude<Source, Key | Denied> ? App<F, Key> : Else, Key extends Others ? App<F, Key> : Else>;
475
471
 
476
472
  type DeltaPipe<Q extends O, T extends Q, F extends HKT<O2>, G extends HKT<O3>> = {
477
473
  with: <Q2 extends O, V extends Q2>(map: (a: Stream<Q, T, F, G>) => Stream<Q | Q2, V, F, G>) => DeltaPipe<Q | Q2, V, F, G>;
@@ -588,7 +584,7 @@ declare const $replaceWith: <T extends O, V extends O>(expr: Expr<V, T>) => Delt
588
584
  type s$1 = string;
589
585
  type JoinId<K1 extends s$1, K2 extends s$1> = K1 | K2 | readonly [K1, middle: s$1, K2] | readonly [K2, middle: s$1, K1];
590
586
  declare const joinIdOf: <K1 extends s$1, K2 extends s$1, D, C = unknown>(k: JoinId<K1, K2>, k1: K1, k1Id: Expr<s$1, D, C>, k2Id: Expr<s$1, D, C>) => Expr<s$1, D, C>;
591
- declare const $unwindDelta: <K1 extends s$1, T extends doc, K2 extends s$1, U extends doc, N1 extends null = never, N2 extends null = never>(k1: AsLiteral<K1>, k2: AsLiteral<K2>, k: JoinId<K1, K2>, includeNull1?: N1, includeNull2?: N2) => RawStages<unknown, Delta<Rec<K1, T | N1> & Rec<K2, Arr<U>>>, Delta<Rec<K1, T | N1> & Rec<K2, U | N2> & ID>>;
587
+ declare const $unwindDelta: <K1 extends s$1, T extends doc, KK2 extends s$1, U extends doc, N1 extends null = never, N2 extends null = never>(k1: AsLiteral<K1>, k2: AsLiteral<Exclude<KK2, K1 | BA>>, k: JoinId<K1, Exclude<KK2, K1 | BA>>, includeNull1?: N1, includeNull2?: N2) => RawStages<unknown, Delta<Rec<K1, T | N1> & Rec<Exclude<KK2, K1 | BA>, Arr<U>>>, Delta<Rec<K1, T | N1> & Rec<Exclude<KK2, K1 | BA>, U | N2> & ID>>;
592
588
 
593
589
  type s = string;
594
590
  type TOf<TT, K extends string> = doc & Omit<TT, K>;
@@ -693,12 +689,12 @@ declare const gt: {
693
689
  <D, C>(...expr: [Expr<number, D, C>, Expr<number, D, C>]): Expr<boolean, D, C>;
694
690
  };
695
691
  declare const lte: {
696
- <D, C>(...expr: [Expr<Date, D, C>, Expr<Date, D, C>]): Expr<boolean, D, C>;
697
- <D, C>(...expr: [Expr<number, D, C>, Expr<number, D, C>]): Expr<boolean, D, C>;
692
+ <D, C>(...expr: [Expr<Date | N, D, C>, Expr<Date | N, D, C>]): Expr<boolean, D, C>;
693
+ <D, C>(...expr: [Expr<number | N, D, C>, Expr<number | N, D, C>]): Expr<boolean, D, C>;
698
694
  };
699
695
  declare const gte: {
700
- <D, C>(...expr: [Expr<Date, D, C>, Expr<Date, D, C>]): Expr<boolean, D, C>;
701
- <D, C>(...expr: [Expr<number, D, C>, Expr<number, D, C>]): Expr<boolean, D, C>;
696
+ <D, C>(...expr: [Expr<Date | N, D, C>, Expr<Date | N, D, C>]): Expr<boolean, D, C>;
697
+ <D, C>(...expr: [Expr<number | N, D, C>, Expr<number | N, D, C>]): Expr<boolean, D, C>;
702
698
  };
703
699
  type Num = number | null | undefined;
704
700
  declare function subtract<D, C>(...expr: [Expr<number, D, C>, Expr<number, D, C>]): Expr<number, D, C>;
@@ -842,5 +838,5 @@ declare const enablePreAndPostImages: <T extends doc>(coll: Collection<T>) => Pr
842
838
  declare const prepare: (testName?: string) => Promise<MongoClient$1>;
843
839
  declare const makeCol: <T extends ID>(docs: readonly OptionalUnlessRequiredId<T>[], database: Db, name?: string) => Promise<Collection<T>>;
844
840
 
845
- export { $accumulator, $and, $countDict, $countDictArray, $entries, $eq, $exists, $expr, $getField, $group, $groupId, $groupMerge, $group_, $gt, $gtTs, $gte, $gteTs, $ifNull, $in, $insert, $insertPart, $insertX, $keys, $let, $lookup, $lt, $lte, $map, $map0, $map1, $match, $matchDelta, $merge, $merge2, $mergeId, $mergePart, $merge_, $ne, $nin, $nor, $or, $outerLookup, $pushDict, $rand, $reduce, $replaceWith, $set, $simpleInsert, $simpleMerge, $simpleMergePart, $substr, $sum, $type, $unwind, $unwindDelta, Expr, Field, Machine, Type, add, and, anyElementTrue, array, ceil, comp, concat, concatArray, createIndex, ctx, current, dateAdd, dateDiff, dateLt, datePart, dayAndMonthPart, divide, emptyDelta, enablePreAndPostImages, eq, eqExtends, eqPar, eqTyped, except, excludeIdem, exprMapVal, field, fieldF, fieldM, filter, filterDefined, first, firstSure, floor, from, fromEq, func, getWhenMatched, getWhenMatchedForMerge, gt, gte, inArray, isArray, ite, joinIdOf, last, literalsEqaul, log, lt, lte, makeCol, map, map1, mapExact, mapExact0, mapExact1, mapExactToObject, mapExactToObject0, mapExactToObject1, mapFromPlainDateTime, mapToPlainDateTime, mapVal, matchDelta, max, maxDate, mergeExact, mergeExact0, mergeExpr, mergeObjects, minDate, monthPart, multiply, ne, nil, noop, not, notExtendExcluded, notNull, now, omitExclude, omitPick, omitRORec, or, padLeft, pair, prepare, rand, range, reflex, regex, renamedFields, root, set, setField, single, size, slice, sortArray, spread, spread0, staging, startOf, str, sub, subtract, sym, to, toInt, translateOmit, val, weekPart, wrap, year };
841
+ export { $accumulator, $and, $countDict, $countDictArray, $entries, $eq, $exists, $expr, $getField, $group, $groupId, $groupMerge, $group_, $gt, $gtTs, $gte, $gteTs, $ifNull, $in, $insert, $insertPart, $insertX, $keys, $let, $lookup, $lt, $lte, $map, $map0, $map1, $match, $matchDelta, $merge, $merge2, $mergeId, $mergePart, $merge_, $ne, $nin, $nor, $or, $outerLookup, $pushDict, $rand, $reduce, $replaceWith, $set, $simpleInsert, $simpleMerge, $simpleMergePart, $substr, $sum, $type, $unwind, $unwindDelta, Expr, Field, Machine, Type, add, and, anyElementTrue, array, ceil, comp, concat, concatArray, createIndex, ctx, current, dateAdd, dateDiff, dateLt, datePart, dayAndMonthPart, divide, emptyDelta, enablePreAndPostImages, eq, eqExtends, eqPar, eqTyped, except, excludeIdem, exprMapVal, field, fieldF, fieldM, filter, filterDefined, first, firstSure, floor, from, fromEq, func, getWhenMatched, getWhenMatchedForMerge, gt, gte, inArray, isArray, ite, joinIdOf, last, literalsEqaul, log, lt, lte, makeCol, map, map1, mapExact, mapExact0, mapExact1, mapExactToObject, mapExactToObject0, mapExactToObject1, mapFromPlainDateTime, mapToPlainDateTime, mapVal, matchDelta, max, maxDate, mergeExact, mergeExact0, mergeExpr, mergeObjects, minDate, monthPart, multiply, ne, nil, noop, not, notNull, now, omitExclude, omitPick, omitRORec, or, padLeft, prepare, rand, range, reflex, regex, renamedFields, root, set, setField, single, size, slice, sortArray, spread, spread0, staging, startOf, str, sub, subtract, sym, to, toInt, translateOmit, val, weekPart, wrap, year };
846
842
  export type { Accumulators, AddO, And, App, AppMap, AppMapRW, ApplyHKT, Arr, ArrHKT, AsLiteral, ConstHKT, DeepFieldHKT, Delta, DeltaAccumulator, DeltaAccumulatorHKT, DeltaAccumulators, DeltaStages, Equal, Exact, ExactKeys, ExactPart, ExactPart1, ExprHKT, Exprs, ExprsExact, ExprsExactHKT, ExprsPart, FieldHKT, GroupCollection, GroupIdCollection, GroupMergeCollection, HKT, I, ID, IdHKT, JoinId, Loose, MapK, MapKDom, MapKPart1, MapO, MapOPart, MappedHKT, Merge, MergeArgs, MergeHKT, MergeInto, MergeMapOArgs, MergedInput, Model, MongoTypeNames, N, NullToOBJ, O, OPick, OPickD, Patch, PromiseHKT, RConstHKT, RORec, RWCollection, RawStages, Rec, RecHKT, RecordHKT, Replace, SnapshotStreamExecutionResult, StrKey, Strict, TS, UBeforeHKT, WithKey1, WriteonlyCollection, doc, jsonPrim, notArr, µ };
package/index.esm.js CHANGED
@@ -400,8 +400,6 @@ const fieldM = (expr, m) => asExpr({
400
400
  const mergeExact = (...[exprsExact1, exprsExact2]) => spread(exprsExact1, exprsExact2);
401
401
  const mergeExact0 = (...[exprsExact1, exprsExact2]) => spread0(exprsExact1, exprsExact2);
402
402
  const mergeExpr = (...exprs) => mergeExact(...exprs);
403
- const asIntersect = (x) => x;
404
- const pair = (k, v) => asIntersect([k, v]);
405
403
  const fieldF = () => (exprs) => Object.keys(exprs).length
406
404
  ? asExpr({
407
405
  raw: f => asExprRaw(mapExactToObject(exprs, e => e.raw(f).get())),
@@ -437,7 +435,6 @@ const renamedFields = () => assertEqual();
437
435
  const translateOmit = () => assertEqual();
438
436
  const excludeIdem = () => assertEqual();
439
437
  const eqPar = () => assertEqual();
440
- const notExtendExcluded = () => assertEqual();
441
438
 
442
439
  const size = (expr) => asExpr({
443
440
  raw: f => asExprRaw({ $size: expr.raw(f).get() }),
@@ -1162,48 +1159,12 @@ const joinIdOf = (k, k1, k1Id, k2Id) => {
1162
1159
  return concat(idOf(k[0]), val(k[1]), idOf(k[2]));
1163
1160
  };
1164
1161
  const andAlso = (probe, keep) => ite(eqTyped(probe, nil), nil, keep);
1165
- const notObjAndAlso = (probe, keep) => ite(eqTyped(probe, field({})), nil, keep);
1166
- const $unwindDelta = (k1, k2, k, includeNull1, includeNull2) => {
1162
+ const slotsMany = (k1, k2, k, emptyOf) => {
1167
1163
  const emptyArr = array();
1168
1164
  const src = root();
1169
1165
  const k2Arr = (side) => src.of(side).of(k2).expr();
1170
1166
  const k2OrEmpty = (side) => $ifNull(k2Arr(side), emptyArr);
1171
- const k2Empty = (side) => eq(k2Arr(side))(emptyArr);
1172
- const beforeItems = k2OrEmpty('before');
1173
- const afterItems = k2OrEmpty('after');
1174
- const beforeIds = $map1(beforeItems, (item) => item.of('_id').expr());
1175
- const newByK2Id = filter({
1176
- expr: afterItems,
1177
- as: 'a',
1178
- cond: not(inArray(ctx()('a').of('_id').expr(), beforeIds)),
1179
- });
1180
- const oldByK2Id = $map0({
1181
- input: beforeItems,
1182
- as: 'b',
1183
- expr: field({
1184
- before: ['before', ctx()('b').expr()],
1185
- after: [
1186
- 'after',
1187
- first$1(filter({
1188
- expr: afterItems,
1189
- as: 'a',
1190
- cond: eq(ctx()('a').of('_id').expr())(ctx()('b').of('_id').expr()),
1191
- })),
1192
- ],
1193
- }),
1194
- });
1195
- const k1Slot = (fill) => array(field({
1196
- before: [
1197
- 'before',
1198
- $ifNull(first$1(beforeItems), fill),
1199
- ],
1200
- after: [
1201
- 'after',
1202
- $ifNull(first$1(afterItems), fill),
1203
- ],
1204
- }));
1205
- const kept = k === k1 ? k1Slot(nil) : oldByK2Id;
1206
- const added = k === k1 ? emptyArr : newByK2Id;
1167
+ const k1Id = root().of('_id').expr();
1207
1168
  const k1Delta = field({
1208
1169
  before: [
1209
1170
  'before',
@@ -1213,154 +1174,132 @@ const $unwindDelta = (k1, k2, k, includeNull1, includeNull2) => {
1213
1174
  'after',
1214
1175
  $ifNull(src.of('after').of(k1).expr(), nil),
1215
1176
  ],
1177
+ deleted: ['deleted', src.of('deleted').expr()],
1216
1178
  });
1217
- const unwindJoin = ({ kept, added, padToNull, isPad, join, }) => {
1218
- const newDeltas = $map0({
1219
- input: added,
1220
- as: 'a',
1179
+ const itemId = (k2Id) => {
1180
+ const at = (key) => (key === k1 ? k1Id : k2Id);
1181
+ if (typeof k === 'string')
1182
+ return at(k);
1183
+ return concat(at(k[0]), val(k[1]), at(k[2]));
1184
+ };
1185
+ const keyed = (side) => {
1186
+ const items = ctx()('items').expr();
1187
+ return $let({ items: ['items', k2OrEmpty(side)] }, ite(eq(items)(emptyArr), emptyOf(k1Id), $map0({
1188
+ input: items,
1189
+ as: 'b',
1221
1190
  expr: field({
1222
- before: ['before', nil],
1223
- after: ['after', ctx()('a').expr()],
1191
+ _id: ['_id', itemId(ctx()('b').of('_id').expr())],
1192
+ value: ['value', ctx()('b').expr()],
1224
1193
  }),
1225
- });
1226
- const deltas = mergeObjects(field(map1(k1, k1Delta)), field(map1(k2, concatArray(kept, newDeltas))));
1227
- const doc = root();
1228
- const parentId = doc.of('_id').expr();
1229
- const k1At = (side) => doc.of(k1).of(side).expr();
1230
- const k2Raw = (side) => doc.of(k2).of(side).expr();
1231
- const docK2Null = root();
1232
- const k2Keep = (side) => docK2Null.of(k2).of(side).expr();
1233
- const k2At = (side) => padToNull(k2Raw(side), k2Keep(side));
1234
- const rowOf = (id, a, b) => mergeObjects(mergeObjects(field({ _id: ['_id', id] }), field(map1(k1, a))), field(map1(k2, b)));
1235
- const docK1 = root();
1236
- const k2RawK1 = (side) => docK1.of(k2).of(side).expr();
1237
- const k2KeepK1K2 = (side) => root().of(k2).of(side).expr();
1238
- const rowOnK1 = (side) => {
1239
- const t = docK1.of(k1).of(side);
1240
- return rowOf(t.of('_id').expr(), t.expr(), padToNull(k2RawK1(side), k2KeepK1K2(side)));
1241
- };
1242
- const docK2 = root();
1243
- const k1AtK2 = (side) => docK2.of(k1).of(side).expr();
1244
- const rowOnK2 = (side) => {
1245
- const u = docK2.of(k2).of(side);
1246
- return rowOf(u.of('_id').expr(), k1AtK2(side), u.expr());
1247
- };
1248
- const docK1K2 = root();
1249
- const k1AtK1K2 = (side) => docK1K2.of(k1).of(side).expr();
1250
- const k2AtK1K2 = (side) => docK1K2.of(k2).of(side).expr();
1251
- const k1IdK1K2 = (side) => docK1K2.of(k1).of(side).of('_id').expr();
1252
- const k2IdK1K2 = (side) => docK1K2.of(k2).of(side).of('_id').expr();
1253
- const completeId = (side) => joinIdOf(k, k1, k1IdK1K2(side), k2IdK1K2(side));
1254
- const rowK1K2 = (side) => rowOf(completeId(side), k1AtK1K2(side), k2AtK1K2(side));
1255
- const liftRowId = $replaceWith_(mergeObjects(root().expr(), field({
1256
- _id: [
1257
- '_id',
1258
- $ifNull(root()
1259
- .of('before')
1260
- .of('_id')
1261
- .expr(), root()
1262
- .of('after')
1263
- .of('_id')
1264
- .expr(), root().of('_id').expr()),
1265
- ],
1266
1194
  })));
1267
- const padded = (side) => isPad(k2Raw(side));
1268
- const emptyObj = field({});
1269
- const deletedFlags = mergeObjects(ite(padded('before'), field({ before: ['before', val(true)] }), emptyObj), ite(padded('after'), field({ after: ['after', val(true)] }), emptyObj));
1270
- const joinAt = (side) => join({
1271
- k1: k1At(side),
1272
- k2: k2At(side),
1273
- rowK1K2: rowK1K2(side),
1274
- rowOnK1: rowOnK1(side),
1275
- rowOnK2: rowOnK2(side),
1276
- k2Keep: k2Keep(side),
1277
- k2Raw: k2Raw(side),
1278
- k2RawK1: k2RawK1(side),
1279
- k2KeepK1K2: k2KeepK1K2(side),
1280
- });
1281
- const joinDelta = mergeObjects(field({
1282
- _id: ['_id', parentId],
1283
- before: ['before', joinAt('before')],
1284
- after: ['after', joinAt('after')],
1285
- }), ite(or(padded('before'), padded('after')), field({ deleted: ['deleted', deletedFlags] }), emptyObj));
1286
- return link()
1287
- .with($replaceWith_(mergeObjects(src.expr(), deltas)))
1288
- .with($unwind_(k2))
1289
- .with($replaceWith_(joinDelta))
1290
- .with(matchDelta())
1291
- .with(liftRowId).stages;
1292
1195
  };
1293
- const noPadToNull = (k2) => k2;
1294
- const neverPad = (_k2) => val(false);
1295
- if (includeNull2 === null) {
1296
- const padObj = field({});
1297
- const padDelta = (after) => field({
1298
- before: ['before', padObj],
1299
- after: ['after', after],
1300
- });
1301
- const addedPadded = k === k1
1302
- ? array()
1303
- : ite(and(not(k2Empty('before')), k2Empty('after')), array(padObj), added);
1304
- const padToNull = (k2, keep) => ite(eqTyped(k2, field({})), nil, keep);
1305
- const isPad = (k2) => ite(eqTyped(k2, field({})), val(true), val(false));
1306
- const keptMatched = ite(k2Empty('before'), ite(k2Empty('after'), array(padDelta(padObj)), array(padDelta(nil))), kept);
1307
- const padded = { added: addedPadded, padToNull, isPad };
1308
- if (includeNull1 === null) {
1309
- if (k === k1) {
1310
- return unwindJoin({
1311
- ...padded,
1312
- kept: k1Slot(padObj),
1313
- join: ({ k1: k1Val, rowOnK1 }) => andAlso(k1Val, rowOnK1),
1314
- });
1315
- }
1316
- if (k === k2) {
1317
- return unwindJoin({
1318
- ...padded,
1319
- kept: keptMatched,
1320
- join: ({ k2Raw, k2Keep, rowOnK2 }) => notObjAndAlso(k2Raw, andAlso(k2Keep, rowOnK2)),
1321
- });
1322
- }
1323
- return unwindJoin({
1324
- ...padded,
1325
- kept: keptMatched,
1326
- join: ({ k1: k1Val, k2RawK1, k2KeepK1K2, rowK1K2 }) => andAlso(k1Val, notObjAndAlso(k2RawK1, andAlso(k2KeepK1K2, rowK1K2))),
1327
- });
1328
- }
1329
- const eq2 = literalsEqaul();
1330
- if (k === k1) {
1331
- return unwindJoin({
1332
- ...padded,
1333
- kept: k1Slot(padObj),
1334
- join: ({ k1: k1Val, rowOnK1 }) => andAlso(k1Val, rowOnK1),
1335
- });
1196
+ const beforeKeyed = keyed('before');
1197
+ const afterKeyed = keyed('after');
1198
+ const bound = (name) => ctx()(name).expr();
1199
+ const idOf = (name) => ctx()(name).of('_id').expr();
1200
+ const valueOf = (name) => ctx()(name).of('value').expr();
1201
+ const kept = $map0({
1202
+ input: bound('beforeK'),
1203
+ as: 'b',
1204
+ expr: field({
1205
+ _id: ['_id', idOf('b')],
1206
+ before: ['before', valueOf('b')],
1207
+ after: [
1208
+ 'after',
1209
+ first$1($map0({
1210
+ input: filter({
1211
+ expr: bound('afterK'),
1212
+ as: 'a',
1213
+ limit: val(1),
1214
+ cond: eq(idOf('a'))(idOf('b')),
1215
+ }),
1216
+ as: 'a',
1217
+ expr: valueOf('a'),
1218
+ })),
1219
+ ],
1220
+ }),
1221
+ });
1222
+ const beforeIds = $map0({
1223
+ input: bound('beforeK'),
1224
+ as: 'id',
1225
+ expr: ctx()('id').of('_id').expr(),
1226
+ });
1227
+ const added = $map0({
1228
+ input: filter({
1229
+ expr: bound('afterK'),
1230
+ as: 'a',
1231
+ cond: not(inArray(idOf('a'), beforeIds)),
1232
+ }),
1233
+ as: 'a',
1234
+ expr: field({
1235
+ _id: ['_id', idOf('a')],
1236
+ before: ['before', nil],
1237
+ after: ['after', valueOf('a')],
1238
+ }),
1239
+ });
1240
+ const slots = $let({
1241
+ beforeK: ['beforeK', beforeKeyed],
1242
+ afterK: ['afterK', afterKeyed],
1243
+ }, concatArray(kept, added));
1244
+ const exclude = excludeIdem();
1245
+ return $replaceWith_(field(exclude.backward(mergeExpr(exclude.forward(map1(k2, slots)), map1(k1, k1Delta)))));
1246
+ };
1247
+ const noEmpty = (_id) => array();
1248
+ const padEmpty = (id) => array(field({
1249
+ _id: ['_id', id],
1250
+ value: ['value', field({})],
1251
+ }));
1252
+ const joinMany = (k1, k2, eq1, eq2) => {
1253
+ const doc = root();
1254
+ const id = () => root().of(k2).of('_id').expr();
1255
+ const k1At = (side) => doc.of(k1).of(side).expr();
1256
+ const rowOf = (a, b) => mergeObjects(mergeObjects(field({ _id: ['_id', id()] }), field(map1(k1, a))), field(map1(k2, b)));
1257
+ const rowPad = (k1v, n2) => {
1258
+ return rowOf(k1v, n2.forward(nil));
1259
+ };
1260
+ const rowReal = (k1v, k2v) => rowOf(k1v, k2v);
1261
+ const k2join = (raw, orNull, pad, real) => ite(eqTyped(raw, field({})), pad, andAlso(orNull, real));
1262
+ const joinAt = (side) => {
1263
+ const k2t = () => root().of(k2).of(side).expr();
1264
+ const k2w = () => root().of(k2).of(side).expr();
1265
+ if (!eq1) {
1266
+ const k1t = () => root().of(k1).of(side).expr();
1267
+ return andAlso(k1At(side), k2join(k2t(), k2t(), eq2 ? rowPad(k1t(), eq2) : nil, rowReal(k1t(), k2t())));
1336
1268
  }
1337
- return unwindJoin({
1338
- ...padded,
1339
- kept: keptMatched,
1340
- join: ({ k1: k1Val, k2RawK1, k2KeepK1K2, rowK1K2 }) => andAlso(k1Val, notObjAndAlso(k2RawK1, andAlso(k2KeepK1K2, eq2.forward(rowK1K2)))),
1341
- });
1342
- }
1343
- if (includeNull1 === null) {
1344
- const eq1 = literalsEqaul();
1345
- return unwindJoin({
1346
- kept,
1347
- added,
1348
- padToNull: noPadToNull,
1349
- isPad: neverPad,
1350
- join: ({ k1, k2: k2Val, k2KeepK1K2, rowK1K2, rowOnK2 }) => {
1351
- return k === k2
1352
- ? andAlso(k2Val, rowOnK2)
1353
- : andAlso(k1, andAlso(k2KeepK1K2, eq1.forward(rowK1K2)));
1354
- },
1355
- });
1356
- }
1357
- return unwindJoin({
1358
- kept,
1359
- added,
1360
- padToNull: noPadToNull,
1361
- isPad: neverPad,
1362
- join: ({ k1, k2KeepK1K2, rowK1K2 }) => andAlso(k1, andAlso(k2KeepK1K2, rowK1K2)),
1269
+ const k1v = () => {
1270
+ return $ifNull(root().of(k1).of(side).expr(), eq1.forward(nil));
1271
+ };
1272
+ return k2join(k2w(), k2w(), eq2 ? rowPad(k1v(), eq2) : nil, rowReal(k1v(), k2w()));
1273
+ };
1274
+ const isPad = (side) => ite(eq(doc.of(k2).of(side).expr())(field({})), val(true), doc.of(k1).of('deleted').of(side).expr());
1275
+ const joinDelta = field({
1276
+ _id: ['_id', id()],
1277
+ before: ['before', joinAt('before')],
1278
+ after: ['after', joinAt('after')],
1279
+ deleted: [
1280
+ 'deleted',
1281
+ field({
1282
+ before: ['before', isPad('before')],
1283
+ after: ['after', isPad('after')],
1284
+ }),
1285
+ ],
1363
1286
  });
1287
+ return $replaceWith_(joinDelta);
1288
+ };
1289
+ const $unwindDelta = (k1, k2, k, includeNull1, includeNull2) => {
1290
+ const stages = (emptyOf, eq1, eq2) => {
1291
+ return link()
1292
+ .with(slotsMany(k1, k2, k, emptyOf))
1293
+ .with($unwind_(k2))
1294
+ .with(joinMany(k1, k2, eq1, eq2))
1295
+ .with(matchDelta()).stages;
1296
+ };
1297
+ const run = (emptyOf) => stages(emptyOf, includeNull1 === null && literalsEqaul(), includeNull2 === null && literalsEqaul());
1298
+ if (k === k2)
1299
+ return run(noEmpty);
1300
+ if (includeNull2 === null)
1301
+ return run(padEmpty);
1302
+ return run(noEmpty);
1364
1303
  };
1365
1304
 
1366
1305
  const $unwind = (k, dict, middle = '.') => {
@@ -1397,7 +1336,10 @@ const $lookupDelta = ({ field1, field2 }, { coll, exec, input }, k1, k2, k, incl
1397
1336
  const normForeignKey = (f) => to($ifNull(root().of(f).of(k1).with(field1).expr(), val(hash)));
1398
1337
  return link()
1399
1338
  .with($replaceWithDelta(field(map1(k1, root().expr()))))
1400
- .with($set_(set()({ bId: ['bId', normForeignKey('before')], aId: ['aId', normForeignKey('after')] })))
1339
+ .with($set_(set()({
1340
+ bId: ['bId', normForeignKey('before')],
1341
+ aId: ['aId', normForeignKey('after')],
1342
+ })))
1401
1343
  .with($simpleLookup_({
1402
1344
  coll,
1403
1345
  k: 'a',
@@ -1419,15 +1361,21 @@ const $lookupDelta = ({ field1, field2 }, { coll, exec, input }, k1, k2, k, incl
1419
1361
  pipeline: link().with(input).with(exec).stages,
1420
1362
  }))
1421
1363
  .with($replaceWithEach((f) => {
1422
- const f1 = f === 'after' ? 'a' : 'b';
1423
- const a = root().of(f1).of('before').expr();
1424
- const part = root().of(f);
1425
- return ite(eq(root().of(f).expr())(nil), nil, field(omit.backward(mergeExpr(omit.forward(map1(k2, a)), map1(k1, part.of(k1).expr())))));
1364
+ const joined = (side, arr) => {
1365
+ const here = root();
1366
+ 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
1367
+ .of(side)
1368
+ .of(k1)
1369
+ .expr())))));
1370
+ };
1371
+ return f === 'after' ? joined('after', 'a') : joined('before', 'b');
1426
1372
  }))
1427
1373
  .with(includeNull1 === null
1428
- ? $replaceWithEach1((f) => {
1429
- const otherField = root().of(f === 'after' ? 'before' : 'after');
1430
- return $ifNull(root().of(f).expr(), field(omit.backward(mergeExpr(omit.forward(map1(k2, otherField.of(k2).expr())), map1(k1, nil)))));
1374
+ ? $replaceWithEach1((part) => {
1375
+ const otherPart = root().of(part === 'after' ? 'before' : 'after');
1376
+ const n1 = literalsEqaul().forward(nil);
1377
+ const expr = $ifNull(root().of(part).expr(), field(omit.backward(mergeExpr(omit.forward(map1(k2, otherPart.of(k2).expr())), map1(k1, n1)))));
1378
+ return expr;
1431
1379
  })
1432
1380
  : link().stages)
1433
1381
  .with($unwindDelta(k1, k2, k, includeNull1, includeNull2)).stages;
@@ -2474,4 +2422,4 @@ const makeCol = async (docs, database, name) => {
2474
2422
  }
2475
2423
  };
2476
2424
 
2477
- export { $accumulator, $and, $countDict, $countDictArray, $entries, $eq, $exists, $expr, $getField, $group, $groupId, $groupMerge, $group_, $gt, $gtTs, $gte, $gteTs, $ifNull, $in, $insert, $insertPart, $insertX, $keys, $let, $lookup, $lt, $lte, $map, $map0, $map1, $match, $matchDelta, $merge, $merge2, $mergeId, $mergePart, $merge_, $ne, $nin, $nor, $or, $outerLookup, $pushDict, $rand, $reduce, $replaceWith, $set, $simpleInsert, $simpleMerge, $simpleMergePart, $substr, $sum, $type, $unwind, $unwindDelta, Field, Machine, add, and, anyElementTrue, array, ceil, comp, concat, concatArray, createIndex, ctx, current, dateAdd, dateDiff, dateLt, datePart, dayAndMonthPart, divide, emptyDelta, enablePreAndPostImages, eq, eqExtends, eqPar, eqTyped, except, excludeIdem, exprMapVal, field, fieldF, fieldM, filter, filterDefined, first$1 as first, firstSure, floor, from, fromEq, func, getWhenMatched, getWhenMatchedForMerge, gt, gte, inArray, isArray, ite, joinIdOf, last, literalsEqaul, log, lt, lte, makeCol, map, map1, mapExact, mapExact0, mapExact1, mapExactToObject, mapExactToObject0, mapExactToObject1, mapFromPlainDateTime, mapToPlainDateTime, mapVal, matchDelta, max, maxDate, mergeExact, mergeExact0, mergeExpr, mergeObjects, minDate, monthPart, multiply, ne, nil, noop, not, notExtendExcluded, notNull, now, omitExclude, omitPick, omitRORec, or, padLeft, pair, prepare, rand, range, reflex, regex, renamedFields, root, set, setField, single, size, slice, sortArray, spread, spread0, staging, startOf, str, sub, subtract, sym, to, toInt, translateOmit, val, weekPart, wrap, year };
2425
+ export { $accumulator, $and, $countDict, $countDictArray, $entries, $eq, $exists, $expr, $getField, $group, $groupId, $groupMerge, $group_, $gt, $gtTs, $gte, $gteTs, $ifNull, $in, $insert, $insertPart, $insertX, $keys, $let, $lookup, $lt, $lte, $map, $map0, $map1, $match, $matchDelta, $merge, $merge2, $mergeId, $mergePart, $merge_, $ne, $nin, $nor, $or, $outerLookup, $pushDict, $rand, $reduce, $replaceWith, $set, $simpleInsert, $simpleMerge, $simpleMergePart, $substr, $sum, $type, $unwind, $unwindDelta, Field, Machine, add, and, anyElementTrue, array, ceil, comp, concat, concatArray, createIndex, ctx, current, dateAdd, dateDiff, dateLt, datePart, dayAndMonthPart, divide, emptyDelta, enablePreAndPostImages, eq, eqExtends, eqPar, eqTyped, except, excludeIdem, exprMapVal, field, fieldF, fieldM, filter, filterDefined, first$1 as first, firstSure, floor, from, fromEq, func, getWhenMatched, getWhenMatchedForMerge, gt, gte, inArray, isArray, ite, joinIdOf, last, literalsEqaul, log, lt, lte, makeCol, map, map1, mapExact, mapExact0, mapExact1, mapExactToObject, mapExactToObject0, mapExactToObject1, mapFromPlainDateTime, mapToPlainDateTime, mapVal, matchDelta, max, maxDate, mergeExact, mergeExact0, mergeExpr, mergeObjects, minDate, monthPart, multiply, ne, nil, noop, not, notNull, now, omitExclude, omitPick, omitRORec, or, padLeft, prepare, rand, range, reflex, regex, renamedFields, root, set, setField, single, size, slice, sortArray, spread, spread0, staging, startOf, str, sub, subtract, sym, to, toInt, translateOmit, val, weekPart, wrap, year };
package/index.js CHANGED
@@ -402,8 +402,6 @@ const fieldM = (expr, m) => asExpr({
402
402
  const mergeExact = (...[exprsExact1, exprsExact2]) => spread(exprsExact1, exprsExact2);
403
403
  const mergeExact0 = (...[exprsExact1, exprsExact2]) => spread0(exprsExact1, exprsExact2);
404
404
  const mergeExpr = (...exprs) => mergeExact(...exprs);
405
- const asIntersect = (x) => x;
406
- const pair = (k, v) => asIntersect([k, v]);
407
405
  const fieldF = () => (exprs) => Object.keys(exprs).length
408
406
  ? asExpr({
409
407
  raw: f => asExprRaw(mapExactToObject(exprs, e => e.raw(f).get())),
@@ -439,7 +437,6 @@ const renamedFields = () => assertEqual();
439
437
  const translateOmit = () => assertEqual();
440
438
  const excludeIdem = () => assertEqual();
441
439
  const eqPar = () => assertEqual();
442
- const notExtendExcluded = () => assertEqual();
443
440
 
444
441
  const size = (expr) => asExpr({
445
442
  raw: f => asExprRaw({ $size: expr.raw(f).get() }),
@@ -1164,48 +1161,12 @@ const joinIdOf = (k, k1, k1Id, k2Id) => {
1164
1161
  return concat(idOf(k[0]), val(k[1]), idOf(k[2]));
1165
1162
  };
1166
1163
  const andAlso = (probe, keep) => ite(eqTyped(probe, nil), nil, keep);
1167
- const notObjAndAlso = (probe, keep) => ite(eqTyped(probe, field({})), nil, keep);
1168
- const $unwindDelta = (k1, k2, k, includeNull1, includeNull2) => {
1164
+ const slotsMany = (k1, k2, k, emptyOf) => {
1169
1165
  const emptyArr = array();
1170
1166
  const src = root();
1171
1167
  const k2Arr = (side) => src.of(side).of(k2).expr();
1172
1168
  const k2OrEmpty = (side) => $ifNull(k2Arr(side), emptyArr);
1173
- const k2Empty = (side) => eq(k2Arr(side))(emptyArr);
1174
- const beforeItems = k2OrEmpty('before');
1175
- const afterItems = k2OrEmpty('after');
1176
- const beforeIds = $map1(beforeItems, (item) => item.of('_id').expr());
1177
- const newByK2Id = filter({
1178
- expr: afterItems,
1179
- as: 'a',
1180
- cond: not(inArray(ctx()('a').of('_id').expr(), beforeIds)),
1181
- });
1182
- const oldByK2Id = $map0({
1183
- input: beforeItems,
1184
- as: 'b',
1185
- expr: field({
1186
- before: ['before', ctx()('b').expr()],
1187
- after: [
1188
- 'after',
1189
- first$1(filter({
1190
- expr: afterItems,
1191
- as: 'a',
1192
- cond: eq(ctx()('a').of('_id').expr())(ctx()('b').of('_id').expr()),
1193
- })),
1194
- ],
1195
- }),
1196
- });
1197
- const k1Slot = (fill) => array(field({
1198
- before: [
1199
- 'before',
1200
- $ifNull(first$1(beforeItems), fill),
1201
- ],
1202
- after: [
1203
- 'after',
1204
- $ifNull(first$1(afterItems), fill),
1205
- ],
1206
- }));
1207
- const kept = k === k1 ? k1Slot(nil) : oldByK2Id;
1208
- const added = k === k1 ? emptyArr : newByK2Id;
1169
+ const k1Id = root().of('_id').expr();
1209
1170
  const k1Delta = field({
1210
1171
  before: [
1211
1172
  'before',
@@ -1215,154 +1176,132 @@ const $unwindDelta = (k1, k2, k, includeNull1, includeNull2) => {
1215
1176
  'after',
1216
1177
  $ifNull(src.of('after').of(k1).expr(), nil),
1217
1178
  ],
1179
+ deleted: ['deleted', src.of('deleted').expr()],
1218
1180
  });
1219
- const unwindJoin = ({ kept, added, padToNull, isPad, join, }) => {
1220
- const newDeltas = $map0({
1221
- input: added,
1222
- as: 'a',
1181
+ const itemId = (k2Id) => {
1182
+ const at = (key) => (key === k1 ? k1Id : k2Id);
1183
+ if (typeof k === 'string')
1184
+ return at(k);
1185
+ return concat(at(k[0]), val(k[1]), at(k[2]));
1186
+ };
1187
+ const keyed = (side) => {
1188
+ const items = ctx()('items').expr();
1189
+ return $let({ items: ['items', k2OrEmpty(side)] }, ite(eq(items)(emptyArr), emptyOf(k1Id), $map0({
1190
+ input: items,
1191
+ as: 'b',
1223
1192
  expr: field({
1224
- before: ['before', nil],
1225
- after: ['after', ctx()('a').expr()],
1193
+ _id: ['_id', itemId(ctx()('b').of('_id').expr())],
1194
+ value: ['value', ctx()('b').expr()],
1226
1195
  }),
1227
- });
1228
- const deltas = mergeObjects(field(map1(k1, k1Delta)), field(map1(k2, concatArray(kept, newDeltas))));
1229
- const doc = root();
1230
- const parentId = doc.of('_id').expr();
1231
- const k1At = (side) => doc.of(k1).of(side).expr();
1232
- const k2Raw = (side) => doc.of(k2).of(side).expr();
1233
- const docK2Null = root();
1234
- const k2Keep = (side) => docK2Null.of(k2).of(side).expr();
1235
- const k2At = (side) => padToNull(k2Raw(side), k2Keep(side));
1236
- const rowOf = (id, a, b) => mergeObjects(mergeObjects(field({ _id: ['_id', id] }), field(map1(k1, a))), field(map1(k2, b)));
1237
- const docK1 = root();
1238
- const k2RawK1 = (side) => docK1.of(k2).of(side).expr();
1239
- const k2KeepK1K2 = (side) => root().of(k2).of(side).expr();
1240
- const rowOnK1 = (side) => {
1241
- const t = docK1.of(k1).of(side);
1242
- return rowOf(t.of('_id').expr(), t.expr(), padToNull(k2RawK1(side), k2KeepK1K2(side)));
1243
- };
1244
- const docK2 = root();
1245
- const k1AtK2 = (side) => docK2.of(k1).of(side).expr();
1246
- const rowOnK2 = (side) => {
1247
- const u = docK2.of(k2).of(side);
1248
- return rowOf(u.of('_id').expr(), k1AtK2(side), u.expr());
1249
- };
1250
- const docK1K2 = root();
1251
- const k1AtK1K2 = (side) => docK1K2.of(k1).of(side).expr();
1252
- const k2AtK1K2 = (side) => docK1K2.of(k2).of(side).expr();
1253
- const k1IdK1K2 = (side) => docK1K2.of(k1).of(side).of('_id').expr();
1254
- const k2IdK1K2 = (side) => docK1K2.of(k2).of(side).of('_id').expr();
1255
- const completeId = (side) => joinIdOf(k, k1, k1IdK1K2(side), k2IdK1K2(side));
1256
- const rowK1K2 = (side) => rowOf(completeId(side), k1AtK1K2(side), k2AtK1K2(side));
1257
- const liftRowId = $replaceWith_(mergeObjects(root().expr(), field({
1258
- _id: [
1259
- '_id',
1260
- $ifNull(root()
1261
- .of('before')
1262
- .of('_id')
1263
- .expr(), root()
1264
- .of('after')
1265
- .of('_id')
1266
- .expr(), root().of('_id').expr()),
1267
- ],
1268
1196
  })));
1269
- const padded = (side) => isPad(k2Raw(side));
1270
- const emptyObj = field({});
1271
- const deletedFlags = mergeObjects(ite(padded('before'), field({ before: ['before', val(true)] }), emptyObj), ite(padded('after'), field({ after: ['after', val(true)] }), emptyObj));
1272
- const joinAt = (side) => join({
1273
- k1: k1At(side),
1274
- k2: k2At(side),
1275
- rowK1K2: rowK1K2(side),
1276
- rowOnK1: rowOnK1(side),
1277
- rowOnK2: rowOnK2(side),
1278
- k2Keep: k2Keep(side),
1279
- k2Raw: k2Raw(side),
1280
- k2RawK1: k2RawK1(side),
1281
- k2KeepK1K2: k2KeepK1K2(side),
1282
- });
1283
- const joinDelta = mergeObjects(field({
1284
- _id: ['_id', parentId],
1285
- before: ['before', joinAt('before')],
1286
- after: ['after', joinAt('after')],
1287
- }), ite(or(padded('before'), padded('after')), field({ deleted: ['deleted', deletedFlags] }), emptyObj));
1288
- return link()
1289
- .with($replaceWith_(mergeObjects(src.expr(), deltas)))
1290
- .with($unwind_(k2))
1291
- .with($replaceWith_(joinDelta))
1292
- .with(matchDelta())
1293
- .with(liftRowId).stages;
1294
1197
  };
1295
- const noPadToNull = (k2) => k2;
1296
- const neverPad = (_k2) => val(false);
1297
- if (includeNull2 === null) {
1298
- const padObj = field({});
1299
- const padDelta = (after) => field({
1300
- before: ['before', padObj],
1301
- after: ['after', after],
1302
- });
1303
- const addedPadded = k === k1
1304
- ? array()
1305
- : ite(and(not(k2Empty('before')), k2Empty('after')), array(padObj), added);
1306
- const padToNull = (k2, keep) => ite(eqTyped(k2, field({})), nil, keep);
1307
- const isPad = (k2) => ite(eqTyped(k2, field({})), val(true), val(false));
1308
- const keptMatched = ite(k2Empty('before'), ite(k2Empty('after'), array(padDelta(padObj)), array(padDelta(nil))), kept);
1309
- const padded = { added: addedPadded, padToNull, isPad };
1310
- if (includeNull1 === null) {
1311
- if (k === k1) {
1312
- return unwindJoin({
1313
- ...padded,
1314
- kept: k1Slot(padObj),
1315
- join: ({ k1: k1Val, rowOnK1 }) => andAlso(k1Val, rowOnK1),
1316
- });
1317
- }
1318
- if (k === k2) {
1319
- return unwindJoin({
1320
- ...padded,
1321
- kept: keptMatched,
1322
- join: ({ k2Raw, k2Keep, rowOnK2 }) => notObjAndAlso(k2Raw, andAlso(k2Keep, rowOnK2)),
1323
- });
1324
- }
1325
- return unwindJoin({
1326
- ...padded,
1327
- kept: keptMatched,
1328
- join: ({ k1: k1Val, k2RawK1, k2KeepK1K2, rowK1K2 }) => andAlso(k1Val, notObjAndAlso(k2RawK1, andAlso(k2KeepK1K2, rowK1K2))),
1329
- });
1330
- }
1331
- const eq2 = literalsEqaul();
1332
- if (k === k1) {
1333
- return unwindJoin({
1334
- ...padded,
1335
- kept: k1Slot(padObj),
1336
- join: ({ k1: k1Val, rowOnK1 }) => andAlso(k1Val, rowOnK1),
1337
- });
1198
+ const beforeKeyed = keyed('before');
1199
+ const afterKeyed = keyed('after');
1200
+ const bound = (name) => ctx()(name).expr();
1201
+ const idOf = (name) => ctx()(name).of('_id').expr();
1202
+ const valueOf = (name) => ctx()(name).of('value').expr();
1203
+ const kept = $map0({
1204
+ input: bound('beforeK'),
1205
+ as: 'b',
1206
+ expr: field({
1207
+ _id: ['_id', idOf('b')],
1208
+ before: ['before', valueOf('b')],
1209
+ after: [
1210
+ 'after',
1211
+ first$1($map0({
1212
+ input: filter({
1213
+ expr: bound('afterK'),
1214
+ as: 'a',
1215
+ limit: val(1),
1216
+ cond: eq(idOf('a'))(idOf('b')),
1217
+ }),
1218
+ as: 'a',
1219
+ expr: valueOf('a'),
1220
+ })),
1221
+ ],
1222
+ }),
1223
+ });
1224
+ const beforeIds = $map0({
1225
+ input: bound('beforeK'),
1226
+ as: 'id',
1227
+ expr: ctx()('id').of('_id').expr(),
1228
+ });
1229
+ const added = $map0({
1230
+ input: filter({
1231
+ expr: bound('afterK'),
1232
+ as: 'a',
1233
+ cond: not(inArray(idOf('a'), beforeIds)),
1234
+ }),
1235
+ as: 'a',
1236
+ expr: field({
1237
+ _id: ['_id', idOf('a')],
1238
+ before: ['before', nil],
1239
+ after: ['after', valueOf('a')],
1240
+ }),
1241
+ });
1242
+ const slots = $let({
1243
+ beforeK: ['beforeK', beforeKeyed],
1244
+ afterK: ['afterK', afterKeyed],
1245
+ }, concatArray(kept, added));
1246
+ const exclude = excludeIdem();
1247
+ return $replaceWith_(field(exclude.backward(mergeExpr(exclude.forward(map1(k2, slots)), map1(k1, k1Delta)))));
1248
+ };
1249
+ const noEmpty = (_id) => array();
1250
+ const padEmpty = (id) => array(field({
1251
+ _id: ['_id', id],
1252
+ value: ['value', field({})],
1253
+ }));
1254
+ const joinMany = (k1, k2, eq1, eq2) => {
1255
+ const doc = root();
1256
+ const id = () => root().of(k2).of('_id').expr();
1257
+ const k1At = (side) => doc.of(k1).of(side).expr();
1258
+ const rowOf = (a, b) => mergeObjects(mergeObjects(field({ _id: ['_id', id()] }), field(map1(k1, a))), field(map1(k2, b)));
1259
+ const rowPad = (k1v, n2) => {
1260
+ return rowOf(k1v, n2.forward(nil));
1261
+ };
1262
+ const rowReal = (k1v, k2v) => rowOf(k1v, k2v);
1263
+ const k2join = (raw, orNull, pad, real) => ite(eqTyped(raw, field({})), pad, andAlso(orNull, real));
1264
+ const joinAt = (side) => {
1265
+ const k2t = () => root().of(k2).of(side).expr();
1266
+ const k2w = () => root().of(k2).of(side).expr();
1267
+ if (!eq1) {
1268
+ const k1t = () => root().of(k1).of(side).expr();
1269
+ return andAlso(k1At(side), k2join(k2t(), k2t(), eq2 ? rowPad(k1t(), eq2) : nil, rowReal(k1t(), k2t())));
1338
1270
  }
1339
- return unwindJoin({
1340
- ...padded,
1341
- kept: keptMatched,
1342
- join: ({ k1: k1Val, k2RawK1, k2KeepK1K2, rowK1K2 }) => andAlso(k1Val, notObjAndAlso(k2RawK1, andAlso(k2KeepK1K2, eq2.forward(rowK1K2)))),
1343
- });
1344
- }
1345
- if (includeNull1 === null) {
1346
- const eq1 = literalsEqaul();
1347
- return unwindJoin({
1348
- kept,
1349
- added,
1350
- padToNull: noPadToNull,
1351
- isPad: neverPad,
1352
- join: ({ k1, k2: k2Val, k2KeepK1K2, rowK1K2, rowOnK2 }) => {
1353
- return k === k2
1354
- ? andAlso(k2Val, rowOnK2)
1355
- : andAlso(k1, andAlso(k2KeepK1K2, eq1.forward(rowK1K2)));
1356
- },
1357
- });
1358
- }
1359
- return unwindJoin({
1360
- kept,
1361
- added,
1362
- padToNull: noPadToNull,
1363
- isPad: neverPad,
1364
- join: ({ k1, k2KeepK1K2, rowK1K2 }) => andAlso(k1, andAlso(k2KeepK1K2, rowK1K2)),
1271
+ const k1v = () => {
1272
+ return $ifNull(root().of(k1).of(side).expr(), eq1.forward(nil));
1273
+ };
1274
+ return k2join(k2w(), k2w(), eq2 ? rowPad(k1v(), eq2) : nil, rowReal(k1v(), k2w()));
1275
+ };
1276
+ const isPad = (side) => ite(eq(doc.of(k2).of(side).expr())(field({})), val(true), doc.of(k1).of('deleted').of(side).expr());
1277
+ const joinDelta = field({
1278
+ _id: ['_id', id()],
1279
+ before: ['before', joinAt('before')],
1280
+ after: ['after', joinAt('after')],
1281
+ deleted: [
1282
+ 'deleted',
1283
+ field({
1284
+ before: ['before', isPad('before')],
1285
+ after: ['after', isPad('after')],
1286
+ }),
1287
+ ],
1365
1288
  });
1289
+ return $replaceWith_(joinDelta);
1290
+ };
1291
+ const $unwindDelta = (k1, k2, k, includeNull1, includeNull2) => {
1292
+ const stages = (emptyOf, eq1, eq2) => {
1293
+ return link()
1294
+ .with(slotsMany(k1, k2, k, emptyOf))
1295
+ .with($unwind_(k2))
1296
+ .with(joinMany(k1, k2, eq1, eq2))
1297
+ .with(matchDelta()).stages;
1298
+ };
1299
+ const run = (emptyOf) => stages(emptyOf, includeNull1 === null && literalsEqaul(), includeNull2 === null && literalsEqaul());
1300
+ if (k === k2)
1301
+ return run(noEmpty);
1302
+ if (includeNull2 === null)
1303
+ return run(padEmpty);
1304
+ return run(noEmpty);
1366
1305
  };
1367
1306
 
1368
1307
  const $unwind = (k, dict, middle = '.') => {
@@ -1399,7 +1338,10 @@ const $lookupDelta = ({ field1, field2 }, { coll, exec, input }, k1, k2, k, incl
1399
1338
  const normForeignKey = (f) => to($ifNull(root().of(f).of(k1).with(field1).expr(), val(hash)));
1400
1339
  return link()
1401
1340
  .with($replaceWithDelta(field(map1(k1, root().expr()))))
1402
- .with($set_(set()({ bId: ['bId', normForeignKey('before')], aId: ['aId', normForeignKey('after')] })))
1341
+ .with($set_(set()({
1342
+ bId: ['bId', normForeignKey('before')],
1343
+ aId: ['aId', normForeignKey('after')],
1344
+ })))
1403
1345
  .with($simpleLookup_({
1404
1346
  coll,
1405
1347
  k: 'a',
@@ -1421,15 +1363,21 @@ const $lookupDelta = ({ field1, field2 }, { coll, exec, input }, k1, k2, k, incl
1421
1363
  pipeline: link().with(input).with(exec).stages,
1422
1364
  }))
1423
1365
  .with($replaceWithEach((f) => {
1424
- const f1 = f === 'after' ? 'a' : 'b';
1425
- const a = root().of(f1).of('before').expr();
1426
- const part = root().of(f);
1427
- return ite(eq(root().of(f).expr())(nil), nil, field(omit.backward(mergeExpr(omit.forward(map1(k2, a)), map1(k1, part.of(k1).expr())))));
1366
+ const joined = (side, arr) => {
1367
+ const here = root();
1368
+ 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
1369
+ .of(side)
1370
+ .of(k1)
1371
+ .expr())))));
1372
+ };
1373
+ return f === 'after' ? joined('after', 'a') : joined('before', 'b');
1428
1374
  }))
1429
1375
  .with(includeNull1 === null
1430
- ? $replaceWithEach1((f) => {
1431
- const otherField = root().of(f === 'after' ? 'before' : 'after');
1432
- return $ifNull(root().of(f).expr(), field(omit.backward(mergeExpr(omit.forward(map1(k2, otherField.of(k2).expr())), map1(k1, nil)))));
1376
+ ? $replaceWithEach1((part) => {
1377
+ const otherPart = root().of(part === 'after' ? 'before' : 'after');
1378
+ const n1 = literalsEqaul().forward(nil);
1379
+ const expr = $ifNull(root().of(part).expr(), field(omit.backward(mergeExpr(omit.forward(map1(k2, otherPart.of(k2).expr())), map1(k1, n1)))));
1380
+ return expr;
1433
1381
  })
1434
1382
  : link().stages)
1435
1383
  .with($unwindDelta(k1, k2, k, includeNull1, includeNull2)).stages;
@@ -2609,7 +2557,6 @@ exports.ne = ne;
2609
2557
  exports.nil = nil;
2610
2558
  exports.noop = noop;
2611
2559
  exports.not = not;
2612
- exports.notExtendExcluded = notExtendExcluded;
2613
2560
  exports.notNull = notNull;
2614
2561
  exports.now = now;
2615
2562
  exports.omitExclude = omitExclude;
@@ -2617,7 +2564,6 @@ exports.omitPick = omitPick;
2617
2564
  exports.omitRORec = omitRORec;
2618
2565
  exports.or = or;
2619
2566
  exports.padLeft = padLeft;
2620
- exports.pair = pair;
2621
2567
  exports.prepare = prepare;
2622
2568
  exports.rand = rand;
2623
2569
  exports.range = range;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "module": "index.esm.js",
4
4
  "typings": "index.d.ts",
5
5
  "name": "@omegup/msync",
6
- "version": "0.1.53",
6
+ "version": "0.1.54",
7
7
  "dependencies": {
8
8
  "dayjs": "^1.11.9",
9
9
  "dotenv": "^16.3.1",