import type { ConflictResolver } from "./resolvers/interface.js"; import type { TenantStore } from "./store/interface.js"; import { type AcceptInviteOptions, type Conflict, type CreatePairOptions, type InviteMemberOptions, type InviteToken, type MemberId, type MemberRecord, type PairId, type PairStateRow } from "./types.js"; export interface TenantPairOptions { store: TenantStore; /** Defaults to LWWResolver */ resolver?: ConflictResolver; /** Provide a deterministic clock for tests */ now?: () => Date; /** Provide a deterministic id factory for tests */ idFactory?: { pairId: () => string; inviteToken: () => string; }; /** Maximum simultaneously pending invites per pair (default 25). */ maxPendingInvites?: number; } /** * Generate a short, human-friendly base32 id. Used as a suffix on the invite * token so a user can read it back over voice ("INVITE: 4HKQ-9XPT"). * * Default `rng` is a crypto-secure CSPRNG. Tests may inject a deterministic * function (e.g., `() => 0`). */ export declare function generateShortCode(rng?: () => number, length?: number): string; export declare class TenantPair { private readonly store; private readonly resolver; private readonly now; private readonly idFactory; private readonly maxPendingInvites; private initialized; constructor(options: TenantPairOptions); init(): Promise; close(): Promise; createPair(opts: CreatePairOptions): Promise<{ pairId: PairId; inviteToken: InviteToken; }>; inviteMember(opts: InviteMemberOptions): Promise<{ inviteToken: InviteToken; expiresAt: string; }>; acceptInvite(opts: AcceptInviteOptions): Promise<{ pairId: PairId; members: MemberRecord[]; }>; listMembers(pairId: PairId): Promise; kickMember(pairId: PairId, actingMemberId: MemberId, targetMemberId: MemberId): Promise<{ removedMemberId: MemberId; }>; leavePair(pairId: PairId, memberId: MemberId): Promise; /** * DSGVO Art. 17 right-to-erasure path. Hard-deletes the member's * `member_state` rows (allergies, dietary restrictions — Art. 9 special * categories) and nulls the `display_name`. The member row itself is * retained for audit (`left_at` is preserved) — only personal data is * erased, not the membership trace. * * Idempotent: calling on an unknown member is a no-op. * * Closes Cold-Cross F6: library was advertised for health-category data * but had no erasure path, blocking DSGVO compliance for downstream * consumers. */ forgetMember(pairId: PairId, memberId: MemberId): Promise; setMemberPreference(pairId: PairId, memberId: MemberId, key: string, value: unknown): Promise<{ validFrom: string; }>; getMemberConstraints(pairId: PairId, memberId: MemberId, keys?: string[]): Promise>; getSharedState(pairId: PairId, namespace?: string): Promise<{ state: Record; version: number; }>; setSharedState(pairId: PairId, memberId: MemberId, key: string, value: unknown, namespace?: string): Promise<{ version: number; }>; listConflicts(pairId: PairId, namespace?: string): Promise; resolveConflicts(pairId: PairId, namespace?: string, customResolver?: ConflictResolver): Promise<{ resolved: number; remaining: number; }>; getPairStateHistory(pairId: PairId, namespace: string, key: string): Promise; } //# sourceMappingURL=tenant-pair.d.ts.map