import type { Json } from "atom.io/foundations/json" import type { ConstructorOf, Transceiver } from "atom.io/internal" import type { MosaicModelIdentifier, MosaicOperationMetadata, MosaicRecovery, MosaicRejectionCode, } from "./protocol.ts" /** Metadata available to deterministic validation and reduction. */ export type MosaicReduceContext = MosaicOperationMetadata & { /** The server stream order, or null for a provisional local projection. */ readonly revision: number | null } /** Local-only context used to translate a friendly intent into an operation. */ export type MosaicPrepareContext = MosaicOperationMetadata & { /** Injected clock time. It must never affect accepted reduction semantics. */ readonly now: number readonly revision: null } export type MosaicModelDecision = | { readonly operation: Operation; readonly status: `accept` } | { readonly dependencies: readonly string[]; readonly status: `defer` } | { /** An optional protocol-safe classification supplied by the model. */ readonly code?: MosaicRejectionCode readonly reason: string /** An optional recovery policy supplied by the model. */ readonly recovery?: MosaicRecovery readonly status: `reject` } /** * The serializable signal carried by a Mosaic transceiver. The wire protocol * adds the mutable-atom address and model identifier around this signal. */ export type MosaicOperationSignal< Operation extends Json.Serializable = Json.Serializable, > = MosaicReduceContext & { readonly operation: Operation } /** * A convergent transceiver held by an ordinary mutable atom. Its readonly view * participates in Atom.io's graph; synchronization remains Store-owned. */ export interface MosaicTransceiver< View extends { subscribe: ( key: string, fn: (signal: MosaicOperationSignal) => void, ) => () => void }, Intent extends Json.Serializable, Operation extends Json.Serializable, Snapshot extends Json.Serializable, > extends Transceiver, Snapshot> { /** Prepare, apply, and publish one provisional local operation. */ change( intent: Intent, context: MosaicPrepareContext, ): MosaicOperationSignal | null /** Apply exactly one validated operation, or throw without mutating. */ do(signal: MosaicOperationSignal): null /** Validate and normalize an untrusted operation against this projection. */ validate( operation: unknown, context: MosaicReduceContext, ): MosaicModelDecision } export type AnyMosaicTransceiver = MosaicTransceiver /** A mutable-atom-compatible constructor for one versioned Mosaic model. */ export type MosaicTransceiverConstructor< TransceiverType extends AnyMosaicTransceiver = AnyMosaicTransceiver, > = ConstructorOf & { readonly mosaic: MosaicModelIdentifier readonly timelinePolicy: `append-only` } export type MosaicView = TransceiverType extends MosaicTransceiver ? View : never export type MosaicIntent = TransceiverType extends MosaicTransceiver ? Intent : never export type MosaicOperation = TransceiverType extends MosaicTransceiver ? Operation : never export type MosaicSnapshot = TransceiverType extends MosaicTransceiver ? Snapshot : never export type MosaicSignal = MosaicOperationSignal< MosaicOperation >