import { Cause, DateTime, Effect, Schema } from "effect"; import type { Success as EffectSuccess } from "effect/Effect"; import { DdfHttp } from "./client.js"; import type { DdfHttpError } from "./client.js"; import { getMember, getOffice, getOpenHouse, getProperty } from "./resources.js"; import type { MediaType } from "./schema/mediaSchema.js"; import type { SocialMedia } from "./schema/officeSchema.js"; import type { RoomsType } from "./schema/roomsSchema.js"; import type { ODataListQuery, ReplicationQuery } from "./types.js"; export declare const SyncModeSchema: Schema.Literals; export declare const SyncResourceSchema: Schema.Literals; export type SyncMode = typeof SyncModeSchema.Type; export type SyncResource = typeof SyncResourceSchema.Type; export type SyncStage = "hydrate" | "persist"; export type PropertyRecord = EffectSuccess>; export type MemberRecord = EffectSuccess>; export type OfficeRecord = EffectSuccess>; export type OpenHouseRecord = EffectSuccess>; export type RoomRecord = RoomsType[number]; export type MediaRecord = MediaType[number]; declare const DdfReplicationIdentifierKeyError_base: new = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & { readonly _tag: "DdfReplicationIdentifierKeyError"; } & Readonly; export declare class DdfReplicationIdentifierKeyError extends DdfReplicationIdentifierKeyError_base<{ readonly resource: SyncResource; readonly keyField: string; readonly page: string; readonly index: number; }> { get message(): string; } export interface SyncOwner { readonly resource: SyncResource; readonly key: string; } export interface PropertyGraph { readonly property: PropertyRecord; readonly rooms: ReadonlyArray; readonly media: ReadonlyArray; } export interface SyncRecordError { readonly resource: SyncResource; readonly key: string; readonly stage: SyncStage; readonly cause: unknown; readonly message: string; } export interface SyncCounts { readonly identifiers: number; readonly hydrated: number; readonly persisted: number; readonly failed: number; } export interface SyncResult { readonly resource: SyncResource; readonly identifiers: ReadonlyArray; readonly errors: ReadonlyArray; readonly counts: SyncCounts; readonly nextWatermark: string | null; } declare const DdfReplicationIdentifierError_base: new = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & { readonly _tag: "DdfReplicationIdentifierError"; } & Readonly; export declare class DdfReplicationIdentifierError extends DdfReplicationIdentifierError_base<{ readonly resource: SyncResource; readonly keyName: string; readonly index: number; }> { get message(): string; } export interface BaseSyncOptions { readonly mode?: SyncMode; readonly since?: string; readonly destinationId?: number; readonly concurrency?: number; readonly query?: ReplicationQuery; } export interface PropertySyncSink { readonly upsertPropertyGraph?: (graph: PropertyGraph) => Effect.Effect; readonly saveWatermark?: (resource: "Property", watermark: string) => Effect.Effect; readonly markMissingPropertiesInactive?: (keys: ReadonlyArray) => Effect.Effect; readonly deleteOpenHousesForListings?: (listings: ReadonlyArray) => Effect.Effect; } export interface MemberSyncSink { readonly upsertMemberWithMedia?: (member: MemberRecord, media: ReadonlyArray) => Effect.Effect; readonly upsertSocialMedia?: (socialMedia: SocialMedia, owner: SyncOwner) => Effect.Effect; readonly saveWatermark?: (resource: "Member", watermark: string) => Effect.Effect; readonly markMissingMembersInactive?: (keys: ReadonlyArray) => Effect.Effect; } export interface OfficeSyncSink { readonly upsertOfficeWithMedia?: (office: OfficeRecord, media: ReadonlyArray) => Effect.Effect; readonly upsertSocialMedia?: (socialMedia: SocialMedia, owner: SyncOwner) => Effect.Effect; readonly saveWatermark?: (resource: "Office", watermark: string) => Effect.Effect; readonly markMissingOfficesInactive?: (keys: ReadonlyArray) => Effect.Effect; } export interface OpenHouseSyncSink { readonly upsertOpenHouse?: (openHouse: OpenHouseRecord) => Effect.Effect; readonly saveWatermark?: (resource: "OpenHouse", watermark: string) => Effect.Effect; } export interface OpenHouseListingScope { readonly listingKey: string; readonly listingId: string | null; } export interface OpenHouseDateWindow { readonly startDate: string; readonly endDate?: string; } export interface PropertySyncOptions extends BaseSyncOptions { readonly sink?: PropertySyncSink; /** * Applied after property hydration because replication identifiers do not expose ListAORKey. * Skipped hydrated properties are logged and counted in `crea_ddf_sync_skipped_total`. */ readonly includeProperty?: (property: PropertyRecord) => boolean; } export interface MemberSyncOptions extends BaseSyncOptions { readonly sink?: MemberSyncSink; readonly includeMember?: (member: MemberRecord) => boolean; } export interface OfficeSyncOptions extends BaseSyncOptions { readonly sink?: OfficeSyncSink; readonly includeOffice?: (office: OfficeRecord) => boolean; } export interface OpenHouseSyncOptions { readonly query?: ODataListQuery; readonly concurrency?: number; readonly sink?: OpenHouseSyncSink; readonly listingScopes?: ReadonlyArray; readonly dateWindow?: OpenHouseDateWindow; readonly listingChunkSize?: number; } export interface MasterListDiff { readonly localKeys: ReadonlyArray; readonly masterKeys: ReadonlyArray; readonly missingLocalKeys: ReadonlyArray; readonly newMasterKeys: ReadonlyArray; } export declare const syncProperties: (options?: PropertySyncOptions | undefined) => Effect.Effect<{ resource: string; identifiers: { readonly ListingKey: string; readonly ModificationTimestamp?: DateTime.Utc | null | undefined; }[]; errors: SyncRecordError[]; counts: SyncCounts; nextWatermark: string | null; }, import("./watermark.js").DdfWatermarkError | DdfHttpError, DdfHttp>; export declare const syncMembers: (options?: MemberSyncOptions | undefined) => Effect.Effect<{ resource: string; identifiers: { readonly MemberKey: string; readonly ModificationTimestamp?: DateTime.Utc | null | undefined; }[]; errors: SyncRecordError[]; counts: SyncCounts; nextWatermark: string | null; }, import("./watermark.js").DdfWatermarkError | DdfHttpError, DdfHttp>; export declare const syncOffices: (options?: OfficeSyncOptions | undefined) => Effect.Effect<{ resource: string; identifiers: { readonly OfficeKey: string; readonly ModificationTimestamp?: DateTime.Utc | null | undefined; }[]; errors: SyncRecordError[]; counts: SyncCounts; nextWatermark: string | null; }, import("./watermark.js").DdfWatermarkError | DdfHttpError, DdfHttp>; export declare const syncOpenHouses: (options?: OpenHouseSyncOptions | undefined) => Effect.Effect<{ resource: string; identifiers: never[]; errors: SyncRecordError[]; counts: SyncCounts; nextWatermark: string | null; }, import("./client.js").DdfInvalidODataQueryError, DdfHttp>; export declare const getPropertyMasterList: (options?: Pick, "destinationId" | "query"> | undefined) => Effect.Effect<{ readonly ListingKey: string; readonly ModificationTimestamp?: DateTime.Utc | null | undefined; }[], DdfReplicationIdentifierKeyError | DdfHttpError, DdfHttp>; export declare const diffLocalKeysAgainstMasterList: (localKeys: ReadonlyArray, masterKeys: ReadonlyArray) => MasterListDiff; export declare const pruneMissingProperties: (localKeys: readonly string[], options?: Pick, "destinationId" | "query" | "sink"> | undefined) => Effect.Effect; export declare const getMemberMasterList: (options?: Pick, "destinationId" | "query"> | undefined) => Effect.Effect<{ readonly MemberKey: string; readonly ModificationTimestamp?: DateTime.Utc | null | undefined; }[], DdfReplicationIdentifierKeyError | DdfHttpError, DdfHttp>; export declare const getOfficeMasterList: (options?: Pick, "destinationId" | "query"> | undefined) => Effect.Effect<{ readonly OfficeKey: string; readonly ModificationTimestamp?: DateTime.Utc | null | undefined; }[], DdfReplicationIdentifierKeyError | DdfHttpError, DdfHttp>; export declare const pruneMissingMembers: (localKeys: readonly string[], options?: Pick, "destinationId" | "query" | "sink"> | undefined) => Effect.Effect; export declare const pruneMissingOffices: (localKeys: readonly string[], options?: Pick, "destinationId" | "query" | "sink"> | undefined) => Effect.Effect; export {}; //# sourceMappingURL=sync.d.ts.map