import { promiseVoid } from "../../../shared/src/resolved-promises.js";
import { CRUD_MUTATION_NAME } from "../../../zero-protocol/src/push.js";
import { crud_impl_exports } from "./crud-impl.js";
//#region ../zero-client/src/client/crud.ts
/**
* This is the zero.mutateBatch function part representing the CRUD operations. If the
* tables are `issue` and `label`, then this object will have `issue` and
* `label` properties.
*
* @param schema - The schema defining the tables
* @param repMutate - The replicache mutate object with the CRUD mutation
* @param mutate - The object to use as the mutate object. Properties for each
*                 table will be assigned to this object.
*/
function makeCRUDMutateBatch(schema, repMutate) {
	if (schema.enableLegacyMutators !== true) return;
	const { [CRUD_MUTATION_NAME]: zeroCRUD } = repMutate;
	const mutateBatch = async (body) => {
		const ops = [];
		const m = {};
		for (const name of Object.keys(schema.tables)) m[name] = makeBatchCRUDMutate(name, schema, ops);
		const rv = await body(m);
		await zeroCRUD({ ops });
		return rv;
	};
	return mutateBatch;
}
function addTableCRUDProperties(schema, mutate, repMutate) {
	const { [CRUD_MUTATION_NAME]: zeroCRUD } = repMutate;
	for (const [name, tableSchema] of Object.entries(schema.tables)) mutate[name] = makeEntityCRUDMutate(name, tableSchema.primaryKey, zeroCRUD);
}
/**
* Creates the `{insert, upsert, update, delete}` object for use outside a
* batch.
*/
function makeEntityCRUDMutate(tableName, primaryKey, zeroCRUD) {
	return {
		insert: (value) => {
			return zeroCRUD({ ops: [{
				op: "insert",
				tableName,
				primaryKey,
				value
			}] });
		},
		upsert: (value) => {
			return zeroCRUD({ ops: [{
				op: "upsert",
				tableName,
				primaryKey,
				value
			}] });
		},
		update: (value) => {
			return zeroCRUD({ ops: [{
				op: "update",
				tableName,
				primaryKey,
				value
			}] });
		},
		delete: (id) => {
			return zeroCRUD({ ops: [{
				op: "delete",
				tableName,
				primaryKey,
				value: id
			}] });
		}
	};
}
/**
* Creates the `{insert, upsert, update, delete}` object for use inside a
* batch.
*/
function makeBatchCRUDMutate(tableName, schema, ops) {
	const { primaryKey } = schema.tables[tableName];
	return {
		insert: (value) => {
			const op = {
				op: "insert",
				tableName,
				primaryKey,
				value
			};
			ops.push(op);
			return promiseVoid;
		},
		upsert: (value) => {
			const op = {
				op: "upsert",
				tableName,
				primaryKey,
				value
			};
			ops.push(op);
			return promiseVoid;
		},
		update: (value) => {
			const op = {
				op: "update",
				tableName,
				primaryKey,
				value
			};
			ops.push(op);
			return promiseVoid;
		},
		delete: (id) => {
			const op = {
				op: "delete",
				tableName,
				primaryKey,
				value: id
			};
			ops.push(op);
			return promiseVoid;
		}
	};
}
function makeCRUDExecutor(tx, schema, ivmBranch) {
	return (tableName, kind, value) => {
		const { primaryKey } = schema.tables[tableName];
		return crud_impl_exports[kind](tx, {
			op: kind,
			tableName,
			primaryKey,
			value
		}, schema, ivmBranch);
	};
}
function makeCRUDMutator(schema) {
	return async (tx, crudArg) => {
		const executor = makeCRUDExecutor(tx, schema, void 0);
		for (const op of crudArg.ops) await executor(op.tableName, op.op, op.value);
	};
}
//#endregion
export { addTableCRUDProperties, makeCRUDExecutor, makeCRUDMutateBatch, makeCRUDMutator };

//# sourceMappingURL=crud.js.map