I was wondering if there is a way to add elements to the context / resource that will only be present in the use
part of a bracket
. What I'm trying to do is to create a transaction for the things I execute in use
and release the tx in release
. This is a simplified example of what I'm trying to achieve:
type TxContext = {
tx: string;
}
type MyDeps = {
getMyData: () => RTE.ReaderTaskEither<
TxContext,
Error,
string
>;
};
const executeOperation = () =>
bracketW(
pipe(
Do,
bindW("deps", () => ask<MyDeps>()),
// start transaction would be here
bindW("tx", () => right("this is a transaction")),
map(({ deps, tx }) => ({
...deps,
tx,
}))
),
({ getMyData, tx }) => {
// no way to pass the tx to the operation here
return pipe(
getMyData(),
map((data) => `got the data: ${data}`),
);
},
(d, e: E.Either<Error, string>) =>
// close transaction would be here
pipe(fromEither(e), map(constVoid))
);
My problem is that this will add the tx
as a mandatory parameter to R
in the
ReaderTaskEither
. Is there a way to prevent this? I want to create the tx within the bracket as part of the acquire
step.
I tried another solution:
const executeOperation = () =>
bracketW(
pipe(
Do,
bindW("deps", () => ask<MyDeps>()),
bindW("tx", () => right("this is a transaction")),
map(({ deps, tx }) => ({
...deps,
tx,
}))
),
(deps) => {
const { getMyData, tx } = deps;
// pass the deps and re-wrap into a new ReaderTaskEither
return fromTaskEither(
pipe(
getMyData(),
map((data) => `got the data: ${data}`)
)({ tx })
);
},
(d, e: E.Either<Error, string>) =>
pipe(fromEither(e), map(constVoid))
);
but it feels hacky to me. Does fp-ts have an out-of-the-box solution for this?