UNPKG

@drip_sync/drip

Version:

Scalable incremental sync for MongoDB aggregation pipelines

50 lines (49 loc) 2.15 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.updateDescriptionToU = updateDescriptionToU; const assert_1 = require("assert"); const zod_1 = __importDefault(require("zod")); function switchTo(u, path) { let cur = u; for (const c of path) { if (!(c in cur)) { cur[c] = {}; } const res = cur[c]; (0, assert_1.strict)(typeof res === "object" && res !== null); cur = res; } return cur; } function getDisambiguatedPath(field, dapaths) { return (zod_1.default.array(zod_1.default.string().or(zod_1.default.number())).optional().parse(dapaths[field]) ?? field.split(".")); } // The storage format here is inspired heavily by the // undocumented oplog entry format of MongoDB itself. // An unofficial effort to document it can be found at // https://github.com/meteor/meteor/blob/7da5b32d7882b510df8aa2002f891fc4e1ae1126/packages/mongo/oplog_v2_converter.js // Most notably, it does not differentiate between // updates to existing fields vs insertion of new field, // as well as array keys (integers) vs string keys. // Additionally, it supports array truncations as a primitive. function updateDescriptionToU(upd) { const res = {}; const dapaths = upd.disambiguatedPaths ?? {}; for (const field of upd.removedFields ?? []) { const path = getDisambiguatedPath(field, dapaths); switchTo(res, [...path.slice(0, -1).map((c) => `s${c}`), "d"])[path[path.length - 1]] = false; } for (const { field, newSize } of upd.truncatedArrays ?? []) { const path = getDisambiguatedPath(field, dapaths); switchTo(res, [...path.slice(0, -1).map((c) => `s${c}`), "t"])[path[path.length - 1]] = newSize; } for (const [field, val] of Object.entries(upd.updatedFields ?? {})) { const path = getDisambiguatedPath(field, dapaths); switchTo(res, [...path.slice(0, -1).map((c) => `s${c}`), "i"])[path[path.length - 1]] = val; } return res; }