import type { IContainEntitiesAndLinks, LinkParams, CreateParams, UpdateParams, UpdateOpts, RuleParams, UniqueKeys, ResolveEntityAttrs } from './schemaTypes.ts';
type Action = 'create' | 'update' | 'link' | 'unlink' | 'delete' | 'merge' | 'ruleParams';
type EType = string;
type Id = string;
type Args = any;
type LookupRef = [string, any];
type Lookup = string;
type Opts = UpdateOpts;
export type Op = [Action, EType, Id | LookupRef, Args, Opts?];
export interface TransactionChunk<Schema extends IContainEntitiesAndLinks<any, any>, EntityName extends keyof Schema['entities']> {
    __ops: Op[];
    __etype: EntityName;
    /**
     * Create objects. Throws an error if the object with the provided ID already
     * exists.
     */
    create: (args: CreateParams<Schema, EntityName>) => TransactionChunk<Schema, EntityName>;
    /**
     * Create and update objects. By default works in upsert mode (will create
     * entity if that doesn't exist). Can be optionally put into "strict update"
     * mode by providing { upsert: false } option as second argument:
     *
     * @example
     *  const goalId = id();
     *  // upsert
     *  db.tx.goals[goalId].update({title: "Get fit", difficulty: 5})
     *
     *  // strict update
     *  db.tx.goals[goalId].update({title: "Get fit"}, {upsert: false})
     */
    update: (args: UpdateParams<Schema, EntityName>, opts?: UpdateOpts) => TransactionChunk<Schema, EntityName>;
    /**
     * Link two objects together
     *
     * @example
     * const goalId = id();
     * const todoId = id();
     * db.transact([
     *   db.tx.goals[goalId].update({title: "Get fit"}),
     *   db.tx.todos[todoId].update({title: "Go on a run"}),
     *   db.tx.goals[goalId].link({todos: todoId}),
     * ])
     *
     * // Now, if you query:
     * useQuery({ goals: { todos: {} } })
     * // You'll get back:
     *
     * // { goals: [{ title: "Get fit", todos: [{ title: "Go on a run" }]}
     */
    link: (args: LinkParams<Schema, EntityName>) => TransactionChunk<Schema, EntityName>;
    /**
     * Unlink two objects
     * @example
     *  // to "unlink" a todo from a goal:
     *  db.tx.goals[goalId].unlink({todos: todoId})
     */
    unlink: (args: LinkParams<Schema, EntityName>) => TransactionChunk<Schema, EntityName>;
    /**
     * Delete an object, alongside all of its links.
     *
     * @example
     *   db.tx.goals[goalId].delete()
     */
    delete: () => TransactionChunk<Schema, EntityName>;
    /**
     *
     * Similar to `update`, but instead of overwriting the current value, it will merge the provided values into the current value.
     *
     * This is useful for deeply nested, document-style values, or for updating a single attribute at an arbitrary depth without overwriting the rest of the object.
     *
     * For example, if you have a goal with a nested `metrics` object:
     *
     * ```js
     * goal = { name: "Get fit", metrics: { progress: 0.3 } }
     * ```
     *
     * You can update the `progress` attribute like so:
     *
     * ```js
     * db.tx.goals[goalId].merge({ metrics: { progress: 0.5 }, category: "Fitness" })
     * ```
     *
     * And the resulting object will be:
     *
     * ```js
     * goal = { name: "Get fit", metrics: { progress: 0.5 }, category: "Fitness"  }
     *  ```
     *
     * @example
     *  const goalId = id();
     *  db.tx.goals[goalId].merge({title: "Get fitter"})
     */
    merge: (args: {
        [attribute: string]: any;
    }, opts?: UpdateOpts) => TransactionChunk<Schema, EntityName>;
    ruleParams: (args: RuleParams) => TransactionChunk<Schema, EntityName>;
}
export type ETypeChunk<Schema extends IContainEntitiesAndLinks<any, any>, EntityName extends keyof Schema['entities']> = {
    [id: Id]: TransactionChunk<Schema, EntityName>;
} & {
    lookup: <Name extends UniqueKeys<Schema['entities'][EntityName]['attrs']>>(attrName: Name, value: ResolveEntityAttrs<Schema['entities'][EntityName]>[Name]) => TransactionChunk<Schema, EntityName>;
};
export type TxChunk<Schema extends IContainEntitiesAndLinks<any, any>> = {
    [EntityName in keyof Schema['entities']]: ETypeChunk<Schema, EntityName>;
};
/**
 * Creates a lookup to use in place of an id in a transaction
 *
 * @example
 * db.tx.users[lookup('email', 'lyndon@example.com')].update({name: 'Lyndon'})
 */
export declare function lookup(attribute: string, value: any): Lookup;
export declare function isLookup(k: string): boolean;
export declare function parseLookup(k: string): LookupRef;
export declare function txInit<Schema extends IContainEntitiesAndLinks<any, any>>(): TxChunk<Schema>;
/**
 * A handy builder for changes.
 *
 * You must start with the `namespace` you want to change:
 *
 * @example
 *   db.tx.goals[goalId].update({title: "Get fit"})
 *   // Note: you don't need to create `goals` ahead of time.
 */
export declare const tx: TxChunk<IContainEntitiesAndLinks<any, any>>;
export declare function getOps(x: TransactionChunk<any, any>): Op[];
export {};
//# sourceMappingURL=instatx.d.ts.map