Skip to content

Instantly share code, notes, and snippets.

@schickling
Created April 3, 2023 14:22
Show Gist options
  • Save schickling/a52266f2d9fc77f5f5299935e7a32508 to your computer and use it in GitHub Desktop.
Save schickling/a52266f2d9fc77f5f5299935e7a32508 to your computer and use it in GitHub Desktop.
Worker codec refactor attempt
import type { Either } from '@mytunes/utils/effect2'
export type HasTag<T = {}> = { _tag: string } & T
// NOTE implementations using `AnyWorkerCodec` might be unsafe
// export type AnyWorkerCodec = WorkerCodec<AnyIWorkerCodec>
export type AnyWorkerCodec = WorkerCodec<any>
// export type AnyWorkerCodec = WorkerCodec<any, any, any, any, any, any, any, any>
export type AnyIWorkerCodec = IWorkerCodec<any, any, any, any, any, any, any, any>
export interface IWorkerCodec<
in out TInitEncoded,
in out TInitDecoded,
in out TReqEncoded,
in out TReqDecoded extends HasTag,
in out TResEncoded,
in out TResDecoded extends HasTag,
in out TResErrDecoded,
// TODO find a better API to enable this use case
in out TReqDecodedMetaData = {},
> {
TInitEncoded: TInitEncoded
TInitDecoded: TInitDecoded
TReqEncoded: TReqEncoded
TReqDecoded: TReqDecoded
TResEncoded: TResEncoded
TResDecoded: TResDecoded
TResErrDecoded: TResErrDecoded
TReqDecodedMetaData: TReqDecodedMetaData
// TInitEncoded: unknown
// TInitDecoded: unknown
// TReqEncoded: unknown
// TReqDecoded: HasTag
// TResEncoded: unknown
// TResDecoded: HasTag
// TResErrDecoded: unknown
// TReqDecodedMetaData: {}
}
export class WorkerCodec<
TWorkerCodec extends AnyIWorkerCodec,
// in out TInitEncoded,
// in out TInitDecoded,
// in out TReqEncoded,
// in out TReqDecoded extends HasTag,
// in out TResEncoded,
// in out TResDecoded extends HasTag,
// in out TResErrDecoded,
// // TODO find a better API to enable this use case
// in out TReqDecodedMetaData = {},
> {
InitEncoded!: TWorkerCodec['TInitEncoded']
InitDecoded!: TWorkerCodec['TInitDecoded']
ReqEncoded!: TWorkerCodec['TReqEncoded']
ReqEncodedWithTransfer!: [msg: TWorkerCodec['TReqEncoded'], transfer: Transferable[]]
ReqDecoded!: TWorkerCodec['TReqDecoded']
ResEncoded!: TWorkerCodec['TResEncoded']
ResEncodedWithTransfer!: [msg: TWorkerCodec['TResEncoded'], transfer: Transferable[]]
ResDecoded!: TWorkerCodec['TResDecoded']
ResErrDecoded!: TWorkerCodec['TResErrDecoded']
readonly decodeInit: Decoder<TWorkerCodec['TInitDecoded'], TWorkerCodec['TInitEncoded']>
readonly encodeInit: Encoder<TWorkerCodec['TInitDecoded'], TWorkerCodec['TInitEncoded']>
readonly decodeReq: Decoder<
TWorkerCodec['TReqDecoded'] & TWorkerCodec['TReqDecodedMetaData'],
TWorkerCodec['TReqEncoded']
>
readonly encodeReq: Encoder<
TWorkerCodec['TReqDecoded'] & TWorkerCodec['TReqDecodedMetaData'],
TWorkerCodec['TReqEncoded']
>
readonly decodeRes: DecoderWithError<
TWorkerCodec['TResDecoded'],
TWorkerCodec['TResErrDecoded'],
TWorkerCodec['TResEncoded']
>
readonly encodeRes: EncoderWithError<
TWorkerCodec['TResDecoded'],
TWorkerCodec['TResErrDecoded'],
TWorkerCodec['TResEncoded']
>
readonly getId: (reqDecoded: TWorkerCodec['TReqDecoded']) => string
constructor({
decodeInit,
encodeInit,
decodeReq,
encodeReq,
decodeRes,
encodeRes,
getId,
}: {
decodeInit: Decoder<TWorkerCodec['TInitDecoded'], TWorkerCodec['TInitEncoded']>
encodeInit: Encoder<TWorkerCodec['TInitDecoded'], TWorkerCodec['TInitEncoded']>
decodeReq: Decoder<TWorkerCodec['TReqDecoded'] & TWorkerCodec['TReqDecodedMetaData'], TWorkerCodec['TReqEncoded']>
encodeReq: Encoder<TWorkerCodec['TReqDecoded'] & TWorkerCodec['TReqDecodedMetaData'], TWorkerCodec['TReqEncoded']>
decodeRes: DecoderWithError<
TWorkerCodec['TResDecoded'],
TWorkerCodec['TResErrDecoded'],
TWorkerCodec['TResEncoded']
>
encodeRes: EncoderWithError<
TWorkerCodec['TResDecoded'],
TWorkerCodec['TResErrDecoded'],
TWorkerCodec['TResEncoded']
>
getId: (reqDecoded: TWorkerCodec['TReqDecoded']) => string
}) {
this.decodeInit = decodeInit
this.encodeInit = encodeInit
this.decodeReq = decodeReq
this.encodeReq = encodeReq
this.decodeRes = decodeRes
this.encodeRes = encodeRes
this.getId = getId
}
}
export type Encoder<TDecoded, TEncoded> = (decoded: TDecoded) => [msg: TEncoded, transfer: Transferable[]]
export type Decoder<TDecoded, TEncoded> = (encoded: TEncoded) => TDecoded
export type EncoderWithError<TDecodedSuccess, TDecodedError, TEncoded> = (
either: Either.Either<TDecodedError, TDecodedSuccess>,
) => [msg: TEncoded, transfer: Transferable[]]
export type DecoderWithError<TDecodedSuccess, TDecodedError, TEncoded> = (
encoded: TEncoded,
) => Either.Either<TDecodedError, TDecodedSuccess>
export const identityEncoder = <TVal>(msg: TVal) => [msg, []] as [msg: TVal, transfer: Transferable[]]
@schickling
Copy link
Author

Note to self: Seems to have a bunch of regressions though
CleanShot 2023-04-03 at 16 22 33@2x

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment