/**
* Effect `Runtime` utilities for Frida.
*
* @since 1.0.0
*/
import type * as Exit from "effect/Exit";
import * as Cause from "effect/Cause";
import * as Effect from "effect/Effect";
import * as Function from "effect/Function";
import * as Logger from "effect/Logger";
import * as Predicate from "effect/Predicate";
/**
* @since 1.0.0
* @category Runtime
*/
export const runMain = Function.dual<
(options?: {
readonly disablePrettyLogger?: boolean | undefined;
readonly teardown?: ((exit: Exit.Exit) => void) | undefined;
}) => (effect: Effect.Effect) => void,
(
effect: Effect.Effect,
options?:
| {
readonly disablePrettyLogger?: boolean | undefined;
readonly teardown?: ((exit: Exit.Exit) => void) | undefined;
}
| undefined
) => void
>(
(arguments_) => Effect.isEffect(arguments_[0]),
(effect, options) => {
const throwNextTick = (throwable: unknown): void =>
Script.nextTick((error): never => {
throw error;
}, throwable);
const throwFromTapErrorCause: (self: Effect.Effect) => Effect.Effect =
Effect.tapCause((cause): Effect.Effect => {
if (!Cause.hasInterruptsOnly(cause)) {
throwNextTick(cause);
return Function.absurd(undefined as never);
} else {
return Effect.void;
}
});
// This is the runtime entry point, so providing the logger layer here is the whole point.
const withLogger =
options?.disablePrettyLogger === false
? // oxlint-disable-next-line effecttsgo/strict-effect-provide
Effect.provide(Logger.layer([Logger.consolePretty()]))
: Function.identity;
const fiber = Effect.runFork(withLogger(throwFromTapErrorCause(effect)));
fiber.addObserver((exit) => (Predicate.isNotUndefined(options?.teardown) ? options.teardown(exit) : void 0));
}
);