import type { ObjectType } from '../objectCache' import { buildWriteObjectWorkerPayload } from './payloads' import { isWorkerMessageEnvelope, isRecord, readWorkerErrorData } from './workerMessage' import type { WriteObjectParams } from './types' export async function writeObjectDirect(params: WriteObjectParams): Promise { const { objectCache } = await import('../objectCache') await objectCache.set({ objectType: params.objectType, hash: params.hash, event: params.event, parsed: params.parsed, version: params.version, hidden: params.hidden, ...(params.index !== undefined ? { index: params.index } : {}), ...(params.published !== undefined ? { published: params.published } : {}), }) } export function postWriteObjectToWorker(params: { worker: Worker writeParams: WriteObjectParams }): Promise { const published = params.writeParams.published ?? false const payload = buildWriteObjectWorkerPayload({ params: params.writeParams, published }) return new Promise((resolve, reject) => { const timeout = setTimeout(() => reject(new Error('Write operation timeout')), 10000) const handler = (event: MessageEvent): void => { if (!isWorkerMessageEnvelope(event.data)) { return } if ( event.data.type === 'WRITE_OBJECT_SUCCESS' && isRecord(event.data.data) && event.data.data.hash === params.writeParams.hash ) { clearTimeout(timeout) params.worker.removeEventListener('message', handler) resolve() return } if (event.data.type === 'ERROR') { const errorData = readWorkerErrorData(event.data.data) if (errorData.originalType !== 'WRITE_OBJECT') { return } clearTimeout(timeout) params.worker.removeEventListener('message', handler) reject(new Error(errorData.error ?? 'Write worker error')) } } params.worker.addEventListener('message', handler) params.worker.postMessage(payload) }) } export async function updatePublishedDirect(params: { objectType: ObjectType id: string published: false | string[] }): Promise { const { objectCache } = await import('../objectCache') await objectCache.updatePublished(params.objectType, params.id, params.published) } export function postUpdatePublishedToWorker(params: { worker: Worker objectType: ObjectType id: string published: false | string[] }): Promise { return new Promise((resolve, reject) => { const timeout = setTimeout(() => reject(new Error('Update published operation timeout')), 10000) const handler = (event: MessageEvent): void => { if (!isWorkerMessageEnvelope(event.data)) { return } if (event.data.type === 'UPDATE_PUBLISHED_SUCCESS') { if (!isRecord(event.data.data) || event.data.data.id !== params.id) { return } clearTimeout(timeout) params.worker.removeEventListener('message', handler) resolve() return } if (event.data.type !== 'ERROR') { return } const errorData = readWorkerErrorData(event.data.data) if (errorData.originalType !== 'UPDATE_PUBLISHED' && errorData.taskId?.startsWith('UPDATE_PUBLISHED') !== true) { return } clearTimeout(timeout) params.worker.removeEventListener('message', handler) reject(new Error(errorData.error ?? 'Write worker error')) } params.worker.addEventListener('message', handler) params.worker.postMessage({ type: 'UPDATE_PUBLISHED', data: { objectType: params.objectType, id: params.id, published: params.published } }) }) }