Skip to content

Commit e5e42f7

Browse files
effect snippets
1 parent 1827b41 commit e5e42f7

File tree

22 files changed

+1197
-0
lines changed

22 files changed

+1197
-0
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"author": "Sandro Maglione <sandro@sandromaglione.com>",
3+
"license": "MIT",
4+
"devDependencies": {
5+
"@types/node": "^22.8.6",
6+
"typescript": "^5.6.3"
7+
},
8+
"dependencies": {
9+
"@effect/platform": "^0.69.13",
10+
"@effect/rpc": "^0.44.13",
11+
"@effect/rpc-http": "^0.42.13",
12+
"effect": "^3.10.8"
13+
}
14+
}

effect-rpc-http-client-complete-example/pnpm-lock.yaml

Lines changed: 116 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import {
2+
FetchHttpClient,
3+
HttpClient,
4+
HttpClientRequest,
5+
} from "@effect/platform";
6+
import { RpcResolver } from "@effect/rpc";
7+
import { HttpRpcResolverNoStream } from "@effect/rpc-http";
8+
import { Effect, flow } from "effect";
9+
10+
// 👇 API derived from `Router` defined in the server
11+
import { SignUpRequest } from "./schema";
12+
import type { Router } from "./server";
13+
14+
export class RpcClient extends Effect.Service<RpcClient>()("RpcClient", {
15+
effect: Effect.gen(function* () {
16+
const baseClient = yield* HttpClient.HttpClient;
17+
const client = baseClient.pipe(
18+
HttpClient.mapRequest(
19+
// 👇 Rpc endpoint as `POST` pointing to a single API endpoint
20+
flow(
21+
HttpClientRequest.prependUrl("/api/rpc"),
22+
HttpClientRequest.setMethod("POST")
23+
)
24+
)
25+
);
26+
27+
return HttpRpcResolverNoStream.make<Router>(client).pipe(
28+
RpcResolver.toClient
29+
);
30+
}),
31+
dependencies: [FetchHttpClient.layer],
32+
}) {}
33+
34+
/// 👇 Example of how to use `RpcClient` to perform requests
35+
const main = Effect.gen(function* () {
36+
const rpcClient = yield* RpcClient;
37+
38+
// 👇 `boolean`
39+
const response = yield* rpcClient(
40+
new SignUpRequest({
41+
email: "test@test.com",
42+
password: "test",
43+
})
44+
).pipe(
45+
Effect.tapError((requestError) => Effect.log(requestError.errorMessage))
46+
);
47+
});
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// @ts-ignore
2+
import type { NextRequest } from "next/server";
3+
4+
import { RpcWebHandler } from "./server";
5+
6+
/**
7+
* Example of using the rpc handler in a NextJs api route.
8+
*
9+
* `RpcWebHandler.handler` takes a standard `Request` and returns `Response`,
10+
* so it can be used in any API supporting standard requests
11+
*/
12+
export async function POST(request: NextRequest): Promise<Response> {
13+
return RpcWebHandler.handler(request);
14+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Schema } from "effect";
2+
3+
class RequestError extends Schema.Class<RequestError>("RequestError")({
4+
errorMessage: Schema.String,
5+
}) {}
6+
7+
export class SignUpRequest extends Schema.TaggedRequest<SignUpRequest>()(
8+
"SignUpRequest",
9+
{
10+
failure: RequestError,
11+
success: Schema.Boolean,
12+
payload: {
13+
email: Schema.NonEmptyString,
14+
password: Schema.String,
15+
},
16+
}
17+
) {}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { HttpApp } from "@effect/platform";
2+
import { Rpc, RpcRouter } from "@effect/rpc";
3+
import { HttpRpcRouterNoStream } from "@effect/rpc-http";
4+
import { Effect, Logger } from "effect";
5+
import { SignUpRequest } from "./schema";
6+
7+
// 👇 Example of added custom logger (as `Layer`)
8+
export const LoggerLayer = Logger.add(
9+
Logger.make(({ logLevel, message }) => {
10+
globalThis.console.log(`[${logLevel.label}] ${message}`);
11+
})
12+
);
13+
14+
const router = RpcRouter.make(
15+
Rpc.effect(SignUpRequest, (params) =>
16+
Effect.gen(function* () {
17+
// 👇 `params` contains the `TaggedRequest` payload
18+
yield* Effect.log(params.email, params.password);
19+
return true;
20+
})
21+
)
22+
);
23+
24+
// 👇 Export `Router` type for client generation
25+
export type Router = typeof router;
26+
27+
export const RpcWebHandler = HttpApp.toWebHandlerLayer(
28+
HttpRpcRouterNoStream.toHttpApp(router),
29+
// 👇 Provide layers used in requests
30+
LoggerLayer
31+
);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"compilerOptions": {
3+
"esModuleInterop": true,
4+
"skipLibCheck": true,
5+
"target": "es2022",
6+
"allowJs": true,
7+
"resolveJsonModule": true,
8+
"moduleDetection": "force",
9+
"isolatedModules": true,
10+
"verbatimModuleSyntax": true,
11+
"strict": true,
12+
"noUncheckedIndexedAccess": true,
13+
"noImplicitOverride": true,
14+
"module": "preserve",
15+
"noEmit": true,
16+
"lib": ["es2022"]
17+
},
18+
"include": ["**/*.ts", "**/*.tsx"],
19+
"exclude": ["node_modules"]
20+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"author": "Sandro Maglione <sandro@sandromaglione.com>",
3+
"license": "MIT",
4+
"devDependencies": {
5+
"typescript": "^5.6.3"
6+
},
7+
"dependencies": {
8+
"effect": "^3.10.8"
9+
}
10+
}

hybrid-logical-clock-implementation-typescript/pnpm-lock.yaml

Lines changed: 48 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)