2026-01-13 14:49:19 +01:00

112 lines
3.6 KiB
TypeScript

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<void> {
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<void> {
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<unknown>): 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<void> {
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<void> {
return new Promise((resolve, reject) => {
const timeout = setTimeout(() => reject(new Error('Update published operation timeout')), 10000)
const handler = (event: MessageEvent<unknown>): 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 } })
})
}