import type { EntityID } from '@wovin/core/applog' import type { IShare } from '@wovin/core/pubsub' import type { CID } from 'multiformats/cid' import { prepareSnapshotForPush } from '@wovin/core' import { Logger } from 'besonders-logger' import { useAgent } from '../data/agent/AgentState' import { getShareThread, makeBlocksSelector, toggleLastWriteWinsSelector } from '../data/getShareThread' import { makeNote3Url } from '../ui/utils-ui' import { storageState } from './storage' const { WARN, LOG, DEBUG, VERBOSE, ERROR } = Logger.setup(Logger.INFO) // eslint-disable-line unused-imports/no-unused-vars export type QuickSharePhase = 'idle' | 'preparing' | 'uploading' | 'done' | 'error' export interface QuickShareResult { cid: CID url: string } export interface QuickShareOptions { withoutHistory?: boolean onPhaseChange?: (phase: QuickSharePhase) => void } export async function quickShareBlock( thread: Parameters[0], blockID: EntityID, options: QuickShareOptions = {}, ): Promise { const { withoutHistory = true, onPhaseChange } = options const agent = useAgent() if (!storageState.ucanUploads?.length) { throw new Error('No storage provider configured. Please set up storage in Settings.') } onPhaseChange?.('preparing') DEBUG('[quickShare] Starting quick share for block:', blockID, { withoutHistory }) // Build selector: blocks(blockID) with optional | lastWriteWins let selector = makeBlocksSelector([blockID]) if (withoutHistory) { selector = toggleLastWriteWinsSelector(selector, true) } // Create a temporary share config (not saved to store) const tempShare: IShare = { id: `quick-share-${blockID}-${Date.now()}`, name: `Quick Share`, selectors: [selector], createdAt: new Date().toISOString(), // No pk/IPNS - this is CID-only } as IShare // Get filtered thread for this block const shareThread = getShareThread(thread, tempShare) DEBUG('[quickShare] Share thread:', { size: shareThread.size, tempShare }) if (!shareThread.size) { throw new Error('No data to share for this block') } // Prepare the CAR blob const { cid, blob } = await prepareSnapshotForPush( agent, thread, shareThread, tempShare, null, // No previous CID - fresh snapshot ) DEBUG('[quickShare] Prepared CAR:', { cid: cid.toString(), blobSize: blob.size }) onPhaseChange?.('uploading') // Upload to storage providers const uploadResults = await Promise.allSettled( storageState.ucanUploads.map(provider => provider.storeCar(blob)), ) const succeeded = uploadResults.filter(r => r.status === 'fulfilled') const failed = uploadResults.filter(r => r.status === 'rejected') if (!succeeded.length) { const errors = failed.map(r => (r as PromiseRejectedResult).reason) ERROR('[quickShare] All uploads failed:', errors) throw new Error(`Upload failed: ${errors[0]?.message || 'Unknown error'}`) } if (failed.length) { WARN('[quickShare] Some uploads failed:', failed.map(r => (r as PromiseRejectedResult).reason)) } onPhaseChange?.('done') const url = makeNote3Url({ pub: cid.toString(), block: blockID, previewPub: true }) LOG('[quickShare] Success:', { cid: cid.toString(), url }) return { cid, url } }