@electric-sql/d2ts
Version:
D2TS is a TypeScript implementation of Differential Dataflow.
58 lines • 2.54 kB
JavaScript
import { MessageType, } from '../types.js';
import { DifferenceStreamWriter, UnaryOperator } from '../graph.js';
import { StreamBuilder } from '../d2.js';
import { MultiSet } from '../multiset.js';
import { DefaultMap } from '../utils.js';
/**
* Operator that buffers collections at each version
* Ensured that completed versions are sent to the output as a whole, and in order
*/
export class BufferOperator extends UnaryOperator {
#collections = new DefaultMap(() => new MultiSet());
run() {
for (const message of this.inputMessages()) {
if (message.type === MessageType.DATA) {
const { version, collection } = message.data;
this.#collections.update(version, (existing) => {
existing.extend(collection);
return existing;
});
}
else if (message.type === MessageType.FRONTIER) {
const frontier = message.data;
if (!this.inputFrontier().lessEqual(frontier)) {
throw new Error('Invalid frontier update');
}
this.setInputFrontier(frontier);
}
}
// Find versions that are complete (not covered by input frontier)
const finishedVersions = Array.from(this.#collections.entries()).filter(([version]) => !this.inputFrontier().lessEqualVersion(version));
// Process and remove finished versions
for (const [version, collection] of finishedVersions) {
this.#collections.delete(version);
this.output.sendData(version, collection);
}
if (!this.outputFrontier.lessEqual(this.inputFrontier())) {
throw new Error('Invalid frontier state');
}
if (this.outputFrontier.lessThan(this.inputFrontier())) {
this.outputFrontier = this.inputFrontier();
this.output.sendFrontier(this.outputFrontier);
}
}
}
/**
* Buffers the elements in the stream
* Ensured that completed versions are sent to the output as a whole, and in order
*/
export function buffer() {
return (stream) => {
const output = new StreamBuilder(stream.graph, new DifferenceStreamWriter());
const operator = new BufferOperator(stream.graph.getNextOperatorId(), stream.connectReader(), output.writer, stream.graph.frontier());
stream.graph.addOperator(operator);
stream.graph.addStream(output.connectReader());
return output;
};
}
//# sourceMappingURL=buffer.js.map