You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
filepizza/src/messages.ts

83 lines
1.7 KiB
TypeScript

import * as t from 'io-ts'
import { pipe } from 'fp-ts/function'
import { fold } from 'fp-ts/Either'
export enum MessageType {
RequestInfo = 'REQUEST_INFO',
Info = 'INFO',
Pause = 'PAUSE',
Start = 'START',
Chunk = 'CHUNK',
Done = 'DONE',
Error = 'ERROR',
}
export const RequestInfoMessage = t.type({
type: t.literal(MessageType.RequestInfo),
browserName: t.string,
browserVersion: t.string,
osName: t.string,
osVersion: t.string,
mobileVendor: t.string,
mobileModel: t.string,
password: t.string,
})
export const InfoMessage = t.type({
type: t.literal(MessageType.Info),
files: t.array(
t.type({
fileName: t.string,
size: t.number,
type: t.string,
}),
),
})
export const StartMessage = t.type({
type: t.literal(MessageType.Start),
fileName: t.string,
offset: t.number,
})
export const ChunkMessage = t.type({
type: t.literal(MessageType.Chunk),
fileName: t.string,
offset: t.number,
bytes: t.unknown,
final: t.boolean,
})
export const PauseMessage = t.type({
type: t.literal(MessageType.Pause),
})
export const DoneMessage = t.type({
type: t.literal(MessageType.Done),
})
export const ErrorMessage = t.type({
type: t.literal(MessageType.Error),
error: t.string,
})
export const Message = t.union([
RequestInfoMessage,
InfoMessage,
PauseMessage,
StartMessage,
ChunkMessage,
DoneMessage,
ErrorMessage,
])
export function decodeMessage(data: any): t.TypeOf<typeof Message> {
const onFailure = (errors: t.Errors): t.TypeOf<typeof Message> => {
throw new Error(`${errors.length} error(s) found`)
}
const onSuccess = (mesg: t.TypeOf<typeof Message>) => mesg
return pipe(Message.decode(data), fold(onFailure, onSuccess))
}