UNPKG

@xylabs/threads

Version:

Web workers & worker threads as simple as a function call

69 lines (57 loc) 2.49 kB
/* eslint-disable import-x/no-internal-modules */ /* eslint-disable @typescript-eslint/no-explicit-any */ import type { SerializedError } from './types/messages.ts' export interface Serializer<Msg = JsonSerializable, Input = any> { deserialize(message: Msg): Input serialize(input: Input): Msg } export interface SerializerImplementation<Msg = JsonSerializable, Input = any> { deserialize(message: Msg, defaultDeserialize: (msg: Msg) => Input): Input serialize(input: Input, defaultSerialize: (inp: Input) => Msg): Msg } export function extendSerializer<MessageType, InputType = any>( extend: Serializer<MessageType, InputType>, implementation: SerializerImplementation<MessageType, InputType>, ): Serializer<MessageType, InputType> { const fallbackDeserializer = extend.deserialize.bind(extend) const fallbackSerializer = extend.serialize.bind(extend) return { deserialize(message: MessageType): InputType { return implementation.deserialize(message, fallbackDeserializer) }, serialize(input: InputType): MessageType { return implementation.serialize(input, fallbackSerializer) }, } } type JsonSerializablePrimitive = string | number | boolean | null type JsonSerializableObject = { [key: string]: JsonSerializablePrimitive | JsonSerializablePrimitive[] | JsonSerializableObject | JsonSerializableObject[] | undefined } export type JsonSerializable = JsonSerializablePrimitive | JsonSerializablePrimitive[] | JsonSerializableObject | JsonSerializableObject[] const DefaultErrorSerializer: Serializer<SerializedError, Error> = { deserialize(message: SerializedError): Error { return Object.assign(new Error(message.message), { name: message.name, stack: message.stack, }) }, serialize(error: Error): SerializedError { return { __error_marker: '$$error', message: error.message, name: error.name, stack: error.stack, } }, } const isSerializedError = (thing: any): thing is SerializedError => thing && typeof thing === 'object' && '__error_marker' in thing && thing.__error_marker === '$$error' export const DefaultSerializer: Serializer<JsonSerializable> = { deserialize(message: JsonSerializable): any { return isSerializedError(message) ? DefaultErrorSerializer.deserialize(message) : message }, serialize(input: any): JsonSerializable { return input instanceof Error ? (DefaultErrorSerializer.serialize(input) as any as JsonSerializable) : input }, }