Skip to content
Oxide
Esc
navigateopen⌘Jpreview

Context

Attach per-request data such as the caller, then read it inside any procedure.

The type argument to tacho<C>() is the context shape. handle() puts req on context. Pass createContext to merge more.

import { const tacho: <C extends Context = {}>() => Builder<C, undefined, unique symbol>tacho } from "tacho";
import { function handle<R extends AnyRouter, C extends Context = {}>(router: R, opts?: HandleOptions<C>): (request: Request) => Promise<Response>handle } from "tacho/transport/fetch";

const 
const rpc: Builder<{
    req: Request;
    user?: string;
}, undefined, unique symbol>
rpc
=
tacho<{
    req: Request;
    user?: string;
}>(): Builder<{
    req: Request;
    user?: string;
}, undefined, unique symbol>
tacho
<{ req: Requestreq: Request; user?: string | undefineduser?: string }>();
export const
const router: {
    me: ProcedureDef<{
        req: Request;
        user?: string;
    }, undefined, string | undefined>;
}
router
=
const rpc: <{
    me: ProcedureDef<{
        req: Request;
        user?: string;
    }, undefined, string | undefined>;
}>(def: {
    me: ProcedureDef<{
        req: Request;
        user?: string;
    }, undefined, string | undefined>;
}) => {
    me: ProcedureDef<{
        req: Request;
        user?: string;
    }, undefined, string | undefined>;
}
rpc
({
me: ProcedureDef<{
    req: Request;
    user?: string;
}, undefined, string | undefined>
me
:
const rpc: Builder<{
    req: Request;
    user?: string;
}, undefined, unique symbol>
rpc
.
run: <string | undefined>(fn: (opts: {
    input: undefined;
    ctx: {
        req: Request;
        user?: string;
    };
}) => string | Promise<string | undefined> | undefined) => ProcedureDef<{
    req: Request;
    user?: string;
}, undefined, string | undefined>
run
(({
ctx: {
    req: Request;
    user?: string;
}
ctx
}) =>
ctx: {
    req: Request;
    user?: string;
}
ctx
.user?: string | undefineduser),
});
handle<{
    me: ProcedureDef<{
        req: Request;
        user?: string;
    }, undefined, string | undefined>;
}, {
    user: string | undefined;
}>(router: {
    me: ProcedureDef<{
        req: Request;
        user?: string;
    }, undefined, string | undefined>;
}, opts?: HandleOptions<{
    user: string | undefined;
}> | undefined): (request: Request) => Promise<Response>
handle
(
const router: {
    me: ProcedureDef<{
        req: Request;
        user?: string;
    }, undefined, string | undefined>;
}
router
, {
createContext?: ((req: Request) => {
    user: string | undefined;
} | Promise<{
    user: string | undefined;
}>) | undefined
createContext
: (req: Requestreq) => ({
user: string | undefineduser: req: Requestreq.Request.headers: Headers
The **`headers`** read-only property of the Request interface contains the Headers object associated with the request. [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/headers)
headers
.Headers.get(name: string): string | null
The **`get()`** method of the Headers interface returns a byte string of all the values of a header within a Headers object with a given name. If the requested header doesn't exist in the Headers object, it returns null. [MDN Reference](https://developer.mozilla.org/docs/Web/API/Headers/get)
get
("x-user") ?? var undefinedundefined,
}), });

Throw from createContext → JSON-RPC INTERNAL_ERROR.

Set context per call in middleware with next({ ctx }):

import { class RpcErrorRpcError, const tacho: <C extends Context = {}>() => Builder<C, undefined, unique symbol>tacho } from "tacho";

const 
const rpc: Builder<{
    req: Request;
    user?: string;
}, undefined, unique symbol>
rpc
=
tacho<{
    req: Request;
    user?: string;
}>(): Builder<{
    req: Request;
    user?: string;
}, undefined, unique symbol>
tacho
<{ req: Requestreq: Request; user?: string | undefineduser?: string }>();
const
const withUser: Builder<{
    req: Request;
    user?: string;
}, undefined, unique symbol>
withUser
=
const rpc: Builder<{
    req: Request;
    user?: string;
}, undefined, unique symbol>
rpc
.
function use(mw: Middleware<{
    req: Request;
    user?: string;
}>): Builder<{
    req: Request;
    user?: string;
}, undefined, unique symbol>
use
(async ({
ctx: {
    req: Request;
    user?: string;
}
ctx
,
next: (opts?: {
    ctx: Partial<{
        req: Request;
        user?: string;
    }>;
} | undefined) => Promise<unknown>
next
}) => {
const const user: string | nulluser =
ctx: {
    req: Request;
    user?: string;
}
ctx
.req: Requestreq.Request.headers: Headers
The **`headers`** read-only property of the Request interface contains the Headers object associated with the request. [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/headers)
headers
.Headers.get(name: string): string | null
The **`get()`** method of the Headers interface returns a byte string of all the values of a header within a Headers object with a given name. If the requested header doesn't exist in the Headers object, it returns null. [MDN Reference](https://developer.mozilla.org/docs/Web/API/Headers/get)
get
("x-user");
if (!const user: string | nulluser) { throw new
new RpcError({ code, message, data }: {
    code: number;
    message: string;
    data?: unknown;
}): RpcError
RpcError
({ code: numbercode: -32001, message: stringmessage: "unauthorized" });
} return
next: (opts?: {
    ctx: Partial<{
        req: Request;
        user?: string;
    }>;
} | undefined) => Promise<unknown>
next
({
ctx: Partial<{
    req: Request;
    user?: string;
}>
ctx
: { user?: string | undefineduser } });
}); export const
const router: {
    me: ProcedureDef<{
        req: Request;
        user?: string;
    }, undefined, string | undefined>;
}
router
=
const rpc: <{
    me: ProcedureDef<{
        req: Request;
        user?: string;
    }, undefined, string | undefined>;
}>(def: {
    me: ProcedureDef<{
        req: Request;
        user?: string;
    }, undefined, string | undefined>;
}) => {
    me: ProcedureDef<{
        req: Request;
        user?: string;
    }, undefined, string | undefined>;
}
rpc
({
me: ProcedureDef<{
    req: Request;
    user?: string;
}, undefined, string | undefined>
me
:
const withUser: Builder<{
    req: Request;
    user?: string;
}, undefined, unique symbol>
withUser
.
run: <string | undefined>(fn: (opts: {
    input: undefined;
    ctx: {
        req: Request;
        user?: string;
    };
}) => string | Promise<string | undefined> | undefined) => ProcedureDef<{
    req: Request;
    user?: string;
}, undefined, string | undefined>
run
(({
ctx: {
    req: Request;
    user?: string;
}
ctx
}) =>
ctx: {
    req: Request;
    user?: string;
}
ctx
.user?: string | undefineduser),
});

Was this page helpful?