UNPKG

@electric-sql/d2ts

Version:

D2TS is a TypeScript implementation of Differential Dataflow.

77 lines 3.69 kB
import { reduce } from './reduce.js'; import { MultiSet } from '../../multiset.js'; import { SQLiteContext } from '../context.js'; /** * Limits the number of results based on a comparator, with optional offset. * This works on a keyed stream, where the key is the first element of the tuple * The ordering is withing a key group, i.e. elements are sorted within a key group * and the limit + offset is applied to that sorted group. * To order the entire stream, key by the same value for all elements such as null. * * @param comparator - A function that compares two elements * @param db - Optional SQLite database (can be injected via context) * @param options - An optional object containing limit and offset properties * @returns A piped operator that limits the number of results */ export function topK(comparator, options) { const limit = options?.limit ?? Infinity; const offset = options?.offset ?? 0; return (stream) => { // Get database from context if not provided explicitly const database = options?.db || SQLiteContext.getDb(); if (!database) { throw new Error('SQLite database is required for topK operator. ' + 'Provide it as a parameter or use withSQLite() to inject it.'); } const reduced = stream.pipe(reduce((values) => { // `values` is a list of tuples, first element is the value, second is the multiplicity const consolidated = new MultiSet(values).consolidate(); const sortedValues = consolidated .getInner() .sort((a, b) => comparator(a[0], b[0])); return sortedValues.slice(offset, offset + limit); }, database)); return reduced; }; } /** * Limits the number of results based on a comparator, with optional offset. * This works on a keyed stream, where the key is the first element of the tuple * The ordering is withing a key group, i.e. elements are sorted within a key group * and the limit + offset is applied to that sorted group. * To order the entire stream, key by the same value for all elements such as null. * Adds the index of the element to the result as [key, [value, index]] * * @param comparator - A function that compares two elements * @param db - Optional SQLite database (can be injected via context) * @param options - An optional object containing limit and offset properties * @returns A piped operator that orders the elements and limits the number of results */ export function topKWithIndex(comparator, options) { const limit = options?.limit ?? Infinity; const offset = options?.offset ?? 0; return (stream) => { // Get database from context if not provided explicitly const database = options?.db || SQLiteContext.getDb(); if (!database) { throw new Error('SQLite database is required for topKWithIndex operator. ' + 'Provide it as a parameter or use withSQLite() to inject it.'); } const reduced = stream.pipe(reduce((values) => { // `values` is a list of tuples, first element is the value, second is the multiplicity const consolidated = new MultiSet(values).consolidate(); let i = offset; const sortedValues = consolidated .getInner() .sort((a, b) => comparator(a[0], b[0])) .slice(offset, offset + limit) .map(([value, multiplicity]) => [ [value, i++], multiplicity, ]); return sortedValues; }, database)); return reduced; }; } //# sourceMappingURL=topK.js.map