import { assert } from "../../../shared/src/asserts.js";
import { throwOutput } from "./operator.js";
import { maybeSplitAndPushEditChange } from "./maybe-split-and-push-edit-change.js";
//#region ../zql/src/ivm/skip.ts
/**
* Skip sets the start position for the pipeline. No rows before the bound will
* be output.
*/
var Skip = class {
	#input;
	#bound;
	#comparator;
	#output = throwOutput;
	constructor(input, bound) {
		const { sort } = input.getSchema();
		assert(sort !== void 0, "Skip requires sorted input");
		this.#input = input;
		this.#bound = bound;
		this.#comparator = input.getSchema().compareRows;
		input.setOutput(this);
	}
	getSchema() {
		return this.#input.getSchema();
	}
	*fetch(req) {
		const start = this.#getStart(req);
		if (start === "empty") return;
		const nodes = this.#input.fetch({
			...req,
			start
		});
		if (!req.reverse) {
			yield* nodes;
			return;
		}
		for (const node of nodes) {
			if (node === "yield") {
				yield node;
				continue;
			}
			if (!this.#shouldBePresent(node.row)) return;
			yield node;
		}
	}
	setOutput(output) {
		this.#output = output;
	}
	destroy() {
		this.#input.destroy();
	}
	#shouldBePresent(row) {
		const cmp = this.#comparator(this.#bound.row, row);
		return cmp < 0 || cmp === 0 && !this.#bound.exclusive;
	}
	*push(change) {
		const shouldBePresent = (row) => this.#shouldBePresent(row);
		if (change.type === "edit") {
			yield* maybeSplitAndPushEditChange(change, shouldBePresent, this.#output, this);
			return;
		}
		if (shouldBePresent(change.node.row)) yield* this.#output.push(change, this);
	}
	#getStart(req) {
		const boundStart = {
			row: this.#bound.row,
			basis: this.#bound.exclusive ? "after" : "at"
		};
		if (!req.start) {
			if (req.reverse) return;
			return boundStart;
		}
		const cmp = this.#comparator(this.#bound.row, req.start.row);
		if (!req.reverse) {
			if (cmp > 0) return boundStart;
			if (cmp === 0) {
				if (this.#bound.exclusive || req.start.basis === "after") return {
					row: this.#bound.row,
					basis: "after"
				};
				return boundStart;
			}
			return req.start;
		}
		req.reverse;
		if (cmp > 0) return "empty";
		if (cmp === 0) {
			if (!this.#bound.exclusive && req.start.basis === "at") return boundStart;
			return "empty";
		}
		return req.start;
	}
};
//#endregion
export { Skip };

//# sourceMappingURL=skip.js.map