UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

185 lines (184 loc) 7.12 kB
import { t as runBestEffortCleanup } from "./non-fatal-cleanup-Dsr9pn7u.js"; //#region src/channels/message/live.ts /** * Live channel message state and preview finalization helpers. * * Tracks draft previews and converts them into finalized message receipts when possible. */ /** Defines a finalizable live-preview adapter while preserving its generic payload/id/edit types. */ function defineFinalizableLivePreviewAdapter(adapter) { return adapter; } /** Creates the initial live-message state, optionally seeded with an existing preview receipt. */ function createLiveMessageState(params) { return { phase: params?.receipt ? "previewing" : "idle", canFinalizeInPlace: params?.canFinalizeInPlace ?? Boolean(params?.receipt), ...params?.receipt ? { receipt: params.receipt } : {}, ...params?.lastRendered ? { lastRendered: params.lastRendered } : {} }; } /** Marks a live message as finalized and disables further in-place preview edits. */ function markLiveMessageFinalized(state, receipt) { return { ...state, phase: "finalized", receipt, canFinalizeInPlace: false }; } /** Creates a receipt for a draft/preview platform message. */ function createPreviewMessageReceipt(params) { const platformMessageId = String(params.id); return { primaryPlatformMessageId: platformMessageId, platformMessageIds: [platformMessageId], parts: [{ platformMessageId, kind: "preview", index: 0, ...params.threadId ? { threadId: params.threadId } : {}, ...params.replyToId ? { replyToId: params.replyToId } : {} }], ...params.threadId ? { threadId: params.threadId } : {}, ...params.replyToId ? { replyToId: params.replyToId } : {}, sentAt: params.sentAt ?? Date.now(), ...params.raw === void 0 ? {} : { raw: [{ meta: { raw: params.raw } }] } }; } /** Finalizes a live preview in place when possible, otherwise falls back to normal delivery. */ async function deliverFinalizableLivePreview(params) { let liveState = params.liveState ?? createLiveMessageState({ canFinalizeInPlace: Boolean(params.draft) }); if (params.kind !== "final" || !params.draft) { if (await params.deliverNormally(params.payload) === false) return { kind: "normal-skipped", liveState }; await params.onNormalDelivered?.(); return { kind: "normal-delivered", liveState }; } const edit = liveState.canFinalizeInPlace ? params.buildFinalEdit(params.payload) : void 0; if (edit !== void 0) { await params.draft.flush(); const previewId = params.draft.id(); if (previewId !== void 0) { await params.draft.seal?.(); let editSucceeded = false; try { await params.editFinal(previewId, edit); editSucceeded = true; } catch (err) { params.logPreviewEditFailure?.(err); if ((await params.handlePreviewEditError?.({ error: err, id: previewId, edit, payload: params.payload, liveState }) ?? "fallback") === "retain") { const receipt = liveState.receipt ?? params.createPreviewReceipt?.(previewId, edit) ?? createPreviewMessageReceipt({ id: previewId }); liveState = { ...liveState, phase: "previewing", canFinalizeInPlace: true, receipt }; return { kind: "preview-retained", liveState }; } } if (editSucceeded) { const finalizedId = params.resolveFinalizedId?.(previewId, edit) ?? previewId; const receipt = params.createPreviewReceipt?.(finalizedId, edit) ?? createPreviewMessageReceipt({ id: finalizedId }); liveState = markLiveMessageFinalized(liveState, receipt); await params.onPreviewFinalized?.(finalizedId, receipt, liveState); const supplementalPayload = params.buildSupplementalPayload?.(params.payload); if (supplementalPayload !== void 0) { const supplementalDelivered = await params.deliverSupplemental?.(supplementalPayload); if (!params.deliverSupplemental || supplementalDelivered === false) { if (await params.deliverNormally(supplementalPayload) === false) throw new Error("Live preview supplemental payload was not delivered"); } } return { kind: "preview-finalized", liveState }; } } } if (params.draft.discardPending) await params.draft.discardPending(); else await params.draft.clear(); liveState = markLiveMessageCancelled(liveState); let delivered; try { delivered = await params.deliverNormally(params.payload) !== false; if (delivered) await params.onNormalDelivered?.(); } finally { if (delivered) { const draft = params.draft; await runBestEffortCleanup({ cleanup: () => draft.clear(), onError: () => console.warn("Live preview cleanup failed after delivery; a stale preview may remain") }); } } return { kind: delivered ? "normal-delivered" : "normal-skipped", liveState }; } /** Runs live-preview finalization through an optional adapter, falling back to normal delivery. */ async function deliverWithFinalizableLivePreviewAdapter(params) { if (!params.adapter) { const liveState = params.liveState ?? createLiveMessageState(); if (await params.deliverNormally(params.payload) === false) return { kind: "normal-skipped", liveState }; await params.onNormalDelivered?.(); return { kind: "normal-delivered", liveState }; } return await deliverFinalizableLivePreview({ kind: params.kind, payload: params.payload, ...params.liveState ? { liveState: params.liveState } : {}, draft: params.adapter.draft, buildFinalEdit: params.adapter.buildFinalEdit, editFinal: params.adapter.editFinal, ...params.adapter.resolveFinalizedId ? { resolveFinalizedId: params.adapter.resolveFinalizedId } : {}, deliverNormally: params.deliverNormally, ...params.adapter.createPreviewReceipt ? { createPreviewReceipt: params.adapter.createPreviewReceipt } : {}, ...params.adapter.onPreviewFinalized ? { onPreviewFinalized: params.adapter.onPreviewFinalized } : {}, ...params.adapter.buildSupplementalPayload ? { buildSupplementalPayload: params.adapter.buildSupplementalPayload } : {}, ...params.adapter.deliverSupplemental ? { deliverSupplemental: params.adapter.deliverSupplemental } : {}, ...params.adapter.handlePreviewEditError ? { handlePreviewEditError: params.adapter.handlePreviewEditError } : {}, ...params.onNormalDelivered ? { onNormalDelivered: params.onNormalDelivered } : {}, ...params.adapter.logPreviewEditFailure ? { logPreviewEditFailure: params.adapter.logPreviewEditFailure } : {} }); } /** Records the latest rendered preview batch and moves the live message into previewing state. */ function markLiveMessagePreviewUpdated(state, rendered) { return { ...state, phase: "previewing", lastRendered: rendered }; } /** Marks a live message cancelled and prevents later in-place finalization. */ function markLiveMessageCancelled(state) { return { ...state, phase: "cancelled", canFinalizeInPlace: false }; } //#endregion export { deliverWithFinalizableLivePreviewAdapter as a, deliverFinalizableLivePreview as i, createPreviewMessageReceipt as n, markLiveMessagePreviewUpdated as o, defineFinalizableLivePreviewAdapter as r, createLiveMessageState as t };