Router
Group procedures into a router, nest them, check their inputs, and call them in the same process.
tacho() creates a procedure builder. Call it as rpc({ ... }) to make a router.
import { const tacho: <C extends Context = {}>() => Builder<C, undefined, unique symbol>tacho } from "tacho";
import { import zz } from "zod";
const const rpc: Builder<{}, undefined, unique symbol>rpc = tacho<{}>(): Builder<{}, undefined, unique symbol>tacho();
export const const app: {
ping: ProcedureDef<{}, undefined, "pong">;
user: {
get: ProcedureDef<{}, {
id: string;
}, {
id: string;
name: string;
}>;
};
}
app = const rpc: <{
ping: ProcedureDef<{}, undefined, "pong">;
user: {
get: ProcedureDef<{}, {
id: string;
}, {
id: string;
name: string;
}>;
};
}>(def: {
ping: ProcedureDef<{}, undefined, "pong">;
user: {
get: ProcedureDef<{}, {
id: string;
}, {
id: string;
name: string;
}>;
};
}) => {
ping: ProcedureDef<{}, undefined, "pong">;
user: {
get: ProcedureDef<{}, {
id: string;
}, {
id: string;
name: string;
}>;
};
}
rpc({
ping: ProcedureDef<{}, undefined, "pong">ping: const rpc: Builder<{}, undefined, unique symbol>rpc.run: <"pong">(fn: (opts: {
input: undefined;
ctx: {};
}) => "pong" | Promise<"pong">) => ProcedureDef<{}, undefined, "pong">
run(() => "pong" as type const = "pong"const),
user: {
get: ProcedureDef<{}, {
id: string;
}, {
id: string;
name: string;
}>;
}
user: {
get: ProcedureDef<{}, {
id: string;
}, {
id: string;
name: string;
}>
get: const rpc: Builder<{}, undefined, unique symbol>rpc
.input<{
id: string;
}>(schema: Schema<{
id: string;
}>): Builder<{}, {
id: string;
}, unique symbol>
input(import zz.function object<{
id: z.ZodString;
}>(shape?: {
id: z.ZodString;
} | undefined, params?: string | {
error?: string | z.core.$ZodErrorMap<NonNullable<z.core.$ZodIssueInvalidType<unknown> | z.core.$ZodIssueUnrecognizedKeys>> | undefined;
message?: string | undefined | undefined;
} | undefined): z.ZodObject<{
id: z.ZodString;
}, z.core.$strip>
object({ id: z.ZodStringid: import zz.function string(params?: string | z.core.$ZodStringParams): z.ZodString (+1 overload)string() }))
.output<{
id: string;
name: string;
}>(schema: Schema<{
id: string;
name: string;
}>): Builder<{}, {
id: string;
}, {
id: string;
name: string;
}>
output(import zz.function object<{
id: z.ZodString;
name: z.ZodString;
}>(shape?: {
id: z.ZodString;
name: z.ZodString;
} | undefined, params?: string | {
error?: string | z.core.$ZodErrorMap<NonNullable<z.core.$ZodIssueInvalidType<unknown> | z.core.$ZodIssueUnrecognizedKeys>> | undefined;
message?: string | undefined | undefined;
} | undefined): z.ZodObject<{
id: z.ZodString;
name: z.ZodString;
}, z.core.$strip>
object({ id: z.ZodStringid: import zz.function string(params?: string | z.core.$ZodStringParams): z.ZodString (+1 overload)string(), name: z.ZodStringname: import zz.function string(params?: string | z.core.$ZodStringParams): z.ZodString (+1 overload)string() }))
.run: (fn: (opts: {
input: {
id: string;
};
ctx: {};
}) => HandlerResult<{
id: string;
name: string;
}>) => ProcedureDef<{}, {
id: string;
}, {
id: string;
name: string;
}>
run(({ input: {
id: string;
}
input }) => ({ id: stringid: input: {
id: string;
}
input.id: stringid, name: stringname: "Ada" })),
},
});
.input(schema)- Standard Schema. Failed input isINVALID_PARAMS..output(schema)- Failed output isINTERNAL_ERROR. Streams check eachyield..run(fn)- Terminal.fngets{ input, ctx }. Return a value, aPromise, or anasync function*.
No .input() → params are untyped / unused. Nested paths are user.get.