A bus is a wrapper around two transformers (serialize and deserialize), with some basic logic included such as chaining or unions.

Busses are executed in parallel, so the order of the errors is not guaranteed (but should not matter). When chaining busses, the deserialized value of the first bus is returned, the others are ignored. This might change in the future.

Transformers should ALWAYS return an IOResult, never throw an error. This is a philosophical choice based on functional programming paradigms. Result objects allow functions to explicitly return errors, and the caller can decide what to do with them. Throwing errors is a side effect, and should be avoided.

Predicates can be attached to ensure validity of the external type, that isn't relevant for the transforming process.

Example

Ensure something is a number:

import * as io from "@prelude-io/core";

const acceptIfNumber = (input: unknown) =>
typeof input === "number"
? io.IOAccept(input)
: io.IOReject({
condition: "number",
value: input,
});

const number = io.Bus.create<unknown, number>(
"number",
acceptIfNumber,
acceptIfNumber
);

console.log(await number.deserialize(1)); // => IORight containing `1`
console.log(await number.deserialize("one")); // => IOLeft containing errors
console.log(await number.serialize(1)); // => IORight containing `1`

Example

Add a predicate to a bus:

import * as io from "@prelude-io/core";
import { Predicate } from "prelude-ts";

const isPositive = Predicate.of((n: number) => n > 0);
const positiveNumber = io.number.if("isPositive", isPositive);

console.log(await positiveNumber.deserialize(1)); // => IORight containing `1`
console.log(await positiveNumber.deserialize("one")); // => IOLeft containing errors
console.log(await positiveNumber.deserialize(-1)); // => IOLeft containing errors for condition "isPositive(number)"

Type Parameters

  • I = any

    The input type of the bus

  • O = any

    The output type of the bus

Hierarchy

  • Bus

Constructors

  • Internal

    Constructor cannot be called directly. Instead, create should be used.

    Type Parameters

    • I = any

    • O = any

    Parameters

    • name: string

      The name used to identify this bus in errors

    • predicate: Option<Predicate<O>>

      An optional Predicate exectuted on the output of the bus

    • deserialize: IOTransformer<I, O>

      A deserialization function

    • serialize: IOTransformer<O, I>

      A serialization function

    • inner: Bus<any, any> | ComplexFields | readonly Bus<any, any>[] = null

      Contains the inner bus if this bus is a wrapper around other busses

    Returns Bus<I, O>

Properties

deserialize: IOTransformer<I, O>

A deserialization function

inner: Bus<any, any> | ComplexFields | readonly Bus<any, any>[] = null

Contains the inner bus if this bus is a wrapper around other busses

name: string

The name used to identify this bus in errors

predicate: Option<Predicate<O>>

An optional Predicate exectuted on the output of the bus

serialize: IOTransformer<O, I>

A serialization function

Methods

  • Creates a new bus with the given name and bus, returning the result of the first bus chained into the second bus.

    The predicates of the chained busses are preserved, but the newly created bus does not have a predicate of its own.

    
    

    Type Parameters

    • OB

      The other bus' output

    Parameters

    • other: Bus<O, OB>

      The other bus to combine with

    • name: string = ...

      The name of the new bus

    Returns Bus<I, OB>

    A new bus "this -> other"

  • Creates a new bus with the given name and bus, returning the result of the first bus if it succeeds, otherwise the result of the second bus.

    On failure, returns the errors of both busses.

    import * as io from "@prelude-io/core";

    // Creates a bus `ADD | UPDATE | DELETE`
    const ActionTypeBus = io
    .Literal("ADD")
    .else(io.Literal("UPDATE"))
    .else(io.Literal("DELETE"));

    // Note that the following are functionally the same thing. Pay attention to the brackets:
    const busA = io.boolean.else(io.string).else(io.number);
    const busB = io.boolean.else(io.string.else(io.number));

    Type Parameters

    • IB

      The other bus' input

    • OB

      The other bus' output

    Parameters

    • other: Bus<IB, OB>

      The other bus to combine with

    • name: string = ...

      The name of the new bus

    Returns Bus<I | IB, O | OB>

    A new bus this | other

  • Attaches a Predicate to a bus. The predicate is applied on the deserialized value before returning.

    Example

    Add a predicate to a bus:

    import * as io from "@prelude-io/core";
    import { Predicate } from "prelude-ts";

    const isPositive = Predicate.of((n: number) => n > 0);
    const positiveNumber = io.number.if("isPositive", isPositive);

    console.log(await positiveNumber.deserialize(1)); // => IORight containing `1`
    console.log(await positiveNumber.deserialize("one")); // => IOLeft containing errors
    console.log(await positiveNumber.deserialize(-1)); // => IOLeft containing errors for condition "isPositive(number)"

    Because this nests the original bus, you can call this function multiple times:

    import * as io from "@prelude-io/core";
    import { Predicate } from "prelude-ts";

    const canDivideBy3 = Predicate.of<number>((input) => input % 3 === 0);
    const canDivideBy5 = Predicate.of<number>((input) => input % 5 === 0);

    // Creates canDivideBy5(canDivideBy3(number))
    io.number.if("canDivideBy3", canDivideBy3).if("canDivideBy5", canDivideBy5);

    // Creates canDivideBy15(number)
    io.number.if("canDivideBy15", canDivideBy3.and(canDivideBy5));

    Parameters

    • name: string

      The name of the predicate. Formatted to be "predicateName(busName)"

    • predicate: Predicate<O>

      The predicate to attach to this bus

    Returns Bus<I, O>

    A new bus with the given predicate attached to it.

  • Creates a new bus with the given name and deserializer.

    Type Parameters

    • I

      The input type for the new bus

    • O

      The output type for the new bus

    Parameters

    Returns Bus<I, O>

Generated using TypeDoc