import GraphAttachmentSetOp from "./GraphAttachmentSetOp.js";
import GraphContentAttachmentSetOp from "./GraphContentAttachmentSetOp.js";
import GraphEdgeRecordSetOp from "./GraphEdgeRecordSetOp.js";
import GraphEdgePropertySetOp from "./GraphEdgePropertySetOp.js";
import GraphNodeRecordSetOp from "./GraphNodeRecordSetOp.js";
import GraphNodePropertySetOp from "./GraphNodePropertySetOp.js";
import WarpError from "../errors/WarpError.js";
/** Immutable graph-operation algebra over node, edge, and attachment records. */
export default class GraphOpAlgebra {
    operations;
    constructor(fields) {
        const checkedFields = requireFields(fields);
        this.operations = requireOperations(checkedFields.operations);
        Object.freeze(this);
    }
}
/** Validates the graph-op algebra constructor envelope. */
function requireFields(fields) {
    if (fields === null || fields === undefined) {
        throw new WarpError('GraphOpAlgebra fields must be provided', 'E_VALIDATION');
    }
    return fields;
}
/** Requires a frozen list of runtime-backed graph operations. */
function requireOperations(operations) {
    if (!Array.isArray(operations)) {
        throw new WarpError('GraphOpAlgebra operations must be an array', 'E_VALIDATION');
    }
    const checkedOperations = [];
    for (const operation of operations) {
        checkedOperations.push(requireOperation(operation));
    }
    return Object.freeze(checkedOperations);
}
/** Requires a supported graph operation instance. */
function requireOperation(operation) {
    if (isRecordOperation(operation) || isProjectionOperation(operation)) {
        return operation;
    }
    throw new WarpError('GraphOpAlgebra operation must be a graph operation instance', 'E_VALIDATION');
}
/** Returns true when the operation is a core graph record operation. */
function isRecordOperation(operation) {
    return (operation instanceof GraphNodeRecordSetOp
        || operation instanceof GraphEdgeRecordSetOp
        || operation instanceof GraphAttachmentSetOp);
}
/** Returns true when the operation is a typed projection operation. */
function isProjectionOperation(operation) {
    return (operation instanceof GraphContentAttachmentSetOp
        || operation instanceof GraphNodePropertySetOp
        || operation instanceof GraphEdgePropertySetOp);
}
