UNPKG

@tanstack/db-ivm

Version:

Incremental View Maintenance for TanStack DB based on Differential Dataflow

146 lines (145 loc) 4.7 kB
"use strict"; var __typeError = (msg) => { throw TypeError(msg); }; var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg); var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)); var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value); var _indexA, _indexB; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const graph = require("../graph.cjs"); const d2 = require("../d2.cjs"); const multiset = require("../multiset.cjs"); const indexes = require("../indexes.cjs"); const negate = require("./negate.cjs"); const map = require("./map.cjs"); const concat = require("./concat.cjs"); class JoinOperator extends graph.BinaryOperator { constructor(id, inputA, inputB, output) { super(id, inputA, inputB, output); __privateAdd(this, _indexA, new indexes.Index()); __privateAdd(this, _indexB, new indexes.Index()); } run() { const deltaA = new indexes.Index(); const deltaB = new indexes.Index(); const messagesA = this.inputAMessages(); for (const message of messagesA) { const multiSetMessage = message; for (const [item, multiplicity] of multiSetMessage.getInner()) { const [key, value] = item; deltaA.addValue(key, [value, multiplicity]); } } const messagesB = this.inputBMessages(); for (const message of messagesB) { const multiSetMessage = message; for (const [item, multiplicity] of multiSetMessage.getInner()) { const [key, value] = item; deltaB.addValue(key, [value, multiplicity]); } } const results = new multiset.MultiSet(); results.extend(deltaA.join(__privateGet(this, _indexB))); __privateGet(this, _indexA).append(deltaA); results.extend(__privateGet(this, _indexA).join(deltaB)); if (results.getInner().length > 0) { this.output.sendData(results); } __privateGet(this, _indexB).append(deltaB); } } _indexA = new WeakMap(); _indexB = new WeakMap(); function join(other, type = `inner`) { switch (type) { case `inner`: return innerJoin(other); case `anti`: return antiJoin(other); case `left`: return leftJoin(other); case `right`: return rightJoin(other); case `full`: return fullJoin(other); default: throw new Error(`Join type ${type} is invalid`); } } function innerJoin(other) { return (stream) => { if (stream.graph !== other.graph) { throw new Error(`Cannot join streams from different graphs`); } const output = new d2.StreamBuilder( stream.graph, new graph.DifferenceStreamWriter() ); const operator = new JoinOperator( stream.graph.getNextOperatorId(), stream.connectReader(), other.connectReader(), output.writer ); stream.graph.addOperator(operator); stream.graph.addStream(output.connectReader()); return output; }; } function antiJoin(other) { return (stream) => { const matchedLeft = stream.pipe( innerJoin(other), map.map(([key, [valueLeft, _valueRight]]) => [key, valueLeft]) ); const anti = stream.pipe( concat.concat(matchedLeft.pipe(negate.negate())), // @ts-ignore TODO: fix this map.map(([key, value]) => [key, [value, null]]) ); return anti; }; } function leftJoin(other) { return (stream) => { const left = stream; const right = other; const inner = left.pipe(innerJoin(right)); const anti = left.pipe(antiJoin(right)); return inner.pipe(concat.concat(anti)); }; } function rightJoin(other) { return (stream) => { const left = stream; const right = other; const inner = left.pipe(innerJoin(right)); const anti = right.pipe( antiJoin(left), map.map(([key, [a, b]]) => [key, [b, a]]) ); return inner.pipe(concat.concat(anti)); }; } function fullJoin(other) { return (stream) => { const left = stream; const right = other; const inner = left.pipe(innerJoin(right)); const antiLeft = left.pipe(antiJoin(right)); const antiRight = right.pipe( antiJoin(left), map.map(([key, [a, b]]) => [key, [b, a]]) ); return inner.pipe(concat.concat(antiLeft), concat.concat(antiRight)); }; } exports.JoinOperator = JoinOperator; exports.antiJoin = antiJoin; exports.fullJoin = fullJoin; exports.innerJoin = innerJoin; exports.join = join; exports.leftJoin = leftJoin; exports.rightJoin = rightJoin; //# sourceMappingURL=join.cjs.map