Loading...
Loading...
Adopt Funkcia in TypeScript codebases using Option, Result, OptionAsync, ResultAsync, and module utilities such as Brand, SafeJSON, SafeURI, SafeURL, and TaggedError patterns. Use when migrating from null/throw/promise-rejection flows, designing typed error boundaries, or implementing domain-safe parsing and validation.
npx skill4agent add lukemorales/funkcia funkciaOptionResultOptionOptionAsyncResultResultAsyncTaggedErrortry/catchResult.tryResultAsync.tryfromNullablefromFalsymapandThenfilterormatchmatch_tagexhaustive(error, { ... })unwrapexpectTypeOfResultAsync.resourceResultimport { Result } from 'funkcia';
function parseWebhook(raw: string) {
return Result.try(
() => JSON.parse(raw),
() => new Error('Invalid webhook payload'),
);
}Optionimport { Option } from 'funkcia';
function findPrimaryEmail(user: User) {
return Option.fromNullable(user.emails.find((x) => x.primary))
.map((email) => email.value.toLowerCase());
}ResultAsyncimport { ResultAsync } from 'funkcia';
function fetchCheckoutSession(sessionId: string) {
return ResultAsync.try(
() => payments.getSession(sessionId),
(cause) => new Error(`Failed to fetch session ${sessionId}: ${String(cause)}`),
);
}async function buildCheckoutSummary(userId: string): Promise<Result<CheckoutSummary, CheckoutError>> {
try {
const user = await usersApi.getById(userId);
if (!user.defaultPaymentMethodId) {
return Result.error(new MissingPaymentMethodError(user.id));
}
const paymentMethod = await paymentsApi.getMethod(user.defaultPaymentMethodId);
const cart = await cartApi.getActiveCart(user.id);
if (!cart) {
return Result.error(new CartNotFoundError(user.id));
}
return Result.ok({
userEmail: user.email,
paymentMethod: paymentMethod.brand,
total: cart.total,
});
} catch (cause) {
return Result.error(new CheckoutInfrastructureError(cause));
}
}function buildCheckoutSummary(userId: string): ResultAsync<CheckoutSummary, CheckoutError> {
return ResultAsync.use(async function* () {
const user = yield* ResultAsync.try(
() => usersApi.getById(userId),
(cause) => new CheckoutInfrastructureError(cause),
);
const paymentMethodId = yield* Result.fromNullable(
user.defaultPaymentMethodId,
() => new MissingPaymentMethodError(user.id),
);
const paymentMethod = yield* ResultAsync.try(
() => paymentsApi.getMethod(paymentMethodId),
(cause) => new CheckoutInfrastructureError(cause),
);
const cart = yield* Result.fromNullable(
yield* ResultAsync.try(
() => cartApi.getActiveCart(user.id),
(cause) => new CheckoutInfrastructureError(cause),
),
() => new CartNotFoundError(user.id),
);
return ResultAsync.ok({
userEmail: user.email,
paymentMethod: paymentMethod.brand,
total: cart.total,
});
});
}references/tagged-errors.mdTaggedErrorreferences/exhaustive.mdexhaustivecorruptreferences/brand.mdreferences/exceptions.mdpanicreferences/safe-functions.mdreferences/generators.mdOptionResultreferences/do-notation.mdDobindletbindToreferences/resources.mdResultAsync.resource